为什么 C 数组在传递 size 时会衰减为指针

Why does a C array decay to a pointer when passed with size

提问人:Dimpl 提问时间:10/8/2017 最后编辑:Paul RDimpl 更新时间:10/9/2017 访问量:691

问:

我理解为什么数组在传递给函数时会衰减为指针而不指定其大小,例如:

void test(int array[]);

为什么当它与大小一起传递时会这样做?例如。

void test(int array[3]);

我在后一个函数签名下遇到了问题,这令人沮丧,因为在编译时数组长度是清楚知道的。sizeof

C 数组

评论

4赞 Paul R 10/8/2017
这就是语言的定义方式(并且已经存在了很长时间)——要么将 size 作为单独的参数传递,要么将数组嵌入到结构中,要么切换到不同的语言。
1赞 user2357112 10/8/2017
因为它就是这样设计的。我们可以给你上一堂历史课,但这对你没有多大帮助。
2赞 StoryTeller - Unslander Monica 10/8/2017
这是代表语言设计者的优化。人们当然可以同意他们的观点,或者回想起来认为现在还为时过早。但这就是语言的设计方式。
0赞 Andrew Henle 10/9/2017
我真的很讨厌“数组衰减为指针”的使用。我想说的是“数组衰减到一个地址”更准确。数组是内存的一个区域 - 它存在。它有一个地址 - 一个无法更改或分配的有效地址。(您不能分配给地址 - 您可以分配给地址引用的内存。另一方面,指针是一个变量(另一个内存位置),可以包含一个地址,该地址可能有效,也可能无效。
0赞 Dimpl 10/9/2017
我想我的观点是,如果编译器只是要忽略提供的大小,为什么还要允许后一种语法呢?

答:

3赞 Valdrinium 10/8/2017 #1
void test(int* array);
void test(int array[]);
void test(int array[3]);

所有这些变体都是相同的。C 只允许您使用替代拼写,但即使是使用数组大小显式注释的最后一个变体也会衰减为指向第一个元素的指针。

也就是说,即使使用最后一个实现,您也可以使用任何大小的数组调用该函数:

void test(char str[10]) { }

test("test"); // Works.
test("let's try something longer"); // Still works.

没有神奇的解决方案,处理该问题的最易读的方法是使用数组 + 大小创建 a,或者简单地将大小作为附加参数传递给函数。struct

LE:请注意,此转换仅适用于数组的第一维。当传递给函数时,an 会转换为 ,而不是 。int[3][3]int (*)[3]int **

评论

0赞 Dimpl 10/9/2017
所以 int array[3] 比其他任何事情都更有利于程序员?
1赞 Valdrinium 10/9/2017
在我看来,它不应该被使用。它可能会给用户一种虚假的安全感(“哦,这个函数只接受长度为 3 的数组,所以我不需要自己检查长度”)
1赞 Jens Gustedt 10/8/2017 #2

因为您将无法正确调用此类函数。在几乎所有上下文中,数组都会衰减为指向第一个元素的指针,并且在尝试调用该函数时,数组将首先转换为指针,并且调用将不匹配。数组衰减的唯一上下文是运算符 、 和 。这些更容易在句法上检测。sizeof_Alignof_Alignas&