如何判斷常量指針(constant pointer)和指針常量(pointer to a constant)是件很頭疼的事,如果是一級指針還好,可以強行記住三種形式,如果是多級指針,那就等着受虐吧。我們先看看教科書的技巧
1. 教科書的方法
Bjarne在他的The C++ Programming Language裡面給出過一個助記的方法:
把一個聲明從右向左讀。
char * const cp; ( * 讀成 pointer to )
cp is a const pointer to char
const char * p;
p is a pointer to const char;
2. 技巧
當定義二級三級甚至多級指針常量/常量指針,用上面的方法就會很複雜。
定義指針常量/常量指針無非是*和const修飾符的位置進行排列,我自己觀察到一個規律:
const修飾符和變量名之間有幾個*,那麼在用這麼多*解引用時,就不能改變這個值。
- 例如,
char * const p1 = &ch1; /* (1)第一種形式 */ const和變量名p1之間有個*,那麼p1 = &ch2;這樣就是錯的。
- 再如,
char const *p2 = &ch2; /*(2)第二種形式*/ const char *p2 = &ch2; /*(3)第三種形式*/ const和變量名p2之間有一個*,那麼*p='b';這樣就是錯的,
- 再舉一個複雜一點的例子,
char ch1 = 'a'; char ch2 = 'b'; char *p1 = &ch1; char *p2 = &ch2; const char **pp = &p1; 因為const到變量名pp之間有個*,那麼**pp = 'b';這樣就是錯的。而, *pp = &ch2;或 pp = &p2;這樣都是對的。
- 更進階的例子,
char ch1 = 'a'; char ch2 = 'b'; char *p1 = &ch1; char *p2 = &ch2; char * const *pp = &p1; 因為const到變量名pp之間有個*,那麼*pp = &ch2;這樣就是錯的。而, **pp = ch2;或 pp = &p2;這樣都是對的。
- 掌握了這個規律,再看谷歌的這道面試題是不是很簡單呢。
[題目]
const char *p="hello"; foo(&p);//函數foo(const char **pp)
下面說法正确的是[]
A.函數foo()不能改變p指向的字元串内容
B.函數foo()不能使指針p指向malloc生成的位址
C.函數foo()可以使p指向新的字元串常量
D.函數foo()可以把p指派為 NULL.
解答:
foo函數的形參類型是const char **pp; 利用上面所說的規律,隻有**pp = ‘w’;這樣通路是不行的。其它都可以,是以答案是ACD。
實際上,即使foo函數聲明成這樣,A也是錯的:foo(char **pp);
原因是,p指向的字元串”hello”是存在放常量區的,不能改變。是以我們用字元串字面值給字元指針指派的時候,一般都将字元指針定義成指針常量:
const char *p = "hello";
*p = 'w'; /*編譯錯誤!*/
char *q = "hello";
*q = 'w'; /*編譯正确,運作時錯誤!*/
3. 總結
最近再整CSDN排名,如果本篇部落格對你有用就評論一下幫我刷個積分吧。