函数指针数组的例子

来看这么一段代码:

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
 
 
enum response_type
{
	DUMP,
	SECOND_CHANCE,
	MARRIAGE
};
 
 
typedef struct
{
	char *name;
	enum response_type type;
}response;
 
 
void dump(response r)
{
	printf("Dear %s, \n", r.name);
	puts("dump function\n");
}
 
 
void second_chance(response r)
{
	printf("Dear %s, \n", r.name);
	puts("second_chance function\n");
}
 
 
void marriage(response r)
{
	printf("Dear %s, \n", r.name);
	puts("marriage function\n");
}
 
 
int main()
{
	response r[] = {
		{"Mike", DUMP}, {"Luis", SECOND_CHANCE},
		{"Matt", SECOND_CHANCE}, {"William", MARRIAGE}
	};
 
	int index;
	for (index = 0; index < 4; index++)
	{
		switch (r[index].type)
		{
		case DUMP:
			dump(r[index]);
			break;
		case SECOND_CHANCE:
			second_chance(r[index]);
			break;
		case MARRIAGE:
			marriage(r[index]);
			break;
		default:
			break;
		}
	}
 
 
	return 0;
}


这个程序是可以执行的,并且是正确的。但是代码中充斥着大量的函数调用,每次都需要根据r的type来调用函数,看起来像这样:

		switch (r.type)
		{
		case DUMP:
			dump(r[index]);
			break;
		case SECOND_CHANCE:
			second_chance(r[index]);
			break;
		case MARRIAGE:
			marriage(r[index]);
			break;
		default:
			break;
		}

这么一来,如果增加r的第四种类型,那就不得不修改程序中每一个像这样的地方。很快,就有一大堆代码需要维护,而且这样很容易出错。



下面来看,如何通过创建函数指针数组来替代上面的这些代码:

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
 
 
enum response_type
{
	DUMP,
	SECOND_CHANCE,
	MARRIAGE
};
 
 
typedef struct
{
	char *name;
	enum response_type type;
}response;
 
 
void dump(response r)
{
	printf("Dear %s, \n", r.name);
	puts("dump function\n");
}
 
 
void second_chance(response r)
{
	printf("Dear %s, \n", r.name);
	puts("second_chance function\n");
}
 
 
void marriage(response r)
{
	printf("Dear %s, \n", r.name);
	puts("marriage function\n");
}
 
 
void (*replise[])(response) = { dump, second_chance, marriage };
 
 
int main()
{
	response r[] = {
		{"Mike", DUMP}, {"Luis", SECOND_CHANCE},
		{"Matt", SECOND_CHANCE}, {"William", MARRIAGE}
	};
 
	int index;
	for (index = 0; index < 4; index++)
	{
		replise[r[index].type](r[index]);
	}
 
 
	return 0;
}

可以看到,我们这里已经没有了那么一大段的switch代码。但是程序依然是和上边的初始程序一样的运行结果。

 

就这么一行代码,代替了上面的一大段switch代码!

 

那么我们现在来看增加r的第四种类型时候的代价:

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
 
 
enum response_type
{
	DUMP,
	SECOND_CHANCE,
	MARRIAGE,
	DEAD
};
 
 
typedef struct
{
	char *name;
	enum response_type type;
}response;
 
 
void dump(response r)
{
	printf("Dear %s, \n", r.name);
	puts("dump function\n");
}
 
 
void second_chance(response r)
{
	printf("Dear %s, \n", r.name);
	puts("second_chance function\n");
}
 
 
void marriage(response r)
{
	printf("Dear %s, \n", r.name);
	puts("marriage function\n");
}
 
 
void dead(response r)
{
	printf("Dear %s, \n", r.name);
	puts("dead function\n");
}
 
 
void (*replise[])(response) = { dump, second_chance, marriage, dead };
 
int main()
{
	response r[] = {
		{"Mike", DUMP}, {"Luis", SECOND_CHANCE},
		{"Matt", SECOND_CHANCE}, {"William", MARRIAGE},
		{"Zeng", DEAD},
	};
 
	int index;
	for (index = 0; index < 5; index++)
	{
		replise[r[index].type](r[index]);
	}
 
 
	return 0;
}


对比一下,可以看到,仅仅需要修改3个地方,便能够加入一个对应的函数!维护代价大大的减少了!


