Golang 中的指针


2022 年 1 月 16 日, 学习 e教程
1861

在本教程中,我们将学习 Go 编程语言中的指针。在 Golang 中,使用指针编程非常容易。与其他任何语言一样,指针概念很简单:它用于指向需要访问的变量所驻留的内存位置的地址,并使用“&”号运算符来寻址内存位置。您将在本教程中学习如何声明和初始化指针。

Golang 中的指针是什么?

指针是一种复合数据类型或派生数据类型,它存储内存位置中存储的任何变量的地址。指针持有或指向另一个变量的内存地址。

指针是一个能够存储对象起始地址并指向该对象的变量。

让我们简要回顾一下内存地址的概念以及变量如何从内存位置存储和访问。
 

GO : Pointer

考虑您的计算机内存,它能够存储 20 字节的信息。每个内存块都能够存储一字节的信息。

假设此内存的起始地址是 1,000,结束地址是 1090。假设您想在内存中存储一个整数数据类型的变量。整数将占用 2 字节的内存,即它将占用 2 个内存块。

假设变量“p”用于存储整数。P 存储分配给它的值 100。在这个例子中,假设有一个指针指向存储变量 p 的位置。假设“ptr”是指向变量“p”的基地址或起始地址的指针。

  • 假设“ptr”指向 1002(起始地址)。
  • 这意味着变量 p 存储在该内存位置,值为 100。
GO : Pointer

注意: 指向意味着它只存储对象的基地址或起始地址。我们示例中的对象是“p”

  • 指针是一个能够存储某个地址并指向存储第一个字节的内存位置的变量
GO : Pointer

让我们看一个简单的程序


package main
import "fmt"

func main() {
   var a int = 100   
   fmt.Printf("Address of memory location of Variable a : %x\n", &a )
}

输出


Address of memory location of Variable a : c000014050

该程序显示变量 a 存储的内存地址,即变量存储在内存位置 c000014050。

注意: 指针是一个特殊的变量,而不是存储整数、字符和浮点数的普通变量。它将存储变量的地址或基地址

何时在 Golang 中使用指针?

在以下情况下使用指针

  • 需要传递大量数据时
  • 需要更改存储在任何内存位置的数据的值时。
  • 它们用于访问、分配或修改存储的数据。
     

如何在 Golang 中声明指针?

声明指针的语法


var <variable_name> *<variable_Type>

其中

  • var:- 声明变量的关键字
  • variable_name:- 声明的指针变量的名称。
  • Varaiable_Type:- 变量的数据类型
  • * 是用于声明指针变量的星号。

var  a *int        /* pointer to an integer variable */
var c *float32    /* pointer to a float variable */

注意: - 声明时,指针的初始值为 nil,即默认情况下指针的值设置为零。


package main
import "fmt"

func main() {
   var a int= 100   /* actual variable declaration */
   var Ptr *int        /* pointer variable declaration */

   Ptr = &a  /* store address of a in pointer variable*/

   fmt.Printf("Address of sampleVariable a value: %x\n", &a  )

   /* address stored in pointer variable */
   fmt.Printf("Address stored in Pointr variable: %x\n", Ptr )

   /* access the value using the pointer */
   fmt.Printf("Value of *Pointr variable: %d\n", *Ptr )
}

输出


Address of sampleVariable a value: c000014050
Address stored in Pointr variable: c000014050
Value of *Pointr variable: 100

解释

  • 指针变量按上述语法声明。
  • 然后使用“&”将变量 a 的地址存储在指针 ptr 中。
  • 从可用地址访问值
  • 一元运算符 * 返回位于指定地址的变量的值。
     
GO : Pointer

如何在 Golang 中初始化指针?

指针可以通过两种方式初始化

  1. 使用运算符 new
  2. 使用运算符 ambersand ‘&’
     

显示 new 运算符的程序


package main
import "fmt"

func main() {
   c := new(int) // new operator
  *c = 25
  fmt.Println("Return the value stored in c \n" ,*c) //Output will be 25
  fmt.Println("Return the address of c in memory \n", &c)
   
}

输出


Return the value stored in c 
 25
Return the address of c in memory 
 0xc00000e030

显示 & 运算符的程序


package main
import "fmt"

