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

一、数组指针

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

#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.mzph.cn/news/755027.shtml

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

相关文章

【基础】哪个厂家的零件更标准?

时间限制 : 1 秒 内存限制 : 128 MB 在统计描述中,方差用来计算每一个变量(观察值)与总体均数之间的差异。比如:甲乙 2 个厂商生产某零件,一批零件要求在尺寸合格的情况下,大小越一致越好,由于生产工艺的问题,零件生产厂商生产的零件不可能一模一样。 为了检测甲乙两…

前端结合 react axios 获取真实下载、上传进度

首页确保项目中使用了axios axios ondownloadprogress中total总为零&#xff0c;content-length不返回? 点我查看 Axios Documention npm i axiosyarn add axios以下我们举例接口调用配置说明&#xff1a; 由于接口下载时&#xff0c;不确定文件下载时长&#xff0c;所以直…

AIX系统下挂载ISO镜像

我们需要将AIX的iso文件作为软件包的安装源挂载的系统目录中 首先我们查看系统下有哪些挂载文件 如何挂载一个系统iso镜像文件 loopmount -i /ftp/iso/LK4T_1807_11.iso -o "-V cdrfs -o ro " -m /mnt/iso 需要安装软件直接执行smit就可以了&#xff0c;在smit中…

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

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

内网信息收集

本机信息收集 一、手工 1.查询网络配置信息: ipconfig /all 2. 查询操作系统和版本信息: systeninfo 查看系统体系架构&#xff1a;echo %PROCESSOR_ARCHITECTURE% 查看安装的软件及版本信息&#xff1a; wmic product get name,version 3.查询本机服务信息&#…

docker init 生成Dockerfile和docker-compose.yml —— 筑梦之路

官网&#xff1a;https://docs.docker.com/engine/reference/commandline/init/ 简介 docker init是一个命令行实用程序&#xff0c;可帮助初始化项目中的 Docker 资源。.dockerignore它根据项目的要求创建 Dockerfile、Compose 文件。这简化了为项目配置 Docker 的过程&#…

【NLP9-Transformer经典案例】

Transformer经典案例 1、语言模型 以一个符合语言规律的序列为输入&#xff0c;模型将利用序列间关系等特征&#xff0c;输出在一个在所有词汇上的概率分布&#xff0c;这样的模型称为语言模型。 2、语言模型能解决的问题 根据语言模型定义&#xff0c;可以在它的基础上完成…

PHP反序列化---字符串逃逸(增加/减少)

一、PHP反序列化逃逸--增加&#xff1a; 首先分析源码&#xff1a; <?php highlight_file(__FILE__); error_reporting(0); class A{public $v1 ls;public $v2 123;public function __construct($arga,$argc){$this->v1 $arga;$this->v2 $argc;} } $a $_GET[v…

探索区块链世界:从加密货币到去中心化应用

相信提到区块链&#xff0c;很多人会想到比特币这样的加密货币&#xff0c;但实际上&#xff0c;区块链技术远不止于此&#xff0c;它正在深刻地改变我们的生活和商业。 首先&#xff0c;让我们来简单了解一下什么是区块链。区块链是一种分布式数据库技术&#xff0c;它通过将…

三维GIS仿真技术发展的几点思考

随着近几年三维GIS的快速发展&#xff0c;三维GIS可视化在数字孪生、元宇宙等热点方向起着重要技术支撑&#xff0c;结合这几年三维GIS技术进展,其出现的进展与问题&#xff0c;有以下几点思考&#xff0c;供读者参考&#xff1a; 1.关于国内GIS三维仿真技术处于什么水平&#…

蓝桥杯-python-递归

递归&#xff1a;通过自我调用解决问题的函数 注意&#xff1a; #1.递归出口 #2.当前问题如何变成子问题 例子&#xff1a;利用递归写一个阶乘函数&#xff0c;F(n),求n的阶乘 def f(n):if n < 1:return 1ans n * f(n-1)return ans print(f(5)) 例子&#xff1a;汉诺塔…

vsto excel 插件注册表属性值含义

在 VSTO (Visual Studio Tools for Office) 中&#xff0c;LoadBehavior 是用于指定 Office 插件加载行为的一个属性。具体含义如下&#xff1a; - LoadBehavior 0&#xff1a;此值表示插件已被禁用&#xff0c;将不会加载。 - LoadBehavior 1&#xff1a;此值表示插件将在 O…

【CSP试题回顾】202303-1-田地丈量

CSP-202303-1-田地丈量 解题思路 问题描述&#xff1a;给定一个长为 a、宽为 b 的矩形区域&#xff08;坐标范围从 (0,0) 到 (a,b)&#xff09;&#xff0c;以及 n 个其他矩形&#xff0c;每个矩形由其对角线的两个顶点 (x1, y1) 和 (x2, y2) 定义。需要计算这些矩形与给定矩形…

深度刨析Android ANR触发原理

一、概述 ANR(Application Not responding)&#xff0c;是指应用程序未响应&#xff0c;Android系统对于一些事件需要在一定的时间范围内完成&#xff0c;如果超过预定时间能未能得到有效响应或者响应时间过长&#xff0c;都会造成ANR。一般地&#xff0c;这时往往会弹出一个提…

015 Linux_生产消费模型

​&#x1f308;个人主页&#xff1a;Fan_558 &#x1f525; 系列专栏&#xff1a;Linux &#x1f339;关注我&#x1f4aa;&#x1f3fb;带你学更多操作系统知识 文章目录 前言一、生产消费模型&#xff08;1&#xff09;概念引入&#xff08;2&#xff09;生产消费模型的优点…

键牌 6寸水口钳工业级电子斜嘴水口剪偏口钳子电工专用小斜口钳

品牌&#xff1a;键牌 型号&#xff1a;6寸水口钳灰红 材质&#xff1a;不锈钢 颜色分类&#xff1a;6寸水口钳灰红 多用途电工钳&#xff0c;高硬度&#xff0c;韧性好&#xff0c;材质优。 匠心之作&#xff0c;精工典范&#xff0c;不锈钢材质&#xff0c;加厚刀刃&am…

JAVA学习-NIO.Buffer(缓冲器)

Java NIO中的缓冲器&#xff08;Buffer&#xff09;是用来存储数据的对象。它是一个固定大小的数组&#xff0c;可以容纳特定类型的数据。 一、Java NIO中提供了7种类型的缓冲器&#xff0c;分别是&#xff1a; 1. ByteBuffer&#xff1a; 字节缓冲器&#xff0c;用来存储字…

解决 ArrayList 的并发问题

目录 1. 场景复现1.1 数据不一致问题示例代码1.2 ConcurrentModificationException 问题示例代码 2. 解决并发的三种方法2.1 使用 Collections.synchronizedList2.2 使用 CopyOnWriteArrayList&#xff08;推荐使用&#xff09;2.3 使用显式的同步控制 3. 总结 ArrayList是java…

【JavaWeb】Spring非阻塞通信 - Spring Reactive之WebFlux的使用

【JavaWeb】Spring非阻塞通信 - Spring Reactive之WebFlux的使用 文章目录 【JavaWeb】Spring非阻塞通信 - Spring Reactive之WebFlux的使用参考资料一、初识WebFlux1、什么是函数式编程1&#xff09;面向对象编程思维 VS 函数式编程思维&#xff08;封装、继承和多态描述事物间…

Magical Combat VFX 2

我们为Unity推出的最新资产包:魔法战斗VFX包!这个包非常适合为你的游戏添加激烈而致命的魔法。有30多种独特的效果,包括血液、酸和毒咒,你可以在战斗场景中大显身手。而且移动支持和优化是首要任务,你可以在旅途中使用这些效果,而不用担心性能问题。使用功能齐全、移动就…