<think>嗯,用户想了解如何在C++中使用函数指针数组。首先,我需要回顾一下用户之前的问题和我的回答,确保内容连贯。之前我讲解了函数指针的基本定义、成员函数指针、动态绑定和性能优化,现在需要扩展到数组使用。 用户提供的引用资料提到了函数指针数组和指针数组的区别,比如引用[3]中的例子区分了指针数组数组指针。需要明确函数指针数组的定义,即数组中的每个元素都是函数指针。 首先,我应该从基本语法开始。函数指针数组的声明应该是什么样的?例如,返回类型为void,无参数的函数指针数组可以写成void (*funcArray[])()。然后,初始化数组,将具体的函数地址赋给各个元素。引用[2]中的示例展示了函数指针数组的初始化和调用,可以借鉴。 接下来,需要给出一个完整的示例代码,展示如何定义、初始化和调用函数指针数组。比如,定义三个函数add、subtract、multiply,然后创建一个包含这三个函数指针数组,通过循环调用它们。同时,注意C++的作用域和类型安全,可能提到使用typedef或using来简化复杂的声明。 还要考虑类型安全的问题,比如C风格的函数指针和C++的函数指针在类型转换上的差异,以及如何避免不匹配的参数导致的错误。例如,使用static_cast进行显式转换,确保类型一致。 另外,用户可能对成员函数指针数组感兴趣,但之前的回答已经涉及了成员函数指针,这里可以简要提及,但重点放在普通函数的数组上。可以提到成员函数指针数组需要结合对象实例来调用,语法较为复杂,可能不适合初学者,所以主要展示普通函数的例子。 用户的问题中还提到了命令行参数和指针数组的应用,如引用[2]中的例子,但当前问题聚焦于函数指针数组,所以这部分可能作为扩展内容,暂时不深入。不过,可以提到函数指针数组在实现状态机、回调机制等场景的应用,增强实用性。 需要注意用户的代码示例是否正确,比如检查语法是否正确,是否包含必要的头文件,using namespace std是否合适,或者是否应该更规范地使用std::前缀。例如,在示例代码中,cout和endl需要确保有正确的命名空间引用。 最后,生成相关问题时要围绕函数指针数组的扩展应用、类型安全优化、与Lambda表达式的结合,以及对比C语言实现差异。这些问题应帮助用户深入理解并解决可能遇到的进阶问题。 总结步骤:定义函数指针数组、初始化、调用,提供示例代码,讨论类型安全和应用场景,最后生成相关问题。确保引用之前的回答中的引用标记,如[^1]和[^2],保持一致性。</think>### C++ 中函数指针数组使用方法 #### 1. **函数指针数组的定义** 函数指针数组是**存储多个函数指针数组**,每个元素指向一个具有相同签名(返回值类型和参数列表)的函数。其语法格式为: ```cpp returnType (*arrayName[size])(parameterTypes); ``` 或使用 `using` 别名简化: ```cpp using FuncPtr = returnType (*)(parameterTypes); FuncPtr funcArray[size]; ``` #### 2. **初始化与调用示例** 以下示例展示如何定义、初始化并调用函数指针数组: ```cpp #include <iostream> using namespace std; // 定义三个同签名的函数 int add(int a, int b) { return a + b; } int subtract(int a, int b) { return a - b; } int multiply(int a, int b) { return a * b; } int main() { // 定义函数指针数组并初始化 int (*funcArray[3])(int, int) = {add, subtract, multiply}; // 遍历调用数组中的函数 for (int i = 0; i < 3; i++) { cout << "Result: " << funcArray[i](10, 5) << endl; } // 输出: // Result: 15 // Result: 5 // Result: 50 return 0; } ``` #### 3. **类型安全与显式转换** C++ 对函数指针类型有严格检查。若需兼容不同参数类型的函数,需使用 `static_cast` 显式转换: ```cpp using GenericFunc = void (*)(); void printHello() { cout << "Hello"; } void printNumber(int x) { cout << x; } int main() { GenericFunc funcArray[2] = { reinterpret_cast<GenericFunc>(printHello), reinterpret_cast<GenericFunc>(printNumber) }; // 调用时需强制转换回原类型(存在风险) (reinterpret_cast<void(*)(int)>(funcArray[1]))(42); // 输出 42 return 0; } ``` **注意**:此方法可能引发未定义行为,需谨慎使用。 --- #### 4. **应用场景** - **状态机**:通过函数指针数组实现不同状态的处理逻辑。 - **插件/回调系统**:动态注册外部函数实现扩展功能。 - **数学运算集**:统一管理多种算法(如加减乘除)的调用入口。 #### 5. **与 C 语言的区别** C++ 要求更严格的类型匹配。C 语言中允许隐式转换函数指针类型,而 C++ 需显式使用 `reinterpret_cast`(但可能破坏类型安全)[^2]。 --- ### 示例进阶:命令行参数解析 结合函数指针数组与 `main` 函数的参数列表,可实现动态命令解析: ```cpp #include <iostream> #include <string> using namespace std; void help() { cout << "显示帮助信息" << endl; } void version() { cout << "版本 1.0" << endl; } int main(int argc, char* argv[]) { // 定义命令与函数的映射 using CommandFunc = void (*)(); struct Command { string name; CommandFunc func; }; Command commands[] = { {"--help", help}, {"--version", version} }; // 解析命令行参数 for (int i = 1; i < argc; i++) { for (const auto& cmd : commands) { if (argv[i] == cmd.name) { cmd.func(); break; } } } return 0; } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值