Академический Документы
Профессиональный Документы
Культура Документы
A função malloc()
A função calloc()
A função realloc()
A função free()
Comparativo entre alocação estática e dinâmica
Estruturas
O que é?
Uma estrutura pode ser vista como um conjunto de variáveis sob o
mesmo nome, e cada uma delas pode ter qualquer tipo (ou o mesmo
tipo). A ideia básica por trás da estrutura é criar apenas um tipo de
dado que contenha vários membros, que nada mais são do que outras
variáveis.
O que é?
Uma estrutura pode ser vista como um conjunto de variáveis sob o
mesmo nome, e cada uma delas pode ter qualquer tipo (ou o mesmo
tipo). A ideia básica por trás da estrutura é criar apenas um tipo de
dado que contenha vários membros, que nada mais são do que outras
variáveis.
struct nome_struct{
tipo1 campo1;
tipo2 campo2;
...
tipon campoN;
};
struct cadastro{
char nome[50];
int idade;
char rua[50];
int numero;
};
Cuidado!
Depois do símbolo de fechar chaves da estrutura, é necessário colocar
um ponto e vírgula!
Professor Me. Rooney R. A. Coelho (UFTM) Aula 2 23 de Agosto de 2017 4 / 51
Escopo local
Importante!
A declaração em escopo local não é muito comum, mas é possível.
struct cadastro{
char nome[50];
int idade;
char rua[50];
int numero;
} cad1, cad2; // Declaração da estrutura e duas
,→ váriáveis desse tipo: cad1 e cad2 são do tipo
,→ cadastro.
Aplicação
O uso de estruturas facilita muito a vida do programador na
manipulação dos dados do programa, reduzindo assim a quantidade de
variáveis definidas.
A função malloc()
A função calloc()
A função realloc()
A função free()
Comparativo entre alocação estática e dinâmica
int main(){
struct cadastro c;
// protótipo de gets: char *gets(char *str)
gets(c.nome);
scanf("%d",&c.idade);
gets(c.rua);
scanf("%d",&c.numero);
return 0;
}
Assim como nos arrays, uma estrutura também pode ser inicializada,
independentemente do tipo das variáveis contidas nela.
Importante!
Elementos omitidos durante a inicialização são inicializados com 0. Se
for uma string, será inicializada com uma string vazia.
A função malloc()
A função calloc()
A função realloc()
A função free()
Comparativo entre alocação estática e dinâmica
int main(){
struct cadastro c[4];
int i;
for(i=0; i<4; i++){
gets(c[i].nome);
scanf("%d",&c[i].idade);
gets(c[i].rua);
scanf("%d",&c[i].numero);
}
return 0;
}
Cuidado!
Atribuições entre estruturas só podem ser feitas quando as estruturas
são AS MESMAS, ou seja, quando possuem o mesmo nome!
int main(){
struct ponto p1, p2= {1,2};
struct novo_ponto p3= {3,4};
p1 = p2;
printf("p1 = %d e %d", p1.x,p1.y);
//ERRO! TIPOS DIFERENTES
p1 = p3;
printf("p1 = %d e %d", p1.x,p1.y);
return 0;
}
Importante!
O acesso aos dados da variável do tipo struct endereco é feito
utilizando-se novamente o operador ponto. O operador ponto é
novamente utilizado para acessar as variáveis dentro dessa estrutura.
int main(){
struct cadastro c;
//Lê do teclado uma string e armazena no campo nome
gets(c.nome);
//Lê do teclado um valor inteiro e armazena no campo
,→ idade
scanf("%d",&c.idade);
//Lê do teclado uma string e armazena no campo rua
,→ da variável ender
gets(c.ender.rua);
//Lê do teclado um valor inteiro e armazena no campo
,→ numero da variável ender
scanf("%d",&c.ender.numero); // <----
return 0;
}
A função malloc()
A função calloc()
A função realloc()
A função free()
Comparativo entre alocação estática e dinâmica
A função malloc()
A função calloc()
A função realloc()
A função free()
Comparativo entre alocação estática e dinâmica
Uma estrutura pode ser passada como parâmetro para uma função de
duas formas distintas : toda a estrutura ou apenas determinados
campos.
struct ponto {
int x, y;
};
void imprime(struct ponto p){
printf("x = %d\n",p.x);
printf("y = %d\n",p.y);
}
int main(){
struct ponto p1 = {10,20};
imprime(p1);
return 0;
}
Atenção!
Ao acessar uma estrutura passada por referência, não podemos
esquecer de colocar os parênteses antes de acessar o seu campo. O uso
dos parênteses serve para diferenciar o que foi passado por referência
do que é ponteiro.
Atenção!
Ao acessar uma estrutura passada por referência, não podemos
esquecer de colocar os parênteses antes de acessar o seu campo. O uso
dos parênteses serve para diferenciar o que foi passado por referência
do que é ponteiro.
Atenção!
(*p).x p é a variável passada por referência.
Importante!
O operador seta, -> , substitui o uso conjunto dos operadores “*” e “.”
no acesso ao campo de uma estrutura passada por referência para uma
função.
A função malloc()
A função calloc()
A função realloc()
A função free()
Comparativo entre alocação estática e dinâmica
O que é?
A linguagem C permite alocar (reservar) dinamicamente (em tempo de
execução) blocos de memórias utilizando ponteiros. A esse processo
dá-se o nome alocação dinâmica.
O que é?
A linguagem C permite alocar (reservar) dinamicamente (em tempo de
execução) blocos de memórias utilizando ponteiros. A esse processo
dá-se o nome alocação dinâmica.
Memória Memória
# var conteúdo # var conteúdo
119 119
120 Alocando 5 120
121 int *n NULL posições de 121 int *n #123
memória em int * n
122 122
123 123 n[0] 11
124 124 n[1] 25
125 125 n[2] 32
126 126 n[3] 44
127 127 n[4] 52
128 128
129 129
O que é?
A função sizeof( ) é usada para saber o número de bytes necessários
para alocar um único elemento de determinado tipo de dado.
int main(){
printf("Tamanho char: %d\n",sizeof(char));
printf("Tamanho int: %d\n",sizeof(int));
printf("Tamanho float: %d\n",sizeof(float));
printf("Tamanho double: %d\n",sizeof(double));
printf("Tamanho struct ponto: %d\n",sizeof(struct
,→ ponto));
int x;
double y;
printf("Tamanho da variavel x: %d\n",sizeof x);
printf("Tamanho da variavel y: %d\n",sizeof y);
return 0;
}
Tamanho char: 1
Tamanho int: 4
Tamanho float: 4
Tamanho double: 8
Tamanho struct ponto: 8
Tamanho da variavel x: 4
Tamanho da variavel y: 8
A função malloc()
A função calloc()
A função realloc()
A função free()
Comparativo entre alocação estática e dinâmica
Atenção!
Note que a função malloc() retorna um ponteiro genérico (void*). Esse
ponteiro pode ser atribuído a qualquer tipo de ponteiro via type cast.
#include <stdio.h>
#include <stdlib.h>
int main(){
int *p;
p = (int *) malloc(5*sizeof(int));
int i;
for (i=0; i<5; i++){
printf("Digite o valor da posicao %d: ",i);
scanf("%d",&p[i]);
}
for (i=0; i<5; i++){
printf("Posição %d: p[%d]: %d\n", p+i ,i, p[i] );
}
return 0;
}
Importante!
Note que o ponteiro criado por malloc pode ser acessado com a
notação de array p[i] ou por aritmética de ponteiros *(p+i).
Note também que o conteúdo alocado está armazenado de forma
sequencial na memória.
Professor Me. Rooney R. A. Coelho (UFTM) Aula 2 23 de Agosto de 2017 34 / 51
A função malloc()
Boa prática
É importante sempre testar se foi possível fazer a alocação de memória.
A função malloc() retorna um ponteiro NULL para indicar que não
há memória disponível no computador ou que ocorreu algum outro
erro que impediu a memória de ser alocada.
Cuidado!
Lembre-se: no momento da alocação da memória, deve-se levar em
conta o tamanho do dado alocado. Alocar 1.000 bytes de memória
equivale a um número de elementos diferente, dependendo do tipo do
elemento: 1000 Bytes para char aloca um array de 1000 posições de
caracteres; 1000 Bytes para int aloca 250 posições de inteiros.
A função malloc()
A função calloc()
A função realloc()
A função free()
Comparativo entre alocação estática e dinâmica
Importante
Existe outra diferença entre a função calloc() e a função malloc():
ambas servem para alocar memória, mas a função calloc() inicializa
todos os BITS do espaço alocado com 0s.
A função malloc()
A função calloc()
A função realloc()
A função free()
Comparativo entre alocação estática e dinâmica
Atenção
Os valores impressos no primeiro loop são: 1 2 3 4 5. Já após o
primeiro realloc, que diminui o tamanho do vetor, têm-se: 1 2 3, note
que manteve-se o início do array.
Ao aumentar o tamanho da memória alocada com o próximo realloc,
têm-se 1 2 3 ? ? ? ? ? ? ?
int *p;
p = (int *) realloc(NULL,5*sizeof(int));
Atenção!
Isso não significa dizer que o novo bloco de memória será alocado no
começo da memória. Nesse caso a função realloc funcionará tal e
qual a malloc. Já para o caso onde o tamanho da memória solicitada
for zero, p = (int *) realloc(p,0), realloc funcionará
tal e qual a função free, liberando a memória alocada.
A função malloc()
A função calloc()
A função realloc()
A função free()
Comparativo entre alocação estática e dinâmica
Importante!
Desalocar, ou liberar, a memória previamente alocada faz com que ela
se torne novamente disponível para futuras alocações.
Boa prática
Atribuir NULL a esses ponteiros após a liberação da memória.
A função malloc()
A função calloc()
A função realloc()
A função free()
Comparativo entre alocação estática e dinâmica