指针——函数指针数组
(一)前文回顾
1、前篇代码分析
void(*signal(int , void(*)(int)))(int) ;
那么这串代码究竟是什么呢?
别慌,让我们来一步一步拆解,首先我们通过之前的学习,已经明白了什么是函数指针(如果有不太懂得,请看前一篇文章)
仔细观察这串代码,不难发现出现了 signal 此时肯定会有人想是不是有什么特殊的含义。。。
很明显,signal就是简简单单的一个函数名,不行,来我们轻轻的把这串代码“大卸八块”。
(1)去掉最外层的 void()(int) 剩余 *signal(int , void(*)(int)) ; 现在signal只有两种可能。【1,就是指针 2,是函数名】
我们之前的学习中已经知道当 * 和()同时存在的时候,()首先于变量名结合,所以此处的 signal(int , void(*)(int)) 首先是一部分,也就是个函数。
(2)再来看 signal(int , void(*)(int)) 的()内的部分,我们发现有个 int,这说明函数内有个参数是 int 类型,那么剩余的参数 void(*)(int) 是什么类型呢?
学过函数指针的朋友不难看出,这就是一个函数指针类型的参数。
(3)再想想,* 是什么呢 ?此时发现不好解释啊,但是你把刚开始去掉的外层结构加上再看就会一目了然!
void(* )(int) //这也是个函数指针类型,再结合中间部分是个函数,我们就能明白整个代码 void(*signal(int , void(*)(int)))(int) ; 的意思是 函数指针类型的函数
(二)函数指针数组
1、基本知识
(1)本质:
函数指针数组,顾名思义就是存放函数指针的一个数组!!!
(2)示例
int add(int x , int y) //定义一个函数实现两个整数的相加
{
return x+y;
}int sub(int x , int y) //定义一个函数实现两个整数的相减
{
return x+y;
}int main()
{
int(*pf)( int ,int ) = add ; //定义一个函数指针指向 add 函数int(*pf1)( int ,int ) = sub ; //定义一个函数指针指向 sub 函数
int( *parr[2] )( int ,int ) = {pf,pf1 }; //此时的parr就是一个数组,类型为函数指针,存放了两个函数指针
}
根据上述代码,我们就能知道函数指针数组究竟是什么样的了,需要注意的是 函数指针数组和普通数组大致相同,存放的元素类型要相同,所以存放的函数指针的类型也要相同!!
2、练习——计算器——避免使用switch()
(1)基本思路
1. 首先简单的计算器我们需要 四个函数 来分别实现 加减乘除 四个功能 ;
2.需要一个菜单来提醒用户;
3.在主函数中需要循环,并且由于不使用 switch(),所以应用本节学习,使用函数指针数组。
(2)代码如下:
#include<stdio.h>
int Add(int x, int y) //定义四个函数
{return x + y;
}
int Sub(int x, int y)
{return x - y;
}
int Mul(int x, int y)
{return x * y;
}
int Div(int x, int y)
{return x / y;
}
void menu() //菜单
{printf("***0.加法*******\n");printf("***1.减法*******\n");printf("***2.乘法*******\n");printf("***3.除法*******\n");printf("***4.退出*******\n");
}
int main()
{int(*pf[5])(int, int) = { Add, Sub ,Mul,Div,NULL };//定义一个函数指针数组,数组第1,2//3,4个元素分别对应四个函数,可以使用下标来取出,最后一个元素是个空指针,来退出程序int a = 0; //定义一个局部变量来让用户选择具体算法int b, c = 0;do {//使用do while()循环可以不判断先执行一次menu();printf("请选择\n");scanf_s("%d", &a);if (a >= 0 && a <= 3)//下标在0~3即对应四个函数{printf("请输入两个数\n");scanf_s("%d %d", &b, &c);int ret = pf[a](b, c); //调用printf("%d\n", ret);}else if (a == 4)//下标为4就对应空指针{printf("退出\n");break;}else{printf("选择错误\n");//选择其余显示错误break;}} while (a);return 0;
}
执行如下:

