网站首页 > 资源文章 正文
void (*Fun)(void);假如就只是写上这样的一句代码,显然这就是定义了一个变量Fun,这个Fun变量是一个指针,指向返回值和参数都是空的函数的指针。而typedef void(*Func)(void) 是函数指针的类型定义,代表了一种新的类型。作用是声明一个 void(*)()类型的函数指针Func。这些基础知识我们一步一步来学习了解一下。
typedef/define的基本概念
typedef
为现有类型创建一个新的名字,基本用法举例:
typedef unsigned char UCHAR;//右边代替左边
typedef能隐藏笨拙的语法构造以及平台一些相关的数据类型,可以使得代码更美观,可维护性、可移植性、可读性更强,来举个例子吧。
//定义一个函数
void tech(void) { printf("tech dreamer"); }
void main()
{
//定义一个指针,指针的名字叫func
void (*func)();//tech函数带参数的话也可以
func = &tech; //&可以不加
func(); //第一种调用方式,带参数也可以
(*func)(); //第二种调用方式,带参数也可以
}
为了写出更加美观和可读性强的代码,我们经常使用typedef来定义一个类型,代码如下。
void tech(void) { printf("tech dreamer"); }
//命名一个类型,那么这个时候func不可以直接调用,而是一个类型了
typedef void (*func)();
void main()
{
//定义一个可调用的指针变量(函数):myfunc
func myfunc;
myfunc = &tech; //&可以不加
myfunc(); //第一种调用方式,带参数也可以
(*myfunc)(); //第二种调用方式,带参数也可以
}
与define的区别
typedef 是在编译过程中被解析的,而#define是在编译之前的预处理时被破解的;#define只是对所定义的别名的简单替换,而typedef可以做到#define能做到的所有事情,而且可以做得更好
函数指针的基本概念
我们先了解一下函数指针的基本概念,函数指针是指向函数的指针变量,他的本质是一个指针变量,函数的指针定义:int (*f)(int);
//举个例子声明一个函数指针
int (*f)(int x);
f=func; /* 将func函数的首地址赋给指针f */
与指针函数的区别
指针函数是返回值是某一类型指针的函数,即本质是一个函数,指针函数定义:int *fun(int x);,举个例子如下
float *fun();
float *p;
p = fun(a);
这个函数的返回值是一个地址值,赋值给用同类型的指针变量p,也就是说,指针函数一定有函数返回值,而且在主调函数中,函数返回值必须赋给同类型的指针变量。
两者主要的区别是一个是指针变量,一个是函数。
typedef void(*Func)(void)为什么能这么用?
可能我们有这样的疑问,typedef一般的用法不是取个新名字吗?如果仿照变量类型声明,应该是这样typedef void(*)() variable;才比较眼熟易懂。
说一说我的理解,我们知道C语言的函数在被调用的时候是执行了一条转移指令,这条指令包含要转移到的地方的数据,同理,变量代表了一个地址,当你引用一个变量的时候,计算机会把这个地址的数据拿出来参与运算。
那么函数名也是一样,函数名代表的是一段代码的入口地址,引用了这个函数,那么计算机会使用转移指令转移到函数名代表的地址。
所以typedef void(*Func)(void)相当于定义了一种类型,这个类型具有下面的特征:他是一个函数,没有返回值,没有参数。
因为处理器在进行上下文切换或者转移的时候要进行现场保护,不同的函数对现场保护的内容可能不一样,传入的参数使用的栈也不一样,相同类型的函数保证了现场保护的内容是一样的,参数的形式也是一样的。所以这样使用可以像用指针引用数据一样使用函数。
typedef void(*Func)(void)的应用
用法的好处,定义一个函数指针类型。
例子:
上面说到typedef void(*Func)(void)可以使得代码更可移植性、可读性更强,我们举个例子,有三个类型相似或功能相似的函数:
//构造3个通用函数
void TEST1(void) { printf("test1\n"); }//函数定义
void TEST2(void) { printf("test2\n"); }//函数定义
void TEST3(void) { printf("test3\n"); }//函数定义
... ...
//声明
typdef void (*func)(void);
再来定义一个调用的函数
void test(int i)
{
func vTask[3] = {&TEST1, &TEST2, &TEST3};
func fun = vTask[i];
(*fun)();
}
在main函数中,分别调用这几个不同输入参数的函数
void main()
{
test(0);
test(1);
test(2);
return 0;
}
这样的话代码就看着很舒服了。
猜你喜欢
- 2025-01-12 恶意代码常见的编程方式
- 2025-01-12 LPL:上野不变,中下换人!LNG 2025年阵容组建完毕
- 2025-01-12 实现多态必须满足什么条件
- 2025-01-12 西门子S7-300 SCL编程笔记(附实例)
- 2025-01-12 OLED弧面显示屏VR问世 Void游戏公园团战指日可待
- 2025-01-12 C++如何定义类对象?有哪几种方式?linux C++第17讲
- 2025-01-12 C语言随机数生成
- 2025-01-12 UCGVR主题公园“The Void”宣传影像(内含Gif)
- 2025-01-12 《Void Path》10月30日登陆Steam 日恐诡异探索
- 2025-01-12 西门子S7-1200/1500PLC的程序组成之FC的应用技巧
你 发表评论:
欢迎- 05-1430个在线地图瓦片URL分享
- 05-1425个在线地图瓦片URL分享
- 05-14PixelStyle for Mac(mac照片编辑器)
- 05-14一篇文章带你了解CSS3 3D 转换知识
- 05-14我们的世界是假的?马斯克:我们生活在高文明模拟的矩阵游戏中
- 05-14【视觉AI的基石】斯坦福大学笔记!带你吃透卷积神经网络 (CNN)
- 05-14潮流 | 通过AAPE的新价目,无虑入荷未来主义服饰
- 05-14身份证查询服务API:准确识别身份证信息
- 最近发表
- 标签列表
-
- 电脑显示器花屏 (79)
- 403 forbidden (65)
- linux怎么查看系统版本 (54)
- 补码运算 (63)
- 缓存服务器 (61)
- 定时重启 (59)
- plsql developer (73)
- 对话框打开时命令无法执行 (61)
- excel数据透视表 (72)
- oracle认证 (56)
- 网页不能复制 (84)
- photoshop外挂滤镜 (58)
- 网页无法复制粘贴 (55)
- vmware workstation 7 1 3 (78)
- jdk 64位下载 (65)
- phpstudy 2013 (66)
- 卡通形象生成 (55)
- psd模板免费下载 (67)
- shift (58)
- localhost打不开 (58)
- 检测代理服务器设置 (55)
- frequency (66)
- indesign教程 (55)
- 运行命令大全 (61)
- ping exe (64)
本文暂时没有评论,来添加一个吧(●'◡'●)