Learning records about C++ reference operations

Preface

In view of my special physique that I will forget after learning, I decided to simply record some meaningful knowledge.
In this article, focus on c++ related knowledge about citation.


Reference as function parameter

Here we comprehensively compare three function parameter setting methods, namely:

  • Pass by value
  • Address transfer (pointer)
  • Pass by reference

The code used is as follows:

// 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;
}

Reference can be understood as an alias for the variable, the alias and the original name point to the same memory space, so that the operations of the two are completely equivalent.
A typical reference initialization is as follows:

int a = 10;
int &b = a;

In this way, a and b are completely equivalent.
In the code, we used the exchange of the values ​​of two variables to observe the effect of the function call.
Among them, the value transfer only changes the formal parameters, and the address and reference transfer both change the actual parameters. Therefore, printing the values ​​of a and b in the main function will have the effect of exchange.
Comparing address transfer and reference transfer, reference transfer only needs to add an ampersand to form a reference transfer in the function definition, and it can achieve the same function as address transfer. Compared with the repeated dereference and complex definition of address transfer, It's much easier.
The function operation effect is as follows:
Insert picture description here


Reference as function return value

There are two main concerns here:

  1. Do not return references to local variables
  2. Function call can be used as lvalue

Not much nonsense, just go to the code!

// 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;
}

For the first point, do not return a local variable as a reference value. You can refer to the subfunction test01(). The function definition method here is to use the reference as the function return value, which can be used to assign a reference (alias) to the returned variable.
Since this operation is to give a variable an alias, the original name cannot be a local variable, because it exists in the stack area and is released when the function call ends, so the return in test01() is an illegal operation.
For the second point, for the function that returns a reference, the call of the function can be used as an lvalue. Observe the sub-function test02(). The change is that the defined variable is a static variable. The static variable exists in the global area of ​​the program. Released when the program ends, so it always exists in the program life cycle and can be used as a function return value.
Here we use a reference ref as an alias for a.
The so-called function call can be used as an lvalue, which can be understood in this way. Here, the static variable a is assigned a value of 1000, and the proof method is output ref (alias of a). It can be seen that ref has become 1000.
The result of the function is as follows:
Insert picture description here
In addition, a can not actually get outside of the sub-function, for example, an error will be reported:

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

It is still unclear what function the function as an lvalue has, and friends are welcome to leave a message in the comment area for discussion.


The essence of reference

For reference, its essence is a pointer constant. For details, you can refer to the following code:

// 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;
}

Briefly introduce the code:
starting from the main function definition a (ignore other displays first), when we create a ref reference, the compiler will use the code:

int &ref = a;

Initialization code recognized as a pointer constant:

int * const ref = &a;

The so-called pointer constant defines a pointer that points to a fixed address, and the value of the memory where the address is located can change. However, because C++ automatically recognizes the reference, it can reduce the input complexity of the code to a certain extent (there must be other functions ).
Afterwards, whenever the reference ref is used, the system will automatically recognize it as:

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

In this way, we have a deeper understanding of references.
For the created sub-function itself, it did not arouse much interest to me. It was only a reference to be passed as a function parameter, but there were some questions about the program operation:
if there is a global variable with the same name, repeated definition and use of reference, there will be What effect?
So the author created a global variable named ref, and the specific program operation results are as follows:
Insert picture description here
It can be seen that the program outputs the data defined by the global variable before defining the ref reference.
After defining the ref reference, it seems to overwrite the global variable of ref, and the subsequent operations have been used as references.
What are the specific reasons to be explored? ? ?


Constant reference

Quoting is a way of "aliasing". If we don't want this alias to not change the value of the original name, what should we do? Constant reference
will be used here . Let me talk about the method of defining constant references, the code is as follows:

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

The first line shows the wrong way of defining, because no valid memory space is referenced (the memory cannot be found).
The third line shows the correct way of definition. As you can see, it is equivalent to:

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

However, this temp is not displayed in the program (does not exist), it is an equivalent action done internally by the compiler.
As for constant references, they are generally used in function calls to prevent sub-functions from modifying actual parameters. The error codes are as follows:

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

Here, the formal parameter is set as a constant reference, so its value cannot be modified in the sub-function, otherwise an error will be reported.


Conclusion

The above is a brief summary of the reference, and we will continue to add der later!

Guess you like

Origin blog.csdn.net/qq_41883714/article/details/109343125