Detailed explanation of C++ references (characteristics of references, difference between references and pointers, other uses of references)

quote

1. Introduction

In life, we may also give nicknames to some students. Take "Zhang Lei" as an example, we can call him "Zhang Sanshi". When we call this nickname, we will naturally think of "Zhang Lei" , "Zhang Sanshi" is Zhang Lei's alias, and the quotation can be understood in this simple way: on the grammatical level, a quotation is an alias .

Two. The more troublesome operators in C++

* and & in C++ have multiple meanings, and have different meanings under different usage conditions:
*

int *p = &a;   /1.指针
a = a * b;     /2.乘法
*p = 100;      /3.指向

&

int c = a&b;    /1.位运算 转换为二进制
int *p = &a;    /2.取地址
int  a = 100;
int & ar = a;   /3.引用

3. Definition of reference

A reference is not a new definition of a variable, but an alias for an existing variable. The compiler will not open up memory space for the reference variable, and it shares the same memory space with the referenced variable.

The format is as follows :

Type & reference variable name (object name) = reference entity
Note that the space here is optional, ie

  • There can be a space before and after the & symbol; as follows: int & ra=a;
  • The & symbol is next to the type, as follows: int& ra=a;
  • The & symbol is next to the reference name, as follows: int &ra=a;

int main()
{
int a =100; \\定义变量名
int b = a;\\将a的值赋给变量
int &c = a;\\引用 将c作为a的别名 c11中成为左值引用
return 0;
}

Here it is equivalent to an entity taking two names as a and c, and does not open up a new space in this space.
insert image description here

4. Features of citations

  1. Must be initialized when defining a reference
  2. no null references
  3. There is no such thing as a secondary citation
  4. A variable can have multiple references (it is equivalent to a variable with several aliases, which is possible)

Explanation:
int main()
{
int a = 10;
int& b = a;
int& x;
int& y = NULL;
int&& c = a;
}
insert image description here
In short:
the reference itself is a variable, but this variable is just another variable and an alias, it does not occupy memory space, it is not a pointer! Just an alias!

5. Comparing pointers and references

Let's use the swap function as an example
to swap two integer values ​​using pointers:

int my _swap (int*ap, int*bp)
{
    
    
	assert(ap != NULL && bp != NULL);
	int tmp = *ap;*ap = *bp;*bp = *ap;
}
int main()
{
    
    
	int x = 10, y = 20;
	my_swap{
    
    &x,&y);
	cout<< "x = " << x << " y = " << y << endl;
	return 0;
}

Swap two pointers using references:

void my_swap (int& a,int& b)
{
    
    
	int tmp = a;a = b;
	b = tmp;
}
int main ()
{
    
    
	int x = 10, y = 20;my_swap(x,y) ;
	cout << " x = " << x<< " y = " << y << endl;
	return 0;
}

When the formal parameter is a pointer: the first sentence must be asserted, and it must be judged whether it is empty; and when using pointers, we need to pay attention: whether it iswild pointer,null pointer,invalidation pointer.
When we use references, there is no NULL reference, no need to judge null, and it is safer than pointers

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
所以:能不使用指针就尽量不要使用指针!
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Six. The difference between references and pointers ( emphasis )

1. Differences at the grammatical level

  1. In terms of grammatical rules, a pointer variable stores the address of an instance (variable or object);
    a reference is an alias of an instance.
  2. The program allocates memory regions for pointer variables; it does not allocate memory regions for references.
int main()
{
    
    
	int a = 10;
	int* ip = &a;
	int& b = a;  \\b是a的别名 并没有分配新的空间
}
  1. Dereferencing is to add "*" before using the pointer; the reference can be used directly.
int main()
{
    
    
	int a = 10;
	int* ip = &a;
	int& b = a;  
	*ip = 100//对于指针使用加“*”
	b = 200//引用不需要“*”
	
}
  1. The value of the pointer variable can be changed to store the addresses of different instances;
    the reference is initialized when it is defined and cannot be changed afterwards (it cannot be a reference to other instances).
int main()
{
    
    
	int a = 10,b = 20;
	int* ip = &a;
	ip = &b ;
	int& c = a;
	c = b;   //b的值给c实则是把b的值给a,将a的值改为20
}
  1. The value of a pointer variable can be empty (NULL, nullptr); there are no null references.
  2. When a pointer variable is used as a formal parameter, its validity needs to be tested (judging NULL);
    references do not need to be judged NULL.
  3. Using "sizeof" on a pointer variable gets the size of the pointer variable;
    using "sizeof" on a reference variable gets the size of the variable.
