函数指针

理解函数指针

为便于理解,你可以这样解释:
typedef void(* Fun)(void) Fun
类似于
typedef int INT

Fun在声明以后,可以把它当作数据类型声明其他变量
Fun的确切意义是一个函数指针类型,该函数没有参数且无返回值  

定义了一个int类型的变量i;
而这样
typedef INT int;
表示用户自己定义了一个整型数据类型INT,实际上就等同于int
所以:INT ii;
同上,表示定义了一个int类型的变量ii;

同样的:
void (*pFn)(void)
定义了一个函数指针,该函数指针指向 类似于 void Foo(void)函数的函数入口地址
而这样:
typedef void (*Fun)(void)
表示用户自己定义了一个函数指针数据类型

Fun pf;
表示定义了一个函数指针pf,改函数指针指向类似于void Foo(void)的函数  

函数名和地址

一个函数名(或称标签),被转换成了一个指针本身。这表明在函数指针被要求当做输入的地方,就能够使用函数名。这也导致了一些看起来很糟糕的代码却能够正确的运行。
#include <stdio.h>
 
// 函数原型

void add(char *name, int x, int y);
 
// 加法 x + y

void add(char *name, int x, int y) {
    printf("%s gives: %d\n", name, x + y);
}
 
// main函数调用

int main() {
 
    
// 一些糟糕的函数指针赋值

    void (*add1Ptr)(char*, int, int) = add;
    void (*add2Ptr)(char*, int, int) = *add;
    void (*add3Ptr)(char*, int, int) = &add;
    void (*add4Ptr)(char*, int, int) = **add;
    void (*add5Ptr)(char*, int, int) = ***add;
 
    
// 仍然能够正常运行

    (*add1Ptr)("add1Ptr", 10, 2);
    (*add2Ptr)("add2Ptr", 10, 2);
    (*add3Ptr)("add3Ptr", 10, 2);
    (*add4Ptr)("add4Ptr", 10, 2);
    (*add5Ptr)("add5Ptr", 10, 2);
 
    
// 当然,这也能运行

    add1Ptr("add1PtrFunc", 10, 2);
    add2Ptr("add2PtrFunc", 10, 2);
    add3Ptr("add3PtrFunc", 10, 2);
    add4Ptr("add4PtrFunc", 10, 2);
    add5Ptr("add5PtrFunc", 10, 2);

// 好吧,这也可以运行
	(**add1Ptr("add1PtrPtr", 10, 2);
}

这是一个简单的例子。运行这段代码,你会看到每个函数指针都会执行,知识会受到一些关于字符转换的警告。但是,这些函数指针都能正常工作。
  1. 在第20行,add作为函数名,返回这个函数的地址,它被隐式的转换为一个函数指针。我之前提到过,在函数指针被要求当作输入的地方,就能够使用函数名。
  2. 在第21行,解引用符作用于add之前,即*add,在返回在这个地址的函数。之后跟函数名一样,它被隐式的转换为一个函数指针。
  3. 在第22行,取地址符作用于add之前,即&add,返回这个函数的地址,之后又得到一个函数指针。
  4. 23到24行,add不断地解引用自身,不断返回函数名,并被转换为函数指针。到最后,它们的结果都和函数名没有区别。

显然,这段代码不是优秀的实例代码。我们从中收获到了如下知识:
其一,函数名会被隐式的转换为函数指针,就像作为参数传递的时候,数组名被隐式的转换为指针一样。在函数指针被要求当作输入的任何地方,都能够使用函数名。
其二,解引用符*和取地址符&用在函数名之前基本上都是多余的。

参考

http://hi.baidu.com/guxue365/blog/item/dc93c52aff9b489c023bf612.html

C语言函数指针基础

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值