#include <stdio.h>
void chuan_a(void);
void chuan_b(void);
int main() {
printf("Smile!\n");
chuan_a; // 錯誤:這裡是函數指標表達式,而非調用
chuan_b; // 錯誤:同理
return 0;
}
void chuan_a(void) { printf("Smile!Smile!\n"); }
void chuan_b(void) { printf("Smile!Smile!Smile!\n"); }
在 C 語言中,函數名代表函數的入口地址 (函數指標)。
chuan_a:類型為 void (*)(void) 的右值,值為函數位址。單獨寫在語句中,屬於「無副作用的表達式語句」,編譯器通常只給警告 (如 statement with no effect),不會執行函數體。chuan_a():函數調用運算子() 告訴編譯器「跳轉到該位址執行代碼,並傳遞參數」。int main() {
printf("Smile!\n");
chuan_a(); // 加上括號 () 即為調用
chuan_b(); // 加上括號 ()
return 0;
}
既然函數名是位址,我們可以將其賦值給函數指標變數,實現回調、多態、狀態機等進階模式。
typedef void (*FuncPtr)(void); // 定義函數指標類型
void execute(FuncPtr f) {
if (f) f(); // 透過指標調用
}
int main() {
execute(chuan_a); // 傳遞函數位址,無需括號
execute(chuan_b);
return 0;
}
開啟高警告等級可捕獲此類低級錯誤:
-Wall -Wextra -Werror (將警告視為錯誤)/W4 /WX編譯上述錯誤碼時,GCC 會提示:warning: statement with no effect [-Wunused-value]。
函數調用必須加括號 (),即使參數列表為空 (void)。缺少括號僅獲取函數位址,不會執行任何代碼。養成閱讀編譯器警告的習慣,能省去無數除錯時間。