[指针类型]:内存地址 和 指针变量
golang 中 的 内存地址 和 指针变量。
内存中的每一个具体的区域,均有属于一个它的唯一地址 (编号) 。我们可以通过内存地址,来唯一地定位到一个内存区域,而这个内存区域中本身又是存着某些数据的。这就像我们通过门牌号找到一栋房子,而这个房子里又住着某一家人。
- 内存地址
package main
import "fmt"
func main() {
// 定义几个通常意义上的变量
myInt, myString, myBool := 33, "hello", true
// 使用普通变量,实际上使用的是"房子里的人",也就是变量存储的值
fmt.Println(myInt)
fmt.Println(myString)
fmt.Println(myBool)
// 使用取地址符号& , 获取普通变量在内存中的 "门牌号" : 内存地址
fmt.Println(&myInt)
fmt.Println(&myString)
fmt.Println(&myBool)
}
/* [运行结果如下]:########################
33
hello
true
0xc0000aa058
0xc000088220
0xc0000aa070
####################################### */
- 指针变量
所谓的指针变量,是一种特殊的变量,它用于存储 "内存地址" 。golang 中定义指针变量,与定义普通变量一样,我们需要指明这个变量对应到的那个数据的数据类型;不同点在于,golang 使用 指针符号 * 来表示这个变量是一个指针变量,它是用来存储地址的。
注意:区分指针变量本身的内存地址(它的门牌号),以及它所保存的内存地址(它存储的值)
package main
import "fmt"
func main() {
// 定义并赋值几个普通变量
myInt, myString := 68, "ok"
// 定义几个指针变量
var myIntP *int
var myStringP *string
// 打印指针变量,就是打印指针变量存储的值。此时没有存储值,故结果为nil
fmt.Println(myIntP)
fmt.Println(myStringP)
fmt.Println()
// 打印指针变量本身的"门牌号",也就是指针变量本身被存储在哪个内存地址中
fmt.Println(&myIntP)
fmt.Println(&myStringP)
fmt.Println()
// 使用 指针变量 存储 普通变量 的 内存地址,也就是让 指针变量的 "房子" 里 住下一组 "其它人的门牌号"
myIntP = &myInt
myStringP = &myString
// 打印指针变量,就是打印它存储的值。此时打印的结果是"其它人的门牌号",不再是nil
fmt.Println(myIntP)
fmt.Println(myStringP)
fmt.Println()
}
/* [运行结果如下]:########################
0xc000006028
0xc000006030
0xc0000120a8
0xc00004e230
####################################### */
- 取地址运算[&] 和 取值运算[*]
在golang中,& 是取地址运算符,对某个变量使用 & ,表示获得这个变量的内存地址 (求门牌号) 。* 是取值运算符,对某个内存地址使用 * ,那么就会读取那个内存地址中所存储的数据值 (访问房子里住的人) 。
值得注意的是,由前述2个例子可知,使用变量名,实际上使用的是变量中所存储的值。也就是说:var_nam 等价于 * &var_nam,效果均为访问 var_name 中存储的数据。
- 使用 指针变量 存储 普通变量的内存地址
package main
import "fmt"
func main() {
// 定义并赋值2个普通变量
var a float64 = 123.45
var b bool = false
// 定义并赋值2个指针变量
var myFloatP *float64 = &a // myFloatP 中 存储了 a 的地址值
var myBoolP *bool = &b // myBoolP 中 存储了 b 的地址值
// 通过指针变量访问它所指向的普通变量
fmt.Println(*myFloatP) // 访问 a地址值 中存储的数据,等价于直接调用a
fmt.Println(a)
fmt.Println()
fmt.Println(*myBoolP) // 访问 b地址值 中存储的数据,等价于直接调用b
fmt.Println(b)
fmt.Println()
// 通过指针变量修改它所指向的普通变量的值
*myFloatP = 999.999
*myBoolP = true
// a和b 的值 确实发生了改变
fmt.Println(*myFloatP)
fmt.Println(a)
fmt.Println()
fmt.Println(*myBoolP)
fmt.Println(b)
fmt.Println()
}
/* [运行结果如下]:########################
123.45
123.45
false
false
999.999
999.999
true
true
####################################### */
---to be continue---