- En aquest apartat es tracta el concepte de pas de paràmetres per referència, doncs es tracta de rebre l'adreça d'una variable i, per tant, un paràmetre per referència és llavors un punter. Es tracta de definir els paràmetres d'una funció com a punters a variables del tipus associat al paràmetre (tipus més asterísc, seguit del nom del paràmetre). Quan es cridi a la funció, però, caldrà anar amb compte de passar l'adreça de les variables i no el valor (cal aplicar l'operador '&' davant el nom de les variables que es passen com a paràmetre).
ex 3.11: Aquest exemple mostra com definir el pas de variables de tipus enter per referència. El programa principal crida a una funció que intercanvia el valor de dos variables enteres si la primera variable és menor que la segona. Com que passem les adreces de les variables, els canvis des de la funció a través dels punters afecten al contingut d'aquestes variables:
#include <stdio.h> void maxmin(int *x, int *y) /* dos paràmetres per referència */ { int temp; if(*x < *y) { temp = *x; /* intercanviar valors variables externes */ *x = *y; /* associades als paràmetres (punters) */ *y = temp; } } void main(void) { int a,b; printf("introdueix 2 números:\n"); scanf("%d",&a); /* scanf() també necessita l'adreça de les */ scanf("%d",&b); /* variables perquè les ha de modificar */ maxmin(&a,&b); /* passem l'adreça de les variables amb '&' */ printf("màxim : %d\n",a); printf("mínim : %d\n",b); }
- Quan es tracta de passar un vector com a paràmetre és molt aconsellable fer-ho per referència. En el cas dels paràmetres només cal escriure uns claudàtors sense cap número dins. Per exemple:
void codifica(char s[]) { int i=0; while(s[i++] != '\0') s[i]++; }
- En el cas dels strings, però, s'acostuma a definir els paràmetres com a punters a char, però és equivalent al mètode anterior;
ex 3.12: Definició de paràmetre string com a punter. El programa demana una frase i crida a una funció per a que la codifiqui i retorni la seva longitud:
#include <stdio.h> int codifica(char *s) { int n=0; while(s[i++] != '\0') { s[i]++; /* accés a un punter a char com si fos un vector */ n++; } return(n); } void main(void) { int a; char frase[80]; printf("introdueix una frase:\n"); gets(frase); a = codifica(frase); /* el nom del vector sense claudàtors és l'adreça base del vector */ printf("frase codificada\n"); printf("%s\n",frase); printf("%d car. codificats\n",a); }
- En el cas dels tuples per paràmetre cal anar amb compte, ja que el C permet passar-les per valor (fa una còpia del contingut a la pila). Si les dades estructurades ocupen molt d'espai serà interessant passar-les per referència. Quan es passen per referència l'accés als camps del paràmetre és farà amb l'operador '->', ja que es tracta d'un punter a una estructura;
ex 3.13: El següent exemple mostra el pas de paràmetres de tuples tant per valor (només lectura) com per referència (lectura/escriptura):
#include <stdio.h> typedef struct { float x; float y;} punt2D; void preguntar_punt(punt2D *p) /* pas per referència */ { printf("\tcoordenada x : "); scanf("%f",&(p->x)); /* passar l'adreça dels camps de */ printf("\tcoordenada y : "); /* l'estructura apuntada per p */ scanf("%f",&(p->y)); } void puntmig(punt2D *p1, punt2D p2) { p1->x = (p1->x + p2.x) / 2; /* per referència: p1->x */ p1->y = (p1->y + p2.y) / 2; /* per valor: p2.x */ } void main(void) { punt2D a,b; preguntar_punt(&a); preguntar_punt(&b); punt_mig(&a,b); /* si és per referència, operador '&' */ printf("\n(%.2f,%.2f)\n",a.x,a.y); }