深入理解指针(7)函数指针变量及函数数组(文章最后放置本文所有原码)
一、函数指针变量
什么是函数指针变量呢?
既然是指针变量,那么它指向的一定是地址,而且我们可以通过地址来调用函数的。
函数是否有地址呢?地址是什么?

经过上面的测试可以看到函数也是有地址的,而且其地址就是函数名(当前是x86环境,这样地址值相对较短更容易分辨)。
1、函数地址的存储
与数组相似,函数的地址存储也是需要使用指针变量来进行存储的。

这里是结果
006F13CA
006F13CA
经过我们上面的代码演示可以看到函数的地址已经被指针p存储了起来,那我们该如何使用他们呢?
2、函数地址的使用
同样我们使用一个代码来清晰的解释如何使用这个话题:

可以看到我们在这里仅使用指针就可以对函数进行访问并使用(提一嘴int(*p)(int, int) = Add;这里的(int,int)可以在后面加上变量,但是不加减少了变量的创建同时也使得代码更简洁)。
我们根据上面以及之前所学习到的所有知识来看下面两段代码(出自《C陷阱和缺陷》这本书):
(*(void (*)())0)();
看到这是不是有点蒙?没关系我来给你逐词解释一下(首先说明这段代码是不可以运行的):

不知道大家对此能否理解呢?
我们来看另外一个:
void (*signal(int , void(*)(int)))(int);
如果可以理解上面的话,下面这段就可以很容易理解了吧!(还是给大家解释一下)

二、typedef关键字
简单说这个关键字的意思就是:重定义一个类型的名字。
例如:

这两个a,b都使用%d 的格式来进行打印,都是没有问题的,但是好像没什么用啊?
其实对于当前代码量较少,类型也比较简单的状态确实没有什么用处,但是当后期学习的更多了就能明白这个的重要性了,比如一个很长的代码中,我们要将其中所有的int类型的数据改成double类型,此时我们只需要在上面进行更改即可,一次更改后面的所有的int类型的数据都会更改为double类型,就不需要再一个一个慢慢的改了!
这个typedef关键字在对函数指针和指针数组在更改时是有所不同的:

