函数指针和回调函数对函数取地址和直接使用函数名的差距

简介

函数的二进制代码存放在内存四区中的代码区,函数的地址是它在内存中的起始地址。如果把函数的地址作为参数传递给函数,就可以在函数中灵活的调用其它函数。

使用函数指针的三个步骤:

1.声明函数指针:

声明普通指针时,必须提供指针的类型。同样,声明函数指针时,也必须提供函数类型,函数的类型是指返回值和参数列表(函数名和形参名不是)

函数之间具有相同的返回值类型和参数列表数目和类型都相同即是同一类函数

1.1声明函数指针语法

函数的返回值类型 (*自定义指针名字) (函数形参列表可写名字也可以不写)

#include <iostream>
using namespace std;

void eat_ming(string food1)
{
	cout << "小明吃" << food1 << endl;
}

void eat_hong(string food2)
{
	cout << "小红吃饭" << food2 << endl;
}

int main()
{
	//声明函数指针
	void (*ming_hong_ptr)(string); 
	ming_hong_ptr = eat_ming;
	//调用
	ming_hong_ptr("香蕉");
	(*ming_hong_ptr)("香蕉");        // 用函数指针名调用函数。 C语言
	ming_hong_ptr = eat_hong;
	ming_hong_ptr("苹果");
	(*ming_hong_ptr)("苹果");		// 用函数指针名调用函数。 C语言
	return 0;
}

2.让函数指针指向函数的地址:

2.1语法:
void (*ming_hong_ptr)(string); 
ming_hong_ptr = eat_ming;
2.2注意在QT中的connect函数中,你可能看见这种写法(&func)对函数取地址:

func函数原型:

void func()
{
	cout << "dfa";
}

按照&运算符本来的意义,它要求其操作数是一个对象,但函数名不是对象(函数是一个对象),本来&func是非法的,但很久以前有些编译器已经允许这样做, c/c++标准的制定者出于对象的概念已经有所发展的缘故,也承认了&func的合法性。

因此,对于func和&func你应该这样理解,func是函数的首地址,它的类型是void (),&func表示一个指向函数func这个对象的地址, 它的类型是void (*)(),因此func和&func所代表的地址值是一样的,但类型不一样。

其实这种写法就跟数组一样,假设有一数组a100]那么a就代表数组的首地址,&a是整个数组的地址。他们的意义不一样。

总的来说,在绝大多数情况下,对函数取地址和直接写函数名在使用上并没有太大的区别。C++ 编译器通常会自动将函数名转换为函数指针类型,以适应上下文。不过在一些特殊的情况下,如明确需要函数指针类型或者在模板编程中,你可能需要注意这些微妙的差别。

3.通过函数指针调用函数。

//调用
ming_hong_ptr("香蕉");
(*ming_hong_ptr)("香蕉");        // 用函数指针名调用函数。 C语言
ming_hong_ptr = eat_hong;
ming_hong_ptr("苹果");
(*ming_hong_ptr)("苹果");		// 用函数指针名调用函数。 C语言

回调函数

现有一个饭店小明和小红还有很多不知名的客人,我们不可能用一个函数封装起来它的所有操作,只能封装起开他们的共同操作

例代码:

#include <iostream>
using namespace std;

void eat( string name, string food1)
{
	cout << name << "吃" << food1 << endl;
}

void fan_dian()
{
	cout << "点餐" << endl;
	cout << "做饭" << endl;
	eat("某某", "某某食物");
}

int main()
{
	fan_dian()
	return 0;
}

在以上代码中我们就只能封装他们的共同性,可是他们的个人习惯也不能没有啊。

此时函数指针就有用了

例代码:

#include <iostream>
using namespace std;


void eat_ming(string food1, int spending_power = 0)
{
	cout << "小明吃" << food1 << endl;
	cout << "小明站在凳子上吃" << endl;
}


void eat_hong(string food2,int spending_power = 0 )
{
	cout << "小红吃饭" << food2 << endl;
	cout << "小红站在桌子上吃" << endl;
}

void fan_dian(void (*habit)(string,int))
{
	cout << "点餐" << endl;
	cout << "做饭" << endl;
	habit("香蕉",59); //缺省值没有用,函数指针写有几个参数就要传入几个参数
}


int main()
{
	void (*habit)(string,int);
	habit = eat_ming;
	fan_dian(habit);
	habit = eat_hong;
	fan_dian(habit);
	return 0;
}

利用函数指针当形参可以传入你想要的客人习惯

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
函数指针指向函数的指针变量。在C语言中,函数指针可以用来存储函数地址,并且可以通过函数指针来调用该函数函数指针可以作为参数传递给其他函数,使得其他函数可以通过该指针来调用指向函数,这就是回调函数的实现方式之一。 回调函数是通过函数指针调用的函数。当我们把一个函数的指针(地址)作为参数传递给另一个函数,并且在该函数内部通过该指针来调用指向函数时,我们就称这个被调用的函数回调函数回调函数不是由该函数的实现方直接调用的,而是由其他函数在特定的条件下调用的。这种机制可以提高程序的灵活性和可扩展性。 在C语言中,我们可以使用函数指针来实现回调函数。具体来说,我们可以将函数的指针传递给另一个函数,然后这个函数就可以通过这个指针来调用回调函数了。这种方式可以使得回调函数在被调用时具有更大的灵活性,因为回调函数可以根据需要被多次调用,也可以在不同的上下文中被调用。 此外,函数指针还可以用来创建函数指针数组。函数指针数组是一个数组,其中的元素都是函数指针。可以使用数组下标来访问和调用数组中的不同函数指针,从而实现对不同函数的调用。这种方式可以便于管理和组织多个函数指针,使得程序的结构更加清晰和易于维护。<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青茶绿梅*2

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值