基本概念

1、数组是具有相同唯一类型的一组已编号且长度固定的数据项序列,这种类型可以是任意的原始类型例如整形、字符串或者自定义类型。

2、在 Go 中因为数组的内存布局是连续的,所以可以通过索引(位置)来读取(或者修改),索引是从 0 开始,第一个元素索引为 0,第二个索引为 1,这样以此类推。

3、声明数组时需要指定数据的类型,以及数组的长度。

var array [6] int
// 声明的规则:var + 变量名 + 类型

Go 和 Python 不一样,在声明变量的时候依次是 “var”、变量名、变量类型。这里我们声明一个包含 6 个元素的 int 类型的数组,这个数组在初始化的时候会被设置为该类型的零值。

数组创建

  1. 声明一个长度为 5 的 int 类型的空数组。
	var arr=[5] int {}
fmt.Println (arr)

因为没有赋值,所以会打印其零值也就是 5 个 0

上面的过程我们可以通过一个图来表示:



图中 5 个连续的蓝色格子表示数组占用内存是连续分配的。

每一个格子表示数组的一个元素,每个元素的类型相同,这里的例子全是整数的,我们可以通过数组的下标访问数组中对应位置的元素。

当数组初始化的时候,数组每个元素都会初始化为其零值,其他语言习惯叫默认值。

每个数据类型的零值也是不一样的,这里就拿我们这个例子,因为每个元素都是 int 类型所以其零值为 0。

  1. 声明一个长度为 6 的 int 类型数组并赋值
array:= [6] int {5,10, 20, 30, 40, 50}
  1. 如果忽略 [] 中的数字不设置数组大小,Go 语言会根据元素的个数来设置数组的大小
arr1:=[...] int {1, 2, 3, 4, 5}
fmt.Println (arr1)

需要注意不指定数组大小的时候使用 ..., 如果不写东西就是切片了。

4. 还可以在定义的时候根据下标进行赋值

  array:=[5] int {0:2,3:2}

定义了一个长度为 5 的 int 类型数组,: 前面的 0,3 表示当前下标,: 后面是要赋的值



通过演示图可以得知,下标 0 和 3 的元素赋值了,其他没有赋值的元素仍然是 0。

  1. 如果数组下标太大,编译会提示下标越界
array:=[4] int {0:2,3:2}
array [6] =4
fmt.Println (array1)

这里我们定义了数组长度为 4,其下标最大是 3, 这是要给下标第 6 个元素赋值,编译不通过。

数组复制

在 Go 中具有相同类型的,相同个数的数组,可以相互直接进行赋值。

	// 复制
array1:=[4] int {0:2,3:2}
array2:=[4] int {}
array3:=[4] int {3,4,5,7}
array2 =array1 // 具有相同类型的,相同个数的数组,可以相互直接进行赋值
array3 =array2
fmt.Println (array2)
fmt.Println (array3) // 可以看到 array3 被 array2 完全覆盖

数组遍历

Go 语言一种独有的结构 for...range,可以用来遍历访问数组的元素,也可以遍历 map。这里先说数组

for ix, value := range array01 {
...
}

第一个返回值 ix 是数组的索引,第二个是在该索引位置的值;他们都是仅在 for 循环内部可见的局部变量。value 只是 array01 某个索引位置的值的一个拷贝,不能用来修改 array01 该索引位置的值。如下面的例子

package main
import "fmt"
var array [6] int
func main () {
array [1] =7 #根据下标给数组赋值,下标 0 开始。
for k,v:=range array {
fmt.Printf ("% d:% d \n",k,v)
}
}

输出结果

0:0
1:7
2:0
3:0
4:0
5:0

上面的代码我们只对列表第二个元素进行了赋值,可以看出其他位置默认零值为 0。

有时候,在一开始就想好了给数组赋几个值,赋什么值,这个时候我们可以使用下面的方式定义。

不过上面的代码有个限制就是,一旦长度设定了,后面就能在改变了。

所以一般情况下更建议使用后面文章提到的切片。

数组指针和指针数组

在说这个问题前,首先需要了解什么是 指针

指针就是一个变量,它存储的数据不仅仅是一个普通的值,如简单的整数或字符串,而是另一个变量的内存地址。

