Desafio C
Inverter array in-place com dois ponteiros
Enunciado
Escreva uma função void inverter(int *v, int n) que inverta os elementos de um array in-place, usando dois ponteiros (um do início, outro do fim). No main, aplique ao array {1, 2, 3, 4, 5} e imprima o resultado separado por espaços.
Requisitos
- A função deve receber
int *veint n. - Usar dois ponteiros que se movem para o centro, trocando os valores.
- Não usar array auxiliar.
- Imprimir os elementos na ordem invertida.
Código inicial
#include <stdio.h>
void inverter(int *v, int n) {
/* use dois ponteiros para trocar os elementos */
}
int main(void) {
int v[5] = {1, 2, 3, 4, 5};
/* chame inverter e imprima */
return 0;
}
Saída esperada
5 4 3 2 1
Ver dica
Comece com int *esq = v; e int *dir = v + n - 1;. Enquanto esq < dir, troque *esq e *dir e mova os dois.
Mostrar solução
#include <stdio.h>
void inverter(int *v, int n) {
int *esq = v; /* aponta para o primeiro */
int *dir = v + n - 1; /* aponta para o ultimo */
while (esq < dir) {
int tmp = *esq; /* troca os valores apontados */
*esq = *dir;
*dir = tmp;
esq++; /* avanca para o centro */
dir--;
}
}
int main(void) {
int v[5] = {1, 2, 3, 4, 5};
inverter(v, 5); /* v decai para int * */
for (int i = 0; i < 5; i++) {
printf("%d%s", v[i], i < 4 ? " " : "\n");
}
return 0;
}
Passo a passo
int *esq = v;aponta para o primeiro elemento.int *dir = v + n - 1;usa aritmética para apontar para o último.- O
while (esq < dir)compara endereços: continua enquanto os ponteiros não se cruzarem. - Salvamos
*esqemtmp, copiamos*dirpara*esqetmppara*dir, trocando os valores. esq++edir--aproximam os ponteiros do centro.- No
main,inverter(v, 5)passa o endereço do primeiro elemento; a função altera o array original. - O laço final imprime os valores já invertidos.
Por que funciona
A função recebe um ponteiro, então trabalha diretamente na memória do array do main — sem cópia. A aritmética de ponteiros permite calcular o último elemento como v + n - 1 e comparar posições com <. A troca via * altera os valores no local, cumprindo o requisito de inverter in-place.
Erros comuns
- Usar
while (esq <= dir)em arrays de tamanho ímpar: o elemento do meio seria trocado consigo mesmo, o que é inofensivo, mas em pares pode causar troca dupla. Prefira<. - Esquecer
n - 1emdir = v + n: aponta para uma posição além do array. - Trocar os ponteiros em vez dos valores:
int *t = esq; esq = dir; dir = t;só muda as variáveis locais, não o array. - Passar
inverter(&v, 5)em vez deinverter(v, 5):&vtem tipoint (*)[5], incompatível comint *.
Outra forma de resolver
Usar índices em vez de ponteiros:
for (int i = 0, j = n - 1; i < j; i++, j--) {
int tmp = v[i]; v[i] = v[j]; v[j] = tmp;
}
É equivalente, porque v[i] é *(v + i). A versão com ponteiros deixa explícita a caminhada na memória.
Saída esperada
5 4 3 2 1