Detalles de referencia de "C ++"

  • Concepto referenciado

La referencia no define una nueva variable, pero toma un alias para una variable existente. El compilador no abrirá espacio para la variable de referencia. Comparte un espacio de memoria con la variable a la que hace referencia.

El método de uso es el siguiente:

int main()
{
    
    
	int a=10;
	int &b=a;//定义引用类型

	printf("%d\n",a);
	printf("%d\n",b);
	printf("%p\n",&a);
	printf("%p\n",&b);
	return 0;
}

Ejecútelo y vea los resultados de la siguiente manera. Está claro que las direcciones de los dos son iguales
Inserte la descripción de la imagen aquí
. Una cosa a tener en cuenta es que el tipo de referencia debe ser del mismo tipo que la entidad de referencia. Por ejemplo, el código a anterior es de type int, por lo que el tipo de referencia también debe ser de tipo int.

  • Características de referencia

1. La referencia debe inicializarse cuando se define, como int & a; si esta oración aparece en su código, el compilador informará
un error 2. Una variable puede tener múltiples referencias, esta oración es fácil de entender, al igual que una la persona puede tener varios apodos, tal vez tus compañeros de clase te llamen XXX, los miembros de tu familia en casa te llamen XX, una razón
3. Una vez que citas una entidad, ya no puedes citar otras entidades

  • A menudo citado

Mira una serie de preguntas

//前提:
const int a = 10;
const int b = 10;
int c = 10;
double d = 1.11;

//下面这些代码谁对谁错??
int &r1 = a;
const int &r2 = b;
int r3 = b;
int *p1 = &b ;
const int *p2 = &b ;
int *p3=&c ;
const *p4=&c ;
int &r4 = d;
const int &r4 = d;

Analice uno por uno. Antes de eso, hablemos de una regla de asignación. Los permisos se pueden reducir pero los permisos no se pueden ampliar
. 1. Incorrecto, a no se puede cambiar a voluntad por sí mismo y no se puede cambiar a voluntad después de ser citado
2 .Correcto, b no se puede cambiar a voluntad, la cotización no puede cambiar arbitrariamente el
3 correcto, pero el valor b se asigna a r3, r3 incluso si el cambio también es independiente del
error b 4., b no puede cambiar, no tener permiso para ampliar
5. correctamente, con 2
6. correctamente, puede cambiar libremente C, lo mismo después de citar
7. Correcto, el permiso se puede reducir
8. Incorrecto, d es un tipo doble, r4 en realidad se refiere a la variable temporal en el medio
9. Correcto

  • Escenarios de uso referenciados

1.Hacer parámetros

Explica con un código simple

void swap(&a,&b)
{
    
    
	int c=a;
	a=b;
	b=c;
}

int main()
{
    
    
	int x1=10,x2=20;
	swap(x1,x2);
	
	cout<<x1<<endl;
	cout<<x2<<endl;
	return 0;
}

2. Como valor de retorno

¿Se puede ejecutar este código?

int Arr(int i)//改成int &Arr(int i)
{
    
    
	static int a[10]={
    
    0,1,2,3,4,5};
	return a[i];
}

int main()
{
    
    
	Arr(3)=10;
	cout<<Arr(3)<<endl;
	
	return 0;
}

No se puede ejecutar, porque cuando asigna 10 a Arr (3), en realidad no asigna un valor de 10 a [3], sino que asigna un valor de 10 a su copia. Cambiar su copia no afecta la cuerpo de una [3]. influencias. Después de la modificación está bien, porque en este momento, a la referencia de un [3] se le asigna un valor de 10, y se cambia su referencia, y también se modifica la ontología, por lo que es factible.
Un punto más, ¿es factible si borras static? No factible, porque si borras static, el valor de retorno se destruirá si el valor de retorno sale fuera de alcance, es decir, la función Arr ().
Entonces, ¿cuál crees que es el resultado del siguiente código? 3? De hecho, es 7. La razón es la misma que la anterior Cuando la función regresa, después de dejar el alcance de la función, la pila se ha devuelto al sistema, por lo que el espacio en la pila no se puede devolver como tipo de referencia. Si se devuelve como un tipo de referencia, la función no debe limitar la duración del valor devuelto.

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

Todos sabemos que el valor se usa como un parámetro o tipo de valor de retorno. Durante la transferencia y el retorno, la función no pasa directamente el parámetro real o devuelve la variable en sí, sino que pasa el parámetro formal, que es una copia temporal del parámetro actual, que es eficiente Es muy inferior, sobre todo cuando el parámetro o tipo de valor de retorno es muy grande, la eficiencia es menor, por lo que somos más eficientes al pasar por valor y devolver por referencia.

  • La diferencia entre referencias y punteros

Como se mencionó anteriormente, una referencia es un alias, no hay espacio independiente y comparte un espacio con la entidad referenciada, pero de hecho, hay espacio para la implementación subyacente de la referencia, porque la referencia se implementa en forma de punteros. .

Entonces, ¿cuál es la diferencia entre referencias y punteros?

  • La referencia se debe inicializar en la definición y no se requiere el puntero
  • Un puntero puede apuntar a cualquier entidad del mismo tipo en cualquier momento, pero una referencia no puede
  • Sin referencias NULL pero punteros NULL
  • El significado es diferente en tamaño, el resultado de referencia es el tamaño del tipo de referencia y el puntero es siempre el número de bytes ocupados por el espacio de direcciones (la plataforma de 32 bits ocupa 4 bytes)
  • Hay punteros multinivel, no referencias multinivel
  • La forma de acceder a la entidad es diferente, el puntero debe ser desreferenciado explícitamente y la referencia la maneja el propio compilador.

Parece que los punteros son más útiles que las referencias, pero ¿por qué todavía necesita usar mucho las referencias? Porque las referencias son relativamente más seguras de usar que los punteros

Supongo que te gusta

Origin blog.csdn.net/NanlinW/article/details/103051574
Recomendado
Clasificación