遇到了一个关于const修饰的变量值是否能修改问题,虽然我知道const变量在某些情况下可以通过指向它的指针来间接修改,但是对原理还是很模糊,今天就整理了一下。
一、三个试验压压惊
1、直接对const变量修改
#include <stdio.h> int main(void) { const int a = 5; a = 10; printf("a=%d",a); }
编译一下,看看出现什么情况:
很遗憾,编译出错了。
2、const变量通过指针修改试验
#include <stdio.h>
int main(void)
{
const int i = 5;
int *p = (int *)&i;
*p = 10;
printf("&i=0x%x
",&i);
printf("p=0x%x
",p);
printf("i=%d
",i);
printf("*p=%d
",*p);
}
~
编译运行,看看出现什么情况:
编译正常,运行正常
3、const变量真的可以通过指针修改么?
#include <stdio.h>
const int i = 5; int main(void) { int *p = (int *)&i; *p = 10; printf("&i=0x%x ",&i); printf("p=0x%x ",p); printf("i=%d ",i); printf("*p=%d ",*p); }
编译运行看现象:
编译通过了,运行时出现了段错误。
二、分析
1、const起作用是在那个时期?编译时期还是运行时期?
这个我们可以通过分析实验1和2来进行定论,实验1是通过显式修改的方式来修改变量值,结果编译器报错。那说明在编译时期,编译器就能发现const被修改这个错误;但是实验2,我们通过指针来间接修改它的值,却发现编译器不仅没报错,反而变量值也被成功修改。说明const常量只是一个编译期间的常量。
2、const修饰全局变量可以修改么?
为了搞清楚这个问题,我进行了实验3,却发现运行时出现了段错误。 我们都知道,出现段错误的原因无非就是这么几个:访问一个不存在的地址、访问系统保护的地址、访问只读内存地址、读写一个空指针、堆栈溢出、数组越界等。我们知道const全局变量存储在全局存储空间,而且是只读的,因此试图修改会出现段错误。