演算子は、&
演算子の「アドレス」です。soはa の値だけでなく、 を&a
意味します。address of a
これが伝えていることは、値が であっても、 a のアドレスが1002
(または、dreamlax が指摘したように、printf の使用方法に奇妙な点があるため、実際のアドレスではない可能性が高い) ということです10
。2 つの値の間に厳密な相関関係はないことに注意してa=121765
ください&a=494260
。
変数のアドレスを知ることで、変数が「参照」または「指している」特定の値/オブジェクトを操作できます。コピーを操作するのではなく、その特定の値/オブジェクトを操作する関数が必要な場合は、変数のアドレスを渡す必要があります。
次のコードを取ります (完全なコードである必要はありません)。
int main(void)
{
int a = 10;
doIt(a);
printf("after doIt: %d", a);
doItByReference(&a);
printf("after doItByReference: %d", a);
}
void doIt(int val)
{
val = 13;
}
void doItByReference(int *val)
{
*val = 15;
}
を呼び出すと、doIt
が保持する値が渡さa
れ、別のアドレスにある新しい整数変数にその値がコピーされます。a
関数はこの複製コピーを自由に変更でき、元の変数に変更は見られません。
ただし、呼び出しdoItByReference
は のアドレスを渡しますa
。指定されたアドレスの値に加えられた変更は、 に加えられた変更として反映されますa
。
これは、特定のオブジェクトに変更を加えて、それらの変更を元のコピーに反映させたい場合に便利です。ただし、元のコピーの値を変更したくない場合でも、値をコピーする必要がないため、これはパフォーマンス面で役立ちます。4 バイト (正確な値は重要ではありません) などの単純な int の場合、これは重要ではありません。
ただし、数千または数百万バイトの構造体があるとします。
struct LargeStruct
{
int buffer[134217728];
};
void doIt(LargeStruct buffer)
{
// ... do something
}
void doItByReference(LargeStruct *buffer)
{
// ... do something
}
今回は、 を呼び出すたびに、数百万バイトのオブジェクトdoIt
全体をコピーする必要がLargeStruct
ありますが、 doItByReference を呼び出すと既存のオブジェクトが使用されるだけで、コピーは必要ありません。