
0x00 最初的起點(diǎn)
首先是一道爛大街的題目:以下四個(gè)變量有什么區(qū)別?

答案很簡(jiǎn)單:
1. v1是一個(gè)指針常量,即指針?biāo)赶虻闹挡豢筛淖?,但是指針?biāo)赶虻牡刂房梢愿淖儭?/h5>
2. v2和v1相同。
3. v3是一個(gè)常量指針,即指針?biāo)赶虻膬?nèi)存地址不可改變。
4. v4是一個(gè)指向常量的常量指針,即無論是指向的內(nèi)存地址,還是內(nèi)存地址中的值都是不可改變的。
可以看到,這個(gè)基本上就是依靠記憶的東西,并沒有什么理解上的難點(diǎn),只是記住之后沒過一段時(shí)間可能就又混淆了。
記憶方案一
1.如果const位于的左側(cè),則const就是用來修飾指針?biāo)赶虻淖兞浚粗羔樦赶驗(yàn)槌A浚?br> 2.如果const位于的右側(cè),則const就是修飾指針本身,即指針本身是常量。
恩... 似乎很有規(guī)律的樣子,但是我記性很差,這種規(guī)則對(duì)我來說還是太繞,過一段時(shí)間就不確定會(huì)不會(huì)記反了。
記憶方案二
Bjarne在他的The C++ Programming Language里面給出過一個(gè)助記的方法:
把一個(gè)聲明從右向左讀。
char * const cp; ( * 讀成 pointer to )
cp is a const pointer to char
const char * p;
p is a pointer to const char;
恩。這樣確實(shí)大大的降低了記混的情況了,但是雖然這種方法已經(jīng)很簡(jiǎn)單了,但是對(duì)于英語不是母語的人來說,還是需要繞一層的,那么有什么更加簡(jiǎn)單的記憶方法嗎?
記憶方案三
const修飾前面的關(guān)鍵字,只有當(dāng)const開頭時(shí)才修飾后面的關(guān)鍵字
即:當(dāng)const前面是char int之類的類型關(guān)鍵字時(shí),表示修飾的是指針?biāo)赶虻膬?nèi)容;而當(dāng)前面的是指針運(yùn)算符(*)的時(shí)候,那么表示修飾的是該指針;當(dāng)const位于表達(dá)式首位時(shí),請(qǐng)參考第一條。
0X01實(shí)現(xiàn)機(jī)制
其實(shí)const關(guān)鍵字并沒有多么復(fù)雜的實(shí)現(xiàn)方法,只是在編譯器的層面做了modify的限制,而const變量和非const變量在runtime期間其實(shí)并無卵分別,最好的證據(jù)就是編譯過程中的匯編代碼了,證據(jù)如下:
首先我們有兩段簡(jiǎn)單到媽都不認(rèn)得的C++代碼:
代碼一
#include <iostream>
using namespace std;
int main()
{
int a = 100;
return 0;
}
代碼二
#include <iostream>
using namespace std;
int main()
{
const int a = 100;
return 0;
}
這兩段代碼唯一的區(qū)別就是,一個(gè)int變量有const修飾,而另一個(gè)int變量沒有const修飾。OK,接下來我們編譯成匯編,使用下面的命令:
g++ -S demo.cpp
編譯之后得到的匯編代碼對(duì)比圖如下所示:

我們可看到,兩者并無什么不同,也就是說,匯編并不會(huì)對(duì)const的變量做什么特殊的處理,const只是在編譯的層面給程序做了限制。
但是,這里又有一個(gè)問題,當(dāng)我們把代碼修改成下面那樣的時(shí)候:
代碼一
#include <iostream>
using namespace std;
int main()
{
int a = 100;
cout << a << endl;
return 0;
}
代碼二
#include <iostream>
using namespace std;
int main()
{
const int a = 100;
cout << a << endl;
return 0;
}
這里的代碼與上面的代碼的區(qū)別無非是,訪問了a的值,按照上面的理論,編譯后的代碼應(yīng)該沒有不同,但是世事難料,對(duì)比圖如下:

我們可以看到竟然還是存在差別的,但是根據(jù)查閱資料和個(gè)人猜測(cè),我認(rèn)為可能的原因是:const的變量存儲(chǔ)的時(shí)候確實(shí)沒有特殊處理,但是在取值時(shí),并不會(huì)訪問const變量的內(nèi)存地址,而是通過一個(gè)全局符號(hào)表(symbol table)替換了該值,所以才會(huì)出現(xiàn)這樣的匯編代碼的差別。
0X02 最后說的話
說到底還是不懂匯編,有空也可以研究一下,如果有匯編大神路過,也請(qǐng)不吝賜教!