[C语言]指针详解一、数组指针、二维数组传参、函数指针

news2024/9/19 21:51:45

一、数组指针

对一个数组,如果我们想要让一个指针指向这个数组,我们应该如何定义呢?我们知道一个数组定义本来就是一个指针,那为何要多定义一个数组指针呢?我们来看看下面这个代码就理解了

#include <stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5 };
	int(*parr)[5] = arr;
	printf("%d\n", *(arr + 1));
	printf("%d\n", *(parr + 1));
}

第一个是我们正常定义的数组

int arr[] 

第二个就是我们定义这个数组的指针

要注意与int*parr[5]的区别,我们上面打字的方式代表的是(*parr)指向了一个数组大小为[5]的指针,而int*parr[5]代表了有个parr[5]的数组里面装的都是指向整形的指针

我们来看一下将他们的地址分别加一得到的结果

我们看到第一个输出结果为2,第二个输出结果是一个很大的数字,这是怎么回事呢?

其实正常数组定义出来计算出来的结果+1就是里面的元素地址加对应所占字节大小的长度,所以到了第二个元素的地址

而对于我们定义的数组指针+1是直接越过了整个数组,所以他的地址加了五个元素,我们可以看看数组内地址的分布情况

下面的parr+1打印就让其打印了越界的0x000000C5642FFCCC的值,这就是为什么打印出来的两个数字不同的原因。

二、二维数组传参

二维数组传参的方式有三种,第一种是直接定义一个函数,函数内的类型和数组的大小相定义就好,如 要传递一个整型二维数组,其大小为3行五列,返回值为空,我们只需要输入:

                    void ( int a[3][5] )

 第二种方式就是不输入多少行输入几列就可以了如我们还是传递一个跟上面一样的数组,我们只需要输入

  void ( int a[][5] )

第三种方式就是用我们定义的数组指针的方式,如上述一样的传递参数,我们输入如下:

void(int (*a)[5])

三种方法均可以传递二维数组

注意我们传递过去的参数为二维数组第一行的地址,是第一维数组的地址

三、函数指针

如果我们要将一个函数保存到一个地址内,应该如何表达呢?

下面我们来看一下代码

void(*pfun)()

void*pfun()

这两个表达式哪一个可以存放函数的地址呢?答案是第一个可以存放,第一个*先和pfun结合表示的是一个指针,然后再和()结合表示的是一个函数,最后void表示返回的是空值。

而第二个表达式,代表了pfun这个函数返回了一个空指针类型

两者少一个括号是完全不同的

下面我们来看一下两个有趣的代码来练习一下掌握的情况

    对于代码1,

我们一步步来解读,首先我们看到最前面的*,我们可以断定这个*是对后面括号地址的一个解引用,那后面这段代码是哪个地址呢,我们看括起来的部分这里有一个有意思的地方就是有一个0,那我们想,这里面是不是0这个数字对应的地址呢?对于我们之前学过的一个强制类型转换,我们知道如果对于一个变量,我们可以用(int *)让其来强制转换为指向整型元素的地址,如果我们看这个void(*)()中间加一个随便的变量如p 变成 void (*p)()我们可以发现这是定义了一个函数指针,其实如果这里的p省去后面再加0就代表了把这个0强制转换为函数指针地址,其返回类型为空,如果对其解引用我们就可以看到代码1的样子,最后一个括号为其要输入的参数

  对于代码2

我们看到signal后面有一个括号代表它是一个函数,其中里面的参数第一个为int,第二个是一个函数指针,其中函数指针的输入是int类型返回为void,其次signal返回的类型也是一个函数指针,其中指向类型为int,返回类型为void的函数,其中signal为函数的声明。

对于代码1,有些程序或者编译器允许访问0的地址,但是笔者没有这样的环境就不演示了,对于代码2,我认为看文字理解是有点吃力的,笔者自己看视频也有些难以理解,因为本人能力有限,我把自己所理解的代码2试着自己编写了一个代码验证自己的思想如下:

#include <stdio.h>

void ADD(int b)
{
	b = b + 3;
	printf("%d\n", b);
}

void (*signal(int a, void(*random)(int)))(int)
{

	random(a);
	return random;
}

int main()
{
	int x = 1;
	signal(x, ADD)(4);
}

其中signal函数内部还需要一个返回值为空输入参数为int的函数,我们简单定义一个ADD函数,并且让其输入的参数加三并且打印出来,对于signal函数我们让其调用的时候,对输入的整型变量a调用我们自己定义的函数,也就是ADD函数,然后这个函数要求返回的是一个返回值为空输入变量为int的函数,那很简单,我们让其直接返回random也就是我们自己定义的ADD函数即可

接下来我们在主函数定义一个变量x,让其代入signal(x,ADD)并且后面跟一个4的常量,按理来说应该x先输入进去加3得到4并且打印出来,然后我们返回ADD函数,在进行ADD(4)得到4+3=7再打印出来,我们看看输出结果是不是这样呢?

可以看到本人自定义的函数输出结果确实如此,不知道这样有没有让读者更加理解第二个代码呢?

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

android adb 实时画面 和操作

1. 下载 scrcpy 建议 windows10 用户 点击链接下载 不然可能会提示缺少部分 dll https://github.com/Genymobile/scrcpy/releases/download/v2.3.1/scrcpy-win32-v2.3.1.ziphttps://github.com/Genymobile/scrcpy/releases/download/v2.3.1/scrcpy-win32-v2.3.1.zip windo…

解决Vue发布后新旧包切换点击路由报错问题

错误截图 解决方案&#xff1a; 1.修改vue.config.js output: {// filename: js/[name].[chunkhash].${timeUpdate}.js,// chunkFilename: js/[id].[chunkhash].${timeUpdate}.jsfilename: [name].[contenthash].js,chunkFilename: [name].[contenthash].chunk.js}2.路由中添…

【算法刷题】Day32

文章目录 1. 单词拆分题干&#xff1a;算法原理&#xff1a;1. 状态表示&#xff1a;2. 状态转移方程3. 初始化4. 填表顺序5. 返回值 代码&#xff1a; 2. 环绕字符串中唯一的子字符串题干&#xff1a;算法原理&#xff1a;1. 状态表示&#xff1a;2. 状态转移方程3. 初始化4. …

突破数据处理极限:揭秘亚信安慧AntDB

亚信安慧AntDB数据库在运营商自主可控替换项目中的成功应用&#xff0c;具有极其重要的意义。该数据库的落地&#xff0c;不仅为这一项目注入了强大的支持力量&#xff0c;还在更大程度上提升了整体的运营效能。作为一种高效可靠的数据库解决方案&#xff0c;AntDB引入了先进的…

苍穹外卖-day13:vue基础回顾+进阶

vue基础回顾进阶 课程内容 VUE 基础回顾路由 Vue-Router状态管理 vuexTypeScript 1. VUE 基础回顾 1.1 基于脚手架创建前端工程 1.1.1 环境要求 要想基于脚手架创建前端工程&#xff0c;需要具备如下环境要求&#xff1a; ​ node.js 前端项目的运行环境 学习web阶段已安…

Windows Server 各版本搭建远程访问 / VPN 服务器实现 VPN 连接(03~19)

一、Windows Server 2003 开机后点击添加或删除角色 点击下一步 勾选自定义&#xff0c;点击下一步 点击 远程访问/VPN 服务器&#xff0c;点击下一步 点击下一步 点击下一步 勾选自定义&#xff0c;点击下一步 选择配置类型&#xff0c;点击下一步 点击完成 点击是 点击完成…

Ubuntu使用Docker部署Nginx容器并结合内网穿透实现公网访问本地服务

目录 ⛳️推荐 1. 安装Docker 2. 使用Docker拉取Nginx镜像 3. 创建并启动Nginx容器 4. 本地连接测试 5. 公网远程访问本地Nginx 5.1 内网穿透工具安装 5.2 创建远程连接公网地址 5.3 使用固定公网地址远程访问 ⛳️推荐 前些天发现了一个巨牛的人工智能学习网站&#…

jar读取目录配置、打包jar后无法获取目录下的配置

jar读取目录配置、打包jar后无法获取目录下的配置 jar读取目录配置、打包jar后无法获取目录下的配置。java打成jar包后获取不到配置文件路径。解决项目打成jar包上线无法读取配置文件。打包jar后无法读取resource下的配置文件 场景 需要读取 src/main/resources/mapper下的所…

【Python循环4/5】跳出循环的办法

目录 导入 break 具体用法 在for循环中的运用 在while循环中的运用 continue 具体用法 区别 总结 导入 前几天的博文里&#xff0c;我们学习了for循环和while循环。 无论是for循环还是while循环&#xff0c;默认的终止条件都是边界条件。在触发边界条件之前&am…

