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

传递一个结构体和该结构体的指针有什么区别,难道它们都不都是指针吗?

韦辰钊
2023-03-14
问题内容

例如

var myStructRef *Vertex
var myStruct Vertex
myStructRef = &Vertex{2, 3}
myStruct = Vertex{2, 3}

fmt.Println(myStructRef)
fmt.Println(myStruct)
changeByReferenceStruct(myStructRef)
changeByValueStruct(myStruct)
fmt.Println(myStructRef)
fmt.Println(myStruct)

func changeByValueStruct(myStruct Vertex) {
    myStruct.X = 5
    fmt.Println(myStruct)
}


func changeByReferenceStruct(myStruct *Vertex) {
    myStruct.X = 7
    fmt.Println(myStruct)
}

是不是都myStructRef *VertexmyStruct Vertex一个指针指向结构本身?当我在html" target="_blank">函数中修改结构时,为什么行为上会有差异?

golang在changeByValueStruct解析参数时是否在创建新的结构?


问题答案:

在Go中只有一种传递参数的方法,那就是 按值 。这意味着总是在传递参数时,会创建值的副本并将其传递给函数。

当您将指针作为参数传递时,实际上是创建了该指针的副本并将其传递给基础函数。不应将其与传递引用混淆。

让我们看一个例子来更好地理解它:

package main

import (
    "fmt"
)

type Point struct {
    x int
    y int
}

func (p Point) String() string {
    return fmt.Sprintf("(%d, %d)", p.x, p.y)
}

func modifyValue(point Point) {
    point.x += 10
}

func modifyPointer(point *Point) {
    point.x = 5
    point.y = 5
}

func modifyReference(point *Point) {
    point = &Point{5, 5}
}

func main() {
    p := Point{0, 0}
    fmt.Println(p) // prints (0, 0)

    modifyValue(p)
    fmt.Println(p) // prints (0, 0)

    modifyPointer(&p)
    fmt.Println(p) // prints (5, 5)

    p = Point{0, 0}
    modifyReference(&p)
    fmt.Println(p) // prints (0, 0)
}

ModifyValue 函数内部发生的事情是修改了Point结构的完全不同的实例,因此调用函数时传递的值不受影响。

在第二个示例中,传递了指向该结构的指针,以便可以以从​​外部可见的方式修改该结构的字段。

最有趣的一点是最后一个函数 ModifyReference
。如果您熟悉其他语言提供的“按引用传递”范例,则可以完全修改被引用的对象,但这不会发生。这是因为您正在修改作为参数传递的指针的 副本

您可能想知道,如果一切都是按值传递的,则何时应传递指针以及何时传递值。传递值可确保调用方函数传递的结构不会受到任何更改,因此,在需要此行为时,请选择该值。不利的一面是制作了整个对象的副本,如果副本太大,则需要考虑内存问题。

如果要传递大结构作为参数,则使用指针会更好,因为它可以节省空间,但是您无法保证对象不会受到任何更改。



 类似资料:
  • 在这个练习中你将会学到如何创建struct,将一个指针指向它们,以及使用它们来理解内存的内部结构。我也会借助上一节课中的指针知识,并且让你使用malloc从原始内存中构造这些结构体。 像往常一样,下面是我们将要讨论的程序,你应该把它打下来并且使它正常工作: #include <stdio.h> #include <assert.h> #include <stdlib.h> #include <st

  • Go 语言中指向结构体的指针和 C 语言一样 结构体和指针 创建结构体指针变量有两种方式 package main import "fmt" type Student struct { name string age int } func main() { // 创建时利用取地址符号获取结构体变量地址 var p1 = &Student{"lnj", 33}

  • 5. 指针与结构体 首先定义一个结构体类型,然后定义这种类型的变量和指针: struct unit { char c; int num; }; struct unit u; struct unit *p = &u; 要通过指针p访问结构体成员可以写成(*p).c和(*p).num,为了书写方便,C语言提供了->运算符,也可以写成p->c和p->num。

  • 我正在学习链表,以及如何在C中使用结构和指针创建链表。下面我举一个例子。据我所知,被调用的将头节点所在的结构的开始内存位置作为参数传递。push()函数的参数将结构节点作为指向指针的指针,因此它作为引用传递,而不是实际副本。因此,我们的的第一个指针只是指向头部节点的内存位置的指针,第二个指针指向该值,该值是头部节点指向的下一个内存位置。我们通过为结构节点分配一些内存,在结构节点内创建一个名为new

  • 主要内容:获取结构体成员,结构体指针作为函数参数当一个 指针变量指向结构体时,我们就称它为 结构体指针。 C语言结构体指针的定义形式一般为: struct 结构体名 *变量名; 下面是一个定义结构体指针的实例: 也可以在定义结构体的同时定义结构体指针: 注意,结构体变量名和数组名不同,数组名在表达式中会被转换为数组指针,而结构体变量名不会,无论在任何表达式中它表示的都是整个集合本身,要想取得结构体变量的地址,必须在前面加 ,所以给 pstu 赋

  • 本文向大家介绍详解C++中的指针结构体数组以及指向结构体变量的指针,包括了详解C++中的指针结构体数组以及指向结构体变量的指针的使用技巧和注意事项,需要的朋友参考一下 C++结构体数组 一个结构体变量中可以存放一组数据(如一个学生的学号、姓名、成绩等数据)。如果有10个学生的数据需要参加运算,显然应该用数组,这就是结构体数组。结构体数组与以前介绍过的数值型数组的不同之处在于:每个数组元素都是一个结