Page 173

CC 2003, 2008 Andr´ es Marzal e Isabel Gracia

1 2

3 Funciones

#include <stdio.h> #include <math.h>

3 4 5 6

struct Punto { float x, y, z; };

7 8 9 10 11

float distancia( struct Punto p ) { return sqrt( p.x*p.x + p.y*p.y + p.z*p.z ); }

12 13 14 15

int main(void) { struct Punto pto;

16

pto.x = 1; pto.y = 1; pto.z = 1;

17 18 19 20

printf ("Distancia al origen: %f\n", distancia(pto) ); return 0;

21 22 23

}

Al pasar un registro a la funci´ on, C copia en la pila cada uno de los valores de sus campos. Ten en cuenta que una variable de tipo struct Punto ocupa 24 bytes (contiene 3 valores de tipo float). Variables de otros tipos registro que definas pueden ocupar cientos o incluso miles de bytes, as´ı que ve con cuidado: llamar a una funci´on pasando registros por valor puede resultar ineficiente. Por cierto, no es tan extra˜ no que un registro ocupe cientos de bytes: uno o m´as de sus campos podr´ıa ser un vector. Tambi´en en ese caso se estar´ıa copiando su contenido ´ıntegro en la pila. Eso s´ı, como est´ as pasando una copia, las modificaciones del valor de un campo en el cuerpo de la funci´ on no tendr´ an efectos perceptibles fuera de la funci´on. Como te hemos anticipado, tambi´en puedes pasar registros por referencia. En tal caso s´olo se estar´a copiando en la pila la direcci´ on de memoria en la que empieza el registro (y eso son 4 bytes), mida lo que mida ´este. Se trata, pues, de un paso de par´ametros m´as eficiente. Eso s´ı, has de tener en cuenta que los cambios que efect´ ues a cualquier campo del par´ametro se reflejar´an en el campo correspondiente de la variable que suministraste como argumento. Esta funci´ on, por ejemplo, define dos par´ametros: uno que se pasa por referencia y otro que se pasa por valor. La funci´ on traslada un punto p en el espacio (modificando los campos del punto original) de acuerdo con el vector de desplazamiento que se indica con otro punto (traslacion): 1 2 3 4 5 6

void traslada( struct Punto * p , struct Punto traslacion) { (*p).x += traslacion.x; (*p).y += traslacion.y; (*p).z += traslacion.z; }

Observa c´ omo hemos accedido a los campos de p. Ahora p es una direcci´on de memoria (es de tipo struct Punto *), y *p es la variable apuntada por p (y por tanto, es de tipo struct Punto). El campo x es accedido con (*p).x: primero se accede al contenido de la direcci´on de memoria apuntada por p, y luego al campo x del registro *p, de ah´ı que usemos par´entesis. Es tan frecuente la notaci´ on (*p).x que existe una forma compacta equivalente: 1 2 3 4 5 6

void traslada(struct Punto * p, struct Punto traslacion) { p->x += traslacion.x; p->y += traslacion.y; p->z += traslacion.z; }

La forma p->x es absolutamente equivalente a (*p).x. Introducci´ on a la Programaci´ on con C

167

Profile for esLibre.com

Introducción a la programación con c  

Introducción a la programación con c  

Advertisement