[C con Clase] Referencias VS punteros

Steven Davidson srd4121 en njit.edu
Mar Feb 9 20:14:57 CET 2010


Hola Utopic,

Utopic wrote:
> Hola gente,
> 
> La pregunta és simple: ¿por què hay referencias y punteros? ¿en que
> se diferencian? No digo que la respuesta tambien sea senzilla ;-)
> 

La referencia es un sobrenombre - un nombre alternativo - para una 
variable. El puntero es una variable que guarda un dirección de memoria 
como valor.

Podemos usar las referencias para crear apodos a variables en un 
programa. Lo usual es usar referencias para pasar parámetros por 
referencia, valga la redundancia, y así conseguir el valor original en 
la invocación a tal función. También podemos hacer algo parecido con los 
punteros, pero conceptualmente sigue siendo una copia de un puntero.

A diferencia de las referencias, los punteros pueden usarse para 
manipular direcciones de memoria. Por ejemplo, al crear y destruir 
dinámicamente memoria, tenemos que usar punteros:

int *ptr = new int[100];
...
delete[] ptr;

Ten presente que C++ se basa en C, y en C, no existen las referencias. 
Por ello, C usaba punteros para emular el paso por referencia. 
Consecuentemente, al agregar las referencias en C++, existen dos formas 
de pasar la información original a una función: con punteros o con 
referencias.

Desde un punto de vista de diseño y como una buena práctica, se intenta 
pasar por referencia (usando referencias) a aquellas funciones que 
describen claramente que se requieren referencias. Por ejemplo,

void intercambiar( int &a, int &b );
int &leerTeclado( int &ref );
...
if( num1 < num2 )
{
   int c = leerTeclado( num1 );
   num2 = num1 * c;
}
intercambiar( num1, num2 );

Estas funciones obviamente requieren referencias por su diseño. Sin 
embargo, para otras funciones, no es algo aparente que estemos pasando 
variables por referencia. Por ejemplo,

unsigned int &asignarBits( unsigned int &bits, int &nCant );
...
unsigned int bBits;
int n = 10;
...
asignarBits( bBits, n );

Se entiende que el primer parámetro se pase por referencia porque va a 
ser modificado, pero el segundo no es tan claro, por lo que no sería 
buena idea hacerlo.

La función anterior beneficiaría si usáramos punteros. Por ejemplo,

unsigned int &asignarBits( unsigned int &bits, int *nCant );
...
asignarBits( bBits, &n );

Podemos ver claramente que el segundo parámetro va a ser modificado y 
esto nos fuerza a escribir el parámetro como un puntero. Básicmente, 
esto agrega claridad a nuestro programa.

El otro uso de las referencias es el ahorro de memoria y tiempo al pasar 
parámetros a las funciones, como constantes. Por ejemplo,

struct Datos { ... };  // sizeof(Datos) = 145 (bytes)

void func( const Datos &ref );

Así no tenemos que pasar toda la información, pero tampoco queremos 
modificar la variable que la contiene.

> Por ejemplo, puedo usar referencias, como en r, o punteros como en s:
> 
> ----------------- .cpp----------------- 
> 
> #include <iostream>
> 
> using namespace std;
> 
> int main() {
> 
> 	int a;
> 	int &r = a;
> 	a = 10;
> 	cout << "r: " << r << endl;
> 	r = 15;
> 	cout << "r: " << r << endl;
> 
> 	int b;
> 	int *s = &b;
> 	b = 10;
> 	cout << "s: " << *s << endl;
> 	*s = 20;
> 	cout << "s: " << *s << endl;
> 
> 	return 0;
> }
> 
> ----------------------------------
> 
> La sintaxis és algo diferente, alguna otra diferencia? como funcionan
> las referencias y los punteros una vez compilado? en que casos

Lo más probable es que internamente la referencia sea un puntero tratado 
especialmente por el compilador. Por ejemplo,

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

El compilador hará lo siguiente internamente:

void intercambiar( int *a, int *b )
{
   int temp = *a;
   *a = *b;
   *b = temp;
}

Como puedes ver, la referencia es como un puntero que es tratado para 
que acceda implícitamente al valor apuntado. Sin embargo, esto no es una 
regla establecida por el lenguaje, como muchas "reglas" que tengan que 
ver con la implementación de la gramática. Es decir, cada compilador 
puede implementar las reglas gramaticales como quiera. En este caso, lo 
más fácil y normal sería usar punteros para implementar referencias.

> aconsejarias referencias y cuando punteros?
> 

Bueno, esto ya lo he explicado más arriba.


Espero haber aclarado la inquietud.

Steven





Más información sobre la lista de distribución Cconclase