会计考友 发表于 2012-8-2 08:51:15

2012年软件水平初级资格程序员考试重点知识5

函数指针的概念是指向函数的指针变量。 因而“函数指针”本身首先应是指针变量,只不过该指针变量指向函数。在大多数情况下我们使用不到,也忽略了它的存在。函数名实际上也是一种指针,指向函数的入口地址,但它又不同于普通的如int*、double*指针,看下面的例子来理解函数指针的概念:
  view plain int function( int x, int y );int main ( void )
  { int (*fun) ( int x, int y );int a = 10, b = 20;function( a, b );fun = function;(*fun)( a, b );……
  }第一行代码首先定义了一个函数function,其输入为两个整型数,返回也为一个整型数(输入参数和返回值可为其它任何数据类型);后面又定义了一个函数指针fun,与int*或double*定义指针不同的是,函数指针的定义必须同时指出输入参数,表明这是一个函数指针,并且*fun也必须用一对括号括起来;并将函数指针赋值为函数function,前提条件是*fun和function的输入参数和返回值必须保持一致,否则无法通过编译。可以直接调用函数function(),也可以直接调用函数指针,二者是等效的。
  声明函数指针
  回调函数是一个程序员不能显式调用的函数;通过将回调函数的地址传给调用者从而实现调用。要实现回调,必须首先定义函数指针。尽管定义的语法有点不可思议,但如果你熟悉函数声明的一般方法,便会发现函数指针的声明与函数声明非常类似。请看下面的例子:
  void f(); // 函数原型
  上面的语句声明了一个函数,没有输入参数并返回void.那么函数指针的声明方法如下:
  void (*) ();
  函数存放在内存的代码区域内,它们同样有地址,我们如何能获得函数的地址呢?
  如果我们有一个int test(int a)的函数,那么,它的地址就是函数的名字,这一点如同数组一样,数组的名字就是数组的起始地址。
  定义一个指向函数的指针用如下的形式,以上面的test()为例:
  int (*fp)(int a); //这里就定义了一个指向函数的指针
  函数指针绝对不能指向不同类型,或者是带不同形参的函数,在定义函数指针的时候我们很容易犯如下的错误。
  int *fp(int a); //这里是错误的,因为按照结合性和优先级来看就是先和()结合,然后变成了一个返回整形指针的函数了,而不是函数指针,这一点尤其需要注意!
  例如函数原型为:
  int fun(int *, int);
  则函数指针可以声明为: int (*pf)(int *, int);
  当然从上述例子看不出函数指针的优点,目的主要是想引出函数指针数组的概念。我们从上面例子可以得知,既然函数名可以通过函数指针加以保存,那们也一定能定义一个数组保存若干个函数名,这就是函数指针数组。正确使用函数指针数组的前提条件是,这若干个需要通过函数指针数组保存的函数必须有相同的输入、输出值。
  view plain //首先定义256个处理函数(及其实现)。
  int function0( int *, int );……
  int function255( int *, int );
  //其次定义函数指针数组,并给数组赋值。
  void (*fun)( int *, int );
  fun = function0;……
  fun = function255;
  如果赋了不同的值给函数指针,那么调用者将调用不同地址的函数。赋值可以发生在运行时,这样使你能实现动态绑定。
  下面我们来看一个具体的例子:
  view plain int test(int a)
  { return a;}
  int main(void)
  { int (*fp)(int a);fp = test; //将函数test的地址赋给函数指针fp cout《fp(5)《“|”《(*fp)(10)《endl; //输出fp(5),这是标准c++的写法,(*fp)(10)这是兼容c语言的标准写法,两种同意,但注意区分,避免写的程序产生移植性问题!
  return 0;} typedef定义可以简化函数指针的定义,在定义一个的时候感觉不出来,但定义多了就知道方便了,上面的代码改写成如下的形式:
  view plain int test(int a)
  { return a;}
  int main(void)
  { typedef int (*fp)(int a); //注意,这里不是生命函数指针,而是定义一个函数指针的类型,这个类型是自己定义的,类型名为fp fp fpi; //这里利用自己定义的类型名fp定义了一个fpi的函数指针!
  fpi = test;cout《fpi(5)《“|”《(*fpi)(10)《endl; //输出fp(5),这是标准c++的写法,(*fp)(10)这是兼容c语言的标准写法,两种同意,但注意区分,避免写的程序产生移植性问题!   return 0;}
页: [1]
查看完整版本: 2012年软件水平初级资格程序员考试重点知识5