青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

woaidongmao

文章均收錄自他人博客,但不喜標(biāo)題前加-[轉(zhuǎn)貼],因其丑陋,見諒!~
隨筆 - 1469, 文章 - 0, 評論 - 661, 引用 - 0
數(shù)據(jù)加載中……

如何理解c和c ++的復(fù)雜類型聲明

曾經(jīng)碰到過讓你迷惑不解、類似于int * (* (*fp1) (int) ) [10];這樣的變量聲明嗎?本文將由易到難,一步一步教會你如何理解這種復(fù)雜的C/C++聲明。

  我們將從每天都能碰到的較簡單的聲明入手,然后逐步加入const修飾符和typedef,還有函數(shù)指針,最后介紹一個能夠讓你準(zhǔn)確地理解任何C/C++聲明的右左法則

  需要強(qiáng)調(diào)一下的是,復(fù)雜的C/C++聲明并不是好的編程風(fēng)格;我這里僅僅是教你如何去理解這些聲明。注意:為了保證能夠在同一行上顯示代碼和相關(guān)注釋,本文最好在至少1024x768分辨率的顯示器上閱讀。
讓我們從一個非常簡單的例子開始,如下:

int n;



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

int *p;



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

char **argv;



理論上,對于指針的級數(shù)沒有限制,你可以定義一個浮點(diǎn)類型變量的指針的指針的指針的指針,再來看如下的聲明:

int RollNum[30][4];

int (*p)[4]=RollNum;

int *q[5];

這里,p被聲明為一個指向一個4元素(int類型)數(shù)組的指針,而q被聲明為一個包含5個元素(int類型的指針)的數(shù)組。另外,我們還可以在同一個聲明中混合實(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類型引用的引用(不合法!)。

const
修飾符

當(dāng)你想阻止一個變量被改變,可能會用到const關(guān)鍵字。在你給一個變量加上const修飾符的同時,通常需要對它進(jìn)行初始化,因?yàn)橐院蟮娜魏螘r候你將沒有機(jī)會再去改變它。例如:

const int n=5;

int const m=10;



上述兩個變量nm其實(shí)是同一種類型的——都是const int(整形恒量)。因?yàn)?span lang="EN-US">C++標(biāo)準(zhǔn)規(guī)定,const關(guān)鍵字放在類型或變量名之前等價的。我個人更喜歡第一種聲明方式,因?yàn)樗怀隽?span lang="EN-US">const修飾符的作用。當(dāng)const與指針一起使用時,容易讓人感到迷惑。例如,我們來看一下下面的pq的聲明:

const int *p;

int const *q;



他們當(dāng)中哪一個代表const int類型的指針(const直接修飾int),哪一個代表int類型的const指針(const直接修飾指針)?實(shí)際上,pq都被聲明為const int類型的指針。而int類型的const指針應(yīng)該這樣聲明: 

int * const r= &n;

// n has been declared as an int



這里,pq都是指向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



下面給出的一些關(guān)于const的聲明,將幫助你徹底理清const的用法。不過請注意,下面的一些聲明是不能被編譯通過的,因?yàn)樗麄冃枰诼暶鞯耐瑫r進(jìn)行初始化。為了簡潔起見,我忽略了初始化部分;因?yàn)榧尤氤跏蓟a的話,下面每個聲明都將增加兩行代碼。

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
的妙用

typedef
給你一種方式來克服“*只適合于變量而不適合于類型的弊端。你可以如下使用typedef

typedef char * PCHAR;

PCHAR p,q;



這里的pq都被聲明為指針。(如果不使用typedefq將被聲明為一個char變量,這跟我們的第一眼感覺不太一致!)下面有一些使用typedef的聲明,并且給出了解釋:

typedef char * a;

// a is a pointer to a char

 

typedef a b();

// b is a function that returns

// a pointer to a char

 

typedef b *c;

// c is a pointer to a function

// that returns a pointer to a char

 

typedef c d();

// d is a function returning

// a pointer to a function

// that returns a pointer to a char

 

typedef d *e;

// e is a pointer to a function

// returning a pointer to a

// function that returns a

// pointer to a char

 

e var[10];

// var is an array of 10 pointers to

// functions returning pointers to

// functions returning pointers to chars.



typedef
經(jīng)常用在一個結(jié)構(gòu)聲明之前,如下。這樣,當(dāng)創(chuàng)建結(jié)構(gòu)變量的時候,允許你不使用關(guān)鍵字struct(在C中,創(chuàng)建結(jié)構(gòu)變量時要求使用struct關(guān)鍵字,如struct tagPOINT a;而在C++中,struct可以忽略,如tagPOINT b)。

typedef struct tagPOINT

{

  int x;

  int y;

}POINT;

 

POINT p; /* Valid C code */

函數(shù)指針

函數(shù)指針可能是最容易引起理解上的困惑的聲明。函數(shù)指針在DOS時代寫TSR程序時用得最多;在Win32X-Windows時代,他們被用在需要回調(diào)函數(shù)的場合。當(dāng)然,還有其它很多地方需要用到函數(shù)指針:虛函數(shù)表,STL中的一些模板,Win NT/2K/XP系統(tǒng)服務(wù)等。讓我們來看一個函數(shù)指針的簡單例子:




