C语言函数中用sizeof计算数组元素个数触发警告的问题咨询
解决C语言函数中获取传入数组元素个数的问题
问题原因
在main函数里,a1是真正的数组,sizeof(a1)能拿到整个数组的字节数,除以单个元素的字节数sizeof(a1[0]),就能算出元素个数。但当数组作为参数传给自定义函数时,会被隐式转换成指向数组首元素的指针——也就是说,函数里的arr本质是int*类型,sizeof(arr)得到的是指针的字节数(32位系统是4,64位是8),这时候再用原来的公式计算,结果肯定不对,编译器也会抛出警告。
解决方法
方法一:额外传递数组长度参数
这是最常用、最稳妥的方案。调用函数时把提前算好的数组长度一起传进去,函数直接用这个数值就行。
修改后的代码:
#include <stdio.h> void func(int arr[], int n) { printf("数组元素个数:%d\n", n); } int main() { int a1[] = {1,2,3,4,5,6}; int len = sizeof(a1)/sizeof(a1[0]); func(a1, len); return 0; }
方法二:用宏简化长度计算
可以定义一个宏,在数组的定义作用域里计算长度,避免重复写sizeof的公式:
#include <stdio.h> #define ARRAY_LEN(arr) (sizeof(arr)/sizeof(arr[0])) void func(int arr[], int n) { printf("数组元素个数:%d\n", n); } int main() { int a1[] = {1,2,3,4,5,6}; func(a1, ARRAY_LEN(a1)); return 0; }
注意:这个宏只能在数组本身的作用域用,要是数组已经退化成指针,宏算出来的结果就错了。
方法三:用结构体包裹数组
把数组和它的长度封装到结构体里,传递结构体时数组不会退化成指针,能保留完整的长度信息。
适合固定长度数组的写法:
#include <stdio.h> typedef struct { int data[6]; int len; } IntArray; void func(IntArray arr) { printf("数组元素个数:%d\n", arr.len); } int main() { IntArray a1 = {{1,2,3,4,5,6}, 6}; func(a1); return 0; }
如果用C99及以上标准,还可以用柔性数组成员实现变长数组:
#include <stdio.h> #include <stdlib.h> typedef struct { int len; int data[]; // 柔性数组成员 } IntArray; IntArray* create_int_array(int len, int* elements) { IntArray* arr = malloc(sizeof(IntArray) + len*sizeof(int)); arr->len = len; for(int i=0; i<len; i++) { arr->data[i] = elements[i]; } return arr; } void func(IntArray* arr) { printf("数组元素个数:%d\n", arr->len); } int main() { int elements[] = {1,2,3,4,5,6}; int len = sizeof(elements)/sizeof(elements[0]); IntArray* a1 = create_int_array(len, elements); func(a1); free(a1); // 记得释放内存 return 0; }
内容的提问来源于stack exchange,提问作者Ojasva Nema
相关产品推荐
相关产品推荐

