指针是一个特殊的变量,本质是一个对象,用来存储内存地址,并且通过该内存地址,对存储在该内存的对象进行相关操作。
刚开始学习C++的时候,着实被指针这个东西搞得头昏脑胀,C++设计功能强大的指针同时,必然伴随着学习难度的提升。后来在学习java、.net的时候,终于有了一种解脱的感觉,再也不用内存怎么分配,怎么管理释放了,甚至有一种感觉,就算不懂内存,也不碍事,java强大的垃圾回收机制解决了内存管理过程的后顾之忧。
现在我们再来看看另一个编程语言,Go语言,Go语言的指针相对于C++,无论是语法上还是应用上都做了简化,不需要复杂的语法规则,也不需要灵活的智能指针和运算,只保留了指针最本质的功能。
1、创建一个指针变量:
var p *int;
指针的变量类型为int,指向int类型对象的内存地址。
2、指针变量赋值:
var I int=100;
p=&I;
&是取地址符号,意思是去除变量i的内存地址,并赋值给指针p;p不能直接等于I;
这时候我们直接输入:fmt.Println(p);
输出内容:0xc042054080
这是一个十六进制的内存块地址。
如果想要通过指针输出内存对象,给指针变量加上取值符号”*”,输入命令:
fmt.Println(*p);
输出内容:100
3、创建指向指针的指针:
我们再创建一个指向指针的指针变量:
var pp **int;
pp=&p;
fmt.Println(pp);//输出指针变量p的内存地址。
fmt.Println(*pp);//输出指针变量p的值,也就是i的地址。
fmt.Println(**pp);//输出指针变量p指向内存的值,也就是i的值。
以上是Go语言的指针,是不是很好理解。我们只需要知道两个符号&、*的使用就可以了。
下面我们用Go语言的指针实现值类型作为实参传递时参数值的变化。
值类型在传递参数时,只是传递了一个拷贝,也就是说我们对形参的所有操作和实参无关。
如:
package main
//引入包
import (
"fmt"
)
func main(){
var value1 int=50;
var value2 int=50;
var sum int=add(value1,value2);
fmt.Println(sum);
fmt.Println(value1);
fmt.Println(value2);
}
func add(a,b int)int{
a++;
b++;
return a+b;
}
输出:102,50,50
这时候实参没有变化。我们通过传递指针实现参数的浅拷贝。
package main
//引入包
import (
"fmt"
)
func main(){
var value1 int=50;
var value2 int=50;
var p1 *int=&value1;
var p2 *int=&value2;
var sum int=add(p1,p2);
fmt.Println(sum);
fmt.Println(value1);
fmt.Println(value2);
}
func add(a,b *int)int{
*a++;
*b++;
return *a+*b;
}
输出:102,51,51