当前位置: 首页 > 面试题库 >

指针的指针(例如** int)有什么用例?

章侯林
2023-03-14
问题内容

这是指向指针的指针

package main

import "fmt"

func main() {
    var num int

    fmt.Println(&num) //  0x...0
    makePointer(&num)
}

func makePointer(firstPointer *int) {
    fmt.Println(firstPointer)  //  0x...0
    fmt.Println(&firstPointer) //  0x...1

    makePointerToAPointer(&firstPointer)
}

func makePointerToAPointer(secondPointer **int) {
    fmt.Println(secondPointer)  //  0x...1
    fmt.Println(&secondPointer) //  0x...2

}

您何时真正使用此功能?您可以适当地提出一些可以更轻松地执行其他操作的方法,但这不是我要的。我真的想知道您将在生产中使用此功能吗?


问题答案:

将指针传递给某物的目的是是否 需要 修改指向的值。(我们也使用指针来避免在传递时复制大型数据结构,但这只是为了优化。)

像这个例子一样:

func main() {
    var i int
    fmt.Println(i)
    inc(&i)
    fmt.Println(i)
}

func inc(i *int) {
    *i++
}

预期的输出(在Go Playground上尝试):

0
1

如果of的参数仅inc()接收int,则只能修改副本,而不能修改原始值,因此调用者将不会观察到更改后的值。

指向某物的指针也是如此。如果需要修改指向的值,则使用指向某个对象的指针,即指向的指针。像这个例子一样:

func main() {
    var i *int
    fmt.Println(i)
    alloc(&i, 1)
    fmt.Println(i, *i)

    setToNil(&i)
    fmt.Println(i)
}

func alloc(i **int, initial int) {
    *i = new(int)
    **i = initial
}

func setToNil(i **int) {
    *i = nil
}

输出(在Go Playground上尝试):

<nil>
0x1040a130 1
<nil>

之所以没有真正使用指向指针的原因,是因为可以通过返回值并将其分配给调用方来代替修改指向的值:

func main() {
    var i *int
    fmt.Println(i)
    i = alloc(1)
    fmt.Println(i, *i)

    i = setToNil()
    fmt.Println(i)
}

func alloc(initial int) *int {
    i := new(int)
    *i = initial
    return i
}

func setToNil() *int {
    return nil // Nothing to do here, assignment happens at the caller!
}

输出是相同的(地址可能不同)(在Go Playground上尝试):

<nil>
0x1040a130 1
<nil>

此变体更易于阅读和维护,因此,这显然是必须修改指针值的函数的广泛青睐的替代方案。

在函数和方法只能有一个返回值的语言中,如果函数还希望返回除指针之外的其他值,则通常需要附加的“工作”,例如,将创建一个包装器来容纳多个返回值。但是由于Go支持多个返回值,因此指针指针的需求基本上降为零,因为可以用返回设置为指向指针的指针代替它。并且不需要额外的工作,也不会使代码的可读性降低。

这与内置append()函数非常相似:将值附加到切片。而且由于切片值发生变化(其长度增加,如果需要分配新的后备数组,其中的指针也可能会更改),因此append()返回您需要分配的新切片值(如果要保留新切片)



 类似资料:
  • 本文向大家介绍什么是指向指针的指针? 相关面试题,主要包含被问及什么是指向指针的指针? 时的应答技巧和注意事项,需要的朋友参考一下 指针指向的变量是一个指针,即具体内容为一个指针的值,是一个地址. 此时指针指向的变量长度也是4位.

  • 在下面给出的代码中,我声明了一个指向int的指针,我们都知道memcpy返回一个指向目标字符串的空指针,所以如果ptr是指向int的指针,那么为什么printf(“%s”,ptr);是完全有效的,ptr毕竟不是指向char的指针。

  • 问题内容: 使用Go编程语言;指针如何变得有用? (如果它们没有真正的用处,为什么不非法呢?) 问题答案: 任何数据类型的有用性取决于要解决的问题和用于解决该问题的方法。如果数据类型不适合该问题,那么它根本就不适合该问题,仅此而已。 Go编程语言(以及大多数其他编程语言)基于程序员可以用来构建新数据类型的 简单 规则。其中一些规则是: :创建一个指向T的新数据类型 :Ts数组 :包含T作为组成部分

  • 指针可以指向一份普通类型的数据,例如 int、double、char 等,也可以指向一份指针类型的数据,例如 int *、double *、char * 等。 如果一个指针指向的是另外一个指针,我们就称它为 二级指针,或者 指向指针的指针。 假设有一个 int 类型的变量 a,p1是指向 a 的指针变量,p2 又是指向 p1 的指针变量,它们的关系如下图所示: 将这种关系转换为C语言代码: 指针变

  • 问题内容: 我习惯于进行Java编程,在编程时,您无需真正考虑指针。但是,此刻我正在用C ++编写程序。在创建具有其他类成员的类时,何时应该使用指针,何时不应该使用指针?例如,什么时候我想这样做: 与此相反: 问题答案: 首先避免指针。 在以下情况下使用它们: 您想使用Pimpl习惯用法或抽象工厂。 该实例实际上是由程序的其他部分管理的,而该类仅需要能够访问它。 您想推迟对象的构建(即,您想 在

  • 6. 指向指针的指针与指针数组 指针可以指向基本类型,也可以指向复合类型,因此也可以指向另外一个指针变量,称为指向指针的指针。 int i; int *pi = &i; int **ppi = &pi; 这样定义之后,表达式*ppi取pi的值,表达式**ppi取i的值。请读者自己画图理解i、pi、ppi这三个变量之间的关系。 很自然地,也可以定义指向“指向指针的指针”的指针,但是很少用到: int