Al pensar en punteros, debe tener en cuenta algunas abstracciones.
Un objeto en la memoria. Esto puede ser de cualquier tipo (y tamaño). Un objeto entero, por ejemplo, ocupará 4 bytes en la memoria (en máquinas de 32 bits). Un objeto de puntero ocupará 4 bytes en la memoria (en máquinas de 32 bits). Como debería ser obvio, el objeto entero contiene valores enteros; un objeto puntero contiene direcciones de otros objetos.
El lenguaje de programación C permite que los símbolos (variables) representen estos objetos en la memoria. Cuando declara,
int i;
el símbolo (variable) i representa algún objeto entero en la memoria. Más específicamente, representa el valor de este objeto. Puede manipular este valor al usar i en el programa.
& le daré la dirección de este objeto en la memoria.
Un objeto de puntero puede contener la dirección de otro objeto. Usted declara un objeto puntero usando la sintaxis,
int * ptr;
Al igual que otras variables, la variable de puntero representa el valor de un objeto, un objeto de puntero. Este valor simplemente es una dirección de algún otro objeto. Establece el valor de un objeto de puntero como así,
ptr = & i;
Ahora, cuando dices ptr en el programa, te estás refiriendo a su valor, que es la dirección de i. Pero si dices * ptr, te estás refiriendo no al valor de ptr, sino más bien al valor del objeto cuya dirección está en ptr, es decir, i.
El problema con la función de intercambio es que está intercambiando valores de punteros, no los valores de los objetos que contienen estos punteros. Para llegar a los valores de los objetos, deberías usar * ptr.
La pregunta obvia sería, ¿qué diferencia hay entre esta implementación y su implementación que funciona? (Sé cuál es el problema con este, solo estoy tratando de ayudarte a encontrarlo.) [Por supuesto, todos los castores ansiosos en SO están dispuestos a saltar directamente a la respuesta.] –
Una sólida lección de choque en pasar por valor. Gracias ppl. –