C++ 函数指针取地址与取值

本文介绍了C++中的函数指针,包括其概念、作用、使用方式以及函数指针的取地址和取值。函数指针是一个特殊的指针,指向函数在内存中的地址,用于实现灵活的函数调用,常用于回调函数和多态实现。通过示例和汇编代码解析,阐述了函数指针与函数名、函数指针地址之间的关系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是函数指针?

void (*funptr)(int param);

这就是一个简单的函数指针的声明。顾名思义,函数指针是一个特殊的指针,它用于指向函数被加载到的内存首地址,可用于实现函数调用。

函数名也是指向函数的内存首地址的,他和函数指针有什么不同?——既然他是指针,而且不是const的,那么他就是灵活可变的,通过赋值不同的函数来实现不同的函数调用。

然而他也有自己的限制(函数签名——返回值类型和参数类型),那不是和覆盖、多态实现的功能一样了么?额。。。要这么理解也行,但不全对。

函数指针作用

上面说到函数指针的功能类似覆盖或多态,覆盖和多态更多体现的是对象自身的特征和对象之间的继承关联,而函数指针则没这么多讲究,他就是灵活。

函数指针不需要依附于对象存在,他可以用来解决基于条件的多个函数筛选,也可以处理完全无关的几个函数。

所以他的作用,什么封装性好、用于回调函数、实现多态等等,随便了,只有一条,符合他的函数签名并且可达。

如何使用

和变量指针类似,声明->赋值->使用 或者 定义->使用

int add(int a,int b)
{
    return a + b;
}

//1.声明->赋值->使用
int (*fun)(int a,int b);
fun = add;    //也可使用 fun = &add;从某篇文章看到是历史原因,后面稍作分析
fun(5,10);    //也可使用 (*fun)(5,10);原因同上
//2.通过宏定义函数指针类型 #define int (*FUN)(int,int); FUN fun = NULL; fun = add; fun(5,10); //3.定义->使用 int (*fun)(int a,int b) = add; fun(5,10); //4.宏定义 #define int (*FUN)(int,int); FUN fun = add; fun(5,10);

函数指针的取地址、取值

上面的代码中,又是取地址符&,又是取引用符*,结果还能相互赋值,交叉调用,这又怎么理解?

首先来看下函数指针、函数名的类型。对于函数指针fun,类型为 int (*)(int,int),这个很好理解,函数名add的类型,通过VS在静态情况下用鼠标查看,类型为int (*)(int,int)。

what?为啥不是int ()(int,int)呢?这个我们可以类比数组。数组名为指向内存中数组首地址的指针,同时数组名可当做指针对数组进行操作。而对于函数名,通过在VS下查看汇编代码可以知道,编译器将函数名赋值为函数加载入内存的首地址,通过call 函数名来跳转到相应内存地址进行函数的执行。所以对这里的函数名为指针类型也可以理解。

这样 fun = add 我们可以理解了,那 fun = &add 又是什么鬼? (*fun)(5,10)也可以理解,fun(5,10)呢?下面来看看汇编代码

 

//原始代码
int main()
{
    FUN f = NULL;
    f = &add;
    FUN f1 = NULL;
    f1 = add;
    add(1,2);

    std::cout<< add <<"  "<< &add <<"   " << *add <<std::endl;
    std::cout<< f <<"   " << &f <<"   " << *f <<"   "<<std::endl;
    std::cout<< (*f)(5, 10) << "   " << f(5,10)  <<std::endl;
    std::cout << (*add)(5, 10) << "   " <<(&add)(5, 10) << std::endl;
}

//对应汇编代码
    //对add函数作了一层跳转(从标识add->add函数),记录了add函数的入口地址
add:
000412F8  jmp         add (042180h)
    //add函数汇编代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值