C++ fourth bullet: reference

Referenced concept

In life, we often call you another name because of our own characteristics. For example, friends who are familiar with you usually call you Xiao Chen. In C++, there is also a concept similar to nicknames—quotes.
First of all, we need to understand that reference does not define a new variable, just like someone gave you a nickname, but you are still you, and you have not become another person. The same is true for references. The compiler will not open up memory space for references. , It and the variable it references share the same memory space.
Instructions:

#include <iostream>
using namespace std;

//类型& 引用变量名(对象名) = 引用实体
void TestReft()
{
    
    
	int a = 10;
	int & ra = a;//定义引用类型(注意:引用类型必须和引用实体是相同类型的)

	printf("%p\n", &a);
	printf("%p\n", &ra);
}

int main()
{
    
    
	TestReft();
	return 0;
}

The results of running the above program are as follows, we see that the address of variable a and the address of a reference ra are exactly the same.
Insert picture description here

Referenced characteristics

1. The reference must be initialized when it is defined.
This is the same as giving someone an alias in life. We must know that person to give him an alias
. 2. A variable can have multiple references.
This is the same as one person. Many aliases are the same.
3. Once an entity is referenced, other entities cannot be referenced.
Although there are many people whose aliases are the same in life, two identical aliases appear in a C++ program, and the compiler recognizes It does not come out, so it is not allowed.

scenes to be used

The reference can be used as a parameter or as a return value.
1. Make parameters

void Swap(int& a, int& b)
{
    
    
	int temp = a;
	a = b;
	b = temp;
}

2. Make the return value

int& count()
{
    
    
	static int n = 0;
	n++;
	return n;
}

It should be noted that if the function returns out of the scope of the function, if the returned object has not been returned to the system, you can use the return by reference, if it has already been returned to the system, you must use the return by value.
What does this sentence mean?
Let's take a look at the following example first:

#include <iostream>
using namespace std;

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;
	system("pause");
	return 0;
}

Operation result:
Insert picture description here
Is it strange, we did not modify the value of ret, but the output is that the value of ret has changed, then we print out the addresses of ret and c in the above program

#include <iostream>
using namespace std;

int& Add(int a, int b)
{
    
    
	int c = a + b;
	printf("c的地址是:%p\n", &c);
	return c;
}
int main()
{
    
    
	int &ret = Add(1, 2);
	printf("ret的地址是:%p\n", &ret);
	Add(3, 4);
	//cout << "Add(1,2) is :" << ret << endl;
	system("pause");
	return 0;
}

Operation result: After
Insert picture description here
printing the addresses of c and ret, we found that their addresses are exactly the same, because ret is a reference to the return value c of the function. When the function runs, the space of the local variable c in the function body is taken back by the system. At this time, ret actually refers to an illegal space, but when the Add function ends, the garbage data in the stack frame is not cleaned up, so ret can also see the garbage data in the space. When we do it for the second time When this function is called, the function changes the value in the space, and the value of ret also changes.

Comparison of pass-by-value and pass-by-reference efficiency

1. When used as a parameter
Code:

#include <iostream>
using namespace std;

#include <time.h>

struct A{
    
     int a[100000]; };
void TestFunc1(A a){
    
    }
void TestFunc2(A &a){
    
    }

void TestRefAndValue()
{
    
    
	A a;
	//以值作为参数
	size_t begin1 = clock();
	for (int i = 0; i < 100000; i++)
	{
    
    
		TestFunc1(a);
	}
	size_t end1 = clock();
	//以引用作为参数
	size_t begin2 = clock();
	for (size_t i = 0; i < 100000; i++)
	{
    
    
		TestFunc2(a);	
	}
	size_t end2 = clock();
	//分别计算两个函数运算完成的时间
	cout << "TestFunc1(A)-time:" << end1 - begin1 << endl;
	cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl;
}
int main()
{
    
    
	TestRefAndValue();
	system("pause");
	return 0;
}

Operation result:
Insert picture description here
2. As the return value
Code:

#include <iostream>
using namespace std;

#include <time.h>

struct A{
    
     int a[100000]; };

A a;//值返回
A TestFunc1(){
    
     return a; }
A& TestFunc2(){
    
     return a; }

void TestReturnByReValue()
{
    
    
	//以值作为返回类型
	size_t begin1 = clock();
	for (size_t i = 0; i < 100000; i++)
	{
    
    
		TestFunc1();
	}
	size_t end1 = clock();
	//以引用作为返回类型
	size_t begin2 = clock();
	for (size_t i = 0; i < 100000; i++)
	{
    
    
		TestFunc2();
	}
	size_t end2 = clock();
	//计算两个函数运算完成之后的时间
	cout << "TestFunc1(A)-time:" << end1 - begin1 << endl;
	cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl;
}
int main()
{
    
    
	TestReturnByReValue();
	system("pause");
	return 0;
}

operation result:
Insert picture description here

The difference between reference and pointer

1. In terms of grammatical concept, a reference is an alias, there is no independent space, and a space is used with its reference entity.
2. There is actually room for the underlying implementation, because the reference is implemented in the way of pointers.
Code:

#include <iostream>
using namespace std;

int main()
{
    
    
	int a = 10;

	int& ra = a;
	ra = 20;

	int * pa = &a;
	*pa = 20;
	return 0;
}

Disassembly comparison of reference and pointer:
Reference:
Insert picture description here
Pointer:
Insert picture description here
The difference between reference and pointer:
1. A reference must be initialized when it is defined.
2. After a reference is referenced to an entity during initialization, it cannot refer to other entities, and the pointer can be in any When pointing to any entity
3. There is no NULL reference, but there is a NULL pointer
4. In sizeof, the meaning is different, the result of the reference is the size of the reference type, but the pointer can always be the number of bytes in the address space (occupies under 32-bit platforms) (4 bytes)
5. Reference self-added and referenced entities increase by 1. Pointer self-addition refers to the size of a type offset afterwards.
6. References are relatively safer to use than pointers.

Guess you like

Origin blog.csdn.net/qq_43825377/article/details/109514113