Escolar Documentos
Profissional Documentos
Cultura Documentos
9129 Mod2-Lp
9129 Mod2-Lp
LINGUAGEM DE PROGRAMAO
PROF. ANDRA
5.
ALOCAO DINMICA...............................................................................................................................................3
5.1 - INTRODUO.....................................................................................................................................................................3
5.2 - ALOCANDO ESPAO DURANTE A EXECUO DO PROGRAMA........................................................................................3
5.3 - HEAP..................................................................................................................................................................................3
5.4 - FUNO MALLOC( )..........................................................................................................................................................3
5.5 - FUNO CALLOC( )...........................................................................................................................................................6
5.6 - FUNO REALLOC( ).........................................................................................................................................................7
5.7 - FUNO FREE( )...............................................................................................................................................................8
5.8 ALOCAO DE MEMRIA NA MAIN X NA FUNO.......................................................................................................9
5.9 EXERCCIOS PROPOSTOS...............................................................................................................................................14
6.
ESTRUTURAS...............................................................................................................................................................15
6.1 INTRODUO..................................................................................................................................................................15
6.2 DEFININDO UM TIPO ESTRUTURA.................................................................................................................................15
6.3 - DECLARANDO AS VARIVEIS DO TIPO ESTRUTURA.....................................................................................................16
6.4 - DEFININDO E DECLARANDO ESTRUTURAS....................................................................................................................17
6.5 - ACESSANDO MEMBROS DA ESTRUTURA........................................................................................................................18
6.6 - MLTIPLAS ESTRUTURAS DE MESMO TIPO..................................................................................................................18
6.7 - DEFINIO DE ESTRUTURAS SEM RTULO OU ETIQUETA..........................................................................................19
6.8 - ESTRUTURAS QUE CONTM MATRIZES.........................................................................................................................19
6.9 EXEMPLO - CRIANDO UMA LISTA DE LIVROS..............................................................................................................20
6.10 - INICIALIZANDO ESTRUTURAS......................................................................................................................................21
6.11 - ATRIBUIES ENTRE ESTRUTURAS..............................................................................................................................22
6.12 - ESTRUTURAS ANINHADAS - ESTRUTURAS QUE CONTM ESTRUTURAS.....................................................................22
6.13 - MATRIZES DE ESTRUTURAS.........................................................................................................................................23
6.14 - INICIALIZANDO ESTRUTURAS COMPLEXAS................................................................................................................25
6.15 EXERCCIOS PROPOSTOS.............................................................................................................................................26
7.
ESTRUTURAS COMPLEXAS.....................................................................................................................................27
5. ALOCAO DINMICA
5.1 - Introduo
A nica finalidade das variveis simples e matrizes alocar espao suficiente na memria para
armazenar valores. E se pudssemos encontrar algum espao disponvel na memria sem ter que criar
uma varivel? Nesse caso, poderamos us-lo para armazenar diretamente os valores e bastaria um
ponteiro que indicasse a posio do primeiro valor e uma varivel que indicasse a quantidade de
elementos armazenados, exatamente como a matriz previamente definida. Mas como fazer para
localizar reas de memria disponveis para armazenagem ?
Usa-se funes para alocar espao na memria enquanto o programa est sendo
executado um processo conhecido como "alocao dinmica".
5.3 - Heap
O heap ou rea de alocao dinmica consiste de toda a memria disponvel que no foi usada
para um outro propsito. Em outras palavras, o heap simplesmente o resto da memria.
A linguagem C oferece um conjunto de funes que permitem a alocao ou liberao
dinmica de memria do heap, como : malloc( ), calloc( ), realloc( ) e free( ).
*ptr;
A funo malloc( ) retorna um ponteiro para o tipo void, portanto esse ponteiro deve ser
moldado para o tipo apropriado antes de ser usado. E para isso usamos a converso de tipos, na
verdade um operador unrio chamado operador de molde, que consiste em colocar um parnteses
envolvendo o tipo de dado desejado.
Ex.: A funo sqrt( ), retorna a raiz quadrada de um nmero do tipo double e temos uma varivel
float:
float n;
double resposta;
resposta = sqrt ((double)n);
Portanto, devemos indicar que o valor retornado por malloc( ) ser do tipo ponteiro para char ou int ou
float.
Exemplo 1 aloca memria para uma matriz com 50 valores do tipo int.
include <stdio.h>
include <stdlib.h>
int *numeros;
main( )
{
if
( (numeros = (int *) malloc(50 * sizeof(int) ) ) = = NULL)
printf("Espao insuficiente para alocar buffer \n");
else
printf("Matriz foi alocada");
}/* main */
Exemplo 2 aloca memria para uma matriz com 10 valores do tipo float.
include <stdio.h>
include <stdlib.h>
float *numeros;
main( )
{
if
( (numeros = (float *) malloc(10 * sizeof(float) ) ) = = NULL)
printf("Espao insuficiente para alocar buffer \n");
else
printf("Matriz foi alocada");
}/* main */
5
se houver espao suficiente para expandir o bloco de memria referenciado por ptr, a memria
adicional alocada e a funo retorna ptr.
se no houver espao suficiente para expandir o bloco atual, um novo bloco do tamanho
especificado em tamanho alocado e os dados existentes so copiados do bloco original para o
incio do novo bloco. A seguir, o bloco original liberado e a funo retorna um ponteiro para o
novo bloco.
se o argumento ptr for NULL, a funo atua como malloc( ), alocando um bloco de tamanho bytes
e retornando um ponteiro para ele.
se o argumento tamanho for 0, a memria indicada por ptr liberada e a funo retorna NULL.
se no houver memria suficiente para a realocao (tanto expandindo o bloco original quanto
alocando um novo bloco), a funo retorna NULL e o bloco original permanece inalterado.
stdlib.h
onde:
ptr corresponde a um ponteiro para o tipo void, aponta para o incio do bloco de memria a ser
liberado.
A funo free ( ) libera a memria referenciada por ptr. Essa memria deve ter sido alocada
usando malloc( ), calloc( ) ou realloc( ). Se ptr for NULL, free ( ) no faz nada.
A funo free( ) declara o seu argumento como um ponteiro para void. A vantagem desta
declarao que ela permite que a chamada funo seja feita com um argumento ponteiro para
qualquer tipo de dado.
Exemplo1 - libera memria alocada por funo desenvolvida em calloc( ).
liberamem()
{
long *ptr, *alocamem();
ptr = alocamem();
free(ptr);
}
if (ptr1 = = NULL)
printf("\n Tentativa de alocar %i bytes falhou", TAMBLOCO);
else
{
printf("\n Primeira alocao de %i bytes realizada", TAMBLOCO);
ptr2 = malloc(TAMBLOCO);
/* tenta alocar o 2 bloco */
if (ptr2 != NULL)
printf("\n Segunda alocao de %i bytes realizada", TAMBLOCO);
else
{
printf("\n Segunda tentativa de alocar %i bytes falhou", TAMBLOCO);
free (ptr1);
printf("\n Liberando o primeiro bloco);
ptr2 = malloc(TAMBLOCO);
if (ptr2 != NULL)
printf("\n Depois de free(), alocao de %i bytes realizada", TAMBLOCO);
}/* else */
}/* else */
}/* main */
Este programa tenta alocar dinamicamente dois blocos de memria, usando a constante
TAMBLOCO para determinar o tamanho de cada bloco. Porm, a 2 alocao s ocorrer se a 1 for
bem sucedida.
main( )
{
int *ptr=NULL;
printf("\nAloca memoria na Funcao e na Main\n");
printf("\nChamada por Referencia - passa ENDERECO do ponteiro\n");
printf("\nFuncao main - antes de alocar");
printf("\nEndereco ptr = %u \nConteudo %u = %u",&ptr,&ptr,ptr);
aloca(&ptr, 1);
//chamada por referencia
printf("\n\nFuncao main - depois de alocar");
printf("\nEndereco ptr = %u \nConteudo %u = %u\n\n\n",&ptr,&ptr,ptr);
system("pause");
}//main
void aloca(int **p, int tam)
{
printf("\n\nFuncao aloca - antes de alocar");
printf("\nEndereco p = %u \tConteudo p = %u (Endereco ptr)",&p,p);
printf("\nConteudo %u = %u\n",p,*p);
if((*p=(int*)realloc(*p, tam*sizeof(int)))== NULL)
{
printf("Erro de alocacao");
exit(1);
}
printf("\n\nFuncao aloca - depois de alocar");
printf("\nEndereco p = %u \tConteudo p = %u (Endereco ptr)",&p,p);
printf("\nConteudo %u = %u\n",p,*p);
}//aloca
Verso utilizando Chamada por Valor com RETORNO do endereo alocado
#include <stdio.h>
#include <stdlib.h>
int*
10
main()
{
int *ptr=NULL;
printf("\nERRO pois aloca memoria apenas na Funcao e nao na Main\n");
printf("\nChamada por Valor - passa CONTEUDO do ponteiro\n");
printf("\nFuncao main - antes de alocar");
printf("\nEndereco ptr = %u \nConteudo %u = %u",&ptr,&ptr,ptr);
aloca(ptr, 1);
printf("\n\nFuncao main - depois de alocar");
printf("\nEndereco ptr = %u \nConteudo %u = %u\n\n\n",&ptr,&ptr,ptr);
NULL
system("pause");
}//main
continua
i;
main( )
{
int
*ptr=NULL;
aloca(&ptr,10);
recebe(ptr,10);
imprime(ptr,10);
system(pause);
}//main
14
6. ESTRUTURAS
6.1 Introduo
Quando nos deparamos com um problema onde desejamos agrupar um conjunto de tipos de
dados no similares sob um nico nome, nosso primeiro impulso seria usar uma matriz. Porm, como
matrizes requerem que todos os seus elementos sejam do mesmo tipo, provavelmente foraramos a
resoluo do problema selecionando uma matriz para cada tipo de dado, resultando em um programa
ineficiente.
O problema de agrupar dados desiguais em C resolvido pelo uso de estruturas
Uma estrutura uma coleo de uma ou mais variveis, possivelmente de tipos diferentes,
colocadas juntas sob um nico nome. (Estruturas so chamadas "registros" em algumas linguagens).
uma outra maneira de representao de dados em C, que servir para a elaborao de um arquivo de
dados na memria acessado atravs de uma lista encadeada.
Um exemplo tradicional de uma estrutura o registro de uma folha de pagamento, onde um
funcionrio descrito por um conjunto de atributos tais como:
nome (string)
n do seu departamento (int)
salrio (float) e assim por diante.
Provavelmente, haver outros funcionrios, e voc vai querer que o seu programa os guarde
formando uma matriz de estruturas.
O uso de uma matriz de vrias dimenses no resolveria o problema, pois todos os elementos
de uma matriz devem ser de um tipo nico, portanto deveramos usar vrias matrizes:
uma de caracteres para os nomes
uma de inteiros para nmero do departamento
uma float para os salrios e assim por diante.
Esta no seria uma forma prtica de manejar um grupo de caractersticas que gostaramos que
tivessem um nico nome: funcionrio.
Uma estrutura consiste de um certo nmero de itens de dados, chamados membros da estrutura,
que no necessitam ser de mesmo tipo, agrupados juntos.
x;
f;
num;
16
tipo_existente
novonome;
Ex.:
1)
typedef
float
portanto, demos usar:
real a, b;
real;
2)
struct facil {
int
num;
char c;
}x;
typedef struct facil facil; //o compilador reconhece facil como outro nome p/ struct facil
facil x;
ou
typedef struct facil {
int
num;
char c;
}facil;
facil
x;
ou
typedef struct {
int
num;
char c;
}facil;
facil
//sem etiqueta
x;
17
O nome da varivel que precede o ponto o nome da estrutura e o nome que o segue o de um
membro especfico da estrutura. As instrues:
x.num = 2;
x.c = 'Z'
struct facil {
int
num;
char c;
};
struct facil
xl, x2;
ou, se preferir:
struct facil {
int
num;
char c;
}x1, x2;
O efeito o mesmo, e o programa torna-se mais compacto.
18
x[2];
y[10];
Definem uma estrutura do tipo data cujos membros so uma matriz inteira com 2 elementos
chamada x e uma matriz de caracteres com 10 elementos chamada y. A seguir, poderamos declarar
uma estrutura chamada record baseada no tipo data:
struct data
record;
record.y[8]
Observe que nessa figura os elementos da matriz x ocupam o qudruplo do espao dos
elementos da matriz y. Isto acontece porque, um elemento do tipo int normalmente exige 4 bytes, ao
passo que um elemento do tipo char normalmente s exige 1 byte.
O acesso aos elementos individuais de uma matriz que um membro de uma estrutura feito
atravs de uma combinao de operadores de membros e subscritos de matrizes:
19
#include <stdio.h>
#include <stdlib.h>
// funo atoi( )
struct livro {
char
titulo[30];
int
regnum;
};
main( )
{
struct livro
livro1,livro2;
char numstr[8];
printf("\n Livro l \n Digite titulo: ");
gets(livro1.titulo);
printf("Digite o numero do registro (3 digitos): ");
gets(numstr);
livro1.regnum = atoi(numstr);
printf("\n Livro 2 \n Digite titulo: ");
gets (1ivro2.titulo);
20
livro1 = {"Helena",102};
livro2 = {"Iracema",321};
21
O programa cria uma estrutura de etiqueta grupo, que consiste de duas outras do tipo livro.
22
dicionario;
literatura;
grupo1 = {
{"Aurelio",134},
{"Iracema",321}
};
printf("\n Dicionario:\n");
printf("Titulo: %s \n", grupo1.dicionario.titulo);
printf("N do registro: %3i \n", grupo1.dicionario.regnum);
printf("\n Literatura:\n");
printf("Titulo: %s \n", grupo1.litertura.titulo);
printf("N do registro: %3i \n", grupo1.literatura.regnum);
}// main
Vamos analisar alguns detalhes deste programa:
Primeiro, declaramos uma varivel estrutura grupo1, do tipo grupo, e inicializamos esta
estrutura com os valores mostrados. Quando uma matriz de vrias dimenses inicializada,
usamos chaves dentro de chaves, do mesmo modo inicializamos estruturas dentro de
estruturas.
Segundo, note como acessamos um elemento da estrutura que parte de outra estrutura. O
operador ponto usado duas vezes:
grupo1.dicionario.titulo
Isto referencia o elemento titulo da estrutura dicionario da estrutura grupo1.
Logicamente este processo no pra neste nvel, podemos ter uma estrutura dentro de outra dentro
de outra.
Tais construes aumentam o nome da varivel, podendo descrever surpreendentemente o seu
contedo.
23
lista[1000];
Esta instruo declara uma matriz chamada lista que contm 1000 elementos. Cada elemento
uma estrutura do tipo entrada e identificada por um ndice, como em qualquer outra matriz. Cada
uma dessas estruturas, por sua vez, contm trs elementos, cada um dos quais uma matriz do tipo
char. Esse esquema relativamente complexo ilustrado abaixo:
lista[0].nome[0]
lista[0]
lista[0].nome
lista[0].email
lista[0].fone
lista[1]
lista[1].nome
lista[1].email
lista[1].fone
lista[999]
lista[999].nome
lista[999].email
lista[999].fone
lista[999].fone[2]
Da mesma forma que podemos atribuir o valor de uma varivel estrutura a outra
lista[5] = lista[1]
Podemos transferir dados entre os elementos individuais das matrizes que so membros
das estruturas:
lista[5].fone[1] = lista[2].fone[3];
Esta instruo move o segundo caractere do nmero de telefone armazenado em lista[5] para a
quarta posio do nmero de telefone armazenado em lista[2]. (No se esquea que os ndices
comeam em 0).
24
o membro da estrutura A1990[1].comprador.firma ser inicializado com o string "Wilson & Cia".
o membro da estrutura A1990[1].comprador.contato ser inicializado com o string "Edi Wilson".
o membro da estrutura A1990[1].item ser inicializado com o string "brincos".
o membro da estrutura A1990[1].quantia ser inicializado com valor 290.
26
7. ESTRUTURAS COMPLEXAS
7.1 - Estruturas e Ponteiros
Podemos declarar ponteiros que apontem para estruturas e tambm usar ponteiros como
membros de estruturas, ou ambos.
*p_pea;
operador de indireo (*) na declarao significa que p_pea um ponteiro para o tipo pea,
no uma instncia da estrutura do tipo pea.
O ponteiro j pode ser inicializado? No, porque a estrutura pea foi definida, mas nenhuma
instncia dessa estrutura foi declarada ainda. Lembre-se que a declarao, no a definio, que
reserva espao na memria para a armazenagem de um objeto de dados. Como o ponteiro precisa de
um endereo na memria para o qual possa apontar, teremos que declarar uma instncia do tipo pea
antes que algo possa apontar para ela.
Portanto, esta a declarao:
struct pea
produto;
Essa instruo atribui o endereo de produto a p_pea. A relao entre uma estrutura e um
ponteiro para essa estrutura mostrada na figura abaixo:
27
produto.nome[ ]
p_pea
Um ponteiro para uma estrutura aponta para o primeiro byte dessa estrutura.
Agora que j temos um ponteiro apontando para a estrutura produto, podemos acessar os
membros de uma estrutura usando um ponteiro de 3 maneiras:
item p_pea deve estar entre parnteses porque o operador (.) tem maior precedncia que o
operador (*).
28
dados[100];
A seguir, podemos declarar um ponteiro para o tipo pea e inicializ-lo para apontar para a
primeira estrutura contida na matriz:
struct pea *p_pea;
p_pea = &dados[0];
Lembrando que o nome de uma matriz sem os colchetes um ponteiro para o primeiro
elemento dessa matriz. Portanto, a segunda linha tambm poderia ter sido escrita da seguinte forma:
p_pea = dados;
Agora j temos uma matriz de estruturas do tipo pea e um ponteiro para o primeiro elemento
dessa matriz (ou seja, para a primeira estrutura da matriz). Poderamos, por exemplo, imprimir o
contedo desse primeiro elemento usando a instruo:
printf("%i
scanf(%i,
1
0
0
1
1002
x[1]
1003
ptr++
1004
1005
1
0
0
5
1006
x[2]
1007
1008
ptr++
1009
1010
1011
1012 .....
1
0
0
9
Isto significa que o seu programa pode avanar atravs de uma matriz de estruturas (ou, para
ser exato, atravs de uma matriz de qualquer tipo) simplesmente incrementando um ponteiro. Este tipo
de notao geralmente mais fcil de usar e mais conciso do que o uso de subscritos de matrizes para
realizar a mesma tarefa.
Ex. - acessa elementos sucessivos de uma matriz atravs do incremento de um ponteiro.
#include <stdio.h>
#define MAX
4
struct pea {
int numero;
char nome[10];
};
main()
{
struct pea
*p_pea,
int
contagem;
30
x);
main( )
{
struct dados reg;
printf("Digite o nome e o sobrenome do doador: ");
scanf("%s
%s", reg.nome, reg..snome);
printf("\n Digite a quantia doada: ");
scanf("%f", ®.quantia);
print_reg( reg );
}// main
31
novonome();
listar (livro liv);
main( )
{
livro livro1, livro2;
livro1 = novonome();
livro2 = novonome();
listar(livro1);
listar(livro2);
} // main
32
33
// aloca 10 elementos
main( )
{
livro *ptr=NULL;
aloca(&ptr, 10);
}//main
34
main()
{
livro *ptr=NULL;
ptr = aloca(ptr, 10);
}//main
4. Fazer um programa para Controle de Hotel - este programa se destina a controlar o check-in
(cadastro de hspedes) de um hotel. O hotel possui 15 quartos. Utilizar alocao dinmica e
ponteiros para a estrutura.
[1] Check-in - alocar dinamicamente espao, receber os valores digitados pelo usurio, se o hspede
no tiver acompanhantes atribuir categoria Solteiro, caso contrrio Familiar, buscar o nmero do
quarto disponvel, de acordo com a categoria na estrutura quartos. Apenas um hspede cadastrado
por vez. No esquecer de atualizar o quarto da estrutura quartos para Ocupado.
[2] Check-out encerra a estadia e apresenta o relatrio, de acordo com o quarto. Apenas um registro
acessado por vez, buscar e mostrar o nmero do quarto, o nome do hspede, quantidade de
acompanhantes, a categoria (Solteiro ou Familiar,o tempo de permanncia em dias e o valor a ser pago.
[3] Fim
36
// nmero do quarto
// quantidade de acompanhantes
// [S]olteiro / [F]amiliar
// tempo de permanncia em dias
// nmero do quarto
// [S]olteiro / [F]amiliar
// [L]ivre / [O]cupado
Categoria de quarto:
[S]olteiro diria R$ 85,00 por pessoa
[F]amiliar diria R$ 45,00 por pessoa
37