int (*p)(char);



這里p被聲明為一個函數(shù)指針,這個函數(shù)帶一個char類型的參數(shù),并且有一個int類型的返回值。另外,帶有兩個float類型參數(shù)、返回值是char類型的指針的指針的函數(shù)指針可以聲明如下:

char ** (*p)(float, float);



那么,帶兩個char類型的const指針參數(shù)、無返回值的函數(shù)指針又該如何聲明呢?參考如下:

void * (*a[5])(char * const, char * const);



右左法則是一個簡單的法則,但能讓你準(zhǔn)確理解所有的聲明。這個法則運(yùn)用如下:從最內(nèi)部的括號開始閱讀聲明,向右看,然后向左看。當(dāng)你碰到一個括號時就調(diào)轉(zhuǎn)閱讀的方向。括號內(nèi)的所有內(nèi)容都分析完畢就跳出括號的范圍。這樣繼續(xù),直到整個聲明都被分析完畢。

對上述右左法則做一個小小的修正:當(dāng)你第一次開始閱讀聲明的時候,你必須從變量名開始,而不是從最內(nèi)部的括號。

下面結(jié)合例子來演示一下右左法則的使用。

int * (* (*fp1) (int) ) [10];



閱讀步驟:

1.
從變量名開始——fp1

2.
往右看,什么也沒有,碰到了),因此往左看,碰到一個*——一個指針

3.
跳出括號,碰到了(int)——一個帶一個int參數(shù)的函數(shù)

4.
向左看,發(fā)現(xiàn)一個*——(函數(shù))返回一個指針

5.
跳出括號,向右看,碰到[10]——一個10元素的數(shù)組

6.
向左看,發(fā)現(xiàn)一個*——指針

7.
向左看,發(fā)現(xiàn)int——int類型

總結(jié):fp1被聲明成為一個函數(shù)的指針,該函數(shù)返回指向指針數(shù)組的指針.

再來看一個例子:

int *( *( *arr[5])())();



閱讀步驟:

1.
從變量名開始——arr

2.
往右看,發(fā)現(xiàn)是一個數(shù)組——一個5元素的數(shù)組

3.
向左看,發(fā)現(xiàn)一個*——指針

4.
跳出括號,向右看,發(fā)現(xiàn)()——不帶參數(shù)的函數(shù)

5.
向左看,碰到*——(函數(shù))返回一個指針

6.
跳出括號,向右發(fā)現(xiàn)()——不帶參數(shù)的函數(shù)

7.
向左,發(fā)現(xiàn)*——(函數(shù))返回一個指針

8.
繼續(xù)向左,發(fā)現(xiàn)int——int類型

還有更多的例子:

float ( * ( *b()) [] )();

// b is a function that returns a

// pointer to an array of pointers

// to functions returning floats.

void * ( *c) ( char, int (*)());

// c is a pointer to a function that takes

// two parameters:

// a char and a pointer to a

// function that takes no

// parameters and returns

// an int

// and returns a pointer to void.

void ** (*d) (int &,

char **(*)(char *, char **));

// d is a pointer to a function that takes

// two parameters:

// a reference to an int and a pointer

// to a function that takes two parameters:

// a pointer to a char and a pointer

// to a pointer to a char

// and returns a pointer to a pointer

// to a char

// and returns a pointer to a pointer to void

float ( * ( * e[10])

  (int &) ) [5];

// e is an array of 10 pointers to

// functions that take a single

// reference to an int as an argument

// and return pointers to

// an array of 5 floats.

 

