構造体を関数に渡しても機能しません[重複]

Aug 16 2020

以下のコードでは、mainとは別に、構造体内のintを半分に分割する関数を作成しました。

その後、新しい値を印刷したいと思います。ただし、出力値はまだ古い値です。

構造体とポインターに関する私の基本的な知識は十分ではないと思います。

誰かがこれで私を助けることができますか?どうもありがとう!!!

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);

}

回答

1 Miket25 Aug 16 2020 at 07:56

divide構造体は値で渡されるため、関数はその構造体のコピーを変更しています。関数が元の構造を変更できるように、構造体へのポインターを渡す必要があります。

void divide(person* A)
{
    person half;

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

divide元の構造のアドレスで呼び出されます

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

に渡すAdivide、のコピーAが作成されます。内部でこのコピーを変更しdivideても、でA定義したローカル変数には影響しませんmain。これを修正するdivideために、へのポインタを取るようにすることができますperson。ポインタはメモリ内のアドレスを効果的に表し、他の方法ではアクセスできない他の関数で定義されたローカル変数にアクセスするために使用できます(これがなぜであるかを理解したい場合はスタックフレームを調べてください)。

だから、実際には、あなたは変更divide:への署名をvoid divide(person *A)し、あなたがいないASSINGこの関数の最後の行にA何でもそれにA間接参照演算子を使用してを指しています:*A = halfmain次に、関数で、演算子のアドレスを使用して、それ自体ではなくのアドレスを渡します。AAdividedivide(&A)

編集:さらに良いことに、half直接実行することで一時的なものの作成を回避できます:A->age /= 2との構文糖衣構文はA->wage /= 2どこにA.xあり(*A).xますか。