const 關鍵字有如下特點:
const 修飾的變量本質上還是一個變量,隻不過這個變量是隻讀的
const 修飾的局部變量在棧上配置設定空間
const 修飾的全局變量在全局資料區配置設定空間
const 隻在編譯器有用,在運作期無用
注意:const 修飾的變量不是真正的常量,隻是告訴編譯器該變量不能出現在指派符号的左邊。const 變量隻是說我不會修改這塊記憶體,并不代表别人不修改。
對于 const 修飾的局部變量在棧上配置設定記憶體,其值還是可以更改的。
對于 const 修飾的全局變量
标準 c 語言編譯器不會将 const 修飾的全局變量存儲在隻讀存儲區,而是存儲于可修改的全局資料區,其值依然可以改變;
現代 c 語言編譯器中,修改 const 全局變量将導緻程式崩潰,因為現代 c 編譯器中的 const 将具有全局聲明周期的變量存儲于隻讀存儲區。
程式實驗:const 的變量本質
對上面的結果:const 修飾的局部變量值可以修改, const 修飾的全局變量存儲于隻讀存儲區,修改會導緻程式崩潰
c 語言中的 const 使得變量具有隻讀屬性
現代 c 編譯器中的 const 将具有全局生命周期的變量存儲于隻讀存儲區
const 不能定義真正意義上的常量,隻是表示我不去修改這個變量。
對上面的程式,全局變量和靜态局部變量都具有全局生命周期,使用 const 修飾,變量存儲于隻讀存儲區,不可修改。i 和 array[5] 是局部變量,雖然具有隻讀屬性,僅僅表示通過變量 i 和 array 不會修改記憶體,并不代表别人不去修改。
const 修飾的函數參數表示在函數體内不希望改變參數的值
const 修飾的函數傳回值表示傳回值不可改變,多用于傳回指針的情況。
小貼士:c 語言中的字元串字面量存儲于隻讀存儲區中,在程式中需要使用 const char* 指針。 const char* s = “hello world”;
執行個體分析:const 修飾的函數參數與傳回值
編譯結果如下:編譯器提示,變量 i 是隻讀變量,不能修改。函數 f() 傳回的是一個 const 類型的指針,将其指派給一個普通指針,有修改的可能,給出警告。
是以,這裡不能修改變量 i 的值;應該将指針 p 改為 const char* p;并且不能修改指針 p 指向的内容。
volatile 平時使用較少,這裡就來說一下這個關鍵字的作用。
volatile 可以了解為”編譯器警告訓示字“,什麼意思呢,就是告訴編譯器必須每次去記憶體中取變量值,防止編譯器對代碼進行優化。我們看一個例子:
對上面的代碼,編譯器在編譯的時候發現 obj 沒有被當作左值使用,是以會”聰明“的直接将 obj 替換成 10,而把 a 和 b 都指派為10。
這樣做會不會有問題呢,看似沒有修改 obj,但是在多線程的程式中,或者在需要進行中斷請求的程式中,不能保證其他線程或者中斷請求對這塊記憶體進行修改,在對 b 指派的時候,可能 obj 的值已經改變了,是以 b 得到的值是不正确的。
是以,volatile 主要修飾可能被多個線程通路的變量,也可以修飾可能被為止因素更改的變量,比如中斷處理。
小問題:const volatile int i = 0; 變量 i 具有什麼樣的特性,編譯器如何處理這個變量? 解析:首先,變量 i 是 int 型的變量,每次對 i 操作都是對直接去記憶體中取,并且這個變量是隻讀的。
1、const 使得變量具有隻讀屬性
2、const 不能定義真正意義上的常量
3、const 将具有全局生命周期的變量存儲在隻讀存儲區
4、volatile 強制編譯器減少優化,必須每次從記憶體中取值