指针是一个特殊的变量,本质是一个对象,用来存储内存地址,并且通过该内存地址,对存储在该内存的对象进行相关操作。

刚开始学习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