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

news2024/11/16 7:54:15

🌟🌟作者主页: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,并且模拟实现。如果你觉得博主讲的还不错,就请留下一个小小的赞在走哦,感谢大家的支持❤❤❤

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SD卡格式化怎么恢复?一键扫描,轻松找回丢失的数据

SD卡格式化怎么恢复数据&#xff1f;在日常生活中&#xff0c;我们常常会使用SD卡来存储各种数据&#xff0c;如照片、视频、文档等。然而&#xff0c;当SD卡意外格式化或者出现其他问题时&#xff0c;里面的数据就会面临丢失的风险。 此时&#xff0c;如何恢复格式化的SD卡就…

webgl_clipping_stencil

ThreeJS 官方案例学习&#xff08;webgl_clipping_stencil&#xff09; 1.效果图 2.源码 <template><div><div id"container"></div></div> </template> <script> import * as THREE from three; // 导入控制器 import …

成都跃享未来教育咨询有限公司,值得信赖!

在浩渺的教育咨询市场中&#xff0c;成都跃享未来教育咨询有限公司以其独特的魅力和卓越的服务质量&#xff0c;成为了行业内的璀璨明星。作为一家致力于为学生提供全方位教育咨询服务的公司&#xff0c;成都跃享未来教育咨询有限公司始终坚持安全可靠的原则&#xff0c;为广大…

docker命令 docker ps -l (latest)命令在 Docker 中用于列出最近一次创建的容器

文章目录 12345 1 docker ps -l 命令在 Docker 中用于列出最近一次创建的容器。具体来说&#xff1a; docker ps&#xff1a;这个命令用于列出当前正在运行的容器。-l 或 --latest&#xff1a;这个选项告诉 docker ps 命令只显示最近一次创建的容器&#xff0c;不论该容器当前…

SAP ERP系统主要模块简介

SAP系统通过提供一系列高度灵活的模块&#xff0c;满足企业在不同业务领域的需求。这些模块不仅功能齐全且相对独立&#xff0c;但它们之间又能紧密协作&#xff0c;共同构筑一个协同高效的工作环境。 财务会计&#xff08;FI&#xff09;模块 它涵盖了总账、应收账款、应付账…

fs.1.10 ON rockylinux8 docker镜像制作

概述 freeswitch是一款简单好用的VOIP开源软交换平台。 rockylinux docker上编译安装fs1.10版本的流程记录。 环境 docker engine&#xff1a;Version 24.0.6 rockylinux docker&#xff1a;8 freeswitch&#xff1a;v1.10.7 手动模式 rockylinux准备 docker hub拉取r…

第三篇——大数据思维的科学基础

目录 一、背景介绍二、思路&方案三、过程1.思维导图2.文章中经典的句子理解3.学习之后对于投资市场的理解4.通过这篇文章结合我知道的东西我能想到什么&#xff1f; 四、总结五、升华 一、背景介绍 大数据时代&#xff0c;大数据思维的重要性不言而喻&#xff1b;而信息在…

搜索引擎优化服务如何寻找?

首先你要了解搜索引擎优化&#xff0c;也就是seo具体是什么&#xff0c;要做些什么&#xff0c;然后就是确定你自身业务的需求&#xff0c;是要特定的关键词排名&#xff0c;还是整体网站流量的提升&#xff0c;还是想要优化目前的网站 接下来你就可以正式的寻找真正能帮助到你…

three.js官方案例(animation / multiple)webgl_animation_multiple.html学习笔记

目录 ​编辑 1 骨架工具&#xff08;SkeletonUtils&#xff09; 1.1 clone方法 2 蒙皮网格&#xff08;SkinnedMesh&#xff09; 3 自测 4 webgl_animation_multiple.html全部脚本 1 骨架工具&#xff08;SkeletonUtils&#xff09; 用于操控 Skeleton、 SkinnedMesh、和…

springboot项目部署需要redis集群问题

本来直接将redis为单独启动模式转为配置 yml文件 spring.redis.cluster.nodes: 192.168.12.78:8001,192.168.12.78:8002,192.168.12.78:8003, java文件 package io.sirc.config;import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.ann…

【JSP】如何在IDEA上部署JSP WEB开发项目

