C Memória Intermediário
Ponteiros e funções
Em C, todos os argumentos são passados por valor: a função recebe uma cópia. Para que uma função modifique uma variável do chamador, passamos o endereço dela com & e a função recebe um ponteiro. Assim, *p = 10 altera a variável original — isso é o que chamamos de passagem por referência simulada.
Ponteiros também permitem que uma função "retorne" mais de um valor: em vez de usar return, ela escreve nos endereços recebidos. Por exemplo, void minmax(int *v, int n, int *min, int *max) devolve dois resultados de uma vez.
O qualificador const documenta a intenção: const int *p é ponteiro para dado constante (não pode alterar o valor apontado), int *const p é ponteiro constante (não pode apontar para outro lugar) e const int *const p proíbe ambos. Já int **pp é um ponteiro para ponteiro, útil quando a função precisa alterar o próprio ponteiro do chamador, como em alocar(&ptr).
Pontos-chave
- Passagem por referência em C é feita passando
&variavel; a função recebe um ponteiro e escreve com*p. - Uma função pode devolver vários valores escrevendo em ponteiros de saída passados pelo chamador.
const int *pprotege o dado apontado;int *const pprotege o próprio ponteiro.int **pppermite que a função modifique o ponteiro original do chamador.- Sempre inicialize ponteiros e só desreferencie endereços válidos.
#include <stdio.h>
/* Troca dois inteiros usando ponteiros (passagem por referência). */
void troca(int *a, int *b) {
int t = *a;
*a = *b;
*b = t;
}
/* Devolve dois resultados via ponteiros de saída. */
void minmax(const int *v, int n, int *min, int *max) {
*min = *max = v[0];
for (int i = 1; i < n; i++) {
if (v[i] < *min) *min = v[i];
if (v[i] > *max) *max = v[i];
}
}
/* Altera o ponteiro do chamador usando ponteiro para ponteiro. */
void apontar_para_maior(int *a, int *b, int **destino) {
*destino = (*a >= *b) ? a : b;
}
int main(void) {
int x = 3, y = 7;
troca(&x, &y);
printf("x=%d y=%d\n", x, y);
int v[] = {4, -1, 9, 2};
int menor, maior;
minmax(v, 4, &menor, &maior);
printf("menor=%d maior=%d\n", menor, maior);
int *p = NULL;
apontar_para_maior(&x, &y, &p);
printf("maior=%d\n", *p);
return 0;
}