C ++参照操作に関するレコードの学習

序文

学んだ後は忘れてしまう自分の特別な体格を考慮して、意味のある知識を記録することにしました。
この記事では、引用に関するC ++関連の知識に焦点を当てます。


関数パラメーターとしての参照

ここでは、3つの関数パラメータ設定方法を包括的に比較します。

  • 値渡し
  • アドレス転送(ポインタ)
  • 参照渡し

使用されるコードは次のとおりです。

// arrayone.cpp -- small arrays of integers
#include <iostream>

using namespace std;

//值传递
void swap01(int a, int b)
{
    
    
    int temp = a;
    a = b;
    b = temp;
}

//地址传递
void swap02(int *a, int *b)
{
    
    
    int temp = *a;
    *a = *b;
    *b = temp;
}
//引用传递
void swap03(int &a, int &b)
{
    
    
    int temp = a;
    a = b;
    b = temp;
}

int main()
{
    
    
    int a = 10;
    int b = 20;

    swap01(a, b);
    cout << "swap01" << endl;
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
    swap02(&a, &b);
    cout << "swap02" << endl;
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
    swap03(a, b);
    cout << "swap03" << endl;
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;

    system("pause");
    return 0;
}

参照は変数のエイリアスとして理解でき、エイリアスと元の名前は同じメモリスペースを指しているため、2つの操作は完全に同等です。
一般的な参照の初期化は次のとおりです。

int a = 10;
int &b = a;

このように、aとbは完全に同等です。
コードでは、2つの変数の値の交換を使用して、関数呼び出しの効果を観察しました。
その中で、値の転送は正式なパラメータのみを変更し、アドレスと参照の転送は両方とも実際のパラメータを変更します。したがって、メイン関数でaとbの値を出力すると交換の効果があります。
アドレス転送と参照転送を比較すると、参照転送は関数定義で参照転送を形成するためにアンパサンドを追加するだけでよく、アドレス転送と同じ機能を実現できます。アドレス転送の繰り返しの逆参照と複雑な定義と比較すると、それは多くのことです。より簡単に。
関数の操作効果は次のとおりです。
ここに画像の説明を挿入


関数の戻り値としての参照

ここには2つの主な懸念事項があります。

  1. ローカル変数への参照を返さない
  2. 関数呼び出しは左辺値として使用できます

あまりナンセンスではありません。コードに移動してください。

// arrayone.cpp -- small arrays of integers
#include <iostream>

using namespace std;

//引用做函数的返回值
//1.不要返回局部变量的引用
int &test01() //这里是用引用的方式做返回值定义函数
{
    
    
    int a = 10; //存放在栈区,不能返回(局部变量)
    return a;   //非法操作
}

//2.函数的调用可以作为左值
int &test02() //这里是用引用的方式做返回值定义函数
{
    
    
    static int a = 10; //静态变量,存放在全局区,全局区数据在程序结束后释放
    return a;          //合法操作
}

int main()
{
    
    
    int &ref = test02();
    cout << "ref = " << ref << endl;
    cout << "ref = " << ref << endl;

    test02() = 1000; //这里返回了a的引用,相当于就是a,ref是a的别名
    cout << "ref = " << ref << endl;
    cout << "ref = " << ref << endl;
    system("pause");
    return 0;
}

最初のポイントとして、ローカル変数を参照値として返さないでください。サブ関数test01()を参照できます。ここでの関数定義メソッドは、参照を割り当てるために使用できる関数の戻り値として参照を使用することです。 (エイリアス)返された変数に。
この操作は変数のエイリアスであるため、元の名前をローカル変数にすることはできません。これは、元の名前がスタック領域に存在し、関数呼び出しの最後に解放されるためです。したがって、test01()での戻りは不正な操作です。
2番目のポイントとして、参照を返す関数の場合、関数の呼び出しを左辺値として使用できます。サブ関数test02()を確認します。変更点は、定義された変数が静的変数であるということです。静的変数が存在します。プログラムのグローバル領域にあります。プログラムの終了時にリリースされるため、プログラムのライフサイクルに常に存在し、関数の戻り値として使用できます。
ここでは、のエイリアスとして参照参照を使用します。
いわゆる関数呼び出しは左辺値として使用でき、次のように理解できます。ここでは、静的変数aに値1000が割り当てられ、証明方法が出力ref(aのエイリアス)になります。その参照は1000になりました。
関数の結果は次のとおりです
ここに画像の説明を挿入
。さらに、aは実際にはサブ関数の外に出ることができません。たとえば、エラーが報告されます。

