【go语言 基础系列】指针

【简介】

指针的值是一个变量的地址

一个指针指示值所保存的位置

使用指针可以在无须知道变量名字的情况下间接读取或更新变量的值

var i int
p=&i

获取一个指向整型变量的指针,它的类型是整型指针(*int)。

其余类型的如下面例子

package main

import (
	"fmt"
)

type myinter interface{}

func main() {
	var myint int
	var mystr string
	var mybool bool
	var myfloat float64
	var myinterface myinter

	myintp := &myint
	mystrp := &mystr
	myboolp := &mybool
	myfloatp := &myfloat
	myinterfacep := &myinterface

	checkType(myintp)
	checkType(mystrp)
	checkType(myboolp)
	checkType(myfloatp)
	checkType(myinterfacep)

}

func checkType(i interface{}) {
	fmt.Printf("  type is %T ,value is %v\n", i, i)
}

执行结果如下

  type is *int ,value is 0xc4200140b0
  type is *string ,value is 0xc42000e1d0
  type is *bool ,value is 0xc4200140b8
  type is *float64 ,value is 0xc4200140c0
  type is *main.myinter ,value is 0xc42000e1e0

【go语言指针的特点】

1、零值是nil
2、不能进行指针运算
3.、指针是可以比较的 (两个指针当且仅当指向同一个变量或者都为nil的情况下才相等)
4、函数返回局部变量的地址是安全的

只声明未赋值的变量,golang都会自动为其初始化为零值。指针变量的零值 是 nil。

其余基础类型的零值如下

package main

import (
	"fmt"
)

func main() {
	var myint int
	var mybool bool
	var mystr string
	var myptr *int
	var myintarr [5]int
	var mystrarr [5]string
	fmt.Printf("myint  is %T,and default value is %v\n", myint, myint)
	fmt.Printf("mybool is %T,and default value is %v\n", mybool, mybool)
	fmt.Printf("mystr  is %T,and default value is %v\n", mystr, mystr)
	fmt.Printf("myptr  is %T,and default value is %v\n", myptr, myptr)
	fmt.Printf("myintarr  is %T,and default value is %v\n", myintarr[0:], myintarr[0:])
	fmt.Printf("mystrarr  is %T,and default value is %v\n", mystrarr[0:], mystrarr[0:])

}

执行结果如下

myint  is int,and default value is 0
mybool is bool,and default value is false
mystr  is string,and default value is 
myptr  is *int,and default value is <nil>
myintarr  is []int,and default value is [0 0 0 0 0]
mystrarr  is []string,and default value is [    ]

###

go语言返回局部变量的地址是安全的,如下demo

package main

import "fmt"

func main() {
	p1 := f()
	fmt.Println("&p1 is:", &p1)
	fmt.Println("p1  is:", p1)
	fmt.Println("*P1 is:", *p1)
	p2 := f()
	fmt.Println("&p2 is:", &p2)
	fmt.Println("p2  is:", p2)
	fmt.Println("*P2 is:", *p2)
	p3 := f()
	fmt.Println("&p3 is:", &p3)
	fmt.Println("p3  is:", p3)
	fmt.Println("*P3 is:", *p3)
}
func f() *int {
	v := 1
	return &v
}

执行结果如下,可以发现&v 局部变量每次返回值都不一样

&p1 is: 0xc42000c028
p1  is: 0xc4200140a0
*P1 is: 1
&p2 is: 0xc42000c038
p2  is: 0xc4200140b8
*P2 is: 1
&p3 is: 0xc42000c040
p3  is: 0xc4200140c8
*P3 is: 1
###

【demo 指针对于值的修改】

package main

import "fmt"

func main() {
	v := 1
	fmt.Println("begin v is:", v)
	incr(&v)  //调用一次incr,v+1
	fmt.Println("after incr(&v) v is:", v)
	fmt.Println(incr(&v))
	fmt.Println(incr(&v))
	fmt.Println(incr(&v))
	fmt.Println(incr(&v))
	fmt.Println("final  v is:", v)
}
func incr(p *int) int {
	(*p)++
	return *p
}

执行结果,v的值发生改变

begin v is: 1
after incr(&v) v is: 2
3
4
5
6
final  v is: 6

###

修改上面代码,变为值传递,如下

package main

import "fmt"

func main() {
	v := 1
	fmt.Println("begin,v is:", v)
	incr(v)
	fmt.Println(incr(v))
	fmt.Println(incr(v))
	fmt.Println(incr(v))
	fmt.Println(incr(v))
	fmt.Println("after,v is:", v)
}
func incr(p int) int {
	p++
	return p
}

执行结果如下,即v的值没有变化

begin,v is: 1
2
2
2
2
after,v is: 1
 

猜你喜欢

转载自blog.csdn.net/natpan/article/details/83086373