C語言函數指針與NULL

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

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章