GO语言学习(三):指针,切片,map映射

1.指针

func main() {
    var a int = 10
    //每个变量有2层含义,变量的内存,变量的地址
    fmt.Printf("a =%d\n", a)
    fmt.Printf("&a =%v\n", &a)

    //保存某个变量的地址,需要指针类型,
    //*int保存int的地址,**int保存*int的地址
    var p *int
    //声明(定义),定义只是特殊的声明
    p = &a //指针变量指向谁,就把谁的地址赋值给指针变量
    fmt.Printf("p =%v, &a =%v\n", p, &a)

    *p =666 //*p操作的不是内存,是p所指向的内存(就是a)
    fmt.Printf("p =%v, a =%v\n", *p, a)  //666  666
}

go语言虽然保留指针,但与其它编程语言不同的是
1)默认值是nil,没有NULL常量
2)操作符"&“是取变量地址,”*“通过指针访问目标对象
3)不支持指针运算,不支持 “->” 运算符,直接用”."访问目标成员
go语言指针定义

func main() {
   var p *int
   p = new(int) //new一个新空间,go语言不需要释放
   q := new(int)
}

指针交换a,b值

func swap(a, b *int){
    *a, *b = *b, *a
    fmt.Printf("swap: a = %d, b =%d\n", a, b)
}
func main() {
    a, b := 10, 20

    //通过一个函数交换a和b的内容
    swap(&a, &b) //变量本身传递,值传递(站在变量角度)
    fmt.Printf("main: a = %d, b =%d\n", a, b)
}

一维数组赋值

func main() {
    //声明定义同时赋值,叫初始化
    //1.全部初始化
    var a [5]int = [5]int{1, 2, 3, 4, 5}
    fmt.Println("a =", a)

    b := [5]int{1,2,3,4,5}
    fmt.Println("b =", b)

    //部分初始化,没有初始化的元素自动赋值为0
    c := [5]int{1,2,3}
    fmt.Println("c =", c)

    //指定某个元素初始化
    d := [5]int{2:10, 4:10}
    fmt.Println("d =", d)
}

二维数组赋值

func main() {

    //二维数组初始化,可部分初始化,没有初始化的值为0
    e := [3][4]int{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 20, 32, 53}}
    fmt.Println(e)

    //部分初始化,只对第二行元素赋值
    f := [3][4]int{1: {5, 6, 7, 8}}
    fmt.Println(f)
}

两数组间支持比较和赋值,只支持 == 或 !=,比较是不是每个元素都一样,两个数组比较,数组类型要一样。
2.随机数生成与冒泡排序

func main() {
   //设置种子,只需一次
   //如果种子参数一样,每次允许程序产生的随机数都一样
   //解决办法,用时间
   rand.Seed(time.Now().UnixNano()) //以当前系统时间作为种子参数

   var a [10]int
   n := len(a)
   for i:=0; i < n; i++{
       //产生随机数
       //fmt.Println("rand = ", rand.Int()) //随机很大的数
       a[i]= rand.Intn(100)
       fmt.Printf("%d, ", a[i]) //Intn函数,限定随机数生成的范围
   }
   fmt.Printf("\n")

   //冒泡排序,挨着的2个元素比较,升序(大于交换)
   for i :=0; i<n-1; i++{
       for j :=0;j<n-1-i;j++{
           if a[j]>a[j+1]{
               a[j], a[j+1] = a[j+1], a[j]
           }
       }
   }
   fmt.Println("有序后:")
    for i:=0; i < n; i++{
        fmt.Printf("%d, ", a[i]) //Intn函数,限定随机数生成的范围
    }
   }

数组做函数参数,它是值传递。实参数组的每个元素给行参数组拷贝一份。如果需要用函数改变数组的值,用指针。

//数组做函数参数,它是值传递
//实参数组的每个元素给行参数组拷贝一份
func  modify(p *[5]int)  {
    (*p)[0] = 666
    fmt.Println("*a = ", *p)
}
func main() {

    a :=[5]int{1,2,3,4,5}
    modify(&a)
    fmt.Println(a)
}

2.切片

func main() {
   array := [...]int {10, 20, 30, 0, 0}
   s := array[0:3:5]
    //[low:high:max]
    //low下标的起点
    //high下标的终点(不包括此下标),左闭右开
    //len=high-low
    //cap = max - low 容量
    fmt.Println("s = ", s)
    fmt.Println("len(s) = ", len(s))  //长度=3-0
    fmt.Println("cap(s) = ", cap(s))  //容量=5-0
   
   //切片与数组的区别
   //数组[]里面的长度是固定的一个常量,数组不能修改长度,len和cap永远固定
    a := [5]int{}
    fmt.Printf("len = %d, cap = %d\n", len(a), cap(a))

    //切片,[]里面为空,或者为...切片的长度或容量可以不固定
    s := []int{}
    fmt.Printf("len = %d, cap = %d\n", len(s), cap(s))
    
    s = append(s, 11)  //给切片末尾增加一个成员
}

切片的创建

