為什么會存在數組,數組主要用于解決什么問題
- 如果我有一堆的數據想要處理怎么存儲呢?
- 如果這些數據類型一致會不會好處理些呢?
- 難道我要一個類型聲明一個變量嗎?
No 那樣太Low,不夠優雅,成百上千個變量,那不干,我們只做有價值的事情,那么數組就來了
數組的定義
數組是一個長度固定,類型一致的數據類型,它常用于存儲一段具有相同類型的元素,數據類型可以是內置類型,也可以是自定義類型
1.長度固定
2.類型一致
3.連續存儲
數組的聲明與初始化
- 數組的聲明
// TODO var 是變量聲明的關鍵字
// TODO array 是數組的變量名稱符合變量命名規范即可
// TODO [5]int 中括號是數據聲明的標識符里面的數字是數組的長度可自定義,
// int表示數組的類型可自定義
var array [5]int
// TODO 數組聲明或初始化不賦值,默認是類型的零值
// TODO 不指定下標直接寫值即{10,20,30,40,50}這樣,編譯器會默認從下標0開始賦值
// TODO 指定小標直接寫值即{10,2:20,30,4:50}這樣,從下標0開始賦值,
// 未指定數據的使用其類型的默認值,碰到下標則將對應的值附上,然后繼續從當前下標繼續賦值
array := [5]int{10,20,30,40,50}
// TODO 省略數組的長度,使用三個點占位,讓編譯器自動計算,感覺不錯
// TODO 錯誤示例,只能在字面量的情況下使用
array := [...]int{10,20,30,40,50}
var array1 [...]int // 報錯
arrar2 := [...]int{} // 正確
-
存儲圖
image.png 聲明方式匯總對比
優勢 | var | 字面量 |
---|---|---|
是否可聲明 | 是 | 是 |
初始化值 | 類型零值 | 類型零值+指定下標值 |
指定下標賦值 | 否 | 是 |
指定長度 | 聲明的長度 | 聲明的長度 |
指定容量 | 同長度 | 同長度 |
數組的使用
// TODO 數組取值:直接使用小標取值 array[0],array[1]
// TODO 索引起始:數組的下標從0開始,最大索引 len(array) - 1(前提是數組長度大于1)
// 數組長度:使用len函數計算數據的長度 arrayLen := len(array)
array := [5]int{}
// TODO 什么是同類型的數組
// TODO 只有長度與類型一致的數組類型才是一致的,僅僅類型相同還不夠,因為長度是數組的一部分(長度+類型)
// TODO var聲明一個長度為4的整形數組[4]int
// TODO 字面量聲明并初始化一個長度為5的整形數組 [5]int
// TODO 將第二個數組,賦值給第一個數組
// TODO 請問打印結果是啥???
var array1 [4]string
array2 := [5]string{"red","blue","green"}
array1 = array2
fmt.Println(array2)
- 認識指針數組
// 聲明一個指針數組,使用類型的零值初始化
// 指針的默認值是nil,nil指針不能操作,因為引用的地址是空的沒有實際的值
var arrPointer1 [4]*string
// 輸出數組的值里面是4個nil
fmt.Println(arrPointer1)
// 使用字面量聲明并初始化
// new函數表示實例化一個類型的指針值
arrPointer2 := [3]*string{new(string),new(string),new(string)}
// 輸出數組的值里面是3個不同的地址
// 地址使用的是16進制表示即0x開始
fmt.Println(arrPointer2)
// *的使用
// 第一種 *用在類型前,表示的是指針類型
// 第二種 *用在變量前,表示取地址指向的值
// &的使用
// &用在變量前,表示取這個變量的地址
num := 10
var numPointer *int
numPointer = &num
fmt.Println(num,numPointer)
image.png
關于地址是16進制的簡單介紹
// 地址占用一個字節,一個字節是8bit,如下所示
0000 0001 0002 0003 0004 0005 0006 0007
// 上述方式寫起來太過繁瑣,很長不易理解,所以16進制顯示直觀
// 按照4個bit轉換成1個16進制數值,轉換結果如下
0x01234567
多維數組
- 聲明一個二維數組
第一種使用var關鍵字聲明 var array [4][2]int
不管是幾維數組其類型都是一樣的,上述表示4個長度為2的數組
使用數組字面量聲明
array := [4][2]int{{10,11},{20,21},{30,32},{40,41}}
image.png
在函數間傳遞數組
- 在函數間傳遞數值是一個開銷很大的操作,在函數間傳遞變量總是以值的方式傳遞,如果這是一個數組,意味著整個數組都被拷貝一份,不管數組多大,都會完整的復制,示例如下
func main(){
// 占用8M內存
var array [1e6]int
foo(array)
foo(array)
foo(array)
foo(array)
foo(array)
foo(array)
foo(array)
foo(array)
foo(array)
foo(array)
foo(array)
foo(array)
foo(array)
foo(array)
foo(array)
foo(array)
foo(array)
foo(array)
foo(array)
foo(array)
}
func foo(array [1e6]int){
fmt.Println("success")
}
課后小練習
- 手寫一個乘法表,要求可自定義乘法表的范圍,即要幾乘幾的可自定義
// @title 乘法表
// @description 2019/6/27 13:28 mick
// @param num int "乘法最大值"
// @return void
// TODO 檢測傳入的數據是否合法,默認只輸出大于等于1
// TODO 外層循環:第一層循環用來表示循環幾階乘法表
// TODO 內層循環:第二層循環表示計算這一階的每個數字
// TODO 打?。焊袷交敵?func multiplication(num int){
if num < 1{
fmt.Println(num)
}
for i:=1;i<=num;i++{
for j:=1;j<=i;j++{
fmt.Printf("%d * %d = %d ",j,i,i+j)
}
fmt.Println()
}
}