C語言的宣告有時會很長,讓人感到恐懼。這裡描述了一種方法,用通俗的語言把宣告分解開來,分別解釋各個組成部分。
理解C語言宣告的優先順序規則的步驟
-
宣告從它的名字開始讀起,然後按照優先順序順序依次讀取。
-
優先順序從高到低依次是:
-
宣告中被括號括起來的那部分
-
字尾操作符: 括號()表示這是一個函式, 方括號[]表示這是一個陣列
-
字首操作符:星號*表示“指向...的指標”
- 如果const和(或)volatile關鍵字的後面緊跟型別說明符(如int,long等),那麼它作用於型別說明符。在其他的情況下,const和(或)volatile關鍵字作用於它左邊緊鄰的指標星號。
例子1: char *const *(*next)();
適用規則 | 解釋說明 |
---|---|
1 | 從變數名開始,next是... |
2.1 | 在把(*next)作為一個整體,得出next是指向...的指標 |
2.2 | 讀字尾(),得出是個函式,這個函式不帶引數,所以next是指向函式的指標 |
2.3 | 讀(*next) 前面的*,得出這個函式返回值是個指標 |
3 | 讀char *const 部分,const修飾的是指標,這是個指向char型別的常指標 |
連線在一起就是,next是一個指標,它指向一個函式,這個函式不帶引數,它返回另外一個指標,這個指標指向char型別的常量指標。
例子2:char *(* c[10])(int **p)
適用規則 | 解釋說明 |
---|---|
1 | 從變數c開始 |
2.1 | 把(* c[10]) 作為一個整體 |
2.2 | 在這個整體裡,讀到[],所以c是一個包含10個元素的陣列 |
2.3 | 陣列的每個元素是個指標 |
2.2 | 讀(int **p) 的部分,這是個函式,引數是指向int的指標的指標 |
2.3 | 這個函式返回的是個指向char型別的指標 |
所以連線在一起就是,c是一個包含10個元素的陣列,陣列中的每個元素是個指向函式指標,該函式的宣告是這樣的,引數是指向int的指標的指標,返回值是指向char型別的指標。
例子3:void (*signal(int sig, void (*func)(int)))(int);
適用規則 | 解釋說明 |
---|---|
1 | 先讀void (*signal(...))(int) ,針對這部分,先從signal開始 |
2.1 | 把(*signal(...)) 當作一個整體 |
2.2 | signal是個函式 |
2.3 | 讀signal前面的*,得出signal這個函式返回一個指標,該指標是指向函式的指標,函式原型是void f(int) |
在讀(int sig, void (*func)(int)) 部分,這部分是signal的引數 |
所以連線在一起就是,signal是個函式,該函式帶2個引數,int和一個函式的指標,該指標所指向的函式原型是void f(int)。signal這個函式的返回為函式的指標,該指標所指向的函式原型也是void f(int)。
雖然這樣簡潔,但是可讀性太差。我們可以藉助typedef來實現與上面宣告等價的宣告。
typedef void (*ptr_to_func) (int);
ptr_to_func signal(int, ptr_to_func);
複製程式碼
ptr_to_func是一個函式指標,該函式接受int引數,返回值為void。signal是個函式,接受int和一個函式指標作為引數,返回值為ptr_to_func函式指標。
例子4: char (*(*x())[])()
適用規則 | 解釋說明 |
---|---|
1 | 先把(*x()) 當成一個整體 |
2.2 | x是個函式 |
2.3 | 該函式返回一個指標 |
把已經處理的部分拿掉,換個新名稱xx,得到char (*xx[])() |
|
2.2 | xx是個陣列 |
2.3 | 陣列的每個元素是個指標,該指標指向函式,函式的原型是 char f() |
所以連線在一起就是, x是個函式,函式返回一個指標,指標指向陣列,陣列的每個元素是個函式的指標,函式的原型是char f()。
《The C Programming Language》第5.12章有寫一個dcl工具,它將C語言的宣告轉換為文字描述。原始碼我已經整理到我的github,在linux上執行下面的命令即可測試:
git clone git@github.com:rexnie/usefulC.git
cd src/tcpl/ch5/5-18
make
複製程式碼
即可在當前目錄下生成a.out, 執行該檔案,得到:
./a.out
char (*(*x())[])()
x: function returning pointer to array[] of pointer to function returning char
複製程式碼
參考:
- 《The C Programming Language中文版(第2版.新版)》
- 《C專家程式設計》
- dcl工具