指针创建常量字符串文字,为什么?

Des*_*Ice 2 c pointers constants

我正在阅读一些说明这一点的文件

第一个案例

char * p_var="Sack";     
Run Code Online (Sandbox Code Playgroud)

将创建一个常量字符串文字.

因此代码就像

  p_var[1]="u";             
Run Code Online (Sandbox Code Playgroud)

因为那个财产会失败.

第二个案例

还提到的是,这仅适用于字符文字,而不适用于通过指针的其他数据类型.所以代码就像

float *p="3.14"; 
Run Code Online (Sandbox Code Playgroud)

将失败,导致编译器错误.

但是,当我尝试它时,我没有得到编译器错误,访问它虽然给了我0.000000f(在Ubuntu上使用gcc).

所以关于上面,我有三个问题:

  1. 为什么在First Case中创建的字符串文字是只读的?

  2. 为什么只允许创建字符串文字,而不是像浮点指针那样的其他常量?

3.为什么Second Case没有给我编译错误?

更新

请丢弃第3个问题和第2个案例.我通过添加引号来测试它.

谢谢

Kon*_*lph 5

前提是错误的:指针不会创建任何字符串文字,既不是只读的也不是可写的.

什么创建一个只读的字符串是字面本身:"foo"是只读的字符串常量.如果将其分配给指针,则该指针指向只读存储器位置.

有了这个,让我们转向你的问题:

为什么在First Case中创建的字符串文字是只读的?

真正的问题是:为什么不呢?在大多数情况下,您不希望稍后更改字符串文字的值,因此默认假设是有意义的.此外,您可以通过其他方式在C中创建可写字符串.

为什么只允许创建字符串文字而不是像浮动这样的其他常量?

再次,错误的假设.您可以创建其他常量:

float f = 1.23f;
Run Code Online (Sandbox Code Playgroud)

这里,1.23f文字是只读的.您还可以将其分配给常量变量:

const float f = 1.23f; 
Run Code Online (Sandbox Code Playgroud)

为什么Second Case没有给我编译器错误?

因为编译器无法检查您的指针是指向只读内存还是可写内存.考虑一下:

char* p = "Hello";
char str[] = "world"; // `str` is a writeable string!

p = &str[0];

p[1] = 'x';
Run Code Online (Sandbox Code Playgroud)

在这里,p[1] = 'x'完全合法 - 如果我们p事先没有重新分配,那将是非法的.检查这一点通常不能在编译时完成.