指针变量的值和指针变量地址

// 记录一下学习指针时遇到的问题,如表述或理解有误,欢迎指正.

  1.指针变量是用来存放内存地址的变量,它的值是一个内存地址,而它本身也保存在一个内存地址中.

  2.当初始化一个指针变量时,cpu会开辟一块内存给这个指针变量;当给这个指针变量赋值后,这个指针会指向一个地址,其值为申明变量时指定类型的零值.

func main() {
	var myInt *int                     //申明一个指针变量myInt
	fmt.Println(&myInt, myInt)         //0xc000006028 <nil> 开辟一块地址给指针变量,初始化前的值为nil
	myInt = new(int)                   //初始化myInt
	fmt.Println(&myInt, myInt, *myInt) //0xc000006028 0xc00000a0c8 0 初始化后myInt指向被分配的地址,值为类型的零值
	t := 1                             //申明一个int类型变量
	fmt.Println(&t)                    //0xc00000a100 int类型变量的地址
	*myInt = t                         // 将t的值赋值给*myInt,此时myInt指向的地址并没有发生变化
	fmt.Println(&myInt, myInt, *myInt) //0xc000006028 0xc00000a0c8 1 myInt指向的地址没有发生变化,但那个地址对应的值以及被修改为1
	myInt = &t                         //将t的地址赋值给muInt,此时myInt指向的地址发生变化
	fmt.Println(&myInt, myInt, *myInt) //0xc000006028 0xc00000a100 1 myInt指向的地址已经不是初始化时cpu分配的地址,而是变成变量t的地址,对应的值也变成t的值
}

  myInt = &t这种操作会修改myInt初始化时指向的地址,所以在开发时会存在下边的坑:

案例:

func Test(s *string) error {
	fmt.Println(s) //s的地址为: 0xc000046230
	myTest := "hello world"
	s = &myTest
	fmt.Println(s) //s的地址为: 0xc000046240
	return nil
}

func main() {
	var str string
	_ = Test(&str)
	fmt.Println(str)
}

/*
上段代码中,Test函数接收一个指针变量类型的参数,即str变量对应的内存地址;
在函数中申明了一个string类型的变量,当执行s=&myTest时,指针变量s指向的地址由&str变成了&myTest;
此时*s的值为"hello world",但并未对&str做任何修改,相当于&str传进来马上就被替换掉了;
&str并未做任何改变,所以最后在主函数中打印str时发现它为空
*/

处理:

func Test(s *string) error {
	fmt.Println(s) //s的地址为: 0xc000088220
	myTest := "hello world"
	*s = myTest
	fmt.Println(s) //s的地址为: 0xc000088220
	return nil
}

func main() {
	var str string
	_ = Test(&str)
	fmt.Println(str) //hello world
}

/*
当使用*s = myTest这种方式进行赋值时,相当于将s指向的地址对应的值修改为"hello world", 即在函数Test中地址&str对应的值被修改
所以在最后打印时成功修改str
*/

总结:

  对于*s = myTest和s = &myTest这两种操作,*s的最终值虽然都是"hello world",但是在计算机内部却是不同的:

  *s = myTest相当于修改s指针变量指向地址对应的值,指向的地址未发生变化;

  s = &myTest相当于修改了指针变量s指向的地址,相应的*s也发生了变化.

 

posted @ 2022-01-11 10:37  屁桃  阅读(1082)  评论(0编辑  收藏  举报