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

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

简介

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

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

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;
}

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

目录
相关文章
|
25天前
|
机器学习/深度学习 搜索推荐 算法
【再识C进阶2(下)】详细介绍指针的进阶——利用冒泡排序算法模拟实现qsort函数,以及一下习题和指针笔试题
【再识C进阶2(下)】详细介绍指针的进阶——利用冒泡排序算法模拟实现qsort函数,以及一下习题和指针笔试题
|
2天前
|
C语言
指针进阶(回调函数)(C语言)
指针进阶(回调函数)(C语言)
|
4天前
|
编译器 C++
函数指针和函数对象不是同一类型怎么替换
函数指针和函数对象不是同一类型,为何可替换用作同一函数的参数
|
4天前
|
存储 C语言
C语言的函数返回值和指针
C|函数返回值(区分各类值)和指针(区分各类存储空间)的细节
|
22天前
|
存储 C语言
C语言学习记录——7000+字长文-复习&学习指针(指针、地址、指针变量、指针与数组、指针与函数、指针数组、多级指针)二
C语言学习记录——7000+字长文-复习&学习指针(指针、地址、指针变量、指针与数组、指针与函数、指针数组、多级指针)二
16 1
|
22天前
|
存储 C语言
C语言学习记录——7000+字长文-复习&学习指针(指针、地址、指针变量、指针与数组、指针与函数、指针数组、多级指针)一
C语言学习记录——7000+字长文-复习&学习指针(指针、地址、指针变量、指针与数组、指针与函数、指针数组、多级指针)一
13 1
|
1天前
|
C语言
C语言中的函数指针、指针函数与函数回调
C语言中的函数指针、指针函数与函数回调
6 0
|
26天前
|
C++ 存储 Java
C++ 引用和指针:内存地址、创建方法及应用解析
'markdown'C++ 中的引用是现有变量的别名,用 `&` 创建。例如:`string &meal = food;`。指针通过 `&` 获取变量内存地址,用 `*` 创建。指针变量存储地址,如 `string *ptr = &food;`。引用不可为空且不可变,指针可为空且可变,适用于动态内存和复杂数据结构。两者在函数参数传递和效率提升方面各有优势。 ```
|
29天前
|
存储 C语言
字符指针作为函数参数
字符指针作为函数参数
27 2
|
9天前
|
存储 编译器
指针?地址?内存?
指针?地址?内存?
10 0