以我的课设为例&#xff0c;教大家拿到他人的项目后&#xff0c;如何在IDEA上部署。 需要准备&#xff1a; JDK17&#xff08;或者JDK13&#xff09;IntelliJ IDEA 2023.2.6MySQL 8.0Tomcat 9.0 一&#xff0c;新建项目添加文件 1.1复制“位置”的路径 1.2找到该文件夹 1.3…

SQLite3(1):介绍安装与测试

目录 1、SQLite3介绍 2、SQLite3的优势和特性 3、SQLite3安装与测试 3.1 SQLite3安装 3.2 SQLite3测试 4、SQLite3简单使用 4.1 连接数据库文件 4.2 创建信息表 4.3 插入三个学生信息 4.4 确认信息 5、总结 1、SQLite3介绍 SQLite3是一种轻量级的关系型数据库管理系…

kafka集群内外网分流方案——筑梦之路

前言 在现代分布式系统架构中&#xff0c;Kafka作为一款高性能的消息队列系统&#xff0c;广泛应用于大数据处理、实时流处理以及微服务间的异步通信场景。特别是往往企业级应用中&#xff0c;业务网段和内网通信网段不是同一个网段&#xff0c;内网的机器想要访问业务数据只能…

计网复习资料

一、选择题&#xff08;每题2分&#xff0c;共40分&#xff09; 1. Internet 网络本质上属于&#xff08; &#xff09;网络。 A.电路交换 B.报文交换 C.分组交换 D.虚电路 2.在 OSI 参考模型中,自下而上第一个提供端到端服务的是( )。 A.数据链路层 B.传输…

【YOLOv10】使用 TensorRT C++ API 调用GPU加速部署 YOLOv10 实现 500FPS 推理速度——快到飞起!

NVIDIA TensorRT ™ 是一款用于高性能深度学习推理的 SDK&#xff0c;包含深度学习推理优化器和运行时&#xff0c;可为推理应用程序提供低延迟和高吞吐量。YOLOv10是清华大学研究人员近期提出的一种实时目标检测方法&#xff0c;通过消除NMS、优化模型架构和引入创新模块等策…

C++进阶之二叉搜索树

个人主页&#xff1a;点我进入主页 专栏分类&#xff1a;C语言初阶 C语言进阶 数据结构初阶 Linux C初阶 C进阶​ ​​​​算法 欢迎大家点赞&#xff0c;评论&#xff0c;收藏。 一起努力&#xff0c;一起奔赴大厂 目录 一.二叉搜索树概念 二.实现 2.1插入 …

K8s存储对象的使用

背景和概念 容器中的文件在磁盘上是临时存放的&#xff0c;这给在容器中运行较重要的应用带来一些问题&#xff1a; 当容器崩溃或停止时&#xff0c;此时容器状态未保存&#xff0c; 因此在容器生命周期内创建或修改的所有文件都将丢失。另外 在崩溃期间&#xff0c;kubelet 会…

3D打印随形水路:模具水路的革命性技术

在快速发展的模具制造行业中&#xff0c;3D打印技术以其独特的优势正在引领一场技术革命。其中&#xff0c;3D打印随形水路技术&#xff0c;凭借其灵活性和定制化设计的能力&#xff0c;为模具带来了前所未有的变革。 模具3D打印随形水路技术&#xff0c;是一种利用3D打印技术制…

《帝国时代 III:决定版》秘籍 怎么在苹果电脑上玩《帝国时代 III:决定版》

《帝国时代 III&#xff1a;决定版》是一款让玩家沉浸于历史长河体验从大航海时代到工业革命时期的游戏。下面我们来看看《帝国时代 III&#xff1a;决定版》是什么类型的游戏&#xff0c;《帝国时代 III&#xff1a;决定版》Mac安装教程的相关内容。 一、《帝国时代 III&…

UI设计公司-蓝蓝设计-交通行业ui设计解决方案

来百度APP畅享高清图片 这是北京兰亭妙微科技有限公司&#xff08;简称蓝蓝设计&#xff09;在交通行业的一些ui设计经验&#xff0c;我们建立了UI设计分享群&#xff0c;每天会分享国内外的一些优秀设计&#xff0c;如果有兴趣的话&#xff0c;可以进入一起成长学习&#xff0…