C语言基础——指针(5)
一. 函数指针变量
1. 函数指针变量的定义:
类比数组指针变量,数组指针变量是存放数组地址的变量,那么同理,函数指针变量就是存放函数地址的变量。
2. 创建函数指针变量:
函数是有地址的,函数名就是函数的地址。此外,&函数名也是函数的地址,二者本质上一样,因此,它们的地址也一样。

我们如果想将函数的地址存放起来,就需要创建函数指针变量了,以下是函数指针变量的创建方式(以上图函数为例):
int (* p)(int x,int y)=plus;
对函数指针变量创建的理解,和对数组指针变量的理解是相似的:
P是一个变量,那么(*p)意思是这个变量是个指针变量;在括号中的(int x,int y)表示p这个指针变量指向的参数的类型和参数的个数。要注意的是,在这里写下x,y和不写都是可以的,只要表明参数的个数和类型就行;最后,最前面的int表示这个函数指针变量指向的返回类型是int类型的。
3. 函数指针变量的使用:
我们通过创建一个加法函数来学习函数指针变量的使用:
int plus(int x, int y)
{
return x + y;
}
int main()
{
int x = 0; int y = 0;
printf("请输入两个数");
scanf("%d %d", &x, &y);
int (*p)(int x, int y) = plus;//创建一个函数指针变量来存放plus这个函数
printf("%d", (*p)(x, y));
return 0;
}
对于(*p)(x, y)这行代码,我们可以这么理解:
通过函数指针p调用指向的函数,并将x和y作为参数传给该函数。
二. typedef关键字
在C语言中,很多时候有很多类型比较长,这时候,如果我们想将这些类型简化,就需要使用typedef关键字,以下是它的基本使用方法(以
unsigned int 为例)
typedef unsigned int uint;
这样,在之后敲写代码的时候,就可以用uint 来代替了。
注:对于数组指针和函数指针要命名时,方法稍有不同:
数组指针:eg: typedef int(* name)[8]
函数指针:eg: typedef int(* name)(int x,int y)
三. 函数指针数组
按照之前所说的理解方式,我们重点关注最后两个字:数组;所以,函数指针数组是存放函数指针变量的数组,下面,我们通过创建一个简单的计算器来学习函数指针数组的应用。
创建简单计算器的基本步骤:
(1)创建四个函数,分别可以进行加减乘除的运算
(2)创建一个菜单,表示计算器的开始界面
(3)让读者选择是否开始使用计算器
(4)让读者选择要使用的计算方法
(5)让读者输入要计算的数
(6)计算结果并给出答案
函数指针数组的创建和使用和函数指针变量类似,以下是其创建和使用格式:
创建:int (*p[5])(int x, int y)
由于[ ]的计算等级比*高,所以p先和[ ]结合,意味着p是一个数组;其再和*结合,意味着这是一个指针数组,而这个指针数组中存放的就是一个或多个函数的地址。这样也就意味着,所有存放的函数的参数和返回值必须是一样的,这样函数指针数组才可以使用。
使用:(*p[input])(x, y)
*p[input]的意思是指向这个函数指针数组中选择的input中的函数,用(x,y)将其赋值,并使用这个函数。
以下是参考代码:
int first(int x, int y)
{
return x + y;
}
int second(int x,int y)
{
return x - y;
}
int third(int x, int y)
{
return x * y;
}
int forth(int x, int y)
{
return x / y;
}
void menu(void)
{
printf("******************************\n");
printf("**********0.退出 ************\n");
printf("**********1.加法 ************\n");
printf("**********2.减法 ************\n");
printf("**********3.乘法 ************\n");
printf("**********4.除法 ************\n");
printf("******************************\n");
}
int main()
{
int input = 0;//选择数
int x = 0;
int y = 0;//要计算的数
//创建一个函数指针数组来存放函数指针变量
int (*p[5])(int x, int y) = { 0,&first,&second,&third,&forth };
int a = 0;//创建一个数来接收函数传过来的变量,便于理解和打印
do
{
menu();
printf("请选择:");
scanf("%d", &input);
if (input <= 4 && input >= 1)
{
printf("请输入要计算的数\n");
scanf("%d %d", &x, &y);
a = (*p[input])(x, y);
printf("计算结果是%d\n", a);
}
else if (input == 0)
{
printf("退出计算器\n");
}
else
{
printf("选择错误,请重新选择\n");
}
} while (input);
return 0;
}
四. 几个基本概念的辨别
数组指针:是指针,里面存的是数组的地址
指针数组:是数组,里面存的是一个或多个指针(地址)
函数指针:是指针,里面存的是一个函数的地址
函数指针数组:是数组,里面存的是一个或多个函数的地址
数组指针:
创建:int (*p)[5]=&arr
使用:(*p)[想找的数组的下标数]
指针数组:
创建:int *arr[3]={arr1,arr2,arr3}
使用:arr[arr中数组的下标][arr 1/2/3中数组的下标]
函数指针:
创建:int (*p)(int x,int y)=&函数名;
使用:(*p)(x,y)
函数指针数组:
创建:int(*p[5])(int x,int y)={&函数名1,&函数名2}
使用:(*p[想找的函数名的下标])(x,y)
相关文章:
C语言基础——指针(5)
一. 函数指针变量 1. 函数指针变量的定义: 类比数组指针变量,数组指针变量是存放数组地址的变量,那么同理,函数指针变量就是存放函数地址的变量。 2. 创建函数指针变量: 函数是有地址的࿰…...
curl+openssl 踩坑笔记
curl编译:点击跳转 踩坑一 * SSL certificate problem: unable to get local issuer certificate * closing connection #0 curl: (60) SSL certificate problem: unable to get local issuer certificate More details here: https://curl.se/docs/sslcerts.html …...
Unity 实现Canvas显示3D物体
新建一个UI相机,选择渲染层为UI 将主相机的渲染层去掉UI层 、 将Canvas的RenderMode设置为Screen Space - Camera,将RenderCamera设置为UI相机 新建3D物体的UI父物体,并将3D物体的层级设置为UI层 适当的放缩3DObjParent,让3D物体能显示出来…...
【Docker命令】如何使用`docker exec`在容器内执行命令
大家好,今天我们来聊聊Docker容器管理中的一个非常有用的命令:docker exec。在日常工作中,我们经常需要在运行中的Docker容器内执行各种命令,docker exec正是帮助我们实现这一需求的利器。下面我将通过一个简单的例子,…...
NetSuite Formula(HTML)超链打开Transaction
当Saved Search作为Sublist应用在Form时,如果Document Number是Group过的,则会出现如下超链失效的情况。 解决办法: 可以利用Saved Search中的Formula(HTML)功能来构建超链,用于打开Transaction。 以下图…...
【React】- 跨域PDF预览、下载(改文件名)、打印
我们经常会碰到跨域来方位PDF,同时需要下载、打印的需求,通常由于浏览器的安全策略,可以预览,但是下载和打印可能会受限,这时候怎么办呢? 1.创建一个隐藏的标签 要下载 iframe 中的 PDF 文件,…...
git clone ssh 设置代理
Linux配置方法 编辑 ~/.ssh/config 文件 Host github.com Hostname github.com ProxyCommand nc -v -x 127.0.0.1:1080 %h %pwindows配置方法 编辑 C:\Users\当前用户名.ssh\config 文件 Host github.com Hostname github.com ProxyCommand connect -S 127.0.0.1:1080 %h %…...
RK3568平台(USB篇)USB网络共享
使用RK的USB网络共享,在内核里面已经有了,这不需要自己写驱动程序,只需要把内核自带的USB网络共享的驱动添加上去即可。 一.RNDIS 协议简介 RNDIS 是微软定义的一种协议,它允许通过 USB 接口实现网络连接。通过 RNDIS,USB 设备可以充当网络适配器,允许主机通过 USB 与设…...
vite 打包时:JavaScript heap out of memory(内存溢出)
出错原因分析: 执行命令 npm run build 时出现以下错误提示: vite v3.2.7 building for production... 11:22:34 transforming (3) src\main.tsWARN Browserslist: caniuse…...
【服务器学习专栏 1.2 -- 带外管理】
请阅读 嵌入式学习必备专栏 文章目录 Overview服务器带外管理BMC 介绍BMC 特点BMC 工作原理 Overview 从技术的角度,网络管理可分为带外管理(out-of-band)和带内管理(in-band)两种管理模式。 带内管理,是指…...
微服务のGeteWay
目录 概念: 三大核心: 工作流程: 9527网关如何做路由映射: GetWay高级特性: 按服务名动态路由服务: 断言Route Predicate Factories : 获取当前时区时间: After Route &…...
html+css+js网页设计 美食 美食家6个页面
htmlcssjs网页设计 美食 美食家6个页面 网页作品代码简单,可使用任意HTML辑软件(如:Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作)。 获取源码 1…...
IntelliJ Idea常用快捷键详解
文章目录 IntelliJ Idea常用快捷键详解一、引言二、文本编辑与导航1、文本编辑2、代码折叠与展开 三、运行和调试四、代码编辑1、代码补全 五、重构与优化1、重构 六、使用示例代码注释示例代码补全示例 七、总结 IntelliJ Idea常用快捷键详解 一、引言 在Java开发中ÿ…...
服务器虚拟化:它是什么以及有什么好处?
运行虚拟服务器有助于创建更高效的 IT 基础架构。 随着业务每天收集的数据量逐年激增,传统的物理服务器已经无法单独满足业务需求。 相反,许多组织正在转向虚拟化的力量。 这是我们创建物理实体的虚拟版本的过程,在计算中,通常指…...
Python爬虫完整代码拿走不谢
对于新手做Python爬虫来说是有点难处的,前期练习的时候可以直接套用模板,这样省时省力还很方便。 使用Python爬取某网站的相关数据,并保存到同目录下Excel。 直接上代码: import re import urllib.error import urllib.request…...
MLA:多头潜在注意力
MLA:多头潜在注意力 多头潜在注意力(MLA)机制是一种在深度学习模型中用于处理序列数据的注意力机制的改进形式,以下是对其原理和示例的详细介绍: 原理 低秩键值联合压缩:MLA机制利用低秩键值联合压缩来消除注意力模块中的某些计算,从而提高模型的运行速度和性能。在传…...
阿里云大模型ACP高级工程师认证模拟试题
阿里云大模型ACP高级工程师认证模拟试题 0. 引言1. 模拟试题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题单选题单选题多选题多选题单选题多选题单…...
游戏引擎学习第67天
reviewing “apron”概念以更新区域 我们正在进行模拟区域的扩展工作,目标是通过增加一个更大的区域来支持更丰富的互动,尤其是那些可能超出摄像机视野的内容。现有的模拟区域包括摄像机能看到的区域和其周围的环境区域,但为了保证更高效的游…...
Nginx知识详解(理论+实战更易懂)
目录 一、Nginx架构和安装 1.1 Nginx 概述 1.1.1 nginx介绍 1.1.2?Nginx 功能介绍 1.1.3?基础特性 1.1.4?Web 服务相关的功能 1.2?Nginx 架构和进程 1.2.1?Nginx 进程结构 1.2.2?Nginx 进程间通信 1.2.3?Nginx 启动和 HTTP 连接建立 1.2.4?HTTP 处理过程 1…...
# 【鸿蒙开发】多线程之Worker的使用
【鸿蒙开发】多线程之Worker的使用 文章目录 【鸿蒙开发】多线程之Worker的使用前言一、Worker的介绍二、注意事项三、Worker使用示例1.新建一个Worker2.主线程使用Worker3.子线程Worker的使用 四、效果展示 前言 本文主要介绍了多线程的方法之一,使用Worker开启多…...
技术判断力之AI三问涌
认识Pass层级结构 Pass范围从上到下一共分为5个层级: 模块层级:单个.ll或.bc文件 调用图层级:函数调用的关系。 函数层级:单个函数。 基本块层级:单个代码块。例如C语言中{}括起来的最小代码。 指令层级:单…...
ArcGIS Pro实战:5分钟搞定气象站点TXT坐标转面状Shapefile(附Python脚本)
ArcGIS Pro气象数据处理实战:从TXT坐标到面状Shapefile的高效转换 在地理信息系统(GIS)工作中,气象站点数据的处理是常见但容易出错的环节。许多气象数据以TXT格式存储,包含站点坐标和边界信息,而将这些数据转换为GIS可用的面状Sh…...
PyCharm虚拟环境配置避坑指南:为什么你的模块导入有提示但运行报错?
PyCharm虚拟环境配置避坑指南:为什么你的模块导入有提示但运行报错? 作为Python开发者,PyCharm的智能提示功能是我们日常开发的重要助力。但你是否遇到过这样的情况:明明在虚拟环境中安装了模块,代码运行时一切正常&am…...
恒压供水全套图纸程序 西门子s7-200smart西门子触摸 屏 1.恒压供水系统
恒压供水全套图纸程序 西门子s7-200smart西门子触摸 屏 1.恒压供水系统,采用西门子S7-200smart PLC,西门子IE700触摸屏; 2.一拖三,根据设定压力自动投切电机,自动升降频率,PID调节,程序逻辑…...
告别浏览器!用JavaFX WebView给你的桌面应用嵌入一个“活”网页(附完整代码)
JavaFX WebView深度实战:打造高性能嵌入式浏览器组件 当我们需要在JavaFX桌面应用中嵌入动态网页内容时,WebView组件往往是最优雅的解决方案。不同于简单调用系统浏览器,WebView提供了完全可控的渲染环境,让网页内容与应用界面无缝…...
股票数据接口对比:A股、B股、港股哪个更适合你的需求?
股票数据接口深度解析:如何根据投资策略选择A股、B股与港股数据源 当你在凌晨三点盯着屏幕上的K线图,突然发现一个关键指标缺失导致策略失效时,那种挫败感足以让任何投资者彻夜难眠。选择正确的股票数据接口,就像为你的投资引擎选…...
docker-enter 脚本完全解析:简化 nsenter 使用的终极工具
docker-enter 脚本完全解析:简化 nsenter 使用的终极工具 【免费下载链接】nsenter 项目地址: https://gitcode.com/gh_mirrors/ns/nsenter 在 Docker 容器管理的早期阶段,nsenter 是一个极其重要的工具,它允许用户直接进入容器的命名…...
ElementPlus主题定制实战:从零到一打造个性化UI风格
1. 为什么需要定制ElementPlus主题? 在实际项目开发中,我们经常会遇到这样的场景:UI设计师给出一套全新的配色方案,要求将ElementPlus默认的蓝色主题替换成项目专属的配色。这时候很多新手开发者可能会直接通过CSS样式覆盖的方式修…...
ESLint Config Standard 与其他配置方案对比:为什么选择标准风格
ESLint Config Standard 与其他配置方案对比:为什么选择标准风格 【免费下载链接】eslint-config-standard ESLint Config for JavaScript Standard Style 项目地址: https://gitcode.com/gh_mirrors/es/eslint-config-standard ESLint Config Standard 是 J…...
SEO_ 低成本高效进行SEO推广的实战策略
低成本高效进行SEO推广的实战策略 在当今数字化时代,SEO(搜索引擎优化)已经成为了每个企业网站流量获取的重要手段。SEO推广的成本往往让人望而却步。本文将为您揭示低成本高效进行SEO推广的实战策略,帮助您在有限的预算内最大化…...
