如何在C中确定数组的大小?
也就是说,阵列可以容纳的元素数量是多少?
执行摘要:
int a[17]; size_t n = sizeof(a)/sizeof(a[0]);
要以字节为单位确定数组的大小,可以使用sizeof
运算符:
int a[17]; size_t n = sizeof(a);
在我的计算机上,整数是4个字节长,所以n是68.
要确定数组中元素的数量,我们可以将数组的总大小除以数组元素的大小.您可以使用类型执行此操作,如下所示:
int a[17]; size_t n = sizeof(a) / sizeof(int);
并获得正确的答案(68/4 = 17),但如果a
您改变了类型,
如果您忘记更改它也会有一个讨厌的错误sizeof(int)
.
因此,首选除数是sizeof(a[0])
数组的零齿数的大小.
int a[17]; size_t n = sizeof(a) / sizeof(a[0]);
另一个优点是,您现在可以轻松地在宏中参数化数组名称并获取:
#define NELEMS(x) (sizeof(x) / sizeof((x)[0])) int a[17]; size_t n = NELEMS(a);
该sizeof
方法是正确的方式当且仅当你面对的不是收到的参数数组.作为参数发送到函数的数组被视为指针,因此sizeof
将返回指针的大小,而不是数组的大小.
因此,在内部函数中,此方法不起作用.相反,始终传递一个额外的参数,size_t size
指示数组中的元素数量.
测试:
#include#include void printSizeOf(int intArray[]); void printLength(int intArray[]); int main(int argc, char* argv[]) { int array[] = { 0, 1, 2, 3, 4, 5, 6 }; printf("sizeof of array: %d\n", (int) sizeof(array)); printSizeOf(array); printf("Length of array: %d\n", (int)( sizeof(array) / sizeof(array[0]) )); printLength(array); } void printSizeOf(int intArray[]) { printf("sizeof of parameter: %d\n", (int) sizeof(intArray)); } void printLength(int intArray[]) { printf("Length of parameter: %d\n", (int)( sizeof(intArray) / sizeof(intArray[0]) )); }
输出(在64位Linux操作系统中):
sizeof of array: 28 sizeof of parameter: 8 Length of array: 7 Length of parameter: 2
输出(在32位Windows操作系统中):
sizeof of array: 28 sizeof of parameter: 4 Length of array: 7 Length of parameter: 1
值得注意的是,sizeof
在处理已经衰减到指针的数组值时没有帮助:即使它指向数组的开头,对于编译器它也与指向该数组的单个元素的指针相同.指针不会"记住"用于初始化它的数组的任何其他内容.
int a[10]; int* p = a; assert(sizeof(a) / sizeof(a[0]) == 10); assert(sizeof(p) == sizeof(int*)); assert(sizeof(*p) == sizeof(int));
"技巧"的大小是我所知道的最好的方式,其中一个很小但是(对我来说,这是一个主要的烦恼)括号使用的重要变化.
正如维基百科条目所表明的那样,C sizeof
不是一个功能; 这是一个运营商.因此,除了参数是类型名称之外,它不需要围绕其参数使用括号.这很容易记住,因为它使参数看起来像一个转换表达式,它也使用括号.
所以:如果你有以下内容:
int myArray[10];
您可以使用以下代码找到元素的数量:
size_t n = sizeof myArray / sizeof *myArray;
对我来说,这比使用括号的替代方案更容易阅读.我也赞成在分区的右侧使用星号,因为它比索引更简洁.
当然,这也是编译时间,因此无需担心影响程序性能的划分.所以尽可能使用此表单.
当你有一个而不是一个类型时,最好在实际对象上使用sizeof,因为那时你不需要担心发出错误并说明错误的类型.
例如,假设您有一个函数可以将一些数据作为字节流输出,例如通过网络输出.让我们调用该函数send()
,并将其作为参数作为指向要发送的对象的指针,以及对象中的字节数.所以,原型变成:
void send(const void *object, size_t size);
然后你需要发送一个整数,所以你这样编码:
int foo = 4711; send(&foo, sizeof (int));
现在,通过指定foo
两个地方的类型,你已经介绍了一种微妙的射击方式.如果一个更改但另一个没有,则代码中断.因此,总是这样做:
send(&foo, sizeof foo);
现在你受到了保护.当然,您复制变量的名称,但如果您更改它,则很可能以编译器可以检测到的方式中断.
int size = (&arr)[1] - arr;
请查看此链接以获取解释
您可以使用sizeof运算符,但它不适用于函数,因为它将采用指针的引用,您可以执行以下操作来查找数组的长度:
len = sizeof(arr)/sizeof(arr[0])
代码最初在这里找到: C程序查找数组中的元素数
如果您知道数组的数据类型,则可以使用以下内容:
int arr[] = {23, 12, 423, 43, 21, 43, 65, 76, 22}; int noofele = sizeof(arr)/sizeof(int);
或者,如果您不知道数组的数据类型,可以使用以下内容:
noofele = sizeof(arr)/sizeof(arr[0]);
注意:只有在运行时未定义数组(如malloc)且数组未在函数中传递时,此方法才有效.在这两种情况下,arr
(数组名称)都是指针.
ARRAYELEMENTCOUNT(x)
每个人都在使用的宏评估错误.实际上,这只是一个敏感问题,因为您不能拥有导致"数组"类型的表达式.
/* Compile as: CL /P "macro.c" */ # define ARRAYELEMENTCOUNT(x) (sizeof (x) / sizeof (x[0])) ARRAYELEMENTCOUNT(p + 1);
实际上评估为:
(sizeof (p + 1) / sizeof (p + 1[0]));
而
/* Compile as: CL /P "macro.c" */ # define ARRAYELEMENTCOUNT(x) (sizeof (x) / sizeof (x)[0]) ARRAYELEMENTCOUNT(p + 1);
它正确评估为:
(sizeof (p + 1) / sizeof (p + 1)[0]);
这显然与数组的大小没有太大关系.我刚刚注意到很多错误都没有真正观察C预处理器的工作原理.您总是包装宏参数,而不是可能涉及的表达式.
这是对的; 我的例子很糟糕.但这实际上应该是应该发生的事情.正如我之前提到的那样,p + 1
最终将作为指针类型并使整个宏无效(就像你试图在带有指针参数的函数中使用宏一样).
在一天结束时,在这个特定的例子中,错误并不重要(所以我只是浪费每个人的时间; huzzah!),因为你没有带有'array'类型的表达式.但我认为关于预处理器评估小数的真正意义重大.
对于多维数组,它有点复杂.通常人们定义显式宏常量,即
#define g_rgDialogRows 2 #define g_rgDialogCols 7 static char const* g_rgDialog[g_rgDialogRows][g_rgDialogCols] = { { " ", " ", " ", " 494", " 210", " Generic Sample Dialog", " " }, { " 1", " 330", " 174", " 88", " ", " OK", " " }, };
但是这些常量也可以在编译时使用sizeof进行评估:
#define rows_of_array(name) \ (sizeof(name ) / sizeof(name[0][0]) / columns_of_array(name)) #define columns_of_array(name) \ (sizeof(name[0]) / sizeof(name[0][0])) static char* g_rgDialog[][7] = { /* ... */ }; assert( rows_of_array(g_rgDialog) == 2); assert(columns_of_array(g_rgDialog) == 7);
请注意,此代码适用于C和C++.对于具有两个以上维度的数组使用
sizeof(name[0][0][0]) sizeof(name[0][0][0][0])
无限的,无限的.
C中数组的大小:
int a[10]; size_t size_of_array = sizeof(a); // Size of array a int n = sizeof (a) / sizeof (a[0]); // Number of elements in array a size_t size_of_element = sizeof(a[0]); // Size of each element in array a // Size of each element = size of type
sizeof(array) / sizeof(array[0])
"你已经介绍了一种在脚下射击自己的微妙方式"
C'原生'数组不存储它们的大小.因此,建议将数组的长度保存在单独的变量/ const中,并在每次传递数组时传递它,即:
#define MY_ARRAY_LENGTH 15 int myArray[MY_ARRAY_LENGTH];
你应该总是避免使用原生数组(除非你不能,在这种情况下,请注意你的脚).如果您正在编写C++,请使用STL的'vector'容器."与阵列相比,它们提供了几乎相同的性能",它们更有用!
// vector is a template, themeans it is a vector of ints vector numbers; // push_back() puts a new value at the end (or back) of the vector for (int i = 0; i < 10; i++) numbers.push_back(i); // Determine the size of the array cout << numbers.size();
请参阅:http: //www.cplusplus.com/reference/stl/vector/
#define SIZE_OF_ARRAY(_array) (sizeof(_array) / sizeof(_array[0]))