一、指针的定义与使用
Go语言中的指针与其他语言类似,用于存储变量的内存地址。指针变量可以指向任何数据类型,包括自定义类型。在Go中,声明指针使用*
操作符,而通过&
操作符可以获取变量的地址。
示例
:
package main
import "fmt"
func main() {
// 定义一个整数变量
var num int = 42
// 声明一个指向整数的指针
var ptr *int
// 获取变量的地址,并将地址赋值给指针变量
ptr = &num
// 打印变量的值和地址
fmt.Println("Value of num:", num)
fmt.Println("Address of num:", &num)
// 打印指针变量的值和指向的变量的值
fmt.Println("Value of ptr:", ptr)
fmt.Println("Value pointed by ptr:", *ptr)
// 修改指向的变量的值
*ptr = 99
// 打印修改后的变量的值
fmt.Println("Modified value of num:", num)
}
解释
:
在这个例子中,我们首先定义了一个整数变量 num
,然后声明了一个指向整数的指针 ptr
。通过 &num
获取了 num
变量的地址,并将地址赋值给指针变量 ptr
。接着,我们打印了变量的值和地址,以及指针变量的值和指向的变量的值。最后,我们通过修改指针变量所指向的变量的值,来展示指针的修改效果。
结果:
Value of num: 42
Address of num: 0xc000016060
Value of ptr: 0xc000016060
Value pointed by ptr: 42
Modified value of num: 99
解释
:
这个例子中,ptr
指向了 num
的地址,通过 *ptr
可以访问该地址上的值。修改 *ptr
的值,实际上就是修改了 num
的值。
二、指针的初始化
在Go语言中,指针变量的初始化通常是通过new
关键字或直接使用地址运算符&
来完成的。
1、使用 new
关键字初始化指针
new
是一个内建函数,用于创建一个新的实例,并返回该实例的地址。可以将其用于初始化指针。
示例
:
package main
import "fmt"
func main() {
// 使用 new 关键字初始化指针
ptr := new(int)
// 打印指针变量的值(指向的地址)
fmt.Println("Value of ptr:", ptr)
// 修改指向的变量的值
*ptr = 42
// 打印修改后的变量的值
fmt.Println("Modified value:", *ptr)
}
结果:
Value of ptr: 0xc00007c020
Modified value: 42
解释
:
在这个例子中,new(int)
返回一个指向新分配的零值整数的指针。然后,我们通过*ptr
访问指针所指向的整数,并将其修改为42。
2、直接使用地址运算符 &
初始化指针
示例
:
package main
import "fmt"
func main() {
// 定义一个整数变量
num := 10
// 使用地址运算符 & 初始化指针
ptr := &num
// 打印指针变量的值(指向的地址)
fmt.Println("Value of ptr:", ptr)
// 打印指向的变量的值
fmt.Println("Value pointed by ptr:", *ptr)
// 修改指向的变量的值
*ptr = 20
// 打印修改后的变量的值
fmt.Println("Modified value of num:", num)
}
结果:
Value of ptr: 0xc000016060
Value pointed by ptr: 10
Modified value of num: 20
解释
:
在这个例子中,我们首先定义了一个整数变量 num
,然后使用 &num
获取 num
变量的地址,并将其赋值给指针变量 ptr
。通过 *ptr
可以访问指针所指向的变量,并进行相应的修改。
三、通过swap交换指针的值
在Go语言中,可以通过指针来实现交换两个变量的值。这是因为通过指针,我们可以直接访问和修改内存中的数据。
示例
:
package main
import "fmt"
// swap 函数接受两个指向整数的指针,并交换它们所指向的值
func swap(a, b *int) {
temp := *a
*a = *b
*b = temp
}
func main() {
// 定义两个整数变量
num1 := 10
num2 := 20
// 打印交换前的值
fmt.Println("Before swap:")
fmt.Println("num1:", num1)
fmt.Println("num2:", num2)
// 调用 swap 函数交换变量值,传递变量地址
swap(&num1, &num2)
// 打印交换后的值
fmt.Println("nAfter swap:")
fmt.Println("num1:", num1)
fmt.Println("num2:", num2)
}
结果:
Before swap:
num1: 10
num2: 20
After swap:
num1: 20
num2: 10
解释
:
在这个例子中,swap
函数接受两个指向整数的指针作为参数,然后通过指针操作,交换了这两个整数的值。在 main
函数中,我们定义了两个整数变量 num1
和 num2
,然后通过调用 swap
函数,传递这两个变量的地址,实现了它们的值的交换。最后,我们打印了交换前后的变量值,验证了交换的效果。
四、nil在go中的细节
在Go语言中,nil
是一个预定义的标识符,用于表示指针、切片、映射、通道、接口和函数等数据类型的零值或未初始化值。nil
通常用于表示某个指针或引用类型的零值,即它不指向任何有效的内存地址或数据。
-
指针(Pointers):
在Go中,指针的零值是
nil
,表示指针未指向任何有效的内存地址。var ptr *int // 声明一个整数指针,其零值为 nil fmt.Println("Value of ptr:", ptr) // 输出: Value of ptr: <nil>
-
var s []int // 未初始化的切片,零值为 nil fmt.Println("Value of slice:", s) // 输出: Value of slice: []
-
未初始化的映射,其零值同样为
nil
。var m map[string]int // 未初始化的映射,零值为 nil fmt.Println("Value of map:", m) // 输出: Value of map: map[]
-
未初始化的通道的零值也是
nil
。var ch chan int // 未初始化的通道,零值为 nil fmt.Println("Value of channel:", ch) // 输出: Value of channel: <nil>
-
一个接口类型的零值是
nil
,当且仅当其动态值和动态类型都为nil
。var intf interface{} // 接口类型的零值为 nil fmt.Println("Value of interface:", intf) // 输出: Value of interface: <nil>
在使用 nil
时,需要小心处理,以避免出现空指针引用或其他相关的运行时错误。
示例
:
package main
import "fmt"
func main() {
// 指针的零值是 nil
var ptr *int
fmt.Println("Value of ptr:", ptr) // 输出: Value of ptr: <nil>
// 未初始化的切片零值是 nil
var s []int
fmt.Println("Value of slice:", s) // 输出: Value of slice: []
// 未初始化的映射零值是 nil
var m map[string]int
fmt.Println("Value of map:", m) // 输出: Value of map: map[]
// 未初始化的通道零值是 nil
var ch chan int
fmt.Println("Value of channel:", ch) // 输出: Value of channel: <nil>
// 接口类型的零值是 nil
var intf interface{}
fmt.Println("Value of interface:", intf) // 输出: Value of interface: <nil>
}
五、指针的原理
在 Go 语言中,指针是一种特殊的变量类型,用来存储另一个变量的内存地址。指针变量可以指向任何数据类型(如整数、字符串、结构体、函数等),并允许直接访问其所指向的变量的值或修改它。
示例
:
package main
import "fmt"
func main() {
var num int = 42 // 声明一个整数变量 num,并赋值为 42
var ptr *int // 声明一个整数指针变量 ptr
ptr = &num // 将 num 的地址赋值给指针 ptr
fmt.Println("Value of num:", num)
fmt.Println("Address of num:", &num)
fmt.Println("Value of ptr:", ptr)
fmt.Println("Value pointed by ptr:", *ptr) // 通过指针访问 num 的值
*ptr = 100 // 通过指针修改 num 的值
fmt.Println("nValue of num after modification:", num) // num 的值已被修改
}
结果:
Value of num: 42
Address of num: 0xc0000140a8
Value of ptr: 0xc0000140a8
Value pointed by ptr: 42
Value of num after modification: 100
解释
:
在这个示例中,首先声明了一个整数变量 num
并赋值为 42
。然后声明了一个整数指针变量 ptr
。通过 &num
获取 num
的地址,并将其赋值给 ptr
,使得 ptr
指向 num
。通过 *ptr
可以访问 ptr
所指向的变量的值。最后,通过 *ptr = 100
修改了 num
的值,因为 ptr
指向了 num
的地址。因此,num
的值被修改为 100
。
原文地址:https://blog.csdn.net/weixin_49015143/article/details/134624049
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_17229.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!