C语言 指针(7)
目录
1.函数指针变量
2.函数指针数组
3.转移表
1.函数指针变量
1.1函数指针变量的创建
什么是函数指针变量呢?
根据前面学习整型指针,数组指针的时候,我们的类比关系,我们不难得出结论:
函数指针变量应该是用来存放函数地址的,未来通过地址能够调用函数的。
那么函数是否有地址呢?
我们做个测试:
#include <stdio.h>
void test()
{printf("hehe\n");
}
int main()
{printf("test: %p\n", test);printf("&test: %p\n", &test);return 0;
}
输出结果如下:
1. test: 005913CA
2. &test: 005913CA
确实打印出来了地址,所以函数是有地址的,函数名就是函数的地址,当然也可以通过 &函数名
的方式获得函数的地址。
如果我们要将函数的地址存放起来,就得创建函数指针变量咯,函数指针变量的写法其实和数组指
针非常类似。如下:
void test()
{printf("hehe\n");
}
void (*pf1)() = &test;
void (*pf2)() = test;int Add(int x, int y)
{return x+y;
}
int(*pf3)(int, int) = Add;
int(*pf3)(int x, int y) = &Add; //x和y写上或者省略都是可以的
函数指针类型解析:
int (*pf3) (int x, int y)
| | |
| | |-- pf3指向函数的参数类型和个数的交代
| |
| |-- 函数指针变量名
|
|-- pf3指向函数的返回类型
int (*) (int x, int y) //pf3函数指针变量的类型
1.2函数指针变量的使用
通过函数指针调用指针指向的函数
#include <stdio.h>
int Add(int x, int y) {return x + y;
}
int main() {int(*pf3)(int, int) = Add;printf("%d\n", (*pf3)(2, 3));printf("%d\n", pf3(3, 5));return 0;
}
输出结果:
1. 5
2. 8
1.3 typedef关键字
typedef 是用来给类型重命名的,可以把复杂的类型变得简单。
比如,觉得 unsigned int 写起来麻烦,要是能写成 uint 就方便多了,那就可以这样用:
typedef unsigned int uint;
//把unsigned int 重命名成uint
指针类型也能重命名,比如把 int* 重命名成 ptr_t ,像这样:
typedef int* ptr_t;
不过对于数组指针和函数指针,重命名有点不一样。
比如有个数组指针类型 int(*)[5] ,要把它重命名成 parr_t ,就得这么写:
typedef int(*parr_t)[5];
//新的类型名必须在*的右边
函数指针类型的重命名也是一样的,比如,将 void(*)(int) 类型重命名为 pf_t ,就可以这样写:
typedef void(*pfun_t)(int); //新的类型名必须在*的右边
2.函数指针数组
数组是一个存放相同类型数据的存储空间,我们已经学习了指针数组,比如:
int * arr[10];
//数组的每个元素是int*
那要把函数的地址存到一个数组中,那个数组就叫函数指针数组,那函数指针的数组如何定义呢?
int (*parr1[3])();
int *parr2[3]();
int (*)() parr3[3];
答案是: parr1
parr1 先和 [] 结合,说明 parr1 是数组,数组的内容是什么呢?
是 int (*)() 类型的函数指针。
3.转移表
函数指针数组的用途: 转移表
举例:计算器的一般实现
#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 x, y;int input = 1;int ret = 0;do{printf("********************\n");printf(" 1:add 2:sub \n");printf(" 3:mul 4:div \n");printf(" 0:exit \n");printf("********************\n");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;
}
代码解释 :
(1)头文件的引入:
#include <stdio.h>
#include <stdio.h> 指令用于引入标准输入输出头文件,该文件包含了 printf 、 scanf 等输入输
出函数的声明,使得程序能够进行输入输出操作。
(2)函数定义:
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;
}
这里定义了四个函数,分别是 add(加法)、sub (减法)、mul (乘法)、div (除法)。每
个函数都接收两个 int 类型的参数,并根据相应的运算规则返回计算结果。
(3)main函数:
int main()
{int x, y;int input = 1;int ret = 0;
- int x, y; 声明了两个整型变量 x 和 y ,用于存储用户输入的操作数。
- int input = 1; 声明并初始化了变量 input ,用于存储用户选择的操作选项,初始值设为 1 是为
了确保 do - while 循环至少执行一次。
- int ret = 0; 声明并初始化了变量 ret ,用于存储运算结果,初始值为 0 。
(4)do-while循环
do{printf("********************\n");printf(" 1:add 2:sub \n");printf(" 3:mul 4:div \n");printf(" 0:exit \n");printf("********************\n");printf("请选择: ");scanf("%d", &input);
- do - while 循环保证了循环体至少执行一次。
- 循环体中,首先通过 printf 函数打印出操作选项菜单,提示用户进行选择。然后使用 scanf 函
数读取用户输入的整数,并存储到 input 变量中。
(5)switch语句:
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);
- switch 语句根据 input 的值来执行不同的分支:
- case 1 :当用户选择 1 时,提示用户输入两个操作数,然后使用 scanf 读取,再调用 add 函
数进行加法运算,将结果存储在 ret 中,并打印出结果。
- case 2 :与 case 1 类似,调用 sub 函数进行减法运算。
- case 3 :调用 mul 函数进行乘法运算。
- case 4 :调用 div 函数进行除法运算。不过这里没有对除数为 0 的情况进行处理,如果用户
输入 0 作为除数,程序会产生未定义行为。
- case 0 :当用户选择 0 时,打印“退出程序”,此时 input 的值为 0 , do - while 循环条件不
满足,程序结束。
- default :当用户输入的不是 0 - 4 之间的数字时,打印“选择错误”。
- do - while 循环的条件是 input ,只要 input 不为 0 ,循环就会继续执行,用户可以不断进行操作选择。
(6)函数返回:
return 0;
}
main 函数返回 0 ,表示程序正常结束。在C语言中, main 函数返回 0 通常用于向操作系统表
明程序执行成功。
希望大家能够好好理解转移表这块的代码,感谢大家的观看!
相关文章:
C语言 指针(7)
目录 1.函数指针变量 2.函数指针数组 3.转移表 1.函数指针变量 1.1函数指针变量的创建 什么是函数指针变量呢? 根据前面学习整型指针,数组指针的时候,我们的类比关系,我们不难得出结论: 函数指针变量应该是用来…...
go 编译报错:build constraints exclude all Go files
报错信息: package command-line-arguments imports github.com/amikos-tech/chroma-go imports github.com/amikos-tech/chroma-go/pkg/embeddings/default_ef imports github.com/amikos-tech/chroma-go/pkg/tokenizers/libtokenizers: …...
Android Service 从 1.0 到 16 的演进史
一、Android 1.0(API 1) - 服务的诞生 核心特性: 基础服务组件:作为四大组件之一,Service 用于在后台执行长时间运行的任务,不提供 UI 界面。 启动方式:通过 startService() 启动独立运行的服…...
如何保障服务器租用中的数据安全?
网络科技和互联网的飞速发展,让用户越来越依赖与网络业务,各个行业开展了不同的线上服务,租用服务器已经成为必不可少的组成部分,能够为企业带来便捷,但是数据安全也是不可忽视的,为了能够保护服务器中数据…...
python校园二手交易管理系统-闲置物品交易系统
目录 技术栈介绍具体实现截图系统设计研究方法:设计步骤设计流程核心代码部分展示研究方法详细视频演示试验方案论文大纲源码获取/详细视频演示 技术栈介绍 Django-SpringBoot-php-Node.js-flask 本课题的研究方法和研究步骤基本合理,难度适中…...
消除AttributeError: module ‘ttsfrd‘ has no attribute ‘TtsFrontendEngine‘报错输出的记录
#工作记录 尝试消除 消除“模块ttsfrd没有属性ttsfrontendengine”的错误的记录 报错摘录: Traceback (most recent call last): File "F:\PythonProjects\CosyVoice\webui.py", line 188, in <module> cosyvoice CosyVoice(args.model_di…...
MD2card + Deepseek 王炸组合 一键制作小红书知识卡片
本文目录 MD2Card介绍使用示例deepseek 提示词输出结果MD2Card 制作小红书卡片 MD2Card介绍 MD2Card 是一个免费的 Markdown 转知识卡片工具,支持一键生成小红书风格海报、社交媒体文案排版,让创作者轻松制作精美的图文内容。支持多种主题风格、长文自动…...
Relay算子注册(在pytorch.py端调用)
1. Relay算子注册 (C层) (a) 算子属性注册 路径: src/relay/op/nn/nn.cc RELAY_REGISTER_OP("hardswish").set_num_inputs(1).add_argument("data", "Tensor", "Input tensor.").set_support_level(3).add_type_rel("Identity…...
基于RT-Thread的STM32F4开发第二讲第一篇——ADC
文章目录 前言一、RT-Thread工程创建二、ADC工程创建三、ADC功能实现1.ADC.c2.ADC.h3.mian.c 四、效果展示和工程分享总结 前言 ADC是什么不多讲了,前面裸机操作部分有很多讲述。我要说的是RT-Thread对STM32的ADC外设的适配极其不好,特别是STM32G4系类&…...
py实现win自动化自动登陆qq
系列文章目录 py实现win自动化自动登陆qq 文章目录 系列文章目录前言一、上代码?总结 前言 之前都是网页自动化感觉太容易了,就来尝尝win自动化,就先写了一个qq登陆的,这个是拿到className 然后进行点击等。 一、上代码…...
Axure : 列表分页、 列表翻页
文章目录 引言I 列表分页操作说明II 列表翻页操作说明引言 列表分页实现思路:局部变量、 中继器设置每页项目数 I 列表分页 操作说明 在列表元件底部添加一个分页下拉控件,分别为10,20,30,40,50; 将列表转换为动态面板,将设置面板大小勾选取消 给分页大小下拉控件添加…...
大学之大:隆德大学2025.5.6
隆德大学:北欧学术明珠的八百年传承与创新 一.前身历史:从中世纪神学院到现代综合大学的蜕变 隆德大学的历史可追溯至1425年,由丹麦国王埃里克七世在瑞典南部城市隆德创立的“神学与教会法研究院”。这所中世纪学府最初以培养天主教神职人员…...
每日算法-250506
每日算法学习记录 - 250506 今天记录了三道算法题的解题过程和思路,分享给大家。 3192. 使二进制数组全部等于 1 的最少操作次数 II 题目 思路 贪心 解题过程 我们从左到右遍历数组。使用一个变量 ret 来记录已经执行的操作次数。 对于当前元素 nums[i]&#x…...
【免费试用】LattePanda Mu x86 计算模块套件,专为嵌入式开发、边缘计算与 AI 模型部署设计
本次活动为载板设计挑战,旨在激发创意与技术实践能力,鼓励电子工程师、创客、学生及开发者围绕指定LattePanda Mu进行功能丰富、应用多样的载板开发设计。参赛用户将有机会展示硬件设计能力,并通过作品解决实际问题或构建创新项目。本次挑战活…...
用于备份的git版本管理指令
一、先下载一个git服务器软件并安装,创建一个git服务器进行备份的版本管理。 下列指令用于git常用备份: 1、强制覆盖远程仓库: git push --force origin master 2、重新指向新仓库: git remote set-url origin http://192.168.1.2…...
STM32H743单片机实现ADC+DMA多通道检测
在stm32cubeMX上配置ADCDMA实现多通道检测功能 DMA配置 生成代码,HAL_ADC_Start_DMA开始DMA读取ADC值,HAL_ADC_Stop_DMA关闭DMA读取 void Start_ADC2_DMA(void) {/* 初始化后校准ADC */HAL_ADCEx_Calibration_Start(&hadc2, ADC_CALIB_OFFSET, ADC_…...
(提升)媒体投稿技能
1\前期策划与准备 精准定位目标受众,分析内容偏好与活跃媒体基于目标受众,确定发稿核心主题与内容方向 2\内容创作与素材 撰写稿件注重标题吸引力,确保内容逻辑清晰价值突出。素材整合准备高质量的配图、视频 3\内部审核与优化 对稿件内…...
2025年提交App到Appstore从审核被拒到通过的经历
今年3月份提交一个App到Appstore,感觉比以前要严格了很多,被拒了多次才通过。 如果周末提交审核会非常非常,所以最好选择周一之周四的中午提交。 第一次提交被拒,原因为 Guideline 2.1 - Performance - App Completeness Guidel…...
63.微服务保姆教程 (六) SkyWalking--分布式链路追踪系统/分布式的应用性能管理工具
SkyWalking—分布式链路追踪系统/分布式的应用性能管理工具(APM) 一、为什么要用SkyWalking 对于一个有很多个微服务组成的微服务架构系统,通常会遇到一些问题,比如: 如何串联整个调用链路,快速定位问题如何缕清各个微服务之间的依赖关系如何进行各个微服务接口的性能分…...
vue3 computed方法传参数
我们对computed的基础用法不陌生,比如前端项目中经常会遇到数据处理的情况,我们就会选择computed方法来实现。但大家在碰到某些特殊场景,比如在template模板中for循环遍历时想给自己的计算属性传参,这个该怎么实现呢,很…...
Linux中为某个进程临时指定tmp目录
起因: 在linux下编译k8s,由于编译的中间文件太多而系统的/tmp分区设置太小,导致编译失败,但自己不想或不能更改/tmp分区大小,所以只能通过其他方式解决。 现象: tmp分区大小: 解决方法&#x…...
Informer源码解析4——完整注意力机制解读
完整注意力机制 源码 class FullAttention(nn.Module):def __init__(self, mask_flagTrue, factor5, scaleNone, attention_dropout0.1, output_attentionFalse):"""实现完整的注意力机制,支持因果掩码和注意力权重输出。Args:mask_flag (bool): 是…...
第一节:Web3开发概述
一、什么是Web3? 如果把互联网比作一个「大超市」: Web1(1990年代):你只能看货架上的商品(比如新浪、搜狐这种只读网站)。Web2(现在):你不仅能看࿰…...
【愚公系列】《Manus极简入门》022-艺术创作顾问:“艺术灵感使者”
🌟【技术大咖愚公搬代码:全栈专家的成长之路,你关注的宝藏博主在这里!】🌟 📣开发者圈持续输出高质量干货的"愚公精神"践行者——全网百万开发者都在追更的顶级技术博主! …...
k8s node 内存碎片化如何优化?
在 Kubernetes 集群中,内存碎片化(Memory Fragmentation)会导致系统无法分配连续的内存块,即使总内存充足,也可能触发 OOM(Out of Memory)或影响性能。以下是针对 k8s Node 内存碎片化的优化策略…...
当K8S容器没有bash时7种高阶排查手段
遇到容器没有bash甚至没有sh的情况,就像被困在没有门窗的房间。但真正的K8S运维高手,即使面对这种情况也能游刃有余。以下是我们在生产环境锤炼出的7大实战技巧: 一、基础三板斧(新手必学) 1. 日志捕获术——穿透重启…...
linux -c程序开发
目的是在linux中创建可执行的c语言程序的步骤 和gcc,make和git的简单运用 建立可执行程序的步骤: -1:预处理: --:头文件展开;--去掉注释;--宏替换;--条件编译 -2:编译 --:将预处理之后的c语言替换为汇编语言带阿米 --:语法分析,语义分析,代码生成 --:检查语法正确性并且优…...
LLM损失函数面试会问到的
介绍一下KL散度 KL(Kullback-Leibler散度衡量了两个概率分布之间的差异。其公式为: D K L ( P / / Q ) − ∑ x ∈ X P ( x ) log 1 P ( x ) ∑ x ∈ X P ( x ) log 1 Q ( x ) D_{KL}(P//Q)-\sum_{x\in X}P(x)\log\frac{1}{P(x)}\sum_{x\in X}…...
【redis】redis 手动切换主从
场景一: 测试需要,需要手动切换主从 在redis节点: $ redis-cli -h xx.xx.xx.xx -p XX -a XX shutdown 不要直接关闭redis进程,使用 shutdown ,能在进程关闭前持久化内存中的数据 待主从切换完毕后࿱…...
Webug4.0靶场通关笔记17- 第21关文件上传(htaccess)
目录 第21关 文件上传(htaccess) 1.打开靶场 2.源码分析 (1)右键源码 (2)源码分析 3.渗透实战 (1)配置环境 (2)构造脚本 (3)访问脚本 本文通过《webu…...
ASP.NET Core 中间件
文章目录 前言一、中间件的本质定义:类比: 二、作用场景:三、中间件的执行顺序四、中间件的配置方式1)委托形式(最常见):2)类形式: 五、核心方法六、注意事项七、中间件 …...
Linux:进程间通信---命名管道共享内存
文章目录 1.命名管道1.1 命名管道是什么1.2 如何创建命名管道1.3 如何通过命名管道实现进程间通信 2. 共享内存2.1 共享内存的原理2.2 共享内存的系统接口与接口的调用2.3 共享内存的挂接2.4 共享内存的特性 序:在上一章对用来进行进程间通信的匿名管道进行了详细的…...
一个基于Asp.Net Core + Angular + Bootstrap开源CMS系统
从零学习构建一个完整的系统 推荐一个功能强大、易于扩展、安全可靠的开源内容管理系统,适用于各种类型和规模的网站。 项目简介 MixCoreCMS是一个基于.NET Core框架的开源内容管理系统(CMS),提供了丰富的的基础功能和插件&…...
ECMAScript 6(ES6):JavaScript 现代化的革命性升级
1. 版本背景与发布 发布时间:2015 年 6 月,由 ECMA International 正式发布,标准编号为 ECMA-262 Edition 6(后称 ES2015)。历史意义: JavaScript 诞生 20 年后的革命性升级,首次引入类&#…...
基于WebUI的深度学习模型部署与应用实践
引言 随着深度学习技术的快速发展,如何将训练好的模型快速部署并提供友好的用户交互界面成为许多AI项目落地的关键。WebUI(Web User Interface)作为一种轻量级、跨平台的解决方案,正被广泛应用于各类AI模型的部署场景。本文将详细介绍基于Python生态构建WebUI的技术方案,包…...
MySQL表的增删查改
目录 一、MySQL表的增删查改二、Create单行数据全列插入多行数据 指定列插入插入否则更新替换数据 三、RetrieveSELECT 列WHERE 条件NULL的查询结果排序筛选分页结果 四、Update将孙悟空同学的数学成绩修改为80分将曹孟德同学的数学成绩修改为60分,语文成绩修改为7…...
Android第六次面试总结之Java设计模式(二)
一、适配器模式(Adapter Pattern) 1. ListView vs RecyclerView 的 Adapter 核心区别?为什么 RecyclerView 需要 ViewHolder? 解答: 核心区别: 特性ListView.Adapter(如 ArrayAdapter…...
QuecPython+腾讯云:快速连接腾讯云l0T平台
该模块提供腾讯 IoT 平台物联网套件客户端功能,目前的产品节点类型仅支持“设备”,设备认证方式支持“一机一密”和“动态注册认证”。 BC25PA系列不支持该功能。 初始化腾讯 IoT 平台 TXyun TXyun(productID, devicename, devicePsk, ProductSecret)配置腾讯 IoT…...
说下RabbitMQ的整体架构
RabbitMQ 是一个基于 AMQP(Advanced Message Queuing Protocol) 协议的开源消息中间件,RabbitMQ的整体架构围绕消息的生产、路由、存储和消费设计,旨在实现高效、可靠的消息传递,它由多个核心组件协同工作。 核心组件 …...
Qt Creator 网络编程----Socket客户端服务端
1、在Qt项目中的.pro中添加 network模块,用于Socket网络编程使用 QT network 2、相关Tcp网络通信协议头文件 #include <QtNetwork/QTcpServer> #include <QtNetwork/QTcpSocket> #include <QtNetwork/QHostAddress> 3、Qt socket运行实…...
《深度学习实践教程》[吴微] ch-5 3/5层全连接神经网络
一、练习课本上3层全连接神经网络识别手写数字。 答案代码: import torch from torch import nn, optim from torch.autograd import Variable from torch.utils.data import DataLoader from torchvision import datasets, transforms# 定义一些超参数 batch_size…...
OrcaFex11.5
OrcaFlex 11.5是一款专业的海洋工程动态分析软件 由英国Orcina公司开发 主要用于模拟和分析海洋结构物在复杂海洋环境中的动态响应 该软件广泛应用于海上油气开发 海上风电 海洋可再生能源等领域 OrcaFlex 11.5具有强大的建模和仿真能力 支持多种海洋结构物的模拟 包括船舶 …...
MUX-vlan
MUX-VLAN 理论环节 1. 定义与核心作用 Principal VLAN(主VLAN) 是 MUX VLAN(Multiplex VLAN)架构的核心组件,充当公共资源的访问枢纽,实现以下核心功能: 资源共享:允许所有从VLAN…...
vue3中解决 return‘ inside ‘finally‘ block报错的问题
vue3中解决 return’ inside ‘finally’ block报错的问题 这个错误信息通常表明你在使用Vue 3框架时,在finally块中不正确地使用了return语句。在JavaScript中,finally块是保证执行的最后一个代码块,用于释放资源或执行清理操作,…...
TestStand API 简介
TestStand API 简介 在自动化测试领域,TestStand 凭借其灵活的架构和强大的功能,成为众多开发者的首选工具。而 TestStand API(Application Programming Interface,应用程序编程接口)则是打开 TestStand 强大功能的 “…...
vue2+element实现Table表格嵌套输入框、选择器、日期选择器、表单弹出窗组件的行内编辑功能
vue2element实现Table表格嵌套输入框、选择器、日期选择器、表单弹出窗组件的行内编辑功能 文章目录 vue2element实现Table表格嵌套输入框、选择器、日期选择器、表单弹出窗组件的行内编辑功能前言一、准备工作二、行内编辑1.嵌入Input文本输入框1.1遇到问题1.文本框内容修改失…...
【Docker系列】使用格式化输出与排序技巧
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...
针对面试-redis篇
1. 缓存穿透 什么是缓存穿透? 缓存穿透就是有人查询一个不存在的数据,数据库查询不到数据也不会直接写入缓存,就会导致每次请求都查数据库。 解决方案一:缓存空数据 当数据库中不存在该数据时,直接把查到的空数据给…...
HTML8:媒体元素
视频和音频 视频元素 video 音频 audio <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>媒体元素学习</title> </head> <body> <!--音频和视频 src:资源路径 controls:控制条…...
把其他conda的env复制到自己电脑的conda上
把其他conda的env复制到自己电脑的conda上 一 拷贝 将要拷贝的env环境拷贝到自己电脑的放置env环境的文件夹中 二 添加配置 找到.conda文件夹下的environments.txt文件,添加配置 三 测试 查看环境是否拷贝成功 激活环境 自此就拷贝成功了!&am…...