Go-07 Golang中的数组

package main

import "fmt"

/*...Golang 中的数组...*/
/*	Go 语言中的数组是指一系列相同类型数据的集合。数组中的元素必须要相同数据类型。数组中包含的每个数据被称为数组元素。
	1. 数组的长度是类型的一部分,也就是说[5]int 和 [10]int 是两个不同的类型。
	Go 语言中数组的基本语法:
		数组支持索引取值和赋值操作。
		var a [3]int	// 定义一个长度为3元素类型为int的数组a
		var b [6]int	// 定义一个长度为6元素类型为int的数组b
		b[0] = 50
		b[1] = 60
		b[2] = 70
	2. 数组定义
		var 数组变量名 [元素数量]T
		比如:var a [5]int, 数组的长度必须是常量,并且长度是数组类型的一部分。一旦定义,长度不能变。
		[5]int 和 [4]int是不同的类型。
		var a [3]int
		var b [4]int
		a = b	// 不可以这样做,因为此时a和b是不同的类型。
		数组可以通过下标进行访问,下标是从0开始,最后一个元素下标是lenth-1,访问越界,则触发访问越界,会panic
	3. 数组的初始化,分为三种
		方法1:初始化数组时,可以使用初始化列表来设置数组元素的值。
		方法2:根据初始值的个数自行推断数组的长度
		方法3:使用指定索引值的方式来初始化数组
	4. 数组的遍历,遍历数组有两种方法,方法1:for循环遍历,方法2:for range 遍历
	5. 数组是值类型,相当于Python中的深度拷贝。赋值和传参会复制整个数组。变量a和变量b是两个独立的内存地址,互不影响。
		a := 3
		b := a
		a += 1
		fmt.Println("a=",a, "b=",b)		// 结果是: a= 4 b= 3
		注意:
		1. 数组支持 == 和 != 操作符,因为内存总是被初始化过的。
		2. [n]*T 表示n个数量的指针数组,*[n]T 表示这是一个数组类型的指针。
	6. 多维数组
		Go 语言中支持多维数组,我们通常情况下不要超过三维,这里以二维数组为例。
		6.1 二维数组的定义:var 数组变量名称 [元素数量][元素数量]Type
			例如下面的数组可以解析为:定义一个三行两列的string类型数组a。
				a := [3][2]string{
					{"北京","上海"},
					{"广州","深圳"},
					{"成都","重庆"},
				}
		6.2 二维数组的遍历,通过for range 循环每一个数组元素的值。
			将上面的数组a进行循环遍历并打印结果:
			for _,v1 := range a {
				for _,v2 := range v1 {
					fmt.Printf("%s \t", v2)
				}
				fmt.Println()
			}
			这个数组aaa循环遍历后的结果如下:
			北京    上海
			广州    深圳
			成都    重庆
		6.3 多维数组只有第一层可以使用...来让编译器推导数组的长度。例如:
			支持的写法是:a := [...][2]string{{"北京","北京"},{"上海","上海"},{"深圳","深圳"}}
		7. 数组练习题
		7.1 请求出一个数组的和以及平均值。for-range
			var intArr2 [5]int = [...]int{1,-1,9,90,12}
			sum := 0
			for _,val := range intArr2 {
				// 累计求和
				sum += val
			}
			// 如何让平均值保留到小数
			fmt.Printf("sum=%v 平均值=%v \n", sum, float64(sum) / float64(len(intArr2)))

*/

func modifyArray(x [3]int) {
	x[0] = 1000
	fmt.Println(x) // [100 20 30]
	a := 3
	b := a
	a += 1
	fmt.Println("a=", a, "b=", b)

}
func modifyArray2(x [3][2]int) {
	x[2][0] = 999
	fmt.Println(x)
}

func main() {
	// 1. 数组的基本语法
	var a [3]int // 定义一个长度为3元素类型为int的数组a
	var b [6]int // 定义一个长度为6元素类型为int的数组b
	b[0] = 50
	b[1] = 60
	b[2] = 70
	fmt.Println(a) // [0 0 0]
	fmt.Println(b) // [50 60 70 0 0 0]
	// 2. 数组的初始化,分为三种
	//	方法1:初始化数组时,可以使用初始化列表来设置数组元素的值。
	var testArray [3]int                              // 数组会初始化为int类型的零值
	var numArray = [3]int{1, 2}                       // 使用指定的初始值完成初始化
	var cityArray = [3]string{"北京", "上海", "广州"} // 使用指定的初始值完成初始化
	fmt.Println(testArray)                            // [0 0 0]
	fmt.Println(numArray)                             // [1 2 0]
	fmt.Println(cityArray)                            // [北京 上海 广州]
	//	方法2:根据初始值的个数自行推断数组的长度
	var testArray2 [3]int
	var numArray2 = [...]int{1, 2}
	var cityArray2 = [...]string{"北京", "上海", "深圳"}
	fmt.Println(testArray2)                           // [0 0 0]
	fmt.Println(numArray2)                            // [1 2 0]
	fmt.Printf("type of numArray:%T \n", numArray2)   // type of numArray:[2]int
	fmt.Println(cityArray2)                           // [北京 上海 深圳]
	fmt.Printf("type of cityArray:%T \n", cityArray2) // type of cityArray:[3]string
	// 方法3:使用指定索引值的方式来初始化数组
	a2 := [...]int{1: 1, 3: 5, 6: 10}
	fmt.Println(a2)                            // [0 1 0 5 0 0 10]
	fmt.Printf("type of a2 is :	%T \n", a2) // type of a2 is :	[7]int
	// 2.1 数组的遍历
	// 遍历数组有两种方法,方法1:for循环遍历,方法2:for range 遍历
	var a3 = [...]string{"北京", "上海", "深圳"}
	// 方法1:for循环遍历
	for i := 0; i < len(a3); i++ {
		fmt.Println("循环遍历打印结果:", a3[i])
	}
	// 方法2: for range 遍历
	for k, v := range a3 {
		fmt.Println("循环遍历打印结果:", k, v)
	}
	// 3. 数组是值类型,值类型属于深度拷贝
	//	数组是值类型,赋值和传参会复制整个数组。因此改变副本的值,不会改变本身的值。类似于Python中的深拷贝。
	aa := [3]int{10, 20, 30}
	modifyArray(aa) // 把aa传过去后,赋值给新的变量x,变量x和变量aa属于深度拷贝。这里面x的值是[1000 20 30]
	// 深度拷贝,在内存中开启两个内存地址保存变量aa和x的值,任何变量的参数修改,他们已经互不影响。
	fmt.Println(aa) // [10 20 30]
	bb := [3][2]int{
		{1, 1},
		{1, 1},
		{1, 1},
	}
	modifyArray2(bb) // 这里面的x的值是 [[1 1] [1 1] [999 1]]
	fmt.Println(bb)  // [[1 1] [1 1] [1 1]]
	// 需求:定义一个三行两列string类型的二位数组,并打印出每一个数组的元素。
	aaa := [3][2]string{
		{"北京", "上海"},
		{"广州", "深圳"},
		{"成都", "重庆"},
	}
	for _, v1 := range aaa {
		for _, v2 := range v1 {
			fmt.Printf("%s \t", v2)
		}
		fmt.Println()
	}
	/*	这个数组aaa循环遍历后的结果如下:
		北京    上海
		广州    深圳
		成都    重庆
	*/
	// 4. 数组练习题
	// 4.1 请求出一个数组的和以及平均值。for-range
	var intArr2 [5]int = [...]int{1, -1, 9, 90, 12}
	sum := 0
	for _, val := range intArr2 {
		// 累计求和
		sum += val
	}
	// 如何让平均值保留到小数,使用%f来接收,然后 %.2f 就表示小数保留两位
	fmt.Printf("sum=%v 平均值=%v \n", sum, float64(sum)/float64(len(intArr2))) // sum=111 平均值=22.2
	/*	4.2 请求出一个数组的最大值,并得到对应的下标。
		4.2.1 声明一个数组 var intArrs = [...]int{1, -1, 12, 65, 11}
		4.2.2 假定第一个元素就是最大值,下标就是0
		4.2.3 然后从第二个元素开始循环比较,如果发现有更大,则进行交换
	*/
	var intArrs = [...]int{1, -1, 12, 65, 11}
	maxValue := intArrs[0]
	maxIndex := 0
	for i := 0; i < len(intArrs); i++ {
		if maxValue < intArrs[i] {
			maxValue = intArrs[i]
			maxIndex = i
		}
	}
	fmt.Println("最大值是:", maxValue, "最大值的索引值是:", maxIndex) // 最大值是: 65 最大值的索引值是: 3
	// 4.3 从数组[1,3,5,7,8]中找出和为8的两个元素的下标并打印
	arr := [...]int{1, 3, 5, 7, 8}
	for i := 0; i < len(arr); i++ {
		for j := i + 1; j < len(arr); j++ {
			if arr[i]+arr[j] == 8 {
				fmt.Printf("(%v,%v) \n", arr[i], arr[j])
			}
		}
	}
	/*	上面打印的结果是:
		(1,7)
		(3,5)
	*/

	/*	上面代码的全部执行结果如下所示:
		PS C:\Users\Zhaoshan.lu\go\DaDi> go run .\09.go
		[0 0 0]
		[50 60 70 0 0 0]
		[0 0 0]
		[1 2 0]
		[北京 上海 广州]
		[0 0 0]
		[1 2]
		type of numArray:[2]int
		[北京 上海 深圳]
		type of cityArray:[3]string
		[0 1 0 5 0 0 10]
		type of a2 is : [7]int
		循环遍历打印结果: 北京
		[10 20 30]
		[[1 1] [1 1] [999 1]]
		[[1 1] [1 1] [1 1]]
		北京    上海
		广州    深圳
		成都    重庆
		sum=111 平均值=22.2
		最大值是: 65 最大值的索引值是: 3
		(1,7)
		(3,5)
		PS C:\Users\Zhaoshan.lu\go\DaDi>

	*/

}



posted @ 2022-12-02 22:24  大海一个人听  阅读(90)  评论(0编辑  收藏  举报