天天看點

區分指針常量和常量指針的技巧1. 教科書的方法2. 技巧3. 總結

如何判斷常量指針(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排名,如果本篇部落格對你有用就評論一下幫我刷個積分吧。

繼續閱讀