2007-04-18

Apontadores e funções

Quando se passam argumentos para funções em C, estes são passados por valor (excepto os arrays, como veremos); ou seja, é criada uma cópia do argumento no stack do processador e é essa cópia que chega à função; quando a função termina essa cópia desaparece. No entanto há situações em que a passagem de argumentos por valor não é muito conveniente; por exemplo, quando queremos que modificações feitas aos argumentos no interior das funções cheguem a quem as chamou, ou quando necessitamos de passar argumentos de tamanho muito elevado (estruturas com muitos membros). Certas linguagens permitem então a passagem de parâmetros de outra forma - passagem por referência - em que a informação que chega à função é apenas o endereço do local na memória onde se encontra o valor do argumento (p. exemplo, argumentos declarados como var no Pascal). No entanto o C não permite esse mecanismo sendo necessário o uso explícito de apontadores para o implementar. (Nota: o C++ contém já esse mecanismo).

Por exemplo, se quiséssemos escrever uma função para trocar o conteúdo de duas variáveis, a forma habitual não funcionaria:

void swap(int a, int b)
{
int t;

t = a; a = b; b = t;
}

com a chamada
swap(i, j);


Para funcionar teríamos de recorrer a apontadores e ao operador
&
de obtenção do endereço de uma variável:

void swap(int *a, int *b)
{
int t;

t = *a; *a = *b; *b = t;
}

com a chamada
swap(&i, &j);


É possível também retornar apontadores como resultado de uma função, usado geralmente quando se pretende retornar informação que ocupe um grande espaço, como as estruturas:

typedef struct { float x, y, z; } coord;

coord *coor_fn(void);

void main(void)
{
coord p1;

...
p1 = *coord_fn();
...
}

coord *coor_fn(void)
{
coord p;

p = ... ;
return &p;
}


Aqui retorna-se um apontador cujo conteúdo é imediatamente de-referenciado para uma variável do tipo correspondente. Deve fazer-se esta transferência de imediato uma vez que a variável p é local à função e desaparece quando a função retorna, podendo a memória que lhe corresponde ser reutilizada.