ChatGPT4的Dalle-3 生成电影海报及升级教程

引言 首先DALL E3首先需要升级为ChatGPT4才能使用&#xff0c;接下来从以下几个方面进行介绍&#xff1a; 一、ChatGPT4中的DALL E3 的电影海报二、ChatGPT4下的DALL E3的实例三、ChatGPT4的升级教程 一、ChatGPT4中的DALL E3 的电影海报 DALLE 3可以直接在画面中识别和生成…

gPTP简介

1、gPTP&#xff08;generalized precision time protocol&#xff09;广义时钟同步协议 gPTP&#xff08;generalized precision time protocol&#xff09;广义时钟同步协议&#xff0c;即IEEE 802.1AS协议。它是IEEE 1588协议的延伸&#xff0c;可以为TSN提供全局精准…

重磅!知名三甲医院更新2024预警期刊名单!1区SCI为何上榜?

毕业推荐 SSCI&#xff08;ABS一星&#xff09; • 社科类&#xff0c;3.0-4.0&#xff0c;JCR2区&#xff0c;中科院3区 • 13天录用&#xff0c;28天见刊&#xff0c;13天检索 SCIE&#xff1a; • 计算机类&#xff0c;6.5-7.0&#xff0c;JCR1区&#xff0c;中科院2区…

C到C++的敲门砖-2

文章目录 引用内联函数auto关键字基于范围的for循环指针空值nullptr后记 引用 引用不是新定义一个变量&#xff0c;而是给已存在变量取了一个别名&#xff0c;编译器不会为引用变量开辟内存空 间&#xff0c;它和它引用的变量共用同一块内存空间。 所谓引用就是给变量起别名&am…

基于消失点的相机自标定

基于消失点的相机自标定 附赠最强自动驾驶学习资料&#xff1a;直达链接 相机是通过透视投影变换来将3D场景转换为2D图像。在射影变换中&#xff0c;平行线相交于一点称之为消失点。本文详细介绍了两种利用消失点特性的标定方法。目的是为根据实际应用和初始条件选择合适的标…

phpStudy安装thinkCMF8时,如何解决服务器rewrite和APIrewrite不支持的问题

解决步骤&#xff1a; 一&#xff1a;服务器rewrite 点击后面的问号跳转到官方文档链接&#xff1a; 复制红框内的代码 打开phpstudy&#xff0c;找到配置的站点&#xff0c;点击管理&#xff0c;找到伪静态 点击确认保存即可。 phpstudy会自动重启站点。 此时&#xff0c;…

CTF 题型 SSRF攻击例题总结

CTF 题型 SSRF攻击&例题总结 文章目录 CTF 题型 SSRF攻击&例题总结Server-side Request Forgery 服务端请求伪造SSRF的利用面1 任意文件读取 前提是知道要读取的文件名2 探测内网资源3 使用gopher协议扩展攻击面Gopher协议 &#xff08;注意是70端口&#xff09;python…

RPC学习笔记一

什么是RPC RPC&#xff08;Remote Procedure Call&#xff0c;远程过程调用&#xff09;是一种用于实现分布式系统中不同计算机或进程之间进行通信和调用的技术和模式。 在传统的过程调用中&#xff0c;当一个程序需要调用另一个程序的函数或方法时&#xff0c;通常是在同一台…

【10】进阶常用第三方库

第三方库概览 名称文档一句话介绍jQuery官网:https://jquery.com/中文网:https://jquery.cuishifeng.cn/让操作 DOM 变得更容易Lodash官网:https://lodash.com/docs中文网:https://www.lodashjs.com/你能想到的工具函数它都帮你写了Animate.css官网:https://animate.style…

图算法总结

BFS: 基于队列, 入队列的顶点先被探索. DFS: 基于栈, 通过将顶点存入栈中, 顶点是沿着路径被探索的, 存在新的相邻顶点就去访问.深度优先遍历类似于树的先根遍历(先序遍历)

大模型提示学习样本量有玄机,自适应调节方法好

引言&#xff1a;探索文本分类中的个性化示例数量 在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;预测模型已经从零开始训练演变为使用标记数据对预训练模型进行微调。这种微调的极端形式涉及到上下文学习&#xff08;In-Context Learning, ICL&#xff09;&…