前言
- 不做文字的搬运工,多做灵感性记录
- 这是平时学习总结的地方,用做知识库
- 平时看到其他文章的相关知识,也会增加到这里
- 随着学习深入,会进行知识拆分和汇总,所以文章会随时更新
- 参考的文章过多、很杂很乱,所以参考会写不全,见谅
指针
这个地方最好补充一下计算机组成原理和数据结构的内容
- go语言提供了控制数据结构指针的能力,但不能进行指针运算。(这个需要查证下)
1.介绍
-
Go语言中可以被拆分为两个核心概念:
-
类型指针:
-
允许对这个指针类型的数据进行修改,
-
传递数据可以直接使用指针而无需拷贝数据。
-
类型指针不能进行偏移和运算
-
( c中的指针 )指针可以做运算,但代价是内存操作越界
-
-
切片 :
- 切片在发生越界时,运行会报出宕机,并打出堆栈,而原始指针只会崩溃
- 在指针的基础上增加了大小,约束了切片对应的内存区域,
- 切片使用中无法对切片内部的地址和大小进行手动调整,因此切片比原始指针更安全、强大。
-
拆分好处
- 指针类型变量即拥有指针高效访问的特点,又不会发生指针偏移,从而避免了非法修改关键性数据的问题。
- 垃圾回收也比较容易对不会发生偏移的指针进行检索和回收。
2.名词概念
1.指针变量
- 通常缩写为 ptr
- 初始值
- 一个指针被定义后没有分配到任何变量时,
- 默认值为 nil。
- 一个指针变量可以指向任何一个值的内存地址,
- 所指向的值的内存地址在
- 32 位机器上占用 4 个字节
- 64 位机器上占用 8个字节,
- 占用字节的大小与所指向的值的大小无关。
2.值类型和引用类型
类型 | 作用 | 内存分配 | |
---|---|---|---|
值类型 | 变量直接存储值, 都有对应的指针类型(*数据类型) | 栈中分配 | 数值型 字符型 布尔型 字符串 结构体 数组 |
引用类型 | 变量存储的是一个地址,这个地址 对应的空间才真正存储数据(值), 内存通常在。当没有任何变量引用这个地址时, 该地址对应的数据空间就成为一个垃圾,由GC来回收 | 堆上分配 | 指针 slice map chan interface |
2.声明
// 基本数据类型在内存中布局,每个变量都有地址
var i int = 20
//前缀&:取变量i所在的内存地址
//前缀*: 指针
var ptr *int = &i // 基本数据类型都有对应的指针类型,如int——*int
fmt.Print("i的地址=\n",&i)
fmt.Print("****\n")
fmt.Printf("1.ptr=%v\n",ptr)
fmt.Printf("2.ptr的地址=%v\n",&ptr)
fmt.Printf("3.ptr 指向的值=%v\n",*ptr)
==========================================
var i int = 20
var ptr *int = &i
变量的值 i :20
变量地址 &i : 0x1105a080
指针变量:ptr
(ptr): 指针变量 ptr 的值为 &i,即 0x1105a080 (指针变量存的是一个地址)
指针地址(&ptr) :指针变量 ptr 的地址为 : 0x11046110
指针取值(*ptr) :指针变量 ptr 指向的值 :20 (地址指向值)
指针类型:*int
ptr 的类型为 *int
3.取地址符----->&(前缀)
//每个变量在运行时,都有一个代表变量在内存位置中的位置的地址
// 获取变量储存值的地址
ptr := &v //ptr的类型为*T,*代表指针
fmt.Println("%p",&ptr) //动词%P取变量的内存地址,指针的值是带有ox十六进制的前缀的一组值,
4.取值操作符------>(*)
- 根本意义: 操作指针指向的变量 ,获取该变量的值
作为右值时,意义是取指针的值(地址上有值) 取指向变量的值
作为左值时,表示指针指向的变量 () 将值设置给指向的变量。
3.创建指针
- new() 函数可以创建一个对应类型的指针,创建过程会分配内存,被创建的指针指向默认值。可以创建基本数据类型的指针
4.使用
1.从指针获取指针指向的值
// 取地址,将地址给一个中间变量,这个中间变量就成为了指针类型,通过取值就可以获得数据
var house = "a" // 准备一个字符串类型
ptr := &house // 对字符串取地址, ptr类型为*string 得到指针变量
value := *ptr // 对指针进行取值操作
}
2.使用指针修改值
//取地址,
func swap(a, b *int) { // 交换函数
t := *a // 取a指针的值, 赋给临时变量t
*a = *b // 取b指针的值, 赋给a指针指向的变量
*b = t // 将a指针的值赋给b指针指向的变量
}
func main() {
x, y := 1, 2 // 准备两个变量, 赋值1和2
swap(&x, &y) // 交换变量值
fmt.Println(x, y) // 输出变量值
}
3.使用指针变量获取命令行的输入信息
- flog包
- &地址操作符和(*)取值操作符,是一对互补操作符
5.出现的错误
!p(string=a) // 这个是说他是非指针变量,不能用%p获得指针地址