【问题标题】:Confusion about Character Pointers in CC语言中关于字符指针的困惑
【发布时间】:2023-04-01 02:31:01
【问题描述】:

C 中的字符指针让我很困惑。

假设我们有一个 char 指针,它指向字符串 constant 的第一个字符。

char *a="ABCD";

那么我们不能使用指针 a 改变那个字符的值,因为下面的语句会导致分段错误。

*a='X';

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

const char B='X';    
char *ptr=&B;

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

*ptr='Z';

我的问题是,这是证明 C 不健壮的未定义行为的情况吗?还是涉及到更深层次的逻辑?

【问题讨论】:

  • @EugeniuRosca 你的意思是char const *a = "ABCD"。它们没有相同的语义。
  • const 表示内存是只读的。时期。不允许通过另一个指针引用它来更改它 - 这会产生编译器警告。

标签: c pointers


【解决方案1】:

假设 C 可以让你很容易地射中自己的脚。修改 B 仍然是未定义的行为,就像修改 *a 一样,因为 B 已被声明为 const

为了解决这个问题,打开警告(您应该始终这样做,除非在非常特殊的情况下)会在 GCC 上显示以下内容:

warning: initialization discards 'const' qualifier from pointer
         target type [-Wdiscarded-qualifiers]

【讨论】:

    【解决方案2】:

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

    那么我们不能使用指针 a 改变那个字符的值,因为下面的语句会导致分段错误。

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

    由于你的指针指向一个字符串常量,它指向的值不能被修改。如果您通过使用数组将常量的副本强制到可修改的内存中,则允许进行相同的修改:

    char a[]="ABCD";
    *a='X';
    

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

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

    【讨论】:

      【解决方案3】:

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

      char *a="ABCD";  
      

      等价于

      char const *a="ABCD";  
      

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

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

      【讨论】:

      • 修改*ptr一点都无效。
      • @Quentin;哎呀!同意。错过了const 说明符。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-09
      • 2021-07-03
      • 1970-01-01
      • 2012-11-04
      • 1970-01-01
      • 2021-06-23
      • 1970-01-01
      相关资源
      最近更新 更多