初學者必備:教你理解復雜的C/C++聲明

字號:

曾經碰到過讓你迷惑不解、類似于int * (* (*fp1) (int) ) [10];這樣的變量聲明嗎?本文將由易到難,一步一步教會你如何理解這種復雜的C/C++聲明。我們將從每天都能碰到的較簡單的聲明入手,然后逐步加入const修飾符和typedef,還有函數(shù)指針,最后介紹一個能夠讓你準確地理解任何C/C++聲明的“右左法則”。需要強調一下的是,復雜的C/C++聲明并不是好的編程風格;這里僅僅是教你如何去理解這些聲明。
    讓我們從一個非常簡單的例子開始,如下:
    int n;
    這個應該被理解為“declare n as an int”(n是一個int型的變量)。接下去來看一下指針變量,如下:
    int *p;
    這個應該被理解為“declare p as an int *”(p是一個int *型的變量),或者說p是一個指向一個int型變量的指針。我想在這里展開討論一下:我覺得在聲明一個指針(或引用)類型的變量時,將*(或&)寫在緊靠變量之前,而不是緊跟基本類型之后。這樣可以避免一些理解上的誤區(qū),比如:
    int* p,q;
    第一眼看去,好像是p和q都是int*類型的,但事實上,只有p是一個指針,而q是一個最簡單的int型變量。我們還是繼續(xù)我們前面的話題,再來看一個指針的指針的例子:
    char **argv;
    理論上,對于指針的級數(shù)沒有限制,你可以定義一個浮點類型變量的指針的指針的指針的指針,再來看如下的聲明:
    int RollNum[30][4];
     int (*p)[4]=RollNum;
     int *q[5];
    這里,p被聲明為一個指向一個4元素(int類型)數(shù)組的指針,而q被聲明為一個包含5個元素(int類型的指針)的數(shù)組。另外,我們還可以在同一個聲明中混合實用*和&,如下:
    int **p1;
     // p1 is a pointer to a pointer to an int.
     int *&p2;
     // p2 is a reference to a pointer to an int.
     int &*p3;
     // ERROR: Pointer to a reference is illegal.
     int &&p4;
     // ERROR: Reference to a reference is illegal.
    注:p1是一個int類型的指針的指針;p2是一個int類型的指針的引用;p3是一個int類型引用的指針(不合法?。?;p4是一個int類型引用的引用(不合法?。?BR>    const修飾符
    當你想阻止一個變量被改變,可能會用到const關鍵字。在你給一個變量加上const修飾符的同時,通常需要對它進行初始化,因為以后的任何時候你將沒有機會再去改變它。例如:
    const int n=5;
     int const m=10;
    上述兩個變量n和m其實是同一種類型的——都是const int(整形恒量)。因為C++標準規(guī)定,const關鍵字放在類型或變量名之前等價的。我個人更喜歡第一種聲明方式,因為它更突出了const修飾符的作用。當const與指針一起使用時,容易讓人感到迷惑。例如,我們來看一下下面的p和q的聲明:
    const int *p;
     int const *q;
    他們當中哪一個代表const int類型的指針(const直接修飾int),哪一個代表int類型的const指針(const直接修飾指針)?實際上,p和q都被聲明為const int類型的指針。而int類型的const指針應該這樣聲明:
    int * const r= &n;
     // n has been declared as an int
    這里,p和q都是指向const int類型的指針,也就是說,你在以后的程序里不能改變*p的值。而r是一個const指針,它在聲明的時候被初始化指向變量n(即r=&n;)之后,r的值將不再允許被改變(但*r的值可以改變)。