【问题标题】:Modify value through a const pointer plus offset in C通过 const 指针加上 C 中的偏移量修改值
【发布时间】:2021-12-03 00:40:37
【问题描述】:
#include<stdio.h>

int main() {
    int a[10] = {1, 2, 3, 4};
    const int *pa = a;
    *(pa + 2) = 4; // error

    char b[4] = "abc";
    const char *pb = b;
    *(pb + 2) = 'c'; // error

    int c = 10;
    const int *pc = &c;
    *(pc + 2) = 4; // error
}

据我了解,const int/char * 仅限制我们不能修改它指向的值。不过貌似修改*(pa + 2)也会报错。为什么会这样?

【问题讨论】:

  • pa + 2 仍然是 const int*。

标签: arrays c pointers constants


【解决方案1】:

因为pa + 2pa 具有相同的类型。要么你想阻止数组被修改,要么你不想,所以结果与原始指针具有相同的类型是有意义的。

【讨论】:

    【解决方案2】:

    首先,请注意const 在很大程度上是一种帮助程序员避免错误的辅助机制,而不是一种始终防止错误的强制机制。用const 定义的数据可以放入只读内存(C 实现允许这样做,也允许不这样做),然后尝试修改该内存(如果不通过请求操作系统更改内存保护来解决它)将产生段错误。否则,const 主要是建议性的,而不是强制执行的。

    编译器必须抱怨 *(pa + 2) = 4; 的具体规则在 C 2018 6.5.16 2 中,其中讨论了赋值运算符。此规则基于所涉及的表达式的类型,而不是它们实际指向的内存中的对象。由于pa 是指向const int 的指针,所以pa + 2 也是指向const int 的指针(C 2018 6.5.6 8:“当将具有整数类型的表达式添加到指针中或从指针中减去时,结果具有指针操作数的类型……”)。那么*(pa + 2)是一个左值,指定pa + 2指向的对象,左值的类型是const int(C 2018 6.5.3.2 4:“…如果操作数有类型”指针指向type”,结果的类型为“type”…”)。

    所以*(pa + 2) = 4; 试图分配给const int 类型的左值。 C 2018 6.5.16 2 说“赋值运算符应有一个可修改的左值作为其左操作数。” const int 不是可修改的类型,因此它不是可修改的左值。本段位于约束部分,这意味着编译器需要针对违反它的情况发出诊断消息。

    【讨论】:

      猜你喜欢
      • 2011-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-14
      • 1970-01-01
      相关资源
      最近更新 更多