func main() {
    //Declare a pointer
    var b *int
    a := 9
    b = &a
    fmt.Println("return the address of a ",b)
    fmt.Println("return the value stored in a",*b)
    }

输出


return the address of a  0xc000014050
return the value stored in a 9
New 运算符 & 运算符

c := new(int) *c = 25

  • 使用 new 运算符初始化
  • * 获取存储在该地址的值
GO : Pointer

var b *int a := 9 b = &a

  • 指针已声明
  • 变量 a 赋值为 9
  • 指针变量 b 存储 a 的地址
GO : Pointer

注意

  • * 运算符用于解引用指针。
  • 返回指针引用的值。

Golang 中的 nil 指针是什么?

一旦声明,指针的默认值是 nil,即零。让我们看一个例子


package main
import "fmt"

func main() {
   var  Ptr *int  //pointer declaration
   fmt.Printf("The default Pointr value is nil : %x\n", Ptr  ) //nil value ie 0
}

输出


The default Pointr value is nil : 0

Golang 中的解引用指针是什么?

  • * 运算符用于解引用指针。
  • 返回指针引用的值。
  • 它用于修改指针位置的值。
     

在下面给出的程序中,声明了一个指针变量 b。它进一步被赋值为变量 a 的地址。& 运算符将变量 a 的地址复制到 b。*b 打印或获取 a 中的值,即下面示例中的 9。
接下来,我们将 b 修改为值 3。因此 b 的内存位置会更新为新值。b 的旧值 (9) 会修改为最新声明的值 (3)。
请查看下面的程序以理解相同之处。

理解解引用指针的程序?


package main
import "fmt"

func main() {
    //Declare a pointer
    var b *int
    a := 9
    b = &a
     fmt.Println(a)  // prints value of a
    fmt.Println(*b)  // * operator dereference prints value in b = 9
    *b = 3
 fmt.Println(a)  //modified value in b with 3 b= 3
 fmt.Println(*b) // prints b = 3
    }   

输出


9
9
3
3

Golang 中的指针到指针引用?

在 Golang 中,可以创建以下格式的指针到指针:

    a := 9
    b = &a
    c = &b
 

b 和 c 是指针变量,b 保存 a 的地址。指针变量 c 保存 b 的地址,b 实际上存储变量“a”的地址,其赋值为 9。在上面的代码中,c 是指向指针的指针。

GO : Pointer

指向指针的程序的程序


package main
import "fmt"

func main() {
 a := 9
 b := &a
 c := &b

 fmt.Printf("Value of a: %d\n", a)
 fmt.Printf("address of a in b: %x\n", b)
 fmt.Printf("pointer to pointer reference in c: %x\n", c)

 fmt.Println()
 fmt.Printf("value in variable a: %d\n", a)
 fmt.Printf("*&a: %d\n", *&a) //value in variable a
 fmt.Printf("*b: %d\n", *b)//value in variable a
 fmt.Printf("**c: %d\n", **c)//value in variable a

 fmt.Println()
 fmt.Printf("displays address of a given &a: %d\n", &a)
 fmt.Printf("b: %d\n", b)//displays address of a
 fmt.Printf("&*b: %d\n", &*b)//displays address of a
 fmt.Printf("*&b: %d\n", *&b)//displays address of a
 fmt.Printf("*c: %d\n", *c)//displays address of a

 fmt.Println()
 fmt.Printf("b: %d\n", &b)
 fmt.Printf("*c: %d\n", c)
 }

输出


Value of a: 9
address of a in b: c000014050
pointer to pointer reference in c: c00000e030

value in variable a: 9
*&a: 9
*b: 9
**c: 9

displays address of a given &a: 824633802832
b: 824633802832
&*b: 824633802832
*&b: 824633802832
*c: 824633802832

b: 824633778224
*c: 824633778224

从给定的程序可以清楚地看出,一些运算符产生相同的输出或与某些其他相同的操作等效。

为了显示变量 a 中的值,a 被赋值为 9。下面给出的符号等同于产生相同的输出。

  • a
  • *&a
  • *b
  • **c
     

同样,等效于显示变量 b(持有 a 的地址)值的符号是

  • &a
  • b
  • &*b
  • *&b
  • *c
     

同样,等效于显示变量 c(持有 a 的地址)值的符号是

  • b
  • *c