const變數通過指標修改 詳解
阿新 • • 發佈:2019-02-08
- 本來以為const變數是無法修改的,今天發現“錯了”(其實沒錯,通過const變數本事是無法修改其值的,但是在“某些情況下”可以通過指向它的指標來間接修改)
一、const變數可以通過指標修改的情況
- 例子:
#include <stdio.h>
void main(void)
{
int const a = 10;
int b = 20;
int *p = (int*)&a;
*p = 20;
printf("&a=%x\n", &a);
printf("&b=%x\n", &b);
printf (" p=%x\n", p);
printf(" a=%d\n", a);
printf("*p=%d\n", *p);
}
解析:
- a和p的地址相同,通過*p其實已經修改了該地址中儲存的值,但是為什麼a的值仍是10呢?
- 因為a是const變數,編譯器對a在預處理的時候就進行了替換。編譯器只對const變數的值讀取一次。所以列印的是10。a實際儲存的值發生了改變。但是為什麼能改變呢,從其儲存地址可以看出來,其儲存在棧中。
二、const變數不可以通過指標修改的情況
- 例子
#include <stdio.h>
int const a = 10;//a作為全域性變數
void main(void)
{
int *p = (int*)&a;
*p = 20;
printf("%d\n", *p);
}
程式編譯通過,但執行時錯誤
解析:
指示a儲存的空間訪問衝突,不可以寫,也就是沒有寫許可權,不能修改其值。估計是儲存在全域性空間,且只有可讀屬性
三、總結:
- 總結,const全域性變數儲存在全域性儲存空間,其值只有可讀屬性,不能修改;
- const區域性變數儲存在堆疊中,可通過指標修改其值;
- const變數在預處理時處理,編譯器只對其值讀取一次。
這其實都是因為編譯器優化導致的
因為a 和p都指向相同的記憶體地址,所以輸出的前兩個結果是相同的,但為啥相同的記憶體裡的結果不相同麼?--這就是常量摺疊.
這個”常量摺疊“是 就是在編譯器進行語法分析的時候,將常量表達式計算求值,並用求得的值來替換表示式,放入常量表。可以算作一種編譯優化。
因為編譯器在優化的過程中,會把碰見的const全部以內容替換掉(跟巨集似的: #define pi 3.1415,用到pi時就用3.1415代替),這個出現在預編譯階段;但是在執行階段,它的記憶體裡存的東西確實改變了!!!
簡單的說就是,當編譯器處理const的時候,編譯器會將其變成一個立即數。