指针数组以及利用函数指针来实现简易计算器及typedef关键字(指针终篇)

文章目录
- 🚀前言
- 🚀两段有趣的代码
- ✈️typedef关键字
- 🚀指针数组
- 🚀简易计算器的实现
🚀前言
基于阿辉前两篇博客指针的基础篇和进阶篇对于指针的了解,那么今天阿辉将为大家介绍C语言的指针剩下的部分,包括指针数组以及利用函数指针来实现简易计算器及typedef关键字,关注阿辉不迷路哦 😘 ,内容干货满满😋,接下来就跟着阿辉一起学习吧👊
🚀两段有趣的代码
以下两段代码出自于《C陷阱和缺陷》这本书,这两段代码有一定的难度,需要有一定的指针基础否则可能看不懂,看不懂的可以翻看阿辉前两篇关于指针的博客。
代码1
( *( void ( * )())0 )()
这段代码确实变态,铁子们别急,让我们分析一下:
1.首先,代码( *( void ( * )())0 )()右边单独的括号()很明显它是函数调用操作符,说明( *( void ( * )())0 )这一大坨代表一个函数名
2.然后,void ( * )()这一坨,铁子们这玩意不就是函数指针类型嘛,被指向函数返回类型是void没有参数, void ( * )()这玩意外面套个括号不就是(类型)强制类型转换嘛
那这不就简单了,不就是把数字0强制转化成一个函数指针,然后解引用调用该函数
代码2
void (*signal(int , void(*)(int)))(int);
void (*signal(int , void(*)(int)))(int)这一坨我们咋一看很懵,不过我要是把这个signal(int , void(*)(int))拎出来铁子们肯定熟,这玩意怎么这么像函数声明,铁子们大胆点,你们看看void (*)(int)这一部分不就是函数指针类型吗,这俩一结合不就是函数声明嘛
signal是函数名,它的两个参数类一个是int,一个是返回值为void参数为int的函数指针类型,然后signal的返回类型也是一个返回值为void参数为int的函数指针类型
这里你可能会想这段码难写可读性还差,其实有解决方法,铁子们咱继续👇
✈️typedef关键字
通过typedef,可以为已有的数据类型定义一个新的名字,使得代码更易读、更易维护
语法格式为:
typedef 类型名 新类型名
例子:
typedef unsigned int size_t;size_t a;对于size_t创建的变量a其实就是unsigned int类型的
对于指针类型,新类型名必须在*右边
例子:
typedef int(*parr_t)[5];typedef void(*pfun_t)(int);void (*signal(int , void(*)(int)))(int);对于上面这段函数我们就可以这么写了pfun_t signal(int , pfun_t);可读性直接提升一大截
🚀指针数组
铁子们都知道,数组是自定义类型,前面咱们学了指针的一系列类型,这不咱们数组又添一个大家族——指针数组,指针数组顾名思义是存放指针的数组
指针数组的创建
type* name[const];
name是数组名
const是常量给定数组大小
type*是数组的类型
注意 :这里要与数组指针区分开,由于[]的优先级高于*,所以type* name[const]中name与[]先结合表明name是指针,而数组指针type (*name)[const]中(*name)确保*与name先结合表明name是指针
举个栗子👇
int* a1[10];//存放整型指针的指针数组
char* a2[10];//存放字符指针的指针数组
int(*a3[10])[5];//存放数组指针的数组指针数组
int(*a4[10])(int);//存放函数指针的函数指针数组
指针数组有什么用呢?铁子们不要急我们接着看👇
🚀简易计算器的实现
利用switch来实现简易计算器
简易计算器的实现思路:
- 内置加减乘除四种运算
- 打印菜单供用户选择运算方式以及退出计算器
- 输入待计算的数字
- 输出计算结果
#include <stdio.h>
void menu()
{打印菜单printf("*************************\n");printf("**** 1:add 2:sub ***\n");printf("**** 3:mul 4:div ***\n");printf("**** 0:exit .... ***\n");printf("*************************\n");
}
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 x, y;int input = 1;int ret = 0;do{menu();printf("请选择:");scanf("%d", &input);switch (input)//选择{case 1:printf("输入两个操作数:");scanf("%d %d", &x, &y);ret = add(x, y);printf("ret = %d\n", ret);break;case 2:printf("输入两个操作数:");scanf("%d %d", &x, &y);ret = sub(x, y);printf("ret = %d\n", ret);break;case 3:printf("输入两个操作数:");scanf("%d %d", &x, &y);ret = mul(x, y);printf("ret = %d\n", ret);break;case 4:printf("输入两个操作数:");scanf("%d %d", &x, &y);ret = div(x, y);printf("ret = %d\n", ret);break;case 0:printf("退出程序\n");break;default:printf("选择错误,请重新选择\n");break;}} while (input);return 0;
}
上面的这段利用switch实现的代码,有大量重复的元素导致代码极为臃肿,而且对于后期代码的维护也是极为不便,这里我们观察发现add,sub,mul,div这四个函数有着同样的参数以及返回类型,这有什么用呢?铁子们我们接着看
我们完全可以,创建一个函数指针数组来存放他们
int (*a[])(int,int) = {add,sub,mul,div};
有了这个函数指针数组,我们只需要输入下标便可以通过a[input](x,y)来调用函数,但是下标并没有与菜单对应起来,很简单仅需要在数组里面添一个NULL就行int (*a[])(int,int) = {NULL,add,sub,mul,div}