相关文章:
指针——函数指针数组
(一)前文回顾 1、前篇代码分析 void(*signal(int , void(*)(int)))(int) ; 那么这串代码究竟是什么呢? 别慌,让我们来一步一步拆解,首先我们通过之前的学习,已经明白了什么是函数指针(如果有…...
MySQL中的增查操作:探索数据的奥秘,开启数据之门
本节,我们继续深入了解MySQL,本章所讲的基础操作,针对的是表的增删查改! 一、Create 新增 1.1、语法 INSERT [INTO] table_name[(column [, column] ...)] VALUES(value_list) [, (value_list)] ... value_list: value, [, va…...
oracle_查询建表语句
查询建表语句 SELECTdbms_metadata.get_ddl ( TABLE, <table_name> ) FROMdualdbms_metadata.get_ddl:是Oracle提供的一个函数,用于获取数据库对象的DDL语句,它允许你查看或导出数据库对象的创建脚本‘TABLE’: 是这个函数…...
004-按照指定功能模块名称分组
按照指定功能模块名称分组 一、说明1.现在有一个需求:2.具体做法 二、代码案例三、效果展示 一、说明 1.现在有一个需求: 需要把一个功能模块的几个功能点放在同一个文档目录下,这几个功能点分布在不同的 Controller 2.具体做法 需要把他…...
ChatGPT写作助手:论文写作必备提示词一览
学境思源,一键生成论文初稿: AcademicIdeas - 学境思源AI论文写作 随着人工智能技术的发展,ChatGPT在学术写作领域的应用越来越广泛。它不仅能够帮助撰写论文,还可以通过不同的提示词完成构思、文献综述、数据分析、润色等任务&a…...
大数据开发电脑千元配置清单
大数据开发电脑配置清单 电脑型号HUANANZHI 台式电脑操作系统Windows 11 专业版 64位(Version 23H2 / DirectX 12)处理器英特尔 Xeon(至强) E5-2673 v3 2.40GHz主板HUANANZHI X99-P4T(P55 芯片组)显卡NVIDIA GeForce GT 610 ( 2…...
VP9官方手册-帧内预测
8.5.1 intra prediction process...
windows 自定义scheme协议。
浏览器打开自定义scheme参考上一篇:Chromium 自定义scheme协议启动过程分析c 1、注册表里面按照如下格式填写自定义scheme协议导入: Windows Registry Editor Version 5.00[HKEY_CLASSES_ROOT\jdtest] "URL:jdtest Protocol" "URL Proto…...
什么是SQLite?
一、什么是SQLite? SQLite是一个进程内的软件库,实现了自给自足的、无服务器的、零配置的、事务性的SQL数据库引擎。它是一个零配置的数据库,这意味着与其他数据库不一样,您不需要在系统中配置。 就像其它数据库,SQLite引擎不是…...
域1:安全与风险管理 第2章-人员安全与风险管理
第二章的内容确实较为丰富,需要细心且耐心地逐步消化和理解。不妨放慢阅读速度,对每个要点都进行深入思考,确保自己真正掌握了其核心意义。这样,虽然可能花费更多时间,但能够更扎实地掌握第二章的知识,为后…...
php中的错误和异常捕获
目录 一: 异常(Exceptions) 二: 错误(Errors) 三:实际项目的异常和错误处理 在PHP中,异常(Exceptions)和错误(Errors)是两个不同的…...
nextjs项目中,使用postgres的完整案例
目的 通过此案例,可以简单快速的过一下数据库的操作,熟悉app-router这种模式下,client component和server component的两种组件中基本的接口使用。 技术栈 nextjs14.2.* app-routervercel/postgres0.10.*typescript5 重要事情说三遍1 ap…...
tsconfig.json 内容解读
tsconfig.json 文件是 TypeScript 项目的主要配置文件,用于指定编译选项和项目设置。通过这个文件,你可以控制编译器的行为,例如输出文件的路径、模块解析方式、严格类型检查等。 以下是一些常见的 tsconfig.json 属性及其详细解释ÿ…...
KClass-关于kotlin中的反射
override val responseType: KClass<SetOperationModeResponse> SetOperationModeResponse::class,这段代码的含义: responseType 是一个只读属性(val),它的类型是 KClass<SetOperationModeResponse>。KClass<T&…...
Java集合剖析2】Java集合底层常用数据结构
一、数据结构与集合 接下来就要学习集合具体的实现类了,集合的实现类底层可能用1种或多种数据结构来存储数据。所以在学习集合的实现类前,我们有必要了解一下一些常见的数据结构,这样我们在后面查看集合实现类的底层源码时,才不会…...
java 第10天 String创建以及各类常用方法
一.String创建的两种形式 1.通过new的当时 String strnew String(); 2.不new的方式 String s1""; 二.new 和不new的方式的区别是什么 不new创建的字符串首先是拿着值去常量池中查找,是否有该内容,有就用常量池该字符串的地址࿰…...
VS 解决方案里面.vs文件夹
VS解决方案中的.vs文件夹主要用于存储当前用户在解决方案中的工作配置。 这些配置包括多个方面: 窗口布局和选项卡状态:.vs文件夹记录了VS关闭前最后的窗口布局以及最后打开的选项卡。这样,当用户重新打开解决方案时,可以继续之前…...
初试PostgreSQL数据库
文章目录 一、PostgreSQL数据库概述1.1 PostgreSQL的历史1.2 PostgreSQL安装1.3 安装PostgreSQL二、PostgreSQL起步2.1 连接数据库2.1.1 SQL Shell2.1.2 执行SQL语句2.2 pgAdmin 42.2.1 打开pgAdmin 42.2.2 查找数据库2.2.3 打开查询工具2.2.4 执行SQL语句三、实战小结文章目录…...
springboot3导出数据库数据到excel
一、导入依赖 <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml --><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.3.0</version></dependency><d…...
十四、行为型(观察者模式)
观察者模式(Observer Pattern) 概念 观察者模式(Observer Pattern)是一种行为型设计模式,它定义了对象间的一对多依赖关系,当被观察的对象(主题)状态发生改变时,所有依赖…...
装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成
一个面向 Java 开发者的 Sring-Ai 示例工程项目,该项目是一个 Spring AI 快速入门的样例工程项目,旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计,每个模块都专注于特定的功能领域,便于学习和…...
ubuntu22.04 安装docker 和docker-compose
首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...

很明显,