Go入门(四)-- 数组Array

数组是 Go 语言中最常用的数据结构之一。顾名思义,数组就是指一系列同一类型数据的集合。数组中包含的每个数据被称为数组元素(element),一个数组包含的元素个数被称为数组长度。

Golang Array 和以往认知的数组有很大不同。

  1. 数组:是同一种数据类型的固定长度的序列
  2. 数组定义:var a [len]int,比如:var a [5]int,数组长度必须是常量,且是类型的组成部分。一旦定义,长度不能变。
  3. 长度是数组类型的一部分:var a[5] intvar a[10]int是不同的类型。
  4. 数组可以通过下标进行访问,下标是从 0 开始,最后一个元素下标是:len - 1
for i := 0; i < len(a); i++ {
}

for index, v := range a {
}
  1. 访问越界:如果下标在数组合法范围之外,则触发访问越界,会panic
  2. 数组是值类型(value type):赋值和传参会复制整个数组,而不是指针。因此改变副本的值,不会改变本身的值。
  3. 支持 "=="、"!=" 操作符,因为内存总是被初始化过的
  4. 指针数组 [n]*T,数组指针 *[n]T

数组初始化

一维数组

全局:
var arr0 [5]int = [5]int{1,2,3}
var arr1 = [5]int{1,2,3,4,5}
var arr2 = [...]int{1,2,3,4,5,6}
var str = [5]string{3:"hello world",5:"go"}
局部:
a := [3]int{1,2} // 未初始化元素的值为0
b := [...]int{1,2,3,4} // 通过初始化值确定数组长度
c := [5]int{2:100,4:300} // 使用索引初始化元素
d := [...]struct {
	name string
    age  uint8
}{
{"user1", 10}, // 可省略元素类型。
{"user2", 20}, // 别忘了最后一行的逗号。
}

示例代码

package main

import (
    "fmt"
)

var arr0 [5]int = [5]int{1, 2, 3}
var arr1 = [5]int{1, 2, 3, 4, 5}
var arr2 = [...]int{1, 2, 3, 4, 5, 6}
var str = [5]string{3: "hello world", 4: "tom"}

func main() {
    a := [3]int{1, 2}           // 未初始化元素值为 0。
    b := [...]int{1, 2, 3, 4}   // 通过初始化值确定数组长度。
    c := [5]int{2: 100, 4: 200} // 使用引号初始化元素。
    d := [...]struct {
        name string
        age  uint8
    }{
        {"user1", 10}, // 可省略元素类型。
        {"user2", 20}, // 别忘了最后一行的逗号。
    }
    fmt.Println(arr0, arr1, arr2, str)
    fmt.Println(a, b, c, d)
}

/*
输出结果:
[1 2 3 0 0] [1 2 3 4 5] [1 2 3 4 5 6] [   hello world tom]
[1 2 0] [1 2 3 4] [0 0 100 0 200] [{user1 10} {user2 20}]
*/

多维数组

全局
var arr0 [5][3]int
var arr1 [2][3]int = [...][3]int{{1,2,3},{7,8,9}}
局部
a := [2][3]int{{1, 2, 3}, {4, 5, 6}}
b := [...][2]int{{1, 1}, {2, 2}, {3, 3}} // 第 2 纬度不能用 "..."

示例代码

package main

import (
    "fmt"
)

var arr0 [5][3]int
var arr1 [2][3]int = [...][3]int{{1, 2, 3}, {7, 8, 9}}

func main() {
    a := [2][3]int{{1, 2, 3}, {4, 5, 6}}
    b := [...][2]int{{1, 1}, {2, 2}, {3, 3}} // 第 2 纬度不能用 "..."。
    fmt.Println(arr0, arr1)
    fmt.Println(a, b)
}

/*
输出结果:
[[0 0 0] [0 0 0] [0 0 0] [0 0 0] [0 0 0]] [[1 2 3] [7 8 9]]
[[1 2 3] [4 5 6]] [[1 1] [2 2] [3 3]]
*/

值拷贝行为会造成性能问题,通常会建议使用 slice或数组指针

package main

import (
    "fmt"
)

func test(x [2]int) {
    fmt.Printf("x: %p\n", &x)
    x[1] = 1000
}

func main() {
    a := [2]int{}
    fmt.Printf("a: %p\n", &a)

    test(a)
    fmt.Println(a)
}

/*
输出结果:
a: 0xc42007c010
x: 0xc42007c030
[0 0]
*/

内置函数 lencap都返回数组长度(元素数量)

package main

func main() {
    a := [2]int{}
    println(len(a), cap(a)) 
}

/*
输出结果:
2 2
*/

多维数组遍历

Go 语言使用 := range 对数组(一维/多维)进行遍历。一维数组可以使用 for 循环。

示例代码

package main

import (
    "fmt"
)

func main() {

    var f [2][3]int = [...][3]int{{1, 2, 3}, {7, 8, 9}}

    for k1, v1 := range f {
        for k2, v2 := range v1 {
            fmt.Printf("(%d,%d)=%d ", k1, k2, v2)
        }
        fmt.Println()
    }
}

/*
输出结果:
(0,0)=1 (0,1)=2 (0,2)=3 
(1,0)=7 (1,1)=8 (1,2)=9
*/

值类型

在Go语言中数组是一个值类型(value type)。所有的值类型变量在赋值和作为参数传递时都将产生一次复制动作。如果将数组作为函数的参数类型,则在函数调用时该参数将发生数组复制。因此,在函数体中无法修改传入的数组内同,因为函数内操作的只是所传入数组的一个副本。

示例代码

package main

import "fmt"

func modify(array [10]int) {
    array[0] = 10      // 试图修改数组的第一个元素
    fmt.Println("In modify(), array values:",array)
}

func main() {
    array := [5]int{1,2,3,4,5}   // 定义并初始化一个数组

    modify(array)        // 传递给一个函数,并试图在函数体内修改这个数组内同

    fmt.Prinln("In main(),array values:",array)
}


/*
输出结果:
In modify(), array values:[10 2 3 4 5]
In main(), array values: [1 2 3 4 5]
*/

从执行结果可以看出,函数 modify() 内操作的那个数组跟 main() 中传入的数组是两个不同的实例。

数组拷贝和传参

示例代码

package main

import "fmt"

func printArr(arr *[5]int) {
    arr[0] = 10
    for i, v := range arr {
        fmt.Println(i, v)
    }
}

func main() {
    var arr1 [5]int
    printArr(&arr1)
    fmt.Println(arr1)
    arr2 := [...]int{2, 4, 6, 8, 10}
    printArr(&arr2)
    fmt.Println(arr2)
}

数组练习

求数组所有元素之和

package main

import (
    "fmt"
    "math/rand"
    "time"
)

// 求元素和
func sumArr(a [10]int) int {
    var sum int = 0
    for i := 0; i < len(a); i++ {
        sum += a[i]
    }
    return sum
}

func main() {
    // 若想做一个真正的随机数,要种子
    // seed()种子默认是1
    //rand.Seed(1)
    rand.Seed(time.Now().Unix())

    var b [10]int
    for i := 0; i < len(b); i++ {
        // 产生一个0到1000随机数
        b[i] = rand.Intn(1000)
    }
    sum := sumArr(b)
    fmt.Printf("sum=%d\n", sum)
}


找出数组中和为给定值的两个元素的下标,例如数组[1,3,5,8,7],找出两个元素之和等于8的下标分别是(0,4)和(1,2)

package main

import "fmt"

//    找出数组中和为给定值的两个元素的下标,例如数组[1,3,5,8,7],
// 找出两个元素之和等于8的下标分别是(0,4)和(1,2)

// 求元素和,是给定的值
func myTest(a [5]int, target int) {
    // 遍历数组
    for i := 0; i < len(a); i++ {
        other := target - a[i]
        // 继续遍历
        for j := i + 1; j < len(a); j++ {
            if a[j] == other {
                fmt.Printf("(%d,%d)\n", i, j)
            }
        }
    }
}

func main() {
    b := [5]int{1, 3, 5, 8, 7}
    myTest(b, 8)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我会为你介绍Python中的数组。 在Python中,数组是一种存储元素的数据结构。与列表不同,数组是固定大小的,且元素类型必须相同。 要使用数组,需要先导入array模块。下面是一个创建数组的示例: ```python import array as arr # 创建一个整数类型的数组 a = arr.array('i', [1, 2, 3, 4, 5]) # 打印数组 print(a) ``` 在上面的示例中,我们使用了`array`模块创建了一个整数类型的数组,并初始化了它。要注意的是,第一个参数是一个字符,用于指定数组元素的类型。在本例中,我们使用了`i`,表示整数类型。 除了整数类型之外,还有其他类型可以使用,如`f`表示浮点数,`d`表示双精度浮点数,`b`表示布尔类型等。 在数组中,可以使用索引来访问元素,如下所示: ```python import array as arr # 创建一个整数类型的数组 a = arr.array('i', [1, 2, 3, 4, 5]) # 访问数组中的第一个元素 print(a[0]) # 修改数组中的第二个元素 a[1] = 6 # 打印数组 print(a) ``` 在上面的示例中,我们使用了索引`0`来访问数组中的第一个元素,使用索引`1`来修改数组中的第二个元素。 除了使用索引来访问和修改元素外,还可以使用循环来遍历数组中的所有元素,如下所示: ```python import array as arr # 创建一个整数类型的数组 a = arr.array('i', [1, 2, 3, 4, 5]) # 遍历数组中的所有元素 for i in a: print(i) ``` 在上面的示例中,我们使用了`for`循环来遍历数组中的所有元素,并打印每个元素的值。 这就是Python中数组的基本用法。希望对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值