Introdução
A aritmética de ponteiros (pointer arithmetic) é uma funcionalidade poderosa em C que permite manipular endereços de memória através da adição ou subtração de valores. Uma das aplicações mais comuns da aritmética de ponteiros é a travessia de arrays (array traversal). Usando ponteiros, podemos mover-nos eficientemente através de arrays, tanto em direção direta quanto inversa.
Neste laboratório, você aprenderá como criar e inicializar arrays, configurar ponteiros para acessar elementos de arrays e usar a aritmética de ponteiros para percorrer arrays. Esta técnica é fundamental na programação em C e forma a base para muitas operações avançadas de manipulação de dados.
Criando um Programa C Básico
Vamos começar criando um novo arquivo C no editor VSCode. Este arquivo conterá nosso programa principal para a travessia de arrays usando ponteiros.
No WebIDE, localize o painel Explorer no lado esquerdo e navegue até o diretório
~/project.Clique com o botão direito na pasta
projecte selecione "New File" (Novo Arquivo). Nomeie o arquivo comomain.c.Copie a seguinte estrutura básica do programa C no arquivo:
#include <stdio.h>
int main() {
printf("Array Traversal using Pointers\n");
return 0;
}
Salve o arquivo pressionando Ctrl+S ou usando File > Save (Arquivo > Salvar) no menu.
Vamos compilar e executar este programa para garantir que tudo esteja configurado corretamente. Abra um terminal no WebIDE selecionando Terminal > New Terminal (Terminal > Novo Terminal) no menu e execute:
cd ~/project
gcc main.c -o main
./main
Você deve ver a seguinte saída:
Array Traversal using Pointers
Isso confirma que seu ambiente de desenvolvimento C está funcionando corretamente. Nos próximos passos, modificaremos este programa para trabalhar com arrays e ponteiros.
Declaração e Inicialização de Arrays e Ponteiros
Nesta etapa, aprenderemos como declarar um array e um ponteiro, que são os componentes fundamentais para a travessia de arrays usando ponteiros.
Entendendo Arrays e Ponteiros
Um array em C é uma coleção de elementos do mesmo tipo armazenados em locais de memória contíguos. Por exemplo, um array de inteiros com 5 elementos reservará espaço para 5 inteiros na memória, um após o outro.
Um ponteiro é uma variável que armazena o endereço de memória de outra variável. Podemos usar ponteiros para acessar indiretamente o valor armazenado em um endereço de memória específico.
Vamos modificar nosso arquivo main.c para incluir um array e um ponteiro:
#include <stdio.h>
int main() {
printf("Array Traversal using Pointers\n\n");
// Declare and initialize an array of 5 integers
int arr[5] = {10, 20, 30, 40, 50};
// Declare a pointer of integer type
int *ptr;
// Print the array elements using array notation
printf("Array elements using array notation:\n");
for(int i = 0; i < 5; i++) {
printf("arr[%d] = %d\n", i, arr[i]);
}
return 0;
}
Neste código:
- Declaramos um array de inteiros
arrcom 5 elementos e o inicializamos com os valores 10, 20, 30, 40 e 50. - Declaramos um ponteiro de inteiro
ptrque será usado posteriormente para apontar para os elementos do array. - Imprimimos os elementos do array usando a notação tradicional de array.
Compile e execute o programa para ver os elementos do array:
gcc main.c -o main
./main
Você deve ver a seguinte saída:
Array Traversal using Pointers
Array elements using array notation:
arr[0] = 10
arr[1] = 20
arr[2] = 30
arr[3] = 40
arr[4] = 50
Na próxima etapa, conectaremos o ponteiro ao array e acessaremos os elementos do array usando o ponteiro.
Ligando Ponteiros com Arrays e Travessia Direta
Nesta etapa, estabeleceremos a conexão entre nosso ponteiro e o array e, em seguida, usaremos o ponteiro para percorrer o array na direção para frente.
Conectando um Ponteiro a um Array
Em C, o nome de um array sem um índice representa o endereço do primeiro elemento do array. Isso significa que podemos atribuir este endereço diretamente a uma variável ponteiro.
Vamos modificar nosso arquivo main.c para vincular o ponteiro ao array e percorrê-lo:
#include <stdio.h>
int main() {
printf("Array Traversal using Pointers\n\n");
// Declare and initialize an array of 5 integers
int arr[5] = {10, 20, 30, 40, 50};
// Declare a pointer of integer type
int *ptr;
// Assign the address of the first element of the array to the pointer
ptr = arr; // This is equivalent to ptr = &arr[0]
// Print the array elements using array notation
printf("Array elements using array notation:\n");
for(int i = 0; i < 5; i++) {
printf("arr[%d] = %d\n", i, arr[i]);
}
// Print the array elements using pointer notation
printf("\nArray elements using pointer notation (forward traversal):\n");
for(int i = 0; i < 5; i++) {
printf("*(ptr + %d) = %d\n", i, *(ptr + i));
}
return 0;
}
Neste código atualizado:
- Atribuímos o endereço do primeiro elemento do array
arrao ponteiroptr. - Adicionamos um novo loop que percorre o array usando aritmética de ponteiros.
- A expressão
*(ptr + i)acessa o valor no local de memóriaptr + i. Quandoié 0, este é o primeiro elemento do array; quandoié 1, é o segundo elemento e assim por diante.
Compile e execute o programa para ver os resultados:
gcc main.c -o main
./main
Você deve ver a seguinte saída:
Array Traversal using Pointers
Array elements using array notation:
arr[0] = 10
arr[1] = 20
arr[2] = 30
arr[3] = 40
arr[4] = 50
Array elements using pointer notation (forward traversal):
*(ptr + 0) = 10
*(ptr + 1) = 20
*(ptr + 2) = 30
*(ptr + 3) = 40
*(ptr + 4) = 50
Observe que ambos os métodos produzem a mesma saída. Isso demonstra que a aritmética de ponteiros pode ser usada para acessar elementos de array, assim como a indexação tradicional de array.
Implementando o Incremento de Ponteiro para a Travessia de Array
Na etapa anterior, acessamos os elementos do array usando a expressão *(ptr + i). Embora isso funcione perfeitamente bem, C fornece uma maneira mais concisa de percorrer um array usando ponteiros: o operador de incremento (++).
Quando incrementamos um ponteiro, ele se move para o próximo local de memória com base no tamanho do tipo de dados ao qual ele aponta. Para um ponteiro de inteiro, incrementá-lo o move para o próximo inteiro na memória.
Vamos modificar nosso arquivo main.c para usar o incremento de ponteiro para a travessia do array:
#include <stdio.h>
int main() {
printf("Array Traversal using Pointers\n\n");
// Declare and initialize an array of 5 integers
int arr[5] = {10, 20, 30, 40, 50};
// Declare and initialize a pointer to the first element of the array
int *ptr = arr; // Same as ptr = &arr[0]
// Print the array elements using pointer incrementation
printf("Array elements using pointer incrementation:\n");
for(int i = 0; i < 5; i++) {
printf("*ptr = %d\n", *ptr);
ptr++; // Move the pointer to the next element
}
// Reset the pointer to the beginning of the array
ptr = arr;
// Print all elements in a single line using pointer incrementation
printf("\nAll elements in a single line: ");
for(int i = 0; i < 5; i++) {
printf("%d ", *ptr++); // Print and then increment
}
printf("\n");
return 0;
}
Neste código atualizado:
- Inicializamos o ponteiro
ptrdiretamente quando o declaramos. - Dentro do primeiro loop, usamos
*ptrpara acessar o elemento atual e, em seguida, usamosptr++para mover para o próximo elemento. - Após o primeiro loop, redefinimos
ptrpara apontar para o início do array novamente. - No segundo loop, usamos o operador de pós-incremento
*ptr++, que primeiro usa o valor atual deptre, em seguida, o incrementa.
Compile e execute o programa para ver os resultados:
gcc main.c -o main
./main
Você deve ver a seguinte saída:
Array Traversal using Pointers
Array elements using pointer incrementation:
*ptr = 10
*ptr = 20
*ptr = 30
*ptr = 40
*ptr = 50
All elements in a single line: 10 20 30 40 50
Isso demonstra como usar o incremento de ponteiro para percorrer um array. O ponto-chave é que ptr++ leva em consideração automaticamente o tamanho do tipo de dados quando ele se move para o próximo elemento.
Implementando a Travessia Inversa usando Decremento de Ponteiro
Nas etapas anteriores, percorremos o array na direção para frente. Agora, vamos aprender como percorrer o array na direção inversa usando o decremento de ponteiro.
Para a travessia para trás, precisamos:
- Inicializar o ponteiro para apontar para o último elemento do array
- Decrementar o ponteiro para mover para trás através do array
Vamos modificar nosso arquivo main.c para implementar a travessia para trás:
#include <stdio.h>
int main() {
printf("Array Traversal using Pointers\n\n");
// Declare and initialize an array of 5 integers
int arr[5] = {10, 20, 30, 40, 50};
// Forward traversal using pointer increment
int *ptr = arr;
printf("Forward traversal using pointer increment:\n");
for(int i = 0; i < 5; i++) {
printf("%d ", *ptr);
ptr++;
}
printf("\n\n");
// Backward traversal using pointer decrement
// Point to the last element of the array
ptr = &arr[4]; // or ptr = arr + 4
printf("Backward traversal using pointer decrement:\n");
for(int i = 0; i < 5; i++) {
printf("%d ", *ptr);
ptr--; // Move the pointer to the previous element
}
printf("\n\n");
// Alternative approach: Start from the last element and decrement in the loop condition
printf("Alternative backward traversal approach:\n");
for(ptr = &arr[4]; ptr >= arr; ptr--) {
printf("%d ", *ptr);
}
printf("\n");
return 0;
}
Neste código atualizado:
- Primeiro, realizamos uma travessia para frente usando o incremento de ponteiro.
- Para a travessia para trás, definimos o ponteiro para o último elemento do array usando
ptr = &arr[4]. - Dentro do loop, imprimimos o elemento atual e, em seguida, decrementamos o ponteiro usando
ptr--. - Também mostramos um método alternativo onde o decremento faz parte da instrução de atualização do loop for.
Compile e execute o programa para ver os resultados:
gcc main.c -o main
./main
Você deve ver a seguinte saída:
Array Traversal using Pointers
Forward traversal using pointer increment:
10 20 30 40 50
Backward traversal using pointer decrement:
50 40 30 20 10
Alternative backward traversal approach:
50 40 30 20 10
Isso demonstra como percorrer um array nas direções para frente e para trás usando aritmética de ponteiros. A capacidade de incrementar e decrementar ponteiros facilita a movimentação através de arrays em qualquer direção.
Resumo
Neste laboratório, você aprendeu como percorrer arrays usando ponteiros na programação C. Aqui estão os principais conceitos que cobrimos:
Noções Básicas de Array e Ponteiro:
- Arrays em C armazenam elementos em locais de memória contíguos
- Ponteiros armazenam endereços de memória e podem ser usados para acessar esses locais
Relação Ponteiro-Array:
- O nome do array (sem índice) representa o endereço do primeiro elemento
- Podemos atribuir este endereço a um ponteiro para estabelecer uma conexão com o array
Técnicas de Travessia para Frente:
- Usando aritmética de ponteiros:
*(ptr + i) - Usando incremento de ponteiro:
*ptrseguido porptr++ - Combinando desreferenciação e incremento:
*ptr++
- Usando aritmética de ponteiros:
Técnicas de Travessia para Trás:
- Inicialize o ponteiro para o último elemento:
ptr = &arr[size-1] - Use decremento de ponteiro:
ptr--para mover para trás - A condição do loop pode verificar quando o ponteiro atinge o início do array
- Inicialize o ponteiro para o último elemento:
A aritmética de ponteiros é um recurso poderoso em C que permite a manipulação eficiente da memória e oferece flexibilidade ao trabalhar com arrays e outras estruturas de dados. Essa técnica forma a base para conceitos de programação mais avançados, como alocação dinâmica de memória, listas encadeadas e outras estruturas de dados complexas.