在对指针数组和函数指针进行重定义时需要将重定义后的类型放在*的右面。
三、函数指针 数组
要把函数的地址存放到一个数字中,那这个数组就叫函数指针数组,那函数指针的数组怎么定义呢?
int (*parr1[3])(); 这就是它的定义,怎么理解呢?
parr1先和[]结合,说明parr1是数组,数组的内容是什么呢?是int(*)()类型的函数指针。
以下就是本文的所有代码了,需要的朋友自取哦!
制作不易,请点个赞再走吧。
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>//void test()
//{
//
//}
//int Add(int x, int y)
//{
// return x + y;
//}
//int main()
//{
// int x = 0, y = 0;
// Add(x,y);
// //这里要将解引用操作符和p使用括号括起来,主要目的是明确优先级和避免歧义
// int(*p)(int, int) = Add;
// printf("%p\n", p);
// printf("%p\n", &Add);
// //printf("%p\n", test);
// //printf("%p\n", &test);
// return 0;
//}
//int Add(int x, int y)
//{
// return x + y;
//}
//int main()
//{
// int(*p)(int, int) = Add;
// printf("%d\n", p(2, 3));
// printf("%d\n", (*p)(2, 3));
// (*(void (*)())0)();
// void (*signal(int, void(*)(int)))(int);
// return 0;
//}//typedef int INT;
//typedef int(*arr_t)[5];
//typedef int(*ptr_t)(int);
//int p1(int a)
//{
//
//}
//ptr_t p2(int a)
//{
//
//}
//int main()
//{
// //int a = 0;
// //INT b = 3;
// int* arr[] = { 0 };
// arr_t n[] = { 0 };
// printf("%d\n", arr[0]);
// printf("%d\n", n[0]);
// printf("%p\n", p1);
// printf("%p\n", p2);
// //printf("%d\n", a);
// //printf("%d\n", b);
// return 0;
//}int main()
{int (*parr1[3])(); //parr1 先和[] 结合,说明 parr1是数组,数组的内容是什么呢?是 int (*)() 类型的函数指针。return 0;
}
相关文章:
深入理解指针(7)函数指针变量及函数数组(文章最后放置本文所有原码)
一、函数指针变量 什么是函数指针变量呢? 既然是指针变量,那么它指向的一定是地址,而且我们可以通过地址来调用函数的。 函数是否有地址呢?地址是什么? 经过上面的测试可以看到函数也是有地址的,而且其地…...
office办公技能|word中的常见使用问题解决方案2.0
一、设置多级列表将表注从0开始,设置为从1开始 问题描述:word中插入题注,出来的是表0-1,不是1-1,怎么办? 写论文时,虽然我设置了“第一章”为一级标题,但是这三个字并不是自动插入的…...
华为2023年年度报告启示:大学生如何把握未来科技趋势,规划个人发展路径
华为2023年年度报告展现了公司在技术创新、生态构建、社会责任等方面的卓越成就与前瞻布局。对于身处数字化时代的大学生而言,这份报告不仅是洞察科技行业发展趋势的窗口,更是规划个人学业与职业道路的重要参考。本文将从报告中提炼关键信息,…...
刚刚,璞华科技、璞华易研PLM产品荣获智能制造领域两大奖项!
刚刚,在e-works数字化企业网于北京举办的“第十三届中国智能制造高峰论坛暨第二十一届中国智能制造岁末盘点颁奖典礼”上,璞华科技凭借在智能制造领域的雄厚实力和产品口碑,荣获两大奖项。 璞华科技被评为e-works【2023年度智能制造优秀供应…...
乐维更改IP地址
1.1 系统IP调整 vim /etc/sysconfig/network-scripts/ifcfg-ens1921.2 Web相关服务IP变更 1.2.1 编辑/itops/nginx/html/lwjkapp/.env文件,更改ZABBIXSERVER、ZABBIXRPCURL、DB_HOST中的IP 1.2.2 进入/itops/nginx/html/lwjk_app/目录下,执行php bin/manager process-conso…...
大话设计模式之简单工厂模式
简单工厂模式(Simple Factory Pattern)是一种创建型设计模式,属于工厂模式的一种。在简单工厂模式中,有一个工厂类负责根据输入参数的不同来创建不同类的实例。 简单工厂模式包含以下几个要素: 1. **工厂类࿰…...
设计模式之单例模式精讲
UML图: 静态私有变量(即常量)保存单例对象,防止使用过程中重新赋值,破坏单例。私有化构造方法,防止外部创建新的对象,破坏单例。静态公共getInstance方法,作为唯一获取单例对象的入口…...
论文复现3:Stable Diffusion v1
abstract: 通过将图像形成过程分解为去噪自动编码器的顺序应用,扩散模型 (DM) 在图像数据及其他方面实现了最先进的合成结果。此外,他们的公式允许一种指导机制来控制图像生成过程,而无需重新训练。然而,由于这些模型通常直接在像素空间中运行,因此强大的 DM 的优化通常会…...
Halcon与VisionMaster对比
作为一个经验丰富的机器视觉算法工程师,我对于机器视觉软件的评价会基于多年的实践经验和对不同软件功能的深入了解。在评价VisionMaster和Halcon软件时,我会从使用场景、工作效率、使用便捷性等方面进行全面分析,并结合软件的优缺点进行讨论…...
多线程的学习1
多线程 线程是操作系统能够进入运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。 进程:是程序的基本执行实体。 并发:在同一个时刻,有多个指令在单个CPU上交替执行。 并行:在同一时刻,…...
警务数据仓库的实现
目录 一、SQL Server 2008 R2(一)SQL Server 的服务功能(二)SQL Server Management Studio(三)Microsoft Visual Studio 二、创建集成服务项目三、配置“旅馆_ETL”数据流任务四、配置“人员_ETL”数据流任…...
Excel·VBA数组分组问题
看到一个帖子《excel吧-数据分组问题》,对一组数据分成4组,使每组的和值相近 目录 代码思路1,分组形式、可分组数代码1代码2代码2举例 2,数组所有分组形式举例 这个问题可以转化为2步:第1步,获取一组数据…...
【笔记】Hbase基础笔记
启动hbase:进入hbase安装目录 输入bin/start-hbase.sh 打开shell命令行模式:进入hbase安装目录 输入bin/hbase shell 退出shell命令行模式:exit 停止hbase:进入hbase安装目录 输入bin/stop-hbase.sh 启动关闭Hadoop和HBase的顺序一…...
创建vue3项目并集成cesium插件运行
创建vue3项目并集成cesium插件 一、vue项目创建 1、前期准备 node.js&npm或yarn 本地开发环境已经安装好。 参考安装 2、安装vue-cli,要求3以上版本 #先查看是否已经安装 vue -V#安装 npm install -g vue/cli4.5.17 示例:Idea工具 页面 Termin…...
Mac 装 虚拟机 vmware、centos7等
vmware: https://www.vmware.com/products/fusion.html centos7 清华镜像: 暂时没有官方的 m1 arm架构镜像 centos7 链接: https://pan.baidu.com/s/1oZw1cLyl6Uo3lAD2_FqfEw?pwdzjt4 提取码: zjt4 复制这段内容后打开百度网盘手机App,操…...
工厂能耗管控物联网解决方案
工厂能耗管控物联网解决方案 工厂能耗管控物联网解决方案是一种创新的、基于先进技术手段的能源管理系统,它深度融合了物联网(IoT)、云计算、大数据分析以及人工智能等前沿科技,以实现对工业生产过程中能源消耗的实时监测、精确计…...
中间件学习
一、ES 场景:某头部互联⽹公司的好房业务,双⼗⼀前⼀天,维护楼盘的运营⼈员突然接到合作开发商的通知,需要上线⼀批热⻔的楼盘列表,上传完成后,C端⼩程序⽀持按楼盘的名称、户型、⾯积等产品属性全模糊搜索…...
iOS开发进阶(十一):ViewController 控制器详解
文章目录 一、前言二、UIViewController三、UINavigationController四、UITabBarController五、UIPageViewController六、拓展阅读 一、前言 iOS 界面开发最重要的首属ViewController和View,ViewController是View的控制器,也就是一般的页面,…...
修改mysql密码
1.在此处文件夹下打开cmd 2.输入命令mysqladmin -uroot -p旧密码 password 新密码 3.在navicat进行测试连接...
uniapp 使用命令行创建vue3 ts 项目
命令行创建 uni-app 项目: vue3 ts 版 npx degit dcloudio/uni-preset-vue#vite-ts 项目名称注意 Vue3/Vite版要求 node 版本^14.18.0 || >16.0.0 如果下载失败,请去gitee下载 https://gitee.com/dcloud/uni-preset-vue/repository/archive/vite-ts…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...
MySQL JOIN 表过多的优化思路
当 MySQL 查询涉及大量表 JOIN 时,性能会显著下降。以下是优化思路和简易实现方法: 一、核心优化思路 减少 JOIN 数量 数据冗余:添加必要的冗余字段(如订单表直接存储用户名)合并表:将频繁关联的小表合并成…...
jmeter聚合报告中参数详解
sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...
WebRTC从入门到实践 - 零基础教程
WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC? WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音…...
