为什么这个数组大小“解决方法”给了我一个警告?

众所周知,当在C中作为参数传递时,数组会衰减为指针。但是数组数组只会衰减到数组的指针; 因此,如果我们将原始数组本身封装在一个数组中,我们可以在将封闭数组传递给函数后检索原始数组长度。 这是一个测试这个想法的程序:

/* array_workaround.c */ #include  void printsize(char array_pointer[][10]); int main(void) { char a[10]; for(char i = 0; i < 10; i++) a[i] = i; char a_p[1][10] = {a}; printsize(a_p); return 0; } void printsize(char array_pointer[][10]) { printf("%lu\n", sizeof(array_pointer[0])); } 

运行时,它会输出正确的值( 10 ),但编译器会发出以下警告:

 array_workaround.c:12:24: warning: incompatible pointer to integer conversion initializing 'char' with an expression of type 'char [10]' [-Wint-conversion] char a_p[1][10] = {a}; 

当然,这种“解决方法”的问题在于它要求将数组的大小硬编码到接收它的函数中,这有点违背了整个目的。 但是,它确实意味着检查数组的大小是正确的,而不必将长度作为单独的参数传递…(只要它总是10!lol)。

那警告发生了什么? 编译器是不是“足够聪明”才能知道这里发生的事情不会破坏任何数据? 或者我只是以某种方式获得幸运? 任何人都可以看到一种方法使其成为一个实际的解决方法,这样你就不必在那里硬编码数字10?

 char a_p[1][10] = {a}; 

a的值,它是a的基地址并具有指向char的指针类型,用于初始化a_p[0][0] ,它应该是char ,这就是编译器为您提供转换警告的原因。

这条线

 char a_p[1][10] = {a}; 

相当于

 char a_p[1][10]; a_p[0][0] = a; 

希望你能看到那里的问题。 至于为什么你的大小很幸运,这是因为你将数组的第一个维度设置为1.试试这个

 char a_p[5][10]; 

看看你得到了什么。 没有解决方法可以避免printsize函数中的数字10。 编译器需要10才能正确计算数组元素的地址。

感谢大家的答案。 我给你答案检查,leeduhem,因为你指出了我所有的误解。 但是我也想在这里添加一个答案(而不是编辑混乱),因为我想出了一种使用变长数组声明和全局变量使其工作的一种方法。

 #include  int length; void printsize(char array_pointer[][length]); int main(void) { char a[10]; length = sizeof a; for(int i = 0; i < sizeof a; i++) a[i] = i; char a_p[1][sizeof a]; for(int i = 0; i < sizeof a; i++) a_p[0][i] = a[i]; printsize(a_p); return 0; } void printsize(char array_pointer[][length]) { printf("%lu\n", sizeof(array_pointer[0])); } 

这将返回10的大小。

编辑:这是一个使用指针来解决问题的版本。 它在运行时获取length的值,但不知何故,取决于长度的声明仍然可以。 (我尝试直接传入数组,但它给了我指回char指针大小,而不是数组大小。)

 #include  int length; int arraylength(char (*a)[length]); int main(void){ int n; printf("Enter array length: "); scanf("%d", &n); char a[n]; for(int i = 0; i < sizeof a; i++) a[i] = i; length = sizeof a; printf("%d\n", arraylength(&a)); } int arraylength(char (*a)[length]){ /* pointer to array of chars */ return sizeof (*a); // note that the "(*a)" here is a deferenced array }