C语言中通过const指针加偏移修改值触发编译报错的原因是什么
问题成因解答
你提供的测试代码如下:
#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 T*类型指针的本质约束是无法通过该指针(以及该指针派生的所有同类型指针)修改其指向的任意T类型对象,这个限制是绑定在指针本身的访问权限上,并非仅绑定在指针当前存储的某个特定地址上。
具体规则拆解
- 指针算术运算不会改变指针的基础类型:你对
const int *pa执行pa + 2操作时,得到的运算结果仍然是const int *类型,只是指向的地址向后偏移了2个int类型的步长。 - 对
const T*类型的指针解引用,得到的是带const限定的T类型左值,C语言标准明确禁止对const限定的左值执行赋值操作,因此*(pa + 2) = 4这类写法会直接触发编译报错。
常见误解澄清
你之前的理解偏差在于把const的限制当成了「仅禁止修改指针当前指向的那一个内存地址的内容」,但实际const修饰的是指针指向的对象类型的限定符,只要是通过这个指针做写入操作,不管是否加偏移、不管偏移到哪个地址,都会被编译器判定为非法操作。
额外说明:第三个示例中pc指向单个int变量c,pc + 2本身已经属于指针越界,属于未定义行为,哪怕没有const限制,这种写法也是错误的。
内容的提问来源于stack exchange,提问作者Ancientmodern
相关产品推荐
相关产品推荐

