目前为止,我所见过的语言里面有指针的就两个:Go和C/C++
两种指针还是有诸多类似的地方,下面我们将这两种指针对比着来学习
内存地址
· Go:不是每个值都有内存地址,但是每一个变量都有其内存地址,允许被&操作。聚合类型的每个成员(结构体的每个字段、数组的每个元素)也有内存地址,允许被&操作。
· C/C++:只要是值就有内存地址,只是区分堆地址、栈地址而已。所有值都可以被&操作。
关于指针的表示
· Go语言
var x int //声明变量
&x //取地址
var p *int //定义指针
p = &x //指针指向变量
*p = 2 //间访变量
· C/C++
int x; //声明变量
&x; //取地址
int* p; //定义指针
p = &x; //指针指向变量
*p = 2; //间访变量
看起来的确很像!
关于默认值
这一点Go和C/C++的规则是一样的,对于聚合类型,创建时会调用默认构造函数(Go而言就时赋默认初值);对于聚合类型指针赋null/nil
package main
import (
"fmt"
)
type TestType struct {
name string
}
func main() {
var test1 TestType
test1.name = "aaa"
fmt.Println(test1)
var test2 *TestType
test2.name = "bbb"
fmt.Println(test2)
}
{aaa}
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x487217]
goroutine 1 [running]:
main.main()
/home/yong/Desktop/awesomeProject/main.go:17 +0xa7
临时变量的指针
在C/C++里面临时变量一般分配在栈内存上,离开作用域的时候被析构函数回收。所以在一般不会在临时变量的作用域之外使用指向零时变量的指针。
但是在Go里面变量又被称为可寻址的值,即使是临时变量也可以接受&(取地址)操作,并且这些指针可以在变量作用域之外使用。
new关键字
在C++里面是关键字,在Go里面是一个预定义函数
· C++
C++里面的new关键字调用的是构造函数,构造出来的值存放在堆区,返回的是指向这个值的指针
int* a = new int(0);
· Go
创建一个匿名变量并返回其指针
var p *int = new(int)