函式指標的 Typedef
我們可以使用 typedef
來簡化函式指標的使用。想象一下,我們有一些函式,都具有相同的簽名,使用他們的引數以不同的方式列印出來:
#include<stdio.h>
void print_to_n(int n)
{
for (int i = 1; i <= n; ++i)
printf("%d\n", i);
}
void print_n(int n)
{
printf("%d\n, n);
}
現在我們可以使用 typedef
來建立一個名為 printer 的命名函式指標型別:
typedef void (*printer_t)(int);
這將建立一個名為 printer_t
的型別,用於指向函式的指標,該函式接受單個 int
引數並且不返回任何內容,這與我們上面的函式的簽名相匹配。要使用它,我們建立一個建立型別的變數,併為其指定一個有問題的函式:
printer_t p = &print_to_n;
void (*p)(int) = &print_to_n; // This would be required without the type
然後呼叫函式指標變數指向的函式:
p(5); // Prints 1 2 3 4 5 on separate lines
(*p)(5); // So does this
因此,typedef
在處理函式指標時允許更簡單的語法。當函式指標用於更復雜的情況時,例如函式的引數,這一點就變得更加明顯。
如果你使用的函式將函式指標作為引數而未定義函式指標型別,則函式定義將是,
void foo (void (*printer)(int), int y){
//code
printer(y);
//code
}
但是,使用 typedef
它是:
void foo (printer_t printer, int y){
//code
printer(y);
//code
}
同樣,函式可以返回函式指標,並且再次使用 typedef
可以使語法更簡單。
一個典型的例子是 <signal.h>
的 signal
功能。它的宣告(來自 C 標準)是:
void (*signal(int sig, void (*func)(int)))(int);
這是一個帶有兩個引數的函式 - 一個 int
和一個指向函式的指標,該函式將 int
作為引數並且不返回任何內容 - 並返回一個指向函式的指標,就像它的第二個引數一樣。
如果我們將型別 SigCatcher
定義為指向函式型別的指標的別名:
typedef void (*SigCatcher)(int);
然後我們可以使用以下方式宣告 signal()
:
SigCatcher signal(int sig, SigCatcher func);
總的來說,這更容易理解(即使 C 標準沒有選擇定義型別來完成工作)。signal
函式有兩個引數,一個 int
和一個 SigCatcher
,它返回一個 SigCatcher
- 其中 SigCatcher
是一個指向一個函式的指標,該函式接受一個 int
引數並且什麼都不返回。
雖然使用 typedef
名稱作為指向函式型別的指標可以使生活更輕鬆,但它也可能導致後來維護程式碼的其他人感到困惑,因此請謹慎使用並使用適當的文件。另請參見功能指標 。