突然觉得 C 语言字符串数组的初始化有点怪

2022-01-06 22:11:28 +08:00
 wyc9296

既然"abc"是返回常量区字符串的首字符的地址,为什么定义字符串数组时可以用char array[] = "abc";?这里定义的array[]是数组,而不是指针吧?数组怎么会等于指针?如果想解释成:数组名是数组首元素的地址,那么char array[] = {'a','b','c','\0'};这种表达好像又没法解释了?

```c
char array1[] = {'a','b','c','\0'};
char array2[] = "abc";
char *pr1 = (char[]){'a','b','c','\0'}; // 用复合字面量表示 
char *pr2 = "abc";
```
1523 次点击
所在节点    编程
7 条回复
LeoJ
2022-01-06 22:45:40 +08:00
数组名就是首元素地址啊。\0 表示字符串结束,"abc"实际写入的就是'a' 'b' 'c' '\0',可以理解在 C 语言中""就是个语法糖而已,反正 C 只有 char 类型,没有 string 类型~
ipwx
2022-01-06 22:49:43 +08:00
在 C++ 里面就没这么奇怪了。

第一、第二种:相当于常量初始化了数组。

第三、第四种:虽然能编译,但是会警告,说其实应该赋值给 const char*。
Origami404
2022-01-06 22:53:56 +08:00
你可以认为是字符数组初始化的语法糖,这是“如同赋值”规则的一些例外…
理论上初始化跟赋值是完全两个东西,只是标准要求初始化的效果如同赋值,但实际上初始化的一些语法跟赋值要求是不一样的
commoccoom
2022-01-06 22:57:29 +08:00
字符串常量和字符串数组不是同一样东西
```
#include <stdio.h>
int main(void)
{
char str1[3]="abc";
printf("%x\n",&str1);
printf("%x\n",str1);
printf("%x\n",&str1[0]);
printf("---------------\n");
char *str2="abc";
printf("%x\n",&str2);
printf("%x\n",str2);
printf("%x\n",&str2[0]);
return 0;
}
```
输出
```
8f7d9f0d
8f7d9f0d
8f7d9f0d
---------------
8f7d9f00
bf410018
bf410018
```
wxd92
2022-01-06 22:57:46 +08:00
@ipwx 第四种是 const 的,第三种可修改的吧
前三种其实是开辟新空间,把字符串 copy 到 new allocted memory 里; 第四种只是指针指向常量数组
fishCatcher
2022-01-06 23:03:48 +08:00
数组和指针是两个东西,你用 sizeof 试试就知道了啊
ipwx
2022-01-06 23:04:42 +08:00
@wxd92 ummm 我确实没仔细考虑。但是我觉得不太可能出现这种 implicit new allocated (至少不可能在堆上

https://godbolt.org/z/M6sPzsWf4

根据 compiler explorer ,是栈空间。第三种和第一种效果一致,虽然可能生成的破代码更慢。
----

顺便 gcc 拒绝在 c++ 模式下编译第三种

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/826688

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX