@@ -1,58 +0,0 @@ 10.数组(array) | 凤凰涅槃进阶之路

10.数组(array)

Abel sun2023年1月6日约 1808 字大约 6 分钟

10.数组(array)

数组是指一系列同一类型数据的集合。

数组中包括的每个数据被称为数组元素(element)。

数组的长度([]里边定义长度)必须是常量,且是类型的组成部分。

1,为什么需要数组

package main

import "fmt"

func main() {
 //传统的给50个变量赋值方式
 // id1 := 1
 // id2 := 2
 // id3 := 3
 //一直写50个来进行定义

 //数组,就是同一个类型的集合
 var id [50]int
 //通过下标,操作数组
 //从0开始,到len()-1
 for i := 0; i < len(id); i++ {
  id[i] = i + 1
  //fmt.Printf("id[%d] = %d\n", i, id[i])
 }
 
 //range具有两个返回值,第一个返回值是元素的数组下标,第二个返回值是下标对应的值
 for x, v := range id {
  fmt.Printf("id[%d] = %d\n", x, v)
 }
}

2,数组的基本使用

package main

import "fmt"

func main() {
 var a [10]int
 var b [5]int

 fmt.Printf("len(a) =%d, len(b) =%d\n", len(a), len(b))
 //注意:定义数组时,指定的数组元素个数必须是常量
 /*n := 10
 var b [n]int*/ //non-constant array bound n

 //通过下标,操作数组
 //从0开始,到len()-1,不对称元素,这个下标,可以使常量,也可以是变量
 a[0] = 1
 i := 1
 a[i] = 2

 //赋值给每个元素
 for i := 0; i < len(a); i++ {
  a[i] = i + 1
 }

 // //range具有两个返回值,第一个返回值是元素的数组下标,第二个返回值是下标对应的值
 for x, v := range a {
  fmt.Printf("id[%d] = %d\n", x, v)
 }
}

3,数组的初始化

package main

import "fmt"

func main() {
 //声明定义变量的同时赋值,叫做初始化
 //1、全部初始化
 var a [5]int = [5]int{5, 4, 3, 2, 1}
 fmt.Println("a = ", a)

 //也可以自动推到类型,直接赋值。
 b := [5]int{5, 4, 3, 2, 1}
 fmt.Println("b = ", b)

 //2、部分初始化,没有初始化的元素,自动赋值为0
 c := [5]int{1, 2, 3}
 fmt.Println("c = ", c)

 //3、指定某个元素初始化,{2:10},其中2表示数组的下标,10表示给下标对应元素赋值
 //其他没初始化的元素,自动赋值为0
 d := [5]int{2: 10, 4: 20}
 fmt.Println("d = ", d)
 
 //根据初始化看结果
 e := []int{10: 200, 5: 100}
 fmt.Println(e)
 fmt.Println(len(e))
 /*结果如下
 [0 0 0 0 0 100 0 0 0 0 200]
 11
 */
 
 //而用如下方式,则是另外不同的结果
 f := []int{010: 200, 005: 100}
 fmt.Println(f)
 fmt.Println(len(f))
 /*结果如下
 [0 0 0 0 0 100 0 0 200]
 9
 */
 
 //好奇怪,看不明白上下这两个区别在哪里 其实 010 的话是一个八进制的,转换成十进制就是8,如此算来,长度自然也就是9了
 
}

4,二维数组的了解

package main

import "fmt"

func main() {
 //有多少个[]就是多少维
 //有多少个[]就用多少个循环

 var a [3][4]int //可以这样理解,有3个元素,每个元素又是一个数组[4]int

 k := 0
 for i := 0; i < 3; i++ {
  for j := 0; j < 4; j++ {
   k++
   a[i][j] = k
   fmt.Printf("a[%d][%d] = %d, ", i, j, a[i][j])
  }
  fmt.Printf("\n")
 }

 //或者直接进行打印
 fmt.Println("a = ", a)

 //直接自动推导类型并进行全赋值
 b := [3][4]int{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}
 fmt.Println("b = ", b)

 //也可以部分初始化,没有初始化的值为0
 c := [3][4]int{{1, 2, 3}, {5, 6, 7}, {9, 10, 11}}
 fmt.Println("c = ", c)
 //也可以初始化部分下标的元素
 d := [3][4]int{{1, 2, 3, 4}, {5, 6, 7, 8}}
 fmt.Println("d = ", d)
 //也可以对指定下标的元素进行初始化
 e := [3][4]int{1: {5, 6, 7, 8}}
 fmt.Println("e = ", e)
}

5,数组的比较和赋值

package main

import "fmt"

func main() {
 //支持比较,只支持 == 或 !=,比较是不是每一个元素都一样
 //两个数组进行比较,数组的类型要一致
 a := [5]int{1, 2, 3, 4, 5}
 b := [5]int{1, 2, 3, 4, 5}
 c := [5]int{1, 2, 3}
 fmt.Println("a == b", a == b)
 fmt.Println("a == c", a == c)

 //同类型的数组可以赋值
 var d [5]int
 d = a
 fmt.Println("d = ", d)
}

6,随机数的使用

随机数可以应用在猜数字,随机验证码等方面。

package main

import "fmt"
import "math/rand"
import "time"

func main() {
 //1、设置种子,只需一次
 //rand.Seed(666) //如果种子参数保持不变,那么每次运行程序所产生的随机数也都一样
 //此时如果想要每次都产生不同的随机数,就要在设置种子的时候,将参数定义成不断变化的
 rand.Seed(time.Now().UnixNano()) //以当前系统时间作为种子参数

 //2、产生5个随机数
 for i := 0; i < 5; i++ {
  //fmt.Println("rand = ", rand.Int()) //随机产生很大的数
  fmt.Println("rand = ", rand.Intn(100)) //Intn(100)表示随机产生100以内的数字
  fmt.Println("rand = ", rand.Perm(6))   //Perm(6)表示返回一个有6个元素的数组
 }
}

要想产生随机数,需要引入一个rand的包,可以去标准库中文版搜索:https://studygolang.com/pkgdocopen in new window

m_c704ef511b58e089b475d5be6da31eb1_r

7,冒泡排序法

冒泡排序法的核心概念是两句话,就是数组里边相邻的两个数进行比较,如果左边的大于右边的,则两数交换。

如此循环一定次数,则可以将一个数组里边的内容进行一个排序。

分析图如下:

m_154291b502dfc9830eedf091c86d4899_r

简单说明: 这里主要需要理解一下i和j这两个变量以及他们的范围的定义。其实直接根据J列的输出,就比较容易能够看出来了,i表示数组里边比较的次数,次数到n-1次。j表示每次对比的两个数的下标,他的值是从0到n-1-i。

用代码实现,则如下:

package main

import "fmt"
import "math/rand"
import "time"

func main() {
 rand.Seed(time.Now().UnixNano()) //以当前系统时间作为种子参数
 var a [10]int
 n := len(a)

 for i := 0; i < n; i++ {
  a[i] = rand.Intn(100)
  fmt.Printf("%d,", a[i])
 }
 fmt.Printf("\n")
 //冒泡排序,挨着的2个元素比较,大于则交换(升序排列)
 for i := 0; i < n-1; i++ {
  for j := 0; j < n-1-i; j++ {
   if a[j] > a[j+1] {
    a[j], a[j+1] = a[j+1], a[j]
   }
  }
 }

 fmt.Printf("\n排序后:\n")
 for i := 0; i < n; i++ {
  fmt.Printf("%d, ", a[i])
 }
}

8,数组做函数的参数

package main

import "fmt"

//数组做函数的参数,它是值传递
//实参数组的每一个元素都会给形参拷贝一份
func test(a [5]int) {
 a[0] = 666
 fmt.Println("test : a = ", a)
}

func main() {
 a := [5]int{1, 2, 3, 4, 5} //初始化

 test(a) //数组传递给函数
 fmt.Println("main: a = ", a)
}

9,数组指针做函数参数

如何使用同一份数组呢,可以利用数组的指针的方式,也就是两者指向同一个数组的内存地址,就可以了。

package main

import "fmt"

//数组做函数的参数,它是值传递
//实参数组的每一个元素都会给形参拷贝一份
func test(p *[5]int) {
 (*p)[0] = 666
 fmt.Println("test : p = ", *p)
}

func main() {
 a := [5]int{1, 2, 3, 4, 5} //初始化

 test(&a) //数组传递给函数
 fmt.Println("main: a = ", a)
}

这样就实现了,两个函数指向了同一份数组。

评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.9.1