二维数组使用和内存布局(一)|学习笔记

简介: 快速学习二维数组使用和内存布局

开发者学堂课程【Go语言核心编程 - 基础语法、数组、切片、Map:二维数组使用和内存布局】与课程紧密联系,让用户快速学习知识

课程地址:https://developer.aliyun.com/learning/course/625/detail/9653


二维数组使用和内存布局(一)

内容介绍:

一、二维数组的使用方式1

二、二维数组的内存布局

三、二维数组的使用方式2

下面介绍二维数组使用方式以及二维数组在内存的存在形式,讲解风格是先分析入门案例,再在案例中讲细节,以及数据结构包括二维数组在内存的存在形式,因为只有理解了数据类型在内存里面的布局,才能深刻的理解这个数组到底是怎么存在的,应用起来就会得心应手。


一、二维数组的使用方式1

方式1:先声明/定义再赋值

1、快速入门案例/使用演示

案例,如:

//定义/声明二维数组

var arr [4][6]int

//赋初值

arr[1][2] = 1

arr[2][1] = 2

arr[2][3] = 3

//遍历二维数组,按照要求输出图形

for i :=0; i<4; i++{

for j:=0; j<6; j++{

fmt.Println(arr[i][j],”")

}

fmt.Println()

}

2、语法: var 数组名[大[大小]类型

前面的大小是二维数组共有多少个元素,第二个大小指的是二维数组里的各个一维数组有几个元素。

3、比如: var arr [2][3]int[][],再赋值。中括号可以不要。

4、二维数组在内存的存在形式(重点)


二、二维数组的内存布局

下面以 var arr2 [2][3]int 为案例来分析二维数组在内存中的布局

分析

//定义/声明二维数组

var arr [4][6]int

//赋初值

arr[1][2] = 1

arr[2][1] = 2

arr[2][3] = 3

//遍历二维数组,按照要求输出图形

for i :=0; i<4; i++{

for j:=0; j<6; j++{

fmt.Println(arr[i][j],”")

}

fmt.Println()

}

fmt. Println() 

//换行

var arr2 [2][3]int

//以这个为例来分析 arr2在内存的布局! !

arr2[1][1] =10

fmt . Println( arr2) //输出arr2

}

此时运行下,运行结果为:

D:\goproject\src\go_code\chapter08\nultiarray>go run main .go

0 0 0 0 0 0

0 0 1 0 0 0

0 2 0 3 0 0

0 0 0 0 0 0

[[0 0 0] [0 10 0]]

在 excel 表中分析:

如图左边为代码,右边为在内存中的布局。首先左边第一行代码执行后,会在内存中生成一个名称为 arr2的变量,有一个空间与之对应,但在这个空间里面并没有直接存放 arr2的数据,而是有两个指针,这两个指针都分别指向一个位置,因为可以看到 arr2中是有两个元素,每个元素都指向一个一维数组,所以说这两个指针分别指向了一个一维数组,分析图如下:

image.png

下面可以把地址打出来观察下:

首先输出 arr2第一个元素地址,再输出第二个地址,为方便观察要加上\n换行,如下:

fmt.Printf("arr2[0]的地址%p\n", &arr2[0])

fmt.Printf("arr2[1]的地址%p\n",&arr2[1])

运行结果:

arr2[0]的地址0xc04200a270

arr2[1]的地址0xc04200a288

可以看到出现了两个地址,而两个地址之间相差24个字节,因为每个元素里面有3个 int,而每个i个 int占8个字节,所以两个地址之间相差24个字节,下面打印两个一维数组首地址进行验证:

fmt. Printf(”arr2[0][0]的地址%p\n" , &arr2[0][0])

fmt. Printf(”arr2[1][0]的地址%p\n", &arr2[1][0])

运行结果为:

arr2[0]的地址0xc04200a270

arr2[1]的地址0xc04200a288

arr2[0][0]的地址0xc04200a270

arr2[1][0]的地址0xc04200a288

可以观察到两个一维数组首地址与前面两个指针地址相同,说明刚刚的图示分析没错。

此时把数组改为arr2 [2][2],则说明arr2一个一维数组里面有两个int,就应该相差16个字节,也就是说两个指针地址应该相差16,此时运行结果为:

arr2[0]的地址0xc04204a0a0

arr2[1]的地址0xc04204a0b0

arr2[0][0]的地址0xc04204a0a0

arr2[1][0]的地址0xc04204a0b0

可以发现a0加上16结果是b0。为了更方便观察,改变代码为arr2 [2][1],两个指针就应该相差8个字节:

var arr2 [2][1]int

arr2[1][0] =10

运行结果为:

arr2[0]的地址0xc042010150

arr2[1]的地址0xc042010158

arr2[0][0]的地址0xc042010150

arr2[1][0]的地址0xc042010158

可以发现50到58确实相差8个字节,那如果改变为arr2 [1][1],则是首先找到arr2里面第二个元素的指针,也就是说找到第二个一维数组空间中下标为1的元素,下标为1就是说第二个元素,这样改动后会发现输出的一维数组值,前面的数组值为0,0,0,后面的数组值为0,10,0,分析图:

image.png

代码为:

var arr2 [2][3]int

arr2[1][1]= 10

运行结果:

[[0 0 0][0 10 0]]arr2[0]的地址0xc04200a270

arr2[1]的地址0xc04200a288

arr2[0][0]的地址0xc04200a270

arr2[1][0]的地址0xc04200a288

可以看到与分析的相同,第二个一维数组中数值被改为10。

相关文章
|
27天前
|
存储 Java
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
这篇文章详细地介绍了Java对象的创建过程、内存布局、对象头的MarkWord、对象的定位方式以及对象的分配策略,并深入探讨了happens-before原则以确保多线程环境下的正确同步。
50 0
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
|
1月前
|
存储 Java
深入理解java对象的内存布局
这篇文章深入探讨了Java对象在HotSpot虚拟机中的内存布局,包括对象头、实例数据和对齐填充三个部分,以及对象头中包含的运行时数据和类型指针等详细信息。
28 0
深入理解java对象的内存布局
|
3月前
|
存储 算法 Oracle
不好意思!耽误你的十分钟,JVM内存布局还给你
先赞后看,南哥助你Java进阶一大半在2006年加州旧金山的JavaOne大会上,一个由顶级Java开发者组成的周年性研讨会,公司突然宣布将开放Java的源代码。于是,下一年顶级项目OpenJDK诞生。Java生态发展被打开了新的大门,Java 7的G1垃圾回收器、Java 8的Lambda表达式和流API…大家好,我是南哥。一个Java学习与进阶的领路人,相信对你通关面试、拿下Offer进入心心念念的公司有所帮助。
不好意思!耽误你的十分钟,JVM内存布局还给你
|
2月前
crash —— 获取物理内存布局信息
crash —— 获取物理内存布局信息
|
3月前
|
缓存 Java 编译器
Go 中的内存布局和分配原理
Go 中的内存布局和分配原理
|
3月前
|
存储 编译器 C++
Method&ConstMethod的内存布局
综上所述,常规方法和常量方法在对象的内存布局中并不直接占据空间;它们作为代码的一部分存储在程序的代码段中。对于虚方法(包括常量虚方法),它们通过VTable在对象中有表示,但即便在这种情况下,方法代码本身也不在对象的内存布局中。理解这些概念有助于深入理解面向对象编程,提高编程效率和代码的可理解性。
37 3
|
4月前
|
存储 缓存 算法
(五)JVM成神路之对象内存布局、分配过程、从生至死历程、强弱软虚引用全面剖析
在上篇文章中曾详细谈到了JVM的内存区域,其中也曾提及了:Java程序运行过程中,绝大部分创建的对象都会被分配在堆空间内。而本篇文章则会站在对象实例的角度,阐述一个Java对象从生到死的历程、Java对象在内存中的布局以及对象引用类型。
122 8
|
3月前
|
存储 NoSQL 程序员
C语言中的内存布局
C语言中的内存布局
45 0
|
3月前
|
存储 程序员 编译器
c++学习笔记08 内存分区、new和delete的用法
C++内存管理的学习笔记08,介绍了内存分区的概念,包括代码区、全局区、堆区和栈区,以及如何在堆区使用`new`和`delete`进行内存分配和释放。
47 0
|
4月前
|
编译器 C++
sizeof之谜与内存布局探秘
【7月更文挑战第18天】`sizeof`之谜与内存布局探秘: 在 C 和 C++ 中,`sizeof` 操作符用于确定类型或变量的字节数。基本类型如 `int` 的大小由编译器和平台决定。结构体因内存对齐可能使其实际大小大于成员总和,例如 `int` 可能按 4 字节对齐。数组的 `sizeof` 返回整个数组的内存空间。理解 `sizeof` 和内存布局有助于避免内存浪费和缓冲区溢出问题,确保程序高效可靠。