Explicación detallada de las referencias de C++ (características de las referencias, diferencia entre referencias y punteros, otros usos de las referencias)

cita

1. Introducción

En la vida, también podemos dar apodos a algunos estudiantes. Tome "Zhang Lei" como ejemplo, podemos llamarlo "Zhang Sanshi". Cuando llamamos a este apodo, naturalmente pensaremos en "Zhang Lei", "Zhang Sanshi". es el alias de Zhang Lei, y la cita se puede entender de esta manera simple: en el nivel gramatical, una cita es un alias .

2. Los operadores más problemáticos en C++

* y & en C++ tienen múltiples significados y tienen diferentes significados bajo diferentes condiciones de uso:
*

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. Definición de referencia

Una referencia no es una nueva definición de una variable, sino un alias para una variable existente.El compilador no abrirá espacio de memoria para la variable de referencia y comparte el mismo espacio de memoria con la variable a la que se hace referencia.

El formato es el siguiente :

Tipo y nombre de variable de referencia (nombre de objeto) = entidad de referencia
Tenga en cuenta que el espacio aquí es opcional, es decir

  • Puede haber un espacio antes y después del símbolo & como sigue: int & ra=a;
  • El símbolo & está al lado del tipo, de la siguiente manera: int& ra=a;
  • El símbolo & está al lado del nombre de la referencia, de la siguiente manera: int &ra=a;

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

Aquí es equivalente a una entidad que toma dos nombres como a y c, y no abre un nuevo espacio en este espacio.
inserte la descripción de la imagen aquí

4. Características de las citas

  1. Debe inicializarse al definir una referencia
  2. sin referencias nulas
  3. No existe tal cosa como una cita secundaria.
  4. Una variable puede tener múltiples referencias (es equivalente a una variable con varios alias, lo cual es posible)

Explicación:
int main()
{
int a = 10;
int& b = a;
int& x;
int& y = NULL;
int&& c = a;
}
inserte la descripción de la imagen aquí
En resumen:
la referencia en sí es una variable, pero esta variable es solo otra variable y un alias, no ocupa espacio en la memoria, ¡no es un puntero! ¡Solo un alias!

5. Comparación de punteros y referencias

Usemos la función de intercambio como ejemplo
para intercambiar dos valores enteros usando punteros:

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

Intercambiar dos punteros usando referencias:

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

Cuando el parámetro formal es un puntero: la primera oración debe afirmarse y debe juzgarse si está vacía; y cuando se usan punteros, debemos prestar atención: si estápuntero salvaje,puntero nulo,puntero de invalidación.
Cuando usamos referencias, no hay referencia NULL, no es necesario juzgar nulo y es más seguro que los punteros.

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
_ <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
_

Seis La diferencia entre referencias y punteros ( énfasis )

1. Diferencias a nivel gramatical

  1. En términos de reglas gramaticales, una variable puntero almacena la dirección de una instancia (variable u objeto);
    una referencia es un alias de una instancia.
  2. El programa asigna regiones de memoria para variables de puntero; no asigna regiones de memoria para referencias.
int main()
{
    
    
	int a = 10;
	int* ip = &a;
	int& b = a;  \\b是a的别名 并没有分配新的空间
}
  1. Desreferenciar es agregar "*" antes de usar el puntero; la referencia se puede usar directamente.
int main()
{
    
    
	int a = 10;
	int* ip = &a;
	int& b = a;  
	*ip = 100//对于指针使用加“*”
	b = 200//引用不需要“*”
	
}
  1. El valor de la variable puntero se puede cambiar para almacenar las direcciones de diferentes instancias;
    la referencia se inicializa cuando se define y no se puede cambiar después (no puede ser una referencia a otras instancias).
int main()
{
    
    
	int a = 10,b = 20;
	int* ip = &a;
	ip = &b ;
	int& c = a;
	c = b;   //b的值给c实则是把b的值给a,将a的值改为20
}
  1. El valor de una variable de puntero puede estar vacío (NULL, nullptr); no hay referencias nulas.
  2. Cuando se utiliza una variable de puntero como parámetro formal, es necesario probar su validez (juzgándolo como NULL);
    no es necesario que las referencias se consideren NULL.
  3. El uso de "sizeof" en una variable de puntero obtiene el tamaño de la variable de puntero;
    el uso de "sizeof" en una variable de referencia obtiene el tamaño de la 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));
}

resultado de la operación:
inserte la descripción de la imagen aquí

  1. En teoría, no hay límite para el número de niveles de punteros, pero solo hay un nivel de referencias.
    es decir, no hay referencias a referencias, pero puede haber punteros a punteros.

  2. Las referencias ++ tienen efectos diferentes a los punteros ++.

Por ejemplo, en términos de operaciones ++:

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

inserte la descripción de la imagen aquí

  1. Las operaciones sobre referencias reaccionan directamente a la entidad referenciada (variable u objeto).
    La operación sobre la variable puntero hará que la variable puntero apunte a la dirección de la siguiente entidad (variable u objeto), en lugar de cambiar el contenido de la entidad apuntada (variable u objeto).
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. Las variables locales u objetos en funciones no se pueden devolver por referencia o puntero.

    La dirección se puede devolver cuando la vida útil de la variable no se ve afectada por la función

2. Diferencias a nivel de montaje

En el nivel de ensamblado, una referencia es un puntero, pero una referencia no es un puntero ordinario. Es un espacio de sintaxis para punteros, y también se puede considerar como un puntero normal.

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

inserte la descripción de la imagen aquí

7. Otros usos de las referencias

  1. A menudo citado:

Una referencia constante es en realidad una referencia universal que puede referirse a variables ordinarias, constantes o constantes literales .

(1) Referirse a variables ordinarias

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

Para este problema de error: porque c no es modificable
inserte la descripción de la imagen aquí
(2) constante de referencia

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

inserte la descripción de la imagen aquí
(3) Cita constantes literales

Al hacer referencia a una constante literal, se divide en dos pasos: primero, definir un temporal para hacer referencia a la constante temporal en lugar de hacer referencia a la constante literal real 10.

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

Al hacer referencia a una matriz, se debe conocer el tamaño de la matriz

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. referencia de puntero

Dado que la referencia es una variable, también puedo darle un alias a la variable de puntero

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
*/

Descubrimos que la variable de puntero p aquí es exactamente igual que su referencia (alias) rp. Pero dado que el propósito de una referencia es similar al de un puntero, generalmente no hay necesidad de crear un alias para el puntero.

Supongo que te gusta

Origin blog.csdn.net/weixin_56935264/article/details/124669712
Recomendado
Clasificación