【c语言】指针就该这么学(3)

🌟🌟作者主页:ephemerals__

🌟🌟所属专栏:C语言

目录

一、函数指针

1.函数指针变量的创建

2.函数指针变量的使用

二、typedef关键字

三、函数指针数组

1.函数指针数组的概念        

2.函数指针数组的定义方式

四、转移表

总结


一、函数指针

        在c语言中,不仅有变量的指针,也有函数指针。与变量相同,函数指针存放的是函数的地址,通过函数的地址可以调用该函数

1.函数指针变量的创建

        函数指针的创建方法如下:

类型1 (*变量名)(类型2,类型3......);

与数组指针的定义方式一样,函数指针的变量名也是需要先和*号结合的。不同的是,之后的方括号变成了圆括号。详细说明一下这里的要点:

类型1指的是函数指针指向函数的返回值类型;

类型2、类型3等等都是指向函数的参数类型,参数的数量和类型要和函数的参数保持一致,类型之后的形参名可写可不写。

接下来让我们尝试定义一个函数指针变量,存放函数的地址:

#include <stdio.h>

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

int main()
{
	int a = 3;
	int b = 5;
	int (*pf1)(int, int) = add;
	int (*pf2)(int, int) = &add;
	return 0;
}

注意:以上代码中,pf1和pf2存放的是完全相同的地址。对于函数来讲,函数名之前是否加取地址符号都表示函数的地址,所以&可写可不写。

2.函数指针变量的使用

接下来我们尝试通过函数指针来调用函数:

#include <stdio.h>

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

int main()
{
	int a = 3;
	int b = 5;
	int (*pf)(int, int) = add;
	int ret = pf(a, b);//指针变量的使用
	printf("%d\n", ret);
	return 0;
}

这里使用pf接收了add函数的地址,pf就等价于add,直接传参就可以调用函数。

二、typedef关键字

        我们学习了复杂的指针类型(例如数组指针、函数指针)之后,会发现它们的定义方式较为复杂。那么是否有办法能够让我们简化定义的代码呢?这就需要用到typedef关键字了。

typedef是c语言中的一个关键字,它用于对类型进行重定义,将复杂的类型简单化。

它的使用方法是:

typedef 类型1 类型2;

进行typedef操作之后,类型2与类型1就是等价的。

接下来我们尝试将一些变量类型进行重定义:

#include <stdio.h>

typedef int t;//类型重定义

t main()
{
	t a = 0;
	printf("%d\n", a);
	return 0;
}

运行结果:

这里我们将int类型重定义了一个名字叫 t ,之后的使用当中定义的整形类型都可以用 t 来表示。

对于指针变量,我们也可以这样重定义:

#include <stdio.h>

typedef int* ptr_t;

int main()
{
	int a = 0;
	ptr_t p = &a;
	printf("%p\n", p);
	return 0;
}

运行结果:

可以看到,程序输出了一个地址,我们将整形指针变量重新起名为ptr_t。

接着,我们尝试对数组指针和函数指针类型重定义:

可以看到,对于数组指针或者函数指针类型重定义时,这种语法是不正确的,我们要将新类型名写到*号旁边

这样,对于一些复杂类型的数组指针或者函数指针,我们就可以用简单的单词来表示。

三、函数指针数组

1.函数指针数组的概念        

我们都知道,指针数组就是数组元素都是指针变量。而函数指针数组就是说这个数组当中的元素类型都是函数指针

2.函数指针数组的定义方式

函数指针数组的定义方式如下:

类型1 (*变量名[元素个数])(类型2,类型3......);

从它的定义方式可以看出,函数指针数组的定义方式就是在函数指针的变量名后加上方括号。这里变量名和[]先结合,说明它是一个数组,而数组的元素就是函数指针类型。代码示例:

#include <stdio.h>

void test1()
{
	printf("hehe\n");
}

void test2()
{
	printf("haha\n");
}

void test3()
{
	printf("hello\n");
}

int main()
{
	void (*pfarr[3])() = { test1,test2,test3 };//函数指针数组的定义和初始化
	int num = 0;
	while (scanf("%d", &num) != EOF)
	{
		pfarr[num - 1]();
	}
	return 0;
}

运行结果:

不难看出,程序就可以根据输入的值来调用不同的函数

注意:我们在使用函数指针数组时,函数指针数组所指向的所有函数的类型必须一致。

四、转移表

        刚才我们简单使用了一下函数指针数组,这种通过函数指针数组来实现的调用不同函数的方法叫做转移表。由于计算器这类程序可以有多种运算功能,我们就运用转移表来实现一个简单的计算器。

