C/C++函数指针(最详细剖析)

创建函数指针:
函数指针有两种用途,一是调用函数,二是做函数的参数。这个可以将两个函数绑定在一起,在调用函数指针时可以调用另一个函数。因此可以做成钩子函数,这个在动态编程中有很重要的作用。
接下来我用代码来进行示范函数指针的几种创建方法。

#include<iostream>

using namespace std;

int myfunc(int a, char b)
{
	cout << "int myfunc(int a, char b)" << endl;
	printf("int=%d,char=%c\n", a, b);
	return 0;
}

void test()
{
	//定义函数类型,通过类型来定义函数指针
	typedef int(FUN_TYPE)(int, char);
	FUN_TYPE *pFUNC1 = myfunc;

	pFUNC1(10, 'a');
	(*pFUNC1)(20, 'b');
	myfunc(30, 'c');
	cout << "pFunc1 size:%d\n" << sizeof(pFUNC1) << endl;

	//直接定义函数指针类型
	typedef int(*FUNC_P)(int, char);
	FUNC_P pFUNC2 = myfunc;
	pFUNC2(40, 'd');
	cout << "pFunc2 size:%d\n" << sizeof(pFUNC2) << endl;

	//把指针转换为函数指针类型写法
	int(*pFUNC3)(int, char) = (int(*)(int, char))NULL;
	pFUNC3 = myfunc;
	pFUNC3(50, 'p');
	cout << "pFunc3 size:%d\n" << sizeof(pFUNC3) << endl;
}

int main()
{
	test();
	system("pause");
	return 0;
}

输出为:

/*int myfunc(int a, char b)
int=10,char=a
int myfunc(int a, char b)
int=20,char=b
int myfunc(int a, char b)
int=30,char=c
pFunc1 size:%d
4
int myfunc(int a, char b)
int=40,char=d
pFunc2 size:%d
4
int myfunc(int a, char b)
int=50,char=p
pFunc3 size:%d
4*/

而且函数指针还可以用做参数,例如下面的这几例:
函数可以做另外一个函数的参数:

void doLogic(int(*pFUN)(int, int))
{
	int a = 10;
	int b = 10;
	int ret = pFUN(a, b);
	cout << "ret=" << ret << endl;
}
void test1()
{
	doLogic(fun2);
}

在这个例子中,pFUN被当作参数一样被函数调用。
还可以作为函数指针数组,批量调用函数,例如下面的这个例子:

//函数指针数组
void fun11()
{
	cout << "11" << endl;
}

void fun22()
{
	cout << "22" << endl;
}

void fun33()
{
	cout << "33" << endl;
}

void test2()
{
	void(*fun_array[3])();
	fun_array[0] = fun11;
	fun_array[1] = fun22;
	fun_array[2] = fun33;

	for (int i = 0; i < 3; i++)
	{
		fun_array[i]();
	}
}

最后一个是使用函数指针来实现回调函数,这个也是比较复杂的:

//函数指针做函数参数(函数参数)
void printALLArray(void* arr, int eleSize, int len, void(*print)(void *))
{
	char *start = (char *)arr;

	for (int i = 0; i < len; i++)
	{
		char *eleADDr = start + i * eleSize;
		print(eleADDr);
	}
}

void MyPrint(void *data)
{
	int *p = (int *)data;
	cout << *p << endl;
}

typedef struct Person
{
	char name[64];
	int age;
}Person;

void MyPrintPerson(void *data)
{
	Person* person = (Person *)data;
	cout << "Name:" << person->name << endl;
	cout << "Age:" << person->age << endl;
}
void test3()
{
	int arr[] = { 1,2,3,4,5 };
	printALLArray(arr, sizeof(int), 5, MyPrint);
	cout << "First" << endl;

	Person persons[] =
	{
	{"aaa",10},
	{"bbb",20},
	{"ccc",30},
	{"ddd",40},
	{"eee",50},
	};

	cout << "Second" << endl;
	printALLArray(persons, sizeof(Person), 5, MyPrintPerson);

}

这里实现了整形数组和结构体数组的打印输出,即利用了函数指针的回调功能。
最后是测试这几个函数的使用:

