web-dev-qa-db-ja.com

ポインタ引数を渡していますか、C ++で値渡ししていますか?

ポインタ引数を渡していますか、C++で値渡ししていますか?ポインタへの変更自体はメソッドの外には反映されないことがわかりました。ただし、ポインターを逆参照することで行う変更は反映されます。

その場合、関数への引数としてポインターへのポインターを使用して、ポインター値を関数内でそのように変更することは、許容できる/標準的な手順ですか?

29
Sulla

はい、両方に。

ポインターは他の場合と同様に値で渡されます。つまり、ポインタ変数の内容(ポイントされたオブジェクトのアドレス)がコピーされます。つまり、関数本体のポインターの値を変更しても、古いオブジェクトを指す外部ポインターにはその変更が反映されません。ただし、ポイントされているオブジェクトの値を変更できます。

ポインターに加えられた変更を外部ポインターに反映させる(別のポインターを指すようにする)には、2レベルの間接参照(ポインターからポインター)が必要です。関数を呼び出すときは、&ポインタの名前の前。これは、Cの標準的な方法です。

C++を使用する場合は、参照よりもポインターを使用することをお勧めします(以下、ポインターへのポインターにも使用)。

why参照はポインタよりも優先されるため、いくつかの理由があります。

  • リファレンスは、関数本体のポインタよりも構文上のノイズが少ない
  • 参照はポインタよりも多くの情報を保持し、コンパイラに役立つ可能性があります

参照の欠点は主に次のとおりです。

  • これらはCの単純な値渡しの規則に違反します。パラメーターに関する関数の動作を理解するために何が必要ですか(それらは変更されますか?)。確かに関数プロトタイプも必要です。しかし、これはCを使用するときに必要な複数のポインターレベルよりも悪くはありません。
  • これらはCではサポートされていないため、CプログラムとC++プログラムの両方で機能するコードを作成するときに問題になる可能性があります(ただし、これは最も一般的なケースではありません)。

ポインターからポインターへの特定のケースでは、違いはほとんど単純ですが、参照を使用すると、両方のレベルのポインターを削除して、ポインターからポインターへの代わりに1つの参照のみを渡すことも簡単な場合があります。

35
kriss

私はここで混乱を理解しています。 「値渡し」と「参照渡し」の概念は、そうであるように見えてもそれほど明確ではありません。コンピュータはこれらの概念を認識しておらず、それに従って動作しないことを覚えておいてください。コンピュータはタイプについて知りません。したがって、ポインターと値を区別しません。例を挙げて説明してみましょう。

void func1(int x)
{
   x = 5;
}

void func2(int *x)
{
   int a;
   x = &a;
}

どちらの関数でも操作は同じです。引数を取得して変更します。 2番目の関数では* xを変更せず、xを変更することに注意してください

これらの関数を呼び出すと、

int y = 10;

func1(y); //value of y does not change

func2(&y); //value of &y does not change, but the value of the address which y points may change. 

基本的に、すべての関数呼び出しは「値による呼び出し」ですと言いたいです。しかし、ポインタ型の場合、メモリ内の別のアドレスの内容を変更する方法があります。

func2 なので

void func2(int *x)
{ 
   *x = 5; 
}

次に、これは「参照による呼び出し」の実際のケースになります。

9
Atilla Baspinar

はい、Cと同じです。

その場合、関数への引数としてポインターへのポインターを使用して、ポインター値を関数内でそのように変更することは、許容できる/標準的な手順ですか?

その場合?なんでしょう? &修飾子を使用して実際の参照を使用できます。

void func(type &ref);
0
nils

ポインタを使用した値渡し例で説明します。

void f(int *ptr)
{
   cout<<*ptr;
}


int main ()
{
   int a=10;
   int *aptr=&a;
   f(aptr);
   return 0;
} 

ここで、メイン関数のaは、内容が10でアドレスが00F8FB04(想定)の整数変数です。 aptrは整数へのポインタであり、整数変数aのアドレスを格納するため、aptrの内容は00F8FB04である整数変数aのアドレスです。 aptrを関数の引数として渡すと、aptrの内容(つまりアドレス)だけが関数のパラメーターにコピーされます。したがって、ptrはaptrのコンテンツのコピー(つまり、アドレス00F8FB04)を受け取ります。

0
Umair Mubasher

ポインター自体を変更する可能性がある場合は、ポインターへのポインターまたはポインターへの参照のいずれかを使用します。元の質問に対して、技術的には、はい、すべてのパラメーターは値で渡されます。

0
Jim Buck