程序代码:

#include <stdio.h>

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 a / b;
}

int main()
{
	int(*pfarr[5])(int, int) = { NULL,add,sub,mul,div };
	int input = 0;
	do
	{
		printf("************************\n");
		printf("***  1.add    2.sub  ***\n");
		printf("***  3.mul    4.div  ***\n");
		printf("***  5.exit ************\n");
		printf("************************\n");
		printf("请选择:>>>");
		scanf("%d", &input);
		if (input >= 1 && input <= 5)
		{
			int a = 0;
			int b = 0;
			printf("请输入两个操作数:>>>");
			scanf("%d %d", &a, &b);
			printf("结果是:%d\n",pfarr[input](a, b));
		}
		else if (input == 0)
		{
			printf("退出计算器\n");
		}
		else
		{
			printf("输入错误!请重新输入!");
		}
	} while (input);
	return 0;
}

当我们使用转移表时,就可以在功能过多的情况下免去使用switch语句和大量的case语句,使得代码更加简洁

总结

        这篇文章我们学习了函数指针,typedef关键字和函数指针数组等知识和应用。之后博主会和大家介绍c语言中的库函数--qsort,并且模拟实现。如果你觉得博主讲的还不错,就请留下一个小小的赞在走哦,感谢大家的支持❤❤❤

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/688470.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【操作系统】进程与线程的区别及总结(非常非常重要,面试必考题,其它文章可以不看,但这篇文章最后的总结你必须要看,满满的全是干货......)

目录 一、 进程1.1 PID(进程标识符)1.2 内存指针1.3 文件描述符表1.4 状态1.5 优先级1.6 记账信息1.7 上下文 二、线程三、总结&#xff1a;进程和线程之间的区别&#xff08;非常非常非常重要&#xff0c;面试必考题&#xff09; 一、 进程 简单来介绍一下什么是进程&#xf…

[UE 虚幻引擎] DTLoadFbx 运行时加载FBX本地模型插件说明

本插件可以在打包后运行时动态加载FBX模型。 新建一个Actor 并添加一个 DT Runtime Fbx Component。 然后直接调用组件的函数 LoadFile 加载显示模型&#xff08;注&#xff1a;不支持模型动画&#xff09; FilePath : 加载模型的绝对路径。 Create Collision : 是否创建碰撞…

R语言探索与分析19-CPI的分析和研究

一、选题背景 CPI&#xff08;居民消费价格指数&#xff09;作为一个重要的宏观经济指标&#xff0c;扮演着评估通货膨胀和居民生活水平的关键角色。在湖北省这个经济活跃的地区&#xff0c;CPI的波动对于居民生活、企业经营以及政府宏观经济政策制定都具有重要的影响。因此&a…

单链表的排序

对一个单链表进行排序。 方法一&#xff1a;构造一个辅助的数组来排序。 Java构造一个集合来存储。先将链表内容存储到集合中去&#xff0c;再对集合进行排序&#xff0c;最后按照顺序取出集合中的数据即可。 public ListNode sortInLit(ListNode head) {if (head null || he…

Solon2分布式事件总线的应用价值探讨

随着现代软件系统的复杂性日益增加&#xff0c;微服务架构逐渐成为开发大型应用的主流选择。在这种架构下&#xff0c;服务之间的通信和协同变得至关重要。Solon2作为一个高性能的Java微服务框架&#xff0c;其分布式事件总线&#xff08;Distributed Event Bus&#xff09;为微…

国标GB/T 28181详解:国标GBT28181-2022的客户端主动发起历史视音频回放流程

目录 一、定义 二、作用 1、提供有效的数据回顾机制 2、增强监控系统的功能性 3、保障数据传输与存储的可靠性 4、实现精细化的操作与控制 5、促进监控系统的集成与发展 三、历史视音频回放的基本要求 四、命令流程 1、流程图 2、流程描述 五、协议接口 1、会话控…

网络空间安全数学基础·多项式环与有限域

5.1 多项式环&#xff08;掌握&#xff09; 5.2 多项式剩余类环&#xff08;理解&#xff09; 5.3 有限域&#xff08;熟练&#xff09; 5.1 多项式环 定义&#xff1a;设F是一个域&#xff0c;称是F上的一元多项式&#xff0e; 首项&#xff1a;如果an≠0&#xff0c;则称 a…

el-dialog给弹框标题后加图标,鼠标悬停显示详细内容

效果&#xff1a; 代码&#xff1a; <div slot"title" class"el-dialog__title">标题<el-tooltip effect"dark" placement"right"><div slot"content">鼠标悬停显示</div><i class"el-icon…

