函数指针语法基础
#include <iostream>
using namespace std;
/*
数组类型基本语法:
1、定义一个数组类型
2、定义一个指针数组类型
3、定义一个指向 数组类型的指针 数组类指针
*/
void main01()
{
int a[10]; //a代表数组首元素的地址 &a代表的是整个数组的地址 a+1 和 &a+1 步长不同
{
//1、定义一个数组类型
typedef int(myTypeArray)[10];
myTypeArray myArray;
myArray[0] = 10;
}
{
//2、定义一个指针数组类型
typedef int(*pTypeArray)[10]; //int *p
pTypeArray myPArray;
myPArray = &a;
(*myPArray)[0] = 20;
printf("%d\n", a[0]);
}
{
//3、定义一个指向 数组类型的指针
int(*myPointer)[10]; //myPointer 是一个指针变量
myPointer = &a;
*myPointer[0] = 30;
printf("%d\n", a[0]);
}
system("pause");
}
/*
函数指针基本语法纸质梳理:
1、如何定义一个函数类型
2、如何定义一个函数指针类型
3、如何定义一个函数指针,指向一个函数的入口
*/
int Add(int a, int b)
{
printf("Add().......\n");
return a + b;
}
void main()
{
int ret = 0;
Add(1, 2); //直接调用函数执行,函数名就是函数的入口地址
{
//如何定义一个函数类型
typedef int (MyFuncType)(int a, int b);
MyFuncType *myPointerFunc = NULL; //定义了一个指向函数的指针
myPointerFunc = &Add;
//myPointerFunc = Add; 细节:都可以正确运行 原因:C语言是逐步完善起来的 兼容了历史版本
ret = myPointerFunc(3, 4); // 间接调用函数
printf("ret = %d\n", ret);
}
{
//定义一个函数指针类型
typedef int (*myPointerFuncType)(int a, int b);
myPointerFuncType myPointer; //定义一个指针
myPointer = Add;
ret = myPointer(4, 5);
printf("ret = %d\n", ret);
}
{
//定义一个函数指针变量
int (*myPointerFunc)(int a, int b); //也就是上面的函数指针类型去掉typedef关键字
myPointerFunc = Add;
ret = myPointerFunc(6, 6);
printf("ret = %d\n", ret);
}
system("pause");
}
函数指针做函数参数语法剖析
函数指针做函数参数
当函数指针 做为函数的参数,传递给一个被调用函数,
被调用函数就可以通过这个指针调用外部的函数,这就形成了回调
练习
#include <stdio.h>
void add(int a, int b) //子任务的实现者
{
int c = a + b;
printf("a+b = %d\n", c);
}
void add2(int a, int b)
{
int c = a + b;
printf("a+b = %d\n", c);
}
void add3(int a, int b)
{
int c = a + b;
printf("a+b = %d\n", c);
}
void add4(int a, int b)
{
int c = a + b;
printf("a+b = %d\n", c);
}
typedef int (*MyTypeFuncAdd)(int a, int b); //定义一个函数指针类型
//函数指针做函数参数
void MainOp(MyTypeFuncAdd myFuncAdd) //任务的调用者
{
myFuncAdd(5, 6);
}
//int (*MyFuncAdd)(int a, int b) 直接定义了一个指向函数的指针 让它做函数参数
void MainOp2(int (*MyPointerFuncAdd)(int a, int b))
{
MyPointerFuncAdd(5, 6);
}
//任务的调用和任务的实现可以分开
void main()
{
MyTypeFuncAdd MyFuncAdd = NULL;
//直接调用
add(1, 2);
//间接调用
MyFuncAdd = add;
MyFuncAdd(3, 4);
//函数指针做函数参数
MainOp(add);
MainOp2(add);
//在MainOp2框架没有发生任何变化的情况下 可以把后来人写的代码add2()、add3()等调用起来
MainOp2(add2);
MainOp2(add3);
system("pause");
}
剖析思路
1函数的调用 和 函数的实现 有效的分离
2 C++的多态,可扩展
回调函数思想:
结论:
回调函数的本质:提前做了一个协议的约定(把函数的参数、函数返回值提前约定)提前布局
请思考:C编译器通过那个具体的语法,实现解耦合的?
C++编译器通过多态的机制(提前布局vptr指针和虚函数表,找虚函数入口地址来实现)