const int * pi 、int const * pi與int * const pi及其操作
1 從const int i 說起
你知道我們申明一個(gè)變量時(shí)象這樣int i ;這個(gè)i是可能在它處重新變賦值的。如下:
int i=0;
//…
i=20;//這里重新賦值了
不過有一天我的程序可能需要這樣一個(gè)變量(暫且稱它變量),在申明時(shí)就賦一個(gè)初始值。之后我的程序在其它任何處都不會(huì)再去重新對它賦值。那我又應(yīng)該怎么辦呢?用const 。
//**************
const int ic =20;
//…
ic=40;//這樣是不可以的,編譯時(shí)是無法通過,因?yàn)槲覀儾荒軐?/span>const 修飾的ic重新賦值的。
//這樣我們的程序就會(huì)更早更容易發(fā)現(xiàn)問題了。
//**************
有了const修飾的ic 我們不稱它為變量,而稱符號(hào)常量,代表著20這個(gè)數(shù)。這就是const 的作用。ic是不能在它處重新賦新值了。
認(rèn)識(shí)了const 作用之后,另外,我們還要知道格式的寫法。有兩種:const int ic=20;與int const ic=20;。它們是完全相同的。這一點(diǎn)我們是要清楚??傊?,你務(wù)必要記住const 與int哪個(gè)寫前都不影響語義。有了這個(gè)概念后,我們來看這兩個(gè)家伙:const int * pi與int const * pi ,按你的邏輯看,它們的語義有不同嗎?呵呵,你只要記住一點(diǎn),int 與const 哪個(gè)放前哪個(gè)放后都是一樣的,就好比const int ic;與int const ic;一樣。也就是說,它們是相同的。
好了,我們現(xiàn)在已經(jīng)搞定一個(gè)“雙包胎”的問題。那么int * const pi與前兩個(gè)式子又有什么不同呢?我下面就來具體分析它們的格式與語義吧!
2 const int * pi的語義
我先來說說const int * pi是什么作用 (當(dāng)然int const * pi也是一樣的,前面我們說過,它們實(shí)際是一樣的)。看下面的例子:
//*************代碼開始***************
int i1=30;
int i2=40;
const int * pi=&i1;
pi=&i2; //4.注意這里,pi可以在任意時(shí)候重新賦值一個(gè)新內(nèi)存地址
i2=80; //5.想想看:這里能用*pi=80;來代替嗎?當(dāng)然不能
printf( “%d”, *pi ) ; //6.輸出是80
//*************代碼結(jié)束***************
語義分析:
看出來了沒有啊,pi的值是可以被修改的。即它可以重新指向另一個(gè)地址的,但是,不能通過*pi來修改i2的值。這個(gè)規(guī)則符合我們前面所講的邏輯嗎?當(dāng)然符合了!
首先const 修飾的是整個(gè)*pi(注意,我寫的是*pi而不是pi)。所以*pi是常量,是不能被賦值的(雖然pi所指的i2是變量,不是常量)。
其次,pi前并沒有用const 修飾,所以pi是指針變量,能被賦值重新指向另一內(nèi)存地址的。你可能會(huì)疑問:那我又如何用const 來修飾pi呢?其實(shí),你注意到int * const pi中const 的位置就大概可以明白了。請記住,通過格式看語義。
3 再看int * const pi
確實(shí),int * const pi與前面的int const * pi會(huì)很容易給混淆的。注意:前面一句的const 是寫在pi前和*號(hào)后的,而不是寫在*pi前的。很顯然,它是修飾限定pi的。我先讓你看例子:
//*************代碼開始***************
int i1=30;
int i2=40;
int * const pi=&i1;
//pi=&i2; 4.注意這里,pi不能再這樣重新賦值了,即不能再指向另一個(gè)新地址。
//所以我已經(jīng)注釋了它。
i1=80; //5.想想看:這里能用*pi=80;來代替嗎?可以,這里可以通過*pi修改i1的值。
//請自行與前面一個(gè)例子比較。
printf( “%d”, *pi ) ; //6.輸出是80
//***************代碼結(jié)束*********************
語義分析:
看了這段代碼,你明白了什么?有沒有發(fā)現(xiàn)pi值是不能重新賦值修改了。它只能永遠(yuǎn)指向初始化時(shí)的內(nèi)存地址了。相反,這次你可以通過*pi來修改i1的值了。與前一個(gè)例子對照一下吧!看以下的兩點(diǎn)分析
1). pi因?yàn)橛辛?/span>const 的修飾,所以只是一個(gè)指針常量:也就是說pi值是不可修改的(即pi不可以重新指向i2這個(gè)變量了)(看第4行)。
2). 整個(gè)*pi的前面沒有const 的修飾。也就是說,*pi是變量而不是常量,所以我們可以通過*pi來修改它所指內(nèi)存i1的值(看5行的注釋)
總之一句話,這次的pi是一個(gè)指向int變量類型數(shù)據(jù)的指針常量。
我最后總結(jié)兩句:
1).如果const 修飾在*pi前則不能改的是*pi(即不能類似這樣:*pi=50;賦值)而不是指pi。
2).如果const 是直接寫在pi前則pi不能改(即不能類似這樣:pi=&i;賦值)。
請你務(wù)必先記住這兩點(diǎn),相信你一定不會(huì)再被它們給搞糊了。
3.補(bǔ)充三種情況。
這里,我再補(bǔ)充以下三種情況。其實(shí)只要上面的語義搞清楚了,這三種情況也就已經(jīng)被包含了。不過作為三種具體的形式,我還是簡單提一下吧!
情況一:int * pi指針指向const int i常量的情況
//**********begin*****************
const int i1=40;
int *pi;
pi=&i1; //這樣可以嗎?不行,VC下是編譯錯(cuò)。
//const int 類型的i1的地址是不能賦值給指向int 類型地址的指針pi的。否則pi豈不是能修改i1的值了嗎!
pi=(int* ) &i1; // 這樣可以嗎?強(qiáng)制類型轉(zhuǎn)換可是C所支持的。
//VC下編譯通過,但是仍不能通過*pi=80來修改i1的值。去試試吧!看看具體的怎樣。
//***********end***************
情況二:const int * pi指針指向const int i1的情況
//*********begin****************
const int i1=40;
const int * pi;
pi=&i1;//兩個(gè)類型相同,可以這樣賦值。很顯然,i1的值無論是通過pi還是i1都不能修改的。
//*********end*****************
情況三:用const int * const pi申明的指針
//***********begin****************
int i
const int * const pi=&i;//你能想象pi能夠作什么操作嗎?pi值不能改,也不能通過pi修改i的值。因?yàn)椴还苁?/span>*pi還是pi都是const的。
//************end****************
第一部分:http://hi.baidu.com/sky_space/blog/item/7a9c2212a266a45bf919b817.html
第二部分:http://hi.baidu.com/sky_space/blog/item/25e8688da6f22d18b21bba1f.html
第三部分:http://hi.baidu.com/sky_space/blog/item/41b3ca091d5b8888d0581b1f.html
聯(lián)系客服