上篇文章思考题
结果
0
可接收错误
strNum := "123.hello" floatNum, er := strconv.ParseFloat(strNum,64) fmt.Println(floatNum,er)
结果
0 strconv.ParseFloat: parsing "123.hello": invalid syntax
介绍
- 数组是值类型,默认情况下作为参数传递给函数时会拷贝,不影响原数组。可通过形参为数组指针,实参为数组地址来修改。
- 声明时,默认值为零值(0、""、false等)
- 声明固定长度,不能动态变化
- 元素的数据类型要相同
- 占用内存连续
声明
var variable_name [SIZE]variable_type
代码
//声明数组 var arr [3]int
声明并初始化
var variable_name [SIZE]variable_type = [SIZE]variable_type{value1,value2...}
var variable_name = [SIZE]variable_type{value1,value2...}
variable_name := [...]variable_type{value1,value2...}
variable_name := [...]variable_type{index1:value1,index2:value2}
注意:size可以使用...省略,推导
//初始化数组 var arr1 [3]int = [3]int{1,2,3} var arr2 = [3]int{1:4,0:5,2:6} arr3 := [...]int{7,8,9} arr4 := [5]int{1:3,3:5}
遍历
for循环,下标
n1 := len(arr1) for i:=0;i<n1;i++{ fmt.Print(arr1[i]," ") }
for range
for key,value := range
for _,n := range arr3{ fmt.Print(n," ") }
_是匿名变量,可以看之前的文章了解变量和常量。
内存
src->cmd->compile->internal->types->type.go
// Array contains Type fields specific to array types. type Array struct { Elem *Type // element type Bound int64 // number of elements; <0 if unknown yet }
// NewArray returns a new fixed-length array Type. func NewArray(elem *Type, bound int64) *Type { if bound < 0 { Fatalf("NewArray: invalid bound %v", bound) } t := New(TARRAY) t.Extra = &Array{Elem: elem, Bound: bound} t.SetNotInHeap(elem.NotInHeap()) return t }
TARRAY是Array指针,以arr4为例,Go会生成一个连续空间,将第一个的地址给arr4第一个值*Type,长度给arr4的第二个值Bound。
fmt.Printf("arr4:%v &arr4:%p &arr4[0]:%v &arr4[1]:%v\n",arr4, &arr4,&arr4[0], &arr4[1])
结果
arr4:[0 3 0 5 0] &arr4:0xc00000c450 &arr4[0]:0xc00000c450 &arr4[1]:0xc00000c458
以arr4为例,数组地址和第一个元素的地址一样,后面相差的为元素所占字节数,这里是int,所以差8。
数组作为参数
值传递
值传递,返回数组最大值下标
// 求数组最大值及下标 func getMax(arr [5]int)(int,int){ maxValue := arr[0] index := 0 for i,v := range arr{ if v > maxValue { maxValue = v index = i } } return index, maxValue }
注意:数组的长度也是数组类型的一部分,[2]int和[3]int是不一样的类型。如果你发现有人的代码写的[]int,可以传递任意长度的“数组”,那么,他说错了,他说的是切片而不是数组。
调用代码
index,value := getMax(arr4)
引用传递
//原地反转数组 func reverseArr(arr *[10]int){ i:=0 j:=len(*arr) - 1 for{ if i>=j{ break } (*arr)[i],(*arr)[j] = (*arr)[j],(*arr)[i] i++ j-- } }
调用代码
arr6 := [10]int{1,4,7,-9,99,2,5,78,22,33} reverseArr(&arr6)
多维数组
以二维数组为例
二维数组:一维数组,每个元素是一维数组(首元素)地址,数组长度为列数
声明并初始化
var arr8 = [...][2]int{{1,2},{2,3}} arr9 := [1][2]int{{5,6}} fmt.Println("arr7 arr8 arr9",arr7,arr8,arr9)
遍历
for
for i:=0;i<len(arr8);i++{ for j:=0;j<len(arr8[0]);j++{ fmt.Print(arr8[i][j]," ") } fmt.Println() }
for range
for _,row := range arr8{ for _,val:= range row{ fmt.Print(val," ") } fmt.Println() }
内存
大概应该是这样,是一维数组指针,没有记录Bound,因为一位数组有记录元素个数,就不必再记录一次了。由于不能.出Bound来,另外,也是刚入门Go,没有仔细阅读源代码,有大佬知道的话可以下方评论,或者等某天如果我发现错了,再回来改。
全部代码
package main import "fmt" // 创建26大小数组,存放A-Z func alpha(){ alpha := [26]byte{} var A byte = 'A' for i :=0;i<26;i++{ alpha[i] = A + byte(i) } fmt.Printf("%c\n",alpha) } // 求数组最大值及下标 func getMax(arr [5]int)(int,int){ maxValue := arr[0] index := 0 for i,v := range arr{ if v > maxValue { maxValue = v index = i } } return index, maxValue } //原地反转数组 func reverseArr(arr *[10]int){ i:=0 j:=len(*arr) - 1 for{ if i>=j{ break } (*arr)[i],(*arr)[j] = (*arr)[j],(*arr)[i] i++ j-- } } func main() { //------------------声明数组------------------ var arr [3]int //-----------------初始化数组----------------- var arr1 [3]int = [3]int{1,2,3} var arr2 = [3]int{1:4,0:5,2:6} arr3 := [...]int{7,8,9} arr4 := [5]int{1:3,3:5} fmt.Println("arr arr1 arr2 arr3 arr4:",arr,arr1,arr2,arr3,arr4) //-------------------遍历数组---------------- n1 := len(arr1) fmt.Print("数组arr1:") for i:=0;i<n1;i++{ fmt.Print(arr1[i]," ") } fmt.Println() fmt.Print("数组arr3:") for _,n := range arr3{ fmt.Print(n," ") } fmt.Println() //--------------------内存---------------------- fmt.Printf("arr4:%v &arr4:%p &arr4[0]:%v &arr4[1]:%v\n",arr4, &arr4,&arr4[0], &arr4[1]) fmt.Println(&arr4[2]) //-----------------数组做参数---------------------- index,value := getMax(arr4) fmt.Println("arr4最大值的下标和值:",index,value) arr6 := [10]int{1,4,7,-9,99,2,5,78,22,33} reverseArr(&arr6) fmt.Println(arr6) //----------------------------二维数组---------------------------------- //------------声明--------------- var arr7 [2][3]int //-----------声明并初始化--------- var arr8 = [...][2]int{{1,2},{2,3}} arr9 := [1][2]int{{5,6}} fmt.Println("arr7 arr8 arr9",arr7,arr8,arr9) //----------遍历----------------- fmt.Println("arr8:") for i:=0;i<len(arr8);i++{ for j:=0;j<len(arr8[0]);j++{ fmt.Print(arr8[i][j]," ") } fmt.Println() } fmt.Println("arr8:") for _,row := range arr8{ for _,val:= range row{ fmt.Print(val," ") } fmt.Println() } //------内存---------- fmt.Printf("&arr8:%p &arr8[0]:%p &arr8[1]:%p &arr8[0][0]:%v &arr8[1][0]:%v",&arr8, &arr8[0], &arr8[1], &arr8[0][0], &arr8[1][0]) }
结果截图
注意
- 数组长度也是数组类型的一部分,所以即使元素类型相同,长度不同也是不一样的类型。
- 如果两个数组大小相同,元素可以使用==比较,那么,两个数组也可以使用==判断是否相等,当所有元素都对应相等时,两个数组相等。
参考
Go-1.16.3源代码
思考题
有函数getMax
// 求数组最大值及下标 func getMax(arr [5]int)(int,int){ maxValue := arr[0] index := 0 for i,v := range arr{ if v > maxValue { maxValue = v index = i } } return index, maxValue }
以下调用,结果如何?
nums := [6]int{7,4,2,6,8,3} index,max := getMax(nums) fmt.Println(max)
答案见下一篇文章:Go-切片类型详解(遍历、内存、追加、插入、删除等)
更多Go相关内容:Go-Golang学习总结笔记
有问题请下方评论,转载请注明出处,并附有原文链接,谢谢!如有侵权,请及时联系。