Golang中指针的使用问题求助:https://play.golang.org/p/Inn0fgn1H23

Golang中指针的使用问题求助:https://play.golang.org/p/Inn0fgn1H23 链接

为什么 fmt.Println(*&j) 输出 39,但如果我将 j 改为 k:链接 却得到 0x414020?

类似地,如果我将 j 改为 k:链接 链接 得到的是地址而不是值。这是为什么?


更多关于Golang中指针的使用问题求助:https://play.golang.org/p/Inn0fgn1H23的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

cherilexvold1974:

为什么 fmt.Println(*&j) 输出 39,但如果我将 j 改为 k:Go Playground - The Go Programming Language 却得到 0x414020?

k 实际上是一个 int 指针数据类型,即 *int。当你设置它时(在这一行:k := &j),它保存了 j 的内存地址作为值。

要访问指针所指向的值,你需要在指针内存地址(例如像 &j&k 这样的指针)或保存内存地址的指针变量(例如:k)前加上星号。示例:

	j := 39
	k := &j   // k is *int

	fmt.Printf("j variable             : %v\n", j)
	fmt.Printf("j pointer              : %v\n", &j)
	fmt.Printf("j pointed value        : %v\n", *&j)
	fmt.Printf("k variable             : %v\n", k)
	fmt.Printf("k pointer              : %v\n", &k)
	fmt.Printf("k value's pointed value: %v\n", *k)
	fmt.Printf("k pointed value        : %v\n", *&k)

你将看到输出是:

j variable             : 39
j pointer              : 0x414020
j pointed value        : 39
k variable             : 0x414020
k pointer              : 0x40c138
k value's pointed value: 39
k pointed value        : 0x414020

请注意,当你访问 k 内存地址的值:*(&k) 时,它返回的是 k 的值。

Playground: Go Playground - The Go Programming Language


所以当你将最后的打印从 fmt.Println(*&j) 改为 fmt.Println(*&k) 时,它仅仅意味着:

访问由 k 变量的内存地址给出的指向值。

这就是为什么你得到的是一个内存地址而不是一个值。要重新得到 39,你将其改为 *k, 这表示:

从给定指针变量的值(存储的内存地址)访问指向的值。

更多关于Golang中指针的使用问题求助:https://play.golang.org/p/Inn0fgn1H23的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在 Go 语言中,指针的使用涉及变量声明和初始化方式的不同,这会影响 *& 操作的结果。让我基于你提供的 Playground 链接中的代码示例来解释。

首先,查看你的第一个链接(https://play.golang.org/p/Inn0fgn1H23):

package main

import "fmt"

func main() {
    j := 39
    fmt.Println(*&j) // 输出 39
}

这里,j := 39 声明了一个整数变量 j 并初始化为 39。&j 获取 j 的地址(一个指向整数的指针),然后 *&j 解引用该指针,得到 j 的值 39。因此,输出是 39。

现在,查看你的第二个链接(https://play.golang.org/p/9qblZnxweVL):

package main

import "fmt"

func main() {
    k := 39
    fmt.Println(*&k) // 输出 0x414020(或其他地址值)
}

在这个代码中,k := 39 同样声明了一个整数变量 k 并初始化为 39。理论上,*&k 应该解引用得到 39。但根据你的描述,输出是类似 0x414020 的地址值。这通常不会发生,除非代码有误或 Playground 环境问题。我怀疑你可能在代码中使用了指针变量而没有正确初始化。例如,如果 k 被声明为指针但没有分配内存,解引用可能产生未定义行为。正确示例:

package main

import "fmt"

func main() {
    k := 39        // k 是整数变量
    fmt.Println(*&k) // 输出 39,因为 &k 是地址,*&k 解引用得到值
}

如果输出地址,可能是由于打印了指针本身而不是解引用值。例如:

package main

import "fmt"

func main() {
    k := 39
    ptr := &k      // ptr 是指向 k 的指针
    fmt.Println(ptr) // 输出地址,如 0x414020
    fmt.Println(*ptr) // 输出 39,解引用指针
}

对于其他链接(如 https://play.golang.org/p/fvHT8SEtb-Jhttps://play.golang.org/p/tPdIL7Ld3o5),如果得到地址而不是值,原因通常是直接打印了指针变量(例如 fmt.Println(&variable)),而不是解引用它(fmt.Println(*pointer))。在 Go 中,未初始化的指针或 nil 指针解引用会导致运行时 panic,但打印指针本身会显示地址。

总结关键点:

  • 使用 &variable 获取变量的地址(指针)。
  • 使用 *pointer 解引用指针以获取值。
  • 如果变量是基本类型(如 int)并正确初始化,*&variable 应返回值。
  • 如果输出地址,检查是否在打印指针而非解引用值。

示例代码演示正确用法:

package main

import "fmt"

func main() {
    // 示例 1: 整数变量
    j := 39
    fmt.Println(*&j) // 输出 39

    // 示例 2: 指针变量
    k := 39
    ptr := &k
    fmt.Println(ptr)   // 输出地址,如 0x1040a124
    fmt.Println(*ptr)  // 输出 39

    // 示例 3: 避免未初始化指针
    var p *int
    // fmt.Println(*p) // 这会 panic,因为 p 是 nil
    p = &k
    fmt.Println(*p) // 输出 39
}

如果你在 Playground 中遇到不一致的输出,请确保代码没有语法错误或未定义行为。指针操作必须基于有效内存地址。

回到顶部