2017-01-16 7 views
0

Я хочу назначить struct 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; 
} 

Это гарантирует, что Вы можете скопировать структуры в main() через

f(&a, &b); 

Как все, что вам нужно, это копия структура, нет необходимо распечатать адреса вообще. Если вам нужно отладить адрес, вы должны преобразовать его в (void *), чтобы избежать всех предупреждений с printf("%p")