1.指針的應(yīng)用場(chǎng)景
交換兩個(gè)變量的值(只能由指針完成)践盼;
函數(shù)返回多個(gè)值,某些值就只能通過(guò)指針?lè)祷?/b>(傳入的參數(shù)實(shí)際上是需要保存帶回的結(jié)果的變量)函數(shù)結(jié)果不止一個(gè)宾巍,通過(guò)指針把要接收的結(jié)果變量的地址傳進(jìn)去,函數(shù)把結(jié)果變量填好傳回值渔伯;
函數(shù)返回運(yùn)算的狀態(tài)顶霞,結(jié)果通過(guò)指針?lè)祷亍?/b>常用的套路是讓函數(shù)返回特殊的不屬于有效范圍的值來(lái)表示出錯(cuò)(-1或0,在文件操作會(huì)看到大量的例子)锣吼。但是當(dāng)任何數(shù)值都是有效的可能結(jié)果時(shí)选浑,就得分開(kāi)返回了。狀態(tài)用 return 玄叠,值用指針古徒。后續(xù)的語(yǔ)言(C++ ,Java)采用了異常機(jī)制來(lái)解決這個(gè)問(wèn)題读恃。
2.指針最常見(jiàn)的錯(cuò)誤
定義了指針變量隧膘,還沒(méi)有指向任何變量,就開(kāi)始使用指針寺惫。
所有本地變量都不會(huì)有默認(rèn)的初始值疹吃,若未賦值,本地變量里什么都沒(méi)有西雀。
任何一個(gè)地址變量萨驶,沒(méi)有被賦值之前,沒(méi)有得到任何變量的地址之前艇肴,不能通過(guò)*訪問(wèn)任何的變量和數(shù)據(jù)腔呜。
3.傳入函數(shù)的數(shù)組成了什么?
普通變量傳入函數(shù)再悼,接收到的是值核畴;指針傳入函數(shù),接收到的是指針的值帮哈,代表外面的變量膛檀。
為什么函數(shù)參數(shù)表里面的數(shù)組在函數(shù)里頭必須留一個(gè)空的方括號(hào)?為什么方括號(hào)里寫(xiě)數(shù)字也沒(méi)用?為什么函數(shù)里沒(méi)有辦法用 sizeof 得到正確的元素個(gè)數(shù)咖刃?
函數(shù)參數(shù)表中的數(shù)組實(shí)際上是指針泳炉,樣子看上去像一個(gè)數(shù)組,函數(shù)頭可以把它寫(xiě)成指針類型嚎杨,編譯通過(guò)花鹅,運(yùn)行正確。對(duì)于函數(shù)參數(shù)中的數(shù)組的 sizeof 枫浙,返回的是 int* 的 sizeof 而不是數(shù)組的刨肃。函數(shù)參數(shù)里的數(shù)組,與 main 中的數(shù)組地址相同箩帚,是同樣的地址代表同一個(gè)數(shù)組真友。
sizeof(a)==sizeof(int*)。但是可以用數(shù)組的運(yùn)算符 [ ] 進(jìn)行運(yùn)算紧帕。
以下4種函數(shù)原型是等價(jià)的:
int sum( int *ar盔然,int n );? ? int sum( int *是嗜,int ?)愈案;
int sum( int ar[ ],int n )鹅搪;? ? int sum( int [ ]站绪,int? );
4.數(shù)組變量是特殊的指針
數(shù)組變量本身表達(dá)地址丽柿。所以 int a[10]; int *p=a; 無(wú)需用&取地址恢准。
但是數(shù)組的單元表達(dá)的是變量,需要用&取地址航厚。a==&a[0];
[ ] 運(yùn)算符可以對(duì)數(shù)組做顷歌,也可以對(duì)指針做。p[0] 相當(dāng)于 a[0]幔睬。把 p (指針變量)所指的地方當(dāng)作是個(gè)數(shù)組眯漩,可認(rèn)為是長(zhǎng)度為1的數(shù)組。
* 運(yùn)算符可以對(duì)指針做麻顶,也可以對(duì)數(shù)組做赦抖。
數(shù)組變量是 const 指針,所以不能被賦值辅肾。數(shù)組變量間不能做互相賦值队萤。
int b[] ;相當(dāng)于 int* const b矫钓; ?b是常數(shù)要尔,不能被改變舍杜,不能代表別的數(shù)組,是一個(gè)常量指針赵辕。
5.指針與 const
指針可以是 const 既绩,指針指向的值可以是 const 。
指針是 const 表示一旦得到了某個(gè)變量的地址还惠,不能再指向其他變量(關(guān)系永久)饲握。
int *const q = &i; // q 是 const, q 的值不能被改變。
*q = 26;// OK ? ? q++;// ERROR
所指是 const 表示不能通過(guò)這個(gè)指針去修改那個(gè)變量(并不能使得那個(gè)變量成為 const)蚕键。
const int *p = &i; ? ?*p = 26;// ERROR! ( *p )是 const 救欧,不能通過(guò) p 做賦值。
i = 26; // OK i 可修改 ? ? p = &j ; ?// OK ?p 可修改
判斷哪個(gè)被 const 的標(biāo)志是 const 在 * 的前面還是后面锣光。
const 在 * 的前面表示所指是 const ,不能通過(guò)指針修改變量笆怠。
const 在 * 的后面表示指針是 const ,指針不能被修改。
6.轉(zhuǎn)換
總是可以把一個(gè)非 const 的值轉(zhuǎn)換成 const 的誊爹。
void f ( const int* x) 骑疆,將 x 用指針的方式傳進(jìn)去,傳 const 指針替废。表示在函數(shù)內(nèi)部不改變指針?biāo)傅闹担荒芡ㄟ^(guò)指針修改變量泊柬。
當(dāng)要傳遞的參數(shù)的類型比地址大的時(shí)候椎镣,這是常用的手段:既能用比較少的字節(jié)數(shù)傳遞值給參數(shù),又能避免函數(shù)對(duì)外面的變量的修改兽赁。
7. const 數(shù)組
const int a[ ] = { 1,2,3,4,5,6 };
數(shù)組變量已經(jīng)是 const 的指針了状答,這里的 const 表明數(shù)組的每個(gè)單元都是 const int 。
所以必須通過(guò)初始化進(jìn)行賦值刀崖。
8.保護(hù)數(shù)組值
因?yàn)榘褦?shù)組傳入函數(shù)時(shí)惊科,傳入的是地址,所以那個(gè)函數(shù)內(nèi)部可以修改數(shù)組的值亮钦。
為了保護(hù)數(shù)組不被破壞馆截,可以設(shè)置參數(shù)為 const 。
int sum( const int a[ ] , int length );