Desafio C
Busca em vetor com ponteiro para ponteiro e `const`
Enunciado
Escreva const int *buscar_maior(const int *v, int n, int **pos) que retorna um ponteiro para o maior elemento de v e escreve em *pos o índice desse elemento. Use const int * no parâmetro e no retorno (o vetor não deve ser modificado). No main, leia n, depois n inteiros, chame a função e imprima maior=<valor> pos=<indice>.
Requisitos
- O parâmetro e o retorno usam
const int *. - O índice é devolvido via
int **pos(ponteiro para ponteiro). - A função não altera o vetor.
- Saída no formato
maior=<valor> pos=<indice>.
Código inicial
#include <stdio.h>
const int *buscar_maior(const int *v, int n, int **pos) {
/* complete */
}
int main(void) {
int n;
scanf("%d", &n);
int v[100];
for (int i = 0; i < n; i++) scanf("%d", &v[i]);
/* chame e imprima */
return 0;
}
Saída esperada
maior=9 pos=2
Ver dica
Use uma variável int idx no main e passe &idx? Cuidado: o parâmetro é int **, então você precisa de um int *p = &idx; e passar &p.
Mostrar solução
#include <stdio.h>
/* Retorna ponteiro para o maior e escreve o índice via int **pos. */
const int *buscar_maior(const int *v, int n, int **pos) {
int idx = 0; /* índice do maior até agora */
for (int i = 1; i < n; i++) {
if (v[i] > v[idx]) idx = i; /* só lê, nunca escreve no vetor */
}
**pos = idx; /* grava o índice no int apontado */
return &v[idx]; /* ponteiro para o maior elemento */
}
int main(void) {
int n;
scanf("%d", &n);
int v[100];
for (int i = 0; i < n; i++) scanf("%d", &v[i]);
int idx = -1; /* variável que receberá o índice */
int *p = &idx; /* ponteiro para idx */
const int *maior = buscar_maior(v, n, &p); /* passamos &p: int ** */
printf("maior=%d pos=%d\n", *maior, idx);
return 0;
}
Passo a passo
const int *vpromete que a função não modifica o vetor;const int *no retorno promete o mesmo sobre o elemento devolvido.int **posé um ponteiro para o ponteiro do chamador; permite alterar para ondepaponta, se necessário.int idx = 0;guarda o índice do maior visto até agora.- O laço compara
v[i]comv[idx]e atualizaidxquando encontra algo maior. **pos = idx;desreferencia duas vezes: primeiro chega aoint *pdomain, depois aoint idx.return &v[idx];devolve o endereço do maior elemento, sem copiar o valor.- No
main,int *p = &idx;ebuscar_maior(v, n, &p)passamint **. printfimprime o valor apontado (*maior) e o índice já atualizado (idx).
Por que funciona
O retorno const int * dá acesso somente leitura ao elemento, evitando cópias. O int ** permite que a função escreva no int do chamador através de dois níveis de indireção: *pos é o ponteiro p, **pos é o int idx. O const no parâmetro documenta e garante que o vetor original não é alterado.
Erros comuns
**pos = idx;trocado por*pos = &idx;: atribui umint *a umint, gerando aviso/erro e resultado errado.- Passar
&idxdiretamente (tipoint *) para um parâmetroint **: o compilador avisa e o comportamento é indefinido. - Retornar
&v[idx]semconstno tipo de retorno: atribuir aconst int *funciona, mas o contrato de não escrita fica implícito; mantenha oconst. - Esquecer de inicializar
idxnomain: sen == 0, oprintflê lixo.
Outra forma de resolver
Sem ponteiro para ponteiro, devolvemos o índice por return e o valor por um int *: int buscar_maior(const int *v, int n, int *valor). É mais simples, mas não exercita int **. Use int ** quando a função precisa realocar ou reapontar o ponteiro do chamador (por exemplo, em alocar(&ptr)).
Saída esperada
maior=9 pos=2