passare una struttura a una funzione non funziona [duplicato]

Aug 16 2020

Nel codice seguente ho creato una funzione oltre a main per dividere l'int all'interno di una struttura a metà.

Dopodiché, voglio stampare il nuovo valore. Tuttavia, il valore di stampa è ancora quello vecchio.

Credo che la mia conoscenza fondamentale di struct e pointers non sia abbastanza buona.

Qualcuno mi può aiutare con questo? Molte grazie!!!

typedef struct{
    int age;
    int wage;
}person;


void divide(person A)
{
    person half;
    half.age = A.age / 2;
    half.wage = A.wage / 2;
    
    A = half;
}

int main(void)
{
    person A;
    A.age = 30;
    A.wage = 35000;
    
    divide(A);
    
    printf("%i\n", A.age);

}

Risposte

1 Miket25 Aug 16 2020 at 07:56

La funzione dividesta modificando una copia di quella struttura poiché le strutture vengono passate per valore. Dovrai passare il puntatore alla struttura, in modo che la funzione possa modificare l'originale.

void divide(person* A)
{
    person half;

    half.age  = A->age  / 2;
    half.wage = A->wage / 2;
    
    *A = half;
}

Chiamato dividecon indirizzo di struttura originaria

divide(&A);
2 Peter Aug 16 2020 at 08:05

Quando si passa Aa divide, Aviene creata una copia di . La modifica di questa copia all'interno dividenon ha alcun effetto sulla variabile locale Adefinita in main. Per rimediare a questo, puoi divideprendere un puntatore a person. Un puntatore rappresenta effettivamente un indirizzo in memoria in modo tale da poterlo utilizzare, ad esempio, per accedere a variabili locali definite in altre funzioni che altrimenti non sarebbero accessibili (cerca gli stack frame se vuoi capire il motivo).

Quindi, in pratica si cambia divide's firma: void divide(person *A)e l'ultima riga di questa funzione non assing a A, ma a tutto ciò che Asta puntando al utilizzando l'operatore dereference: *A = half. Nella vostra mainfunzione è quindi passa l' indirizzo del Aposto di Asé per divideutilizzando l'indirizzo dell'operatore: divide(&A).

EDIT: ancora meglio, puoi evitare di creare il temporaneo halfeseguendo direttamente: A->age /= 2e A->wage /= 2dove A.xsta lo zucchero sintattico (*A).x.