[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.rhkb.cn/news/278891.html

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

相关文章

数据结构——lesson10排序之插入排序

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#x…

第十五届蓝桥杯模拟考试III_物联网设计与开发官方代码分析

目录 前言&#xff1a;显示界面部分&#xff1a;页面切换:数值的轮回调整&#xff1a;传递数据&#xff1a; 前言&#xff1a; 这次模拟的效果很不好。85分&#xff0c;4h的限时我花了两天完成&#xff0c;这个时间是远远超出要求的&#xff0c;而且最后还只拿到56分&#xff0…

使用 Boot Camp 助理查明您的 Mac 需不需要 Windows 安装介质

使用 Boot Camp 助理查明您的 Mac 需不需要 Windows 安装介质 当前的 Mac 机型无需介质即可安装 Windows&#xff0c;也就是说&#xff0c;您不需要用到外置驱动器。较早的 Mac 机型需要用到 USB 驱动器或光盘驱动器。使用 Boot Camp 助理可查明您需要用到什么。 Boot Camp 助…

了解常用开发模型 -- 瀑布模型、螺旋模型、增量与迭代、敏捷开发

目录 瀑布模型 开发流程 开发特征 优缺点 适用场景 螺旋模型 开发流程 开发特征 优缺点 适用场景 增量与迭代开发 什么是增量开发&#xff1f;什么是迭代开发&#xff1f; 敏捷开发 什么是敏捷开发四原则&#xff08;敏捷宣言&#xff09;&#xff1f; 什么是 s…

nodejs 使用express插件multer文件上传,接收不到文件的bug

把路径改成绝对路径即可 改成 temp是你想上传到文件夹的路径&#xff0c;一般是在项目根目录下

Java-JVM 虚拟机原理调优实战

一、基础 栈帧&#xff08;Stack Frame&#xff09;栈空间的 基本元素&#xff0c;用于 方法的调用和方法的执行的数据结构 堆内存用来存放由new创建的对象和数组。在堆中分配的内存&#xff0c;由Java虚拟机的自动垃圾回收器来管理。在堆中产生了一个数组或对象后&#xff0c…

多线程:线程安全、线程同步、线程通信

线程安全 什么是线程安全问题? 多个线程&#xff0c;同时操作同一个共享资源的时候&#xff0c;可能会出现业务安全问题。 1.线程安全问题出现的原因? 存在多个线程在同时执行同时访问一个共享资源存在修改该共享资源 用程序模拟线程安全问题 取钱案例 需求: 小明和小红…

2025张宇考研数学基础36讲,视频百度网盘+PDF

一、张宇老师全年高数体系&#xff08;听课用书指南&#xff09; 25张宇全程&#xff1a; docs.qq.com/doc/DTmtOa0Fzc0V3WElI 复制粘贴在浏览器上打开&#xff0c;就可以看到2025张宇的全部的啦&#xff01; 一般来说我们把考研数学划分为3-4个阶段&#xff0c;分别是基础阶…

2. IS-IS 基础实验

2.1 IS-IS 配置实验 2.1.1 实验介绍 2.1.1.1 学习目标 1. 实现 IS-IS 协议基本配置 2. 实现 IS-IS 协议 DIS 优先级修改 3. 实现 IS-IS 协议网络类型修改 4. 实现 IS-IS 协议外部路由引入 5. 实现 IS-IS 接口 cost 修改 6. 实现 IS-IS 路由渗透配置 2.1.1.2 实验组网介…

Git——标签详解

目录 Git标签1、概述1.1、标签是什么1.2、什么时候使用标签1.3、标签的分类 2、轻量标签&#xff08;lightweight tag&#xff09;3、有附注的标签&#xff08;annotated tag&#xff09;4、两种标签的区别5、删除标签 Git标签 1、概述 1.1、标签是什么 在Git中&#xff0c;…

Java基于springboot的篮球NBA球队管理系统ssm

本次将以NBA球队管理方面为切入点&#xff0c;论述了NBA球队管理的意义和内容&#xff0c;以此展开对NBA球队管理系统的开发与建设的详细分析。从数据挖掘的角度出发&#xff0c;了解信息管理系统的作用&#xff0c;对NBA球队管理系统的过程以及用处进行更深一步的研究&#xf…

Java 世界破破烂烂,电音小猫缝缝补补

Java 世界破破烂烂&#xff0c;电音小猫缝缝补补 Java 通用代码生成器光 2.4.0 电音之王尝鲜版六正在研发&#xff0c;昨天发布了介绍视频&#xff0c;请见&#xff1a; https://www.bilibili.com/video/BV1yD421j7UP/ 电音之王尝鲜版六支持哑数据模式&#xff0c;支持枚举。…

win10笔记本在显示设置中不慎将主显示器禁用掉导致开机黑屏的解决方案

因为笔记本电脑的显示扩展接口有问题&#xff0c;所以在电脑开机之后&#xff0c;会误识别出几个不存在的扩展屏幕&#xff0c;所以我就想从显示设置中将这几个误识别出来的扩展屏幕禁用掉&#xff08;不然鼠标总是移动到主屏幕边界之外的地方&#xff09;&#xff0c;在显示设…

RabbitMQ介绍及搭建

架构 RabbitMQ是实现了高级消息队列协议&#xff08;AMQP&#xff09;的开源消息代理软件&#xff0c;使用erlang语言编写&#xff0c;依赖Erlang环境运行。 Broker&#xff1a;运行消息队列服务进程的节点&#xff0c;包含Exchange、Queue&#xff1b; Producer&#xff1a;消…

蓝桥杯刷题总结(Python组)

1、蛇形矩阵 解题思路&#xff1a;每次赋值后都对方向进行改变&#xff0c;一般上下左右就是&#xff08;-1&#xff0c;0&#xff09;&#xff0c;&#xff08;0&#xff0c;1&#xff09;&#xff0c;&#xff08;1&#xff0c;0&#xff09;&#xff0c;&#xff08;0&…

TSINGSEE青犀AI智能分析网关V4酿酒厂安全挂网AI检测算法

在酿酒行业中&#xff0c;安全生产一直是企业经营中至关重要的一环。为了确保酒厂生产过程中的安全&#xff0c;TSINGSEE青犀AI智能分析网关V4的安全挂网AI检测算法发挥了重要作用。 TSINGSEE青犀AI智能分析网关V4的安全挂网检测算法是针对酒厂里酒窖挂网行为进行智能检测与识…

爬虫 Day2

resp.close()#关掉resp 一requests入门 &#xff08;一&#xff09; 用到的网页&#xff1a;豆瓣电影分类排行榜 - 喜剧片 import requestsurl "https://movie.douban.com/j/chart/top_list" #参数太长&#xff0c;重新封装参数 param {"type": "…

【Qt问题】使用QSlider创建滑块小部件无法显示

问题描述&#xff1a; 使用QSlider创建滑块小部件用于音量按钮的时候&#xff0c;无法显示&#xff0c;很奇怪&#xff0c;怎么都不显示 一直是这个效果&#xff0c;运行都没问题&#xff0c;但是就是不出现。 一直解决不了&#xff0c;最后我在无意中&#xff0c;在主程序中…

LLM 面试知识点——模型基础知识

1、主流架构 目前LLM(Large Language Model)主流结构包括三种范式,分别为Encoder-Decoder、Causal Decoder、Prefix Decode。对应的网络整体结构和Attention掩码如下图。 、 各自特点、优缺点如下: 1)Encoder-Decoder 结构特点:输入双向注意力,输出单向注意力。 代表…

MySQL中数据库表的监控

MySQL中数据库表的监控 &#xff08;1&#xff09;查看数据库中当前打开了哪些表&#xff1a;show OPEN TABLES &#xff0c;如图6-1-5所示。另外&#xff0c;还可以通过show OPEN TABLES where In_use > 0过滤出当前已经被锁定的表。 查看数据库中表的状态&#xff1a;SHO…