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.