队列的讲解与实现

这里写目录标题 一、队列的概念及结构二、队列的实现(使用VS2022的C语言)1.初始化、销毁2.入队、出队3.返回队头元素、返回队尾元素、判空、返回有效元素个数 三、完整 Queue.c 源代码 一、队列的概念及结构 队列&#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端…

手机相册的排列方式探讨

不论你是不是程序员&#xff0c;你一定留意过一个问题&#xff1a;相册 App 基本都将图片裁剪成了居中的 1:1 正方形。那么手机相册 App&#xff0c;为什么要将图片切割成 1:1 正方形&#xff0c;然后以网格排列&#xff1f;是行业标准吗&#xff1f; 自适应图片宽度的图库&a…

vr样板房实景漫游展示制作解决了地产商难题

家具和软装销售中&#xff0c;如何直观展示产品优势一直是老板们的难题。口头描述往往难以让客户真正感受到产品的独特之处&#xff0c;这不仅影响了销售效果&#xff0c;也增加了沟通的难度。但现在&#xff0c;我们有了全新的解决方案——样板房VR全景编辑软件! 样板房VR全景…

SpringMVC:消息转换器

1. HttpMessageConvertor 简介 HttpMessageConverter是Spring MVC中非常重要的一个接口。翻译为&#xff1a;HTTP消息转换器。该接口下提供了很多实现类&#xff0c;不同的实现类有不同的转换方式。 转换器 如上图所示&#xff1a;HttpMessageConverter接口的可以将请求协议转…

数据结构之ArrayList与顺序表(上)

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;数据结构&#xff08;Java版&#xff09; 顺序表的学习&#xff0c;点我 上面这篇博文是关于顺序表的基础知识&#xff0c;以及顺序表的实现。…

美团面试:百亿级分片,如何设计基因算法?

尼恩说在前面 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;最近有小伙伴拿到了一线互联网企业如得物、阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格&#xff0c;遇到很多很重要的架构类/设计类的场景题&#xff1a; 1.说说分库分表的基因算法&#xff1f…

【Linux】深入解析动静态库:原理、制作、使用与动态链接机制

文章目录 前言&#xff1a;1. 什么是动静态库2. 动静态库的制作和使用3. 动态库的查找问题4. 理解动态库的加载4.1. 站在系统的角度理解4.2. 编址、可执行程序4.3. 动态库动态链接和加载问题 总结&#xff1a; 前言&#xff1a; 在软件开发中&#xff0c;动静态库是两种重要的…

Netty中的ByteBuf使用介绍

ByteBuf有三类&#xff1a; 堆缓存区&#xff1a;JVM堆内存分配直接缓冲区&#xff1a;有计算机内存分配&#xff0c;JVM只是保留分配内存的地址信息&#xff0c;相对于堆内存方式较为昂贵&#xff1b;复合缓冲区&#xff1a;复合缓冲区CompositeByteBuf&#xff0c;它为多个B…

6月26~28日,2024北京国际消防展即将开幕!

随着社会的快速发展&#xff0c;消防安全日益受到广大民众的高度关注。为了进一步推动消防科技的创新与发展&#xff0c;提升全民消防安全意识&#xff0c;2024年北京消防展将于6月26日在北京国家会议中心盛大开展。目前:观众预登记已全面启动&#xff0c;广大市民和业界人士可…

Skins

本主题解释如何将DevExpress主题/皮肤应用到应用程序中&#xff0c;如何允许用户在运行时在主题之间切换&#xff0c;如何自定义现有皮肤或创建自己的皮肤&#xff0c;等等。 WinForms订阅包括许多基本控件&#xff1a;按钮、复选框、表单、消息框、对话框、对话框等。 我们实现…

python面向过程与初始面向对象编程

让我们穿越到《龙珠》世界&#xff0c;一起揭开 面向对象编程 的神秘面纱吧。 面向过程编程与面向对象编程 天下第一武道会 选手登记 第 22 届天下第一武道会即将召开&#xff0c;各路武术高手齐聚一堂&#xff0c;其中最受瞩目的&#xff0c;当属卡卡罗特&#xff08;孙悟…

Docker高级篇之Docker搭建mysql主从复制架构

文章目录 1. 安装mysql主从复制2. 主从复制测试 1. 安装mysql主从复制 首先创建主节点 docker run -d -p 3308:3306 \ --privilegedtrue \ -v /Users/jackchai/Desktop/lottory_docker/learndocker/mymysql/master/log:/var/log/mysql \ -v /Users/jackchai/Desktop/lottory_…