006 - Ponteiros e alocação dinâmica
Arquivos necessários
Baixe todos os programas aqui.
Configuração do VSCode
Idênticas as da aula 5, incluídas no zip desta aula.
C
ponteiro1.c
#include <stdio.h>
int main(void)
{
char a = 'C';
char *p = nullptr;
printf("a contém %c\n", a);
printf("p contém %p\n", p);
printf("&a é %p\n", (void *)&a);
printf("&p é %p\n", (void *)&p);
puts("\np recebe o endereço de a\n");
p = &a;
printf("p contém %p\n", p);
printf("&p é %p\n", (void *)&p);
printf("a contém %c\n", a);
printf("*p é %c\n", *p);
puts("\np altera o conteúdo de a\n");
*p = 'D';
printf("p contém %p\n", p);
printf("&p é %p\n", (void *)&p);
printf("a contém %c\n", a);
printf("*p é %c\n", *p);
}
ponteiro2.c
#include <stdio.h>
void troca_sp(int a, int b)
{
int tmp = a;
a = b;
b = tmp;
}
void troca(int *a, int *b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
int main(void)
{
int a = 5, b = 3;
printf("a=%d b=%d\n", a, b);
// Por valor
troca_sp(a, b);
printf("a=%d b=%d\n", a, b);
// Por referencia
troca(&a, &b);
printf("a=%d b=%d\n", a, b);
}
alocando1.c
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char *s = nullptr;
printf("s antes da alocação: %p\n", s);
s = malloc(50);
printf("s depois da alocação: %p\n", s);
free(s);
}
alocando2.c
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
int nelementos = 0;
puts("Digite o número de elementos:");
scanf("%d", &nelementos);
int *a = malloc(sizeof(int) * nelementos);
for (int i = 0; i < nelementos; i++)
{
// *(a + i) = i * 2;
a[i] = i * 2;
}
for (int i = 0; i < nelementos; i++)
{
printf("[%d] = %d\n", i, a[i]);
}
free(a);
}
alocando3.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char *replica(char modelo, int quantidade)
{
char *s = malloc(quantidade + 1);
memset(s, modelo, quantidade);
s[quantidade] = 0;
return s;
}
int main(void)
{
char *s = nullptr;
for (int i = 1; i < 20; i++)
{
s = replica('.', i);
printf("[%s]\n", s);
free(s);
}
}
alocando4.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void replica(char **z, char modelo, int quantidade)
{
*z = malloc(quantidade + 1);
memset(*z, modelo, quantidade);
(*z)[quantidade] = 0;
}
int main(void)
{
char *s = nullptr;
for (int i = 1; i < 10; i++)
{
replica(&s, '=', i);
printf("[%s]\n", s);
free(s);
}
}
struct1.c
#include <stdio.h>
#include <stdlib.h>
struct exemplo
{
int a;
int b;
};
void print_struct(char *nome, struct exemplo v)
{
printf("%s {a=%d, b=%d}\n", nome, v.a, v.b);
}
int main(void)
{
struct exemplo x1, x2 = {.a = 1, .b = 2};
x1.a = 10;
x1.b = 20;
print_struct("x1", x1);
print_struct("x2", x2);
x2.a = 5;
print_struct("x2", x2);
}
struct2.c
#include <stdio.h>
#include <stdlib.h>
typedef struct exemplo
{
int a;
int b;
} exemplo;
void print_struct(char *nome, exemplo v)
{
printf("%s {a=%d, b=%d}\n", nome, v.a, v.b);
}
int main(void)
{
exemplo x1, x2 = {.a = 1, .b = 2};
x1.a = 10;
x1.b = 20;
print_struct("x1", x1);
print_struct("x2", x2);
}
struct3.c
#include <stdio.h>
#include <stdlib.h>
typedef struct exemplo
{
int a;
int b;
} exemplo;
void print_struct(char *nome, exemplo v)
{
printf("%s {a=%d, b=%d}\n", nome, v.a, v.b);
}
void troca_a_b(exemplo v)
{
int tmp = v.a;
v.a = v.b;
v.b = tmp;
}
int main(void)
{
exemplo x1 = {.a = 1, .b = 2};
print_struct("x1", x1);
troca_a_b(x1);
print_struct("x1", x1);
}
struct4.c
#include <stdio.h>
#include <stdlib.h>
typedef struct exemplo
{
int a;
int b;
} exemplo;
void print_struct(char *nome, exemplo v)
{
printf("%s {a=%d, b=%d}\n", nome, v.a, v.b);
}
void troca_a_b(exemplo *v)
{
int tmp = v->a;
v->a = v->b;
v->b = tmp;
}
int main(void)
{
exemplo x1 = {.a = 1, .b = 2};
print_struct("x1", x1);
troca_a_b(&x1);
print_struct("x1", x1);
}
struct5.c
#include <stdio.h>
#include <stdlib.h>
typedef struct exemplo
{
int a;
int b;
} exemplo;
void print_struct(char *nome, exemplo v)
{
printf("%s {a=%d, b=%d}\n", nome, v.a, v.b);
}
exemplo *cria(int a, int b)
{
exemplo *nova = malloc(sizeof(exemplo));
nova->a = a;
nova->b = b;
return nova;
}
int main(void)
{
const int N = 10;
exemplo *x[N];
for (int i = 0; i < N; i++)
{
x[i] = cria(i, i * 2);
}
for (int i = 0; i < N; i++)
{
printf("i=%d x[%d]=%p ", i, i, (void *)x[i]);
print_struct("x", *x[i]);
}
for (int i = 0; i < N; i++)
{
free(x[i]);
}
}
struct6.c
#include <stdio.h>
#include <stdlib.h>
typedef struct exemplo
{
int a;
int b;
} exemplo;
void print_struct(char *nome, exemplo v)
{
printf("%s {a=%d, b=%d}\n", nome, v.a, v.b);
}
int main(void)
{
const int N = 10;
exemplo *x = malloc(sizeof(exemplo) * N);
for (int i = 0; i < N; i++)
{
x[i] = (exemplo){.a = i, .b = 2 * i};
}
for (int i = 0; i < N; i++)
{
printf("i=%d x[%d]=%p ", i, i, (void *)&x[i]);
print_struct("x", x[i]);
}
puts("\nCom aritmética de ponteiros:");
for (int i = 0; i < N; i++)
{
printf("i=%d x[%d]=%p ", i, i, (void *)(x + i));
print_struct("x", x[i]);
}
free(x);
}
lista1.c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct exemplo
{
int a;
int b;
} exemplo;
typedef struct lista
{
int tamanho;
int capacidade;
exemplo *elementos;
} lista;
lista *cria_lista(int capacidade)
{
lista *nova_lista = malloc(sizeof(lista));
*nova_lista = (lista){.tamanho = 0,
.capacidade = capacidade,
.elementos = malloc(sizeof(exemplo) * capacidade)};
return nova_lista;
}
bool append(lista *l, exemplo valor)
{
if (l->tamanho == l->capacidade)
{
return false;
}
l->elementos[l->tamanho] = valor;
l->tamanho += 1;
return true;
}
void print_struct(char *nome, exemplo v)
{
printf("%s {a=%d, b=%d}\n", nome, v.a, v.b);
}
int main(void)
{
lista *l = cria_lista(10);
for (int i = 0; i < 10; i++)
{
if (!append(l, (exemplo){.a = i, .b = i * 3}))
{
printf("Erro, não consegui adicionar o elemento %d\n", i);
}
}
for (int v = 0; v < l->tamanho; v++)
{
char etiqueta[50];
sprintf(etiqueta, "l[%d]", v);
print_struct(etiqueta, l->elementos[v]);
}
// free(l->elementos);
free(l);
}
lista2.c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct exemplo
{
int a;
int b;
} exemplo;
typedef struct lista
{
int tamanho;
int capacidade;
exemplo *elementos;
} lista;
lista *cria_lista(int capacidade)
{
lista *nova_lista = malloc(sizeof(lista));
*nova_lista = (lista){.tamanho = 0,
.capacidade = capacidade,
.elementos = malloc(sizeof(exemplo) * capacidade)};
return nova_lista;
}
bool append(lista *l, exemplo valor)
{
if (l->tamanho == l->capacidade)
{
return false;
}
l->elementos[l->tamanho] = valor;
l->tamanho += 1;
return true;
}
void libera_lista(lista *l)
{
l->tamanho = 0;
l->capacidade = 0;
free(l->elementos);
free(l);
}
void print_struct(char *nome, exemplo v)
{
printf("%s {a=%d, b=%d}\n", nome, v.a, v.b);
}
int main(void)
{
lista *l = cria_lista(10);
for (int i = 0; i < 10; i++)
{
if (!append(l, (exemplo){.a = i, .b = i * 3}))
{
printf("Erro, não consegui adicionar o elemento %d", i);
}
}
for (int v = 0; v < l->tamanho; v++)
{
char etiqueta[50];
sprintf(etiqueta, "l[%d]", v);
print_struct(etiqueta, l->elementos[v]);
}
libera_lista(l);
}
lista3.c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct exemplo
{
int a;
int b;
} exemplo;
typedef struct lista
{
int tamanho;
int capacidade;
exemplo **elementos;
} lista;
lista *cria_lista(int capacidade)
{
lista *nova_lista = malloc(sizeof(lista));
*nova_lista = (lista){.tamanho = 0,
.capacidade = capacidade,
.elementos = malloc(sizeof(exemplo *) * capacidade)};
return nova_lista;
}
bool append(lista *l, exemplo valor)
{
if (l->tamanho == l->capacidade)
{
return false;
}
exemplo *novo = malloc(sizeof(exemplo));
l->elementos[l->tamanho] = novo;
*novo = valor;
l->tamanho += 1;
return true;
}
void libera_lista(lista *l)
{
for (int x = 0; x < l->tamanho; x++)
{
free(l->elementos[x]);
}
l->tamanho = 0;
l->capacidade = 0;
free(l->elementos);
free(l);
}
void print_struct(char *nome, exemplo v)
{
printf("%s {a=%d, b=%d}\n", nome, v.a, v.b);
}
int main(void)
{
const int MAX = 25;
lista *l = cria_lista(MAX);
for (int i = 0; i < MAX; i++)
{
if (!append(l, (exemplo){.a = i, .b = i * 3}))
{
printf("Erro, não consegui adicionar o elemento %d\n", i);
}
}
char etiqueta[50];
for (int v = 0; v < l->tamanho; v++)
{
sprintf(etiqueta, "l[%d]", v);
print_struct(etiqueta, *l->elementos[v]);
}
libera_lista(l);
}
realloc1.c
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
char *p = nullptr;
printf("p aponta para %p\n", p);
p = malloc(100);
printf("p aponta para %p (após malloc)\n", p);
p = realloc(p, 200);
printf("p aponta para %p (após realloc)\n", p);
free(p);
}
realloc2.c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
// Modificação de lista 3
typedef struct exemplo
{
int a;
int b;
} exemplo;
typedef struct lista
{
int tamanho;
int capacidade;
exemplo **elementos;
} lista;
lista *cria_lista(int capacidade)
{
lista *nova_lista = malloc(sizeof(lista));
*nova_lista = (lista){.tamanho = 0,
.capacidade = capacidade,
.elementos = malloc(sizeof(exemplo *) * capacidade)};
return nova_lista;
}
bool append(lista *l, exemplo valor)
{
if (l->tamanho == l->capacidade)
{
printf("Expandindo... dobrando a capacidade (%d -> %d).\n", l->capacidade, l->capacidade * 2);
exemplo **novo = realloc(l->elementos, (l->capacidade * 2) * sizeof(exemplo *));
if (novo != nullptr)
{
l->elementos = novo;
l->capacidade *= 2;
}
else
{
return false;
}
}
exemplo *novo = malloc(sizeof(exemplo));
l->elementos[l->tamanho] = novo;
*novo = valor;
l->tamanho += 1;
return true;
}
void libera_lista(lista *l)
{
for (int x = 0; x < l->tamanho; x++)
{
free(l->elementos[x]);
}
l->tamanho = 0;
l->capacidade = 0;
free(l->elementos);
free(l);
}
void print_struct(char *nome, exemplo v)
{
printf("%s {a=%d, b=%d}\n", nome, v.a, v.b);
}
int main(void)
{
lista *l = cria_lista(10);
for (int i = 0; i < 1000; i++)
{
if (!append(l, (exemplo){.a = i, .b = i * 3}))
{
printf("Erro, não consegui adicionar o elemento %d\n", i);
}
}
char etiqueta[50];
for (int v = 0; v < l->tamanho; v++)
{
sprintf(etiqueta, "l[%d]", v);
print_struct(etiqueta, *l->elementos[v]);
//printf("Endereco de %s > %p\n", etiqueta, (void *) l->elementos[v]);
}
libera_lista(l);
}
calloc1.c
#include <stdlib.h>
#include <stdio.h>
int main(void){
int *v = malloc(10 * sizeof(int));
int *c = calloc(10, sizeof(int));
printf("v=%p\n", (void *)v);
printf("c=%p\n", (void *)c);
free(v);
free(c);
}
void.c
#include <stdio.h>
#ifdef _WIN32
#include <winsock.h>
#else
#include <arpa/inet.h>
#endif
int main(void)
{
int z = 10;
double zd = z;
printf("%d - %f\n", z, zd);
int x = 3;
double zdx = z / x;
printf("%f\n", zdx);
double zdy = z / (double)x;
printf("%f\n", zdy);
void *a = (void *)0xdeadbeef;
printf("a = %p\n", a);
printf("a = %zu\n", sizeof(a));
// a += 1;
int b = 0xadacaffe;
a = &b;
printf("a = %p\n", a);
// printf("a = %d\n", *a);
char *c = a;
printf("c[0] = %02x\n", *c);
printf("c[1] = %02x\n", *(c + 1));
printf("c[2] = %02x\n", *(c + 2));
printf("c[3] = %02x\n\n", *(c + 3));
unsigned char *uc = a;
printf("uc[0] = %02x\n", *uc);
printf("uc[1] = %02x\n", *(uc + 1));
printf("uc[2] = %02x\n", *(uc + 2));
printf("uc[3] = %02x\n", *(uc + 3));
printf("%02x %02x %02x %02x\n", uc[0], uc[1], uc[2], uc[3]);
int n = htonl(b);
unsigned char *ucn = (unsigned char *)&n;
printf("ucn[0] = %02x\n", *ucn);
printf("ucn[1] = %02x\n", *(ucn + 1));
printf("ucn[2] = %02x\n", *(ucn + 2));
printf("ucn[3] = %02x\n", *(ucn + 3));
printf("%02x %02x %02x %02x\n", ucn[0], ucn[1], ucn[2], ucn[3]);
}
func.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int soma(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
char *nova(int x)
{
char *n = malloc(x + 1);
memset(n, 'x', x);
n[x] = 0;
return n;
}
int main(void)
{
int (*p)(int, int) = soma;
printf("p é soma(1, 2): %d\n", p(1, 2));
p = sub;
printf("p é sub(5, 3): %d\n", p(5, 3));
char *(*z)(int) = nova;
for (int nz = 1; nz < 10; nz++)
{
char *r = z(nz);
printf("z(%d) => %s\n", nz, r);
free(r);
}
}
Videos
Linguagem C para quem já programa em Python - Aula 6
Parte 1 - Conceito de ponteiro, endereço, passagem por valor e por referência
Parte 2 - Alocação dinâmica, malloc, free, memset, ponteiros para ponteiros
Parte 3 - Estruturas (structs)
Parte 4 - listas, sprintf e realloc
Disponível a partir de 29/05/2024 (19:00 Bruxelas)
Parte 5 - calloc, void pointer, pre-processador, ponteiros para funções
Disponível a partir de 01/06/2024 (19:00 Bruxelas)
Assine o canal para não perder os novos vídeos