函数指针的作用以及好处

<span style="font-family:SimSun;">//函数指针使用的例子</span>
<span style="font-family:SimSun;">#include <stdio.h>
#include <string.h>
 
char * fun(char * p1,char * p2)
{
  int i = 0;
  i = strcmp(p1,p2);
 
  if (0 == i)
  {
    return p1;
  }
  else
  {
    return p2;
  }
}
 
int main()
{
  char * (*pf)(char * p1,char * p2);
  pf = &fun;
  (*pf) ("aa","bb");
  return 0;
}</span>

我们使用指针的时候,需要通过钥匙(“*”)来取其指向的内存里面的值,函数指针使用也如此。通过用(*pf)取出存在这个地址上的函数,然后调用它。

  这里需要注意到是,在VS2015里,给函数指针赋值时,可以用&fun或直接用函数名fun。这是因为函数名被编译之后其实就是一个地址,所以这里两种用法没有本质的差别。

看下另外的例子:

<span style="font-family:SimSun;">void Function()
{
  printf("Call Function!\n");
}
int main()
{
  <span style="line-height: 25.2px;">void (*p)();</span>
  *(int*)&p=(int)Function;
  (*p)();
  return 0;
} </span>
首先来看这行代码:

void (*p)();

这行代码定义了一个指针变量p,p指向一个函数,这个函数的参数和返回值都是void。
&p是求指针变量p本身的地址,这是一个32位的二进制常数(32位系统)。
(int*)&p表示将地址强制转换成指向int类型数据的指针
(int)Function表示将函数的入口地址强制转换成int类型的数据。
分析到这里,相信你已经明白*(int*)&p=(int)Function;表示将函数的入口地址赋值给指针变量p。

那么(*p) ();就是表示对函数的调用。

其实函数指针与普通指针没什么差别,只是指向的内容不同而已。

主要作用:

1.       实现面向对象编程中的多态性

2.       回调函数


比如:

int fun1(char *str );
int fun2(char *str);

有一个结构体维护:
typedef int (*fun)(char *str);

struct
{
      fun f;
}Fun;


最后有一个调用函数:
int call(char * str)
{
     return Fun.f(str);
}

2. Windows编程中的事件handle函数,即回调函数,在事件队列都是一个函数指针来保存的:


typedef void (*event_handler) (unsigned int para1, unsigned int para2);
struct event {
  unsigned int ev_id;
  event_handler handler;
};

struct event event_queue[MAX_EVENT_SIZE];

程序可以通过扫描这个事件队列来获取每个事件对应的处理函数,然后调用它,即为回调函数。

<think>好的,我现在需要回答用户关于C/C++中函数指针和指针函数的区别及使用方法的问题。首先,我得先理清楚这两个概念的定义,避免混淆。 根据用户提供的引用内容,指针函数是一个返回指针的函数,而函数指针是一个指向函数的指针变量。我需要确保在解释时能够明确两者的不同点,比如指针函数本质是函数,返回指针;函数指针本质是指针,指向函数的地址。 接下来,我需要分别详细说明两者的语法结构和使用方法。例如,指针函数的声明可能是`int *func(...)`,而函数指针的声明则是`int (*func)(...)`。要注意这里的括号位置不同,容易让人混淆,需要重点强调语法上的差异。 然后,需要举例子来帮助理解。比如指针函数可以返回动态分配的内存地址,避免返回局部变量的指针,这一点引用中提到了,应该重点说明。而函数指针的例子可以展示如何指向不同的函数,并通过指针调用它们,比如引用中的函数指针数组实现菜单系统的例子。 还要注意两者的应用场景。指针函数适合需要返回大量数据的情况,如结构体指针;函数指针则用于回调函数、策略模式等动态调用函数的场景。引用中的例子,如菜单系统,可以具体说明其实际用途。 另外,常见错误也需要提及,比如指针函数返回局部变量指针导致的问题,以及函数指针声明时可能出现的语法错误,如遗漏括号导致成为函数声明而非指针。 最后,总结两者的区别,确保用户能够清晰区分。同时,生成相关问题,帮助用户进一步学习,比如性能影响、回调函数应用和动态内存返回的注意事项。 需要确保整个回答结构清晰,步骤明确,使用中文,并且正确应用LaTeX格式,行内公式用$...$,独立公式用$$...$$。同时检查引用标注是否正确,每个引用在回答中适当的位置自然添加标识符。</think>### 函数指针与指针函数的区别及使用方法 #### 1. **指针函数(Pointer Function)** - **定义**:本质是一个函数,其返回值类型为指针。 - **语法**:`返回类型* 函数名(参数列表)` 例如: ```c int* create_array(int size); // 返回int类型指针的函数 ``` - **核心用途**: 从函数返回大量数据(如结构体指针、动态分配的内存地址)[^2]。 - **注意事项**: - 避免返回局部变量的指针(局部变量在函数结束后会被回收)。 - 应使用动态内存(如`new`或`malloc`)确保指针有效性。 **示例**: ```cpp int* generate_data() { int* arr = new int[10]; // 堆上动态分配 for (int i=0; i<10; i++) arr[i] = i; return arr; // 返回堆内存指针 } ``` #### 2. **函数指针(Function Pointer)** - **定义**:本质是一个指针变量,指向函数的入口地址。 - **语法**:`返回类型 (*指针名)(参数列表)` 例如: ```cpp void (*print_func)(int); // 指向参数为int、返回void的函数 ``` - **核心用途**: 实现回调函数、动态绑定函数逻辑(如策略模式、菜单系统)[^3]。 - **初始化与调用**: ```cpp void print_num(int x) { cout << x; } print_func = &print_num; // 指向函数 (*print_func)(5); // 通过指针调用 ``` **高级用法(函数指针数组)**: ```cpp bool (*compare[3])(int, int) = {equal, great, less}; // 引用[3]中的示例 compare[0](a, b); // 调用第一个比较函数 ``` --- #### 3. **关键区别** | 特性 | 指针函数 | 函数指针 | |-----------------|----------------------------------|-----------------------------------| | **本质** | 函数(返回指针) | 指针(指向函数地址) | | **声明语法** | `int* func()` | `int (*func)()` | | **内存分配** | 函数栈帧中运行,返回需动态内存 | 仅存储函数地址,无需额外分配 | | **典型错误** | 返回局部变量指针导致悬空引用 | 声明时遗漏`*`或参数列表不匹配 | --- #### 4. **应用场景** - **指针函数**: - 动态创建数据结构(如链表节点)并返回其指针。 - 从文件读取数据后返回缓冲区的指针。 - **函数指针**: - 实现回调机制(如事件处理、排序算法中的比较函数)。 - 构建插件系统,动态加载函数逻辑。 --- #### 5. **常见问题** - **如何避免指针函数的内存泄漏?** 确保调用方在接收返回的指针后负责释放内存(如`delete[]`或`free()`)。 - **函数指针的类型安全如何保证?** 使用`typedef`定义明确的函数签名: ```cpp typedef void (*Callback)(int); Callback handler = &event_handler; // 类型匹配检查 ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值