12

次のコードでは、amp_swap()との両方star_swap()が同じことをしているように見えます。では、なぜ誰かがどちらか一方を使用することを好むのでしょうか? どちらが好ましい記法で、その理由は? それとも単に好みの問題ですか?

#include <iostream>

using namespace std;

void amp_swap(int &x, int &y)
{
    int temp = x;
    x = y;
    y = temp;
}

void star_swap(int *x, int *y)
{
    int temp = *x;
    *x = *y;
    *y = temp;
}

int main()
{
    int a = 10, b = 20;
    cout << "Using amp_swap(): " << endl;
    amp_swap(a, b);
    cout << "a = " << a << ", b = " << b << endl;
    cout << "Using star_swap(): " << endl;
    star_swap(&a, &b);
    cout << "a = " << a << ", b = " << b << endl;
    return 0;
}

御時間ありがとうございます!


関連項目

C++ のポインター変数と参照変数の違い

4

8 に答える 8

13

1 つは参照を使用しており、もう 1 つはポインターを使用しています。

NULL 参照を渡すことはできません (一方、NULL ポインターを渡すことはできます)。

したがって、次のようにします。

star_swap(NULL, NULL);

アプリケーションがクラッシュします。一方、試してみると:

amp_swap(NULL, NULL); // This won't compile

ポインターを使用する正当な理由がない限り、常に参照を使用してください。

このリンクを参照してください: http://www.google.co.uk/search?q=references+vs+pointers

于 2008-10-10T08:50:17.880 に答える
4

参照バージョンよりもポインター バージョンを優先するという議論を行うこともできます。実際、ドキュメンテーションの観点からは、入力引数が変更されるという事実を呼び出し元が認識できるため、優れています。次の 2 つの呼び出しを比較します。

swap(a, b);
swap(&a, &b); // This cries “will modify arguments” loud and clear.

もちろん、swap関数の場合、この点は意味がありません。その引数が変更されることは誰もが知っています。これがあまり明白でない他のケースがあります。C# には、refまさにこの理由でキーワードがあります。C# では、上記は次のようになります。

swap(ref a, ref b);

もちろん、この動作を文書化する方法は他にもあります。ポインターを使用することは、そのための有効な手法の 1 つです。

于 2008-10-10T09:10:25.903 に答える
2

参照を NULL にすることはできません。したがって、最初のバージョンを使用すると、呼び出し元が関数の引数の 1 つとして NULL を渡すことができなくなります。

参照を別のものを指すように再割り当てすることはできません。amp_swap()つまり、 function 内で、xyが常に同じものを参照していることがわかります。ポインター バージョンでは、(より複雑な関数で) 再割り当てxyて別のものを指すことができます。これにより、ロジックがわかりにくくなる可能性があります (はい、int *const xこの再割り当てを回避するようにパラメーターを宣言できます)。

リファレンス バージョンの関数本体は、スターが少ないため、よりきれいに見えます。

于 2008-10-10T08:50:40.297 に答える
2

これは表記の問題ではありません。

関数にパラメーターを渡す方法は 3 つあります。

  1. 値による
  2. 参照により
  3. ポインタによる

amp_swap参照によって実際のパラメーターを渡します。これは C++ でのみ導入され、有効です。

ではstar_swap、ポインターを使用してパラメーターを渡します。これが元のC-wayでした。

基本的に、C++ を使用している場合は、参照を使用することをお勧めします。変数を読みやすくするためです。ポインターが必要な場合は、ぜひ使用してください。

また、参照を使用してメソッドを宣言するときは、記号を使用することを忘れ&ないでください。そうしないと、バグが発生するためです。で参照を宣言しない場合amp_swap、関数は何もスワップしません。このように方法 1 (パラメーター値のみを渡す) を使用すると、関数内で関数のスコープ内でのみ有効な 2 つの新しい自動変数が作成されるためです。このようにして、元の外部変数は変更されません。

于 2008-10-10T08:56:51.267 に答える
2

ここを見ると、ポインターと参照の説明が見つかります。最も役立つ情報は、最初にこの引用から得られます。

参照は本質的に > const であるため、C++ では「const 参照」を宣言できません。つまり、参照をバインドしてオブジェクトを参照すると、それを再バインドして別のオブジェクトを参照することはできません。参照を宣言した後に参照を再バインドするための表記法はありません。

以下は、i を参照するように ri をバインドします。

int &ri = i;

次に、次のような割り当て:

ri = j;

ri を j にバインドしません。j の値を、ri によって参照されるオブジェクト、つまり i に割り当てます。

これがより明確であることを願っています。

于 2008-10-10T09:03:20.787 に答える
1

(int *param)ダイレクト メモリ ポインターを使用する古い C スタイルです。(int &param)参照 (生のポインターを囲む型安全なラッパー) を使用する最新の C++ スタイルです。C++ を使用している場合は、おそらく参照を使用する必要があります。

于 2008-10-10T08:50:05.993 に答える
1
  • ポインタと同様に、参照はパラメータとして渡されたデータの変更を可能にします
  • ポインターと同様に、参照はポリモーフィズムを可能にします
  • ポインターとは異なり、参照は NULL になることはありません (これは何らかのハックで実現できますが、これはコーディングというより妨害行為に似ています...)
  • ポインターとは異なり、参照は const の場合、型の昇格を有効にします (つまり、char * を受け入れる std::string パラメーターを持つ関数を持ちます)。
  • ポインターとは異なり、参照を再割り当てすることはできません。コードのある時点で参照を変更する方法はありませんが、ポインターはある時点で A を指し、別の時点で B を指し、別の時点で再び NULL を指すことができます。そして、エラーによってポインターに ++ を適用したくありません...
  • ポインターとは異なり、参照を使用すると、常に * 演算子を使用しなくても、「int」や「bool」などのプリミティブを使用する場合と同じくらい簡単にデータを操作できます。

これらの理由から、C++ では通常、参照の使用がデフォルトであり、ポインターは例外です。

したがって、一貫性を保つために、あなたが提案する2つの「スワップ」関数の間で、amp_swapを使用してソースからスターを削除します(誰もそれを使用せず、ソースに無駄なポインタコードを追加しないようにするためです).. .

于 2008-10-10T20:34:09.227 に答える
0

それらはコンピューターにとってまったく同じものです。ただし、一方は参照 (&) で、もう一方はポインター (*) です。

http://www.google.com/search?hl=ja&q=pointers+vs+references&btnG=Google+Search&aq=1&oq=pointers+vs

どちらにも用途があると思います-ポインターと同様に、より低レベルのメモリ操作を行うことができますが、参照の構文はより簡単です。

:)

于 2008-10-10T08:49:55.087 に答える