3

参照渡しを使用するC++では、引数から本質的にポインタである関数のパラメータに渡したもののアドレスを参照しますよね? つまり、それらは本質的にエイリアスとすべて同じものですが、ポインタもメモリ空間を必要としませんか? したがって、パラメーター関数にあるものは何でも、渡された引数が何であれ、B を呼び出して、値のメモリ位置である A を呼び出してはなりません (A が値のメモリ位置を渡したため)。引数として)?

値渡しを使用する Java では、渡されたアドレスのコピーを作成します (たとえば、オブジェクトへの参照)。

したがって、最終的には、値渡しと参照渡しの違いが本当にわかりません。値渡しは、元の渡された引数にメモリ内のスペースを割り当て、値を指すコピーと参照渡しの両方が、値のメモリ位置を引数として渡します。関数は、値を指すために使用します。

4

3 に答える 3

4

参照渡しを使用するC++では、引数から本質的にポインタである関数のパラメータに渡したもののアドレスを参照しますよね?

いいえ。参照は、既存の変数のエイリアス (別名) です。
しかし、アセンブリ レベルでは、実装によって、参照された変数のアドレスが、呼び出された関数が使用するアドレス レジスタ (または同様のもの) に格納される場合があります (それが意味する場合)。

しかし、簡単にするために、自動的に逆参照されるポインターと考えることができます (これは、私が最初に始めたときに行ったことです)。しかし、言語の話に入ると、参照は実際にはポインターとは根本的に異なります。

つまり、それらは本質的にエイリアスとすべて同じものですが、ポインタもメモリ空間を必要としませんか?

C++ レベルのポインターは (アドレス可能であるため) スペースを必要とします。ポインタのアドレスを取得できます。基本的に、参照にはスペースは必要ありません (アドレスを取得できないため)。実装レベルでは、コンパイラが実装する方法に応じて、物理メモリの場所がある場合とない場合があります。

したがって、パラメーター関数にあるものは何でも、B を呼び出して、渡された引数が何であれ、そのメモリ位置を指すようにすべきではありません。

上記をコード例で説明していただければよかったです。しかし、私は理解していると思います。関数がインライン化されていないと仮定すると、参照として渡されるパラメーターには、元のオブジェクトへの何らかの形式のリンクが必要です (参照は常に基本的にライブ オブジェクトを参照するため)。それで、それはどのようにしますか。コンパイラの実装の詳細 (気にする必要はありません)。しかし、おそらくスタック上のポインターか、アドレスレジスター内の単なるアドレスです。

次に、値のメモリ位置はどれですか (A が値のメモリ位置を引数として渡したため)?

多分かどうか。参照には、言語レベルでの物理的な場所はありません。したがって、コンパイラはそれを使って多くの素敵な小さなトリックを実行できます。

値渡しを使用する Java では、渡されたアドレスのコピーを作成します (たとえば、オブジェクトへの参照)。

Java では、参照を値で渡します。しかし、Java 参照は基本的に、メモリー位置へのポインターにすぎません。したがって、ポインターを値で渡しています。これは使用する1つのテクニックです。幸いなことに、C++ は 1 つの手法に限定されません。

パラメータは値または参照で渡すことができます。値または参照によってオブジェクトへのポインターを渡すこともできます。そのため、状況に応じて使用する興味深いテクニックがいくつかあります。

したがって、最終的には、値渡しと参照渡しの違いが本当にわかりません。

おそらく、Java 参照 (値によって渡される) について考えているためです。

C++ で。値渡しの場合は、パラメーターとして渡される新しいオブジェクトを作成しています (つまり、元のオブジェクトのコピーを作成するため、コストがかかる可能性があります)。参照渡しの場合は、エイリアスをオブジェクトに渡しています。したがって、オブジェクトを操作すると、元のオブジェクトが変更されます。

 int inc(int val)     // pass by value
 {
     return ++val;    // increment the passed value and return as a result.
 }

 int incref(int& val) // pass by reference
 {
     return ++val;    // increment the reference.
                      // Since the reference is an alias this increment affects the
                      // original object. The result is returned.
 }

 void code()
 {
       int x = 5;
       int y = inc(x);  // x =5 and y = 6

       int a = 8;
       int b = incref(a); // a = 9 and b = 9
 }  

値渡しは、元の渡された引数にメモリ内のスペースを割り当て、値を指すコピーと参照渡しの両方が、値のメモリ位置を引数として渡します。関数は、値を指すために使用します。

すみません、それを失いました。

于 2013-08-05T04:31:22.467 に答える
0

値渡しでは、アドレスの値が計算され、実行時に渡されます。しかし、参照渡しでは値は決定されません。アドレスのみが関数に渡されます。値を自分で読み取り、メモリ位置で直接変更を加えます-値渡しのように渡された値ではありません-これは非常に重要です低レベルであり、1 つ以上のプログラムがメモリ位置で同時に操作を実行している場合、あいまいになる可能性があるため、問題が発生する可能性があります。これが、Java がポインターをサポートしていない理由の 1 つです。

値渡しでは、関数が操作を実行している間、メモリ位置のデータは変更されません。そのコピーに対して操作を実行しているためです。Javaのマルチスレッドのようなもの。

于 2013-08-05T04:12:48.273 に答える