函数指针的学习

来源:互联网 发布:阿里云ecs 共享改独享 编辑:程序博客网 时间:2024/06/01 10:26


阅读完链接的文章,有所收获: http://www.cnblogs.com/iuices/archive/2011/11/21/2257710.html

感谢作者,我对函数指针的了解更多了。



其实函数也是一种类型而已,比起简单的float,int等,其声明格式只是稍微有些不同:需要带上返回值类型,参数类型,也就是这样了。在编译器对源代码进行编译的时候,其实也是把对符号等操作转换为地址操作,这也是cpu执行指令的本质。


定义两个简单的函数:

 int sum(int x,int y){
    int c=x+y;
    printf("%d+%d=%d\n",x,y,c);
    return c;
  }


 int minus(int x,int y){
    int c=x-y;
    printf("%d-%d=%d\n",x,y,c);
    return c;
  }


 其中,sum,minus就相当于是定义了2个符号:代表函数的开始地址,相当于是一个指针。

我们习惯了这样调用:

sum(1,2)或minus(3,4)

其实按照我们的理解,如果sum,minus是代表了地址的话,那不是应该是(*sum)(1,2),(*minus)(3,4)吗?确实是的,是编译器帮忙做了这转换,使得程序员不用写的这么繁琐。


既然sum代表了一个地址,我们对它进行一下转换,将它转为一个函数指针(虽然这是很多余的):

( *( int(*)(int,int))sum)(10,12);

这个表示了将sum转换为(int (*)(int,int))的函数指针。

然后执行该函数指针所指向的函数(入口地址就是sum的值),并且传递2个参数:10,12.

上面说到了对于(*sum)(1,2)也可以写成是sum(1,2)所以,上面的也可以写成:

(int(*)(int,int)sum)(10,12)


再来看:

  void *p;

  p=∑
 ((int(*)(int,int))p)(15,16);//执行加法操作

 

 p=minus;//它就是地址,取它的地址也是它代表的值
 ((int(*)(int,int))p)(18,16); //执行减法操作

 (*(int(*)(int,int))p)(18,16);


打印一下值:

 printf("sum:%d,0x%x,minus:%d,0x%x,p:pcont=0x%x\n",sum,sum,minus,&minus   ,*((int(*)(int,int))p));

结果:

sum:134514210,0x8048622,minus:134514266,0x804865a,p:pcont=0x804865a


原文章分析的

( *( void(*)())0)();

就是把0这个地址入口,转换为一个函数的入口,并执行。这个函数的原型为:void ()。

上面的这一句话,就是说,执行0地址的代码。


那么我也可以在程序里直接指定地址来执行函数:

unsigned long addr=∑
(*(int(*)(int,int))addr)(100,100);

取sum的地址,转换一下,执行。






0 0
原创粉丝点击