標籤:
應該是小試牛刀的時候了。
在 ANSI C 的標準庫中,有一個 atexit()函數。如果使用這個函數,當程式正常結束的時候,可以回調一個指定的函數。
atexit()的原型定義如下:
int atexit(void (*func)(void));
1、首先著眼於標識符。
int atexit(void (*func)(void));
英語的表達為:
atexit is
2、解釋用於函數的()。
int atexit(void (*func)(void));
英語的表達為:
atexit is function() returning
3、函數的參數部分比較複雜,所以先解析這部分。同樣地, 先著眼於標識符。
int atexit(void (*func)(void));
英語的表達為:
atexit is function(func is) returning
4、因為有括弧, 所以這裡解釋*。
int atexit(void (*func)(void));
英語的表達為:
atexit is function(func is pointer to) returning
5、解釋用於函數的()。這裡的參數還是比較簡單的, 是 void(無參數) 。
int atexit(void (*func)(void));
英語的表達為:
atexit is function(func is pointer to function (void) returning) returning
6、解釋類型指定符 void。這樣就結束了 atexit 的參數部分的解釋。
int atexit(void (*func)(void));
英語的表達為:
atexit is function(func is pointer to function(void) returning void) returning
7、解釋資料類型修飾符 int。
int atexit(void (*func)(void));
英語的表達為:
atexit is function (func is pointer to function (void) returning void) returning int
8、翻譯成中文……
atexit 是返回 int 的函數(參數是,指向返回 void 沒有參數的函數的指標) 。
下面是一個更加複雜的例子。
標準庫中有一個 signal()函數,它的原型聲明如下,
void (*signal(int sig, void (*func)(int)))(int);
1、首先著眼於標識符。
void (*signal(int sig, void (*func)(int)))(int);
英語的表達為:
signal is
2、相比*, ()的優先順序更高,所以先解釋這部分。
void (*signal(int sig, void (*func)(int)))(int);
英語的表達為:
signal is function() returning
3、解釋參數部分。這裡有兩個參數,第一參數是 int sig。
void (*signal(int sig, void (*func)(int)))(int);
英語的表達為:
signal is function(sig is int,) returning
4、著眼另外一個參數。
void (*signal(int sig, void (*func)(int)))(int);
英語的表達為:
signal is function(sig is int, func is) returning
5、因為有括弧, 所以這裡解釋*。
void (*signal(int sig, void (*func)(int)))(int);
英語的表達為:
signal is function(sig is int, func is pointer to) returning
6、解釋表示函數的(), 參數為 int。
void (*signal(int sig, void (*func)(int)))(int);
英語的表達為:
signal is function(sig is int, func is pointer to function(int) returning) returning
7、解釋資料類型修飾符 void。
void (*signal(int sig, void (*func)(int)))(int);
英語的表達為:
signal is function(sig is int, func is pointer to function(int) returning void) returning
8、參數部分已經解釋結束。接著因為有括弧,所以這裡解釋*。
void (*signal(int sig, void (*func)(int)))(int);
英語的表達為:
signal is function(sig is int, func is pointer to function(int) returning void) returning pointer to
9、解釋表示函數的(),參數為 int。
void (*signal(int sig, void (*func)(int)))(int);
英語的表達為:
signal is function(sig is int, func is pointer to function(int) returning void) returning pointer to function(int) returning
10、最後,添上 void。
void (*signal(int sig, void (*func)(int)))(int);
英語的表達為:
signal is function(sig is int, func is pointer to function(int) returning void) returning pointer to function(int) returning void
11、翻譯成中文……
signal 是返回“指向返回 void,參數為 int 的函數的指標”的函數,它有兩個參數, 一個是 int,另一個是“指向返回 void 參數為 int 的函數的指標”。
如果能讀懂這種難度的聲明,我想應該不會再有什麼讓你畏懼的 C 聲明了。
下面的說明可能會讓你對 C 語言感到更加不快。
signal()是用於註冊訊號處理(當中斷髮生時被調用的函數)的函數。此函數的傳回值是之前註冊的處理當前訊號中斷的函數。
也就是說,其中的一個參數和傳回值,它們都是相同的類型——指向訊號處理函數的指標。在一般的語言中,同樣的表現模式出現兩次並不會讓你感到不適,但是解釋 C 語言聲明的過程是“一會兒向左一會兒向右”,因此,表示傳回值的部分散落了在左右兩側。
此時,運用 typedef 可以讓聲明變得格外得簡潔。
/*摘錄於FreeBSD 的man page /typedef void(sig_t)(int);sig_t signal(int sig, sig_t func);
sig_t 代表“指向訊號處理函數的指標”這個類型。
《征服 C 指標》筆記6:練習——挑戰那些複雜的聲明