然后一堆的switch case语句简化成:
if (input == 0){printf("退出计算器\n");}else if (input >= 1 && input <= 4){ printf("请输入两个操作数:");scanf("%d %d", &x, &y);ret = pfArr[input](x, y); printf("%d\n", ret);}else{printf("选择错误,重新选择\n");}
不得不说设计C语言的人真的是厉害,后面如果要添加其他运算仅仅只用添函数改一下菜单以及把数组名加到数组里面就行了,绝真的绝!!!
到这里,阿辉今天对于C语言中指针部分的分享就结束了,希望这篇博客能让大家有所收获, 如果觉得阿辉写得不错的话,记得给个赞呗,你们的支持是我创作的最大动力🌹

相关文章:
指针数组以及利用函数指针来实现简易计算器及typedef关键字(指针终篇)
文章目录 🚀前言🚀两段有趣的代码✈️typedef关键字 🚀指针数组🚀简易计算器的实现 🚀前言 基于阿辉前两篇博客指针的基础篇和进阶篇对于指针的了解,那么今天阿辉将为大家介绍C语言的指针剩下的部分&#…...
josef JZ-7Y-33静态中间继电器 电压DC220V 板前接线
系列型号: JZ-7Y-201X静态中间继电器;JZ-7J-201X静态中间继电器; JZ-7L-201X静态中间继电器;JZ-7D-201X静态中间继电器; JZ-7Y-201静态中间继电器;JZ-7J-201静态中间继电器; JZ-7L-201静态中…...
Java第二十章 ——多线程
本文主要讲了java中多线程的使用方法、线程同步、线程数据传递、线程状态及相应的一些线程函数用法、概述等。 在这之前,首先让我们来了解下在操作系统中进程和线程的区别: 进程:每个进程都有独立的代码和数据空间(进程上下文…...
【超强笔记软件】Obsidian实现免费无限流量无套路云同步
【超强笔记软件】Obsidian如何实现免费无限流量无套路云同步? 目录 一、简介 软件特色演示: 二、使用免费群晖虚拟机搭建群晖Synology Drive服务,实现局域网同步 1 安装并设置Synology Drive套件 2 局域网内同步文件测试 三、内网穿透群…...
【Linux小项目】实现自己的bash
0. bash原理介绍 bash实际上就是一个负责解析输入字符串工具. 我们需要做的事是这些: 手动分割出输入的字符串判断哪些变量是内建命令(自己执行),哪些命令是普通命令(创建子进程执行)实现的功能有: echo export cd 常规指令 输入、输出流重定向 #include<stdio.h> #i…...
客户案例:EDLP助力金融行业打造高效数据防泄露体系
客户背景 某金融机构是一家以金融科技为核心,致力于为客户提供全方位、智能化、便捷化金融服务的综合性企业。公司总部位于南京,业务范围覆盖全国,拥有强大的技术研发团队和优秀的业务精英,为客户提供全方位的金融服务解决方案。 …...
【JavaFX漏扫开发基础】stage窗口/模式/模态
文章目录 stage一、stage窗口二、stage窗口,模式,模态stage模式(5种样式)模态化窗口stage stage其实就是一个窗口,它啥也不是,打开所有windows的程序都会有一个窗口,这个窗口就是javafx里的stage。里面的内容不属于stage,stage就是一个窗口,就这么简单。 Stage is a…...
MySQL进阶知识:锁
目录 前言 全局锁 表级锁 表锁 元数据锁(MDL) 意向锁 行级锁 行锁 行锁演示 间隙锁/临界锁 演示 前言 MySQL中的锁,按照锁的粒度分,分为以下三类 全局锁:锁定数据库中的所有表。表级锁:每次操…...
linux下的工具---gdb
一、gdb简介 GDB,是The GNU Project Debugger 的缩写,是 Linux 下功能全面的调试工具。 GDB支持断点、单步执行、打印变量、观察变量、查看寄存器、查看堆栈等调试手段。 程序的发布方式有两种,debug模式和release模式 Linux gcc/g出来的二进制程序&am…...
ESP32-Web-Server编程-JS 基础 2
ESP32-Web-Server编程-JS 基础 2 概述 上节介绍了 JS 编程的基础。如前所述,在 HTML 中,可以通过下述 两种方式使用 JS 程序: 直接在 HTML 文件中通过 script 标签中嵌入 JavaScript 代码。通过 src 元素引入外部的 JavaScript 文件。 在…...
Java Web基础教程
Java Web基础教程 1. Servlet基础 1.1 什么是Servlet Servlet是JavaEE中的标准组件之一,专门用于处理客户端的HTTP请求。并且它必须依赖于Servlet容器(Tomcat就是一个标准的Servlet容器)才能运行。因为Servlet实例的创建和销毁都是由容器负…...
BUUCTF john-in-the-middle 1
BUUCTF:https://buuoj.cn/challenges 题目描述: 注意:得到的 flag 请包上 flag{} 提交 密文: 下载附件,解压得到john-in-the-middle.pcap文件。 解题思路: 1、双击文件,打开wireshark。 看到很多http流…...
HashMap的死循环及数据覆盖问题
目录 一,HashMap 线程不安全的原因 二,HashMap 死循环问题 死循环发生的条件 死循环的具体过程 死循环执行步骤1 死循环执行步骤2 死循环执行步骤3 三,HashMap 数据覆盖问题 数据覆盖执行流程1 数据覆盖执行流程2 数据覆盖执行流…...
数据库数据恢复—MongoDB数据库文件拷贝出现错误的数据恢复案例
MongoDB数据库数据恢复环境: 一台Windows Server操作系统的虚拟机,虚拟机上部署有MongoDB数据库。 MongoDB数据库故障&检测: 在未关闭MongoDB服务的情况下,工作人员将MongoDB数据库文件拷贝到其他分区,然后将原数…...
2023年11月个人工作生活总结
本文为 2023 年 11 月工作生活总结。 研发编码 GIS 模仿了一些有名的地图服务商的网站,将离线地图页面做成全屏,对于大屏幕更加好友。再美化一下全区的边界和区内地域的边界。不过主要工作量还是绘制路线,而绘线作为内部工作,还…...
Spark-06:Spark 共享变量
目录 1.广播变量(broadcast variables) 2.累加器(accumulators) 在分布式计算中,当在集群的多个节点上并行运行函数时,默认情况下,每个任务都会获得函数中使用到的变量的一个副本。如果变量很…...
Spring整合web环境
目录 Javaweb三大组件及环境特点 Spring整合web环境的思路及实现 Spring的web开发组件spring-web MVC框架思想及其设计思路 Javaweb三大组件及环境特点 Spring整合web环境的思路及实现 package com.xfy.listener;import com.xfy.config.SpringConfig; import org.springfra…...
分享从零开始学习网络设备配置--任务4.3 使用动态路由RIPng实现网络连通
任务描述 某公司使用IPv6技术搭建企业网络,由于静态路由需要管理员手工配置,在网络拓扑发生变化时,也不会自动生成新的路由,因此采用IPv6动态路由协议RIPng实现网络连通,实现任意两个节点之间的通信,并降低…...
vue2.0+elementui集成file-loader之后图标失效问题
背景 跑vue2elementUI项目时,由于前端这边需要在本地存放xlsx模板文件,供用户下载模板文件,所以需要在webpack构建的时候增加file-loader进行解析xlsx文件打包。 vue版本2.x element-ui 版本 2.13.x 注意 npm i -D file-loader版本号给vue项…...
C# 文件帮助类(FileHelper)
引言 在研究程序反射的时候我们往往需要获取当前运行程序所引用的dll文件,按照传统的方式我们可以维护一个这样的列表,但是这样维护成本实在是太高,而且不利于团队合作开发,在高版本的.net 4.6.2之后官方出了专门的dll帮我们做这个事情Microsoft.Extensions.DependencyMod…...
如何快速集成gh_mirrors/ca/card到React/Vue/Angular:打造专业信用卡表单的完整指南
如何快速集成gh_mirrors/ca/card到React/Vue/Angular:打造专业信用卡表单的完整指南 【免费下载链接】card :credit_card: make your credit card form better in one line of code 项目地址: https://gitcode.com/gh_mirrors/ca/card gh_mirrors/ca/card是一…...
Python数据分析实战:用Seaborn绘制炫酷相关性热力图(附完整代码)
Python数据分析实战:用Seaborn绘制炫酷相关性热力图 数据分析工作中,相关性分析是理解变量间关系的核心技能。而热力图作为直观展示相关性的工具,已经成为数据科学家和商业分析师的标准配置。本文将带你从零开始,掌握用Seaborn绘…...
数据处理与统计分析----沙箱
命令行操作沙箱...
RC滤波器设计实战:从基础到高阶应用
1. RC滤波器设计基础与核心概念在嵌入式系统设计中,信号滤波是每个硬件工程师必须掌握的核心技能。我从业十余年处理过无数传感器信号,发现90%的噪声问题都可以通过合理设计的RC滤波器解决。与动辄使用运放或DSP方案相比,无源RC滤波器以极低成…...
cool-admin(midway版)数据权限过滤:实现方案与对比
cool-admin(midway版)数据权限过滤:实现方案与对比 【免费下载链接】cool-admin-midway 🔥 cool-admin(midway版)一个很酷的后台权限管理框架,模块化、插件化、CRUD极速开发,永久开源免费,基于midway.js 3.x、typescri…...
Go语言中的正则表达式
Go语言中的正则表达式 1. 正则表达式的基本概念 正则表达式是一种用于匹配字符串中字符组合的模式。在Go语言中,正则表达式通过regexp包来实现。 2. 基本用法 2.1 编译正则表达式 package mainimport ("fmt""regexp" )func main() {// 编译正则…...
【黑金云课堂笔记】第一~二期FPGA知识点总结
知识卡片一:【FPGA 基础篇】开启硬件编程之门FPGA 的本质: FPGA(现场可编程门阵列)并非在运行软件程序,而是在构建电路本身。用户可以通过 Verilog/VHDL 等硬件描述语言,在芯片出厂后随时重新配置其内部逻辑…...
避开STM32H743的坑:GPIO复用配置常见错误与排查指南(附引脚分配图详解)
避开STM32H743的坑:GPIO复用配置常见错误与排查指南 在STM32H743的开发过程中,GPIO复用配置往往是让开发者又爱又恨的部分。爱它是因为灵活多变的外设复用能力让这颗高性能MCU如虎添翼;恨它则是因为稍有不慎就会陷入各种配置冲突和功能异常的…...
基于DRAMsim3的扩散模型训练加速仿真:内存时延与能耗分析
基于DRAMsim3的扩散模型训练加速仿真:内存时延与能耗分析 摘要 扩散模型在生成式AI领域取得了巨大成功,但其训练过程极其昂贵,主要体现在对内存带宽的巨大需求(尤其是Attention机制和梯度存储)。本文聚焦于利用DRAMsim3模拟器,在系统架构层面仿真扩散模型(如DDPM)训练…...
用STM32F103做个智能门禁卡管理终端:RC522读卡、OLED菜单、4x4键盘改密码,附工程源码
基于STM32F103的智能门禁终端开发实战:从模块整合到系统优化 在物联网设备开发领域,将多个功能模块整合为一个稳定可靠的终端系统是开发者常面临的挑战。本文将深入探讨如何基于STM32F103RCT6微控制器构建一个功能完善的智能门禁管理终端,涵盖…...
