特に、パラメータ*param
への変更が関数の呼び出し元に反映されず、パラメータへの変更が反映されるのはなぜ**param
ですか?
2 に答える
どちらの場合も変更は反映されますが、関数の呼び出しに依存します。
以下のケースを参照してください(コードを指定していないため、一般的なシナリオを想定しています)
有名なスワップ機能
int a=5,b=10;
swap(&a,&b) // Calling by address
void swap(int *paramA,int *paramB)
{
// Do the swap
}
関数定義だけでも*params
、変更が呼び出し元の環境に反映されていることがわかります。
ただし、それ以外の場合*param
、値渡しの場合は反映されない場合があります。つまり、
このコードを参照してください。
int a;
int *p = &a;
foo(p); // calling by value
void foo(int *param)
{
// if you do anything or change param to point to some other memory location
// then it will not be reflected back and p still be pointing to a.
}
一方、これを行う場合
foo(&p); //calling
void foo(int **param)
{
// if you do anything or change param to point to some other memory location
// then it must be reflected back in calling environment.
}
これらは、関数を呼び出すときに呼び出されPass by value
ます。Pass by Address
C
あなたがそれを手に入れたことを願っています。
int param
変数、つまりデータです。
int * param
変数へのポインタ、つまりデータのメモリアドレスです。
int * * param
変数へのポインタへのポインタ、つまりデータのメモリアドレスのメモリアドレスです。
等々。
変数を引数として関数が呼び出されると、その引数がスタックにコピーされます (値渡し)。関数がパラメーターに対して行う変更は、実際にはコピーに対して行われ、関数が戻るときに残りのスタック フレームと共に破棄されます。
void foo( int x )
{
x = 23; // any changes done on x are strictly local
}
int main()
{
int a = 42;
foo( a ); // no matter what foo() does, a will still be 42.
return 0;
}
変数へのポインタを関数の引数として渡すと、同様にコピーされますが、メモリ アドレスのコピーは依然として同じメモリ アドレスを指しているため、関数はそのメモリ アドレス (つまり、元の変数ではなく、元の変数) にアクセスできます。スタック上のそのコピー)。関数がそのメモリ アドレスの内容に対して行う変更は、関数の呼び出し元に影響します。
void foo( int * x )
{
*x = 23; // changing the contents of the memory address pointed to by x
}
int main()
{
int a = 42;
foo( &a ); // passing the address of a; a will be changed to 23.
return 0;
}
そこから自分で取ることができるはずです。