web-dev-qa-db-ja.com

Cの*と&の違いは何ですか?

私はCを学んでいますが、_&_と_*_の違いをまだ理解しているかどうかはまだわかりません。

それを説明しようとさせてください:

_int a; // Declares a variable
int *b; // Declares a pointer
int &c; // Not possible

a = 10;
b = &a; // b gets the address of a
*b = 20; // a now has the value 20
_

私はこれらを手に入れました、しかしそれからそれは混乱します。

_void funct(int a) // A declaration of a function, a is declared
void funct(int *a) // a is declared as a pointer
void funct(int &a) // a now receives only pointers (address)

funct(a) // Creates a copy of a
funct(*a) // Uses a pointer, can create a pointer of a pointer in some cases
funct(&a) // Sends an address of a pointer
_

それで、funct(*a)funct(&a)の両方が正しいですよね?違いは何ですか?

5
Cristian Ceron

もともとCにはポインタがあり、参照はありませんでした。値をコピーせずにアクセスしたいだけで、実際の値ではなくアドレスを渡しているという事実は重要ではないことがよくあります。

C++は、ポインターの配管を抽象化するための参照を導入しました。 C++で関数に値を「表示」する場合は、参照をお勧めします。この関数は、参照がnullではなく、値自体であるかのようにアクセスできることが保証されています。ポインターは他の目的にも必要です。たとえば、ポインターを「再照準」するか、ポインターを使用してdeleteを指定できますが、参照を使用してこれを行うことはできません。

それらの機能します重複し、少しの歴史がなければすべきです私たちが両方を持っていることを混乱させます。

したがって、直接の質問に対する答えは、ほとんどの場合、違いがないということです。とはいえ、f(int*)は、関数がポインターがnullかどうかをチェックできるようにする場合に役立ちます。 Cを使用している場合は、ポインターが唯一のオプションです。

1
Praxeolitic

*の意味は、コンテキストによって異なります。データまたは関数の引数宣言では、それはデータ型修飾子であり、notoperatorint*はそれ自体がデータ型です。このため、次のように書くと便利です。

int* x ;

のではなく:

int *x ;

それらは同一ですが、最初の形式は、*が型名の一部であることを強調し、間接参照演算子としての使用法と視覚的に区別します。

インスタンス化されたポインタ変数に適用されると、それはdereference演算子であり、ポイントされた値を生成します。

Cの&は単なる演算子であり、オブジェクトのアドレス(またはポインタ)を生成します。宣言には使用できません。 C++では、isreferenceの型修飾子です。これはポインターに似ていますが、動作がより制限されているため、多くの場合、より安全です。

ここのコメントであなたの提案:

funct(&a) // Sends an address of a pointer

正しくありません。 aのアドレスが渡されます。それは "ポインタのアドレス"はa自体がポインタです。ポインタisアドレス。 ポインタのアドレスからintへのタイプは、int**(ポインタへのポインタ)になります。

おそらく、ポインタ変数と値変数の基本を説明する必要がありますか? ポインタは変数のメモリ内の場所を記述し、はメモリ位置の内容を記述します。

  • <typename>*は-<typename>データ型へのポインタです。
  • & * <value-variable>は、<variable>(つまり、ポインタ<variable>)のアドレスまたは場所を生成します。
  • * * <pointer-variable>は、ポインターを逆参照して、ポインターによって表されるアドレスの値を生成します。

たとえば、次のようになります。

int a = 10 ;
int* pa = &a ; 

その後

*pa == 10
0
Clifford

void funct(int &a)は、 参照 を取る関数を宣言します。参照は、関数が渡された変数を変更できるという点で概念的にはポインターですが、構文的には値のように使用されます(したがって、参照を使用するために常に逆参照する必要はありません)。

0
tskuzzy

C++は多くの点でcとは異なり、参照はその一部です。

C++コンテキストの観点から:

void funct(int * a)// aはポインターとして宣言されますこれはc..soでのポインターの使用と相関関係があるため、この機能をcの機能と比較できます。

void funct(int&a)// aはポインタ(アドレス)のみを受け取るようになりましたこれはc ++での参照の使用につながります...これをcの参照に関連付けることはできません。

これら2つの違いを明確にする良いQ&Aがあります。 C++のポインタ変数と参照変数の違いは何ですか?

0
basav

「参照による呼び出し」と呼ばれるfunc(&a)を実行すると、パラメーター「a」を関数内で実際に変更でき、加えられた変更は呼び出し元のプログラムに表示されます。これは、次のような関数から複数の値を返したい場合に便利な方法です。

int twoValues(int &x)
{
  int y = x * 2; 
  x = x + 10; 
  return y; 
}

このようにメインプログラムからこの関数を呼び出すと、次のようになります。

 int A, B; 
 B = 5; 
 A = twoValues(B); 

これにより、次のようになります。

 A holding the value 10 (which is 5 * 2) 
 and B will hold the value 15 (which is 5 + 10).

関数シグニチャに&記号がない場合、関数 "twoValues"に渡されるパラメータに加えた変更は、その関数内でのみ表示されますが、呼び出し元のプログラム(mainなど)に関する限り、同じになります。

値の配列またはリストを渡したい場合は、ポインターパラメーターを使用して関数を呼び出すと最も便利です。例:

float average ( int *list, int size_of_list) 
{
  float sum = 0; 
  for(int i = 0; i < size_of_list; i++)
   {
    sum += list[i];
    }
   return (sum/size_of_list);
}

size_of_listパラメーターは、渡す配列内の要素の数にすぎないことに注意してください(バイト単位のサイズではありません)。

これがお役に立てば幸いです。

0
MaYa