int main()
{
    
    
	double dx = 10;
	double* dp = &dx;
	double& a = dx; 
	printf("sizeof(dp):%d\n", sizeof(dp));
	printf("sizeof(a):%d", sizeof(a));
}

operation result:
insert image description here

  1. In theory, there is no limit to the number of levels of pointers; but there is only one level of references.
    i.e. there are no references to references, but there can be pointers to pointers.

  2. ++references have different effects than ++pointers.

For example in terms of ++ operations:

int main()
(
	int ar[5] = {
    
     1,2,34,5 };
	int* ip = ar; //数组首元素地址
	int& b = ar[O]; //数组首元素的别名叫b
	++ip;  //由0下标的地址指向1下标的地址
	++b;  //由0下标指向1下标
}

insert image description here

  1. Operations on references react directly to the referenced entity (variable or object).
    The operation on the pointer variable will make the pointer variable point to the address of the next entity (variable or object); instead of changing the content of the pointed entity (variable or object).
int main()
(
	int ar[5] = {
    
     1,2,34,5 };
	int* ip = ar; //数组首元素地址
	int& b = ar[O]; //数组首元素的别名叫b
	++(*ip); //值由1>>2 
	(*ip)++; //所有表达式结束后 进行++ 
	//有括号 先取ip的值与*结合 然后++为所指之物的++
	int x = *ip++;
	//没有括号 先将ip的值取出 与*结合 把所指之物取出(此时已与*结合完) 然后将ip取出进行++ ++后的值回写给ip 将值存储到x中
	//通过()提高了优先级
}
  1. Local variables or objects in functions cannot be returned by reference or pointer.

    The address can be returned when the lifetime of the variable is not affected by the function

2. Differences at the assembly level

At the assembly level, a reference is a pointer, but a reference is not an ordinary pointer. It is a syntax slot for pointers, and it can also be regarded as a regular pointer.

int main()
{
    
    
	int a = 10;
	int* ip = &a;
	int& x = a;
	*ip = 100;
	x = 200;
}

insert image description here

7. Other uses of references

  1. Often cited:

A constant reference is actually a universal reference that can refer to ordinary variables, constants, or literal constants .

(1) Refer to ordinary variables

int main()
{
    
    
	int a = 10;
	int & b = a;
    const int& c = a;
    b += 10;
    a += 10;
    c += 10;
    return 0;
}

For this error problem: because c is not modifiable
insert image description here
(2) reference constant

int main()
{
    
    
    int a = 10;
    const int b =20;
    int& x = a;
    int& y = b;  //error 不安全
    const int& y = b; //ok
    const int& z =10; //ok
    return 0;
}

insert image description here
(3) Quote literal constants

When referencing a literal constant, it is divided into two steps. First, define a temporary to refer to the temporary instead of referencing the real literal constant 10.

int main()
{
    
    
    int a = 10;
    const int& z =10; //ok
    //int tmp =10;
    //const int &z = tmp;
    return 0;
}
  1. array reference

When referencing an array, the size of the array must be known

int main()
{
    
    
    int a = 10;
    int b = 10;
    int ar[5] = {
    
     1,2,3,4,5 };
    int& x = ar[0];  //ok
    int(&x)[5] = ar; //ok   没有[5]无法编译通过
  
    return 0;
}
  1. pointer reference

Since the reference is a variable, I can also give the pointer variable an alias

int main()
{
    
    
	int a = 100;
	int *p = &a;
	int * &rp = p;
 
	cout << a << endl;
	cout << *p << endl;
	cout << *rp << endl; //这里为什么要将*放在前面,因为p的类型是 int * 作为一个整体哦!!
 
	cout << p << endl;
	cout << rp << endl;
 
	getchar();
	return 0;
}
/*
100
100
100
012FF84C
012FF84C
*/

We found that the pointer variable p here is exactly the same as its reference (alias) rp. But since the purpose of a reference is similar to that of a pointer, there is generally no need to alias the pointer.

Guess you like

Origin blog.csdn.net/weixin_56935264/article/details/124669712