二维数组和数组指针数组的关系

在深入理解指针end中,我在最后写了一长段代码

#include<stdio.h>
void test1(int arr[][5], int x, int y)
//void test1(int(*p)[5], int x, int y)
{for (int i = 0; i < x; i++){for (int j = 0; j < y; j++){//printf("%d ", *(*(p + i) + j));printf("%d ", arr[i][j]);}printf("\n");}printf("\n");
}
void test2(int* p[5], int x, int y)
{for (int i = 0; i < x; i++){for (int j = 0; j < y; j++){printf("%d ", p[i][j]);//printf("%d ", *(*(p + i) + j));}printf("\n");}
}
int main()
{int arr1[5] = { 1,2,3,0,0 };int arr2[5] = { 4,5,6,0,0 };int arr3[5] = { 7,8,9,0,0 };int arr4[3][5] = { {1,2,3,0,0},{4,5,6,0,0},{7,8,9,0,0} };int* (p[3])[5] = { arr1,arr2,arr3 };test1(arr4, 3, 5);test2(p, 3, 5);return 0;
} 

现在我们来拆解一下这段代码。

1:理解二维数组的本质

二维数组就是多个一维数组的集合,元素就是一维数组。

二维数组数组名是第一行一维数组的地址,是第一行数组的地址,也是是第一行一维数组里面第一个元素的地址!!!!

如图

2:理解数组指针数组的本质

数组指针数组是一个数组,数组里面的元素是数组指针。

数组指针,就是存放数组的指针。

我们来层层破茧,来慢点理解其本质

先理解一维数组和指针的关系,也就是数组指针和数组的关系

如图

数组指针的打印的地址和一维数组的地址一样。

我们数组指针数组,就是把上面的三个数组指针放到数组里面。

如图可看,p1,2,3在数组指针数组打印的地址不是一维数组的地址了。

p1,2,3也是变量,是变量就要开辟新的内存。所以我们打印的是p,1,2,3所占的地址

如图可看

数组arr4也是新开辟的也由属于他自己的内存,但是我图上没画。

记住,是变量就要开辟空间,指针变量也是变量

但是我们可以借助*接引用来直接实现arr4中打印一维数组的地址

电脑中每一次打印地址是会变的

于此我就讲解完了,数组指针数组,数组指针的本质。

3:二维数组和数组指针数组的关系

二维数组,可以看出多个一维数组的集合

数组指针数组,可以看成多个数组指针的集合

而一维数组首元素的地址一般都代表整个指针的地址。我们在进行数组指针变量初始化是,也可以看成是把首元素的地址放在了数组指针变量中。

4:分析代码

由此我们开始理解最开始的代码

int main()
{int arr1[5] = { 1,2,3,0,0 };int arr2[5] = { 4,5,6,0,0 };int arr3[5] = { 7,8,9,0,0 };int arr4[3][5] = { {1,2,3,0,0},{4,5,6,0,0},{7,8,9,0,0} };int* (p[3])[5] = { arr1,arr2,arr3 };test1(arr4, 3, 5);test2(p, 3, 5);return 0;
} 

我定义了,一个二维数组arr4和一个数组指针数组p[3]

这个数组指针数组的类型是int*()[5]。

我们向函数传递的是数组,传递的是数组,传递的是数组!!!!

现在我们来分析test1和test2函数

1:test1

void test1(int arr[][5], int x, int y)
//void test1(int(*p)[5], int x, int y)
{for (int i = 0; i < x; i++){for (int j = 0; j < y; j++){//printf("%d ", *(*(p + i) + j));printf("%d ", arr[i][j]);}printf("\n");}printf("\n");
}

我们传递的是arr4数组,数组是,一个五列元素的一维数组集合起来的。是非常正常的打印二维数组的方式。

我们看//部分的代码

void test1(int(*p)[5], int x, int y)
{for (int i = 0; i < x; i++){for (int j = 0; j < y; j++){printf("%d ", *(*(p + i) + j));}printf("\n");}printf("\n");
}

这个是直接使用指针来接收二维数组,p是一个指针,指针类型是int () [5];

通过解引用p我们可以逐次访问二维数组

*(p+i)表示访问第一行的元素,也是访问第一行的首元素地址

*(*(p+i)+j)表示访问第i行的第j个元素,因为+j就是将指向首元素的地址往后移动j个单位

2:test2

void test2(int* p[5], int x, int y)
{for (int i = 0; i < x; i++){for (int j = 0; j < y; j++){printf("%d ", p[i][j]);//printf("%d ", *(*(p + i) + j));}printf("\n");}
}

这个就是直接接收的数组指针数组,p表示的是数组,数组元素的类型是int* [5]的

打印我们可以直接使用二维数组的打印方式,都是数组了,推理一下也就可以直接使用数组常规的打印方式。

看//部分

//部分是用指针来打印的,逻辑和test1差不多。

*(p+i),是把p这个数组名当成了数组首元素的地址。

单独的一个数组名是可以当首元素的地址,这个结论是前面说过的。

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

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

相关文章

vue+websocket实现即时聊天平台

目录 1 什么是websocket 2 实现步骤 2.1 导入依赖 2.2 编写代码 1 什么是websocket WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。它主要用于在客户端和服务器之间建立持久的连接&#xff0c;允许实时数据交换。WebSocket 的设计目的是为了提高 Web 应用程序的…

【D3.js in Action 3 精译_038】4.2 D3 折线图的绘制方法及曲线插值处理

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第一部分 D3.js 基础知识 第一章 D3.js 简介&#xff08;已完结&#xff09; 1.1 何为 D3.js&#xff1f;1.2 D3 生态系统——入门须知1.3 数据可视化最佳实践&#xff08;上&#xff09;1.3 数据可…

Git 的分支管理

一、分支介绍 1、分支是什么 Git作为一个分布式版本控制系统&#xff0c;提供了强大而灵活的分支管理功能&#xff0c;使得开发团队能够高效地协作开发、管理不同的功能和版本。 2、为什么有分支 一般情况下主分支&#xff08;master/main&#xff09;应始终保持可部署的状…

Linux环境基础和基础开发工具使用

文章目录 一、yum软件管理器1、包管理器2、yum3、apt4、安装源 二、编辑器vim1、各种模式2、打开时直接让光标定位到指定号3、&#xff01;加命令字符 三、命令模式1、i 进入插入模式2、**Shift :** 进入底行模式3、光标定位4、ZZ&#xff08;大写&#xff09;保存并退出vim5、…

【java】哈希<两数之和> 理解哈希

两数之和 题目描述&#xff1a; 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案&#xff0c;并且你不能使用两次相同的元素。 你…

【Linux】信号三部曲——产生、保存、处理

信号 1. 信号的概念2. 进程如何看待信号3. 信号的产生3.1. kill命令3.2. 终端按键3.2.1. 核心转储core dump3.2.2. OS如何知道键盘在输入数据 3.3. 系统调用3.3.1. kill3.3.2. raise3.3.3. abort 3.4. 软件条件3.4.1. SIGPIPE信号3.4.2. SIGALRM信号 3.5. 硬件异常3.5.1. 除零异…

Vue 计算属性和监听器

文章目录 一、计算属性1. 计算属性定义2. computed 比较 methods3. 计算属性完整写法 二、监听器1. 普通监听2. 添加额外配置项 一、计算属性 1. 计算属性定义 概念&#xff1a;基于现有的数据&#xff0c;计算出来的新属性&#xff0c;依赖的数据变化&#xff0c;自动重新计…

【计网】实现reactor反应堆模型 --- 框架搭建

没有一颗星&#xff0c; 会因为追求梦想而受伤&#xff0c; 当你真心渴望某样东西时&#xff0c; 整个宇宙都会来帮忙。 --- 保罗・戈埃罗 《牧羊少年奇幻之旅》--- 实现Reactor反应堆模型 1 前言2 框架搭建3 准备工作4 Reactor类的设计5 Connection连接接口6 回调方法 1 …

外包干了2年,快要废了。。。

先说一下自己的情况&#xff0c;普通本科毕业&#xff0c;在外包干了2年多的功能测试&#xff0c;这几年因为大环境不好&#xff0c;我整个人心惊胆战的&#xff0c;怕自己卷铺盖走人了&#xff0c;我感觉自己不能够在这样蹉跎下去了&#xff0c;长时间呆在一个舒适的环境真的会…

linux驱动-i2c子系统框架学习(2)

linux驱动-i2c子系统框架学习(1) 在这篇博客里面已经交代了i2c设备驱动层&#xff0c;主要的功能就是编写具体i2c的外设驱动&#xff0c;和创建设备接点给上层使用 &#xff0c;按之前学习的字符设备&#xff0c;有了设备节点&#xff0c;就可以对硬件操作了&#xff0c;在i2c…

Webserver(4.6)poll和epoll

目录 pollclient.cpoll.c epollepoll.cclient.c epoll的两种工作模式水平触发边沿触发 poll poll是对select的一个改进 select的缺点在于每次都需要将fd集合从用户态拷贝到内核态&#xff0c;开销很大。每次调用select都需要在内核遍历传递进来的所有fd&#xff0c;这个开销也…

Stable Diffusion的解读(一)

Stable Diffusion的解读&#xff08;一&#xff09; 文章目录 Stable Diffusion的解读&#xff08;一&#xff09;摘要Abstract一、机器学习部分1. Stable Diffusion的早期工作1.1 从编码器谈起1.2 第一条路线&#xff1a;VAE和DDPM1.3 第二条路线&#xff1a;VQVAE1.4 路线的交…

计算机网络——TCP篇

TCP篇 基本认知 TCP和UDP的区别? TCP 和 UDP 可以使用同一个端口吗&#xff1f; 可以的 传输层中 TCP 和 UDP在内核中是两个完全独立的软件模块。可以根据协议字段来选择不同的模块来处理。 TCP 连接建立 TCP 三次握手过程是怎样的&#xff1f; 一次握手:客户端发送带有 …

ROS话题通信机制理论模型的学习

话题通信是ROS&#xff08;Robot Operating System&#xff0c;机器人操作系统&#xff09;中使用频率最高的一种通信模式&#xff0c;其实现模型主要基于发布/订阅模式。 一、基本概念 话题通信模型中涉及三个主要角色&#xff1a; ROS Master&#xff08;管理者&#xff0…

【Android】名不符实的Window类

1.“名不符实”的Window类 Window 是一个窗口的概念&#xff0c;是所有视图的载体&#xff0c;不管是 Activity&#xff0c;Dialog&#xff0c;还是 Toast&#xff0c;他们的视图都是附加在 Window 上面的。例如在桌面显示一个悬浮窗&#xff0c;就需要用到 Window 来实现。Wi…

后端java——如何为你的网页设置一个验证码

目录 1、工具的准备 2.基本方法 3.实现类 4.实践 HTML文件&#xff1a; Java文件1:创建验证码 Java文件2:验证验证码 本文通过HUTOOL实现&#xff1a;Hutool参考文档Hutool&#xff0c;Java工具集https://hutool.cn/docs/#/ 1、工具的准备 如果我们通过hutool来实现这个…

【go从零单排】Strings and Runes 字符串和字符

Don’t worry , just coding! 内耗与overthinking只会削弱你的精力&#xff0c;虚度你的光阴&#xff0c;每天迈出一小步&#xff0c;回头时发现已经走了很远。 概念 在Go语言中&#xff0c;rune 是一个内置的数据类型&#xff0c;用于表示一个Unicode字符。它实际上是一个别名…

如何在本地Linux服务器搭建WordPress网站结合内网穿透随时随地可访问

文章目录 前言1. 安装WordPress2. 创建WordPress数据库3. 安装相对URL插件4. 安装内网穿透发布网站4.1 命令行方式&#xff1a;4.2. 配置wordpress公网地址 5. 配置WordPress固定公网地址 前言 本文主要介绍如何在Linux Ubuntu系统上使用WordPress搭建一个本地网站&#xff0c…

vue data变量之间相互赋值或进行数据联动

摘要&#xff1a; 使用vue时开发会用到data中是数据是相互驱动&#xff0c;经常会想到watch,computed&#xff0c;总结一下&#xff01; 直接赋值&#xff1a; 在 data 函数中定义的变量可以直接在方法中进行赋值。 export default {data() {return {a: 1,b: 2};},methods: {u…

在 Java 中使用脚本语言

在 Java 中使用脚本语言&#xff0c;特别是在 Java 平台上集成如 Python、JavaScript 或 Ruby 等语言&#xff0c;通常可以通过 Java 的 Scripting API 来实现。这个 API 基于 JSR 223&#xff08;“Scripting for the Java Platform”&#xff09;&#xff0c;提供了一种标准方…