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

0 c parameters struct reference function

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

当然,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;
}
Run Code Online (Sandbox Code Playgroud)

产生以下输出:

3415000
5
3415000
5
3415000
0
Run Code Online (Sandbox Code Playgroud)

任何帮助将非常感激!

oua*_*uah 5

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

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

所以你的banjo函数相当于:

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

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

printf("%p\n", (void *p) &str);
Run Code Online (Sandbox Code Playgroud)