遇到了一個關於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 \r\n",&i); printf("p=0x%x \r\n",p); printf("i=%d \r\n",i); printf("*p=%d \r\n",*p); } ~
編譯運行,看看出現什么情況:

編譯正常,運行正常
3、const變量真的可以通過指針修改么?
#include <stdio.h>
const int i = 5; int main(void) { int *p = (int *)&i; *p = 10; printf("&i=0x%x \r\n",&i); printf("p=0x%x \r\n",p); printf("i=%d \r\n",i); printf("*p=%d \r\n",*p); }
編譯運行看現象:

編譯通過了,運行時出現了段錯誤。
二、分析
1、const起作用是在那個時期?編譯時期還是運行時期?
這個我們可以通過分析實驗1和2來進行定論,實驗1是通過顯式修改的方式來修改變量值,結果編譯器報錯。那說明在編譯時期,編譯器就能發現const被修改這個錯誤;但是實驗2,我們通過指針來間接修改它的值,卻發現編譯器不僅沒報錯,反而變量值也被成功修改。說明const常量只是一個編譯期間的常量。
2、const修飾全局變量可以修改么?
為了搞清楚這個問題,我進行了實驗3,卻發現運行時出現了段錯誤。 我們都知道,出現段錯誤的原因無非就是這么幾個:訪問一個不存在的地址、訪問系統保護的地址、訪問只讀內存地址、讀寫一個空指針、堆棧溢出、數組越界等。我們知道const全局變量存儲在全局存儲空間,而且是只讀的,因此試圖修改會出現段錯誤。
