您的位置:首页 > 编程语言 > Go语言

第4课 Go数组Array和切片Slice

2016-07-28 00:27 836 查看
数组array

package main

import (
"fmt"
)

func main() {
/*
数组Array
-定义数组的格式: var<varName>
<type> ,n>=0
-数组长度也是类型的一部分,因此具有不同长度的数组为不同类型
-注意区分指向数组的指针和指针数组
-数组在Go中为值类型
-数组之间可以使用==或者!=进行比较,但不可以使用<或者>
-可以使用new来创建数组,此方法返回一个指向数组的指针
-Go支持多维数组

-Go语言版冒泡排序
*/
var a [2]int
var b [1]int
//注意a和b是两种数据类型!
//b = a此操作不可行
fmt.Println(a)
fmt.Println(b)
//输出结果是
//  [0 0]
//  [0]
fmt.Println("----")

c := [2]int{1, 1} //初始化方法1
d := [2]int{1}    //初始化方法2
fmt.Println(c)
fmt.Println(d)
//会自动把d的第二个元素赋0值
fmt.Println("----")

e := [20]int{19: 3} //初始化方法3
fmt.Println(e)
fmt.Println("----")

f := [...]int{0: 1, 1: 2, 2: 3} //初始化方法4
fmt.Println(f)
fmt.Println("----")

g := [...]int{19: 1}
fmt.Println(g) //初始化方法5
fmt.Println("----")
}


指向数组的指针和指针数组,多维数组

package main

import (
"fmt"
)

func main() {
a := [...]int{99: 1}
var p *[100]int = &a //创建了指向元素数为100的数组的指针p并且赋值以a的地址
fmt.Println(p)
//p为指向数组的指针

x, y := 1, 2
b := [...]*int{&x, &y} //创建了一个数组b,数组元素为指针
fmt.Println(b)
fmt.Println("-----")

c := [2]int{1, 2}
d := [2]int{1, 2}
fmt.Println(c == d) //输出为true

/*
e := [2]int{1, 2}
f := [1]int{1}
fmt.Println(e==f) //输出为true
不可以进行比较,会有编译错误
*/
e := [10]int{}
e[1] = 2
fmt.Println(e)
f := new([10]int)
f[1] = 2
fmt.Println(f)
//不管是指向数组的指针,或者是数组指针都可以使用f[1]=2这种行形式来操作数组
fmt.Println("-----")

g := [...][3]int{ //顶级的数组可以用...来自动计算,非顶级的中括号内不可以用[...]
{1, 1, 1},
{2, 2, 2}}
fmt.Println(g)
//多维数组,同样也可以像操作一维数组一样对待多维数组
fmt.Println("-----")
}


Go语言版冒泡排序如下:

package main

import (
"fmt"
)

func main() {
a := [...]int{5, 2, 6, 3, 9}
fmt.Println(a)

num := len(a)
for i := 0; i < num; i++ {
for j := i + 1; j < num; j++ {
if a[i] < a[j] {
temp := a[i]
a[i] = a[j]
a[j] = temp
}
}
}
fmt.Println(a)
}


切片



package main

import (
"fmt"
)

func main() {
/*
切片Slice
-其本身不是数组,它指向底层的数组
-作为变长数组的替代方案,可以关联底层数组的局部或全部
-为引用类型
-可以直接创建或从底层数组获取生成
-使用len()获取元素个数,cap()获取容量
一般使用make()创建
-如果多个slice指向相同底层数组,其中一个的值改变会影响全部

-make([]T,len,cap)
-其中cap可以省略,则和len的值相同
-len表示存数的元素个数,cap表示容量
*/

var s1 []int    //这就完成了创建切片
fmt.Println(s1) //输出[] 一个元素也没有

a := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9}
fmt.Println(a)  //打印出1到9和一个0
s1 = a[5:10]    //s2为切片,a[5,6,7,8,9] 可见包括索引为5但是不包括10
fmt.Println(s1) //输出[6 7 8 9 0]

s2 := a[5:len(a)] //从索引为5取到尾部
fmt.Println(s2)

s3 := a[:5] //取前五个元素
fmt.Println(s3)

s4 := a[5:] //从索引为5取到尾部
fmt.Println(s4)
fmt.Println("-----")

s5 := make([]int, 3, 10) //另外一种声明方法,保存int,目前包含多少个元素,容量
//当切片中元素超过容量时,容量增加一倍,由10变成20,再变成40
fmt.Println(len(s5), cap(s5))
//也可以省略那个10,这时候会默认认为容量=元素数=3
fmt.Println("-----")

/*
Reslice
-Reslice时索引以被slice的切片为准
=索引不可以超过被slice的切片的容量cap()值
-索引越界不会导致底层数组的重新分配而是引发错误

Append
-可以在slice尾部追加元素
-可以将一个slice追加在另一个slice尾部
-如果最终长度未超过追加到slice的容量则返回原始slice
-如果超过追加到的slice的容量则将重新分配并拷贝原始数据

Copy
*/
s6 := make([]int, 3, 6)
fmt.Printf("%p\n", s6)
s6 = append(s6, 1, 2, 3) //将1,2,3添加到s6尾部,并且返回一个新的指针赋给了s6
fmt.Printf("%v %p\n", s6, s6)
//未超过切片容量,地址不变化
s6 = append(s6, 1, 2, 3)
fmt.Printf("%v %p\n", s6, s6)
//超过切片容量,重新分配,地址变化
fmt.Println("-----")

s7 := []int{1, 2, 3, 4, 5, 6}
s8 := []int{7, 8, 9}
copy(s7, s8)
fmt.Println(s7)
//s7变成了7,8,9,4,5,6
//s8还是 7,8,9
//把短的拷贝给多的,只影响相应的位数
//但是如果反过来呢?
s9 := []int{1, 2, 3, 4, 5, 6}
s10 := []int{7, 8, 9}
copy(s10, s9)
fmt.Println(s10)
//s10变成了123
//s9还是1,2,3,4,5,6
//把多的拷贝给短的,也只影响相应的位数
copy(s10, s9[2:5]) //如果想拷贝一部分(拷贝s9[2,3,4])
fmt.Println(s10)
}


运行结果如下:

[]

[1 2 3 4 5 6 7 8 9 0]

[6 7 8 9 0]

[6 7 8 9 0]

[1 2 3 4 5]

[6 7 8 9 0]

—–

3 10

—–

0xc04203fd70

[0 0 0 1 2 3] 0xc04203fd70

[0 0 0 1 2 3 1 2 3] 0xc04203a1e0

—–

[7 8 9 4 5 6]

[1 2 3]

[3 4 5]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: