函数指针做为参数的例子

本文详细介绍了C++中函数指针的应用及多态实现方式,通过实例展示了如何使用函数指针来实现不同函数的选择调用,以及如何通过虚函数实现多态性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1

2

#include <iostream>

using namespace std;

void f1(){std::cout<<"---f1---"<<endl;}
void f2(){std::cout<<"---f2---"<<endl;}
void f3(){std::cout<<"---f3---"<<endl;}

typedef void (*Menu)();
int main()
{
	
	Menu a[]={f1,f2,f3};
	for(int i=1;i;)
	{
		std::cout<<"1----display f1"<<endl;
		std::cout<<"2----display f1"<<endl;
		std::cout<<"3----display f1"<<endl;
		std::cout<<"Enter your chioce:"<<endl;
		cin >> i;
		switch (i)
		{
			case 1:a[0]();break;
			case 2:a[1]();break;
			case 3:a[2]();break;
			case 0:return 0;
			default :std::cout<<"you entered a wrong key.\n";
		}
	
	}
	return 0;
}


#include <iostream>

using namespace std;

typedef void (*FuncPtr)(void);

void fn()
{
	cout << "void fn()" << endl;
}



int main()
{
	cout << "第一种定义形式" << endl;
	void (*p)();  //定义函数指针,不是声明 
	p = fn;       //初始化 ,,初始化时注意函数参数和返回值类型要一致 
	p();
	
	cout << "第二种定义形式" << endl;
	void (*pt)() = fn;//定义函数指针,并且初始化, 初始化时注意函数参数和返回值类型要一致 
	pt(); 
	
	cout << "第三种定义形式" << endl;
	FuncPtr fp = fn;   //定义返回值和参数都为空的函数指针,并初始化 ,,初始化时注意函数参数和返回值类型要一致  
	fp();
	
	return 0;
}




<think>嗯,用户想了解C/C++中指针函数作为参数的用法和原理。首先,我需要明确指针函数和函数指针的区别。有时候这两个术语容易混淆,但正确的术语应该是函数指针,也就是指向函数的指针。用户可能指的是将函数指针作为参数传递给其他函数的情况。 根据引用[1],函数指针可以存储函数的地址,这样就能通过指针调用函数。那作为参数的话,主要的作用应该是实现回调函数或者动态调用不同的函数。比如在排序时,可以通过传递不同的比较函数来实现不同的排序方式,这就是qsort函数的做法。 接下来要考虑原理部分。函数指针作为参数时,实际上传递的是函数的入口地址。当调用这个指针时,程序会跳转到对应的函数执行。引用[5]提到参数的入栈顺序是从右到左,这可能与支持可变参数有关,但函数指针作为参数时,调用方式应该和普通函数一样,不过需要正确传递地址。 需要解释为什么使用函数指针作为参数。比如提高灵活性,允许在运行时决定具体调用的函数,或者实现策略模式。引用[3]中提到的例子是关于交换函数需要传递指针,但这里的情况不同,函数指针本身就是地址,所以传递时不需要再取地址,直接使用函数名即可。 还要注意语法,如何声明函数指针参数。比如一个函数接受一个返回int并带有两个int参数函数指针,应该写成int (*func)(int, int)。这里可能容易出错,需要正确使用括号。 另外,引用[4]中的可变参数函数示例,虽然不直接相关,但展示了参数处理的方式,可能和函数指针参数传递有类似之处。不过可变参数更多使用va_list,而函数指针则是直接传递地址。 总结一下,回答需要包括函数指针作为参数的作用(如回调、动态调用)、原理(传递函数地址,通过指针调用)、语法示例,以及应用场景。同时要引用提供的参考资料来支持解释,比如引用[1]和[2]中关于指针存储地址和函数指针使用的部分。 可能还需要对比普通函数调用和通过指针调用的区别,以及为什么这样做更灵活。比如在事件处理、多态实现中的应用。此外,错误使用的情况,比如声明不正确导致的编译错误,也需要提及,帮助用户避免常见错误。</think>### C/C++ 函数指针作为参数的作用与原理 #### 一、函数指针的基本概念 函数指针是一种存储函数内存地址的指针类型,其本质与普通指针类似,但指向的是函数而非数据。通过函数指针,可以间接调用函数,实现动态行为绑定。例如,声明一个函数指针类型: ```c int (*func_ptr)(int, int); // 指向接受两个int参数且返回int的函数的指针 ``` 引用[1]中提到,函数指针类型用于存储函数的地址,这为程序提供了动态调用函数的能力[^1]。 --- #### 二、函数指针作为参数的作用 1. **实现回调机制** 通过将函数指针作为参数传递给其他函数(如库函数或框架接口),可以在特定事件(如排序、事件触发)时回调用户自定义的逻辑。例如,标准库中的`qsort`函数: ```c void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void*, const void*)); ``` 用户通过`compar`参数传入自定义的比较函数,`qsort`在排序过程中动态调用该函数。 2. **支持策略模式** 在需要灵活切换算法或行为的场景中,函数指针允许运行时动态选择不同的实现。例如: ```c void process_data(int *data, int size, int (*algorithm)(int*, int)) { algorithm(data, size); // 动态调用不同算法 } ``` 3. **简化代码耦合** 将函数逻辑解耦为独立模块,通过参数传递实现逻辑组合,避免硬编码。 --- #### 三、函数指针作为参数的原理 1. **内存地址传递** 函数指针参数实际传递的是函数的入口地址。当调用该指针时,程序跳转到对应地址执行函数体。例如: ```c void caller(void (*func)(int)) { func(42); // 通过指针调用函数 } ``` 2. **栈帧与调用约定** 引用[5]指出,C/C++参数入栈顺序为**从右向左**,这种设计支持可变参数函数(如`printf`)。函数指针作为参数时,其地址被压入栈中,调用时通过栈帧恢复执行环境[^5]。 3. **类型安全性** 函数指针的声明需严格匹配目标函数的参数和返回类型,否则会导致未定义行为。 --- #### 四、代码示例 ```c #include <stdio.h> // 定义函数指针类型 typedef void (*Callback)(int); // 接受函数指针作为参数的函数 void event_handler(Callback callback, int value) { printf("事件触发,值=%d\n", value); callback(value); // 回调用户定义的函数 } // 用户自定义的回调函数 void custom_callback(int x) { printf("自定义处理: %d\n", x * 2); } int main() { event_handler(custom_callback, 10); // 传递函数指针 return 0; } ``` 输出: ``` 事件触发,值=10 自定义处理: 20 ``` --- #### 五、注意事项 1. **类型匹配** 函数指针的声明必须与目标函数完全一致(参数类型、返回类型),否则可能引发崩溃。 2. **空指针检查** 调用函数指针前需确保其非空。 3. **作用域限制** 若函数指针指向局部函数(如`static`函数),需确保其在调用时有效。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值