36

在以下规则中,当数组衰减为指针时:

出现在表达式中的 T 数组类型的左值 [参见问题 2.5] 衰减(除了三个例外)成指向其第一个元素的指针;结果指针的类型是指向 T 的指针。

(例外情况是数组是 sizeof 或 & 运算符的操作数,或者是字符数组的文字字符串初始值设定项。)

当数组是“字符数组的文字字符串初始值设定项”时,如何理解这种情况?请举个例子。

谢谢!

4

4 回答 4

51

数组不衰减为指针的三个例外情况如下:

例外 1. — 当数组是 的操作数时sizeof

int main()
{
   int a[10];
   printf("%zu", sizeof(a)); /* prints 10 * sizeof(int) */

   int* p = a;
   printf("%zu", sizeof(p)); /* prints sizeof(int*) */
}

例外 2. — 当数组是运算符的操作数时&

int main()
{
    int a[10];
    printf("%p", (void*)(&a)); /* prints the array's address */

    int* p = a;
    printf("%p", (void*)(&p)); /*prints the pointer's address */
}

例外 3. — 当数组用文字字符串初始化时。

int main()
{
    char a[] = "Hello world"; /* the literal string is copied into a local array which is destroyed after that array goes out of scope */

    char* p = "Hello world"; /* the literal string is copied in the read-only section of memory (any attempt to modify it is an undefined behavior) */
}
于 2010-01-10T04:49:23.983 回答
9

假设声明

char foo[] = "This is a test";
char *bar  = "This is a test";

在这两种情况下,字符串文字“ This is a test”的类型都是“15 元素的 char 数组”。在大多数情况下,数组表达式从类型“T 的 N 元素数组”隐式转换为“指向 T 的指针”,并且表达式的计算结果为数组第一个元素的地址。在声明中bar,这正是发生的事情。

然而,在 的声明中foo,表达式被用于初始化另一个数组的内容,因此不会转换为指针类型;相反,字符串文字的内容被复制到foo.

于 2010-01-11T21:03:49.720 回答
5

这是字符数组的文字字符串初始值设定项:

char arr[] = "literal string initializer";

也可以是:

char* str = "literal string initializer";

来自 K&R2 的定义:

字符串文字,也称为字符串常量,是用双引号括起来的字符序列,如“...”。字符串具有“字符数组”类型和静态存储类(参见下面的第 A.3 节),并使用给定的字符进行初始化。相同的字符串文字是否不同是实现定义的,而试图改变字符串文字的程序的行为是未定义的。

于 2010-01-10T04:44:50.367 回答
2

似乎您从 comp.lang.c 常见问题解答中提取了该引用(可能是旧版本或印刷版本;它与在线版本的当前状态不太匹配):

http://c-faq.com/aryptr/aryptrequiv.html

相应部分链接到常见问题解答的其他部分,以详细说明这些例外情况。在您的情况下,您应该查看:

http://c-faq.com/decl/strlitinit.html

于 2010-01-10T04:53:14.640 回答