怎样返回另一个函数的地址

怎样返回另一个函数的地址

 

首先声明:文中的例子完全是按照本人的编程风格来编写的,所以,如果与你的编程风格不同,请原谅;再者,也许文中有些不对的地方,请给予指正。

 

       在某些时候,我们需要一个函数返回另一个函数的地址,而非函数的返回值的时候,这是一个很有用的问题,因为某些时候,我们形参是需要一个函数的地址,需非一个函数值的时候,这时候就需要我们去寻找函数的地址,通常我们只关心函数的返回值,很少去关心函数的地址,但是,在上述的某些时候,关心函数的地址更加为重要。

       其实,函数名本身就是函数的地址,它标志此函数在内存中的启始位置,只是我们通常调用函数的时候都只用其返回值,所以,对函数名这一标号的真实意义没有去过多的了解,关于函数名的一些问题,请读者去参考相关的资料。在此我来分析怎么从一个函数返回另一个函数地址。

       首先,如果你的指针学得够好的话,应该会想到这样的一个问题,我可以返回一个指针,这个指针指向一个函数,不错,就个指针就是我通常所说的函数指针(并非指针函数,请注意这两个名词之间的区别),那么这样一分析不就出来了吗,一个返回函数指针的函数就能办到,这也是一般常用的办法,但是在函数声明与调用时就有些问题了,首先我们来分析一下声明,第一点我们必须保证它是一个函数,再次这个函数还返回一个指针,并且这个指针指向另一个函数,就这样就搞定了,在此假设读者对函数指针有一定的了解,这样就很好办事了,我们先来声明一个函数指针,例如 int (*fun)(int,int),这个声明就是一个函数指针,它表明fun是一个指针,它所指向的是一个int xx (int,int)的函数,如果读者你看过《C专家编程》,在3.3节中有一个关于声明的优先级规则的,那么效果会更好。好了,我接着分析一个我们的原问题,可以从函数指针开始出发,根据C语言中声明的优先级规则(请查看《C专家编程》),我们可以应用其后缀规则来变种我们所需的函数声明,真正的一种满足文章需求的声明为int (*fun(int)(int,int),这对于初学者有点难度,我们从C语言中声明的优先级规则开始,第一可以确定fun是一个有一个int形参的函数,该函数的返回值是一个指针,该指针指向一个int xx(int,int)的函数,好了,这样就把该函数的原形给确定下来了。下面我们应以这个函数原形为出发点,写一个简单的例子。完整的例子如下(说明,这个例子是本人在网上看到的一个公司的笔试题,这种解法有些烦锁,关于这个题目的解法我在《函数名之标号地址》一文中写出了三种解法,写这一篇文章所用的例子完全从其中获取一些源码):

#ifndef _TEST_C_

#define _TEST_C_

 

#include <stdio.h>

 

int _my_add(int,int);

int _my_sub(int,int);

int _my_mul(int,int);

int _my_div(int,int);

int _my_mod(int,int);

 

unsigned long function_buffer[][2] = {

       (unsigned long) _my_add,'+',

       (unsigned long) _my_sub,'-',

       (unsigned long) _my_mul,'*',

       (unsigned long) _my_div,'/',

       (unsigned long) _my_mod,'%',

};

 

int (*_my_function(int))(int,int);

 

int main(void)

{

       int number_one;

       int number_two;

       int number_control;

       int (*temp_fun_pin)(int,int);

 

    while(1)

       {

              printf("这是一个简单的计算器,主要有下面的功能!/n");

              printf("    1:/n     2:/n     3:/n     4:/n     5:求模/n");

              printf("请输入第一操作数  第二操作数  相关运算/n");

 

              scanf("%d %d %d",&number_one,&number_two,&number_control);

 

    if(((number_control == 4) && (!(number_two | 0x0)))/

         || (number_control > 5)){

                     printf("input is err/n");

                     continue;

              }

 

        temp_fun_pin = _my_function(number_control);

 

              printf("/n%d %c %d = %d/n/n",number_one,/

                     *(*(function_buffer + number_control - 1) + 1),/

                     number_two,temp_fun_pin(number_one,number_two));

       }

 

       return 0;

}

 

int (*_my_function(int number_control))(int,int)

{

       int (*temp_fun_pin)(int,int);

 

       temp_fun_pin = /

(int (*)(int,int))function_buffer[number_control - 1][0];

 

       return temp_fun_pin;

}

 

int _my_add(int number_one,int number_two)

{

       return number_one + number_two;

}

 

int _my_sub(int number_one,int number_two)

{

       return number_one - number_two;

}

 

int _my_mul(int number_one,int number_two)

{

       return number_one * number_two;

}

 

int _my_div(int number_one,int number_two)

{

       return number_one / number_two;

}

 

int _my_mod(int number_one,int number_two)

{

       return number_one % number_two;

}

#endif

 

在上面的分析忘记了分析怎么调用些函数了,其实只要类型相匹配就可以了,函数的返回值是一个函数指针,那么我们就声明一个函数指针,让这个函数指针来获取函数的返回值就行了。

 

其实,上述方法有一点难于理解,这需要读者对指针有相当的了解,所以,我接着来实现一个更为简单一点的例子,这个例子需要读者知道函数名其实就是一个标号,标志其在内存中的地址,关于不同系列CPU地址所用的类型请参考相关的CPU手册,在此以unsigned long来做为内存地址的类型。这一个列子,只需要读者再有一点函数指针的基础,就能很容易地理解,完全比上一个例子更加好理解,完整代码如下:

#ifndef _TEST_C_

#define _TEST_C_

 

#include <stdio.h>

 

int _my_add(int,int);

 

unsigned long _my_call_function(void);

 

int main(void)

{

       int number_one;

       int number_two;

       int result;

       unsigned long my_fun_address;

 

    while(1)

       {

printf("这是一个应用函数地址进行调用函数的例子,主要用加法来验证/n");

              printf("请输入被加数,加数/n");

 

              scanf("%d %d",&number_one,&number_two);

 

              my_fun_address = _my_call_function();

        result = ((int (*) (int,int)) my_fun_address)(number_one,number_two);

 

              printf("/n%d %c %d = %d/n/n",number_one,'+',number_two,result);

       }

 

       return 0;

}

 

unsigned long _my_call_function(void)

{

  return (unsigned long)_my_add;

}

 

int _my_add(int number_one,int number_two)

{

       return number_one + number_two;

}

 

#endif

 

此例子有点多做的问题,如果就这个例子来说,直接调用那不更好,但是这个例子的目的不在于怎么调用一个函数,需要说明的是怎么直接返回函数的地址并调用之。所以,看起来才有一点多余。

好了,本人的知识水平也只能写成这样了,如果有什么不对的地方,请给予指正,让本人也有学习与改正的机会。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

舒稳

2010.8.4于长沙理工大学

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值