一个指针变量可以指向任何一个值的内存地址它指向那个值的内存地址,在 32 位机器上占用 4 个字节,在 64 位机器上占用 8 个字节,并且与它所指向的值的大小无关。当然,可以声明指针指向任何类型的值来表明它的原始性或结构性;你可以在指针类型前面加上 * 号(前缀)来获取指针所指向的内容,这里的 * 号是一个类型更改器。使用一个指针引用一个值被称为间接引用。

当一个指针被定义后没有分配到任何变量时,它的零值为 nil。

每个变量在运行时都拥有一个地址,这个地址代表变量在内存中的位置。Go 语言中使用 & 作符放在变量前面对变量进行 “取地址” 操作。

了解了什么是指针了,下面让我们先看什么是数组指针。

简单说,数组指针其实就是 “数组的指针” 的简写,指针指向的数组的内存地址。

其形式为

	var arr =  [...] int {5:2}
// 数组指针
var ptf *[6] int = &arr // 和数组数量必须相等
ptf [2]=3
ptf [1]=7
fmt.Println (ptf)

然后看指针数组,同样的可以理解为指针数组的全称是 “指针类型的数组”。

func main () {
array1 := [5]*int {0: new (int), 1: new (int)}
*array1 [0] = 10
*array1 [1] = 20
array1 [2] = new (int) // 因为定义的时候没有给下标 2 的元素分配空间,所以这里是分配一块内存
*array1 [2] = 30 // 如果没有上一步这步会报错
fmt.Println (array1)
}

打印可以发现

[0xc000016038 0xc000016040]

所谓的指针数组就是,数组的元素全是指针组成的。

上面 array1 数组操作用图表示的话



此时的数组内每个元素存的实际上是指向 new 创建对应类型的指针,这里是 int 类型的指针。

官方对 new 的描述是:内建函数 new 用来分配内存,它的第一个参数是一个类型,不是一个值,它的返回值是一个指向新分配类型零值的指针。

需要注意的一点是只有给元素分配内存空间了才能对其进行操作,如果元素是 nil,直接对元素赋值的话就会出现错误,就像上面的 array1[2]。

这个数组的元素是指针类型的,存放的是指向整数的地址的指针。

指针数组的复制

下面我们看看如果对指针数组进行复制操作,内存中变化什么样呢。

func main () {
array1 := [5]*int {0: new (int), 1: new (int)} // 为索引为 0 和 1 的元素赋值
*array1 [0] = 10
*array1 [1] = 20
array2 := array1
*array1 [0] =80
fmt.Println (array2==array1)
}



通过图片可以得知,复制数组指针,只会复制指针的值,而不会复制指针所指向的值。

所以修改 array1 的指针指向的地址时,array2 也会跟着变,所以 array1 和 array2 相等。

后记

在函数间传递数组,如果数组过大将造成巨大的开销,所以一般会将其转换为指针,这里为什么没有单独的拿出讲解,就是因为不推荐给函数传入数组。而是使用抽象度更高的切片。

更多内容关注公众号:python学习开发,添加微信:italocxa,回复加群:关键词Python、Go,需要哪个回复哪个即可。