test02() = 1000; //这里返回了a的引用,相当于就是a,ref是a的别名
cout << "a = " << a << endl;//不能这么使用

左辺値としての関数がどのような機能を持っているかはまだ不明であり、友人はコメント領域にメッセージを残して議論することを歓迎します。


参照の本質

参考までに、その本質はポインタ定数です。詳細については、次のコードを参照してください。

// arrayone.cpp -- small arrays of integers
#include <iostream>

using namespace std;

//引用的本质
int ref = 0;//自己没事找事看看会出现什么现象
//发现是引用,转换为 int* const ref = &a;
void func(int &ref)
{
    
    
    ref = 100; // ref是引用,转换为*ref = 100
}

int main()
{
    
    
    cout << "ref = " << ref << endl;

    int a = 10;
    int &ref = a; //自动转换为 int* const ref = &a; 指针常量是指针指向不可改,也说明为什么引用不可更改

    ref = 20; //内部发现ref是引用,自动帮我们转换为: *ref = 20;

    cout << "a = " << a << endl;
    cout << "ref = " << ref << endl;

    func(a);
    
	cout << "a = " << a << endl;
    cout << "ref = " << ref << endl;

    system("pause");
    return 0;
}

コードを簡単に紹介します。
メイン関数定義aから始めて(最初に他の表示を無視します)、ref参照を作成すると、コンパイラーは次のコードを使用します。

int &ref = a;

ポインタ定数として認識される初期化コード:

int * const ref = &a;

いわゆるポインタ定数は、固定アドレスを指すポインタを定義し、アドレスが配置されているメモリの値は変更される可能性があります。ただし、C ++は参照を自動的に認識するため、コードの入力の複雑さをある程度(他の機能が必要です)。
その後、参照参照が使用されるたびに、システムはそれを次のように自動的に認識します。

ref = 10;//引用的用法
*ref = 10;//编译器识别到的

このようにして、参照についてより深く理解することができます。
作成されたサブ関数自体については、あまり興味をそそられませんでした。関数パラメーターとして渡されるのは参照だけでしたが、プログラムの操作についていくつか質問があり
ました。同じ名前のグローバル変数があるかどうか。 、繰り返し定義と参照の使用、どのような効果がありますか?
そのため、作成者はrefという名前のグローバル変数を作成しました。具体的なプログラム操作の結果は次のとおりです。
ここに画像の説明を挿入
プログラムは、ref参照を定義する前に、グローバル変数で定義されたデータを出力することがわかります。
ref参照を定義した後、refのグローバル変数を上書きしているようで、後続の操作が参照として使用されています。
調査する具体的な理由は何ですか?


一定の参照

引用は「エイリアス」の方法です。このエイリアスで元の名前の値が変更されないようにするには、どうすればよいですか。
ここでは定数参照が使用されます
定数参照を定義する方法について説明します。コードは次のとおりです。

	//int &ref = 10;//非法引用,引用要引向合法的内存空间
    //该行程序相当于:int temp = 10;  const int &ref = temp;
    int const &ref = 10; //没有原名(一般不这么用)

最初の行は、有効なメモリスペースが参照されていない(メモリが見つからない)ため、間違った定義方法を示しています。
3行目は、正しい定義方法を示しています。ご覧のとおり、次のようになります。

	int temp = 10;  
	const int &ref = temp;

ただし、この一時はプログラムに表示されません(存在しません)。これは、コンパイラーによって内部的に実行される同等のアクションです。
定数参照に関しては、サブ関数が実際のパラメーターを変更するのを防ぐために、関数呼び出しで一般的に使用されます。エラーコードは次のとおりです。

void showValue(const int &temp)
{
    
    
    temp = 1000;//不小心修改了这个数据,报错!
    cout << "temp = " << temp << endl;
}

ここでは、仮パラメータが定数参照として設定されているため、その値をサブ関数で変更することはできません。変更しないと、エラーが報告されます。


結論

上記はリファレンスの簡単な要約であり、後でderを追加し続けます!

おすすめ

転載: blog.csdn.net/qq_41883714/article/details/109343125