关于C中字符指针的困惑

Sum*_*eet 5 c pointers

C中的字符指针令我困惑.

假设我们有一个char指针,它指向string 常量的第一个字符.

char *a="ABCD";
Run Code Online (Sandbox Code Playgroud)

然后我们不能使用指针a更改该字符的值,因为以下语句会导致分段错误.

*a='X';
Run Code Online (Sandbox Code Playgroud)

现在假设我们有一个char指针,指向一个字符常量.

const char B='X';    
char *ptr=&B;
Run Code Online (Sandbox Code Playgroud)

然后我们可以使用该语句更改该字符的值

*ptr='Z';
Run Code Online (Sandbox Code Playgroud)

我的问题是,这是一个未定义的行为,证明C不健壮?或者是否涉及更深层次的逻辑?

Que*_*tin 7

让我们说C让你很容易在脚下射击.修改B仍然是未定义的行为,就像修改一样*a,因为B已声明const.

为了解决这个问题,打开警告(除非在非常特殊的情况下,你应该总是这样做)在GCC 上发出以下信息:

warning: initialization discards 'const' qualifier from pointer
         target type [-Wdiscarded-qualifiers]
Run Code Online (Sandbox Code Playgroud)


hac*_*cks 5

在C中,不允许修改字符串文字.

char *a="ABCD";  
Run Code Online (Sandbox Code Playgroud)

相当于

char const *a="ABCD";  
Run Code Online (Sandbox Code Playgroud)

*a='X';正在修改字符串文字ABCD.而在第二种情况下,ptr指向一个不应该被更改的字符,*ptr='Z';并将修改包含的位置的内容X也是无效的.

请注意,修改const限定对象是违反约束的.


das*_*ght 5

指针表现不同的原因是C程序有几个内存段,其中一些是受保护的.

然后我们不能使用指针a更改该字符的值,因为以下语句会导致分段错误.

与其他常量不同,字符串常量被放入受保护的段中.任何修改此段的尝试都会导致未定义的行为(即您的程序可能会出现段错误).

由于指针指向一个字符串常量,因此无法修改它指向的值.如果通过使用数组强制将常量的副本转换为可修改的内存,则允许进行相同的修改:

char a[]="ABCD";
*a='X';
Run Code Online (Sandbox Code Playgroud)

然后我们可以使用该语句更改该[single]字符的值

这是因为字符常量总是被复制到可修改的内存中.