為什么會存在數(shù)組兰伤,數(shù)組主要用于解決什么問題
- 如果我有一堆的數(shù)據(jù)想要處理怎么存儲呢?
- 如果這些數(shù)據(jù)類型一致會不會好處理些呢?
- 難道我要一個類型聲明一個變量嗎?
No 那樣太Low摹迷,不夠優(yōu)雅,成百上千個變量郊供,那不干峡碉,我們只做有價值的事情,那么數(shù)組就來了
數(shù)組的定義
數(shù)組是一個長度固定颂碘,類型一致的數(shù)據(jù)類型异赫,它常用于存儲一段具有相同類型的元素,數(shù)據(jù)類型可以是內(nèi)置類型头岔,也可以是自定義類型
1.長度固定
2.類型一致
3.連續(xù)存儲
數(shù)組的聲明與初始化
- 數(shù)組的聲明
// TODO var 是變量聲明的關(guān)鍵字
// TODO array 是數(shù)組的變量名稱符合變量命名規(guī)范即可
// TODO [5]int 中括號是數(shù)據(jù)聲明的標(biāo)識符里面的數(shù)字是數(shù)組的長度可自定義塔拳,
// int表示數(shù)組的類型可自定義
var array [5]int
// TODO 數(shù)組聲明或初始化不賦值,默認(rèn)是類型的零值
// TODO 不指定下標(biāo)直接寫值即{10,20,30,40,50}這樣峡竣,編譯器會默認(rèn)從下標(biāo)0開始賦值
// TODO 指定小標(biāo)直接寫值即{10,2:20,30,4:50}這樣靠抑,從下標(biāo)0開始賦值,
// 未指定數(shù)據(jù)的使用其類型的默認(rèn)值适掰,碰到下標(biāo)則將對應(yīng)的值附上颂碧,然后繼續(xù)從當(dāng)前下標(biāo)繼續(xù)賦值
array := [5]int{10,20,30,40,50}
// TODO 省略數(shù)組的長度,使用三個點占位,讓編譯器自動計算类浪,感覺不錯
// TODO 錯誤示例载城,只能在字面量的情況下使用
array := [...]int{10,20,30,40,50}
var array1 [...]int // 報錯
arrar2 := [...]int{} // 正確
-
存儲圖
image.png 聲明方式匯總對比
優(yōu)勢 | var | 字面量 |
---|---|---|
是否可聲明 | 是 | 是 |
初始化值 | 類型零值 | 類型零值+指定下標(biāo)值 |
指定下標(biāo)賦值 | 否 | 是 |
指定長度 | 聲明的長度 | 聲明的長度 |
指定容量 | 同長度 | 同長度 |
數(shù)組的使用
// TODO 數(shù)組取值:直接使用小標(biāo)取值 array[0],array[1]
// TODO 索引起始:數(shù)組的下標(biāo)從0開始,最大索引 len(array) - 1(前提是數(shù)組長度大于1)
// 數(shù)組長度:使用len函數(shù)計算數(shù)據(jù)的長度 arrayLen := len(array)
array := [5]int{}
// TODO 什么是同類型的數(shù)組
// TODO 只有長度與類型一致的數(shù)組類型才是一致的费就,僅僅類型相同還不夠诉瓦,因為長度是數(shù)組的一部分(長度+類型)
// TODO var聲明一個長度為4的整形數(shù)組[4]int
// TODO 字面量聲明并初始化一個長度為5的整形數(shù)組 [5]int
// TODO 將第二個數(shù)組,賦值給第一個數(shù)組
// TODO 請問打印結(jié)果是啥力细?睬澡??
var array1 [4]string
array2 := [5]string{"red","blue","green"}
array1 = array2
fmt.Println(array2)
- 認(rèn)識指針數(shù)組
// 聲明一個指針數(shù)組,使用類型的零值初始化
// 指針的默認(rèn)值是nil眠蚂,nil指針不能操作煞聪,因為引用的地址是空的沒有實際的值
var arrPointer1 [4]*string
// 輸出數(shù)組的值里面是4個nil
fmt.Println(arrPointer1)
// 使用字面量聲明并初始化
// new函數(shù)表示實例化一個類型的指針值
arrPointer2 := [3]*string{new(string),new(string),new(string)}
// 輸出數(shù)組的值里面是3個不同的地址
// 地址使用的是16進制表示即0x開始
fmt.Println(arrPointer2)
// *的使用
// 第一種 *用在類型前,表示的是指針類型
// 第二種 *用在變量前逝慧,表示取地址指向的值
// &的使用
// &用在變量前昔脯,表示取這個變量的地址
num := 10
var numPointer *int
numPointer = &num
fmt.Println(num,numPointer)
image.png
關(guān)于地址是16進制的簡單介紹
// 地址占用一個字節(jié),一個字節(jié)是8bit,如下所示
0000 0001 0002 0003 0004 0005 0006 0007
// 上述方式寫起來太過繁瑣馋艺,很長不易理解栅干,所以16進制顯示直觀
// 按照4個bit轉(zhuǎn)換成1個16進制數(shù)值,轉(zhuǎn)換結(jié)果如下
0x01234567
多維數(shù)組
- 聲明一個二維數(shù)組
第一種使用var關(guān)鍵字聲明 var array [4][2]int
不管是幾維數(shù)組其類型都是一樣的捐祠,上述表示4個長度為2的數(shù)組
使用數(shù)組字面量聲明
array := [4][2]int{{10,11},{20,21},{30,32},{40,41}}
image.png
在函數(shù)間傳遞數(shù)組
- 在函數(shù)間傳遞數(shù)值是一個開銷很大的操作碱鳞,在函數(shù)間傳遞變量總是以值的方式傳遞,如果這是一個數(shù)組踱蛀,意味著整個數(shù)組都被拷貝一份窿给,不管數(shù)組多大,都會完整的復(fù)制率拒,示例如下
func main(){
// 占用8M內(nèi)存
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")
}
課后小練習(xí)
- 手寫一個乘法表崩泡,要求可自定義乘法表的范圍,即要幾乘幾的可自定義
// @title 乘法表
// @description 2019/6/27 13:28 mick
// @param num int "乘法最大值"
// @return void
// TODO 檢測傳入的數(shù)據(jù)是否合法猬膨,默認(rèn)只輸出大于等于1
// TODO 外層循環(huán):第一層循環(huán)用來表示循環(huán)幾階乘法表
// TODO 內(nèi)層循環(huán):第二層循環(huán)表示計算這一階的每個數(shù)字
// 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()
}
}