Tutorial de Programación en C para Linux Parte 8 – Llamada por valor Vs Llamada por puntero/dirección

En la primera parte de esta serie de tutoriales en curso, hablamos brevemente de las funciones, incluyendo su declaración y su cuerpo. De lo que no hablamos entonces fue de las múltiples formas en que se llama a las funciones. Aquí, en este tutorial, hablaremos rápidamente de las formas que existen.

En lenguaje C, puedes llamar a una función de un par de formas: llamada por valor y llamada por puntero o dirección. Vamos a discutir estos dos conceptos con algunos ejemplos fáciles de entender.

Supongamos que quieres escribir un programa que intercambie dos valores. He aquí cómo puedes hacerlo:

#include <stdio.h>
int main()
{
int a=0, b=0, c=0;

printf("Enter two integer values\n");

scanf("%d %d",&a,&b);

printf("Entered values are: %d and %d", a,b);

c = a;
a = b;
b = c;

printf("\nSwapped values are: %d and %d", a,b);

return 0;
}

Aquí tienes la salida de este código con los valores introducidos 5 y 9:

Enter two integer values
5 9

Entered values are: 5 and 9
Swapped values are: 9 and 5

Ahora, supongamos que el requisito es tener una función independiente -digamos «intercambiar»- que haga todo el trabajo relacionado con el intercambio y pueda ser llamada siempre que el programador quiera intercambiar dos valores. A continuación se muestra el código que lo hace:

#include <stdio.h>
void swap (int val1, int val2)
{
int temp = 0;

temp = val1;
val1 = val2;
val2 = temp;

printf("\nSwapped values are: %d and %d", val1,val2);

}

int main()
{
int a=0, b=0;

printf("Enter two integer values\n");

scanf("%d %d",&a,&b);

printf("Entered values are: %d and %d", a,b);

swap(a,b);

return 0;
}

Ahí lo tienes. Se ha creado una función independiente llamada «intercambio» que recibe dos valores (introducidos originalmente por el usuario y capturados en la función «principal») como argumentos, los intercambia e imprime el resultado.

La forma en que se ha llamado a «intercambio» se conoce como «llamada por valor». La razón es que, cuando se realiza la llamada, sólo se pasan a la función «swap» como argumentos los valores que tienen «a» y «b». Estos valores son recibidos por los argumentos ‘val1’ y ‘val2’, y son estas variables sobre las que se realiza el proceso de intercambio.

Esto significa que las variables ‘a’ y ‘b’ de la función ‘main’ siguen manteniendo los valores originales incluso después de que se haya realizado la operación de intercambio. Pero, ¿y si el requisito es que los valores de ‘a’ y ‘b’ se intercambien después de llamar a la función ‘swap’? Bien, aquí es donde entra en escena el método de «llamada por puntero/dirección».

Básicamente, lo que hacemos aquí es pasar la dirección de las variables (como ‘a’ y ‘b’ en nuestro caso) como argumentos. La función a la que se llama («swap» en este caso) está preparada para recibir direcciones como argumentos y luego el proceso de intercambio se realiza sobre los valores guardados en esas direcciones, lo que significa que los valores de las variables originales («a» y «b» en este caso) se intercambian.

Ahora bien, en el párrafo anterior dijimos que la función»está equipada para recibir direcciones como argumentos». Pues bien, con «equipada» queríamos decir que tiene un tipo especial de argumentos que pueden recibir direcciones. Estos argumentos son variables de tipo «puntero». Hablaremos de los «punteros» en detalle en un próximo tutorial, pero de momento, ten en cuenta que las variables puntero almacenan direcciones de memoria como valores.

He aquí cómo se declara/define un puntero a un número entero:

int *x;

Básicamente, x es una variable puntero que puede utilizarse para almacenar la dirección de memoria de una variable entera. Supongamos que «i» es una variable entera, así es como puedes hacer que «x» almacene la dirección de «i»:

x = &i;

Y siempre que quieras acceder al valor de ‘i’ a través de ‘x’, escribes ‘*x’. Por ejemplo, así es como puedes cambiar el valor de «i» a, digamos, 10:

*x = 10;

Con todo esto en mente, así es como puedes llamar a ‘swap’ utilizando el método de llamada por dirección o puntero:

#include <stdio.h>
void swap (int *val1, int *val2)
{
int temp = 0;

temp = *val1;
*val1 = *val2;
*val2 = temp;

}

int main()
{
int a=0, b=0, c=0;

printf("Enter two integer values\n");

scanf("%d %d",&a,&b);

printf("Entered values are: %d and %d", a,b);

swap(&a,&b);

printf("\nSwapped values are: %d and %d", a,b);

return 0;
}

Esta vez, en lugar de pasar los valores de «a» y «b» como argumentos, pasamos las direcciones de estas variables. En la función ‘swap’, las direcciones se reciben en dos variables puntero (‘val1’ y ‘val2’). Y utilizando las dos variables puntero, la lógica intercambia directamente los valores de ‘a’ y ‘b’.

Ésta es la salida:

Enter two integer values 
6 8 
Entered values are: 6 and 8 
Swapped values are: 8 and 6

Conclusión

Este artículo debería haberte dado al menos una idea básica de lo que son las formas de llamada a funciones «llamada por valor» y «llamada por dirección/puntero», y cuándo se pueden utilizar. Prueba los ejemplos que hemos puesto aquí y dinos en los comentarios si tienes alguna duda o consulta.

También te podría gustar...