这是我参与8月更文挑战的第18天,活动详情查看:8月更文挑战
指针是什么
程序在内存中存储它的值,每个内存块都 有一个地址,而存储这个地址的变量被称为指针变量,指针。
通常用十六进制数表示,如:0x6b0820 或 0xf84001d7f0
一个指针变量可以指向任何一个值的内存地址 它指向那个值的内存地址,在 32 位机器上占用 4 个字节,在 64 位机器上占用 8 个字节,并且与它所指向的值的大小无关。
指针可以指向任何类型的值,但是使用时指定指针的类型在实际编码中具有重要意义;
在指针类型前面加上 * 号来获取指针所指向的内容。
使用一个指针引用一个值被称为间接引用。
主要用于管理内存
指针是一个特殊的变量
存储的是另一个变量的内存地址
指针内存示意图
指针的作用及应用场景
作用
-
- 节省内存空间,提高执行效率(当操作的数据量较大规模时)
-
- 访问变量的值
应用场景
-
- 修改变量的值
-
- 访问变量的值
获取指针的值
获取一个指针意味着访问指针指向的变量的值,语法是: *a
示例代码:
package main
import "fmt"
func main() {
b := 255
a := &b
fmt.Println(a)
fmt.Println(*a)
}
操作指针改变变量的数值
示例代码:
package main
import "fmt"
func main() {
b := 255
a := &b
fmt.Println(a) // 0xc0000ac058
fmt.Println(*a) // 255
*a++
fmt.Println(b) 256
}
使用指针传递函数的参数
示例代码:
package main
import "fmt"
func change(val *int) {
*val = 55
}
func main() {
a := 50
fmt.Println(a) // 50
b := &a
change(b)
fmt.Println(a) // 55 指引变了
不要将一个指向数组的指针传递给函数,使用切片
假设我们想对函数内的数组进行一些修改,并且对调用者可以看到函数内的数组所做的更改,一种方法是将一个指向数组的指针传递给函数
package main
import "fmt"
func change(arr *[3]int) {
(*arr)[0] = 90
}
func main() {
a := [3]int{1, 2, 3}
change(&a)
fmt.Println(a) // [90 2 3]
}
虽然将指针传递给一个数组作为函数的参数并对其进行修改,但这并不是实现这一目标的惯用方法,我们有切片
示例代码:
package main
import "fmt"
func change(arr []int) {
arr[0] = 0
}
func main() {
a := [3]int{1, 2, 3}
change(a[:])
fmt.Println(a) // [0 2 3]
}
go不支持指针算法
package main
import "fmt"
func main() {
b := [...]int{1, 2, 3}
p := &b
fmt.Println(p)
}
指针数组
package main
import "fmt"
const MAX int = 3
func main() {
a := []int{1, 2, 3}
var i int
for i = 0; i < MAX; i++ {
fmt.Println(i, a[i]) // i: 0, 1, 2 a[i]: 1, 2, 3
}
}
有一种情况,我们可能需要保存数组,这样我们就需要使用指针
package main
import "fmt"
const MAX int = 3
func main() {
a := []int{1, 2, 3}
var i int
var ptr [MAX]*int
for i = 0; i < MAX; i++ {
ptr[i] = &a[i] // 整数地址复制给数组
}
fmt.Println(ptr)
for i = 0; i < MAX; i++ {
fmt.Printf("a[%d] = %d\n", i,*ptr[i] )
}
}
指针的指针
如果一个指针变量存放的又是另一个指针变量的地址,则称这个指针变量为指向指针的指针变量
var ptr **int
package main
import "fmt"
func main() {
var a int
var ptr *int
var pptr **int
a = 3000
/* 指针 ptr 地址 */
ptr = &a
/* 指向指针 ptr 地址 */
pptr = &ptr
/* 获取 pptr 的值 */
fmt.Printf("变量 a = %d\n", a )
fmt.Printf("指针变量 *ptr = %d\n", *ptr )
fmt.Printf("指向指针的指针变量 **pptr = %d\n", **pptr)
}
套多少层,就剥离多少层
指针为函数参数
package main
import "fmt"
func main() {
/* 定义局部变量 */
var a int = 100
var b int= 200
fmt.Printf("交换前 a 的值 : %d\n", a )
fmt.Printf("交换前 b 的值 : %d\n", b )
/* 调用函数用于交换值
* &a 指向 a 变量的地址
* &b 指向 b 变量的地址
*/
swap(&a, &b);
fmt.Printf("交换后 a 的值 : %d\n", a )
fmt.Printf("交换后 b 的值 : %d\n", b )
}
func swap(x *int, y *int) {
var temp int
temp = *x /* 保存 x 地址的值 */
*x = *y /* 将 y 赋值给 x */
*y = temp /* 将 temp 赋值给 y */
}