C语言 通过引用功能修改结构



我想将结构a分配给结构b。打印函数调用前后数组的地址和值,表明在函数调用期间赋值有效,并且两个指针都指向相同的结构地址。但是,从函数返回后,更改将被反转。为什么?

typedef struct arrayA {
    int a[3]; 
}arrayA; 
void f(arrayA *a, arrayA *b){
    a = b; 
    printf("address of a: %pn", a); 
    printf("address of b: %pn", b); 
}
int main(int argc, char *argv[]) {
    printf("------------ Array assignment test -----------------n"); 
    arrayA a = { { 0, 0, 0} }; 
    arrayA b = { { 1, 1, 1} }; 
    printf("address of a: %pn", &a); 
    printf("address of b: %pn", &b); 
    printf("a[0] : %d a[1] : %dn", a.a[0], a.a[1]); 
    f(&a, &b); 
    printf("a[0] : %d a[1] : %dn", a.a[0], a.a[1]); 
    printf("address of a: %pn", &a); 
    printf("address of b: %pn", &b); 
    printf("----------------------------------------------------n"); 
    return 0;
}

指纹

 ------------ Array assignment test -----------------
address of a: 0x7ffd3fc17b80
address of b: 0x7ffd3fc17b90
a[0] : 0 a[1] : 0
address of a: 0x7ffd3fc17b90
address of b: 0x7ffd3fc17b90
a[0] : 0 a[1] : 0
address of a: 0x7ffd3fc17b80
address of b: 0x7ffd3fc17b90
----------------------------------------------------

您正在按值传递指针并期望它们被修改。它们将在函数中被修改,因为有一个指向函数本地的指针(地址)的副本。当函数返回时,原件保持不变。(您可以尝试打印函数中局部变量的地址以更好地理解。

如果要更改结构,则需要取消引用指针:

void f(arrayA *a, arrayA *b){
    *a = *b; 
    printf("address of a: %pn", a); 
    printf("address of b: %pn", b); 
}

如果要更改指针本身,则需要额外的间接寻址:

void f(arrayA **a, arrayA **b){ // Note the ** here
    *a = *b; 
    printf("address of a: %pn", a); 
    printf("address of b: %pn", b); 
}

但是,从函数返回后,更改将被反转。为什么?

您的f()函数实际上只是更改其中的指针,并且这些指针更改不会在函数之后保留。

您可以通过传递指针复制结构:

void f(arrayA *a, arrayA *b){
    *a = *b; 
}

这将确保您可以通过以下方式复制main()结构

f(&a, &b); 

由于您所需要的只是复制结构,因此根本不需要打印出地址。如果您确实需要调试地址,则应转换为 (void *)以避免所有带有printf("%p")的警告

最新更新