程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 初學者必備:教你理解復雜的C/C++聲明

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

編輯:C++入門知識

曾經碰到過讓你迷惑不解、類似於int * (* (*fp1) (int) ) [10];這樣的變量聲明嗎?本文將由易到難,一步一步教會你如何理解這種復雜的C/C++聲明。我們將從每天都能碰到的較簡單的聲明入手,然後逐步加入const修飾符和typedef,還有函數指針,最後介紹一個能夠讓你准確地理解任何C/C++聲明的“右左法則”。需要強調一下的是,復雜的C/C++聲明並不是好的編程風格;這裡僅僅是教你如何去理解這些聲明。

讓我們從一個非常簡單的例子開始,如下:

int n;

這個應該被理解為“declare n as an int”(n是一個int型的變量)。接下去來看一下指針變量,如下:

int *p;

這個應該被理解為“declare p as an int *”(p是一個int *型的變量),或者說p是一個指向一個int型變量的指針。我想在這裡展開討論一下:我覺得在聲明一個指針(或引用)類型的變量時,最好將*(或&)寫在緊靠變量之前,而不是緊跟基本類型之後。這樣可以避免一些理解上的誤區,比如:

int*  p,q;

第一眼看去,好像是p和q都是int*類型的,但事實上,只有p是一個指針,而q是一個最簡單的int型變量。我們還是繼續我們前面的話題,再來看一個指針的指針的例子:

char **argv;

理論上,對於指針的級數沒有限制,你可以定義一個浮點類型變量的指針的指針的指針的指針,再來看如下的聲明:

int RollNum[30][4]; 

int (*p)[4]=RollNum; 

int *q[5];

這裡,p被聲明為一個指向一個4元素(int類型)數組的指針,而q被聲明為一個包含5個元素(int類型的指針)的數組。另外,我們還可以在同一個聲明中混合實用*和&,如下:

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類型引用的引用(不合法!)。

const修飾符

當你想阻止一個變量被改變,可能會用到const關鍵字。在你給一個變量加上const修飾符的同時,通常需要對它進行初始化,因為以後的任何時候你將沒有機會再去改變它。例如:

const int n=5; 

int const m=10;

上述兩個變量n和m其實是同一種類型的——都是const int(整形恆量)。因為C++標准規定,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的值可以改變)。

組合上述兩種const修飾的情況,我們來聲明一個指向const int類型的const指針,如下:

const int * const p=&n 

// n has been declared as const int

下面給出的一些關於const的聲明,將幫助你徹底理清const的用法。不過請注意,下面的一些聲明是不能被編譯通過的,因為他們需要在聲明的同時進行初始化。為了簡潔起見,我忽略了初始化部分;因為加入初始化代碼的話,下面每個聲明都將增加兩行代碼。

char ** p1; 

//    pointer to    pointer to    char 

const char **p2;

//    pointer to    pointer to const char 

char * const * p3;

//    pointer to const pointer to    char 

const char * const * p4;

//    pointer to const pointer to const char 

char ** const p5;

// const pointer to    pointer to    char 

const char ** const p6;

// const pointer to    pointer to const char 

char * const * const p7;

// const pointer to const pointer to    char 

const char * const * const p8;

// const pointer to const pointer to const char

注:p1是指向char類型的指針的指針;p2是指向const char類型的指針的指針;p3是指向char類型的const指針;p4是指向const char類型的const指針;p5是指向char類型的指針的const指針;p6是指向const char類型的指針的const指針;p7是指向char類型const指針的const指針;p8是指向const char類型的const指針的const指針。

typedef

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved