c - 为什么不能在函数中修改结构体的成员变量?

标签 c function struct parameters reference

我很好奇为什么在将结构体的变量作为参数传递给函数时不能修改它。我知道参数是按值传递的,但是在传递结构变量时,您将其引用作为值传递。

当然 C 不会在堆栈上创建结构的副本,因为传入的结构引用的值与将结构指针传递给函数的值相同。

#include <stdio.h>
#include <stdlib.h>


typedef struct String {
    char* name;
    int x;
} String;

/* Func Protos */
void foo(String str);
void bar(String * str);
void banjo(String str);

int main() {
    String str = *(String *)malloc(sizeof(String));
    str.x = 5; /* x == 5 */
    foo(str); /* x == 5 still */
    printf("%d\n", str.x);
    banjo(str); /* x == 5 still */
    printf("%d\n", str.x);
    bar(&str); /* and of course, x = 0 now */
    printf("%d\n", str.x);
}

void foo(String str) {
    printf("%d\n", str); /* Same value as if we passed String * str */
    str.x = 0; 
}

void bar(String * str) {
    printf("%d\n", *str);
    str->x = 0;
}

void banjo(String str) {
    printf("%d\n", str);
    String * strptr = &str; /* This should be identical to passing String * str */
    strptr->x = 0;
}

产生这个输出:

3415000
5
3415000
5
3415000
0

如有任何帮助,我们将不胜感激!

最佳答案

void banjo(String str) {
    printf("%d\n", str);
    String * strptr = &str; /* This should be identical to passing String * str */
    strptr->x = 0;
}

C 是按值传递。您在带有 str 参数的 banjo 函数中得到的是 main str 对象的副本。

因此您的 banjo 函数等同于:

void banjo(String str) {
    printf("%d\n", str);
    strptr.x = 0;  // useless, the object is discarded after function returns
}

顺便说一句,printf("%d\n", str); 无效。 d 转换说明符需要 int 但您传递的是结构值。该调用调用未定义的行为。如果要打印 str 对象的地址,请使用:

printf("%p\n", (void *p) &str);

关于c - 为什么不能在函数中修改结构体的成员变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25939435/

相关文章:

c - 这是否违反了严格的别名规则?

c - 使用字符串读取数字

c - 堆排序适用于字符串,但不适用于整数

c - MATLAB 墨西哥 : retrieving a logical from a struct in MATLAB

c - 能够从未初始化的结构指针数组打印预期结果 - 困惑

结构而不是数组的运算符的 C 地址?

c - 如何将二进制数转换为有符号十进制数

python - 类型错误 : endturn() missing 1 required positional argument: 'self'

Python - 字典 - 最大值和根据键与函数和 for 循环

引用 html 元素的 Javascript 函数参数