数组定义和内存布局|学习笔记

简介: 快速学习数组定义和内存布局。

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

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


数组定义和内存布局


内容介绍

一、数组的定义

二、数组的内存布局

 

一、数组的定义

数组的定义

var数组名【数组大小】数据类型  var 是一个关键字

var a [5] int  a 为数组的名称,5代表数组最多存放5个数据,int 代表此数组能够存放的数据类型是什么

赋初值 a[0]=1a[1]=30…  a[0]代表给第一个元素赋初值,a[1]代表给第二个元素赋初值

 

二、数组的内存布局

1. 数组内存图(重要)

image.png

//使用代码来画图

2. 新建一个文件夹叫 arrarydemo02,新建一个文件叫 main.go

package main

import (

"fmt"

func main() { //定义一个组函数

//定义一个数组,用于存放 int ,数组大小为可以存放3个数据的数组

var intArr [3]int  //int 占8个字节

//当我们定义完数组后,其实数组的各个元素有默认值0

//打印值

fmt.Println(intArr)

运行结果如下:

image.png

三个元素的值都是0。

3.执行完var intArr[3]int 后,内存图中会出现一个 intArr 的变量,会出现一个数组,由于只能存储3个数据,所以空间有3个,空间中每个元素默认为0,intArr 由于是值类型,则会直接指向空间,进行关联,

数组的名字就是数组的首地址

获取地址

fmt.Printf(“intArr的地址=%p”,&intArr)

运行效果如下:

image.png

可以看到地址是0xc04204a0a0

所以可以知道,intArr 是指向地址的首地址0xc04204a0a0,而且数组的首地址就是第一个元素的地址

4.测试第一个元素的地址是否跟数组的首地址一样

fmt.Printf(“intArr的地址=%p intArr[0] 地址%p”,&*intArr,&intArr[0])

保存并运行,出现如下效果:

image.png

可以看见,地址完全一致。

5.由此可以推断出第二个元素的地址就是第一个元素地址基础上,加上int数组类型占用的字节数

fmt.Printf(“intArr的地址=%p intArr[0] 地址%p intArr[1] 地址%p”,&intArr,&intArr[0],intArr[1])

运行结果如下:

image.png

测试第三个元素的地址

fmt.Printf(“intArr的地址=%p intArr[0] 地址%p intArr[1] 地址%p intArr[2] 地址%p”,&intArr,&intArr[0],intArr[1],intArr[2])

运行结果如下:

image.png

可以发现地址都是连在一起的,第一个元素的地址最后一位为0,第二个元素地址最后一位为8,第三个元素的地址最后增加了一个 b0,因为是16进制,需要进位,所以 a 会变成 b,8会变成0

此可以得出,数组元素的地址是连续的,这也是 go 语言中的一个特点。

如果想要快速定位一个值,最快的方法就是在地址上加上一个值例如在第一个元素的地址上加一个8,就可以马上取得下一个元素的地址,然后取值。

6.如果将 var intArr [3]int 改为 var intArr [3]int32,元素之间的地址还是连续的,而且地址之间每个相差4,因为32是四个字节

运行效果如下:

image.png

首地址仍然不变,但是下一个地址增加了一个4,因为 int32每一个元素占了4个字节,所以每个地址需要增加一个4

所以最终呈现的内存图为:
image.png

为什么可以直接把数组的所有元素都取值出来,因为找到首地址之后,每个元素加8个字节,就可以把所有的值都取出来。

进行赋值

intArr[0]= 10  //第一个元素赋值为10

intArr[1]= 20  //第二个元素赋值为20

intArr[2]= 30  //第三个元素赋值为30

保存成功,运行输出结果如下:
image.png

通过元素的访问,可以改变各个元素中具体包含的值。

6.内存图:
image.png

从图中可以反映出数组是值类型,如果是引用类型的话,intArr 不会直接指向数据空间,而是指向地址。还反映出,内存中的每个元素的地址是连续分布的,而且中间每隔多少是取决于数组的类型。

7.对上图的总结:

1)数组的地址可以通过数组名来获取&intArr

2)数组的第一个元素的地址,就是数组的首地址

3)数组的各个元素的地址间隔是依据数组的类型决定,比如 int64 -> 8  int32->4...

注意:打印地址要是用%p,它代表取出地址

相关文章
|
16天前
|
Rust 安全 Java
内存数组越界
【10月更文挑战第14天】
20 1
|
27天前
|
存储 Java
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
这篇文章详细地介绍了Java对象的创建过程、内存布局、对象头的MarkWord、对象的定位方式以及对象的分配策略,并深入探讨了happens-before原则以确保多线程环境下的正确同步。
48 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月前
|
编译器 Linux API
基于类型化 memoryview 让 Numpy 数组和 C 数组共享内存
基于类型化 memoryview 让 Numpy 数组和 C 数组共享内存
33 0
|
2月前
|
存储 安全 Linux
将文件映射到内存,像数组一样访问
将文件映射到内存,像数组一样访问
29 0
|
3月前
|
存储 程序员 Python
Python类的定义_类和对象的关系_对象的内存模型
通过类的定义来创建对象,我们可以应用面向对象编程(OOP)的原则,例如封装、继承和多态,这些原则帮助程序员构建可复用的代码和模块化的系统。Python语言支持这样的OOP特性,使其成为强大而灵活的编程语言,适用于各种软件开发项目。
33 1
|
2月前
crash —— 获取物理内存布局信息
crash —— 获取物理内存布局信息
|
3月前
|
缓存 Java 编译器
Go 中的内存布局和分配原理
Go 中的内存布局和分配原理
|
3月前
|
存储 NoSQL 程序员
C语言中的内存布局
C语言中的内存布局
45 0