Last active
July 30, 2020 16:23
-
-
Save KennedyTedesco/2581a714b54b734ca1ff6e25debc540e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Estudo sobre o básico de ponteiros e ponteiros de ponteiros lidando com inteiros. | |
#include <stdio.h> | |
#define LEN 5 | |
int values[LEN]; | |
int main() { | |
int *ptr; // Ponteiro | |
int **ptrp; // Ponteiro de ponteiro | |
// Inicializa o array com valores | |
for (int i = 0; i < LEN; i++) { | |
// Deslocamento de bits que nesse caso surte o mesmo efeito que i * 2 | |
values[i] = i << 1; | |
// Também seria possui fazer a atribuição pelo ponteiro "values" usando aritmética de ponteiro: | |
// *(values + i) = i << 1; | |
// Imprime os valores e seus respectivos endereços | |
printf("%d - %p\n", values[i], &values[i]); | |
} | |
// 0 - 0x404040 | |
// 2 - 0x404044 | |
// 4 - 0x404048 | |
// 6 - 0x40404c | |
// 8 - 0x404050 | |
// "ptr" recebe o endereço da primeira posição do array "values" | |
// "values", na realidade, é um ponteiro pra primeira posição contígua de um bloco de memória | |
// São expressões equivalentes: "ptr", "values", "&values[0]" | |
ptr = values; | |
printf("\n%p, %p, %p\n", ptr, values, &values[0]); // 0x404050, 0x404050, 0x404050 | |
// Se quero obter o valor da primeira posição, posso conseguir isso de diferentes formas: | |
printf("\n%d, %d, %d, %d\n", *ptr, ptr[0], *values, values[0]); // 0, 0, 0, 0 | |
// "ptrp" agora aponta pro ponteiro "ptr", logo, "ptrp" armazena o endereço de "ptr" | |
ptrp = &ptr; | |
printf("\nptrp : %p = &ptr : %p\n\n", ptrp, &ptr); // ptrp : 0x7ffd4bbc47d8 = &ptr : 0x7ffd4bbc47d8 | |
// Uma vez que "ptr" aponta pra um bloco contíguo de memória, consigo fazer aritmética de ponteiro | |
for (int i = 0; i < LEN; i++) { | |
// Operando sobre o valor do bloco atual de 4 bytes (32 bits). | |
// Essa operação com o unário * é chamada de indirection, estou acessando o valor. | |
*ptr *= 2; | |
// Imprimo os novos valores acessando-os pelos ponteiros "ptr" e "ptrp" | |
printf("ptr value : %d = ptrp value : %d\n", *ptr, **ptrp); | |
// Abaixo temos aritmética de ponteiro, incrementa o ponteiro em + 1, como estamos lidando com o tipo int | |
// e na maioria das plataformas ele tem 4 bytes, esse é o valor do step size do incremento. | |
// ou seja, avançamos 4 bytes no bloco de memória e não apenas 1 byte (como intuitivamente pode parecer ocorrer) | |
// seria o avanço de 1 byte se estivéssemos lidando com char (muito comum quando operamos strings ASCII) | |
ptr++; | |
// Como "ptrp" aponta pra "ptr", poderia conseguir o mesmo resultado fazendo: (*ptrp)++ | |
} | |
// ptr value : 0 = ptrp value : 0 | |
// ptr value : 4 = ptrp value : 4 | |
// ptr value : 8 = ptrp value : 8 | |
// ptr value : 12 = ptrp value : 12 | |
// ptr value : 16 = ptrp value : 16 | |
// Ainda sobre aritmética de ponteiro, se quero obter o valor da posição 2 (lembrando que começamos na posição 0): | |
printf("\n%d\n", *(values + 2)); // 8 | |
// É possível avançar ou recuar na memória (com decremento) graças ao fato do bloco ser contíguo | |
// Esse é um dos segredos pelo fato do acesso a uma hash table ser em tempo constante, pois um bloco de memória é | |
// pré-alocado e então por uma hash function chegamos no endereço exato onde o valor se encontra. | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment