[C con Clase] Pregunta sobre Punteros

Davidson, Steven srd4121 en njit.edu
Sab Feb 2 02:28:30 CET 2013


Hola Edwin,

2013/2/1 Edwin Alexander Bohorquez Gamba <edwinprogramacion en hotmail.es>

>
>
[CORTE]

Si en este ejemplo se esta pasando un puntero por valor, no entiendo porque
> las modificaciones se conservan al abandonar la funcion?. Lo digo porque la
> salida del programa es :
> Variable a :150
> Variable *p : 150  //esta salida no la entiendo, si los cambios en el
> propio puntero son locales y no se conservan al regresar, la salida no
> deberia quedar:  Variable *p : 100 ?.
>
>
Recuerda que estamos enviando la variable de tipo puntero, 'p', como
parámetro y no la variable del entero, 'a'. Al entrar en la función,
creamos la variable, 'q', que es una copia del parámetro original 'p'. El
comportamiento es el siguiente:


int a = 100;
int *p = &a;

// Invocamos: funcion(p)
int *q = p;  // Copiamos el parámetro
*q += 50;
// Terminamos de invocar: funcion(p)

cout << "Variable a: " << a << endl;
cout << "Variable *p: " << *p << endl;


Como puedes ver, 'p' no cambia, pero nada impide que la variable apuntada
por 'p' sea modificada, que es justamente lo que ha ocurrido en este
ejemplo. A través de 'q', podemos cambiar el entero apuntado, pero no
podemos cambiar el valor de 'p', porque 'q' es una copia de 'p'. Te pongo
otro ejemplo,

void funcion( int *q )
{
  *q += 50;
  ++q;
}


Aquí modificamos el valor de la variable apuntada por 'q' y luego
incrementamos 'q' - modificando su valor - para que apunte al "siguiente"
entero en memoria. Sin embargo, el parámetro original, 'p', no es
modificado, porque pasamos 'p' por copia.

Y la otra pregunta es: Usando el mismo codigo, pero ahora pasando el
> puntero por referencia, porque la salida del programa es la misma?, si en
> el anterior se paso por valor y en este por referencia, porque los
> resultados son iguales?
>
>
Esto es porque no hemos cambiado la implementación de 'funcion()'; es
decir, seguimos modificando el valor de la variable apuntada por 'q' - y
por 'p'. Como no modificamos el valor de 'q', el valor de 'p' no se ve
alterado y por tanto, seguimos apuntando a la misma variable, 'a'. Lo
puedes ver claramente aquí,

void funcion( int * &q )
{
  *q += 50;
}

Ahora bien, si cambiamos lo anterior por esto:

void funcion( int *q )
{
  *q += 50;
  ++q;
}

Entonces, 'p' se verá modificado, apuntando al siguiente entero en memoria.
Obviamente, no aconsejo hacer esto tal y como esté escrito en el ejemplo,
porque no hay ningún "entero" que controlemos, así que puede haber
problemas durante la ejecución del programa. Pero, podríamos hacer este
cambio

int main()
{
  int a[10] = { 100, 200 };
  int *p = a;  // o incluso, int *p = &a[0];
  funcion( p );

  cout << "Variable a: " << a << endl;
  cout << "Variable *p: " << *p << endl;

  return 0;
}

void funcion( int * &q )
{
  *q += 50;
  ++q;
}

Debería aparecer en pantalla:

Variable a: 101
Variable *p: 200

Recuerda que una variable de tipo  puntero sigue siendo una variable. Las
reglas para pasar variables o valores por parámetro son las mismas
irrelevantemente del tipo de variable o valor. Si pasamos el valor de tipo
'int', las reglas son las mismas que si pasamos el valor de tipo 'int ***'.


Espero que esto aclare las dudas.

Steven
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20130201/039a966e/attachment.html>


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