関数に渡される引数として単純な変数名を使用すると、関数はこの変数名に対応する値を取得し、その目的のために関数によって作成された新しいメモリ位置に新しい変数としてインストールします。しかし、配列のアドレスが引数として関数に渡されるとどうなりますか?関数は別の配列を作成し、呼び出し元のプログラムの配列からその配列に値を移動しますか?
7 に答える
いいえ、何かのアドレスを関数に渡すと、関数はそのアドレスを取得します。技術的には、アドレスのコピーを取得します(これはすべて値渡しであり、ポインターを使用して参照渡しをシミュレートするだけです)。そのため、関数内でそのアドレスを変更しても、戻り値には影響しません。
アドレスを間接参照することにより、アドレスが指すものを変更できます。例えば:
void changeValA (int x) {
x = 42; // x is 42 but a is unchanged.
}
void changeValB (int *x) {
*x = 42; // *x (hence a) is now 42
}
:
int a = 31415; // a is 31415
changeValA (a); // a is still 31415
changeValB (&a); // a is now 42
配列のアドレスを渡すことは、配列自体を渡すこととほとんど同じです。このような状況では、配列は最初の要素のアドレスに減衰します。
いいえ。
配列が関数に渡されると、配列の最初の要素へのポインターに減衰します。これにより、関数は元のコードとまったく同じように配列要素にアクセスできます。これには、関数へのポインターを渡すことで要素を変更する機能が含まれますが、配列のコンパイル時のサイズをsizeof
.
基本的に、これは:
void func(int a[]);
// ...
int i[] = { 0, 1, 2, 3, 4 };
func(i);
効果的にこれを行っています:
void func(int *a);
// ...
int i[] = { 0, 1, 2, 3, 4 };
func( & (i[0]) );
このため、配列を受け取る関数はその長さを知る方法がないことに注意してください。そのため、配列 (またはポインター) を受け取るほとんどすべての関数は、サイズ パラメーターも受け取ります。
アドレスが指すメモリ空間ではなく、アドレスの数値がスタックにコピーされます!
配列の名前は、その開始点へのポインターとして扱うことができます。したがって、配列を関数に渡すときは、ポインターを渡しているかのようになります。新しいアレイは作成されません。
いいえ。配列の参照/アドレスのみが移動します。したがって、配列の関数内での更新は、渡された配列に影響します。
C では、配列は常に参照によって渡されます (つまり、先頭へのポインターのみが渡されます)。
本当に配列を値で渡したい場合は、それを構造体でラップして、構造体を渡すことができます。配列を値で渡す方法は他にありません。
いいえ、配列のアドレスを渡すと(ポインターについて話していると思います)、ポインターのコピーが関数に渡されます。