C的指针一直都没学过,恰巧Golang里边有顺带了解一下。
指针
Go语言中的函数传参都是值拷贝,当我们想要修改某个变量的时候,我们可以创建一个指向该变量地址的指针变量。传递数据使用指针,而无须拷贝数据。
区别于C的指针,Golang中指针不能进行偏移和运算
两个符号:&
(取地址)、*
(根据地址取值)
语法
指向了一个值的内存地址。
类似于变量和常量,在使用指针前需要声明指针。格式:
var var_name *var_type
Demo01
package main
import "fmt"
func main() {
var p *int
fmt.Printf("p:%v\n", p) //未赋值时默认为nil
fmt.Printf("p:%T\n", p) //类型为*init
a := 100
p = &a //&取a的地址
fmt.Printf("%v\n", p) //p直接输出地址
fmt.Printf("%v", *p) //*p输出地址对应的值
}
结果:
p:<nil>
p:*int
0xc00000a0c0
100
数组指针
语法
var var_name [MAX]*int;
Demo02
package main
import "fmt"
func main() {
a := [3]int{1, 2, 3}
var p [3]*int
fmt.Printf("p:%v\n", p) //未赋值时默认为nil
for i := 0; i < len(a); i++ {
p[i] = &a[i]
}
fmt.Printf("p:%v\n", p) //赋值后则输出地址
for i := 0; i < len(p); i++ {
fmt.Printf("%v ", *p[i]) //取出对应地址的值
}
}
结果:
p:[<nil> <nil> <nil>]
p:[0xc000014150 0xc000014158 0xc000014160]
1 2 3
也可以通过指针进行地址计算
package main
import (
"fmt"
"unsafe"
)
func main() {
p := [3]int8{1, 2, 3}
//1.获取数组的第一个元素的地址指针
var f = &p[0]
//2.转换成Pointer类型
ptr := unsafe.Pointer(f)
//3.转换成uintptr类型,然后进行内存地址的计算(地址加一个字节,意味着取第二个索引的值)
targetAddress := uintptr(ptr) + 1
//4.根据新地址,重新转换成Pointer类型
newPtr := unsafe.Pointer(targetAddress)
//5.Pointer对象转换成int8指针类型
value := (*int8)(newPtr)
fmt.Println(*value)
}