C語言深度解剖 筆記4

2021-06-07 23:13:44 字數 1254 閱讀 5545

1最易變的關鍵字  volatile 型別修飾符

用volatile修飾的變數表示可以被某些編譯器未知的因素更改,比如作業系統、硬體或者其他執行緒等。遇到這個關鍵字宣告的變數,編譯器對訪問該變數的**就不再進行優化,從而可以提供對特殊位址的穩定訪問。比如:volatile關鍵字告訴編譯器某變數是隨時可能發生變化的,每次使用它的時候必須從記憶體中取出它的值,因而編譯器生成的彙編**會重新從它的位址中讀取資料。

這樣如果i是乙個暫存器變數或者表示乙個埠資料或者是多個執行緒的共享資料,就容易出錯,所以說volatile可以保證對特殊位址的穩定訪問。

但是注意通過下面的內容,會對const和volatile有更深的理解:

#include

using namespace std; 

int main() 

dec++和vc++執行結果都是 

i=0 *p=2 且&i和p的值相等. 

造成這樣的原因:

1 上面的**是強制型別轉換,繞過編譯器靜態型別檢查,從而獲取變數的位址,因而在程式中只要有合法位址(非作業系統的保護記憶體)就可以修改位址中的資料,語言中const以及其他只是在語法上限制,無法從根本上限制。

2 但為什麼在輸出i的值時,仍然是0呢?

上面的**如果修改為:

const int i=0;

int *p=(int*)&i;

*p=100;

這樣i的內容也被修改了。

從而,我們想到如果使用c++中的另乙個關鍵字:volatile,它就是用來解決這個問題。

因為從暫存器訪問變數比從記憶體要快,所以如果乙個變數在某次使用過後沒有被顯式修改,那麼編譯器將盡量從暫存器讀入它的值。加volatile可以強制要求編譯器每次用到這個變數時都從記憶體中提取它的值。所以這樣就會得到正確結果: 

#include

using namespace std; 

int main() 

{ volatile const int i=0; 

int *p=const_cast(&i); 

*p=2; 

cout << "i=" << i << "\n*p=" << *p << endl; 

cout<<"&i="<<&i<<"\np="《只要是cosnt定義的變數, 並且這個變數是用立即數初始化的, 那麼, 在使用這個變數的時候, 編譯器一定是用立即數代替。 

在筆記中綜合了各種論壇等網上的內容,甚至使用的例子有的都是網上論壇中的例子,在此只是為了自己檢視的時候方便和分享我在學習中的收穫,無侵犯原著的意思,請見諒。

c語言深度解剖筆記

關鍵字 register 這個關鍵字請求編譯器盡可能的將變數存在 cpu內部暫存器中而不是通過記憶體定址訪問以提高效率。注意是盡可能,不是絕對。你想想,乙個 cpu的暫存器也就那麼幾個或幾十個,你要是定義了很多很多 register 變數,它累死也可能不能全部把這些變數放入暫存器吧,輪也可能輪不到你...

讀書筆記《c語言深度解剖》 4

10.struct關鍵字 這裡struct關鍵字講解得比較少,主要有3點 1 空結構體的大小為1 在gcc下我的輸出是0 2 柔性陣列 在c99中,允許結構最後乙個元素是乙個大小未確定的陣列,這個陣列叫做柔性陣列。但是柔性陣列前面必須至少有乙個其他成員。用sizeof返回結構體大小的時候,並不包含柔...

c語言深度解剖筆記1

2016.8.14 dage 複習內容 c語言深度解剖筆記1 有三大類 算術運算子 關係運算子與邏輯運算子,還有位運算子等,相同優先順序運算子,從左至右依次運算。注意字尾運算優先順序高於字首。因此 i 應解釋為 i 基本表示式 1級 最高 字尾表示式 2極 單目 一元運算 3級 強制型別表示式 4級...