//自动推导类型,同时初始化
   s1 := []int{1, 2, 3, 4}
   fmt.Println("s1 =", s1)

   //借助make函数,格式make(切片类型, 长度, 容量)
   s2 := make([]int, 5, 10)
   fmt.Printf("len = %d, cap = %d\n", len(s2), cap(s2))
   //容量可缺省,缺省时容量等于长度

切片操作

array := []int{0,1,2,3,4,5,6,7,8,9}
   s1 := array[:] //[0:len(array):len(array)],不指定时容量和长度一样
   fmt.Println(s1)
   fmt.Printf("len = %d, cap = %d\n", len(s1), cap(s1))

   //操作某个元素,和数组操作方式一样
   data := array[0]
   fmt.Println(data)
   s2 := array[3:6:7]
   fmt.Printf("len = %d, cap = %d\n", len(s2), cap(s2))
   s3 := array[:6]  //从0开始,取6个元素,容量为10
   fmt.Printf("len = %d, cap = %d\n", len(s3), cap(s3))
   s4 := array[3:]  //从下标为3开始到结尾
   fmt.Println(s4)  //取7个元素,容量为7
   fmt.Printf("len = %d, cap = %d\n", len(s4), cap(s4))

切片与底层数组的关系

array := []int{0,1,2,3,4,5,6,7,8,9}
   //新切片修改后原数组也发生改变
   s1 := array[2:5]
   s1[1] = 666
   fmt.Println(s1)
   fmt.Println(array)
   fmt.Printf("len = %d, cap = %d\n", len(s1), cap(s1))

   //另外新切片,切片的切片
   s2 := s1[2:7]
   s2[2] = 777
   fmt.Println(s2)
    fmt.Println(array)

使用append函数,如果超过原来的容量,通常以2倍容量扩容

func test(m map[int]string){
    delete(m,2)
}
func main() {
     var ml map[int]string
     fmt.Println("ml =", ml)
     //队友map只有len,没有cap
     fmt.Println("len =",len(ml))

     //可以通过make创建
     m2 := make(map[int]string)
    fmt.Println("ml =", m2)
    fmt.Println("len =", len(m2))

     //可通过make创建指定长度,只是指定了容量,长度由map内数据决定
    m3 := make(map[int]string,10)
    m3[1] = "mike"
    m3[20] = "c++"
    m3[50] = "go"
    fmt.Println("ml =", m3)
    fmt.Println("len =", len(m3))

    //初始化,且键值唯一
    m4 := map[int]string{1: "mike", 2: "go", 3: "c++"}
    fmt.Println("m4 =", m4)

    //遍历
    for key, value := range m4 {
        fmt.Printf("%d ====> %s\n", key, value)
    }

    //如何判断一个key是否存在
    //第一个返回值为key所对应的value,第二个返回值为key是否存在的条件,存在ok为true
    value, ok := m4[1]
    if ok == true{
        fmt.Println("m[1] =",value)
    }else{
        fmt.Printf("key不存在\n")
    }

    //删除某个值
    delete(m4, 1)  //删除key为1的内容
    fmt.Println(m4)

    //将删除操作写在函数内部
    test(m4) //在函数内部删除某个key
    fmt.Println("m4 = ", m4)
}

2.定义结构体

//结构体类型
//有时我们需要将不同数据类型的数组合成一个有机的整体

//定义一个结构体类型
type Student struct{
    id int
    name string
    sex byte
    age int
    addr string
}

func main() {
    //顺序初始化,每个成员必须初始化
    var s1 Student = Student{1,"mike", 'm', 18, "bj"}
    fmt.Println("s1 =", s1)

    //指定成员初始化,没有初始化
    s2 := Student{name: "mike", addr: "bj"}
    fmt.Println("s2 =", s2)

    //初始化指针变量
    var s3 *Student = &Student{1,"mike", 'm', 18, "bj"}
    fmt.Println("s3 =", *s3)
    s4 := &Student{name: "mike", addr: "bj"}
    fmt.Println("s4 =", *s4)
}

结构体指针变量

 //1.指针有合法指向后,才操作成员
   //先定义一个普通结构体变量
   var s Student
   //再定义一个指针变量,保存s的地址
   var p1 *Student
   p1 = &s

   //通过指针操作成员,p1.id和(*p).id完全等价,只能用.运算符
   p1.id = 1
   p1.name = "mike"
   p1.sex = 'm'
   p1.age = 18
   p1.addr = "bj"
   fmt.Println("p1 = ",p1)

   //2.通过new申请一个结构体
   p2 :=new(Student)
    p2.id = 1
    (*p2).name = "mike"
    p2.sex = 'm'
    p2.age = 18
    p2.addr = "bj"
    fmt.Println("p2 = ",p2)

如果想使用别的包的函数,结构体类型,结构体成员
函数名,类型名,结构体成员变量名,首字母必须大写,可见
如果首字母是小写,只能在同一个包里使用

猜你喜欢

转载自blog.csdn.net/weixin_43011810/article/details/84718319