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

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值