「C ++」リファレンスの詳細

  • 参照される概念

参照は新しい変数を定義しませんが、既存の変数のエイリアスを取ります。コンパイラは参照変数用のスペースを開きません。参照する変数とメモリスペースを共有します。

使用方法は以下のとおりです。

int main()
{
    
    
	int a=10;
	int &b=a;//定义引用类型

	printf("%d\n",a);
	printf("%d\n",b);
	printf("%p\n",&a);
	printf("%p\n",&b);
	return 0;
}

それを実行して、次のように結果を確認します。2つのアドレスが同じであることは明らかです
ここに画像の説明を挿入します
。注意すべき点の1つは、参照型は参照エンティティと同じ型でなければならないということです。たとえば、上記のコードは次のとおりです。 intと入力するため、参照型もint型である必要があります。

  • 参照特性

1.参照は定義時に初期化する必要があります(int&a;など)。この文がコードに含まれている場合、コンパイラはエラーを報告
ます。2。変数には複数の参照を含めることができます。この文、人は複数のニックネームを持つことができます。おそらく、クラスメートはあなたをXXXと呼び、自宅の家族はあなたをXXと呼びます
。これは、理由の1つです。3。エンティティを引用すると、他のエンティティを引用できなくなります。

  • よく引用される

一連の質問を見てください

//前提:
const int a = 10;
const int b = 10;
int c = 10;
double d = 1.11;

//下面这些代码谁对谁错??
int &r1 = a;
const int &r2 = b;
int r3 = b;
int *p1 = &b ;
const int *p2 = &b ;
int *p3=&c ;
const *p4=&c ;
int &r4 = d;
const int &r4 = d;

1つずつ分析します。その前に、割り当てルールについて説明します。権限は減らすことはできますが、拡大
することはできません。1。間違っています。aはそれ自体で自由に変更することはできず、引用後に自由に変更することはできません
2 。正解、bは自由に変更できず、quoteは
3を任意に変更できませんが、変更がb
4から独立している場合でも、値bはr3、r3に割り当てられます。エラー、bは変更できません、しません拡大する許可を持っている
5.正しく、2
6.正しく、自由に変更できるC変更、引用後も同じ
7.正しい、許可を減らすことができる
8.間違っている、dはdouble型、r4は実際には真ん中
9.正解

  • 参照される使用シナリオ

1.パラメータを作成します

簡単なコードで説明する

void swap(&a,&b)
{
    
    
	int c=a;
	a=b;
	b=c;
}

int main()
{
    
    
	int x1=10,x2=20;
	swap(x1,x2);
	
	cout<<x1<<endl;
	cout<<x2<<endl;
	return 0;
}

2.戻り値として

このコードは実行できますか?

int Arr(int i)//改成int &Arr(int i)
{
    
    
	static int a[10]={
    
    0,1,2,3,4,5};
	return a[i];
}

int main()
{
    
    
	Arr(3)=10;
	cout<<Arr(3)<<endl;
	
	return 0;
}

Arr(3)に10を割り当てる場合、実際にはa [3]に10の値を割り当てるのではなく、そのコピーに10の値を割り当てるため、実行できません。コピーを変更しても、 a [3]の本体。影響。変更後は、この時点でa [3]の参照に値10が割り当てられ、彼の参照が変更され、オントロジーも変更されるため、実行可能であるため、問題ありません。
もう1つ、staticを削除すると実行可能ですか?実行不可能です。staticを削除すると、戻り値がスコープ外になると戻り値が破棄されるためです。つまり、関数Arr()です。
では、次のコードの出力は何だと思いますか?3?実際は7です。理由は上記と同じです。関数が戻ると、関数スコープを離れた後、スタックがシステムに戻されているため、スタック上のスペースを参照型として返すことはできません。参照型として返される場合、戻り値の存続期間は関数によって制限されてはなりません。

int &Add(int a,int b)
{
    
    
	int c=a+b;
	return c;
}

int main()
{
    
    
	int &ret =Add(1,2);
	Add(3,4);
	cout<<"Add(1,2) is:"<<ret<<endl;
	return 0;
}

値がパラメーターまたは戻り値の型として使用されることは誰もが知っています。転送および戻り中に、関数は実際のパラメーターを直接渡したり、変数自体を返したりするのではなく、正式なパラメーターを渡します。これは、効率的な実際のパラメータ特にパラメータまたは戻り値の型が非常に大きい場合は効率が低くなるため、値を渡したり参照で返したりする場合に効率が高くなります。

  • 参照とポインタの違い

前述のように、参照はエイリアスであり、独立したスペースはなく、参照されるエンティティとスペースを共有しますが、実際には、参照はポインターの方法で実装されるため、参照の基礎となる実装のためのスペースがあります。 。

では、参照とポインタの違いは何ですか?

  • 参照は定義で初期化する必要があり、ポインターは必要ありません
  • ポインタはいつでも同じタイプの任意のエンティティを指すことができますが、参照はできません
  • NULL参照はありませんが、NULLポインター
  • sizeofの意味は異なり、参照結果は参照型のサイズであり、ポインターは常にアドレス空間が占めるバイト数です(32ビットプラットフォームは4バイトを占めます)
  • マルチレベルのポインタがあり、マルチレベルの参照はありません
  • エンティティにアクセスする方法は異なり、ポインタは明示的に逆参照される必要があり、参照はコンパイラ自体によって処理されます

ポインタは参照よりも便利なようですが、なぜそれでも参照を頻繁に使用する必要があるのでしょうか。参照はポインタよりも比較的安全に使用できるため

おすすめ

転載: blog.csdn.net/NanlinW/article/details/103051574