最近複習的過程中發現網上對於const的說法不一,讓人摸不著頭腦,為了搞清其原理,決定通過反彙編的方式來看一看其內部究竟發生了什麼,下面是一篇簡單的介紹反彙編指令的文章,用來理解本次所研究的東西已經足夠
下面將按照乙個觀點乙個例子的方式來進行:(該測試基於vs2017環境)
1.將字面值賦給const變數時,會在編譯期間將程式中用到該變數的地方替換成對應的數值(類似於巨集替換),同時該變數在記憶體中分配空間,通過指標也可以對該變數的內容進行更改,但不會影響到程式中使用const變數的地方,因為程式真正執行的時候,const變數所在的地方已經替換成了字面值,例如
其反彙編的結果為:
從結果分析可知,
在1處,程式將字面值0ch直接賦值給了x變數
在2處,程式通過指標訪問x變數的位址,將0dh賦值給了x所在的記憶體位置
其過程可由下圖看出
執行前:
執行後:
在3處,程式通過訪問x變數所在的記憶體位址將值取出並賦給變數b
在4處,本應將x變數的值賦給變數c,但在反彙編結果中可見,程式將字面值0ch直接賦給了變數c,而沒有通過位址取值
2.若通過乙個變數賦值給乙個const變數,那麼上面的說法將不再成立,經過試驗發現,此種情況下const限制只對變數名訪問有效,對於指標修改的方式並不能起到限制寫的作用,試驗過程如下:
#include//此**相對於上乙個例子只是將x變數賦值的方式改變,其餘位置不變
其反彙編的結果為:
此次反彙編結果僅1,2兩處與先前不同,中間部分一致,不再贅述
從結果分析可知:
通過變數賦值方式初始化的const變數,其賦值時需要訪問原變數的位址
通過此方式初始化的const變數,在使用時也會到記憶體中取它的值,而不會像上乙個例子中一樣做巨集替換
3.****現字串的地方都會在記憶體常量區中儲存,若同乙個字串在**中多次出現,編譯器會自動識別,不會重複產生同樣的串
#include#includeint main()
其反彙編的結果為:
觀察1.2.4可看出,當程式中使用同乙個字串時,編譯器並不會產生新的串,而是共用一塊位址中的內容,當串不同時,才會在常量區中儲存新的串
觀察2.3並結合圖二可看出,當使用指標指向常量區中的位址時,由於常量區的內容本身就是不可更改的,因此,用不用const都是一樣的,即使強制型別轉換為普通指標修改了其中的內容,也會在執行時產生異常
觀察2.4可看出,使用指標指向常量時,指標變數記憶體入的是常量區中常量的位址值,而使用字元陣列儲存字串時,編譯器會將常量區中的常量複製乙份賦給棧中的字元陣列空間
c 中關於const的一些細節問題
const是一件奇妙的事情,它指定乙個語義約束,而編譯器會強制執行這項約束,它允許你告訴編譯器或者其他程式設計師某值應該保持不變。你可以用const修飾class內部的static和non static成員變數,你也可以指出指標之身或者是指標所指物,或者兩個都是。比如 char greeting h...
關於C 中const 返回型別的一些看法
看下面這段 class cpentry class a int main 上面的這段 在編譯時沒有任何的警告,執行時也不會出現問題。但當cpentry有乙個指標型別的變數時就可能會引發無效指標問題。再看下面這段 class cpentry class a int main printf s test...
關於const的一些知識
首先來看幾個句子 1 const int a 2 int const a 3 const int a 4 int const a 5 int const a const 1和2的作用是一樣的 a是乙個整形常數。3說明a是乙個指向整形常數的指標 雖然整形常數不可修改,但指標可以修改的 4的意思是a是乙...