go - 学习笔记 -3


指针类型

package main

func main() {
	/*
		//(1) 获取地址: &变量
		var x = 10 // x 为整型变量
		fmt.Printf("赋值前x的对应地址:%p\n", &x)
		x = 100
		fmt.Printf("赋值后x的对应地址:%p\n", &x)

		//(2) 地址赋值:引出了指针类型  *int *string *bool *float
		var p *int //p 是一个整形指针类型
		p = &x     // var p = &x
		fmt.Printf("p的对应地址:%p\n", p)

		// (3) 取值操作: 使用 *指针变量 将具体存放的值取出/修改
		fmt.Printf("取值:%d\n", *p)
		fmt.Println(reflect.TypeOf(*p))

		*p = 10
		fmt.Printf("取值:%d\n", *p)
		fmt.Println(x)
	*/
	/*
		//思考
		// 值拷贝
		//var a = 1
		//var b = a
		//b = 100
		//fmt.Printf("a的值为:%d\ta的地址为:%#v\n", a, &a)
		//fmt.Printf("b的值为:%d\tb的地址为:%#v\n", b, &b)


		// 地址赋值
		var a = 1
		var b = &a // b获取到a的指针地址,便于后续*b获取/修改a指针内存储的值
		var c = b // 同理,c存储和b一样的a的指针地址

		*b = 100
		fmt.Printf("a的值为:%d\ta的地址为:%#v\n", a, &a)
		fmt.Printf("b的值为:%d\tb的地址为:%#v\n", *b, &b)
		fmt.Printf("c的值为:%d\tc的地址为:%#v\n", *c, &c)
	*/
	/*
		// 指针应用 1
		var x = 100
		var y = x       // 值拷贝 y = x = 100
		var z = &x      // z存放x的指针地址
		x = 20          // x = 20 = *z; y = 100
		fmt.Println(x)  // 20
		fmt.Println(y)  // 100
		fmt.Println(*z) // 20
		*z = 30
		fmt.Println(x) // 30
	*/
	/*
		// 指针应用 2
		var x = 10
		var y = &x // y取值为x的指针地址,y是一个指针变量,属于*int
		var z = *y // z取值为y的指针地址,z是一个整形,属于int
		x = 20
		fmt.Println(x)  // 20
		fmt.Println(*y) // 20
		fmt.Println(z)  // 10
	*/
	/*
		// 指针应用 3
		var a = 100
		var b = &a // b取a的指针地址,*int类型
		var c = &b // c取b的指针地址,**int类型
		**c = 200
		fmt.Println(a) // 200
	*/

	/*
		// 指针应用 4
		p1 := 1          // p1 = 1,int类型
		p2 := &p1        // p2 = p1的指针地址,*int类型
		*p2++            // *p2 = 1 +1 = 2 = p1
		fmt.Println(p1)  // 2
		fmt.Println(*p2) // 2
	*/

	// 指针应用 5

}

new函数

package main

import "fmt"

func main() {

	// 基本数据类型,即:整型、浮点型、布尔型、字符串、数组、结构体等,泛属于值类型
	// 值类型特点:当声明未赋值之前,存在一个默认,即:zero value

	// 指针类型属于引用类型,存储的是值的地址,包括后续的切片、man、channel都属于引用类型
	// 引用类型,当声明未赋值之前,是没有开启默认空间的,即:没有默认值
	var p *int
	p = new(int) // new函数就是在创建前,先在内存里开辟一块空间,填入指定类型的一个默认值
	fmt.Printf("p的对应:%d\n", *p)
	*p = 10
	fmt.Println(*p)
	fmt.Println(p)
}

数组的声明并赋值

package main

import "fmt"

func main() {
	/*
		// 数组的特点:长度不可变,一旦创建,长度不能伸缩
		// 1、数组声明
		// 数组必须限制长度
		var arr [3]int
		fmt.Println(arr) // 默认值为:[0 0 0]

		var names [3]string
		fmt.Println(names) // 默认值为:["" "" ""]

		// 2、赋值
		arr[0] = 10
		arr[1] = 20
		arr[2] = 30
		fmt.Println(arr) // 默认值为:[10 20 30]

		names[0] = "lin"
		names[1] = "lin2"
		names[2] = "lin3"
		fmt.Println(names) // 默认值为:[lin lin2 lin3]

		// 3、索引
		fmt.Println(arr[0]) // 10
		fmt.Println(arr[1]) // 20
		fmt.Println(arr[2]) // 30

		fmt.Println(names[0]) // lin
		fmt.Println(names[1]) // lin2
		fmt.Println(names[2]) // lin3
	*/
	/*
		// 4、数组的声明并赋值
		var names = [3]string{"yuan", "rain", "alvin"}
		fmt.Println(names)
		var age = [3]int{11, 22, 33}
		fmt.Println(age)
	*/
	/*
		// 5、省略长度赋值
		var names = [...]string{"yuan", "rain", "alvin"}
		fmt.Println(names)
	*/

	// 6、索引赋值
	var names = [3]string{0: "yuan", 1: "rain", 2: "alvin"}
	fmt.Println(names)

	// go len函数:计算容器数据的长度
	fmt.Println(len(names))
	fmt.Println(len("ali"))
}

数组的操作

package main

import (
	"fmt"
	"reflect"
)

func main() {

	var names = [3]string{"yuan", "rain", "alvin"}
	// 1、索引操作
	fmt.Println(names[0]) // 索引取值
	names[2] = "Alivin"   // 索引修改
	fmt.Println(names[2])

	// 2、切片操作  数组[start索引:end索引]
	var arr = [5]int{11, 12, 13, 14, 15}
	s := arr[1:3]
	fmt.Println(s, reflect.TypeOf(s)) // [12 13] []int

	s1 := arr[1:]
	fmt.Println(s1, reflect.TypeOf(s1)) // [12 13 14 15] []int

	// 3、遍历数组
	var arr2 = [5]int{21, 22, 23, 24, 25}
	for i := 0; i < len(arr2); i++ {
		fmt.Println(i, arr2[i])
	}

	// range循环
	for i, v := range arr2 {
		fmt.Println(i, v)
	}

}

切片的底层存储

package main

import "fmt"

func main() {

	/*
		// 构建切片方式一:通过数组切片操作,获得切片对象
		var arr = [3]string{"rain", "erric", "alvin"}
		fmt.Println(arr, reflect.TypeOf(arr)) // [rain erric alvin] [3]string
		s1 := arr[0:2]
		fmt.Println(s1, reflect.TypeOf(s1)) //[rain erric] []string
		s2 := arr[1:]                       // 切片包含:起始地址 长度 容量
		fmt.Println(s2, reflect.TypeOf(s2)) //[erric alvin] []string
	*/
	/*
		var a = [5]int{1, 2, 3, 4, 5}
		var slice1 = a[:]
		var slice2 = a[:2]
		fmt.Println(len(slice1), cap(slice1))       // 长度:5		容量:5
		fmt.Println(len(slice2), cap(slice2))       // 长度:2		容量:5
		fmt.Println(slice1, reflect.TypeOf(slice1)) // [1 2 3 4 5] []int
		newSlice := slice1[1:3]
		fmt.Println(len(newSlice), cap(newSlice))   // 长度:2		容量:4
		fmt.Println(newSlice, reflect.TypeOf(newSlice)) // [2 3] []int

		newSlice[1] = 1000
		fmt.Println(a)
		fmt.Println(slice1)
		fmt.Println(slice2)
	*/

	// 2、 直接声明切片
	//var arr = [5]int{11,12,13,14,15}
	//s := arr[:]

	var s = []int{11, 12, 13, 14, 15}
	s1 := s[1:4]                      // [12,13,14]
	fmt.Println(s1, len(s1), cap(s1)) // 长度:3		容量:4
	s2 := s[3:]                       // [14,15]
	fmt.Println(s2, len(s2), cap(s2)) // 长度:2		容量:2
	s3 := s1[1:2]                     // [13]
	fmt.Println(s3, len(s3), cap(s3)) // 长度:1		容量:3

}

切片练习题

package main

import "fmt"

func main() {

	// 练习题 1
	s1 := []int{1, 2, 3} // s1 = [1,2,3]
	s2 := s1[1:]         // s2 = [2,3]
	s2[1] = 4            // s2[1] = 3 -> 4 = [2,4]
	fmt.Println(s1)      // [1,2,4]

	// 练习题 2
	var a = []int{1, 2, 3} // a = [1,2,3]
	b := a                 // b = a = [1,2,3]
	a[0] = 100             // a[0] = 1 -> 100; 此时a = [100,2,3] = b
	fmt.Println(b)
}

make函数

package main

import "fmt"

func main() {
	/*
		// var s = []int{1,2,3,4,5} // 这里声明并初始化了

		//var s []int  // 这样只声明,没有赋值,没有默认值
		//s[0] = 1 // 因为没有默认值,所以没有索引,会报错

		// 初始化创建空间
		var s = make([]int, 5, 10) // 5为长度,10为容量,便于后续扩展;创建后,前面5个总量内会存储默认的int格式默认值0,后面的因为没有默认值,无法打印显示
		fmt.Println(s, len(s), cap(s))
		s[0] = 100
		fmt.Println(s)
	*/

	// 练习题 1
	a := make([]int, 5) // a = [0 0 0 0 0]
	b := a[0:3]         // b = [0 0 0]
	a[0] = 100          // a[0] = 0 -> 100
	fmt.Println(a)      // [100 0 0 0 0]
	fmt.Println(b)      // [100 0 0]
}

append函数

package main

import "fmt"

func main() {

	//var s []int
	//
	//s1 := append(s, 1)
	//fmt.Println(s1)
	//
	//s2 := append(s1, 2, 3, 4, 5)
	//fmt.Println(s2)
	//
	//var t = []int{6, 7, 8}
	//s3 := append(s2, t...)
	//fmt.Println(s3)

	var s4 = make([]int, 3, 10)
	s5 := append(s4, 100)
	fmt.Println(s5)

}

append原理

package main

import "fmt"

func main() {
	/*
		a := []int{11, 22, 33}
		fmt.Println(len(a), cap(a)) // 3 3

		// 这里在a切片的原始数组内,因容量只有3,再次新增字段,源数组无法写入,所以自动扩容了新的数组,c指向新的数组写入44值。
		// 新的数组是在原数组基础上做的2倍扩容,所以新的数组容量为6;此时a和c这两个切片实际指向的源数组不一致了,如果变更其中一个切片值,a和c不会联动了
		c := append(a, 44)
		a[0] = 100
		fmt.Println(a)
		fmt.Println(c)
	*/

	/*	// make函数
		a := make([]int, 3, 10) // [0 0 0]
		fmt.Println(a)          // [0 0 0]

		b := append(a, 11, 22) // b = [0 0 0 11 22]
		fmt.Println(a)         // [0 0 0]
		fmt.Println(b)         // [0 0 0 11 22]

		a[0] = 100
		fmt.Println(a) // [100 0 0]
		fmt.Println(b) // [100 0 0 11 22]
	*/

	// 练习题
	arr := [4]int{10, 20, 30, 40}
	s1 := arr[0:2]                            // s1 = [10,20]
	s2 := s1                                  // s2 = s1 = [10 20]
	s3 := append(append(append(s1, 1), 2), 3) // s3 = [10 20 1 2 3]
	s1[0] = 1000                              // s1 = [1000 20]
	fmt.Println(s1)
	fmt.Println(s2)
	fmt.Println(s3)
	fmt.Println(arr)

}

append的增删改查

package main

import "fmt"

func main() {

	/*	var s = []int{1, 2, 3}
		fmt.Printf("%p\n", &s)
		s = append(s, 4)
		fmt.Printf("%p\n", &s)
	*/

	// 在切片内插入数据
	// 1、在切片的前面插入数据
	var a = []int{1, 2, 3}
	fmt.Println(append([]int{0}, a...))
	fmt.Println(append([]int{-1, -2, -3, 0}, a...))

	// 2、在切片任意位置插入数据
	var b = []int{1, 2, 3, 4, 5}
	var i = 2
	fmt.Println(append(b[:i], append([]int{6}, b[i:]...)...))

	// 3、删除切片内元素
	var c = []int{1, 2, 3, 4, 5}
	var x = 2
	fmt.Println(append(c[:x], c[x+1:]...))
}
  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值