typedef 函数指针的用法

本文深入探讨了C++中函数指针的概念及应用,重点讲解了typedef如何简化函数指针的定义,以及其在函数模板和具体实例中的区别与联系。通过实例演示了如何使用typedef定义函数指针别名,实现函数之间的灵活调用。

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

“做学问就要有打破沙锅问到底的精神!”

碰到问题就绕着走,以后碰到了要再花一倍时间来弄懂它,

既然始终绕不开,索性就把他解决掉!!!

目录

1、用法1:定义指向特定类型函数的指针别名,注意主语是指针。语法:typedef int (*MYFUN)(int, int); 

2、用法2:typedef 给变量类型定义一个别名.

3、实例

4 、与函数模板的区别

5、有无typedef函数指针的区别



 

3、实例

 typedef 行为有点像 #define 宏,用其同义字替代实际类型,不同点:typedef 在编译时被解释,因此让编译器来应付超越预处理器能力的文本替换

1、用法1:定义指向特定类型函数的指针别名,注意主语是指针。语法:typedef int (*MYFUN)(int, int); 


主要用于定义一种指针,使其可以指向某一类形参类型相同返回值相同函数,通过指针的使用,使用户根据需要可以在这些函数之间方便的跳转。

上面的例子定义MYFUN 是一个(函数指针, 函数类型是带(两个int 参数), 返回(一个int) 。

分析这种形式的定义的时候可以用下面的方法:

 先去掉(typedef) 和(别名剩下的就是(原变量的类型).

比如,去掉typedef和MYFUN以后就剩: int (*)(int, int),要特别注意,这个形式其实表示的是一个(指向某种特定类型函数的指针),本例中函数类型是带(两个int 参数), 返回(一个int)的函数。 typedef int (*MYFUN)(int, int) 的作用其实就是在给int (*)(int, int)这个指针函数定义(别名)

typedef char(*pFun)(int)  //也可写成:char(*pFun)(int);
/*typedef的功能是定义新的类型。第一句就是定义了一种PFUN的类型,
并定义这种类型为指向某种函数的指针,这种函数以一个int为参数并返回char类型。*/

char glFun(int a){return;}
//定义了一个函数glFun().该函数正好是一个以int为参数返回char的函数。

void main()

{

pFun =glFun; //对指针进行赋值。

(*pFun)(2);  //通过指针调用函数glFun。

}

2、用法2:typedef 给变量类型定义一个别名.

typedef struct{ 
int a; 
int b; 
}MY_TYPE; 

这里把一个未命名结构直接取了一个叫MY_TYPE的别名, 这样如果你想定义结构的实例的时候就可以这样: 

MY_TYPE tmp;

3、实例

//#include<iostream.h>
#include<stdio.h>


typedef int (*FP_CALC)(int, int);
//注意这里不是函数声明而是函数定义,它是一个地址,你可以直接输出add看看
int add(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
int mul(int a, int b)
{
return a * b;
}
int div(int a, int b)
{
return b? a/b : -1;
}

//定义一个函数,参数为op,返回一个指针,该指针类型为FP_CALC,它是一个拥有两个int参数、
//返回类型为int 的函数指针。它的作用是根据操作符返回相应函数的地址;
//它的作用其实是引入第三个参数,来选择我究竟选择“+”、“-”、“*”,“/”哪一个运算式;
FP_CALC calc_func(char op)
{
switch (op)
{
case '+': return add;//返回函数的地址
case '-': return sub;
case '*': return mul;
case '/': return div;
default:
return NULL;
}
return NULL;
}


//s_calc_func为函数,它的参数是 op,
//返回值为一个拥有两个int参数、返回类型为int 的函数指针
//它的功能类似于calc_func(op),其实它最终也是调用的calc_func(op)
//说明定义函数指针的方式非常简洁;
int (*s_calc_func(char op)) (int, int)
{
return calc_func(op);
}


//最终用户直接调用的函数,该函数接收两个int整数,和一个算术运算符,返回两数的运算结果
int calc(int a, int b, char op)
{
FP_CALC fp = calc_func(op); //根据预算符得到各种运算的函数的地址
int (*s_fp)(int, int) = s_calc_func(op);//用于测试
//ASSERT(fp == s_fp);   // 可以断言这俩是相等的

if (fp) return fp(a, b);//根据上一步得到的函数的地址调用相应函数,并返回结果
else return -1;

//以下这几种为函数赋值的方法都是可以的,
//if (fp == s_fp) return s_fp(a, b);//根据上一步得到的函数的地址调用相应函数,并返回结果
//if (fp) return (*fp)(a, b);//根据上一步得到的函数的地址调用相应函数,并返回结果

}
void main()
{
int a = 110, b = 20;
printf("calc(%d, %d, %c) = %d\n", a, b, '+', calc(a, b, '+'));
printf("calc(%d, %d, %c) = %d\n", a, b, '-', calc(a, b, '-'));
printf("calc(%d, %d, %c) = %d\n", a, b, '*', calc(a, b, '*'));
printf("calc(%d, %d, %c) = %d\n", a, b, '/', calc(a, b, '/'));
}

4 、与函数模板的区别

函数模板,可以传递类型参数给到模板,让其根据需要生成我们需要的函数代码,这些代码的特点是参数类型可以不同,但是函数名相同,这样就方便我们调用。详见:C++模板简介。

typedef定义的是指向某一类函数的指针,这一类函数的参数类型和返回值类型都是相同的,只是函数名不同,用指针的的方法,将相同参数类型,但函数名不同的函数统一起来,方便我们使用。

二者目的相同,都是为了实现编写代码的简洁,但途径有所不同,函数模板是从函数生成的角度出发,生成函数名一致参数不同的代码;typedef是将函数名不同,参数类型相同的函数名称用指针别名的方法统一起来。

5、有无typedef函数指针的区别

typedef int(*pSum)(int a,int b);  //有typedef时,pSum是一个指针类型,他可以初始化实例;
int(*pSum)(int a,int b); //无typedef时,pSum仅仅是一个指针。


(1)有typedef时

#include "stdafx.h"

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

int main(int argc, char* argv[])
{
	int(*pSum)(int a, int b);
	// pSum test; 这样写是错误的,在这里不能象前面那个例子用函数指针声明实例
	pSum = Sum;
	printf("%d\n", (*pSum)(16, 2));
	return 0;

}


(2)没有typedef时:

#include "stdafx.h"

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

int main(int argc, char* argv[])
{
    int(*pSum)(int a,int b); 
    // pSum test; 这样写是错误的,在这里不能象前面那个例子用函数指针声明实例
    pSum=Sum;
    printf("%d\n",(*pSum)(16,2));
    return 0;  

  }

参考学习了“code2012“的:https://www.cnblogs.com/shenlian/archive/2011/05/21/2053149.html,谢谢!

<think>好的,用户想了解C或C++函数指针的使用方法和示例。首先,我需要回忆一下函数指针的基本概念。根据引用[2]和[3],函数指针是指向函数的指针变量,可以用来调用函数。那用户可能需要知道如何声明、初始化和使用函数指针。接下来,我得整理一下结构。先从定义开始,说明函数指针的声明方式,比如如何根据函数原型来声明指针。例如,一个返回int,参数为两个int的函数,其指针类型是int(*)(int,int)。然后,给出赋值和调用的方法,比如直接指向函数名或者使用取地址符号,调用时可以用(*ptr)()或者直接ptr()。 然后,考虑应用场景,比如回调函数,这在排序或事件处理中很常见。引用[3]中的例子是Add函数,可以演示如何用函数指针调用。另外,引用[2]中的例子展示了指针函数和函数指针的区别,可能需要强调两者的不同,避免混淆。 还要注意示例代码的正确性,确保语法正确,比如在C++中使用using或typedef来简化声明。比如typedefint (*FuncPtr)(int, int)可以让代码更易读。此外,动态绑定和多态的例子,比如根据输入选择不同的操作函数,这能展示函数指针的灵活性。用户可能还关心常见错误,比如函数指针类型不匹配导致的错误,或者空指针调用的问题。但用户的问题主要是用法和示例,这部分可能需要放在注意事项里简要提及。最后,生成相关问题,帮助用户深入理解,比如函数指针和指针函数的区别,回调函数的应用,C++中的改进方式如std::function等。这样用户可以有进一步学习的路径。 需要确保回答结构清晰,分点说明,每个部分有示例代码,并正确引用提供的资料,比如引用[2]和[3]中的代码片段。同时,检查LaTeX格式是否符合要求,比如行内公式用$...$,独立公式用$$...$$,不过这个问题可能不涉及数学公式,但代码块需要用正确标记。</think>在C/C++中,函数指针是实现动态行为调用的重要工具,以下从5个核心场景详解其用法: ### 一、基础定义与调用 函数指针的声明遵循函数原型规则: ```c int (*func_ptr)(int, int); // 声明指向函数的指针 ``` 赋值时可直接取函数地址: ```c int Add(int a, int b) { return a + b; } func_ptr = &Add; // 或 func_ptr = Add; ``` 调用方式具有等价性: ```c int result = (*func_ptr)(3,5); // 传统方式 int result = func_ptr(3,5); // C++简化写法 ``` ### 二、回调函数实战 在排序算法中应用(参考qsort原型): ```c void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); int compare_int(const void *a, const void *b) { return *(int*)a - *(int*)b; } int arr[] = {5,2,8,1}; qsort(arr, 4, sizeof(int), compare_int); // 通过函数指针注入比较逻辑[^2] ``` ### 三、结构体封装 创建可扩展的接口: ```c typedef struct { int (*open)(const char*); void (*close)(int); } DeviceDriver; int usb_open(const char *dev) { /*...*/ } void usb_close(int fd) { /*...*/ } DeviceDriver usb_driver = {usb_open, usb_close}; ``` ### 四、多态实现 运行时动态绑定: ```c++ void encrypt_AES(const char* data) { /*...*/ } void encrypt_RSA(const char* data) { /*...*/ } void process_data(const char* data, void (*encryptor)(const char*)) { encryptor(data); // 动态选择加密算法 } ``` ### 五、类型安全进阶(C++11) 使用`using`提升可读性: ```cpp using MathFunc = int(*)(int,int); // C++11类型别名 MathFunc func = std::max; ``` #### 注意事项 1. 匹配返回值和参数类型 2. 空指针检查:`if(func_ptr != nullptr)` 3. C++推荐使用`std::function`和lambda表达式 ```mermaid graph TD A[函数指针声明] --> B[赋值函数地址] B --> C[调用函数指针] C --> D[回调函数应用] D --> E[多态实现] E --> F[类型安全封装] ```
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值