为什么C中的字符串用'const'声明?

B.L*_*.Li 3 c string pointers const

例如,为什么不:

char *s= "example";
Run Code Online (Sandbox Code Playgroud)

代替:

const char *s= "example";
Run Code Online (Sandbox Code Playgroud)

我知道const使它不可更改,但为什么在编译第一个时会收到错误?

此外,该概念如何适用

int * x;
Run Code Online (Sandbox Code Playgroud)

VS

const int *x;
Run Code Online (Sandbox Code Playgroud)

我看到第二个使用了更多,使用"cons int*"是好的做法吗?

Kei*_*son 12

没有要求使用const,但这是一个好主意.

在C中,字符串文字是类型的表达式char[N],其中N字符串的长度加1(对于终止'\0'空字符).但是,尝试修改与字符串文字对应的数组具有未定义的行为.许多编译器安排将该数组存储在只读存储器中(不是物理ROM,而是由操作系统标记为只读的存储器).(在大多数上下文中,数组表达式转换为指向数组对象的初始元素的指针表达式.)

使字符串文字更有意义const,但const旧版本的C中不存在该关键字,并且它会破坏现有代码.(C++确实创建了字符串文字const).

这个:

char *s= "example"; /* not recommended */
Run Code Online (Sandbox Code Playgroud)

实际上在C中完全有效,但它有潜在危险.如果在此声明之后,您执行以下操作:

s[0] = 'E';
Run Code Online (Sandbox Code Playgroud)

然后你试图修改字符串文字,并且行为是未定义的.

这个:

const char *s= "example"; /* recommended */
Run Code Online (Sandbox Code Playgroud)

也有效; 在char*从评估字符串字面量的结果值是安全,安静地转化为const char*.它通常比第一个版本更好,因为它允许编译器在您尝试修改字符串文字时警告您(在编译时捕获错误比在运行时捕获错误更好).

如果你的第一个例子出现错误,那么很可能你无意中将你的代码编译为C++而不是C - 或者你正在使用gcc的-Wwrite-strings选项或类似的东西.(-Wwrite-strings使字符串文字const;它可以提高安全性,但它也可能导致gcc拒绝,或至少警告有效的C代码.)