函数指针(个人参考使用)

一、函数指针的定义
int (*foo)();      //foo是一个函数指针,它指向一个返回值为int的函数
int *(*foo)();    //foo是一个函数指针,它指向一个返回值为int*的函数
int (*foo[])();   //foo是一个数组,该数组的元素为一个指向返回值为int的函数的指针
int *(*foo[])();  //foo是一个数组,指针指向的类型为一个指向返回值为int×的函数的指针
二、用途
1、回调函数
用户把一个函数指针作为参数传递给其他函数,后者将”回调“用户的函数。任何时候,如果你所编写的函数必须在不同的时刻执行不同类型的工作或执行只能由函数调用者定义的工作,可以使用函数指针。
最常见的是一些窗口系统使用回调函数链接多个动作。
2、转移表
在使用switch语句时,其操作符的代码必须是整数。如果它们是从0开始连续的整数,可以使用转移表来实现和switch相同的任务。
转移表就是一个函数指针数组。
创建一个转移表的步骤主要有两步:
(1)、声明并初始化一个函数指针数组。唯一需要注意的是确保这些函数的原型出现在这个数组声明之前。如:
int foo1(int ,int);
int foo2(int, int);
int foo3(int, int);
....
int (*foo[])(int, int) =
{
    foo1, foo2, foo3,....
};
初始化列表中各个函数名的正确顺序取决于程序中用于表示每个操作符的整型代码。
(2)、采用如下语句替换switch语句。
int result = foo[index] (op1, op2);
注意:
在转换表中,越界下标引用就像在其他任何数组中一样是不合法的。一旦出现这种情况,程序可能在三个地方中止:
  • 如果下标值远远越过了数组的边界,它所标识的位置可能在分配给该程序的内存之外。有些操作系统能检测到这个错误并中止程序,但有些操作系统并不这么做。如果程序中止,这个错误将在靠近转换表语句的地方被报告,这时容易诊断。
  • 如果程序并未中止,非法下标所标识的值被提取,处理器跳到该位置,这个不可预测的值可能代表程序中一个有效的地址,但也可能不是这样。如果它不代表一个有效地址,程序此时也会中止,但错误报告的地址从本质上说是一个随机数,此时极难调试。
  • 如果程序此时还未失败,机器将开始执行根据非法下标所获取的虚假地址的指令,此时调试也极为困难。如果这个随即地址位于一块存储数据的内存中,程序通常会很快中止,这通常是由于非法指令或非法的操作数地址所致。要想知道机器为什么会到达那个地方,唯一的线索是转移表调用函数时存储于堆栈中的返回地址。如果任何随机指令在执行时修改了堆栈或堆栈指针,那么连这个线索也没有了。更糟的是,如果这个随机地址恰好位于一个函数的内部,那么该函数会被执行,修改谁也不知道的数据,直到它运行结束。但是函数的返回地址并不是该函数所期望的保存与堆栈上的地址,而是另一个随机值,这个值就成为下一个指令的执行地址,计算机将在各个随机地址间跳转,执行位于那里的指令。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值