arr
。什么情况下以下方法不能给出数组元素的数量:sizeof(arr) / sizeof(arr[0])
?我只能想到一种情况:数组包含与该数组类型不同的派生类型。
我是否正确?除此之外还有其他情况(我几乎可以确定还有)吗?
抱歉这个问题很琐碎,我是Java开发人员,对C++相当新手。
谢谢!
arr
。什么情况下以下方法不能给出数组元素的数量:sizeof(arr) / sizeof(arr[0])
?假设我有一个数组arr。什么情况下以下代码不会返回数组元素的数量:sizeof(arr) / sizeof(arr[0])?
我经常看到新手程序员犯这样的错误:
void f(Sample *arr)
{
int count = sizeof(arr)/sizeof(arr[0]); //what would be count? 10?
}
Sample arr[10];
f(arr);
新手程序员们认为count
的值将会是10。但这是错误的。
即使是这样也是错误的:
void g(Sample arr[]) //even more deceptive form!
{
int count = sizeof(arr)/sizeof(arr[0]); //count would not be 10
}
这是因为一旦你将数组传递给任何一个函数,它会变成指针类型,所以sizeof(arr)
会给出指针的大小,而不是数组的大小!
编辑:
以下是一种优雅的方式,您可以将数组传递给函数,而不让它退化为指针类型:
template<size_t N>
void h(Sample (&arr)[N])
{
size_t count = N; //N is 10, so would be count!
//you can even do this now:
//size_t count = sizeof(arr)/sizeof(arr[0]); it'll return 10!
}
Sample arr[10];
h(arr); //pass : same as before!
std::size(container)
,它将返回该容器中元素的数量。std::vector<int> vec = { 1, 2, 3, 4, 8 };
std::cout << std::size(vec) << "\n\n"; // 5
int A[] = {40,10,20};
std::cout << std::size(A) << '\n'; // 3
C++中的数组与Java中的数组非常不同,因为它们是完全未经管理的。编译器或运行时根本不知道数组的大小。
如果在声明中定义了大小,则只有在编译时才能知道信息:
char array[256];
arr
,根据数组和sizeof
的定义,sizeof(arr) / sizeof(arr[0])
的值始终等于元素数量,没有任何例外情况。实际上这个结论已经在§5.3.3/2中明确指出:
重点在于除以一个元素的大小当应用于数组时,结果是数组中的总字节数。 这意味着n元素的数组大小是每个元素大小的n倍。
sizeof(arr[0])
,得到n的值。不,这样仍然会产生正确的值,因为您必须将数组定义为单个类型的所有元素或该类型的指针。在任何情况下,数组大小在编译时已知,因此sizeof(arr)/ sizeof(arr [0])始终返回元素计数。
以下是如何正确使用它的示例:
int nonDynamicArray[ 4 ];
#define nonDynamicArrayElementCount ( sizeof(nonDynamicArray) / sizeof(nonDynamicArray[ 0 ]) )
在这里我想再进一步说明使用这种方法的何时是合适的。你不会经常使用它,主要情况是你想定义一个数组,以便稍后添加元素时不需要改变很多代码,这种构造方式主要用于维护。当我考虑到这个问题时,经典的例子就是为某个程序构建命令表,然后打算稍后添加更多命令。在此示例中,如果你要维护/改进你的程序,则只需将另一个命令添加到数组中,然后添加命令处理程序:
char *commands[] = { // <--- note intentional lack of explicit array size
"open",
"close",
"abort",
"crash"
};
#define kCommandsCount ( sizeof(commands) / sizeof(commands[ 0 ]) )
void processCommand( char *command ) {
int i;
for ( i = 0; i < kCommandsCount; ++i ) {
// if command == commands[ i ] do something (be sure to compare full string)
}
}
sizeof
获取数组大小的上下文中。 - GManNickGsizeof
没有起作用。 :) - GolezTrol_countof(my_array)在MSVC中的用法
我只能想到一种情况:数组包含不同派生类型的元素。
C++中的数组元素是对象,而不是指针,因此您不能将派生类型对象作为元素。
就像上面提到的那样,sizeof(my_array)(以及_countof())仅适用于数组定义的范围内。
std::vector
而不是数组来规避该问题。其次,如果您将派生类的对象放入超类的数组中,则会出现切片问题,但好消息是,您的公式仍然有效。在 C++ 中实现多态集合需要使用指针。这里有三个主要选项:
vector
。使用向量并使用shared_ptr
。 - Björn Pollexn
个元素,而且n
很小,我不明白为什么要浪费时间使用std::vector
。 - GManNickGsizeof(arr) / sizeof(arr[0])
?arr
实际上不是数组(而是指向初始元素的指针)时,就会发生这种情况。其他答案解释了这是如何发生的。C++数组不是一等对象。您可以使用boost::array使它们更像Java数组,但请记住,您仍将具有值语义而不是引用语义,就像其他所有内容一样。(特别是,这意味着您无法真正声明类似于Java中的Foo[]
类型的变量,也无法用大小不同的另一个数组替换数组;数组大小是类型的一部分。)在此类中使用.size()
,在Java中使用.length
。(它还提供了提供C++迭代器的常规接口的迭代器。)
看起来,如果您知道数组中元素的类型,您也可以利用sizeof
来优化代码。
int numList[] = { 0, 1, 2, 3, 4 };
cout << sizeof(numList) / sizeof(int);
// => 5