2017-01-16 8 views
0

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 
---------------------------------------------------- 
+0

'a = b;'。標準的な初心者の問題。関数のパラメータは、Cの*値で渡されます。関数内のパラメータに対する変更は、呼び出し元の変数には影響しません。 – kaylum

+0

どのように参照して渡すことができますか? – SebNag

+0

正確に何を達成したいですか?内容をコピーしたい場合は 'memcpy(a、b、sizeof(* b))'や '* a = * b'を使います。 – kaylum

答えて

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

はしかし、関数から戻った後の変更は逆になっています。どうして?

f()の機能は実際にはその内部のポインタを変更するだけで、そのポインタの変更はその機能の後に予約されません。

あなたが渡しのポインタで構造体をコピーすることができます。

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

あなたが必要とするすべてがコピー構造体であるため、ノーあり

f(&a, &b); 

を経由してあなたがmain()で構造体をコピーすることができようになりますアドレスをすべて印刷する必要があります。アドレスをデバッグする必要がある場合は、すべての警告を避けるために(void *)に変換する必要があります。printf("%p")

関連する問題