通过引用函数修改struct

时间:2017-01-16 22:08:08

标签: c pointers struct memory-address

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

typedef struct arrayA {
    int a[3]; 
}arrayA; 

void f(arrayA *a, arrayA *b){
    a = b; 
    printf("address of a: %p\n", a); 
    printf("address of b: %p\n", 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: %p\n", &a); 
    printf("address of b: %p\n", &b); 
    printf("a[0] : %d a[1] : %d\n", a.a[0], a.a[1]); 
    f(&a, &b); 
    printf("a[0] : %d a[1] : %d\n", a.a[0], a.a[1]); 
    printf("address of a: %p\n", &a); 
    printf("address of b: %p\n", &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
----------------------------------------------------

2 个答案:

答案 0 :(得分:2)

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

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

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

如果你想自己更改指针,你需要一个额外的间接:

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

答案 1 :(得分:1)

  

然而,从函数返回后,更改被反转。为什么呢?

您的f()函数实际上只是更改了它内部的指针,并且在函数之后不会保留那些指针更改。

您可以通过pass-by-pointer复制struct:

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

这将确保您可以通过

复制main()中的结构
f(&a, &b); 

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

的所有警告