Go by Example-图解数组的更多相关文章

  1. Java - 数组详解(图解数组的基本操作)

    目录 什么是数组 数组的定义和内存分配 数组的赋值和访问 数组的注意事项 数组的内存图解 数组的插入 数组的删除 数组的扩容 数组的反转 首先 什么是数组 数组是一组地址连续.长度固定的具有相同类型的 ...

  2. 05 方法与数组笔记【JAVA】

    ---恢复内容开始--- 1:方法(掌握) (1)方法:就是完成特定功能的代码块. 注意:在很多语言里面有函数的定义,而在Java中,函数被称为方法. (2)格式: 修饰符 返回值类型 方法名(参数类 ...

  3. Java Day 04

    01 语句 循环结构 嵌套  列的递减 1-5 2-5 3-5// 1-5 1-4 1-3 转义字符 \n 回车 \t 制表符 \b 退格 \r 按下回车键 windows 回车符由 \r \n 组成 ...

  4. Junit 注解 类加载器 .动态代理 jdbc 连接池 DButils 事务 Arraylist Linklist hashset 异常 哈希表的数据结构,存储过程 Map Object String Stringbufere File类 文件过滤器_原理分析 flush方法和close方法 序列号冲突问题

    Junit 注解 3).其它注意事项: 1).@Test运行的方法,不能有形参: 2).@Test运行的方法,不能有返回值: 3).@Test运行的方法,不能是静态方法: 4).在一个类中,可以同时定 ...

  5. JavaBasic_05

    方法 简述:实现特定功能的代码块 格式 修饰符: 返回值类型 方法名(参数类型 参数名1,参数类型 参数名2…){           函数体;           return 返回值;} 方法格式 ...

  6. 字符串模式匹配之KMP算法图解与 next 数组原理和实现方案

    之前说到,朴素的匹配,每趟比较,都要回溯主串的指针,费事.则 KMP 就是对朴素匹配的一种改进.正好复习一下. KMP 算法其改进思想在于: 每当一趟匹配过程中出现字符比较不相等时,不需要回溯主串的 ...

  7. js数组操作-最佳图解

    js数组操作-最佳图解

  8. 06-01 Java 二维数组格式、二维数组内存图解、二维数组操作

    二维数组格式1 /* 二维数组:就是元素为一维数组的一个数组. 格式1: 数据类型[][] 数组名 = new 数据类型[m][n]; m:表示这个二维数组有多少个一维数组. n:表示每一个一维数组的 ...

  9. Java中数组在内存中的图解

    Java中的数组在内存中的图解,其实对于数组,还是比较熟悉的,平时用的也是很多的,在看数据结构与算法的极客时间专栏,最常用的10个数据结构:数组.链表.栈.队列.散列表.二叉树.堆.跳表.图.Trie ...

  10. 图解c/c++多级指针与“多维”数组

    声明:本文为原创博文,如有转载,请注明出处.若本文有编辑错误.概念错误或者逻辑错误,请予以指正,谢谢. 指针与数组是C/C++编程中非常重要的元素,同时也是较难以理解的.其中,多级指针与“多维”数组更 ...

随机推荐

  1. js的变量类型

    参考网址:https://www.cnblogs.com/focusxxxxy/p/6390536.html (讲的蛮好得,图文并茂,我下面只是总结下) 一:ECMAScirpt 变量的两种数据类型 ...

  2. S5PV210 启动流程

    S3C6410启动流程 首先,看一下S3C6410启动流程 ① iROM supports initial boot up : initialize system clock, D-TCM, devi ...

  3. 【亲测有效】vs2017无法断点

    解决方案: 一:设置为Debug模式 二:[工具]--[选项]--[调试]--[常规],取消打钩[要求源文件与原始版本完全匹配]

  4. IDEA提示不区分大小写设置

    File–>Settings–>Editor–>General–>Code Completion–>Mach case的勾取消掉就可以了 取消勾后效果如下

  5. 【leetcode】338 .Counting Bits

    原题 Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate t ...

  6. mongodb副本集和分片存储理论整理

    目录 理论概述 一.各种集群简述 二.原理 主从复制 Mongodb副本集 理论概述 一.各种集群简述 mongodb有三种集群搭建方式: 分片:sharding.指为处理大量数据,将数据分开存储,不 ...

  7. jquery-deferred应用

    我们说jquery1.5之后用的用deferred,那么deferred到底是个什么东西,看个例子 var wait = function(){ var task = function(){ cons ...

  8. 【转】Python源码学习Schedule

    原文:https://www.cnblogs.com/angrycode/p/11433283.html ----------------------------------------------- ...

  9. JavaScript事件——拖拉事件

    拖拉事件的种类 拖拉(drag)指的是,用户在某个对象上按下鼠标键不放,拖动它到另一个位置,然后释放鼠标键,将该对象放在那里. 具体的api可查看 拖拽变色demo <div draggable ...

  10. TOMCAT上传下载文件

    实现下载 修改server.xml修改web.xml   实现上传 实现客户端的上传post请求代码实现 实现服务端的处理   小结         实现下载 实现下载需要  - 修改Tomcat中的 ...