1. 程式人生 > >const變數通過指標修改 詳解

const變數通過指標修改 詳解

  • 本來以為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儲存的空間訪問衝突,不可以寫,也就是沒有寫許可權,不能修改其值。估計是儲存在全域性空間,且只有可讀屬性

三、總結:

  1. 總結,const全域性變數儲存在全域性儲存空間,其值只有可讀屬性,不能修改;
  2. const區域性變數儲存在堆疊中,可通過指標修改其值;
  3. const變數在預處理時處理,編譯器只對其值讀取一次。
  • 這其實都是因為編譯器優化導致的

    因為a 和p都指向相同的記憶體地址,所以輸出的前兩個結果是相同的,但為啥相同的記憶體裡的結果不相同麼?--這就是常量摺疊.

    這個”常量摺疊“是 就是在編譯器進行語法分析的時候,將常量表達式計算求值,並用求得的值來替換表示式,放入常量表。可以算作一種編譯優化。

    因為編譯器在優化的過程中,會把碰見的const全部以內容替換掉(跟巨集似的: #define pi 3.1415,用到pi時就用3.1415代替),這個出現在預編譯階段;但是在執行階段,它的記憶體裡存的東西確實改變了!!!
    簡單的說就是,當編譯器處理const的時候,編譯器會將其變成一個立即數。