深入理解指针(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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/499908.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何准备科学海报

科学会议上的海报展示可以为早期职业研究人员提供宝贵的机会来练习他们的沟通技巧&#xff0c;获得有关他们研究的反馈&#xff0c;并扩大他们的网络。“通过与其他研究人员一对一地讨论我的工作&#xff0c;[我发现]我可以确定哪些工作做得好&#xff0c;哪些需要改进&#xf…

dnf手游:如何利用副本和任务快速积累泰拉财富?

DNF手游中&#xff0c;搬砖赚钱的方式多种多样&#xff0c;其中利用副本和任务是一种快速赚取泰拉的有效途径。本攻略将介绍如何通过参与副本和任务来获取泰拉&#xff0c;帮助玩家在游戏中获得更多的经济收益。 一、认识游戏中的泰拉 在DNF手游中&#xff0c;泰拉是一种主要的…

HarmonyOS 开发之应用/组件级配置

在开发应用时&#xff0c;需要配置应用的一些标签&#xff0c;例如应用的包名、图标等标识特征的属性。本文描述了在开发应用需要配置的一些关键标签。 应用包名配置 应用需要在工程的AppScope目录下的 app.json5配置文件 中配置bundleName标签&#xff0c;该标签用于标识应用…

Containerd 介绍、安装和使用

Containerd介绍、安装和使用 文章目录 Containerd介绍、安装和使用1.containerd是什么&#xff1f;2.Containerd安装2.1 主机初始化2.1.1 设置ip地址2.1.2 配置镜像源2.1.3 关闭防火墙2.1.4 禁用SELinux2.1.5 禁用swap2.1.6 设置时区 2.2 安装 containerd2.2.1 内核参数调整2.2…

基于SSM的高校普法系统(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的高校普法系统&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spring Spri…

每天五分钟深度学习:使用神经网络完成人脸的特征点检测

本文重点 我们上一节课程中学习了如何利用神经网络对图片中的对象进行定位,也就是通过输出四个参数值bx、by、bℎ和bw给出图片中对象的边界框。 本节课程我们学习特征点的检测,神经网络可以通过输出图片中对象的特征点的(x,y)坐标来实现对目标特征的识别,我们看几个例子。…

Oracle-MNIST代码学习

一、网络结构 二、代码学习 2.1、x = F.relu(self.conv1(x)) # self.conv1 = nn.Conv2d(1, 20, 5, 1) ​​​​​ 1)Conv2d 详解参考:PyTorch nn.Conv2d - 知乎 2) relu pytorch学习线性回归与非线性回归,以及理解nn.linear()和ReLU激活函数_pytorch 非线性函数作用-C…

访学博后须知|携带手机等电子产品入境美国注意事项

美国对携带手机等电子产品入境有着严格的规定&#xff0c;因此知识人网小编提醒拟出国做访问学者、博士后或联合培养的博士生了解以下注意事项&#xff0c;尽量减少不必要的麻烦。 随着互联网的普及&#xff0c;手机等电子产品在人民生活中占有不可或缺的地位。因为研究和工作需…

AcWing刷题-空调

空调 差分&#xff1a; N int(input()) p list(map(int, input().split())) t list(map(int, input().split())) d,s[0]*100010,[0]*100010 for i in range(N):d[i] p[i]-t[i]for i in range(N):s[i] d[i]s[i1] - d[i] ans 0 for i in range(N1):if s[i]>0:ans s[i]…

大话设计模式之代理模式

代理模式&#xff08;Proxy Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许通过代理对象控制对另一个对象的访问。代理对象充当客户端和实际对象之间的中介&#xff0c;客户端通过代理对象间接访问实际对象&#xff0c;从而可以在访问控制、缓存、延迟加载等方面提…

二维随机变量的条件分布-已知X概率密度,X条件下的Y概率密度求解y的概率密度

问题&#xff1a;设数X在区间(0,1)上随机地取值,当观察到Xx(0<x<1)时,数Y在区间(x,1)上随机地取值.求Y的概率密度f(y)&#xff1f; 求解&#xff1a; 首先&#xff0c;数X在区间(0,1)上均匀分布&#xff0c;因此其概率密度函数fX​(x)为&#xff1a; fX​(x)1 0<…

PLC_博图系列☞N:扫描操作数的信号下降沿

PLC_博图系列☞N&#xff1a;扫描操作数的信号下降沿 文章目录 PLC_博图系列☞N&#xff1a;扫描操作数的信号下降沿背景介绍N&#xff1a;扫描操作数的信号下降沿说明参数示例 关键字&#xff1a; PLC、 西门子、 博图、 Siemens 、 N 背景介绍 这是一篇关于PLC编程的文章…

代码随想录算法训练营第二十四天| 理论基础,77. 组合

题目与题解 参考资料&#xff1a;回溯法理论基础 带你学透回溯算法&#xff08;理论篇&#xff09;| 回溯法精讲&#xff01;_哔哩哔哩_bilibili 77. 组合 题目链接&#xff1a;​​​​​​​​​​​​​​77. 组合 代码随想录题解&#xff1a;77. 组合 视频讲解&#xff…

AI的“换脸“魔术,究竟是弊大于利还是利大于弊?

公众号&#xff1a;【可乐前端】&#xff0c;每天3分钟学习一个优秀的开源项目&#xff0c;分享web面试与实战知识&#xff0c;也有全栈交流学习摸鱼群&#xff0c;期待您的关注! 每天3分钟开源 hi&#xff0c;这里是每天3分钟开源&#xff0c;很高兴又跟大家见面了&#xff0…

知识图谱与大数据:区别、联系与应用

目录 前言1 知识图谱1.1 定义1.2 特点1.3 应用 2 大数据2.1 定义2.2 应用 3. 区别与联系3.1 区别3.2 联系 结语 前言 在当今信息爆炸的时代&#xff0c;数据成为了我们生活和工作中不可或缺的资源。知识图谱和大数据是两个关键概念&#xff0c;它们在人工智能、数据科学和信息…

C++入门知识(1)

命名空间的引入 C语言的缺陷以及C的解决。 看下面这个代码&#xff1a; 这里进行了报错。 这里包含rand所在的头文件&#xff0c;然后头文件会进行展开。然后头文件里的rand和全局变量rand就会发生冲突。 这个就叫做命名冲突。 因此C引入了一个解决办法 namespace&#x…

EasyRecovery2024 安装步骤及功能特色介绍

在数字化时代&#xff0c;数据的重要性不言而喻。无论是个人用户还是企业用户&#xff0c;都可能面临数据丢失的风险。为了应对这一挑战&#xff0c;EasyRecovery作为一款专业的数据恢复软件&#xff0c;成为了越来越多人的选择。 EasyRecovery以其强大的功能和易用的界面&…

老阳推荐的视频号项目是真的吗?能赚钱吗?

在当下数字化、信息化的社会背景下&#xff0c;视频号项目如雨后春笋般涌现&#xff0c;成为许多人关注的焦点。特别是在一些知名人士&#xff0c;如老阳的推荐下&#xff0c;这些项目更是受到了广泛的关注和讨论。那么&#xff0c;老阳推荐的视频号项目是否真实存在?它能否真…

一篇复现Dockerfile指令

华子目录 制作镜像基于dockerfile制作镜像dockerfile介绍注意 格式PATH上下文路径URL- Dockerfile指令-FROM指令格式示例 Dockerfile指令-MAINTAINER指令介绍示例 Dockerfile指令-COPY指令介绍示例1示例2 Dockerfile指令-ADD指令介绍示例 Dockerfile指令-WORKDIR指令介绍示例 D…

【详细讲解Android Debug Bridge各种命令及用法的文章】

&#x1f525;博主&#xff1a;程序员不想YY啊&#x1f525; &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家&#x1f4ab; &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 &#x1f308;希望本文对您有所裨益&#xff0c;如有…