當(dāng)前位置:首頁 > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > 理解C語言的聲明
1. 理解C語言的聲明
聲明主要由聲明器、類型說明符、類型限定符和存儲屬性組成
1.1. 聲明器(declarator)
1) 指針
* const volatile
* volatile
*
* const
* volatile const
指針的五種限定形式
2) 數(shù)組
類型 標(biāo)識符[下標(biāo)]
3) 函數(shù)
類型 標(biāo)識符(參數(shù)列表)
1.2. 類型說明符
1) void char short int long signed unsigned float double
2) 結(jié)構(gòu)體struct
3) 枚舉enum
4) 聯(lián)合體union
1.3. 類型限定符
1) const
2) volatile可以放在類型前面,也可以放在后面
1.4. 存儲屬性
1) static
2) extern
3) register
4) auto
5) typedef針對標(biāo)識符(名稱)
1.5. 聲明的限制
1) 非法
函數(shù)的返回值不能為函數(shù)
函數(shù)的返回值不能為數(shù)組
數(shù)組中不能有函數(shù)
函數(shù)的參數(shù)不能為函數(shù)
2) 合法
函數(shù)的返回值可以是函數(shù)指針
void (*func(void))(int)
函數(shù)的返回值可以是指向數(shù)組的指針
int(*func(void))[10]
數(shù)組中可以有函數(shù)指針
void (*array[10])(int)
函數(shù)的參數(shù)可以是函數(shù)指針
void func(void (*)(int))
1.6. 聲明組成的優(yōu)先級規(guī)則
1) 從名字開始
2) 優(yōu)先級順序
聲明中被括起來的部分
后綴操作符
括號()表示是一個函數(shù)
方括號[ ]表示是一個數(shù)組
前綴操作符
星號 * 表示是”指向……的指針“
3) const或volatile關(guān)鍵字
如果后面緊跟著類型說明符(如int,long等),則作用于類型說明符
其他情況下,作用于左邊緊鄰的星號 *,表示指針常量(指針不可變)
4) 整體思路
從里往外
從右到左
一找函數(shù)
二找數(shù)組
三找指針
2. 練習(xí)題
詳細解釋說明如下所列的聲明
char *ptr;
char const *ptr;
const char *ptr;
char * const ptr;
char * const *ptr;
int demo1(int);
int *demo2(int);
int (*demo2)(int);
int (*demo3(int))(void);
int (*(*demo4)(int))(void);
int (*(*demo5[10])(int))(void);
int (*(*(*demo6)[10])(int))(void);
int (*(*(*demo7)[10])(void (*cb)(int)))(void);
int (*(*(*const demo8)[10])(void (*cb)(int)))(void);
int * const * (*(*demo9)[10])(void (*cb)(int));
int * const * (*(*demo10)[10])(int (*(*cb)(int))[10]);
習(xí)題分步講解:
char *ptr;
ptr //名稱是ptr
* //ptr是一個指向...的指針
char //char類型的數(shù)據(jù)
/*ptr是一個指向char類型數(shù)據(jù)的指針。*/
char const *ptr;
ptr //名稱是ptr
* //ptr是一個指向...的指針
char const //char類型的const常量
/*ptr是一個指向char類型const常量數(shù)據(jù)的指針。*/
const char *ptr;
ptr //名稱是ptr
* //ptr是一個指向...的指針
const char //char類型的const常量
/*ptr是一個指向char類型const常量數(shù)據(jù)的指針。*/
char * const ptr;
Ptr //名稱是ptr,ptr是一個...
* const //指向...的指針常量
char //char類型數(shù)據(jù)
/*ptr是一個指向char類型數(shù)據(jù)的指針常量。*/
char * const *ptr;
ptr //名稱是ptr
* //ptr是指向...的指針
* const //指向...的指針常量
char //char型數(shù)據(jù)
/*ptr是指向一個指向char型數(shù)據(jù)的指針常量 的指針。*/
int demo1(int);
demo1 //名稱是demo1
int (int); //demo1是一個函數(shù),參數(shù)是int,返回值int
/*demo1是一個帶有一個int型參數(shù),返回值為int類型的函數(shù)。*/
int *demo2(int);
demo2 //名稱是demo2
* (int); //demo2是一個函數(shù),參數(shù)是int,返回一個指向...的指針int //int類型數(shù)據(jù)
/*demo2是一個帶有一個int型參數(shù),返回值為一個指向int類型數(shù)據(jù)的指針。*/
int (*demo2)(int);
demo2 //名稱是demo2,demo2是一個...
* //指向...的指針int ( )(int); //一個函數(shù),參數(shù)是int,返回一個int類型數(shù)據(jù)
/*demo2是一個指向函數(shù)的指針,函數(shù)有一個int類型參數(shù),返回一個int類型數(shù)據(jù)。*/
int (*demo3(int))(void);
demo3 //名稱是demo3
* (int) //demo3是一個函數(shù),參數(shù)是int,返回一個指向...的指針
int ( )(void); //一個函數(shù),參數(shù)是void,返回一個int類型數(shù)據(jù)
/*demo3是一個帶有一個int型參數(shù),返回值為一個沒有參數(shù)的函數(shù),函數(shù)返回值為int的函數(shù)指針。*/
int (*(*demo4)(int))(void);
demo4 //名稱是demo4
* //demo4是指向...的指針
*( )(int) //一個函數(shù),參數(shù)int,返回指向...的指針
int ( )(void); //一個函數(shù),無參數(shù),返回int
/*demo4是指向一個帶有一個int型參數(shù),返回一個無參數(shù)返回值為int的函數(shù)指針的函數(shù)的指針。*/
int (*(*demo5[10])(int))(void);
demo5 //名稱是demo5
[10] //demo5是一個有10個...類型數(shù)據(jù)元素的數(shù)組
* //指向...的指針
*( )(int) //一個函數(shù),參數(shù)是int,返回一個指向...的指針
int ( )(void); //一個函數(shù),無參數(shù),返回一個int類型的數(shù)據(jù)
/*demo5是一個有10個函數(shù)指針為元素的指針數(shù)組,指針數(shù)組元素指向的函數(shù)是帶有一個int型參數(shù),返回一個無參數(shù)返回值為int的函數(shù)指針的函數(shù)。*/
int (*(*(*demo6)[10])(int))(void);
demo6 //名稱是demo6
* //demo6是一個指向...的指針
*( )[10] //有10個元素的數(shù)組,數(shù)組元素類型是指向...的指針
*( )(int) //一個函數(shù),參數(shù)是int,返回一個指向...的指針
int ( )(void); //一個函數(shù),無參數(shù),返回一個int類型的數(shù)據(jù)
int (*(*(*demo7)[10])(void (*cb)(int)))(void);
demo7 //名稱demo7
* //demo7是一個指向...的指針
*( )[10] //有10個元素的數(shù)組,數(shù)據(jù)元素類型是指向...的指針
*( )( . . . . ) //一個函數(shù),參數(shù)是...,返回值為一個指向...的指針
*( )( * ) //一個函數(shù),參數(shù)是一個指向...的指針,返回值為一個指向...的指針
*( )(void ( )(int)) //一個函數(shù),參數(shù)是一個指向一個函數(shù)(參數(shù)int)的指針,返回值為一個指向...的指針
int ( )(void); //一個函數(shù),無參數(shù),返回值為int類型數(shù)據(jù)
/*demo7是一個指向有10個函數(shù)指針為元素的數(shù)組的指針,指針數(shù)組元素指向的函數(shù)是以一個帶一個int型參數(shù)返回為空的函數(shù)指針為參數(shù),返回一個無參數(shù)返回值為int的函數(shù)指針的函數(shù)。*/
int (*(*(*const demo8)[10])(void (*cb)(int)))(void);
demo8 //名稱是demo8
*const //demo8是一個指向...的指針常量
*( )[10] //有10個元素的數(shù)組,元素數(shù)據(jù)類型是指向...的指針
*( )( . . . . . ) //一個函數(shù),參數(shù)是...,返回值為一個指向...的指針
* //一個指向...的指針
void ( )(int) //一個函數(shù),參數(shù)是int,返回void
int ( )(void); //一個函數(shù),參數(shù)是void,返回int
/*demo8是一個指向有10個函數(shù)指針為元素的數(shù)組的指針常量(指針不可變),指針數(shù)組元素指向的函數(shù)是以一個帶一個int型參數(shù)返回為空的函數(shù)指針為參數(shù),返回一個無參數(shù)返回值為int的函數(shù)指針的函數(shù)。*/
int * const * (*(*demo9)[10])(void (*cb)(int));
demo9 //名稱是demo9
* //demo9是一個指向...的指針
*( )[10] //有10個元素的數(shù)組,元素數(shù)據(jù)類型是指向...的指針
* ( )( . . . . ) //一個函數(shù),參數(shù)是...,返回值為一個指向...的指針
* // 參數(shù)是一個指向...的指針
void ( )(int) // 一個函數(shù),參數(shù)是int,返回void
* const //指向...的指針常量
int //int類型數(shù)據(jù)
/*demo9是一個指向有10個函數(shù)指針為元素的數(shù)組的指針,指針數(shù)組元素指向的函數(shù),是以一個帶一個int型參數(shù)返回為空的函數(shù)指針為參數(shù),返回指向一個int類型數(shù)據(jù)的指針常量的指針。*/
int * const * (*(*demo10)[10])(int (*(*cb)(int))[10]);
demo10 //demo10
* //demo10是一個指向...的指針
*( )[10] //有10個元素的數(shù)組,元素數(shù)據(jù)類型是指向...的指針
* ( )( . . . . ); //一個函數(shù),參數(shù)是...,返回值為一個指向...的指針
( * ); // 參數(shù)是一個指向...的指針
( *( )(int) ); // 一個函數(shù),參數(shù)是int,返回一個指向...的指針
(int ( )[10]); // 一個有10個元素的數(shù)組,數(shù)組元素類型是int
* const //指向...的指針常量
int //int類型數(shù)據(jù)