数组不会衰变为指针的例外情况是什么?

95

我在许多帖子中看到过“在大多数情况下,数组名称会衰减为指向其第一个元素的指针”。


我可以知道在哪些情况/表达式中,数组名称不会衰减为指向其第一个元素的指针吗?


2
需要更多的上下文信息:您是在使用特定的编程语言吗?您有示例吗? - abiessu
考虑C语言。我正在寻找一个数组名称不会衰变为指针的示例。 - nj-ath
1
@TheJoker,我在这里给出了一个答案,其中展示了这些情况。 - Grijesh Chauhan
关于H2Co3的第二点,即使用sizeof,我正在阅读《Head First C》,它首先使用在函数内部使用sizeof(msg)来说明指针衰减,其中msg作为参数传递。他们有一个小框解释说,当数组变量作为参数传递到函数中时,它会衰减为指针(改述),因此您得到的是4或8(字节),而不是数组大小。我感到困惑,因为在下一章中介绍了字符串库,他们引入了strlen()并像使用sizeof()一样使用它。我来这里澄清一下,现在你让我更加困惑了。 :P - punstress
这个答案提供了所有带有示例的异常。 - legends2k
1个回答

79

好的。

C99 中有三种基本情况,分别是:

  1. 当它是 &(取地址)运算符的参数时。

  2. 当它是 sizeof 运算符的参数时。

  3. 当它是类型为 char [N + 1] 或类型为 wchar_t [N + 1]N 是字符串长度)的字符串字面值,用于初始化数组时,例如 char str[] = "foo";wchar_t wstr[] = L"foo";

此外,在 C11 中,新引入的 alignof 运算符也不会使其数组参数退化为指针。

在 C++ 中,还有其他规则,例如当它通过引用传递时。


2
很抱歉,您能否更清楚地解释第三种情况?我的意思是第三种情况中的str不是用来引用字符串的内存位置吗?因此又是一个指针? - nj-ath
4
不,那应该是 const char *str_ptr = "literal";。在我的例子中,str 声明为数组,因此它 一个数组。 - user529758
1
@newacct 我建议你阅读C标准的相关部分 - 这些情况都是枚举的。此外,在数组初始化中,仅当RHS是字符串字面值时,它才是一个表达式(具有数组类型),而不是初始化列表。 - user529758
8
首先,对于初始化,它明确指出“字符串字面量”。它根本没有提到“数组表达式”或“表达式”。因此,字符串字面量语法恰好用于两个地方:作为初始化的右侧和表达式。这并不意味着初始化的右侧是一个表达式。此外,问题明确询问了“数组名”,而字符串字面量不是数组名,您不能在数组的初始化右侧放置数组名(或任何其他数组表达式,除了字符串字面量)。 - newacct
1
@AlexDan 我知道它可以编译,并且我接受使用字符串字面值进行数组初始化是一种特殊语法。然而,如果我们接受特殊语法和例外的存在,那么我们同样可以接受 const char foo[] = <another array>; 是可以的——只要这个数组是一个字符串字面值。 - user529758
显示剩余12条评论

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