字节数组中的项数

4

我有以下的C++数组:

byte data[] = {0xc7, 0x05, 0x04, 0x11 ,0x45, 0x00, 0x00, 0x00, 0x00, 0x00};

我该如何知道这个数组中有多少项?


在您提供的情况下,您希望答案是5还是10? - Mark Byers
10(我讨厌对评论的15个限制) - Alon Gubkin
3个回答

10

对于字节大小的元素,您可以使用sizeof(data)

更一般地,sizeof(data)/sizeof(data[0])将给出元素的数量。


由于这个问题在您上一个问题中出现过,我想澄清一下:当您将数组作为参数传递给函数时,不能使用此方法:

void f(byte arr[])
{
    //This always prints the size of a pointer, regardless of number of elements.
    cout << sizeof(arr);
}

void g()
{
    byte data[] = {0xc7, 0x05, 0x04, 0x11 ,0x45, 0x00, 0x00, 0x00, 0x00, 0x00};
    cout << sizeof(data);    //prints 10
}

1
请注意,这仅在编译器看到数组定义时才起作用(即数组是全局的或在相同的函数内)。如果将数组作为参数传递给函数,则此方法将失败,并提供错误答案而不发出任何警告。int f( char data[] ) { return sizeof(data)/sizeof(data[0]); } void caller() { char array[] = { 0 }; f(array) } 将返回指针的大小(通常为4/8),而不是实际解决方案1. 这是因为在通过值传递时,数组在函数调用时会退化为指针。 - David Rodríguez - dribeas
提示:通常可以定义一个宏,如下所示:#define ARRSIZE(arr) (sizeof(arr)/sizeof(*(arr)))以获取在编译时已知大小的数组元素数量。 - Matteo Italia
当您将数组传递给函数时,这不能使用。但是,如果使用引用,则可以。 - Georg Fritzsche

5
你应该真正使用Neil的建议:std::vector<byte>在大多数情况下是更好的解决方案(唯一更复杂的部分是初始化,在其他任何情况下都更安全)。
如果不使用sizeof(array)/sizeof(array[0])sizeof(array)(因为sizeof(byte)==1),你可以使用带有模板的类型安全方法:
template <typename T, unsigned int N>
unsigned int size_of_array( T (&)[N] ) {
   return N;
}

或者,如果您需要一个编译时常量(同时又想确保不会意外地将其用于非数组):

template <typename T, unsigned int N>
char (&static_size_of_array( T (&)[N] ))[N];

#define compile_time_size(x) (sizeof(static_size_of_array((x))))

在大多数情况下,您不需要使用最后一种解决方案。当传递指针(而不是数组)时,两个模板化解决方案都会快速失败:

void f( char array[] ) // misleading name:
{
   char array2[] = { 1, 2, 3 };
   size_of_array(array2);          // 3
   size_of_array(array);           // compile time error

   sizeof(array)/sizeof(array[0]); // 4/8, depending on architecture!!!
}

2
sizeof( data);     // because sizeof(byte) is 1

但是这不是一个好的通用解决方案 - 特别是如果你将数组传递给函数:

void  f( byte a[] ) {
   // number of elements in 'a' unknown here 
}

数组会衰变为指针,因此sizeof运算符将始终给出指针的大小,而不是数组中元素的数量。
相反,您应该使用std::vector<byte>,它具有size()成员函数。

数组会衰变为指针,但是引用可以解决这个问题:template<size_t n> void f(byte (&a)[n]) - Georg Fritzsche
那么你必须提供大小作为编译时模板参数吗? - anon
不,例如在这里(自我推销,但是最快找到):https://dev59.com/ukrSa4cB1Zd3GeqPVllu#1745963 ... 通过引用完整的数组类型被保留。 - Georg Fritzsche

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接