C語言中,函數指針和普通指針類似,如果定義了一個函數指針,比如int (*fun)(int a,int b); 那麼函數指針fun將默認初始化爲NULL。
注意:
1)函數指針不是函數聲明,不要混淆。
2)C中函數名可以隱式轉換爲函數指針,但是C++中非靜態成員函數無法隱式轉換,
因此在C/C++中獲取函數指針時最好統一用取地址符&:即函數指針 = &函數名。
比如定義一個函數指針fun:
#include <stdio.h>
int (*fun)(int a,int b); //定義函數指針
main()
{
printf("fun=%p\r\n", fun);
}
編譯 gcc test_fun.c -o test_fun
運行./test_fun, 輸出:fun=(nil) 即空指針。
如果函數指針是通過extern引入的,比如 test.h 聲明瞭一個函數指針:
extern int (*fp)(int,int);
那麼必須在某個.c裏面有其定義,否則在其他.c中調用fp指針會在鏈接時找不到定義。
比如將其定義在test_lib.c:
#include "test.h"
int (*fp)(int,int); //函數指針定義
void init_fun(int (*fp_p)(int,int))
{
fp = fp_p;
}
那麼在其他.c文件中可以訪問這個函數指針,比如test.c:
#include "test.h"
#include <stdio.h>
int test_fun(int a,int b)
{
return 0;
}
int test_fun2(int a,int b)
{
return 0;
}
main()
{
printf("fp=%p\r\n", fp);
printf("test_fun ptr=%p\r\n", test_fun); //函數名隱式轉換爲函數指針
printf("test_fun ptr=%p\r\n", &test_fun); //函數名取地址獲取函數指針
printf("test_fun2 ptr=%p\r\n", &test_fun2);
fp = test_fun;
printf("fp=%p\r\n", fp); //函數指針
printf("fp ptr=%p\r\n", &fp); //函數指針的指針
init_fun(&test_fun2);
printf("fp=%p\r\n", fp);
}
編譯gcc test.c test_lib.c -o test
運行./test 輸出:
fp=(nil)
test_fun ptr=0x400538
test_fun ptr=0x400538
test_fun2 ptr=0x400549
fp=0x400538
fp ptr=0x600a70
fp=0x400549
如果test_lib.c 中把int (*fp)(int,int); 這行註釋掉,會報錯:
[me@vm009190 test]$ gcc test.c test_lib.c -o test
/tmp/ccwI8oyG.o: In function `main':
test.c:(.text+0x29): undefined reference to `fp'
test.c:(.text+0x6a): undefined reference to `fp'
test.c:(.text+0x75): undefined reference to `fp'
test.c:(.text+0x9d): undefined reference to `fp'
/tmp/ccdAmTQX.o: In function `init_fun':
test_lib.c:(.text+0xf): undefined reference to `fp'
collect2: error: ld returned 1 exit status