在初始化,未知大小的数组中使用sizeof() - C++
我是新来的C++编程,我试图获取数组的大小。有人可以解释为什么会发生这种情况吗?我试着运行runnable.com中的代码,结果如图所示。在初始化,未知大小的数组中使用sizeof() - C++
我相信这是不正确的做法。如果可能的话,你能提出任何简单的方法来获得这种数组的大小吗?
#include <iostream>
using namespace std;
int main()
{
int set1[] = {1, 9, 3, 50, 31, 65};
int set234[] = {3, 5, 5};
cout << sizeof(set1) << endl;
cout << sizeof(set234) << endl;
cout << "When sizeof() return value is divided by 4"<< endl;
cout << sizeof(set1)/4 << endl;
cout << sizeof(set234)/4 << endl;
return 0;
}
****************************************************************
Output:
24
12
When sizeof() return value is divided by 4
6
3
****************************************************************
**编辑:感谢您的回复。 飞走:D
数组的大小等于其所有元素的大小之和。就像在你的例子中你处理int类型的数组那样,你系统中的sizeof(int)等于4,因此第一个数组有6个元素,那么它的大小等于6 * sizeof(int)
即24。数组等于3 * sizeof(int)
即12。 如果例如系统中的sizeof(int)等于8,那么第一个数组的大小将等于48(6 * sizeof * int)),并且大小第二个数组将等于18(3 * sizeof(int))。
所以,如果你想例如知道有多少元素有一个数组,你可以计算出下面这样的方式
sizeof(YouArray)/sizeof(YourArray[0])
或
sizeof(YouArray)/sizeof(ElementType)
+1或'sizeof(YourArray)/ sizeof(* YourArray)',以及所有这些(无可争辩的),在'YourArray'是一个简单的指针而不是真正的本地数组时编译。如果使用'std:array ',如果通过工具链提供的话,那么就会有更多的燃料。 – WhozCraig 2014-09-02 17:45:02
@NOWA这个解决方案有点危险,就好像'YouArray'实际上是一个指针或者带有重载的'[]'的东西,它返回没有任何警告的虚假信息。 – Yakk 2014-09-02 18:46:30
@Yakk在这种情况下,你可以使用标准类std :: extent – 2014-09-02 18:58:07
sizeof以字节为单位返回数组的大小,而不是元素。它看起来像在32位系统(或LP64上运行,意味着只有long和指针是64位,但ints仍然是32),因此整数数组中的每个元素都是4个字节。在您的set1中,这是6个元素,即6x4 = 24个字节。
要获取元素的大小,请执行sizeof(set1)/ sizeof(set1 [0])。不过,这对编译时列出元素的数组起作用。但是,如果您只有一个int *,sizeof运算符将返回指针的大小。
我正在64位系统中运行。多谢,伙计。这有帮助。 – NOWA 2014-09-02 17:34:21
噢,呃,可能是LP64,这意味着长和指针是64位的。整数仍然是32位。更新答案来解决这个问题。 – 2014-09-02 17:35:10
sizeof()以字节为单位给出总大小。例如,如果int为4,并且数组中有6个元素。它会返回4 * 6 = 24作为答案。因此下面的代码会给你一个数组的大小。
#include <iostream>
using namespace std;
int main()
{
int set1[] = {1, 9, 3, 50, 31, 65};
int set234[] = {3, 5, 5};
cout << (sizeof(set1))/4 << endl;
cout << (sizeof(set234))/4 << endl;
return 0;
}
您也可以使用此:
#include <iostream>
#include <array>
int main()
{
array<int,5> a;
cout << "size is" << a.size();
return 0;
}
sizeof
返回的字节数,而不是元素的数量。大多数情况下你应该避免数组;使用std::vector
或std::array
,都提供了一种获取元素数量的简单方法。
要获得元素的计数在堆栈中分配的数组中,通常的方法是获取整个数组的总大小(以字节为单位),然后除以单个数组项的大小(以字节为单位):
<item count> = <total array size in bytes>/<single array item size in bytes>
然而,该公式可以仅应用于阵列堆栈上分配,不到阵列动态在堆上分配(例如使用new[]
):在后一种情况下,您需要将数组项计数保存为单独的一条信息。
的Microsoft Visual C++提供了一个方便_countof()
宏,即做上述计算为您,并且安全地断裂编译过程,如果该参数是一个指针例如到一个动态分配的数组(因为在这种情况下,上面的公式给出了一个不正确的结果,即指针的大小 - 它是固定的,例如32位系统上的4个字节,与指向的数组大小无关 - 除以第一个指出的项目的大小)。
看起来好像是there is an equivalent safe ARRAY_SIZE()
macro for Linux。
#include <cstddef>
template<class T, std::size_t N>
std::size_t length_of(T(&)[N]) {
return N;
}
是解决您的问题的模板。
在C++ 11具有更高的工业强度的版本是:
#include <array>
template<class T, std::size_t N>
constexpr std::size_t size(T(&)[N]) {
return N;
}
template<class T, std::size_t N>
constexpr std::size_t size(std::array<T,N> const&) {
return N;
}
template<class C,class=void>
struct has_size : std::false_type {};
template<class>using void_t=void;
template<class C, void_t< decltype(std::declval<C&>().size()) > >
struct has_size : std::true_type {};
template<bool b, class T=void>using enable_if_t=typename std::enable_if<b,T>::type;
template<class C, class=enable_if_t< has_size<C>::value, bool[1] >>
constexpr std::size_t size(C const& c) {
return c.size();
}
template<class C, class=enable_if_t< !has_size<C>::value, bool[2] >>
constexpr std::size_t size(C const& c) {
using std::begin; using std::end;
return end(c)-begin(c);
}
这可能走得太远。请注意,缺少大小的容器中的非随机访问迭代器可能无法编译(因为通常没有定义-
),这种类型在purpoes上(我们不希望意外执行O(n)工作)。
我只是把它称为它的大小。另一个版本(可以适用于所有容器,而不仅仅是C风格的数组)可以使用'return std :: end(array) - std :: begin(array);'(其中'array'是你的名字论据)。为什么标准提供'std :: begin'和'std :: end'而没有提供'std :: size'节拍。 – 2014-09-02 19:11:08
@JamesKanze增加威逼工业强度版本。当有size时,使用'begin' /'end'也是一个坏主意,imho,因为它可能效率更低和/或不起作用(参见'std :: unordered_map',它有一个'size )'但在它的迭代器上没有'operator-')上面的std :: array版本可能是多余的,因为'.size()'已经是'array'的'constexpr'了? – Yakk 2014-09-02 19:31:46
当然,你说得对,如果容器有'尺寸',那就是你应该使用的。但我真正的问题仍然是:为什么它不在标准中?正如你的代码所指出的那样,一个工业强度版本并不是微不足道的,它确实是标准应该提供的东西。 – 2014-09-04 12:53:28
'sizeof(arr)/ sizeof(arr [0])' – bolov 2014-09-02 17:29:13
@NOWA什么不清楚? – 2014-09-02 17:29:17
规范的答案是'sizeof(foo)/ sizeof(foo [0])'。 – 2014-09-02 17:36:15