posted on 2008-11-07 22:45 肥仔 閱讀(470) 評論(0)  編輯 收藏 引用 所屬分類: C++ 基礎(chǔ)

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲人成欧美中文字幕| 欧美伦理91i| 一区二区三区在线视频播放| 亚洲自拍啪啪| 欧美理论电影在线观看| 久久精品亚洲精品| 欧美日韩一区在线视频| 欧美国产一区二区在线观看| 在线日韩日本国产亚洲| 欧美一级久久久| 欧美一级午夜免费电影| 久久综合图片| 欧美激情影音先锋| 亚洲第一级黄色片| 久久精品中文字幕免费mv| 免费欧美在线| 在线免费观看日本欧美| 欧美一区二区三区视频免费| 午夜精品免费| 亚洲少妇在线| 欧美亚洲专区| 国产精品久久久久久久9999| 日韩视频在线一区二区三区| 欧美成人一区二区三区| 亚洲黄色片网站| 亚洲三级影片| 免费成人高清| 亚洲黄色性网站| 国产亚洲成av人在线观看导航| 亚洲永久字幕| 亚洲精品在线观看视频| 欧美wwwwww| 免费成人黄色| 亚洲精品中文在线| 一区二区三区精品国产| 亚洲图片在线| 国产一区二区三区网站| 欧美一级免费视频| 一本久道久久久| 亚洲日本久久| 日韩亚洲成人av在线| 欧美精选午夜久久久乱码6080| 欧美激情一区二区久久久| 国产在线不卡精品| 欧美成人免费在线视频| 亚洲精品永久免费| 亚洲免费网站| 亚洲一级在线| 男人的天堂成人在线| 亚洲国产精品成人| 欧美日本在线视频| 欧美一区二区视频在线观看| 狂野欧美性猛交xxxx巴西| 亚洲国产精品高清久久久| 欧美黄色一级视频| 亚洲欧美久久久| 久久久夜精品| 亚洲三级观看| 国产精品日韩欧美一区| 久久福利电影| 亚洲激情另类| 久久亚洲国产精品日日av夜夜| 亚洲国产综合视频在线观看| 欧美区二区三区| 小辣椒精品导航| 99re66热这里只有精品3直播| 欧美一区三区三区高中清蜜桃| 伊人影院久久| 国产精品久久久久久久久久ktv | 亚洲高清三级视频| 欧美久久99| 99在线精品视频| 欧美成人午夜免费视在线看片| 一区二区三区久久久| 国产欧美一区二区精品性| 久久精品一二三区| 亚洲自拍三区| 亚洲人成小说网站色在线| 欧美亚洲尤物久久| 亚洲午夜在线观看视频在线| 国内久久婷婷综合| 国产精品v一区二区三区| 久久久午夜视频| 欧美一二三区精品| 99热在线精品观看| 欧美成人高清| 老司机67194精品线观看| 亚洲女同同性videoxma| 亚洲毛片在线| 国产一区二区电影在线观看| 欧美亚州韩日在线看免费版国语版| 久久露脸国产精品| 亚洲欧美日韩视频一区| 亚洲影院色在线观看免费| 亚洲国产另类精品专区| 久久精品视频va| 一区二区三区久久精品| 亚洲精品在线观看免费| 在线日本高清免费不卡| 国产欧美短视频| 欧美高清在线观看| 欧美ab在线视频| 久久综合久久美利坚合众国| 欧美影院成人| 久久久91精品国产一区二区三区| 亚洲女人天堂成人av在线| 亚洲乱码一区二区| 噜噜噜91成人网| 你懂的国产精品| 免费观看成人| 影音先锋另类| 欧美wwwwww| 欧美精品在线播放| 亚洲精品一区二区三区不| 亚洲国产精品久久| 亚洲第一精品在线| 亚洲激情影院| 一级成人国产| 亚洲欧美另类综合偷拍| 午夜视频久久久| 久久青草欧美一区二区三区| 乱人伦精品视频在线观看| 欧美国产高清| 欧美午夜片在线观看| 国产精品自拍在线| 韩国v欧美v日本v亚洲v| 亚洲国产视频a| 亚洲视频观看| 久久国产主播精品| 欧美国产日韩二区| 亚洲国产精品嫩草影院| 欧美激情中文字幕一区二区| 欧美成人精品三级在线观看| 欧美成人精品在线观看| 亚洲黑丝在线| 亚洲天堂av综合网| 欧美在线综合| 欧美大片免费久久精品三p| 欧美视频在线免费| 国内自拍视频一区二区三区| 日韩视频在线一区| 欧美尤物巨大精品爽| 欧美激情麻豆| 正在播放亚洲一区| 久久久爽爽爽美女图片| 欧美色区777第一页| 国产一区二区三区四区老人| 亚洲激情在线观看视频免费| 亚洲综合欧美日韩| 欧美国产视频日韩| 亚洲综合国产| 欧美国产一区视频在线观看| 国产日产欧美a一级在线| 亚洲精选在线观看| 久久久噜噜噜久久中文字幕色伊伊 | 欧美h视频在线| 欧美日韩在线一区| 极品av少妇一区二区| 亚洲夜间福利| 欧美国产日韩精品| 欧美一区二区三区视频免费播放| 欧美日韩国产成人在线91| 国产日韩欧美综合在线| 夜夜爽av福利精品导航| 蜜桃久久精品乱码一区二区| 亚洲午夜电影网| 欧美人与禽性xxxxx杂性| 在线播放亚洲| 久久久久国内| 亚洲欧美国产高清va在线播| 欧美日韩国产综合视频在线| 精久久久久久| 欧美一级午夜免费电影| 一本色道久久加勒比88综合| 欧美高清在线观看| 91久久精品一区二区别| 久久一区二区三区四区| 午夜精品成人在线视频| 亚洲精品一品区二品区三品区| 这里只有精品视频在线| 久久亚洲精品一区二区| 一区二区三区国产精品| 欧美激情亚洲视频| 亚洲第一精品夜夜躁人人爽| 久久久777| 国产午夜精品一区二区三区视频| 欧美不卡三区| 久久国产欧美日韩精品| 国产伦精品一区二区三区四区免费| 在线亚洲精品福利网址导航| 亚洲电影一级黄| 免费人成网站在线观看欧美高清| 狠狠色2019综合网| 久久香蕉国产线看观看av| 久久大逼视频| 狠狠久久综合婷婷不卡| 久久夜色撩人精品| 久久综合久色欧美综合狠狠| 伊人狠狠色j香婷婷综合| 免费一级欧美在线大片|