int main()
{
	test();
	cout << "test1()" << endl;
	test1();
	cout << "test2()" << endl;
	test2();
	cout << "test3()" << endl;
	test3();

	system("pause");
	return 0;
}

这个函数的输出为:

int myfunc(int a, char b)
int=10,char=a
int myfunc(int a, char b)
int=20,char=b
int myfunc(int a, char b)
int=30,char=c
pFunc1 size:%d
4
int myfunc(int a, char b)
int=40,char=d
pFunc2 size:%d
4
int myfunc(int a, char b)
int=50,char=p
pFunc3 size:%d
4
test1()
11
22
33
test2()
ret=10
test3()
1
2
3
4
5
First
Second
Name:aaa
Age:10
Name:bbb
Age:20
Name:ccc
Age:30
Name:ddd
Age:40
Name:eee
Age:50

这就是我对函数指针的一些认识,如果有不正确的地方欢迎大家批评指正。最后贴上完整代码:

#include<iostream>

using namespace std;

int myfunc(int a, char b)
{
	cout << "int myfunc(int a, char b)" << endl;
	printf("int=%d,char=%c\n", a, b);
	return 0;
}

void test()
{
	//定义函数类型,通过类型来定义函数指针
	typedef int(FUN_TYPE)(int, char);
	FUN_TYPE *pFUNC1 = myfunc;

	pFUNC1(10, 'a');
	(*pFUNC1)(20, 'b');
	myfunc(30, 'c');
	cout << "pFunc1 size:%d\n" << sizeof(pFUNC1) << endl;

	//直接定义函数指针类型
	typedef int(*FUNC_P)(int, char);
	FUNC_P pFUNC2 = myfunc;
	pFUNC2(40, 'd');
	cout << "pFunc2 size:%d\n" << sizeof(pFUNC2) << endl;

	//把指针转换为函数指针类型写法
	int(*pFUNC3)(int, char) = (int(*)(int, char))NULL;
	pFUNC3 = myfunc;
	pFUNC3(50, 'p');
	cout << "pFunc3 size:%d\n" << sizeof(pFUNC3) << endl;
}

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

int fun2(int a, int b)
{
	return a + b - 10;
}

int fun3(int a, int b)
{
	return a * b;
}

int fun4(int a,int b)
{
	return a / b;
}

//函数可以做另外一个函数的参数
void doLogic(int(*pFUN)(int, int))
{
	int a = 10;
	int b = 10;
	int ret = pFUN(a, b);
	cout << "ret=" << ret << endl;
}

//函数指针数组
void fun11()
{
	cout << "11" << endl;
}

void fun22()
{
	cout << "22" << endl;
}

void fun33()
{
	cout << "33" << endl;
}

void test1()
{
	void(*fun_array[3])();
	fun_array[0] = fun11;
	fun_array[1] = fun22;
	fun_array[2] = fun33;

	for (int i = 0; i < 3; i++)
	{
		fun_array[i]();
	}
}

void test2()
{
	doLogic(fun2);
}

//函数指针做函数参数(函数参数)
void printALLArray(void* arr, int eleSize, int len, void(*print)(void *))
{
	char *start = (char *)arr;

	for (int i = 0; i < len; i++)
	{
		char *eleADDr = start + i * eleSize;
		print(eleADDr);
	}
}

void MyPrint(void *data)
{
	int *p = (int *)data;
	cout << *p << endl;
}

typedef struct Person
{
	char name[64];
	int age;
}Person;

void MyPrintPerson(void *data)
{
	Person* person = (Person *)data;
	cout << "Name:" << person->name << endl;
	cout << "Age:" << person->age << endl;
}

void test3()
{
	int arr[] = { 1,2,3,4,5 };
	printALLArray(arr, sizeof(int), 5, MyPrint);
	cout << "First" << endl;

	Person persons[] =
	{
	{"aaa",10},
	{"bbb",20},
	{"ccc",30},
	{"ddd",40},
	{"eee",50},
	};

	cout << "Second" << endl;
	printALLArray(persons, sizeof(Person), 5, MyPrintPerson);

}

int main()
{
	test();
	cout << "test1()" << endl;
	test1();
	cout << "test2()" << endl;
	test2();
	cout << "test3()" << endl;
	test3();

	system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值