[GO]结构体的值传递和地址传递

本文通过一个Go语言示例,详细解析了结构体在函数调用中的值传递与引用传递的区别,展示了如何通过指针修改原始结构体的属性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package main

import "fmt"

type student struct {
    id   int
    name string
    sex  byte
    age  int
    addr string
}

func test01(s student)  {
    s.id = 2
    fmt.Println("test s = ", s)
}

func test02(p *student )  {
    p.id = 3
    fmt.Println("p = ", *p)
}

func main() {
    s1 := student{id: 1, name: "baylorqu", age: 18}
    fmt.Println("s1 = ", s1)
    test01(s1) //这里进行的是值传递,形参无法变更实参
    fmt.Println("s1 = ", s1)
    test02(&s1) //这里传递的是结构体的地址,函数里的操作会直接操作地址指向的结构体
}

执行结果为

s1 =  {1 baylorqu 0 18 }
test s =  {2 baylorqu 0 18 }
s1 =  {1 baylorqu 0 18 }
p =  {3 baylorqu 0 18 }

 

转载于:https://www.cnblogs.com/baylorqu/p/9610745.html

<think>好的,我现在需要回答用户关于结构体在不同编程语言中作为参数传递时是值传递还是引用传递的问题。首先,我得回忆一下常见的编程语言在这方面的处理方式。用户提到了C、Python、Java、C++、JavaScript这些语言,可能需要分别说明。 首先,C语言的结构体参数传递。记得在C中,函数参数传递默认是值传递,所以结构体会被复制一份传入函数,函数内修改不会影响原结构体。如果需要修改原结构体,必须传递指针,也就是引用传递的方式。引用中的资料[^2][^3]都提到了C语言中使用结构体作为参数时的情况,尤其是多线程编程混合编程中的结构体指针传递,这支持我的记忆。 接下来是Python的情况。Python中的变量传递其实是对象引用传递,但结构体可能对应的是自定义类或者字典等类型。不过严格来说,Python没有结构体的原生类型,通常用类或字典模拟。对于可变对象(如类实例、列表),函数内修改会影响原对象;不可变对象(如元组)则不会。所以需要根据具体的数据类型来判断,但一般用户用类的话,传递的是引用,所以是引用传递。 然后是Java。Java中基本类型是值传递,对象则是引用传递,但这里的引用传递是指引用的值被传递,所以函数内修改对象的内容会影响原对象,但重新赋值不会改变原对象的引用。结构体在Java中可能用类来模拟,所以属于引用传递。这点需要确认,但根据Java的特性,应该是这样。 C++的情况C类似,但C++有引用符号&,可以显式指定引用传递。默认情况下,结构体作为参数是值传递,但使用引用修饰符后变为引用传递。所以需要分情况讨论,用户可能需要知道默认行为如何显式改变。 JavaScript中,对于对象(包括类似结构体的对象)是引用传递,函数内修改属性会影响原对象,但重新赋值不会改变外部引用。这一点Python类似,需要明确说明。 然后,我需要确保每个语言的描述准确,并且引用正确的资料。例如,C语言部分引用[^3],其中提到了结构体参数传递多线程中的使用,支持值传递需要指针的观点。而Python部分虽然没有直接引用,但根据一般知识回答。 还需要注意用户的问题中的关键词:“结构体参数传递”,“值传递还是引用传递”,以及不同的编程语言。要确保每个语言都明确回答这一点,并给出示例代码说明。 最后,生成相关问题时要围绕结构体传递、不同语言特性、优缺点等展开,帮助用户进一步学习。例如,如何优化结构体传递性能,不同语言的结构体传递差异,值传递引用传递的优缺点,以及多线程中的应用。 现在,检查是否有遗漏的语言或错误,比如是否有其他常见语言如C#、Go等,但用户的问题中没有提到,所以可能不需要。确保每个段落清晰,符合格式要求,使用正确的LaTeX,没有语法错误。同时,引用标记要正确添加,例如在C语言部分引用[^3],而Python部分没有引用资料,可能不需要添加。 总结:需要分语言详细说明,结合示例代码,引用相关资料,最后生成相关问题。</think>### 结构体参数传递方式分析 结构体作为参数传递时,不同编程语言的默认行为差异较大,主要分为以下两种情况: #### 1. **C语言** C语言默认采用**值传递**方式。函数调用时会将整个结构体复制一份传入函数,函数内部修改不会影响原结构体。若需修改原结构体,需显式传递指针(即引用传递)。 ```c // 值传递示例 void modify_struct(struct MyStruct s) { s.value = 10; // 不影响原结构体 } // 引用传递示例 void modify_struct_ptr(struct MyStruct* s) { s->value = 10; // 修改原结构体 } ``` 引用示例:[C语言多线程编程需通过结构体指针传递参数],[混合编程中结构体参数传递需封装指针]。 #### 2. **Python** Python中参数传递为**对象引用传递**。若结构体用类或字典实现,函数内修改可变属性会影响原对象;若为不可变类型(如元组),则不会影响。 ```python class MyStruct: def __init__(self, value): self.value = value def modify_struct(s): s.value = 10 # 影响原对象 s = MyStruct(5) modify_struct(s) print(s.value) # 输出10 ``` #### 3. **Java** Java中结构体通常用类实现,参数传递为**引用传递**(传递对象引用的副本)。函数内修改对象属性会影响原对象,但重新赋值不会改变原引用。 ```java class MyStruct { int value; } void modifyStruct(MyStruct s) { s.value = 10; // 影响原对象 s = new MyStruct(); // 不影响原引用 } ``` #### 4. **C++** 默认采用**值传递**,但可通过`&`显式指定引用传递: ```cpp // 值传递 void modifyStruct(MyStruct s) { ... } // 引用传递 void modifyStructRef(MyStruct &s) { ... } ``` #### 5. **JavaScript** 对象(包括结构体)采用**引用传递**,函数内修改属性会影响原对象,但重新赋值不会改变外部引用。 ```javascript function modifyStruct(s) { s.value = 10; // 影响原对象 s = {}; // 不影响外部引用 } ``` ### 关键总结 | 语言 | 默认传递方式 | 需注意的特性 | |--------|--------------|---------------------------| | C | 值传递 | 需用指针实现引用传递 | | Python | 引用传递 | 区分可变/不可变对象 | | Java | 引用传递 | 无法直接操作内存地址 | | C++ | 值传递 | 可显式使用引用或指针 | | JavaScript | 引用传递 | 对象属性修改影响原数据 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值