Вы находитесь на странице: 1из 156

ESTRUTURA DE

DADOS I

Professor Me. Rogrio de Leon Pereira

GRADUAO

Unicesumar

Reitor
Wilson de Matos Silva
Vice-Reitor
Wilson de Matos Silva Filho
Pr-Reitor de Administrao
Wilson de Matos Silva Filho
Pr-Reitor de EAD
Willian Victor Kendrick de Matos Silva
Presidente da Mantenedora
Cludio Ferdinandi
NEAD - Ncleo de Educao a Distncia
Direo Operacional de Ensino
Ktia Coelho
Direo de Planejamento de Ensino
Fabrcio Lazilha
Direo de Operaes
Chrystiano Mincoff
Direo de Mercado
Hilton Pereira
Direo de Polos Prprios
James Prestes
Direo de Desenvolvimento
Dayane Almeida
Direo de Relacionamento
Alessandra Baron
Gerncia de Produo de Contedo
Juliano de Souza
Superviso do Ncleo de Produo de
Materiais
Ndila de Almeida Toledo
Coordenador de contedo
Daniello Xavier Saes
Design Educacional
Ndila de Almeida Toledo
Fernando Henrique Mendes
Rossana Costa Giani
C397 CENTRO UNIVERSITRIO DE MARING. Ncleo de Educao a
Distncia; PEREIRA, Rogrio de Leon.

Estrutura de dados I. Rogrio de Leon Pereira.

(Reimpresso revista e atualizada)

Maring-Pr.: UniCesumar, 2016.

156 p.
Graduao - EaD.


1. Sistemas numricos. 2. Vetores e matrizes. 3. Ponteiros. 4. EaD.
I. Ttulo.
ISBN 978-85-8084-593-8

CDD - 22 ed. 005.73


CIP - NBR 12899 - AACR/2

Ficha catalogrfica elaborada pelo bibliotecrio


Joo Vivaldo de Souza - CRB-8 - 6828

Projeto Grfico
Jaime de Marchi Junior
Jos Jhonny Coelho
Editorao
Fernando Henrique Mendes
Thayla Daiany Guimares Cripaldi
Reviso Textual
Jaquelina Kutsunugi, Keren Pardini, Maria
Fernanda Canova Vasconcelos, Nayara
Valenciano, Rhaysa Ricci Correa e Susana Incio
Ilustrao
Robson Yuiti Saito

Viver e trabalhar em uma sociedade global um


grande desafio para todos os cidados. A busca
por tecnologia, informao, conhecimento de
qualidade, novas habilidades para liderana e soluo de problemas com eficincia tornou-se uma
questo de sobrevivncia no mundo do trabalho.
Cada um de ns tem uma grande responsabilidade: as escolhas que fizermos por ns e pelos nossos far grande diferena no futuro.
Com essa viso, o Centro Universitrio Cesumar
assume o compromisso de democratizar o conhecimento por meio de alta tecnologia e contribuir
para o futuro dos brasileiros.
No cumprimento de sua misso promover a
educao de qualidade nas diferentes reas do
conhecimento, formando profissionais cidados
que contribuam para o desenvolvimento de uma
sociedade justa e solidria , o Centro Universitrio Cesumar busca a integrao do ensino-pesquisa-extenso com as demandas institucionais
e sociais; a realizao de uma prtica acadmica
que contribua para o desenvolvimento da conscincia social e poltica e, por fim, a democratizao
do conhecimento acadmico com a articulao e
a integrao com a sociedade.
Diante disso, o Centro Universitrio Cesumar almeja ser reconhecida como uma instituio universitria de referncia regional e nacional pela
qualidade e compromisso do corpo docente;
aquisio de competncias institucionais para
o desenvolvimento de linhas de pesquisa; consolidao da extenso universitria; qualidade
da oferta dos ensinos presencial e a distncia;
bem-estar e satisfao da comunidade interna;
qualidade da gesto acadmica e administrativa; compromisso social de incluso; processos de
cooperao e parceria com o mundo do trabalho,
como tambm pelo compromisso e relacionamento permanente com os egressos, incentivando a educao continuada.

Diretoria de
Planejamento de Ensino

Diretoria Operacional
de Ensino

Seja bem-vindo(a), caro(a) acadmico(a)! Voc est


iniciando um processo de transformao, pois quando investimos em nossa formao, seja ela pessoal
ou profissional, nos transformamos e, consequentemente, transformamos tambm a sociedade na qual
estamos inseridos. De que forma o fazemos? Criando
oportunidades e/ou estabelecendo mudanas capazes de alcanar um nvel de desenvolvimento compatvel com os desafios que surgem no mundo contemporneo.
O Centro Universitrio Cesumar mediante o Ncleo de
Educao a Distncia, o(a) acompanhar durante todo
este processo, pois conforme Freire (1996): Os homens
se educam juntos, na transformao do mundo.
Os materiais produzidos oferecem linguagem dialgica e encontram-se integrados proposta pedaggica, contribuindo no processo educacional, complementando sua formao profissional, desenvolvendo
competncias e habilidades, e aplicando conceitos
tericos em situao de realidade, de maneira a inseri-lo no mercado de trabalho. Ou seja, estes materiais
tm como principal objetivo provocar uma aproximao entre voc e o contedo, desta forma possibilita o desenvolvimento da autonomia em busca dos
conhecimentos necessrios para a sua formao pessoal e profissional.
Portanto, nossa distncia nesse processo de crescimento e construo do conhecimento deve ser
apenas geogrfica. Utilize os diversos recursos pedaggicos que o Centro Universitrio Cesumar lhe possibilita. Ou seja, acesse regularmente o AVA Ambiente
Virtual de Aprendizagem, interaja nos fruns e enquetes, assista s aulas ao vivo e participe das discusses. Alm disso, lembre-se que existe uma equipe de
professores e tutores que se encontra disponvel para
sanar suas dvidas e auxili-lo(a) em seu processo de
aprendizagem, possibilitando-lhe trilhar com tranquilidade e segurana sua trajetria acadmica.

AUTOR

Professor Me. Rogrio de Leon Pereira


Possui graduao em Tecnologia em Processamento de Dados pelo Centro
de Ensino Superior de Maring (1999) e mestrado em Cincia da Computao
pela Universidade Estadual de Maring (2006). Atualmente analista de
informtica da Universidade Estadual de Maring. Tem experincia na rea de
Cincia da Computao, com nfase em desenvolvimento de sistemas Web.

APRESENTAO

ESTRUTURA DE DADOS I
SEJA BEM-VINDO(A)!
Recebi a proposta de elaborar o material que voc carrega em suas mos sobre Estrutura de Dados, contedo de extrema importncia que liga o conhecimento obtido na
matria de algoritmos com as disciplinas tcnicas de programao que voc ver at o
final do seu curso.
Quando falamos em Estrutura de Dados, estamos falando da forma como os dados so
armazenados e manipulados no computador. Falamos tambm das tcnicas para incluso, acesso, alterao e excluso destes dados.
Na dcada de 1980, quando eu jogava videogame (ATARI 2600) com o meu irmo mais
velho, Ricardo, ele sempre dizia: Como que um monte de 1s e 0s pode ser to legal?.
Essa pergunta me intrigou por muito tempo, mas a resposta voc encontrar neste livro. Como veremos nas pginas a seguir, de nada importa as sequncias de 1s e 0s que
o computador carrega na memria, seja na primria ou na secundria, elas no tm
significado algum se no forem determinadas regras de como essas informaes sero
analisadas.
Na Unidade I, veremos os principais sistemas numricos utilizados na computao: decimal, binrio e hexadecimal, contedo j visto na disciplina de Fundamentos e Arquiteturas de Computadores. Seu entendimento de supraimportncia para o aprendizado do
contedo deste livro. Tambm sero revistas as definies de variveis unidimensionais
contidas na disciplina de Algoritmos e Lgica de Programao II e a forma como elas so
estruturadas na memria do computador.
Passando para a Unidade II, completaremos a reviso vendo as variveis multidimensionais. Com esse contedo aprendido, j veremos as duas primeiras estruturas: a Fila e a
Pilha.
O prximo passo ser estudar o contedo considerado, por muitos, um dos mais difceis
na rea de programao, que o conceito de Ponteiros.
Em seguida, veremos a aplicao e o uso dos Ponteiros na criao de listas dinmicas,
que uma alternativa muito interessante forma esttica criada com as variveis multidimensionais.
Para o encerramento do contedo, foi reservado na Unidade V um espao para falar
sobre Grafos, uma estrutura muito utilizada em vrios nveis de programao, e tambm
sobre algumas tcnicas para trabalhar com eles.
Lembre-se que o curso de graduao criado seguindo um processo lgico e estruturado de formao do conhecimento. Voc j aprendeu sobre os sistemas numricos
na disciplina de Fundamentos e Arquitetura de Computadores e sobre variveis na de
Algoritmos e Lgica de Programao.
O que veremos aqui, neste livro, uma sequncia desse contedo e a sua aplicao, que
servir de base para as prximas disciplinas de cunho tcnico do seu curso e para a sua
formao como profissional de Tecnologia da Informao.

8-9

SUMRIO

UNIDADE I

SISTEMAS NUMRICOS E ALOCAO DE MEMRIA


15 Introduo
16 Sistema Decimal
19 Sistema Binrio
21 Representao de Decimal em Binrio
23 Sistema Hexadecimal
26 Estrutura de Dados
28 Tipos De Variveis E Alocao Na Memria
29 Nmeros Inteiros
31 Nmeros Reais
33 Consideraes Finais

UNIDADE II

PILHAS E FILAS
39 Introduo
39 Estruturas Homogneas e Heterogneas
40 Vetores e Matrizes
41 Registros
42 Pilhas
53 Filas
62 Consideraes Finais

SUMRIO

UNIDADE III

PONTEIROS
69 Introduo
69 Ponteiros
76 Propriedades de Ponteiros
77 Alocao Dinmica na Memria
82 Criando Vetores Dinmicos
84 Consideraes Finais

UNIDADE IV

LISTAS DINMICAS
91 Introduo
91 Fundamentos de Listas Dinmicas
94 Implementando uma Lista Dinmica
101 Lista Dinmica com Forma de Pilha
104 Lista Dinmica com Forma de Fila
108 Consideraes Finais

10 - 11

SUMRIO

UNIDADE V

GRAFOS
113 Introduo
113 Sete Pontes de Knigsberg
116 Teoria dos Grafos
117 Grafos como Representao de Problemas
118 Representao Computacional de Grafos
122 Implementando Grafos em C
129 Consideraes Finais


131 CONCLUSO
133 REFERNCIAS
135 GABARITO
155 ANEXO

SISTEMAS NUMRICOS E
ALOCAO DE MEMRIA

UNIDADE

Professor Me. Rogrio de Leon Pereira

Objetivos de Aprendizagem
Conhecer os principais sistemas numricos utilizados na
computao: decimal, binrio e hexadecimal.
Aprender a relao e a converso de valores entre diferentes sistemas
numricos.
Conhecer os principais tipos de variveis.
Entender como os dados das variveis so armazenados na memria.

Plano de Estudo
A seguir, apresentam-se os tpicos que voc estudar nesta unidade:
Sistema decimal
Sistema binrio
Representao de decimal em binrio
Sistema hexadecimal
Estrutura de dados
Tipos de variveis e alocao na memria
Nmeros inteiros
Nmeros reais

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

14 - 15

shutterstock

INTRODUO
Nmeros so sequncias ordenadas de algarismos que tm seu valor determinado pela posio de seus elementos e de sua base numrica.
Parece complicado, mas no . Estamos acostumados a trabalhar em apenas uma base numrica, a Decimal. Nesta unidade veremos mais a fundo como
funcionam diferentes sistemas numricos como o Binrio, o Hexadecimal e suas
aplicaes.
Compreendendo melhor os sistemas numricos, passaremos a estudar como
os dados so armazenados na memria. Isso importante para entender como
funcionam as estruturas de dados mais simples, que so as variveis.
As informaes esto armazenadas na memria do computador, mas para
decifr-las preciso saber qual a sua estrutura. Um grupo de bits pode ser interpretado de diversas maneiras diferentes. como ler um livro em outro idioma
sem o respectivo dicionrio. Voc at reconhece as letras, mas no sabe qual
grupo forma qual vocbulo, qual o seu som e significado.
Parte desse contedo no novidade, j foi visto na disciplina de Fundamentos
e Arquitetura de Computadores e na de Algoritmos e Lgica de Programao
II. E voc no ir parar por a, porque o que aprendermos agora ser utilizado
mais frente no seu curso em outras disciplinas correlatas.
Introduo

shutterstock

Voc pode at no ter ouvido falar do Sistema de Numerao de Base 10, ou


Sistema Decimal, mas com certeza o conhece h muito tempo, pois nesse sistema que aprendemos a contar os nmeros e realizar as mais bsicas operaes
algbricas: adio, subtrao, multiplicao e diviso.
Os algarismos no sistema decimal podem assumir apenas dez valores, do 0
ao 9, da a origem de seu nome. Da mesma forma, dito que um sistema de
base dez, pois todos os seus nmeros so formados por algarismos que podem
assumir apenas dez valores distintos.
A representao formal de um nmero pode ser dada da seguinte forma:
N = (An-1...Ap+2 Ap+1 Ap)B
Onde:
N = o nmero a ser formado;
A = so os algarismos que compem o nmero N;
p = posio do algarismo A no nmero N, iniciando-se em p = 0 na primeira posio direita indo at p = n - 1, onde n o nmero de algarismos
que compem o nmero;
B = a base do nmero N, que no caso do sistema decimal 10.
O elemento A uma varivel e pode assumir diversos valores dentro do
conjunto CD dos algarismos que compem os nmeros decimais, que pode ser
representado na seguinte forma:

SISTEMAS NUMRICOS E ALOCAO DE MEMRIA

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

SISTEMA DECIMAL

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

16 - 17

CD = (0,1,2,3,4,5,6,7,8,9)
O valor de cada um dos algarismos tem a sua relevncia dada pela posio que ocupa no nmero. Como estamos
trabalhando no sistema decimal, cada componente ser multiplicado por uma potncia de base 10 com expoente relativo
a sua posio no nmero.
N=A*10n-1+...+A*10p+2+A*10p+1+A*10p
Assim, podemos dizer que um nmero no sistema decimal o somatrio da multiplicao dos seus elementos por
uma potncia de base 10 elevada ao ndice da sua posio
de relevncia.

Por questes acadmicas, faz-se necessrio o uso da notao


formal. Porm, por se tratar de um material especialmente
preparado para o uso em autoestudo, preciso que tal informao seja abstrada para uma linguagem mais coloquial. A
melhor forma de realizar isso por meio de exemplos.
Exemplo 1: calcule o valor do nmero 12345 na base
decimal.
Sabemos que a representao numrica de N dada pelo
nmero 12345, ou seja:
N = 12345
Como j foi dito, o valor dele dever ser calculado no
sistema de base 10 (decimal). Assim:
N = (12345)10
Pela definio apresentada, o valor de N o somatrio
da multiplicao de seus elementos pela potncia de base
10 elevada ao expoente p, onde p a posio do algarismo
no nmero, contando-se da direita para a esquerda iniciando-se com 0.
N = 1*104 + 2*103 + 3*102 + 4*101 + 5*100

shutterstock

Sistema Decimal

Calculando as potncias, temos:


N = 1*10000 + 2*1000 + 3*100 + 4*10 + 5*1
Realizando as multiplicaes:
N = 10000 + 2000 + 300 + 40 + 5
E, por ltimo, a soma dos elementos j calculados:
N=12345
Exemplo 2: calcule o valor do nmero 54321 na base decimal.
N = 54321
N = 5*104 + 4*103 + 3*102 + 2*101 + 1*100
N = 5*10000 + 4*1000 + 3*100 + 2*10 + 1*1
N = 50000+4000+300+20+1
N = 54321
Exemplo 3: calcule o valor do nmero 42 na base decimal.
N = 42
N = (42)10
N = 4*101+2*100
N = 4*10+2*1
N = 40+2
N=42
Parece bvio dizer que o nmero 42 na base decimal equivale a 42, mas isso
se d porque estamos trabalhando com um sistema numrico que j utilizado
diversas vezes durante o dia. O importante saber como realizado o clculo
de um nmero de forma posicional, o que ser til para entender o funcionamento em sistemas que no utilizam a base 10.

Dois nmeros em bases diferentes podem ter valores distintos mesmo possuindo os mesmos algarismos nas mesmas posies.

SISTEMAS NUMRICOS E ALOCAO DE MEMRIA

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

N = (54321)10

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

18 - 19

shutterstock

SISTEMA BINRIO
Esse com certeza voc j deve ter ouvido falar. Ele utiliza apenas dois valores, 0
e 1, e amplamente utilizado tanto para o armazenamento fsico das informaes quanto para os clculos realizados dentro do ncleo do processador. No
importa o que voc est vendo nesse exato momento: figuras, desenhos, letras
ou nmeros decimais, at mesmo ouvindo uma msica no computador, celular
ou MP3 player. Internamente tudo representado por uma sequncia de algarismos 0 e 1.
Voltando notao formal j utilizada na representao do sistema decimal, vamos aplic-la agora para entender melhor a composio de um nmero
no sistema binrio.
N = (An-1...Ap+2 Ap+1Ap)B
Diferente do sistema decimal que possua base 10, o sistema binrio possui
apenas dois valores (base 2). Assim o conjunto CD de elementos que representam os possveis valores do algarismo A :
CD = (0,1)
Sistema Binrio

Como j apresentado anteriormente, o valor de cada um dos algarismos tem


a sua relevncia dada pela posio que ocupa no nmero. No caso do sistema
binrio, cada componente ser multiplicado por uma potncia de base 2 com
expoente relativo a sua posio no nmero.
N = A*2n-1 +...+ A*2p+2 + A*2p+1 + A*2p
Novamente, podemos dizer que o valor de um nmero o somatrio da multiplicao dos seus elementos por uma potncia de base B elevada ao ndice da
sua posio de relevncia. No caso do sistema binrio, o valor de B = 2 (base 2):

Calculando as potncias, temos:


N = 1*32+0*16+1*8+0*4+1*2+0*1

SISTEMAS NUMRICOS E ALOCAO DE MEMRIA

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

Note que a forma de encontrar o valor de um nmero no sistema binrio similar


utilizada para encontrar o valor de um nmero no sistema decimal, diferenciando-se apenas pelo valor da base B e do conjunto CD de possveis valores do
elemento A.
Vamos ver agora alguns exemplos de como calcular o valor de um nmero
representado no sistema binrio.
Exemplo 1: calcule o valor decimal do nmero 101010 na base binria.
Sabemos que a representao numrica de N dada pelo nmero 101010,
ou seja:
N=101010
Como j foi dito, o valor dele dever ser calculado no sistema de base 2
(binrio). Assim:
N=(101010)2
Pela definio apresentada, o valor de N o somatrio da multiplicao de
seus elementos pela potncia de base 2 elevada ao expoente p, onde p a posio
do algarismo no nmero, contando-se da direita para a esquerda, iniciando-se
com 0.
N = 1*25 + 0*24 + 1*23 + 0*22 + 1*21 + 0*20

20 - 21

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

Um nmero binrio que termina com 1 ser sempre um valor decimal mpar,
j que a primeira posio direita equivale a 20 = 1, e como todas as demais
potncias de 2 so nmeros pares, qualquer nmero par acrescido de 1 ser
um nmero mpar.

Realizando as multiplicaes:
N = 32+8+2
E, por ltimo, a soma dos elementos j calculados:
N=42
Exemplo 2: calcule o valor decimal do nmero 1101 na base binria.
N= 1101
N= (1101)2
N= 1*23 + 1*22 + 0*21 + 1*20
N= 1*8 + 1*4 + 0*2 + 1*1
N=8+4+1
N=13

REPRESENTAO DE DECIMAL EM BINRIO


No sistema decimal, a quantidade de nmeros inteiros nicos possveis se d
pela forma 10n, onde n a quantidade de algarismos presentes no nmero. Dessa
forma, um nmero decimal com apenas um algarismo pode formar 101 nmeros:
101 = (0,1,2,3,4,5,6,7,8,9)
Um nmero decimal com dois algarismos forma 102 combinaes possveis,
ou seja, 100 nmeros:
102 = (00,01,02,03,...,97,98,99)
Analogamente, a quantidade de nmeros formados no sistema binrio se
d pela frmula Bn, onde n a quantidade de smbolos (algarismos) no nmero
Representao de Decimal em Binrio

e B a base do sistema, que no caso do binrio B = 2 (base 2). Desse modo, um


nmero binrio com dois algarismos formar quatro valores:
22=(00,01,10,11)
Assim, caso seja necessrio representar todos os valores de um nmero decimal inteiro positivo de apenas um dgito (101), seriam necessrios pelo menos
4 dgitos binrios (24), conforme a tabela abaixo:
BINRIO

0000

0001

0010

0011

0100

0101

0110

0111

1000

1001

Fonte: o autor

Note que a quantidade de combinaes possveis para um nmero com 4 dgitos


binrios so 16, porm, apenas 10 so necessrios para a representao de um
algarismo decimal. Os nmeros 1010, 1011, 1100, 1101, 1110 e 1111 acabam no
sendo utilizados. importante entender que uma mesma combinao de valores pode ter diversos significados diferentes, de acordo com as regras utilizadas
para a sua interpretao. Isso ficar mais claro quando abordarmos o conceito
de variveis ainda nesta unidade.

SISTEMAS NUMRICOS E ALOCAO DE MEMRIA

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

DECIMAL

22 - 23

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

shutterstock

SISTEMA HEXADECIMAL
O sistema de base 16 o ltimo que veremos dentro da disciplina de estrutura
de dados. Ele tambm muito utilizado na computao para a representao
numrica. Por ser um sistema de base 16, os nmeros hexadecimais so compostos por algarismos que podem assumir 16 valores diferentes, conforme exposto
no conjunto CD abaixo:
CD = (0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F)
Onde a letra A representa o valor 10, a letra B o valor 11, a letra C o valor
12, e assim por diante, at a letra F, que representa o valor 15.
O sistema hexadecimal muito utilizado porque considerado um intermedirio entre aquilo que estamos habituados a ver (nmeros decimais) e aquilo
com o que o computador trabalha internamente em nvel de hardware (nmeros binrios). Outra justificativa se d pela possibilidade de representar todos
os smbolos hexadecimais em um nmero binrio de 4 dgitos, diferente do que
acontece quando tentamos representar um dgito decimal em binrio.
DECIMAL

BINRIO

HEXADECIMAL

0000

0001

0010

0011

0100

Sistema Hexadecimal

DECIMAL

BINRIO

HEXADECIMAL

0101

0110

0111

1000

1001

10

1010

11

1011

12

1100

13

1101

14

1110

15

1111

Fonte: o autor

Para saber o valor de um nmero hexadecimal, basta converter cada um dos algarismos de base 16 para base 2 e o resultado final em base 10. Vamos ver agora
alguns exemplos de como calcular o valor de um nmero representado no sistema hexadecimal.
Exemplo 1: calcule o valor decimal do nmero F2 na base hexadecimal.
Isolando cada um dos algarismos, podemos formar a seguinte tabela:
HEXADECIMAL

DECIMAL

BINRIO

15

1111

0010

SISTEMAS NUMRICOS E ALOCAO DE MEMRIA

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

24 - 25

Agrupando agora os valores binrios dos dgitos hexadecimais, temos:


N=(11110010)2
O valor de N o somatrio da multiplicao de seus elementos pela potncia de base 2 elevada ao expoente p, onde p a posio do algarismo no nmero,
contando-se da direita para a esquerda, iniciando-se com 0.
N = 1*27 + 1*26 + 1*25 + 1*24 + 0*23 + 0*22 + 1*21 + 0*20
Calculando as potncias, temos:
N = 1*128 + 1*64 + 1*32 + 1*16 + 0*8 + 0*4 + 1*2 + 0*1
Realizando as multiplicaes:
N = 128 + 64 + 32 + 16 + 2
E, por ltimo, a soma dos elementos j calculados:
N = 242
Exemplo 2: calcule o valor decimal do nmero 1A na base hexadecimal.
HEXADECIMAL

DECIMAL

BINRIO

0001

10

1010

N= (00011010)2
N= 0*27+0*26+0*25+1*24+1*23+0*22+1*21+0*20
N= 0*128 + 0*64 + 0*32 + 1*16 + 1*8 + 0*4 + 1*2 + 0*1
N= 16+8+2
N= 26

Sistema Hexadecimal

0011 1011

0010 1101

0010 1001

N1

N2

N3

Assim, para o primeiro grupo N1:


N1= (0011 1011)2
N1= 0*27 + 0*26 + 1*25 + 1*24 + 1*23 + 0*22 + 1*21 + 1*20
N1= 0*128 + 0*64 + 1*32 + 1*16 + 1*8 + 0*4 + 1*2 + 1*1
N1= 32+16+8+2+1
N1= 59
Para o prximo grupo de 8 bits, N2:
N2= (0010 1101)2
N2= 0*27+0*26+1*25+0*24+1*23+1*22+0*21+1*20
N2=0*128+0*64+1*32+0*16+1*8+1*4+0*2+1*1
N2= 32+8+4+1
N2= 45
SISTEMAS NUMRICOS E ALOCAO DE MEMRIA

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

Digamos que voc est acessando a memria do computador e encontra um agrupamento de 24 bits
na seguinte configurao:
0011 1011 0010 1101 0010 1001
O que significa essa string binria
(sequncia de 1s e 0s)? A resposta correta
: qual a estrutura do dado?
Voc pode ter se perguntado por que fizemos
uma reviso sobre os sistemas numricos e outros conceitos j vistos em
disciplinas anteriores. Tambm ficou curioso(a) em saber o que a to falada
estrutura de dados que at agora no ficou claro. Prepare-se, pois em alguns
minutos voc dir: agora as coisas comeam a fazer sentido.
Ns temos essa string binria, mas no sabemos como a sua estrutura,
ento, esse mesmo dado pode ser lido de inmeras maneiras diferentes. Vamos
considerar que cada conjunto de 8 bits representa um valor decimal.

shutterstock

ESTRUTURA DE DADOS

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

26 - 27

E finalmente, para os ltimos 8 bits, N3:


N3= (0010 1001)2
N3= 0*27+0*26+1*25+0*24+1*23+0*22+0*21+1*20
N3= 0*128+0*64+1*32+0*16+1*8+0*4+0*2+1*1
N3= 32+8+1
N3= 41
Ento, se interpretssemos a string de bits 0011 1011 0010 1101 0010 1001
como trs agrupamentos de 8 bits, o resultado seria a sequncia de nmeros: 59,
45 e 41. Note que a sequncia de nmeros apresentados diferente do nmero
decimal 594541.
Porm, como no sabemos qual a estrutura do dado, podemos ler a mesma
string de outras formas. E se cada grupo de 4 bits representar um nmero hexadecimal? Qual seria o resultado? Vamos usar uma tabela para facilitar a converso:
0011

1011

0010

1101

0010

1001

DECIMAL

11

13

HEXADECIMAL

BINRIO

Temos que a string de bits 0011 1011 0010 1101 0010 1001 em hexadecimal equivale a 3B2D29, usando a regra de que cada 4 bits formam 1 caractere de base 16.
Eu sei que cada dois caracteres hexadecimais podem formar 162 combinaes
possveis, ou seja, 256 nmeros, que a quantidade de caracteres existentes na
Tabela ASC II e sua extenso. Digamos ento que eu deseje olhar na tabela e ver
qual o caractere para cada grupo de dois dgitos em base 16. O resultado seria:
HEXADECIMAL

3B

2D

29

TABELA ASC II

Vamos analisar agora todas as formas que encontramos para interpretar o mesmo
valor. Lembre-se que como no sabemos como o dado foi estruturado na memria, existem ainda outras possibilidades de anlise.

Estrutura de Dados

O nmero representado por 11 pode possuir diferentes significados. Se for


na base hexadecimal, o nmero 11 equivale a 17 decimal. Se for na base
binria, o nmero 11 representa o 3 decimal.

Binrio

0011 1011 0010 1101 0010 1001

Decimal, em grupo de 8 bits

59 45 41

Hexadecimal, em grupo de 4 bits

3B 2D 29
;-)

Agora ficou claro que no basta apenas ler a memria, preciso saber como as
informaes armazenadas foram estruturadas para ento fazer a correta interpretao de seus valores.
Voc encontrar a Tabela ASC II e a sua extenso no final deste livro.

TIPOS DE VARIVEIS E ALOCAO NA MEMRIA


Para esta disciplina, escolhemos a Linguagem C, que foi a mesma adotada na
disciplina de Algoritmos e Lgica de Programao II. Dessa forma, esperamos
que o aluno possa entrar direto no entendimento do contedo sem muita necessidade de estudo aprofundado da sintaxe.
O C uma linguagem de tipagem forte, ou
seja, todas as variveis precisam ter um tipo
definido. Outras linguagens como o Clipper
e o PHP possuem tipagem fraca, as variveis
so criadas sem definio e podem assumir
qualquer valor.
Existem 7 tipos de variveis na linguagem
C e eles ainda permitem o uso de modificadores como
signed, unsigned, short, long etc. Quando falamos em tipo,
shutterstock

SISTEMAS NUMRICOS E ALOCAO DE MEMRIA

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

Hexadecimal, convertido pela tabela ASC II

28 - 29

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

falamos da estrutura da varivel. o conjunto de regras que determina como ela


deve ser lida e como as operaes matemticas so realizadas.
Observe o seguinte trecho de cdigo:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

#include <stdio.h>
#include <stdlib.h>
int i, j, k;
float l, m, n;
int main() {
i = 1;
j = 2;
k = i + j;
l = 1;
m = 2;
n = l + m;
printf( k = %d\n n = %f\n, k, n);
system(pause);
return(0);
}

Tanto o valor da varivel k quanto o valor da varivel n so obtidos por meio


da atribuio de uma soma de duas outras variveis. Apesar de ambos os casos
utilizarem o mesmo smbolo de operao (+), a forma como o clculo realizado internamente diferente. O compilador sabe que a estrutura de nmeros
inteiros diferente da estrutura de nmeros reais e que para cada caso a mesma
operao (adio) precisa ser realizada de acordo com as regras definidas pelo
tipo da varivel.

NMEROS INTEIROS
Um nmero inteiro positivo utiliza todos os bits para compor seu valor. Assim,
um nmero com n bits tem 2n valores possveis. Para ficar mais fcil o entendimento, vamos imaginar um nmero inteiro positivo com 8 bits (n = 8). Aplicando
Nmeros Inteiros

Para encontrar o seu valor negativo (-42) usando o modo Complemento de 1


basta inverter o valor de todos os seus bits:
1

As possveis representaes de nmeros vo de -(2n-1 - 1) a +(2n-1 - 1). Em um


nmero inteiro com 8 bits, os valores variam de -127 a +127. Essa notao permite a existncia de duas representaes para o nmero 0. O zero positivo 0000
0000 e o zero negativo 1111 1111.
Na notao Complemento de 2, o valor 1 somado na notao Complemento
de 1 de um nmero negativo. Por exemplo, o nmero 42 representado por 0010
1010 e o seu Complemento de 1 encontrado invertendo o valor de todos os
bits ficando 1101 0101, representando -42. Na notao Complemento de 2 basta
somar 1 ao nmero negativo encontrado no Complemento de 1, que 1101 0110.
Nessa notao, as possveis representaes variam de -(2n-1) a +(2n-1 - 1).
Pensando em um nmero inteiro de 8 bits, os valores variam de -128 a +127.
Isso acontece porque h apenas uma nica representao para o nmero 0, que
0000 0000. Achando o Complemento de 1 do nmero 0 encontramos 1111

SISTEMAS NUMRICOS E ALOCAO DE MEMRIA

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

a regra de 2n com n = 8, temos:


28= 256
Ento o intervalo de nmeros inteiros positivos vlidos com 8 bits vai de 0
(0000 0000) a 255 (1111 1111).
Segundo Tenenbaum (1995), existem vrias formas de representar nmeros
inteiros negativos. As duas principais so o Complemento de 1 e o Complemento
de 2.
No Complemento de 1, o primeiro bit a partir da esquerda (a maior potncia
de 2) reservado como identificador de sinal no nmero. Para um inteiro com n
bits, os n - 1 bits restantes so usados para a representao de valor. Uma sequncia
de bits comeando por 0 representa um nmero positivo e uma sequncia de
bits comeando por 1 representa um valor negativo. O nmero negativo obtido
invertendo o valor de todos os bits.
Exemplo: O nmero 42 representado por:

30 - 31

Quando o primeiro bit da esquerda de uma varivel numrica for 1, significa


que o nmero negativo desde que a varivel suporte valores menores do
que zero (signed).

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

1111 e somando-se 1 a esse valor obtemos 1 0000 0000. Como o resultado tem
9 bits, o nono bit descartado ficando apenas 0000 0000.

NMEROS REAIS
O conjunto dos nmeros reais formado por nmeros com casas decimais alm
dos j conhecidos nmeros inteiros. Assim, todo nmero inteiro um nmero
real, mas nem todo nmero real um nmero inteiro. O 42 um nmero inteiro
e tambm um nmero pertencente ao conjunto dos nmeros reais. O nmero
4,2 um nmero real, mas no inteiro.
Se em um programa for necessrio controlar a quantidade de produtos em
estoque e os produtos no so fracionados, usa-se um nmero inteiro. Para guardar o preo do produto, indicado um nmero real, j que alguns preos podem
ser quebrados com complemento em centavos de reais.
Na computao, a forma mais utilizada para a representao de nmeros
reais a notao de ponto flutuante. Segundo Tenenbaum (1995), existem vrios
tipos de notao de ponto flutuante, cada qual com caractersticas prprias. O
conceito que a representao de um nmero real se d por um nmero, chamado mantissa (M), multiplicado por uma base (B) elevada a uma potncia
com expoente (E) inteiro.
M * BE
Vamos considerar, por exemplo, o nmero real 123,45 e que para represent-lo como ponto flutuante a base seja fixada em 10 (B=10). A notao ficaria:
12345 * 10-2
Como 10-2 = 0,01, ento 12345 * 0,01 = 123,45. Note que o nmero (mantissa)
Nmeros Reais

10

0000 0000 0000 0000 0000 1010 0000 0000

100

0000 0000 0000 0000 0110 0100 0000 0000

1000

0000 0000 0000 0011 1110 1000 0000 0000

0,001

0000 0000 0000 0000 0000 0001 1111 1101

10421,12

0000 1111 1110 0110 1100 0000 1111 1110

A vantagem da notao de ponto flutuante que ela permite a representao


de valores absolutos muito grandes ou muito pequenos. Na notao descrita
nesta unidade, o maior nmero que pode ser representado 223-1 *10127, que
um nmero muito grande, e o menor 10-128, que um nmero muito pequeno.
O limitante com o qual os nmeros podem ser escritos est diretamente relacionado quantidade de bits significativos na mantissa. Nem todo nmero entre
o intervalo do menor e do maior podem ser representados. No formato aqui
utilizado, 24 bits so reservados para a mantissa, sendo o primeiro usado para
identificar se ele positivo ou negativo, restando apenas 23 bits significativos.
Dessa forma, o nmero 10 milhes e 1 (que exige 24 dgitos binrios significativos na mantissa) precisa ser aproximado para 10 milhes, (1*107) que exige
apenas um nico dgito de significncia.

SISTEMAS NUMRICOS E ALOCAO DE MEMRIA

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

fixo e que a casa decimal (vrgula) flutua no nmero uma quantidade de algarismos definida pela potncia formada pela base elevada ao expoente.
A notao de ponto flutuante pode variar de acordo com a arquitetura do
hardware ou das regras definidas pelo compilador. O nmero 1000, por exemplo,
pode ser escrito como 1000*100, 100 *101, 10*102 ou 1*103. O mais usualmente
utilizado para representar um nmero real uma string de 32 bits, sendo os primeiros 24 bits reservados para a mantissa e os ltimos 8 para o expoente, com
a base fixa em 10.
A representao em binrio de 24 bits do nmero decimal inteiro 12345
0000 0000 0011 0000 0011 1001, e a representao em complemento de 2 em 8
bits de -2 1111 1110. Seguindo esses conceitos, a representao de 123,45 se
d pela seguinte string de 32 bits:
0000 0000 0011 0000 0011 1001 1111 1110
Vejamos alguns exemplos de nmeros em notao de ponto flutuante:

32 - 33

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

shutterstock

CONSIDERAES FINAIS
 grande maioria dos profissionais que trabalham com computador tem uma
A
viso de alto nvel do que acontece, ou seja, veem e interagem apenas com o
resultado do processo, sem ter acesso e conhecimento de como ele se desenvolve.
Nesta unidade, voc teve a oportunidade de observar melhor como as coisas acontecem em baixo nvel, no nvel em que o computador trabalha. Agora
quando voc for criar um programa e definir uma varivel, voc com certeza ir
lembrar que ela no s um espao reservado na memria, ela uma estrutura
que define como aquelas informaes sero lidas e trabalhadas.
Para poder trabalhar com estruturas de dados mais complexos, precisamos
primeiramente ver as estruturas mais simples, e para isso necessrio saber como
as informaes so representadas nos principais sistemas numricos. Esse foi o
objetivo desta unidade.
Na prxima unidade comearemos fazendo um pequeno resumo sobre variveis para armazenamento de valores mltiplos que so os vetores, matrizes e
registros. Em seguida, aplicaremos o que foi visto at o momento e apresentaremos duas das mais simples e mais importantes estrutura de dados: pilhas e filas.

<http://youtube.com.br/watch?v=ntylzQWvzCA>.
<http://youtube.com.br/watch?v=TsoXOQ8ZEa0>.
<http://pontov.com.br/site/index.php/cpp/41-visual-c/59-como-utilizar-o-visual-c-parte-1>.
<http://pontov.com.br/site/index.php/
cpp/41-visual-c/72-como-utilizar-o-visual-studio-c-parte-2>.
<http://pontov.com.br/site/index.php/
cpp/41-visual-c/73-como-utilizar-o-visual-studio-c-parte-3>.

Consideraes Finais

1. Uma string de 8 bits pode conter diversos tipos de dados diferentes. Considerando que as strings a seguir possuam um valor decimal inteiro positivo ou dois
nmeros em hexadecimal de 4 bits cada, efetue a converso conforme o exemplo da letra a:
a) 1010 1010
Para encontrar o valor em decimal de uma sequncia de bits, basta somar as potncias de 2 elevado posio de relevncia do bit, para os bits de valor 1.
1 * 27

1 * 128

128

0*2

0 * 64

1 * 25

1 * 32

32

0 * 24

0 * 16

1*2

1*8

0*2

0*4

1 * 21

1*2

0*2

0*1

Total

170

Para encontrar o valor hexadecimal, basta calcular o valor decimal de cada grupo de
4 bits e comparar com o conjunto de valores em hexadecimal (de 0 a F).
BINRIO

Resposta:
Binrio = 1010 1010
Decimal = 170
Hexadecimal = AA
a) 1100 0011
b) 1100 1100
c) 1101 1111
d) 0000 1000

DECIMAL

HEXADECIMAL

1010

10

1010

10

34 - 35

2. Encontre o valor decimal, o nmero negativo em Complemento de 1 e Complemento de 2 das strings de bits a seguir, conforme o exemplo da letra a:
a) 0010 1010
Para encontrar o valor em decimal de uma sequncia de bits, basta somar as potncias de 2 elevado posio de relevncia do bit, para os bits de valor 1.
0 * 27

0 * 128

0*2

0 * 64

1 * 25

1 * 32

32

0 * 24

0 * 16

1*2

1*8

0*2

0*4

1 * 21

1*2

0*2

0*1

Total

42

Para encontrar o Complemento de 1 de uma string de bits, basta inverter o valor de


todos os seus bits.
42
0

-42 (Complemento de 1)

Para encontrar o Complemento de 2, basta somar 1 ao Complemento de 1 do nmero.


-42 (Complemento de 2)
1

a) 0111 1111
b) 0000 0000
c) 0110 0011
d) 0101 1010

3. Sempre que uma string de bits contiver o valor 1 no primeiro bit da direita o
nmero ser mpar? Por qu?
4. Sempre que uma string de bits contiver o valor 1 no primeiro bit da esquerda o
nmero ser negativo? Por qu?

36 - 37

PILHAS E FILAS

UNIDADE

Professor Me. Rogrio de Leon Pereira

II

Objetivos de Aprendizagem
Relembrar o conceito de variveis heterogneas.
Revistar a estrutura de vetores e matrizes.
Criar novos tipos de estruturas usando registros.
Aprender sobre pilhas e filas.

Plano de Estudo
A seguir, apresentam-se os tpicos que voc estudar nesta unidade:
Estruturas homogneas e heterogneas
Vetores e matrizes
Registros
Pilhas
Filas

38 - 39

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

INTRODUO
Faremos agora uma pequena e breve reviso sobre estruturas homogneas e heterogneas. Isso se faz necessrio porque elas so a base para a criao de estruturas
mais complexas como as filas e pilhas.
Tanto a fila como a pilha so conjuntos ordenados de itens, porm ambas se diferenciam pelas regras de entrada e sada. Na pilha a entrada e a sada de dados se do
pela mesma extremidade, chamada de topo da pilha. Na fila a entrada e a sada ocorrem em lugares opostos: a entrada acontece no final da fila e a sada no seu incio.
Apesar de simples, ambas as estruturas (fila e pilha) so amplamente utilizadas em diversas reas da computao. Um exemplo pode ser visto no problema de
escalonamento do uso do processador descrito por Machado (2002, p. 138-141).
A estrutura, a utilizao e as regras de insero e remoo em pilhas e filas so
o foco de estudo desta unidade.

ESTRUTURAS HOMOGNEAS E HETEROGNEAS


A primeira estrutura que estudamos foi a varivel. Ela um local reservado na
memria para armazenamento de dados. Cada varivel pode armazenar apenas uma nica informao. Porm, em alguns momentos necessrio guardar
muitas informaes e a primeira soluo em vista seria declarar variveis em
quantidade suficiente para atender a toda a demanda.
Isso tem muitas desvantagens. Para um programa que vai ler 5 entradas,
no algo muito trabalhoso, mas imagine ter que ler 50, 100 ou 1000 valores,
seria necessrio criar muitas variveis, muito cdigo destinado a leitura, processamento e sada.
Para esses casos, a maioria das linguagens de programao traz estruturas
prontas para armazenamento mltiplo em uma nica varivel. Elas so classificadas em homogneas, que armazenam um nico tipo de informao, e
heterogneas, que podem armazenar informaes de tipos diferentes.
Introduo

II

VETORES E MATRIZES
A declarao de um vetor na linguagem C muito simples, basta declarar uma
varivel e colocar o seu tamanho entre colchetes logo aps o nome. Pense no
vetor como uma matriz de uma nica linha e quantidade de colunas equivalente
ao seu tamanho. O vetor uma estrutura homognea, por isso s pode armazenar um nico tipo de dado. Exemplo da declarao em linguagem C de um vetor
chamado dados com capacidade para armazenar 5 valores inteiros:
int dados[5];

Na linguagem C o ndice dos vetores e matrizes comea no valor 0 e vai at


n - 1, onde n o tamanho do vetor. No exemplo acima, para acessar a primeira
posio da varivel dados usa-se o ndice 0 e a ltima o ndice 4.
dados[0]; // primeira posio do vetor dados
dados[1]; // segunda posio
dados[2];
dados[3];
dados[4]; // quinta e ltima posio

As matrizes possuem pelo menos duas dimenses. A declarao parecida


com a de vetores, precisando indicar tambm a quantidade de linhas alm da
quantidade de colunas. Abaixo o exemplo da declarao de uma matriz de nmeros reais com duas linhas e trs colunas.
float matriz[2][3];

PILHAS E FILAS

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

shutterstock

40 - 41

Lembre-se que so necessrios dois ndices para acessar os dados em uma matriz
bidimensional.

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

matriz[0][0]; // primeira linha, primeira coluna


matriz[0][1]; // primeira linha, segunda coluna
matriz[1][2]; // segunda e ltima linha, terceira e ltima coluna

REGISTROS
O registro uma coleo de variveis, e por ser uma estrutura heterognea, permite o armazenamento de informaes de tipos diferentes. Ele possibilita que o
programador crie tipos de dados especficos e personalizados.
A declarao de um registro se d pela palavra reservada struct, seguida pelo
conjunto de elementos que o compem. Veja um exemplo de um registro chamado fraction que possui trs elementos: numerator, denominator e value.
struct fraction {
int numerator;
int denominator;
float value;
}

Aps declarado o registro o seu uso se d como tipo de varivel, assim como
usado para inteiros, reais, caracteres etc. Cada elemento do registro acessado
por meio de uma referncia composta pelo nome_da_varivel.nome_do_elemento.
fraction metade; // cria uma varivel do tipo fraction
metade.numerator = 1; // atribui valor ao elemento numerator
metade.denominator = 2; // atribui valor ao elemento denominator
metade.value = metade.numerator / metade.denominator

possvel criar vetores e matrizes para acomodar mltiplos registros. Vamos


definir um registro chamado livro para armazenar quatro notas e depois vamos
criar um vetor para armazenar as notas de 40 alunos.

Registros

II

struct livro {
float nota1;
float nota2;
float nota3;
float nota4;
}
livro alunos_notas[40];

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

PILHAS

shutterstock

A Pilha uma das estruturas mais simples e mais versteis


dentre as utilizadas na computao. Antes de entrar nas
nuances tcnicas sobre pilhas, vamos abstrair o seu conceito para uma situao real.
Imagine estar trabalhando na construo civil. Existem
inmeros tijolos que precisam ser organizados e preparados
para a edificao de um prdio. Voc orientado a empilh-los prximo do local da obra. O primeiro tijolo colocado
no cho, no local estipulado, em seguida o segundo tijolo
colocado em cima do primeiro e cada novo tijolo colocado
no topo da pilha. Na hora de levantar uma nova parede,
os tijolos so retirados a partir do topo da pilha de tijolos.
Os tijolos foram empilhados e depois desempilhados.
No faz sentido querer pegar o primeiro tijolo que est l
em baixo na base, mas sim o primeiro que est livre na parte
de cima. Esse o conceito principal de Pilha. o mesmo
para uma pilha de camisas, pilha de caixas de leite, pilha de
papis etc.

PILHAS E FILAS

42 - 43

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

Na informtica, a pilha uma estrutura onde os dados so


inseridos e removidos no seu topo. So estruturas conhecidas como Last In, First Out (LIFO), que pode ser traduzido
por ltimo a Entrar, Primeiro a Sair.
Vamos agora pensar em um exemplo para facilitar o
entendimento. Temos um vetor de 10 posies no qual
sero inseridos os seguintes valores nessa ordem: 1, 5,
12 e 3. O vetor deve ficar com essa cara:
1

12

shutterstock

Agora sero inseridos mais dois nmeros na sequncia: 14 e 2. O vetor ficar


com essa configurao:
1

12

14

Pensando que o valor mais esquerda o comeo da pilha, o lado oposto o


seu final e todos os valores vo entrando na primeira casa livre direita. Esse
o processo de empilhamento, onde cada novo valor inserido em cima dos
valores previamente inseridos (empilhados).
Agora preciso remover um valor. Qual ser removido e por qu? O valor
removido ser o ltimo valor da pilha, j que pela regra, o ltimo valor que entra
ser o primeiro valor a sair (Last In, First Out). o processo de desempilhamento.
1

12

14

Para se construir uma pilha, so necessrios pelo menos trs elementos: um


vetor para armazenar os dados e dois nmeros inteiros, um para marcar o incio
e outro o final da pilha. Veja o exemplo, a seguir em linguagem C da definio
de uma estrutura para uma pilha:

Pilhas

II

//Constantes
#define tamanho 10
//Estrutura da Pilha
struct tpilha {
int dados[tamanho];
int ini;
int fim;
};
//Variveis globais
tpilha pilha;

//Mostrar o contedo da Pilha


void pilha_mostrar() {
int i;
printf([ );
for (i = 0; i < tamanho; i++) {
printf(%d , pilha.dados[i]);
}
}printf(]\n\n);

Para a entrada dos dados, criamos a funo pilha_entrar(). Para o empilhamento, necessrio ler o dado diretamente na primeira posio disponvel, que
representa o topo da pilha. Isso possvel utilizando o atributo fim criado na

PILHAS E FILAS

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

Optamos por criar uma constante chamada tamanho para guardar a capacidade
mxima da pilha. Se houver necessidade de aumentar estaticamente o tamanho da pilha, basta alterar o valor da constante sem precisar revisar o resto do
cdigo-fonte. Essa constante tambm ser til na hora de fazer verificaes nos
processos de empilhamento e desempilhamento.
O vetor dados guardar os valores que forem sendo empilhados, o atributo
ini marca o incio da pilha e o atributo fim o seu final. Ambas as variveis ini e
fim so inicializadas com valor zero para indicar que a pilha est vazia.
Em seguida, vamos criar trs funes, uma para mostrar o contedo da
pilha, que ajuda no entendimento e visualizao do processo, uma para a entrada
(empilhamento) e outra para a sada (desempilhamento).
A funo pilha_mostrar() muito simples, beirando o trivial. Basta um
lao de repetio para percorrer todas as posies do vetor e ir imprimindo seus
valores na tela. Aqui j usamos a constante tamanho para saber quantos valores cabem na pilha.

44 - 45

estrutura da pilha. Depois da leitura, o valor de fim atualizado para que ele
aponte sempre para a primeira posio disponvel.

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

//Adicionar um elemento no final da Pilha


void pilha_entrar(){
printf(\nDigite o valor a ser empilhado: );
scanf(%d, &pilha.dados[pilha.fim]);
pilha.fim++;
}

Do jeito que est, no h nenhum tipo de controle. Os valores so empilhados infinitamente, porm, sabemos que a nossa pilha tem um tamanho finito.
necessrio criar mecanismos que evitem o estouro da pilha. Vamos escrever
novamente a funo pilha_entrar() adicionando agora um desvio condicional
para verificar se existe espao disponvel para o novo empilhamento.
//Adicionar um elemento no final da Pilha
void pilha_entrar(){
if (pilha.fim == tamanho) {
printf(\nA pilha est cheia, impossvel empilhar um novo
elemento!\n\n);
system(pause);
}
else {
printf(\nDigite o valor a ser empilhado: );
scanf(%d, &pilha.dados[pilha.fim]);
pilha.fim++;
}
}

Agora faremos uma pequena simulao do funcionamento da funo de


empilhamento de uma pilha com 5 posies. O vetor dados e as variveis de
controle ini e fim so inicializados com 0.
NDICE =

DADOS =

ini = 0
fim = 0
tamanho = 5
Pilhas

II

Vamos inserir o nmero 42 no final da pilha. A primeira coisa que a funo


pilha_entrar() faz verificar se a pilha atingiu o seu limite. Isso se d comparando o atributo fim com a constante tamanho. Como fim (0) diferente de
tamanho (5), o algoritmo passa para a leitura do dado que ser guardado na
posio fim do vetor dados. Em seguida, o atributo fim sofre o incremento de 1.
NDICE =

DADOS =

42

NDICE =

DADOS =

42

33

22

13

ini = 0
fim = 4
tamanho = 5
Note que o atributo fim possui valor 4, mas no h nenhum valor inserido
nessa posio do vetor dados. O atributo fim est apontando sempre para a primeira posio disponvel no topo da pilha. Ele tambm representa a quantidade
de valores inseridos (4) e que atualmente ocupam as posies 0 a 3 do vetor.
Vamos inserir um ltimo nmero: 9.
NDICE =

DADOS =

42

33

22

13

PILHAS E FILAS

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

ini = 0
fim = 1
tamanho = 5
Vamos inserir mais 3 valores: 33, 22 e 13. Para cada entrada ser feita a verificao do atributo fim com a constante tamanho; o valor ser inserido no vetor
dados na posio fim e o valor de fim ser incrementado em 1.

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

46 - 47

ini = 0
fim = 5
tamanho = 5
Agora a pilha est completa. Se tentarmos inserir qualquer outro valor, a
comparao de fim (5) com tamanho (5) far com que seja impresso na tela
uma mensagem informando que a pilha j se encontra cheia, evitando assim o
seu estouro. O atributo fim contm o valor 5, indicando que existem 5 valores
no vetor e ele aponta para uma posio invlida, j que um vetor de 5 posies
tem ndice que comea em 0 e vai at 4.
Para o desempilhamento, vamos criar a funo pilha_sair(). A remoo se
d no elemento fim -1 do vetor dados, lembrando que o atributo fim aponta para
a primeira posio livre, e no esse o valor que queremos remover, mas sim o
valor diretamente anterior. Aps a remoo do item, o valor de fim deve ser atualizado para apontar corretamente para o final da pilha que acabou de diminuir.
/Retirar o ltimo elemento da Pilha
void pilha_sair() {
pilha.dados[pilha.fim-1] = 0;
pilha.fim--;
}

O que acontece quando o vetor dados est vazio? E se removermos mais elementos do que existem na pilha? Nesse caso, no haver um estouro na pilha,
mas voc pode considerar que seria um tipo de imploso. Os vetores no trabalham com ndice negativo, e se muitos elementos fossem removidos alm da
capacidade do vetor, o valor de fim iria diminuindo at passar a ser um valor
negativo. Na hora da incluso de um novo valor, o mesmo seria adicionado em
uma posio invlida e seria perdido.
preciso fazer um controle antes da remoo para verificar se a pilha est
vazia. Vamos comparar ento o valor de ini com fim. Se forem iguais, significa
que a pilha est vazia e que nenhum valor pode ser removido.

Pilhas

II

Vamos resgatar agora a estrutura que carinhosamente empilhamos nas pginas anteriores.
NDICE =

DADOS =

42

33

22

13

ini = 0
fim = 5
tamanho = 5
Precisamos remover um nmero. Como no se trata de um vetor qualquer,
mas sim de uma estrutura em pilha, a remoo comea sempre do ltimo para o
primeiro (Last In, First Out). O primeiro passo da funo pilha_sair() a comparao dos atributos ini (0) e fim (5), para verificar se a pilha no est vazia.
Como os valores so diferentes, o algoritmo segue para a linha de remoo.

muito comum encontrar na literatura os termos push para o processo de


empilhar e pop para o de desempilhar.

PILHAS E FILAS

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

//Retirar o ltimo elemento da Pilha


void pilha_sair() {
if (pilha.ini == pilha.fim) {
printf(\nA pilha est vazia, no h nada para desempilhar!\n\n);
system(pause);
}
else {
pilha.dados[pilha.fim-1] = 0;
pilha.fim--;
}
}

48 - 49

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

Lembrando que o atributo fim aponta para a primeira posio livre (ou seja, o
fim da pilha), ento temos que remover o valor do vetor dados na posio fim
subtraindo-se 1, que a ltima posio preenchida (topo da pilha). Por ltimo,
atualizamos o valor de fim para que aponte para a posio recm-liberada do
vetor dados.
NDICE =

DADOS =

42

33

22

13

ini = 0
fim = 4
tamanho = 5
Vamos agora remover os outros valores: 13, 22, 33 e 42. A pilha ir ficar
desse jeito:
NDICE =

DADOS =

ini = 0
fim = 0
tamanho = 5
Se tentarmos agora remover mais algum item da pilha, o programa escrever uma mensagem de erro na tela, j que o atributo fim (0) est com o mesmo
valor de ini (0), que significa que a pilha est vazia.
A seguir, voc encontrar o cdigo-fonte completo de uma pilha em
linguagem C. Logo aps coloquei comentrios sobre cada bloco do cdigo.
Digite o exemplo no seu compilador e execute o programa.

Pilhas

II

//Bibliotecas
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
//Constantes
#define tamanho 5
//Estrutura da Pilha
struct tpilha {
int dados[tamanho];
int ini;
int fim;
};
//Variveis globais
tpilha pilha;
int op;
//Protipao
void pilha_entrar();
void pilha_sair();
void pilha_mostrar();
void menu_mostrar();
//Funo principal
int main(){
setlocale(LC_ALL, "Portuguese");
op = 1;
pilha.ini = 0;
pilha.fim = 0;
while (op != 0) {
system("cls");
pilha_mostrar();
menu_mostrar();
scanf("%d", &op);
switch (op) {
case 1:
pilha_entrar();
break;

41
case 2:
42
pilha_sair();
43
break;
44
}
45
}
46
return(0);
47 }
48
49 //Adicionar um elemento no final da Pilha
50 void pilha_entrar(){
PILHAS
51 E FILASif (pilha.fim == tamanho) {
printf("\nA pilha est cheia, impossvel empilhar!\n\n");
52

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

case 2:
pilha_sair();
break;

50 - 51

}
}
return(0);
}
//Adicionar um elemento no final da Pilha
void pilha_entrar(){
if (pilha.fim == tamanho) {
printf("\nA pilha est cheia, impossvel empilhar!\n\n");

system("pause");
}
else {
printf("\nDigite o valor a ser empilhado: ");
scanf("%d", &pilha.dados[pilha.fim]);
pilha.fim++;
}
}
//Retirar o ltimo elemento da Pilha
void pilha_sair() {
if (pilha.ini == pilha.fim) {
printf("\nA pilha est vazia, impossvel desempilhar!\n\n");

system("pause");
}
else {
pilha.dados[pilha.fim-1] = 0;
pilha.fim--;
}
}
//Mostrar o contedo da Pilha
void pilha_mostrar() {
int i;
printf("[ ");
for (i = 0; i < tamanho; i++) {
printf("%d ", pilha.dados[i]);
}
printf("]\n\n");
}

//Mostrar o menu de opes


void menu_mostrar() {
printf("\nEscolha uma opo:\n");
printf("1 - Incluir na Pilha\n");
printf("2 - Excluir da Pilha\n");
printf("0 - Sair\n\n");
}

Linhas 1 a 4
Incluso de bibliotecas necessrias para o funcionamento do programa.
Linhas 6 e 7
Definio de constante para o tamanho da pilha.
Pilhas

II

PILHAS E FILAS

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

Linhas 9 a 14
Registro de estrutura para criar o tipo pilha contando com um vetor para
armazenar os dados e dois nmeros inteiros para controlar o incio e fim da pilha.
Linhas 16 a 18
Definies de variveis.
Linhas 20 a 24
Prototipao das funes. Para mais detalhes sobre prototipao, consulte
o livro de Algoritmos e Estrutura de Dados II.
Linhas 26 a 47
Funo principal (main), a primeira que ser invocada na execuo do
programa.
Linha 28
Chamada de funo para configurar o idioma para portugus, permitindo
o uso de acentos (no funciona em todas as verses do Windows).
Linhas 29 a 31
Inicializao das variveis.
Linhas 32 a 45
Lao principal, que ser executado repetidamente at que o usurio decida
finalizar o programa.
Linha 33
Chamada de comando no sistema operacional para limpar a tela.
Linha 34
Chamada da funo que mostra o contedo da Pilha na tela.
Linha 35
Chamada da funo que desenha o menu de opes.
Linha 36
L a opo escolhida pelo usurio.
Linhas 37 a 44
Desvio condicional que faz chamada de acordo com a opo escolhida pelo
usurio.
Linhas 49 a 60
Funo pilha_entrar(), que faz checagem do topo da pilha e insere novos
valores no vetor dados.

52 - 53

FILAS
As filas tambm so estruturas muito utilizadas, porm suas particularidades
fazem com seu que seu funcionamento seja um pouco menos simples do que
o das pilhas.
Voltemos ao exerccio de abstrao e pensemos como as filas esto presentes
no nosso dia a dia. Isso fcil, o brasileiro adora uma fila e s vezes se encontra em uma sem saber para qu. Fila no supermercado, fila no cinema, fila no
banco e assim por diante.
Chegando a uma agncia bancria, para ser atendido pelo caixa, um cidado honesto se dirige para o final da fila. Quando um caixa fica livre, aquele que
est na fila h mais tempo (primeiro da fila) atendido.
Esse conceito bsico de toda fila FIFO (First In, First Out), ou na traduo, o Primeiro que Entra o Primeiro que Sai.
Vamos agora simular uma fila em uma casa lotrica, imaginando que existe
lugar apenas para 5 pessoas e que o restante dos apostadores esperam fora do edifcio. O primeiro a chegar Joo, mas
ele ainda no atendido porque os
caixas esto contando o dinheiro e se
preparando para iniciar os trabalhos.
shutterstock

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

Linhas 62 a 72
Funo pilha_sair(), que verifica se existem elementos na pilha e remove o
ltimo inserido.
Linhas 74 a 82
Funo pilha_mostrar(), que l o contedo e desenha o vetor dados na tela.
Linhas 84 a 90
Funo menu_mostrar(), que desenha na tela as opes permitidas para o
usurio.

Filas

II

Joo

Em seguida, dois clientes entram praticamente juntos, Maria e Jos, e como


todo cavalheiro, Jos deixa que Maria fique frente na fila.
Joo

Maria

Jos

Maria

Jos

Maria passa automaticamente a ser a primeira da fila, ocupando o lugar que


era de Joo, tendo logo atrs de si Jos aguardando a sua vez de ser atendido.
Maria

Jos

Agora que est claro o funcionamento de uma fila, vamos program-la em


linguagem C. A primeira coisa que precisamos definir a sua estrutura. Usaremos
um vetor para armazenar os valores que sero enfileirados e dois nmeros inteiros para fazer o controle de incio e fim da fila. Usaremos tambm uma constante
para definir a capacidade de armazenamento.
//Constantes
#define tamanho 5
//Estrutura da Fila
struct tfila {
int dados[tamanho];
int ini;
int fim;
};
//Variveis globais
tfila fila;

Vamos criar uma funo chamada fila_entrar() para controlar a entrada


de novos valores na fila. A primeira coisa a se fazer verificar se h espao. Isso

PILHAS E FILAS

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

Um dos funcionrios est pronto para iniciar o atendimento e chama o cliente.


Qual deles ser atendido? O Joo, porque ele ocupa o primeiro lugar na fila, j
que em teoria o Primeiro que Entra o Primeiro que sai.

54 - 55

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

pode ser feito comparando o atributo fim com a constante tamanho. Caso haja
uma posio livre, o valor ser inserido no vetor dados na posio fim e finalmente o valor de fim incrementado em um.
//Adicionar um elemento no final da Fila
void fila_entrar(){
if (fila.fim == tamanho) {
printf(\nA fila est cheia, impossvel adicionar um novo valor!\n\n);
system(pause);
}
else {
printf(\nDigite o valor a ser inserido: );
scanf(%d, &fila.dados[fila.fim]);
fila.fim++;
}
}

At agora, a fila e a pilha esto muito parecidas na sua definio e modo de


entrada de dados. A principal diferena entre as duas estruturas est na forma
de sada. Na pilha sai sempre o elemento mais recente, na fila sai sempre o mais
antigo. Assim como na pilha, necessrio fazer uma verificao na fila para saber
se ainda existe algum elemento a ser removido.
//Retirar o primeiro elemento da Fila
void fila_sair() {
if (fila.ini == fila.fim) {
printf(\nA fila est vazia, no h nada para remover!\n\n);
system(pause);
}
}

Como o primeiro elemento da fila ser removido, os demais precisam andar


em direo ao incio, assim como acontece em uma fila de verdade. Em seguida,
atualizamos o valor do atributo fim para apontar corretamente para o final da fila.
int i;
for (i = 0; i < tamanho; i++) {
fila.dados[i] = fila.dados[i+1];
}
fila.dados[fila.fim] = 0;
fila.fim--;

Filas

II

A funo fila_sair() completa fica com essa cara:

Para finalizar agora, falta apenas a funo fila_mostrar(), que possui um


lao de repetio que percorre todo o vetor dados e imprime os valores na tela.
//Mostrar o contedo da Fila
void fila_mostrar() {
int i;
printf([ );
for (i = 0; i < tamanho; i++) {
printf(%d , fila.dados[i]);
}
printf(]\n\n);
}

A principal regra para uma fila que o primeiro que entra o primeiro que sai.
Esse exemplo no a nica forma de implementao de fila. No nosso caso, cada
vez que algum sai da fila, todos os outros clientes precisam se mover para a primeira posio que ficou livre a sua esquerda.

PILHAS E FILAS

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

//Retirar o primeiro elemento da Fila


void fila_sair() {
if (fila.ini == fila.fim) {
printf(\nA fila est vazia, no h nada para remover!\n\n);
system(pause);
}
else {
int i;
for (i = 0; i < tamanho; i++) {
fila.dados[i] = fila.dados[i+1];
}
fila.dados[fila.fim] = 0;
fila.fim--;
}
}

56 - 57

Existem outras formas de fila, por exemplo, a fila cclica. Ao invs de mover
os dados para a esquerda sempre que uma posio fica livre, move-se o atributo
que marca o incio da fila para a direita. Essa uma alternativa interessante para
quando se tem filas muito grandes e no se pode perder tempo movendo todo
o resto dos dados em direo ao comeo da fila.
Vamos voltar ao exemplo da fila anterior com o Joo, a Maria e o Jos.

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

Joo

Maria

Jos

ini = 0
fim = 3
tamanho = 5
Quando o Joo deixa a fila, no a Maria que anda em direo posio
ocupada por Joo, mas o incio da fila que se move em direo a Maria.
Maria

Jos

ini = 1
fim = 3
tamanho = 5
Nesse exemplo, para saber o tamanho da fila, necessrio subtrair o valor
do atributo fim (3) do atributo ini (1).

Filas

II

comum na literatura o uso do termo enqueue para indicar a insero e


dequeue para a remoo em filas.

1 //Bibliotecas
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <locale.h>
5
6 //Constantes
7 #define tamanho 5
8
9 //Estrutura da Fila
10 struct tfila {
11
int dados[tamanho];
12
int ini;
13
int fim;
14 };
15
16 //Variveis globais
17 tfila fila;
18 int op;
19
20 //Protipao
21 void fila_entrar();
22 void fila_sair();
23 void fila_mostrar();
24 void menu_mostrar();
25
26 //Funo principal
27 int main(){
28
setlocale(LC_ALL, "Portuguese");
29
op = 1;
30
fila.ini = 0;
31
fila.fim = 0;
32
while (op != 0) {
33
system("cls");
34
fila_mostrar();
35
menu_mostrar();
36
scanf("%d", &op);
PILHAS
37 E FILAS switch (op) {
38
case 1:

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

Apesar de ser implementado de forma diferente, o conceito ainda o mesmo: o


primeiro que entra o primeiro que sai. Ningum gosta de fura-fila, no verdade?
Segue agora o cdigo-fonte completo de uma fila em linguagem C. Fiz comentrios explicando cada bloco do cdigo. Digite o exemplo no seu compilador e
execute o programa.

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

24 void menu_mostrar();
25
26 //Funo principal
27 int main(){
28
setlocale(LC_ALL, "Portuguese");
29
op = 1;
30
fila.ini = 0;
31
fila.fim = 0;
32
while (op != 0) {
33
system("cls");
34
fila_mostrar();
35
menu_mostrar();
36
scanf("%d", &op);
37
switch (op) {
38
case 1:
39
fila_entrar();
40
break;
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77

78
79
80
81
82
83
84
85
86
87

58 - 59

case 2:
fila_sair();
break;
}
}
return(0);
}
//Adicionar um elemento no final da Fila
void fila_entrar(){
if (fila.fim == tamanho) {
printf("\nA fila est cheia, volte outro dia!\n\n");

system("pause");
}
else {
printf("\nDigite o valor a ser inserido: ");
scanf("%d", &fila.dados[fila.fim]);
fila.fim++;
}
}
//Retirar o primeiro elemento da Fila
void fila_sair() {
if (fila.ini == fila.fim) {
printf("\nFila vazia, mas logo aparece algum!\n\n");

system("pause");
}
else {
int i;
for (i = 0; i < tamanho; i++) {
fila.dados[i] = fila.dados[i+1];
}
fila.dados[fila.fim] = 0;
fila.fim--;
}
}

//Mostrar o contedo da Fila


void fila_mostrar() {
int i;
printf("[ ");
for (i = 0; i < tamanho; i++) {
printf("%d ", fila.dados[i]);
}
printf("]\n\n");
}

Filas

II
//Mostrar o contedo da Fila
void fila_mostrar() {
int i;
printf("[ ");
for (i = 0; i < tamanho; i++) {
printf("%d ", fila.dados[i]);
}
printf("]\n\n");
}
//Mostrar o menu de opes
void menu_mostrar() {
printf("\nEscolha uma opo:\n");
printf("1 - Incluir na Fila\n");
printf("2 - Excluir da Fila\n");
printf("0 - Sair\n\n");
}

Linhas 1 a 4
Incluso de bibliotecas necessrias para o funcionamento do programa.
Linhas 6 e 7
Definio de constante para o tamanho da fila.
Linhas 9 a 14
Registro de estrutura para criar o tipo fila contando com um vetor para
armazenar os dados e dois nmeros inteiros para controlar o incio e fim da fila.
Linhas 16 a 18
Definies de variveis.
Linhas 20 a 24
Prototipao das funes. Para mais detalhes sobre prototipao, consulte
o livro de Algoritmos e Estrutura de Dados II.
Linhas 26 a 47
Funo principal (main), a primeira que ser invocada na execuo do
programa.
Linha 28
Chamada de funo para configurar o idioma para portugus, permitindo
o uso de acentos (no funciona em todas as verses do Windows).

PILHAS E FILAS

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

60 - 61

Linhas 29 a 31
Inicializao das variveis.
Linhas 32 a 45
Lao principal, que ser executado repetidamente at que o usurio decida
finalizar o programa.
Linha 33
Chamada de comando no sistema operacional para limpar a tela.
Linha 34
Chamada da funo que mostra o contedo da Fila na tela.
Linha 35
Chamada da funo que desenha o menu de opes.
Linha 36
L a opo escolhida pelo usurio.
Linhas 37 a 44
Desvio condicional que faz chamada de acordo com a opo escolhida pelo
usurio.
Linhas 49 a 60
Funo fila_entrar(), que faz checagem do fim da fila e insere novos valores no vetor dados.
Linhas 62 a 76
Funo fila_sair(), que verifica se existem elementos na fila e remove o elemento mais antigo.
Linhas 78 a 86
Funo fila_mostrar(), que l o contedo e desenha o vetor dados na tela.
Linhas 88 a 94
Funo menu_mostrar(), que desenha na tela as opes permitidas para o
usurio.

Filas

II

CONSIDERAES FINAIS

<http://www.mlaureano.org/livro/livro_estrutura_conta.pdf> (Captulos 3 e
4).

PILHAS E FILAS

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

Na unidade anterior, vimos uma pequena reviso sobre os tipos de variveis e


aprendemos como elas so alocadas na memria. Isso muito importante, porque uma sequncia de bits nada mais do que um monte de nmeros 1 e 0 sem
sentido algum. a estrutura de dados que determina como ela deve ser lida e
qual o seu significado.
Agora foi a vez de revisarmos as estruturas homogneas e heterogneas. Elas
so fundamentais para que possamos estudar estruturas mais complexas, como
as pilhas e as filas.
Os vetores e matrizes permitem que tenhamos em uma nica varivel uma
coleo grande de dados agrupados. Com os registros podemos criar nova tipagem de variveis e us-las para definir estruturas capazes de conter informaes
de diferentes tipos.
Tanto as pilhas como as filas so tipos de listas, ou seja, coleo de dados
agrupados. A diferena que tanto a pilha como a fila possuem regras de entrada
e sada, diferente das listas simples.
As pilhas so usadas em problemas onde mais importante resolver o problema mais recente, ou mais oneroso, ou mais prximo. J as filas tm funo
contrria e so aplicadas na soluo de casos onde proibido que questes mais
recentes recebam ateno antes de questes mais antigas.
At o momento, trabalhamos com estruturas estticas. Depois de definido
o tamanho da pilha ou da fila, ele permanecer o mesmo at o final da execuo
do programa. Na prxima unidade, aprenderemos sobre ponteiros e a sua utilizao na criao de estruturas dinmicas sem tamanho ou limite pr-definido.

62 - 63

1. Quando um livro devolvido na Biblioteca do CESUMAR, o funcionrio responsvel pelo recebimento coloca o livro em cima de uma pilha de livros na mesa
ao lado da recepo. O auxiliar de bibliotecrio pega o livro do topo da pilha,
verifica o seu cdigo e leva-o para o seu devido local no acervo.
No atual sistema de informao, possvel verificar se o livro est disponvel ou
se est emprestado. Porm, o livro que acabou de ser devolvido ainda no se
encontra na prateleira, pois existe um intervalo de tempo entre a devoluo do
mesmo e o momento em que ele guardado na estante.
A sugesto do departamento de TI de criar um programa que faa o controle
na pilha, assim, pode-se verificar se o livro ainda no foi guardado e qual a sua
posio dentro da pilha de livros que aguardam ao lado da recepo.
a) Crie uma estrutura para a pilha de livros. Lembre-se de que ela tem que ter
um vetor para armazenar os dados (cdigo, nome do livro
e autor) e dois nmeros inteiros, um para controlar o
incio e outro o final da pilha.
b) Defina a varivel que ser um vetor do tipo pilha de
livros.
c) Faa uma funo de empilhamento, lembrando-se
de verificar se a pilha atingiu o tamanho mximo de
livros (a mesa no aguenta muito peso).
d) Crie uma funo para desempilhamento de livros, no
se esquea de que necessrio verificar se ainda existem livros para ser guardados.
e) Elabore uma funo que apresente na tela a lista de
todos os livros que se encontram empilhados ao lado
da recepo.

shutterstock

shutterstock

2. Uma agncia bancria est querendo inovar o atendimento criando mais conforto para seus clientes. Para isso, foram colocadas diversas cadeiras na recepo
do banco. Quando um cliente chega, o atendente lana no computador o seu
nome e o horrio que chegou. Assim que um caixa fica livre, a recepcionista olha
no sistema e chama o primeiro cliente da fila. Dessa forma possvel que os
clientes esperem confortavelmente sentados pelo seu atendimento, no importando o local onde se encontrem dentro da agncia bancria.
a) Faa uma estrutura para o controle da fila. Voc precisa guardar o nome e
a hora que o cliente chegou. Use um vetor para armazenar os dados e dois
nmeros inteiros, um para controlar o incio e outro o final da fila.
b) Defina a varivel que ser um vetor do tipo fila de clientes.
c) Crie uma funo enfileirar, lembrando que preciso verificar se h espao
na fila (o nmero de cadeiras na recepo limitado).
d) Elabore a funo desenfileirar cliente, no se esquea de que necessrio
verificar se ainda existem clientes para serem atendidos.
e) Faa uma funo que apresente na tela a lista de todos os clientes que esto aguardando atendimento na recepo.

MATERIAL COMPLEMENTAR

Estruturas de Dados
Fabiana Lorenzi, Patrcia Noll de Mattos e Tanisi Pereira de Carvalho
Editora: Thomson Learning
Sinopse: Na cincia da computao so estudados vrios tipos de
estruturas de dados, sua aplicao e manipulao. A escolha da
estrutura de dados adequada para representar uma realidade deve
considerar aspectos como alocao da memria, formas de consulta,
acesso e operaes de insero e excluso. O objetivo desta obra
apresentar as principais estruturas de dados conhecidas de uma
forma prtica e fcil de compreender. So apresentadas as diversas
aplicaes dessas estruturas por meio de exemplos de programas em C e em Pascal.

Material Complementar

PONTEIROS

UNIDADE

Professor Me. Rogrio de Leon Pereira

III

Objetivos de Aprendizagem
Aprender o conceito de ponteiros.
Entender como capturar o endereo de uma varivel na memria e
armazen-la num ponteiro.
Estudar a relao entre os ponteiros e as demais variveis.
Verificar as propriedades e aplicaes de ponteiros.
Alocar variveis dinamicamente em tempo de execuo.

Plano de Estudo
A seguir, apresentam-se os tpicos que voc estudar nesta unidade:
Ponteiros
Propriedades de ponteiros
Alocao dinmica na memria
Criando vetores dinmicos

68 - 69

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

shutterstock

INTRODUO
Existe uma lenda que atormenta o sono dos programadores, e o nome dela
Ponteiro. Nesta unidade, voc ver de forma simples e com muitos exemplos
prticos que no h necessidade de perder o seu sono por causa dos mal falados ponteiros.
Essa estrutura uma das mais importantes, porque graas a ela possvel
fazer alocao dinmica na memria, navegar nela para frente e para trs a partir de uma varivel ou de qualquer endereo.
Um ponteiro permite ainda que voc monitore endereos na memria, atribua e recupere valores de variveis sem ao menos toc-las. Entendendo essa
unidade, voc passar a se sentir mais confiante e ampliar definitivamente os
seus horizontes como programador.

PONTEIROS
Uma varivel um objeto que representa um espao reservado na memria.
Quando escolhemos o tipo da varivel, estamos definindo o tamanho de bytes
que ela ter e as regras de como seus bits sero lidos, conforme foi discutindo
no incio deste livro.
Um inteiro tem 4 bytes (32 bits), assim como um nmero real, s que no
nmero inteiro positivo, todos os bits so significativos, na varivel de ponto
Introduo

III

#include <stdio.h>
#include <stdlib.h>
int xi;
int *ptr_xi;
float xf;
float *ptr_xf;
char xc;
char *ptr_xc;
main() {
system(Pause);
return(0);
}

A varivel xi do tipo inteiro, j ptr_xi um ponteiro que aponta para uma


varivel do tipo inteiro. A mesma relao existe para xf e ptr_xf, s que no caso
deles para armazenar um valor de ponto flutuante e um ponteiro para uma
varivel do tipo ponto flutuante. Por ltimo, xc uma varivel do tipo caractere

PONTEIROS

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

flutuante s os primeiros 24 representam valor, os


ltimos 8 determinam a posio da casa decimal no nmero.
Por isso, quando encontramos uma varivel de 4 bytes alocada na memria, precisamos
saber qual o seu tipo para fazer a sua correta
leitura.
Ao invs de obter o valor armazenado em
shutterstock
uma varivel, podemos opcionalmente obter o seu endereo
na memria. Por exemplo, criamos uma varivel x do tipo inteiro, para saber
qual o seu endereo, usamos a notao &x. Isso significa que &x um ponteiro
que aponta para o endereo da varivel x na memria.
Tambm possvel usar um ponteiro como tipo de dado na declarao de
uma varivel, s que nesse caso ele no ir guardar um valor, mas sim uma posio na memria. Vejamos agora exemplos de criao de variveis e ponteiros:

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

70 - 71

e ptr_xc um ponteiro para um caractere.


Segundo Tenenbaum (1995): [...] um ponteiro como
qualquer outro tipo de dado em C. O valor de
um ponteiro uma posio na memria da
mesma forma que o valor de um inteiro um
nmero. Os valores dos ponteiros podem ser
Fonte: ilustrao de Clarissa Brasil
atribudos como quaisquer outros valores (p. 29).
A imagem, a seguir, simula um espao na memria. Na parte de cima esto
os endereos e na de baixo os valores contidos naquelas posies. Essa ilustrao
ajuda a entender melhor o conceito de ponteiro e a sua relao com uma varivel.
Como ptr_xi um ponteiro, no posso simplesmente atribuir a ele o valor
de xi, preciso sim atribuir o endereo que xi ocupa na memria. Para isso, usamos a anotao &xi, que significa o ponteiro que aponta para o endereo na
memria da varivel xi.
ptr_xi = &xi;

Eu sei que ptr_xi contm o endereo de uma varivel, mas como saber o
valor daquele objeto? Para isso, usada a notao *ptr_xi, que significa: o valor
da varivel para qual aponta o ponteiro ptr_xi.
xi = *ptr_xi;

Alterei a imagem anterior e inclui as duas


novas notaes (&xi e *ptr_xi) para demonstrar melhor as suas relaes.
Existem ainda outros conceitos interessantes sobre ponteiros, porm necessrio
primeiramente fixar o que foi visto at aqui
antes de seguirmos com o contedo. Vamos
Fonte: ilustrao de Clarissa Brasil
partir para a prtica.
Primeiramente, vamos criar duas variveis, a primeira ser xi do tipo inteiro,
e a segunda ser ptr_xi do tipo ponteiro de inteiro.
int xi;
int *ptr_xi;

Ponteiros

III

Agora vamos fazer uma funo chamada imprimir(), que vai desenhar na tela o
valor de xi, &xi, ptr_xi e *ptr_xi.
void imprimir() {
printf(Valor de
printf(Valor de
printf(Valor de
printf(Valor de
}

xi = %d \n, xi);
&xi = %p \n, &xi);
ptr_xi = %p \n, ptr_xi);
*ptr_xi = %d \n\n, *ptr_xi);

main() {
xi = 10;
ptr_xi = &xi;
imprimir();

system(Pause);
return(0);

A primeira coisa que a funo imprimir() faz mostrar o valor de xi, que
sabemos ser 10. Depois imprime o endereo da memria de xi que obtido pela
notao &xi. A prxima sada o valor de ptr_xi, que agora aponta para o endereo da varivel xi e, por ltimo, o valor de *ptr_xi, que o contedo para onde
ptr_xi est apontando.
Valor
Valor
Valor
Valor

de
de
de
de

PONTEIROS

xi = 10
&xi = 00405020
ptr_xi = 00405020
*ptr_xi = 10

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

Lembrando que xi uma varivel do tipo inteira e &xi o ponteiro que


aponta para o endereo onde xi est armazenada na memria. A varivel ptr_xi
um ponteiro para um inteiro e *ptr_xi o valor para o qual o ponteiro ptr_xi
est apontando.
Dentro da funo main(), vamos atribuir o valor 10 para xi e o valor de &xi
para ptr_xi. Em seguida, vamos chamar a funo imprimir() e observar o resultado.

72 - 73

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

Note que o valor de ptr_xi o mesmo que &xi, j que quando usamos a notao &xi conseguimos o endereo da memria da varivel xi e o ponteiro ptr_xi
est apontando exatamente para ele. Quando usamos a notao *ptr_xi, conseguimos acessar o endereo de xi e resgatar o seu valor armazenado.
Vamos fazer algo diferente agora. Aps as atribuies iniciais, antes de chamar a funo imprimir(), vamos alterar o valor da varivel xi para 20.
main() {
xi = 10;
ptr_xi = &xi;
xi = 20;
imprimir();
system(Pause);
return(0);

O que devemos esperar como sada? D para dizer sem titubear que o valor
de xi ser 20 e no 10, mas e o resto das variveis e notaes, o que elas iro nos
revelar?
Valor
Valor
Valor
Valor

de
de
de
de

xi = 20
&xi = 00405020
ptr_xi = 00405020
*ptr_xi = 20

Tanto ptr_xi quanto &xi mantm o mesmo valor, j que no houve alterao
da posio na memria que ocupa a varivel xi. Porm, apesar de termos alterado apenas o valor de xi, o valor de *ptr_xi tambm aparece diferente. Como
isso possvel? Como o ponteiro ptr_xi aponta para a varivel xi, qualquer alterao feita em seu contedo ir refletir automaticamente quando verificamos o
valor de *ptr_xi.
Vamos fazer mais uma alterao agora, aproveitando tudo o que j foi feito.
S que ao invs de alterar o valor de xi, vamos tentar alterar o valor de *ptr_xi
para 30.

Ponteiros

III

main() {
xi = 10;
ptr_xi = &xi;
xi = 20;
*ptr_xi = 30;
imprimir();
system(Pause);
return(0);

Valor
Valor
Valor
Valor

de
de
de
de

xi = 30
&xi = 00405020
ptr_xi = 00405020
*ptr_xi = 30

Por que o valor de xi foi alterado quando modificamos o valor de *ptr_xi?


Essa fcil de responder. O ponteiro ptr_xi aponta para o local onde xi est
armazenado, ou seja, o endereo &xi. Quando atribumos 30 para *ptr_xi no
alteramos o valor do ponteiro ptr_xi, mas sim o valor da varivel que o ponteiro
estava apontando, que xi.
Acabamos de colocar em prtica diversos conceitos interessantes. Foi possvel entender como atribuir a um ponteiro o endereo de uma varivel. Vimos
tambm que quando alteramos o valor de uma varivel, esse novo valor reflete
no contedo para o qual o ponteiro est apontando. E, por fim, vimos que possvel alterar o valor de uma varivel sem fazer uma atribuio direta a ela, apenas
manipulando um ponteiro que aponta para o seu endereo.
Segue abaixo o cdigo-fonte completo para o exemplo que acabamos de
criar. Experimente digit-lo no seu compilador e execut-lo. Compare as sadas
que voc obteve com as demonstradas aqui nesta parte do livro. Faa algumas
alteraes nas atribuies e nos valores e observe o resultado.

PONTEIROS

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

J sabemos que o valor de xi no ser 10, j que atualizamos ele para 20


antes da impresso, no ? Fizemos apenas uma alterao no valor de *ptr_xi e
sabemos que o ponteiro ptr_xi aponta para o contedo de xi e no o contrrio.
Repare no que aconteceu agora:

74 - 75

#include <stdio.h>
#include <stdlib.h>

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

int xi;
int *ptr_xi;
void imprimir() {
printf(Valor de
printf(Valor de
printf(Valor de
printf(Valor de
}

xi = %d \n, xi);
&xi = %p \n, &xi);
ptr_xi = %p \n, ptr_xi);
*ptr_xi = %d \n\n, *ptr_xi);

main() {
xi = 10;
ptr_xi = &xi;
imprimir();
xi = 20;
imprimir();
*ptr_xi = 30;
imprimir();
system(Pause);
return(0);

Essa a sada esperada para o algoritmo descrito acima.


Valor
Valor
Valor
Valor

de
de
de
de

xi = 10
&xi = 00405020
ptr_xi = 00405020
*ptr_xi = 10

Valor
Valor
Valor
Valor

de
de
de
de

xi = 20
&xi = 00405020
ptr_xi = 00405020
*ptr_xi = 20

Valor
Valor
Valor
Valor

de
de
de
de

xi = 30
&xi = 00405020
ptr_xi = 00405020
*ptr_xi = 30

Ponteiros

III

PROPRIEDADES DE PONTEIROS

int xi;
int *ptr_xi;

float xf;
float *ptr_xf;
char xc;
char *ptr_xc;

Porm, possvel em C fazer a converso de ponteiros de tipos diferentes.


Por exemplo, possvel converter o valor de ptr_xf para o tipo ponteiro para
um inteiro por meio do comando (int *).
ptr_xi = (int *) ptr_xf;

Pare tudo! Pare o mundo! Agora voc deve estar se perguntando: Mas por
que tudo isso? Esses detalhes so realmente necessrios? No uma questo
de puro preciosismo dos criadores da linguagem, eu vou explicar agora o porqu de tudo isso.
O ponteiro um tipo de dado, e eu posso criar uma varivel com esse tipo,
certo? E possvel aplicar diversos operadores aritmticos em variveis, no
verdade? Se ptr_xi contm o endereo de um valor inteiro na memria, ptr_xi
+1 ir apontar para o endereo do nmero inteiro imediatamente posterior a
*ptr_xi, e ptr_xi -1 ir apontar para o primeiro endereo de um nmero inteiro

PONTEIROS

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

importante ressaltar que quando criamos um ponteiro, no estamos apenas


criando uma varivel que aponta para um endereo, estamos criando uma varivel que aponta para um endereo de um determinado tipo.
Como vimos no incio do livro, cada tipo de dado possui as suas regras e
organizao lgica. Se olharmos o contedo de um bloco de 4 bytes, o mesmo
contedo pode ser interpretado de formas diferentes caso seja um inteiro ou
um ponto flutuante.
Dessa forma, quando criamos ptr_xi, criamos um ponteiro que aponta para
uma varivel do tipo inteiro, assim como ptr_xf aponta para uma varivel de tipo
flutuante e ptr_xc aponta para um caractere.

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

76 - 77

imediatamente anterior a *ptr_xi. Dessa


forma, a partir de um ponteiro possvel
navegar pela memria investigando os valores de outros endereos sem precisar saber a
qual varivel eles pertencem.
Suponha que o nosso hardware enderece cada posio na memria byte a byte e o
Fonte: ilustrao de Clarissa Brasil
compilador use 4 bytes para cada varivel do
tipo inteiro. Se ptr_xi est apontando para o valor armazenado na posio 100
da memria, quando procurarmos ptr_xi +1, estaremos acessando o endereo
104, j que a varivel atual comea na posio 100, mas um valor inteiro ocupa
4 bytes, ou seja, da posio 100 a posio 103. Analogamente, quando fizermos
ptr_xi -1, estaremos acessando a posio 96.
Como definimos que o ponteiro aponta para um tipo inteiro, ento ele sabe
que cada varivel possui 4 bytes. Dessa forma, quando usamos a notao *(ptr_
xi +1), estaremos acessando o valor inteiro formado pelos bytes 104, 105, 106 e
107, e para *(ptr_xi -1) o inteiro formado pelos bytes 96, 97, 98 e 99.

ALOCAO DINMICA NA MEMRIA


At o presente momento, fizemos apenas alocao esttica de objetos. Definimos
variveis dentro do corpo do cdigo-fonte e quando o programa executado,
todas as variveis so criadas e inicializadas na memria.
Existe, porm, uma forma de alocar variveis dinamicamente, criando mais
e mais espaos de acordo com a necessidade do programador sem haver a necessidade de prev-las durante o desenvolvimento do programa. Observe esse
pequeno trecho de cdigo:
int *ptr;
printf (Endereco: %p\n\n, ptr);

Alocao Dinmica na Memria

III

Definimos uma varivel do tipo ponteiro de inteiro chamado ptr. Como toda
varivel, ela inicializada pelo compilador durante a carga do programa. Uma
varivel numrica (inteiros, pontos flutuantes) tem o seu valor inicializado com
0, j um ponteiro inicializado com um endereo invlido na memria, ou seja,
ele no aponta para local algum. No possvel obter o valor de *ptr, pois se tentarmos ver o seu contedo, o programa encerrar com um erro. Mas podemos
observar para onde ele aponta nesse exato momento.
Endereco: 00000008

Por enquanto, no temos nenhum interesse em criar uma nova varivel, mas
ento, onde iremos usar o ponteiro ptr? Todo ponteiro aponta para um endereo na memria e nos exemplos anteriores usamos os ponteiros para guardar
o endereo de outras variveis. Vamos adicionar agora uma linha no nosso programa para fazer a alocao dinmica de um espao na memria.
int *ptr;
printf (Endereco: %p\n\n, ptr);
ptr = (int *) malloc(sizeof (int));
printf (Endereco: %p \nValor: %d\n\n, ptr, *ptr);

A funo malloc reserva um espao na memria do tamanho sizeof. No caso


de um inteiro, sabemos que C considera-o com 4 bytes. Como ptr um ponteiro do tipo inteiro, precisamos nos certificar de que o retorno de malloc seja
um valor compatvel, por isso o uso de (int *). O retorno dessa execuo pode
ser visto abaixo:

PONTEIROS

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

shutterstock

78 - 79

Endereco: 00000008

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

Endereco: 00380CA0
Valor: 3673280

Note que aps a alocao na memria pela funo malloc, o ponteiro ptr j
passa a apontar para um endereo vlido disponibilizado pelo compilador. Porm,
quando um espao na memria reservado de forma dinmica, seu valor no
inicializado tal qual na declarao de uma varivel esttica. Observe que o valor
de *ptr 3673280, mas de onde surgiu esse valor?
O compilador buscou na memria um bloco de 4 bytes disponvel e passou
esse endereo para ptr, porm, aqueles bytes j possuam valores. A memria do
computador s zerada quando o mesmo desligado e sua fonte de alimentao de energia interrompida, ou ainda por algum comando especfico do sistema
operacional. As variveis so criadas e destrudas na memria, mas os valores
dos bits continuam inalterados.
Por isso sempre importante inicializar o valor de uma varivel criada de
forma dinmica. Acompanhe o novo trecho do programa:
int *ptr;
printf (Endereco: %p\n\n, ptr);
ptr = (int *) malloc(sizeof (int));
printf (Endereco: %p \nValor: %d\n\n, ptr, *ptr);
*ptr = 10;
printf (Endereco: %p \nValor: %d\n\n, ptr, *ptr);

Agora que ptr est apontando para um endereo vlido na memria, podemos sem problema algum ir at l e armazenar um valor em *ptr. Note que aps
a atribuio de *ptr = 10 o endereo do ponteiro continua inalterado.
Endereco: 00000008
Endereco: 00380CA0
Valor: 3673280
Endereco: 00380CA0
Valor: 10

Alocao Dinmica na Memria

III

Um ponteiro aponta para um endereo na memria, seja ele de uma varivel pr-definida ou alocada dinamicamente. Tome cuidado para no passar um endereo diretamente para um ponteiro, deixe esse trabalho para o
compilador. Voc pode acabar acessando uma poro da memria ocupada
por outro programa ou pelo prprio sistema operacional.

int x;
x = 20;
ptr = &x;
printf (Endereco: %p \nValor: %d\n\n, ptr, *ptr);

O que podemos esperar na sada de printf? Acertou se disse que ptr agora
aponta para um novo endereo na memria, o endereo da varivel x. Como ptr
aponta para &x, o valor de *ptr passa a retornar o valor de x, que 20.
Endereco: 0028FF08
Valor: 20

E o que aconteceu com o endereo original de ptr? Ele se perdeu, j que


ele no era de nenhuma varivel, mas alocado dinamicamente para o ponteiro.
Vamos ento fazer um novo malloc para ptr e ver qual o resultado.
int x;
x = 20;
ptr = &x;
printf (Endereco: %p \nValor: %d\n\n, ptr, *ptr);
ptr = (int *) malloc(sizeof (int));
printf (Endereco: %p \nValor: %d\n\n, ptr, *ptr);

Veremos que ptr agora aponta para um novo endereo na memria, endereo esse diferente do primeiro obtido pela funo malloc e diferente do endereo
da varivel inteira x.

PONTEIROS

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

Ns j declaramos ptr e alocamos um espao na memria para ele. Vamos criar


agora uma varivel x do tipo inteira, inicializ-la com valor 20 e atribuir o endereo &x para ptr.

80 - 81

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

Endereco: 0028FF08
Valor: 20
Endereco: 00380CC0
Valor: 3683664

Novamente *ptr traz o lixo de bits existente no endereo que acabou de


ser alocado a ele pela funo malloc. Essa funo traz o endereo de um espao
disponvel na memria, mas no faz nenhum tratamento com a atual string de
bits naquela posio. Abaixo, voc encontra o cdigo-fonte completo do exemplo que acabamos de estudar. Leia com ateno e tente entender cada uma das
linhas do programa.
#include <stdio.h>
#include <stdlib.h>
main() {
int *ptr;
printf (Endereco: %p\n\n, ptr);
ptr = (int *) malloc(sizeof (int));
printf (Endereco: %p \nValor: %d\n\n, ptr, *ptr);
*ptr = 10;
printf (Endereco: %p \nValor: %d\n\n, ptr, *ptr);
int x;
x = 20;
ptr = &x;
printf (Endereco: %p \nValor: %d\n\n, ptr, *ptr);
ptr = (int *) malloc(sizeof (int));
printf (Endereco: %p \nValor: %d\n\n, ptr, *ptr);
system(Pause);
return(0);

Os endereos que aparecem ao executarmos o exemplo variam cada vez


que o programa inicializado, isso porque o compilador sempre procura novas
posies livres na memria no momento de criao de variveis estticas e dinmicas. Execute o cdigo algumas vezes e observe como os endereos variam.

Alocao Dinmica na Memria

III

Endereco: 00000008
Endereco: 00380CA0
Valor: 3673280
Endereco: 00380CA0
Valor: 10
Endereco: 0028FF08
Valor: 20

CRIANDO VETORES DINMICOS


Quando criamos um vetor, dizemos na sua declarao qual ser o seu tamanho.
Independente se vamos us-lo inteiro ou um pedao, todo o espao na memria
reservado assim que o programa inicializado. Isso ruim por dois motivos:
1) Podemos estar reservando mais espao do que realmente precisamos;
2) Ficamos limitados quela quantidade de posies previamente definidas no vetor.
Uma forma de resolver esses problemas criar vetores dinmicos, com seu tamanho definido em tempo de execuo do programa. Vamos criar um pequeno
exemplo para ilustrar isso.
Na funo main(), vamos criar uma varivel tam do tipo inteiro para ler
o tamanho do vetor e uma varivel do tipo ponteiro de inteiro chamada vetor,
que ser criada de forma dinmica de acordo com o valor lido na varivel tam.
int tam;
int *vetor;
printf (Escolha o tamanho do vetor: );
scanf(%d, &tam);
vetor = (int *) malloc(sizeof (int)*tam);

PONTEIROS

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

Endereco: 00380CC0
Valor: 3683664

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

82 - 83

shutterstock

O processo de alocao de um vetor usando malloc muito parecido com o


de uma varivel simples. Basta multiplicar o tipo definido em sizeof pela quantidade de posies que deseja para o vetor.
Para comprovar o funcionamento desse exemplo, vamos fazer um lao de
repetio e vamos colocar em cada posio do novo vetor uma potncia de base
2 elevada a sua posio definida pelo ndice i.
for (int i = 0; i < tam; i++) {
vetor[i] = pow(2,i);
printf (Posicao %d: %d\n, i, vetor[i]);
}

Esse programinha ser muito til quando for resolver exerccios onde precisa
saber o valor de vrias potncias de 2, como no caso da converso de nmeros
binrios em decimais. A execuo do exemplo com tam = 5 ser essa:
Escolha
Posicao
Posicao
Posicao
Posicao
Posicao

o tamanho do vetor: 5
0: 1
1: 2
2: 4
3: 8
4: 16

Analise o cdigo completo do exemplo, copie no compilador C de sua preferncia e execute o programa lendo diferentes valores para o tamanho tam.

Criando Vetores Dinmicos

III

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

CONSIDERAES FINAIS
At o presente momento voc programou de forma esttica. Ficou limitado(a) a
criar variveis somente durante a codificao do sistema. Encontrava situaes
onde a varivel ocupava mais espao na memria do que realmente precisaria,
ou o contrrio, com espao insuficiente para tanta informao.
Isso tudo mudou com o contedo visto nesta unidade. O ponteiro uma
estrutura de dados muito poderosa e permite, alm de outras coisas, fazer alocaes dinmicas na memria. Agora possvel, por exemplo, criar filas e pilhas
de tamanhos personalizados e ajustados as suas necessidades pontuais.
E no s isso. Na Unidade IV experimentaremos um pouco mais do poder
dos ponteiros na criao de listas encadeadas e duplamente encadeadas onde o
limite ser o tamanho da memria do computador.

PONTEIROS

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

main() {
int tam;
int *vetor;
printf (Escolha o tamanho do vetor: );
scanf(%d, &tam);
vetor = (int *) malloc(sizeof (int)*tam);
for (int i = 0; i < tam; i++) {
vetor[i] = pow(2,i);
printf (Posicao %d: %d\n, i, vetor[i]);
}
system(Pause);
return(0);
}

84 - 85

1. Faa um pequeno programa para testar seus conhecimentos sobre ponteiros e


alocao dinmica na memria.
a) Defina um ponteiro do tipo inteiro;
b) Faa alocao dinmica para o ponteiro recm-criado;
c) Preencha a memria com o valor 42;
d) Imprima o endereo do ponteiro na memria e o valor contido nele.
2. Uma famosa fbrica de semforos est testando um novo prottipo, menor,
mais barato e eficiente. Foi solicitado equipe de TI um programa em linguagem
C para fazer o teste do novo hardware. O semforo tem trs objetos, cada um
contm um atributo cor e outro id. Devido s limitaes de memria e processamento, necessria a criao de um ponteiro que vai percorrendo a memria e
imprimindo o valor na tela.
a) Crie uma estrutura que tenha dois atributos: cor (cadeia de caracteres) e id
(inteiro);
b) Crie trs variveis com o tipo definido no item a;
c) Crie um ponteiro do mesmo tipo;
d) Inicialize as estruturas da seguinte forma:
Cor vermelha, id 1;
Cor amarela, id 2;
Cor verde, id 3.
e) Inicialize o ponteiro apontando para a primeira varivel criada;
f ) Por meio de operaes aritmticas com ponteiros, percorra a memria e imprima o valor de cada uma das variveis criadas nesse programa.
3. Qual a diferena entre uma varivel do tipo inteira de um ponteiro do tipo inteiro?

4. Por que devemos preencher um ponteiro apenas com o endereo de uma varivel ou por alocao dinmica usando funes como malloc?
5. Crie um programa que leia uma varivel e crie dois vetores dinmicos, um com
o tamanho lido e outro com o dobro desse tamanho. Preencha esses vetores,
respectivamente, com potncias de 2 e potncias de 3.
a) Crie uma varivel inteira e dois ponteiros do tipo inteiro.
b) Pergunte ao usurio o tamanho do vetor dinmico e leia esse valor na varivel inteira.
c) Aloque dinamicamente os dois vetores usando a funo malloc.
d) Faa um lao de repetio para preencher o primeiro vetor com potncias
de 2.
e) Faa um segundo lao de repetio para preencher o outro vetor com potncias de 3.
f ) No se esquea de usar a biblioteca math.h para poder usar o clculo de potncia (pow).

86 - 87

MATERIAL COMPLEMENTAR

Projeto de Algoritmos
Nivio Ziviani
Editora: CENGAGE Learning
Sinopse: Esta obra apresenta os principais algoritmos conhecidos.
Algoritmos e estruturas de dados formam o ncleo da cincia
da computao, sendo os componentes bsicos de qualquer
software. Aprender algoritmos crucial para qualquer pessoa que
deseja desenvolver um software de qualidade.
As tcnicas de projeto de algoritmos so ensinadas por meio de
refinamentos sucessivos at o nvel de um programa em Pascal.
Todo programa Pascal tem um programa C correspondente no
apndice.
Mais de 163 exerccios propostos, dos quais 80 com solues; 221 programas em Pascal e 221
programas em C; 164 figuras ilustrativas.

Material Complementar

LISTAS DINMICAS

UNIDADE

Professor Me. Rogrio de Leon Pereira

IV

Objetivos de Aprendizagem
Aprender o conceito de listas.
Usar a alocao dinmica de memria na construo de listas.
Entender como se d a navegao em listas.

Plano de Estudo
A seguir, apresentam-se os tpicos que voc estudar nesta unidade:
Fundamentos de listas dinmicas
Implementando uma lista dinmica
Lista dinmica em forma de pilha
Lista dinmica em forma de fila

90 - 91

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

shutterstock

INTRODUO
At agora, usamos os vetores como base para a implementao de estruturas mais
complexas como pilhas e listas. Apesar da facilidade e praticidade dos vetores,
esse tipo de dado possui diversas limitaes.
Veremos agora uma nova estrutura chamada Lista. Apesar de ser parecida
com o que vimos at ento, o seu conceito no inclui regras de entrada e sada
como as que existem em estruturas como a FIFO e a LIFO. Porm, as listas possuem caractersticas prprias que lhe do grande versatilidade.
Apesar de ser possvel criar uma lista de forma esttica, focaremos nesta unidade a criao e aplicao das listas dinmicas.

FUNDAMENTOS DE LISTAS DINMICAS


A maneira mais simples de guardar um conjunto de informao na memria se
d pelo uso de vetores. Devido as suas caractersticas, o vetor mantm os dados
armazenados numa estrutura sequencial. Imaginemos uma varivel do tipo vetor
de inteiros chamada vec. Para acessarmos a quinta posio desse vetor, precisamos apenas usar o ndice correto na leitura do vetor vec[4], lembrando que
em C um vetor comea na posio 0 e vai at n-1, onde n a quantidade de elementos no vetor.
Introduo

IV

Vetor vec
Valores

15

22

50

13

42

77

ndices

Inico
Dado

Prximo

LISTAS DINMICAS

Dado

Dado

Prximo

Prximo

NULL

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

Na criao de uma pilha, o vetor se mostra muito eficaz, j que a entrada e a


sada so feitas sempre no seu ltimo elemento. Para a fila o vetor j mostra algumas dificuldades de implementao, j que o elemento que sai sempre o mais
antigo e uma das formas de manter os dados de forma sequencial mover todo
o resto dos dados para as posies precedentes.
No um problema quando se trabalha com poucos dados, mas imagine
uma fila com 100, 500, 1000 ou mais posies. D para mover o incio da fila
alterando o valor de uma varivel auxiliar criada para indicar qual a posio de
incio da fila no vetor, mas a o incio da fila no seria no incio do vetor, perdendo assim a forma sequencial da estrutura.
preciso ento alterar a forma de organizao dos dados para garantir que
a ordenao seja independente do ndice da varivel. Suponhamos que os itens
de uma pilha ou fila contivessem alm do seu valor o endereo do prximo elemento. Dessa forma, a partir do primeiro elemento da estrutura, seria possvel
percorr-la toda na ordem correta, mesmo que fisicamente os dados no se encontrem ordenados na memria do computador. Segundo Tenenbaum (1995, p.
224), tal ordenao explcita faz surgir uma estrutura de dados que conhecida
como lista ligada linear. Na literatura, tambm pode-se encontrar referncias a
tal estrutura como lista encadeada.

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

92 - 93

Cada item na lista chamado de n e contm pelo menos dois elementos: um


de dados e um de endereo. O campo de dados contm o real elemento da lista,
j o campo de endereo um ponteiro para o prximo n. preciso tambm
uma varivel extra que contenha o endereo do primeiro elemento da lista. Para
finalizar uma lista, o atributo endereo do ltimo n contm um valor especial
conhecido como null (nulo).
Existem tambm outros tipos de listas. Uma delas, que muito conhecida,
a lista duplamente encadeada. Cada n possui pelo menos trs campos: um de
dados e dois de endereo. Um dos endereos usado para apontar ao n anterior
e o segundo aponta para o prximo n. Dessa forma, possvel percorrer a lista
em ambas as direes, algo muito verstil e que no possvel na lista simples.
O endereo anterior do primeiro n tambm contm um valor null indicando
o incio da lista.

No caso do vetor, todo o espao reservado na memria pelo compilador, independendo se estamos usando uma, nenhuma ou todas as suas posies. J com
uma lista dinmica isso no ocorre, pois vamos adicionando ns sempre que
for necessrio.
A insero de um novo elemento em uma lista muito simples. Basta encontrar a posio desejada, fazer com que o n atual aponte para o n que ser
inserido e o novo n aponte para o local onde apontava o n imediatamente
anterior. A imagem a seguir ilustra bem esse conceito.
Inico

NULL

Novo n
Fundamentos de Listas Dinmicas

IV

O processo de remoo tambm simples, basta que o n anterior ao que for


removido passe a apontar para o elemento que o n removido apontava.
Inico

NULL

IMPLEMENTANDO UMA LISTA DINMICA


Romperemos agora a barreira da conceituao terica e vamos nos aventurar no
maravilhoso mundo da coisa prtica. No h forma melhor de aprender a programar do que programando.
A primeira coisa que iremos precisar para criar uma lista dinmica a estrutura do n. Ela vai ter dois elementos, um inteiro que guardar a informao
propriamente dita e um ponteiro que ir apontar para o prximo n.
struct no {
int dado;
struct no *proximo;
};

Com a estrutura j definida, precisamos criar agora um ponteiro do tipo n.


Ele ser necessrio para fazer a alocao dinmica na memria para cada novo
elemento da lista.
typedef no *ptr_no;

Por ltimo, criaremos uma varivel que ir apontar para o incio da lista.
A partir dela poderemos navegar do primeiro ao ltimo elemento, fazer remoes e inseres.
ptr_no lista;

A varivel do tipo ponteiro lista foi criada para apontar para a nossa lista
encadeada. Como ela ainda no existe, vamos criar o primeiro n com o atributo dado valendo 0 e o ponteiro proximo apontando para null.

LISTAS DINMICAS

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

n removido

94 - 95

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

lista = (ptr_no) malloc(sizeof(no));


lista->dado = 0;
lista->proximo = NULL;

Conforme j visto neste livro, a funo malloc precisa como parmetro sizeof
o tipo de dado que ser alocado (estrutura no), com isso o compilador saber a
quantidade exata de memria que precisar reservar. O retorno da funo precisa ser do tipo esperado pela varivel lista, que no caso do tipo ptr_no.
Com a lista definida e devidamente inicializada, podemos criar agora a funo lista_mostrar(), que iremos utilizar para desenhar na tela o contedo da nossa
lista dinmica. Ela recebe como parmetro uma varivel do tipo ptr_no, que ser
aquela que criamos l no comeo para apontar para o incio da lista.
void lista_mostrar(ptr_no lista){
system(cls);
while(1) {
printf(%d, , lista->dado);
if (lista->proximo == NULL){
break;
}
lista = lista->proximo;
}
}

Nesse exemplo criamos um lao infinito (loop infinito) que ir funcionar at


que o atributo proximo do n atual seja nulo. Essa abordagem perigosa porque
se houver um erro na implementao e o valor do ltimo elemento no apontar
para um endereo nulo, ficaremos presos nesse lao de forma indeterminada.
Vamos redesenhar a funo lista_mostrar() fazendo com que a verificao da nulidade do atributo proximo esteja definida como condicional do lao.
void lista_mostrar_2(ptr_no lista){
system(cls);
while(lista->proximo != NULL) {
printf(%d, , lista->dado);
lista = lista->proximo;
}
printf(%d, , lista->dado);
}

Implementando uma Lista Dinmica

IV

A repetio ir parar quando chegar ao ltimo elemento, mas sair do lao antes
de imprimir o valor de dado do ltimo n na tela. Para isso, se faz necessrio um
comando printf adicional no final da funo.
Para a insero dinmica de um novo n na lista, vamos criar uma funo chamada lista_inserir(). Sabemos onde a nossa lista dinmica comea, pois
temos uma varivel do tipo ponteiro chamada lista que foi criada especialmente
para isso. A partir dela, vamos percorrer toda a estrutura at achar o valor null
no elemento proximo do ltimo n.

Criamos um novo n e fazemos o ltimo n da lista apontar para ele.

NULL

Agora fazemos o novo n que recm adicionamos na lista apontar para null.

NULL

Resumindo: a funo possui um lao de repetio usado para percorrer a lista


at o ltimo n. Alocamos memria no ponteiro que apontava para nulo, o que
significa criar um novo elemento. Fazemos ento com que ele aponte para null
passando agora a ser ento o novo final da lista.
void lista_inserir(ptr_no lista){
while(lista->proximo != NULL){
lista = lista->proximo;
}
lista->proximo = (ptr_no) malloc(sizeof(no));
lista = lista->proximo;
lista->dado = rand()%100;
lista->proximo = NULL;
}

LISTAS DINMICAS

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

NULL

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

96 - 97

Para diferenciar os ns, toda vez que um novo elemento adicionado lista
atribumos um valor aleatrio ao seu atributo dados. Isso possvel utilizando a
funo rand() contida na biblioteca <time.h>.
A remoo de um elemento no final da lista to simples como a insero
que acabamos de codificar. Para complicar, ento, vamos permitir que seja excludo um elemento em qualquer posio. Vamos criar uma nova funo chamada
lista_remover(), que ir receber como parmetro a varivel que aponta para o
comeo da lista.
Novamente precisaremos de um lao que percorra a lista a partir do primeiro
elemento at a posio que queremos remover. Se a estrutura do n possusse
dois ponteiros, um para o elemento anterior e um para o prximo, poderamos
ir e voltar livremente pela lista. Como no o nosso caso, precisamos guardar a
posio atual antes de mover a lista para o prximo n.
ptr_no atual;
atual = (ptr_no) malloc(sizeof(no));
while((lista->dado != dado) ){
atual = lista;
lista = lista->proximo;
}

Conforme a lgica que acabamos de expor, a varivel lista conter o elemento


que desejamos remover e o n imediatamente anterior estar na varivel atual.
Para concretizar a remoo, fazemos com que o n atual aponte para onde o n
lista estava apontando.
atual

lista

A seguir, temos a implementao final da funo lista_remover(). Ela est um


pouco mais completa, pois pergunta ao usurio qual n ir ser removido e faz
um controle dentro do lao para finalizar a funo caso chegue ao ltimo n
sem encontrar o item a ser removido.
Implementando uma Lista Dinmica

IV

At agora, apresentamos apenas fragmentos de cdigo com o objetivo de


explicar pontos cruciais na implementao de listas dinmicas. A seguir voc
encontrar a verso completa em linguagem C de um programa que define a
estrutura da lista, permite a insero de um n no seu final e a remoo de qualquer um de seus elementos.
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <time.h>
4
5
//Definindo a estrutura da lista
6
struct no {
7
int dado;
8
struct no *proximo;
9
};
10
11
//Definindo variveis
12
typedef no *ptr_no;
13
ptr_no lista;
14
int op;
15
16
//Prototipao
17
void menu_mostrar();
18
void menu_selecionar(int op);
19
void lista_inserir(ptr_no lista);
20
void lista_remover(ptr_no lista);
21
void lista_mostrar(ptr_no lista);
22
23
//Funo Principal
LISTAS
24 DINMICAS
main() {
25
//Inicializando mquina de nmeros randmicos

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

void lista_remover(ptr_no lista){


int dado;
ptr_no atual;
atual = (ptr_no) malloc(sizeof(no));
printf(\n\nEscolha uma dos itens:\n);
scanf(%d, &dado);
while((lista->dado != dado) ){
if (lista->proximo == NULL){
break;
}
atual = lista;
lista = lista->proximo;
}
if (lista->dado == dado){
atual->proximo = lista->proximo;
}
}

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

typedef no *ptr_no;
ptr_no lista;
int op;

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71

//Mostra o menu de opes


void menu_mostrar(){
lista_mostrar(lista);
printf("\n\nEscolha uma das opcoes:\n");
printf("1 - Inserir no final da Lista\n");
printf("2 - Remover um item da Lista\n");
printf("0 - Sair\n\n");
}

//Prototipao
void menu_mostrar();
void menu_selecionar(int op);
void lista_inserir(ptr_no lista);
void lista_remover(ptr_no lista);
void lista_mostrar(ptr_no lista);
//Funo Principal
main() {
//Inicializando mquina de nmeros randmicos
srand(time(NULL));
op = 1;
//Criando o primeiro n da lista
lista = (ptr_no) malloc(sizeof(no));
lista->dado = 0;
lista->proximo = NULL;
//Lao principal
while (op !=0){
system("cls");
menu_mostrar();
scanf("%d", &op);
menu_selecionar(op);
}
system("Pause");
return(0);
}

//Executa a opo escolhida no menu


void menu_selecionar(int op){
switch (op){
case 1:
lista_inserir(lista);
break;
case 2:
lista_remover(lista);
break;
}
}
//Insere um elemento no final da Lista
void lista_inserir(ptr_no lista){
while(lista->proximo != NULL){
lista = lista->proximo;
}
lista->proximo = (ptr_no) malloc(sizeof(no));
lista = lista->proximo;
lista->dado = rand()%100; Implementando uma Lista Dinmica
lista->proximo = NULL;

98 - 99

IV

break;
}
}
//Insere um elemento no final da Lista
void lista_inserir(ptr_no lista){
while(lista->proximo != NULL){
lista = lista->proximo;
}
lista->proximo = (ptr_no) malloc(sizeof(no));
lista = lista->proximo;
lista->dado = rand()%100;
lista->proximo = NULL;
}
//Remove um elemento da Lista
void lista_remover(ptr_no lista){
int dado;
ptr_no atual;
atual = (ptr_no) malloc(sizeof(no));
printf("\n\nEscolha uma dos itens:\n");
scanf("%d", &dado);
while((lista->dado != dado) ){
if (lista->proximo == NULL){
break;
}
atual = lista;
lista = lista->proximo;
}
if (lista->dado == dado){
atual->proximo = lista->proximo;
}
}
//Desenha o contedo da Lista na tela
void lista_mostrar(ptr_no lista){
system("cls");
while(1) {
printf("%d, ", lista->dado);
if (lista->proximo == NULL){
break;
}
lista = lista->proximo;
}
}
//Desenha o contedo da Lista na tela
void lista_mostrar_2(ptr_no lista){
system("cls");
while(lista->proximo != NULL) {
printf("%d, ", lista->dado);
lista = lista->proximo;
}
printf("%d, ", lista->dado);
}

LISTAS DINMICAS

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114

100 - 101

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

LISTA DINMICA COM FORMA DE PILHA


O que difere uma lista de uma pilha? Uma pilha possui regras de entrada e sada,
fora isso, as estruturas so muito parecidas. A lista possui como caracterstica a
ordenao independente da forma de armazenamento.
Ento, o que precisaramos para implementar de forma dinmica uma pilha?
Simples, basta criar uma lista dinmica e adicionar nela as regras LIFO: o ltimo
que entra o primeiro que sai.
Vamos criar uma funo pilha_inserir(). Ela vai percorrer a lista dinmica at
que o ltimo n aponte para uma posio NULL. Inserimos ali um novo n, ou
como diz a definio de pilha, s podemos adicionar valores no final da estrutura.
//Insere um elemento no final da Pilha
void pilha_inserir(ptr_no pilha){
while(pilha->proximo != NULL){
pilha = pilha->proximo;
}
pilha->proximo = (ptr_no) malloc(sizeof(no));
pilha = pilha->proximo;
pilha->dado = rand()%100;
pilha->proximo = NULL;
}

A remoo na pilha se d da mesma maneira, pode-se remover sempre o


ltimo elemento. A funo pilha_remover() vai percorrer toda a lista at encontrar o n que aponta para uma posio NULL. Isso significa que chegou ao seu
final, mas como remov-lo?
Para isso precisamos ir guardando a posio atual antes de mover o ponteiro para a prxima posio. Quando o ponteiro pilha apontar para o ltimo
n da pilha, o ponteiro atual estar apontando para a penltima posio. Basta
fazer com que o ponteiro atual aponte para NULL e o ltimo elemento acaba de
ser removido da estrutura.

Lista Dinmica com Forma de Pilha

IV

//Remove um elemento da pilha


void pilha_remover(ptr_no pilha){
ptr_no atual;
atual = (ptr_no) malloc(sizeof(no));
while(pilha->proximo != NULL){
atual = pilha;
pilha = pilha->proximo;
}
atual->proximo = NULL;
}

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//Definindo a estrutura da pilha
struct no {
int dado;
struct no *proximo;
};
//Definindo variveis
typedef no *ptr_no;
ptr_no pilha;
int op;
//Prototipao
void menu_mostrar();
void menu_selecionar(int op);
void pilha_inserir(ptr_no pilha);
void pilha_remover(ptr_no pilha);
void pilha_mostrar(ptr_no pilha);
//Funo Principal
main() {
//Inicializando mquina de nmeros randmicos
srand(time(NULL));
op = 1;
//Criando o primeiro n da pilha
pilha = (ptr_no) malloc(sizeof(no));
pilha->dado = 0;
pilha->proximo = NULL;
//Lao principal
while (op !=0){
system("cls");
menu_mostrar();
LISTAS DINMICAS
scanf("%d", &op);

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

Abaixo, segue o cdigo de uma lista dinmica com regras de entrada e sada
na forma de pilha.

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

main() {
//Inicializando mquina de nmeros randmicos
srand(time(NULL));
op = 1;
//Criando o primeiro n da pilha
pilha = (ptr_no) malloc(sizeof(no));
pilha->dado = 0;
pilha->proximo = NULL;
//Lao principal
while (op !=0){
system("cls");
menu_mostrar();
scanf("%d", &op);
menu_selecionar(op);
}
system("Pause");
return(0);
}
//Mostra o menu de opes
void menu_mostrar(){
pilha_mostrar(pilha);
printf("\n\nEscolha uma das opcoes:\n");
printf("1 - Inserir no final da pilha\n");
printf("2 - Remover no final da pilha\n");
printf("0 - Sair\n\n");
}
//Executa a opo escolhida no menu
void menu_selecionar(int op){
switch (op){
case 1:
pilha_inserir(pilha);
break;
case 2:
pilha_remover(pilha);
break;
}
}
//Insere um elemento no final da Pilha
void pilha_inserir(ptr_no pilha){
while(pilha->proximo != NULL){
pilha = pilha->proximo;
}
pilha->proximo = (ptr_no) malloc(sizeof(no));
pilha = pilha->proximo;
pilha->dado = rand()%100;
pilha->proximo = NULL;
}
//Remove um elemento da pilha
void pilha_remover(ptr_no pilha){
ptr_no atual;
atual = (ptr_no) malloc(sizeof(no));
while(pilha->proximo != NULL){
atual = pilha;
pilha = pilha->proximo;
}
atual->proximo = NULL;
}
Lista Dinmica com Forma de Pilha

102 - 103

atual = (ptr_no) malloc(sizeof(no));


while(pilha->proximo != NULL){
atual = pilha;
pilha = pilha->proximo;
}
atual->proximo = NULL;

IV

}
//Desenha o contedo da pilha na tela
void pilha_mostrar(ptr_no pilha){
system("cls");
while(pilha->proximo != NULL) {
printf("%d, ", pilha->dado);
pilha = pilha->proximo;
}
printf("%d, ", pilha->dado);
}

LISTA DINMICA COM FORMA DE FILA

//Insere um elemento no final da fila


void fila_inserir(ptr_no fila){
while(fila->proximo != NULL){
fila = fila->proximo;
}
fila->proximo = (ptr_no) malloc(sizeof(no));
fila = fila->proximo;
fila->dado = rand()%100;
fila->proximo = NULL;
}

A remoo sim um pouco diferente. Sabemos que na fila sempre se remove


o elemento mais antigo, ou seja, o primeiro da fila.

LISTAS DINMICAS

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

Podemos tambm implementar em uma lista dinmica as regras da fila FIFO:


primeiro que entra, primeiro que sai.
Para inserir na fila no diferente do que j fizemos at agora, a funo fila_
inserir() deve percorrer a lista at o final, encontrando o n que aponta para uma
posio NULL e ali inserir o novo elemento.

104 - 105

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

Como na lista dinmica temos um ponteiro que aponta para o incio da fila,
basta guardar essa posio e andar na fila apenas uma vez, e fazer com que o incio da fila aponte para o segundo elemento. A funo file_remover() apresentada
abaixo tambm verifica se a fila no est vazia antes da fazer a remoo, o que
pode ocasionar um erro e finalizar de forma repentina o programa em execuo.
//Remove um elemento do incio da fila
void fila_remover(ptr_no fila){
ptr_no atual;
atual = (ptr_no) malloc(sizeof(no));
atual = fila;
if (fila->proximo != NULL){
fila = fila->proximo;
atual->proximo = fila->proximo;
}
}

A seguir temos uma lista dinmica completa em linguagem C, com as regras


de entrada e sada de fila.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//Definindo a estrutura da fila
struct no {
int dado;
struct no *proximo;
};
//Definindo variveis
typedef no *ptr_no;
ptr_no fila;
int op;
//Prototipao
void menu_mostrar();
void menu_selecionar(int op);
void fila_inserir(ptr_no fila);
void fila_remover(ptr_no fila);
void fila_mostrar(ptr_no fila);
//Funo Principal
main() {
//Inicializando mquina de nmeros randmicos
Lista Dinmica com Forma de Fila
srand(time(NULL));
op = 1;

int op;

IV

//Prototipao
void menu_mostrar();
void menu_selecionar(int op);
void fila_inserir(ptr_no fila);
void fila_remover(ptr_no fila);
void fila_mostrar(ptr_no fila);

//Mostra o menu de opes


void menu_mostrar(){
fila_mostrar(fila);
printf("\n\nEscolha uma das opcoes:\n");
printf("1 - Inserir no final da fila\n");
printf("2 - Remover no inicio da fila\n");
printf("0 - Sair\n\n");
}
//Executa a opo escolhida no menu
void menu_selecionar(int op){
switch (op){
case 1:
fila_inserir(fila);
break;
case 2:
fila_remover(fila);
break;
}
}
//Insere um elemento no final da fila
void fila_inserir(ptr_no fila){
while(fila->proximo != NULL){
fila = fila->proximo;
}
fila->proximo = (ptr_no) malloc(sizeof(no));
fila = fila->proximo;
fila->dado = rand()%100;
= NULL;
LISTAS fila->proximo
DINMICAS
}

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

//Funo Principal
main() {
//Inicializando mquina de nmeros randmicos
srand(time(NULL));
op = 1;
//Criando o primeiro n da fila
fila = (ptr_no) malloc(sizeof(no));
fila->dado = 0;
fila->proximo = NULL;
//Lao principal
while (op !=0){
system("cls");
menu_mostrar();
scanf("%d", &op);
menu_selecionar(op);
}
system("Pause");
return(0);
}

break;
}
}

106 - 107

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

//Insere um elemento no final da fila


void fila_inserir(ptr_no fila){
while(fila->proximo != NULL){
fila = fila->proximo;
}
fila->proximo = (ptr_no) malloc(sizeof(no));
fila = fila->proximo;
fila->dado = rand()%100;
fila->proximo = NULL;
}
//Remove um elemento do incio da fila
void fila_remover(ptr_no fila){
ptr_no atual;
atual = (ptr_no) malloc(sizeof(no));
atual = fila;
if (fila->proximo != NULL){
fila = fila->proximo;
atual->proximo = fila->proximo;
}
}
//Desenha o contedo da fila na tela
void fila_mostrar(ptr_no fila){
system("cls");
while(fila->proximo != NULL) {
printf("%d, ", fila->dado);
fila = fila->proximo;
}
printf("%d, ", fila->dado);
}

Lista Dinmica com Forma de Fila

IV

CONSIDERAES FINAIS

1) Somente ser permitido inserir elementos no final da lista;


2) Somente ser permitido remover elementos do final da lista.
O que teremos? Uma pilha. A diferena que agora com o conceito de lista,
podemos implementar a pilha de forma dinmica, ou seja, no precisamos mais
definir o tamanho mximo da pilha. A pilha agora pode ser to grande quanto
o espao disponvel na memria do computador.
Podemos fazer mais. Em cima da implementao de uma lista dinmica,
vamos imaginar outras duas regras:
1) Somente ser permitido inserir elementos no final da lista;
2) Somente ser permitido remover elementos do incio da lista.
Acertou quem de cara percebeu que acabamos de criar uma fila com base em
uma lista encadeada.
Assim como a pilha e a fila tm como caracterstica as regras de adio e
remoo de elementos, a caracterstica principal da lista est em seus elementos conterem informaes que permitam naveg-la de forma sequencial mesmo
que os dados no estejam fisicamente em sequncia.
Na prxima unidade veremos de perto a Teoria dos Grafos. Mais do que uma
simples estrutura de dados, os grafos so formas de modelagem de problemas.
Se um problema puder ser modelado na forma de um grafo, possvel aplicar a
ele um algoritmo conhecido para encontrar a soluo do problema.

LISTAS DINMICAS

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

Nesta unidade, vimos dois assuntos muito


importantes. O primeiro foi a conceitualizao
de lista como uma estrutura de dados. O segundo foi
a sua implementao de forma dinmica.
A principal caracterstica da lista possuir na estrushutterstock
tura do seu n um atributo que armazena o endereo do prximo
elemento. Essa regra existe em qualquer tipo de implementao, seja ela em uma
lista dinmica ou esttica.
Se adicionarmos ao exemplo apresentado nesta unidade duas regras:

108 - 109

1. possvel criar uma lista de forma esttica usando um vetor?


2. Crie a estrutura de um n para uma lista encadeada.
3. Crie a estrutura de um n para uma lista duplamente encadeada.
4. Qual a vantagem de uma lista duplamente encadeada em relao a uma lista
simples?
5. Como sabemos qual o n inicial de uma lista simples?
6. Como sabemos qual o n final de uma lista simples?
7. Se o n de uma lista duplamente encadeada possui dois ponteiros, um para o
prximo elemento e um para o anterior, qual informao est contida nesses
ponteiros do primeiro n da lista?

MATERIAL COMPLEMENTAR

Algoritmos
Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein
Editora: Elsevier
Sinopse: Este livro apresenta um texto abrangente sobre o moderno estudo de algoritmos para
computadores. uma obra clssica, cuja primeira edio tornou-se amplamente adotada nas
melhores universidades em todo o mundo, bem como padro de referncia para profissionais da
rea.
Nesta terceira edio, totalmente revista e ampliada, as mudanas
so extensivas e incluem novos captulos, exerccios e problemas;
reviso de pseudocdigos e um estilo de redao mais claro.
A edio brasileira conta ainda com nova traduo e reviso
tcnica do Prof. Arnaldo Mandel, do Departamento de Cincia
da Computao do Instituto de Matemtica e Estatstica da
Universidade de So Paulo.
Elaborado para ser ao mesmo tempo verstil e completo, o livro
atende alunos dos cursos de graduao e ps-graduao em
algoritmos ou estruturas de dados.

GRAFOS

UNIDADE

Professor Me. Rogrio de Leon Pereira

Objetivos de Aprendizagem
Conhecer a origem dos grafos.
Aprender suas propriedades.
Representar grafos computacionalmente.
Estudar exemplos de aplicao de grafo na modelagem de
problemas.

Plano de Estudo
A seguir, apresentam-se os tpicos que voc estudar nesta unidade:
Sete pontes de Knigsberg
Teoria dos Grafos
Grafos como representao de problemas
Representao computacional de grafos
Implementando Grafos em C

112 - 113

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

INTRODUO
Reservamos para o fechamento deste livro um dos assuntos mais pesquisados e
interessantes dentro da cincia da computao que a Teoria dos Grafos. Mais
do que uma estrutura de dados, os grafos permitem modelar de forma matemtica problemas reais de logstica, custos, eficincia dentre muitos outros.
Um exemplo da aplicao de grafo para a soluo de problemas demonstrado por Tanenbaum (2003, pp. 375-377) no captulo sobre roteamento pelo
caminho mais curto. O grafo representa os roteadores e as rotas entre eles, e
com o algoritmo de Dijkstra possvel encontrar a menor rota entre dois roteadores na rede.
Quando voc busca um endereo pelo Google Maps, ou em um GPS, as
informaes das ruas esto armazenadas em forma de grafo e algoritmos conhecidos que so aplicados para apresentar a voc possveis caminhos de onde voc
est no momento at o destino desejado.
Veremos nesta unidade onde o grafo surgiu e quem o criou. Abordaremos
a parte terica da sua definio, seu conceito e a sua utilizao. Ensinaremos
tambm a forma de criar uma representao grfica a partir de um conjunto de
dados e vice-versa. Finalmente, ensinaremos uma das muitas formas de modelagem computacional de grafos.

SETE PONTES DE KNIGSBERG


A Teoria dos Grafos surgiu informalmente em 1736 quando o matemtico e fsico
suo Leonhard Paul Euler (1707 - 1783), por meio do seu artigo Solutio problematis ad geometriam situs pertinentes, props uma soluo para o famoso
problema matemtico conhecido como Sete pontes de Knigsberg.
A regio de Knigsberg (atual Kaliningrado) era (e ainda ) cortada pelo Rio
Preglia, que divide o territrio em duas grandes ilhas e duas faixas continentais.

Introduo

Na poca havia 7 pontes que interligavam todo o complexo geogrfico que formava a cidade.

Em uma poca sem internet, TV a cabo e telefones celulares, a populao possua


poucas opes de lazer. Uma delas era solucionar uma lenda popular que dizia
ser possvel atravessar todas as sete pontes de Knigsberg sem repetir nenhuma
delas no trajeto.
Euler provou matematicamente que no havia uma soluo possvel de
satisfazer tais restries. Para isso, ele modelou o problema de forma abstrata.
Considerou cada poro de terra como um ponto (vrtice) e cada ponte como uma reta (aresta) que ligava
dois pontos (duas pores de terra). Esse o registro
cientfico formal mais antigo de um grafo.
Grafo criado por Euler para representar o problema das sete pontes de Knigsberg
Analisando a figura, ele percebeu que s seria possvel caminhar todo o percurso atravessando cada uma das pontes uma nica vez
se houvesse exatamente zero ou dois vrtices de onde sasse um nmero mpar
de arestas. Falar fcil, o difcil provar que isso uma verdade. Vamos olhar
atentamente a figura criada por ele e tentar chegar mesma concluso.

GRAFOS

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

Fonte: <http://corbettmaths.files.wordpress.com/2012/02/bridges-of-konigsberg.jpg>

114 - 115

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

Eu posso passar quantas vezes eu quiser por cada uma das pores de terra (pontos), o que eu no posso repetir as pontes (retas). Se um vrtice possuir um
nmero par de arestas, eu posso chegar quele ponto pela primeira aresta e sair
pela segunda. No havendo vrtices com nmero mpar de arestas, o percurso
pode ser iniciado a partir de qualquer vrtice, porm, dever iniciar e terminar
no mesmo ponto no grafo. Isso prova que a primeira afirmao feita por Euler
verdadeira: deve haver exatamente zero vrtice com nmero mpar de arestas.

Percorrendo um grafo apenas com vrtices de nmero par de arestas


Mas para a prova final, precisamos testar a veracidade da segunda afirmao feita por ele. No caso de haver vrtices com nmero mpar de arestas, precisa
haver exatamente dois deles. Se um ponto possuir um nmero mpar de arestas
eu posso entrar e sair usando duas delas, sobrando uma terceira. Quando temos
exatamente dois pontos com nmeros mpares de caminhos, um desses vrtices
ser obrigatoriamente o incio e outro o final do trajeto.
Grafo com exatamente dois vrtices com nmero mpar de arestas

Sete Pontes de Knigsberg

TEORIA DOS GRAFOS

GRAFOS

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

A teoria dos grafos um ramo da matemtica que estuda as relaes entre os


objetos de um determinado conjunto. Para isso, so empregadas estruturas chamadas de grafos.
Grafo uma estrutura G = (V,E), onde V um
conjunto finito no nulo de vrtices (ou ns), e E
um conjunto de arestas (ou arcos). Uma aresta um
par de vrtices a = {v,w}, onde v e w V e a E.
Aps a apresentao formal entre voc, caro(a) aluno(a), e o dito Grafo, vamos analisar novamente o
desenho criado por Euler e traduzir isso para uma
linguagem menos matemtica.
Como acabamos de apresentar, o grafo formado por dois conjuntos: um de
vrtices (V, que no pode ser nulo) e um de arestas (E). Dado o grafo de Euler,
podemos dizer que o conjunto V formado por:
V= { a,b,c,d }
As arestas so formadas sempre por dois vrtices que existam no conjunto V
e no h nenhuma obrigatoriedade da existncia de arestas no grafo. Com isso
em mente, conclumos que E tem a seguinte configurao:
E= { (a,b), (b,c), (c,d), (d,a) }
No caso dos pares de vrtices serem ordenados,
ou seja, uma aresta a = (v,w) considerada diferente da aresta a = (w,v), o grafo dito orientado
(ou dgrafo).
Para indicar que os elementos do conjunto E
so pares ordenados, usamos a notao de chaves
angulares ao invs de parnteses. A representao
do conjunto E do grafo anterior a seguinte:
Exemplo de grafo orientado
E= {<a,b>, <c,b>, <a,d>, <d,a>}
Em um grafo simples, dois vrtices v e w so adjacentes (ou vizinhos) se h uma aresta
a = {v,w} em G. Esta aresta dita ser incidente a ambos, v e w. No caso de grafos

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

116 - 117

orientados, diz-se que cada aresta a = (v,w) possui uma nica direo de v para
w onde a aresta a = (v,w) dita divergente de v e convergente a w.
O grau de um vrtice definido pela sua
quantidade de arestas. O seu grau de sada a
quantidade de arestas divergentes e o grau de
entrada o de arestas convergentes. No exemplo de grafo orientado, podemos afirmar que o
vrtice a possui grau 3, sendo grau de sada 2
{(a, b), (a, d)} e grau 1 de entrada {(d, a)}.
Um grafo dito grafo conexo quando possvel partir de um vrtice v at um vrtice w atravs
Exemplo de grafo desconexo
de suas arestas incidentes. Caso contrrio, o grafo
dito desconexo.
Vimos at agora que possvel desenhar um grafo a partir de um conhecido
conjunto G = (V,E) da mesma forma que a partir de uma representao grfica
podemos encontrar os elementos pertencentes aos conjuntos V e E.

GRAFOS COMO REPRESENTAO DE PROBLEMAS


O grafo uma estrutura muito interessante e verstil. Ela permite modelar de
forma matemtica diversos problemas reais existentes no nosso cotidiano. Foi
o que Euler fez em 1736. A partir do modelo matemtico, possvel procurar a
soluo por meio de inmeros algoritmos j criados.
Por exemplo, no desenvolvimento de um site, voc pode considerar cada
pgina como um vrtice e o link entre duas delas como uma aresta. Assim, voc
pode representar toda a organizao e fluxo do site por meio de um grafo. Isso
pode ajudar na hora de verificar se todas as pginas esto ligadas, se o usurio tem
a possibilidade de acessar todo o contedo e se a estrutura tem boa navegabilidade.
Uma empresa de logstica pode considerar cada cliente como um n e o caminho entre dois deles um arco. Por meio de um algoritmo de busca de caminho,
Grafos como Representao de Problemas

REPRESENTAO COMPUTACIONAL DE GRAFOS


Existem inmeras formas de representar computacionalmente um grafo, cada
qual com suas vantagens e desvantagens em relao a tempo de implementao,
uso de memria, gasto de processamento etc. Por questes pedaggicas, vamos
apresentar a mais prtica.
Sabemos que um grafo uma estrutura G = (V,E), onde V um conjunto
finito no nulo de vrtices ou ns. Qual a maneira mais simples e prtica para
representar um conjunto finito de informaes? Acertou quem se lembrou do
nosso velho conhecido vetor.

GRAFOS

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

como o algoritmo de busca em largura (BFS - Breadh First Search), um sistema


informatizado poderia traar a rota de entrega para o dia seguinte de forma automtica a partir de uma lista de pedidos.
Ainda usando o exemplo da empresa de logstica, imagine que cada aresta
do grfico possui um peso que indica a distncia entre dois locais de entrega.
Existem algoritmos como o de Dijkstra (um BFS guloso) capaz de no apenas
buscar o caminho entre dois pontos, mas procurar o caminho de menor custo,
mais eficiente ou de maior lucro.
Podemos aplicar isso em outros problemas, como em uma empresa de transporte areo. Imagine que cada aeroporto/cidade seja considerado um vrtice no
grfico, a rota (voo) entre eles uma aresta. Se um passageiro decidir viajar de
Curitiba no Paran at Manaus no Amazonas e no h um voo direto entre essas
duas capitais, o sistema pode buscar e oferecer vrias opes de conexes entre
diferentes rotas para o viajante.
Os pesos nas arestas no precisam necessariamente representar o custo monetrio entre dois ns. Podemos considerar outras grandezas como o tempo de
espera no aeroporto, o tempo de viagem, modelo da aeronave e assim por diante.

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

118 - 119

shutterstock

Ainda pensando na estrutura do grafo G, E um conjunto de arestas ou arcos.


Uma aresta um par de vrtices a = {v,w}, onde v e w V e a E. Para a representao de pares ordenados, podemos utilizar uma matriz bidimensional.
Dada uma matriz Mij onde i a quantidade de linhas e j a quantidade de colunas, podemos dizer que se houver uma aresta a ligando os vrtices v e w, ento
o valor contido em Mvw ser 1. Essa matriz
chamada de Matriz de Adjacncia, lembrando
que dois vrtices so adjacentes em um grafo
se houver uma aresta entre eles.
Vamos ilustrar essas definies usando o
grafo ao lado:
O vetor que representa os seus vrtices
representado por:
V= { a,b,c,d }
Como o grafo possui quatro vrtices, a sua
matriz de adjacncia ter quatro linhas e quatro colunas. Cada interseco entre
linha e coluna representa um par ordenado (aresta) no grafo.

R
S
Sa
S
M = Sb
Sc
SS
d
T

a
0
0
0
0

b
0
0
0
0

c
0
0
0
0

d
0
0
0
0

V
W
W
W
W
W
WW
X

Representao Computacional de Grafos

Sabemos que existe uma aresta ligando os vrtices a e b, ento o valor de Mab 1.

R
S
Sa
S
M = Sb
Sc
SS
d
T

a
0
0
0
0

b
1
0
0
0

c
0
0
0
0

d
0
0
0
0

V
W
W
W
W
W
WW
X

R
S
Sa
S
M = Sb
Sc
SS
d
T

a
0
1
0
0

b
1
0
0
0

c
0
0
0
0

d
0
0
0
0

V
W
W
W
W
W
WW
X

Usando desse raciocnio, vamos completar a matriz M alterando para 1 o valor


de cada par ordenado que representar uma aresta entre dois vrtices do grafo.

R
S
Sa
S
M = Sb
Sc
SS
d
T

a
0
1
0
1

b
1
0
1
1

c
0
1
0
1

d
1
1
1
0

V
W
W
W
W
W
WW
X

A representao de um conjunto E de vrtices na forma de uma Matriz de


Adjacncias tambm facilita a visualizao de outros tipos de informao. Por
exemplo, sabemos que o vrtice a de grau dois, pois possui duas arestas {(a, b),
(a, d)}. Em uma matriz de adjacncia o grau de um determinado vrtice dado
pela quantidade de nmeros 1 na sua linha ou coluna.

R
S
Sa
S
M = Sb
Sc
SS
d
T

GRAFOS

a
0
1
0
1

b
1
0
1
1

c
0
1
0
1

d
1
1
1
0

V
W
W
W
W
W
WW
X

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

Como se trata de um grafo no ordenado, podemos dizer que de Mab =


Mba. Dessa forma, verdade dizer que Mba tambm 1.

120 - 121

Quando se trata de um grafo no ordenado, podemos dizer que um vrtice


a = {v,w} igual ao vrtice a = {w,v}, porm, em um grafo ordenado isso no
verdade.

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

Vamos criar agora uma matriz de adjacncias para um grafo orientado.

R
S
Sa
S
M = Sb
Sc
SS
d
T

a
0
0
0
1

b
1
0
1
0

c
0
0
0
0

d
1
0
0
0

V
W
W
W
W
W
WW
X

possvel dizer o grau de sada de um vrtice contando a quantidade de nmeros 1 na sua linha e o seu grau de entrada pela quantidade de nmeros 1 na sua
coluna.

R
S
Sa
S
M = Sb
Sc
SS
d
T

a
0
0
0
1

b
1
0
1
0

c
0
0
0
0

d
1
0
0
0

V
W
W
W
W
W
WW
X

Nesse exemplo, o grau do vrtice a 3, sendo grau 2 de sada e grau 1 de


entrada.

Representao Computacional de Grafos

IMPLEMENTANDO GRAFOS EM C

//Constantes
#define maximo 10

Como variveis, vamos criar um vetor chamado grafo que ter o tamanho
definido na constante maximo. Para as arestas, usaremos um vetor bidimensional chamado ma, que representar uma matriz de adjacncias. Vamos permitir
no nosso projeto que o usurio defina o tamanho do grafo at o limite estabelecido em maximo. Uma varivel chamada tamanho do tipo inteira o suficiente
para tal tarefa.
//Constantes
#define maximo 10
//Variveis
int tamanho=0;
int grafo[maximo];
int ma[maximo][maximo];

O vetor foi criado com um tamanho muito grande, mas o usurio vai poder
usar apenas uma parte dele. Vamos criar uma funo chamada grafo_tamanho() que l a quantidade de vrtices e retorna essa informao para a chamada
da funo.

GRAFOS

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

Agora que voc j viu a Teoria dos Grafos e aprendeu uma forma simples de
represent-los de forma computacional, vamos colocar a mo na massa. No h
maneira melhor de aprender a programar do que programando.
No iremos trabalhar aqui com estruturas dinmicas, ento devemos utilizar de estruturas estticas para armazenar as informaes do grafo. O grafo
composto por dois elementos, sendo o primeiro um conjunto de vrtices e o
segundo um conjunto de arestas.
Para representar os vrtices, vamos usar um vetor e para as arestas uma
matriz (vetor bidimensional). Como no sabemos a quantidade de vrtices no
grafo, vamos criar um vetor suficientemente grande para que acomode uma
grande quantidade de informaes. Para isso, vamos definir uma constante chamada maximo de valor 10.

122 - 123

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

//Define o nmero de vrtices do Grafo


int grafo_tamanho(){
int tamanho;
printf(Escolha a quantidade de vrtices do grafo: );
scanf(%d, &tamanho);
return tamanho;
}

Como o foco aqui demonstrar como criar a estrutura de um grafo em linguagem C, vamos nos concentrar apenas nas funes principais. Se voc vai deixar o
usurio escolher a quantidade de ns, voc precisa verificar se esse valor vlido,
ou seja, se maior do que zero e menor ou igual ao tamanho definido no vetor.
Agora que eu j sei quantos vrtices tem no grafo, o prximo passo inserir
as arestas. Em uma matriz de adjacncias, a representao de uma aresta entre um
vrtice x qualquer com um vrtice y se d pelo valor 1 na posio xy da matriz.
Como no se trata de um grafo orientado, podemos considerar que se existe
uma aresta xy, tambm verdadeiro considerar que existe uma aresta yx. Assim,
a funo grafo_inserir() perguntar para o usurio os dois vrtices e ir adicionar o valor 1 nas respectivas posies dentro da matriz de adjacncias.
//Inserir aresta
void grafo_inserir(){
int num1, num2;
system(cls);
printf(Escolha o vrtice de origem entre 0 a %d: , tamanho-1);
scanf(%d,&num1);
printf(Escolha o vrtice de destino entre 0 a %d: , tamanho-1);
scanf(%d,&num2);
if (num1 > tamanho-1 || num2 > tamanho-1 || num1 <0 || num2 <0){
printf(\nOs valores precisam estar entre 0 e %d\n\n, tamanho);
system(pause);
}
else {
ma[num1][num2]=1;
ma[num2][num1]=1;
}

Precisamos tambm do efeito oposto, o de remover uma aresta no grafo. No


queremos que o usurio comece tudo do zero caso tenha inserido uma aresta
Implementando Grafos em C

por engano. A funo grafo_remover() tambm ser til em momentos que seja
necessrio transformar o grafo a partir da remoo de arestas. O procedimento
ser o mesmo, s que ao invs de colocar o valor 1 na posio xy da matriz de
adjacncias, o valor ser definido como 0.

Com os dados na memria, s falta mostrar o resultado para o usurio.


Vamos criar duas funes, uma chamada grafo_desenhar(), que apresentar na
tela a lista de vrtices, e outra chamada grafo_desenhar_ma(), pra desenhar a
matriz de adjacncias.
Para o vetor de vrtices muito simples, basta um lao de repetio que
comece em zero e v at o valor contido na varivel tamanho. Para cada interao no lao, o programa deve imprimir na tela o valor da posio no vetor.
//Funo para desenhar o vetor de vrtices
void grafo_desenhar(){
//Desenhando lista de vrtices
printf(Listas de vrtices\n[ );
for (int i = 0; i < tamanho; i++){
printf(%d , grafo[i]);
}
printf(]\n\n);
}

J para desenhar a matriz, precisaremos de dois laos de repetio, um percorrendo todas as linhas, e para cada linha o segundo lao percorre todas as colunas.

GRAFOS

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

//Remover aresta
void grafo_remover(){
int num1, num2;
system(cls);
printf(Escolha o vrtice de origem entre 0 a %d: ,tamanho);
scanf(%d, &num1);
printf(Escolha o vrtice de destino entre 0 a %d: ,tamanho);
scanf(%d, &num2);
if (num1 > tamanho-1 || num2 > tamanho-1 || num1 <0 || num2 <0){
printf(\nOs valores precisam estar entre 0 e %d\n\n,tamanho);
system(pause);
}
else {
ma[num1][num2]=0;
ma[num2][num1]=0;
}
}

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

124 - 125

//Funo para desenhar a matriz de arestas


void grafo_desenhar_ma(){
//Desenhando matriz de adjacncias
printf(Matriz de adjacencias\n[\n);
for (int i = 0; i < tamanho; i++){
for (int j = 0; j < tamanho; j++){
printf( %d, ma[i][j]);
}
printf(\n);
}
printf(]\n\n);
}

A seguir, voc encontrar o cdigo completo da implementao de um


Grafo em linguagem C. Digite o cdigo no seu compilador e faa alguns testes
incluindo e removendo arestas. Experimente recriar no seu programa os grafos
vistos nesta unidade.
//Bibliotecas
#include <stdio.h>
#include <stdlib.h>
//Constantes
#define maximo 10
//Variveis
int tamanho=0;
int grafo[maximo];
int ma[maximo][maximo];
int op=1;
//Prototipao
int grafo_tamanho();
void grafo_desenhar();
void grafo_desenhar_ma();
void grafo_inserir();
void grafo_remover();
void menu_mostrar();
//Funo Principal
main(){
while (tamanho <= 0 || tamanho > maximo){
tamanho = grafo_tamanho();

Implementando Grafos em C

//Define o nmero de vrtices do Grafo


int grafo_tamanho(){
int tamanho;
printf(Escolha a quantidade de vrtices do grafo: );
scanf(%d, &tamanho);
return tamanho;
}
//Funo para desenhar o vetor de vrtices
void grafo_desenhar(){
//Desenhando lista de vrtices
printf(Listas de vrtices\n[ );
for (int i = 0; i < tamanho; i++){
printf(%d , grafo[i]);
}

GRAFOS

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

if(tamanho <= 0 || tamanho > maximo) {


system(cls);
printf(Escolha um valor entre 1 e %d!\n\n, maximo);
}
else {
for(int i=0; i<tamanho;i++){
grafo[i]=i;
}
}
}
while (op != 0) {
system(cls);
grafo_desenhar();
grafo_desenhar_ma();
menu_mostrar();
scanf(%d, &op);
switch (op) {
case 1:
grafo_inserir();
break;
case 2:
grafo_remover();
break;
}
}
system(Pause);
return(0);

126 - 127

printf(]\n\n);

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

//Funo para desenhar a matriz de arestas


void grafo_desenhar_ma(){
//Desenhando matriz de adjacncias
printf(Matriz de adjacencias\n[\n);
for (int i = 0; i < tamanho; i++){
for (int j = 0; j < tamanho; j++){
printf( %d, ma[i][j]);
}
printf(\n);
}
printf(]\n\n);
}
//Inserir aresta
void grafo_inserir(){
int num1, num2;
system(cls);
printf(Escolha o vrtice de origem entre 0 a %d: ,tamanho-1);
scanf(%d,&num1);
printf(Escolha o vrtice de destino entre 0 a %d: ,tamanho-1);
scanf(%d,&num2);
if (num1 > tamanho-1 || num2 > tamanho-1 || num1 <0 || num2
<0){
printf(\nOs valores precisam estar entre 0 e %d\n\n,tamanho);
system(pause);
}
else {
ma[num1][num2]=1;
ma[num2][num1]=1;
}
}
//Remover aresta
void grafo_remover(){
int num1, num2;
system(cls);
printf(Escolha o vrtice de origem entre 0 a %d: ,tamanho);
scanf(%d, &num1);

Implementando Grafos em C

//Mostrar o menu de opeses


void menu_mostrar() {
printf(\nEscolha uma opo:\n);
printf(1 - Inserir aresta\n);
printf(2 - Remover aresta\n);
printf(0 - Sair\n\n);
}

GRAFOS

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

printf(Escolha o vrtice de destino entre 0 a %d: ,tamanho);


scanf(%d, &num2);
if (num1 > tamanho-1 || num2 > tamanho-1 || num1 <0 || num2
<0){
printf(\nOs valores precisam estar entre 0 e %d\n\n,tamanho);
system(pause);
}
else {
ma[num1][num2]=0;
ma[num2][num1]=0;
}
}

128 - 129

Teoria dos Grafos

Reproduo proibida. Art. 184 do Cdigo Penal e Lei 9.610 de 19 de fevereiro de 1998.

<www.ime.usp.br/~pf/teoriadosgrafos/texto/TeoriaDosGrafos.pdf>

CONSIDERAES FINAIS
Os grafos so estruturas fascinantes. Com eles, podemos representar de forma
grfica ou matemtica diversos problemas reais presentes no nosso dia a dia.
Ns no percebemos, mas diversas facilidades existentes hoje na vida moderna
so graas aplicao de algoritmos especializados em resolver problemas baseados em grafos.
Muitas empresas modelam em grafo a sua cadeia de produo, distribuio e logstica aplicando estudos e algoritmos para maximizar lucro, diminuir
custo, otimizar o tempo.
Se um problema puder ser representado na forma de um grafo, muito possvel que exista um algoritmo que possa encontrar uma boa soluo dentro de
um conjunto desconhecido de possibilidades. E se esse algoritmo no existir,
voc j tem conhecimento suficiente para cri-lo.

Consideraes Finais

Dados os seguintes conjuntos G = (V,E):


a) V= {a}, E= {}
b) V= {a,b}, E= {(a,b)}
c) V= {a,b}, E= {<b,a>}
d) V= {a,b,c}, E= {(a,b), (b,c)}
e) V= {a,b,c}, E= {<a,b>, <c,b>, <a,c>, <c,a>}
f ) V= {a,b,c,d}, E= {<a,b>, <d,a>}
g) V= {a,b,c,d}, E= {(a,b), (a,c), (a,d)}
1. Desenhe a representao em Grafo de cada conjunto G = (V,E).
2. Classifique cada um dos conjuntos G = (V,E) como sendo orientado, no orientado, conexo e desconexo.
3. Crie a matriz de adjacncia para cada conjunto G = (V,E).

130 - 131
130 - 131

CONCLUSO
No incio deste livro, voc foi convidado(a) a fazer uma reviso sobre o sistema numrico decimal. Com essa informao, pudemos estudar outros sistemas como o
binrio, usado no computador, e o hexadecimal, conhecido como o intermedirio
entre a linguagem humana e a linguagem de mquina.
Passamos a entender melhor o que acontece no hardware. Muitos deviam se perguntar como o computador sabe a diferena entre um nmero inteiro de 32 bits e
um nmero de ponto flutuante, que tambm possui 32 bits. No poderamos desvendar esse mistrio sem saber mais sobre como os nmeros so organizados na
memria.
E a memria, que antes era um local atingvel apenas pela referncia indireta das
variveis, passou a ser uma ferramenta poderosa e acessvel ao programador pelo
uso dos ponteiros. Agora voc, caro(a) aluno(a), pode investigar o contedo ali armazenado de forma indireta, navegando livremente pela vastido de informaes
carregadas no computador.
E esse foi s o comeo. Foi possvel se libertar das amarras estticas criadas pelos tipos pr-definidos de valores e alar voos maiores por meio de estruturas dinmicas,
criando o seu prprio espao de forma arrojada e independente.
Voc aprendeu sobre as Listas, estrutura verstil que permite organizar as informaes definindo a sua prpria forma de ordenao sequencial, independente da posio fsica que os dados ocupam na memria.
Aprendeu tambm os conceitos de Pilhas e Filas, que so tipos de Listas que possuem regras rgidas e bem definidas para a entrada e sada de informao.
Por fim, foi apresentada a Teoria dos Grafos, recurso indispensvel para qualquer
profissional que queira programar de forma eficiente e que permite resolver computacionalmente problemas complexos do dia a dia.
A rea de Tecnologia da Informao se destaca por ser um ramo da cincia que est
em plena evoluo. O conhecimento se renova, novas ferramentas surgem a cada
dia, os computadores ficam mais rpidos, menores e mais baratos. Mas a base ainda
a mesma, e o contedo aprendido neste livro ir certamente acompanh-lo(a) por
toda a sua carreira.

132 - 133

REFERNCIAS
CORMEN, Thomas H. et al. Algoritmos. Traduo de Arlete Simille Marques. 3. ed.
Rio de Janeiro: Elsevier, 2012.
IFRAH, Georges. Os nmeros: histria de uma grande inveno. Traduo de Stella
Maria de Freitas Senra. 11. ed. So Paulo: Globo, 2005.
LAUREANO, Marcos. Estrutura de Dados com Algoritmos em C. Rio de Janeiro:
BRASPORT, 2012.
LEAL, Gislaine Camila Lapasini. Algoritmos e lgica de programao II. Maring:
CESUMAR, 2012.
MACHADO, Francis Berenger; MAIA, Luiz Paulo. Arquitetura de Sistemas Operacionais. 3. ed. Rio de Janeiro: LTC Editora, 2002.
TENENBAUM, Aaron M. Estruturas de dados usando C. Traduo de Teresa Cristina
Flix de Souza. So Paulo: MAKRON Books, 1995.
TANENBAUM, Andrew S. Redes de computadores. Traduo de Vandenberg D. de
Souza. Rio de Janeiro: Elsevier, 2003.
VILELA JUNIOR, Aparecido. Fundamentos e arquitetura de computadores. Maring: CESUMAR, 2012.

134 - 135

GABARITO

UNIDADE I
1. Considerando que uma string de 8 bits pode conter um valor decimal inteiro
positivo ou dois nmeros em hexadecimal de 4 bits cada, efetue a converso:
a) 1010 1010
1 * 27

1 * 128

128

0*2

0 * 64

1 * 25

1 * 32

32

0*2

0 * 16

1*2

1*8

0 * 22

0*4

1 * 21

1*2

0*2

0*1

Total

170

BINRIO

DECIMAL

HEXADECIMAL

1010

10

1010

10

Resposta:
Binrio = 1010 1010
Decimal = 170
Hexadecimal = AA
b) 1100 0011
1 * 27

1 * 128

128

1 * 26

1 * 64

64

0 * 25

0 * 32

0*2

0 * 16

GABARITO

0 * 23

0*8

0 * 22

0*4

1*2

1*2

1 * 20

1*1

Total

195

BINRIO

DECIMAL

HEXADECIMAL

1100

12

0011

BINRIO

DECIMAL

HEXADECIMAL

1100

12

1100

12

Resposta:
Binrio = 1100 0011
Decimal = 195
Hexadecimal = C3
c) 1100 1100
1 * 27

1 * 128

128

1 * 26

1* 64

64

0*2

0 * 32

0 * 24

0 * 16

1 * 23

1*8

1*2

1*4

0*2

0*2

0 * 20

0*1

Total

204

136 - 137

GABARITO
Resposta:
Binrio = 1100 1100
Decimal = 204
Hexadecimal = CC
d) 1101 1111
1 * 27

1 * 128

128

1*2

1 * 64

64

0 * 25

0 * 32

1 * 24

1 * 16

16

1*2

1*8

1*2

1*4

1 * 21

1*2

1*2

1*1

Total

223

BINRIO

DECIMAL

HEXADECIMAL

1101

13

1111

15

Resposta:
Binrio = 1101 1111
Decimal = 223
Hexadecimal = DF
e) 0000 1000
0 * 27

0 * 128

0*2

0 * 64

0 * 25

0 * 32

0*2

0 * 16

1*2

1*8

4
3

GABARITO

0 * 22

0*4

0 * 21

0*2

0*2

0*1

Total

BINRIO

DECIMAL

HEXADECIMAL

0000

1000

Resposta:
Binrio = 0000 1000
Decimal = 8
Hexadecimal = 08
2. Encontre o valor decimal, o nmero negativo em Complemento de 1 e Complemento de 2 das strings de bits abaixo:
a) 00101010
0 * 27

0 * 128

0*2

0 * 64

1 * 25

1 * 32

32

0 * 24

0 * 16

1*2

1*8

0 * 22

0*4

1 * 21

1*2

0*2

0*1

Total

42

42
0

-42 (Complemento de 1)
1

138 - 139

GABARITO
-42 (Complemento de 2)
1

b) 0111 1111
0 * 27

0 * 128

1*2

1 * 64

64

1 * 25

1 * 32

32

1*2

1 * 16

16

1*2

1*8

1 * 22

1*4

1 * 21

1*2

1*2

1*1

Total

127

127
0

-127 (Complemento de 1)
1

-127 (Complemento de 2)
1

c) 0000 0000
0 * 27

0 * 128

0 * 26

0 * 64

0*2

0 * 32

0*2

0 * 16

0 * 23

0*8

0*2

0*4

GABARITO

0 * 21

0*2

0 * 20

0*1

Total

0
0

-0 (Complemento de 1)
1

0 (Complemento de 2)
0

d) 0110 0011
0 * 27

0 * 128

1*2

1 * 64

64

1 * 25

1 * 32

32

0 * 24

0 * 16

0*2

0*8

0 * 22

0*4

1*2

1*2

1*2

1*1

Total

99

99
0

-99 (Complemento de 1)
1

-99 (Complemento de 2)
1

140 - 141

GABARITO
e) 0101 1010
0 * 27

0 * 128

1*2

1 * 64

64

0 * 25

0 * 32

1 * 24

1 * 16

16

1*2

1*8

0*2

0*4

1 * 21

1*2

0*2

0*1

Total

90

90
0

-90(Complemento de 1)
1

-90 (Complemento de 2)
1

3. Sempre que uma string de bits contiver o valor 1 no primeiro bit da direita o
nmero ser mpar? Por qu?
Sim, porque o primeiro bit da direita a menor potncia de 2, ou seja, 20, que
1, assim, como os demais potncias de dois resultam em nmeros pares, a soma
de qualquer nmero par com 1 dar um nmero mpar.
4. Sempre que uma string de bits contiver o valor 1 no primeiro bit da esquerda o
nmero ser negativo? Por qu?
No, porque o primeiro bit da esquerda reservado para o sinal de positivo (0)
ou negativo (1) apenas em variveis que permitirem valores negativos como signed int, signed float etc.

GABARITO

UNIDADE II
1.
a) Crie uma estrutura para a pilha de livros. Lembre-se de que ela tem que ter um
vetor para armazenar os dados (cdigo, nome do livro e autor) e dois nmeros
inteiros, um para controlar o incio e outro o final da pilha.
//Constantes
#define tamanho 5
//Estrutura do Livro
struct tlivro {
int codigo;
char nome[50];
char autor[50];
};
//Estrutura da Pilha
struct tpilha {
tlivro dados[tamanho];
int ini;
int fim;
};

b) Defina a varivel que ser um vetor do tipo pilha de livros.


//Variveis globais
tpilha pilha;

142 - 143

GABARITO
c) Faa uma funo de empilhamento, lembrando-se de verificar se a pilha atingiu
o tamanho mximo de livros (a mesa no aguenta muito peso).
//Adicionar um elemento no final da Pilha
void pilha_entrar(){
if (pilha.fim == tamanho) {
printf(\nA pilha est cheia, impossvel empilhar!\n\n);
system(pause);
}
else {
printf(\nDigite o cdigo do livro: );
scanf(%d, &pilha.dados[pilha.fim].codigo);
printf(\nDigite o nome do livro: );
scanf(%s, pilha.dados[pilha.fim].nome);
printf(\nDigite o nome do autor: );
scanf(%s, pilha.dados[pilha.fim].autor);
pilha.fim++;
}
}

d) Crie uma funo para desempilhamento de livros, no se esquea de que necessrio verificar se ainda existem livros para ser guardados.
//Retirar o ltimo elemento da Pilha
void pilha_sair() {
if (pilha.ini == pilha.fim) {
printf(\nA pilha est vazia, impossvel desempilhar!\n\n);
system(pause);
}
else {
pilha.dados[pilha.fim-1].codigo = 0;
pilha.dados[pilha.fim-1].nome = ;
pilha.dados[pilha.fim-1].autor = ;
pilha.fim--;
}
}

GABARITO
e) Elabore uma funo que apresente na tela a lista de todos os livros que se encontram empilhados ao lado da recepo.
//Mostrar o contedo da Pilha
void pilha_mostrar() {
int i;
printf([ );
for (i = 0; i < tamanho; i++) {
printf(%d , pilha.dados[i].codigo);
}
printf(]\n\n);
}

2.
a) Faa uma estrutura para o controle da fila. Voc precisa guardar o nome e a hora
que o cliente chegou. Use um vetor para armazenar os dados e dois nmeros
inteiros, um para controlar o incio e outro o final da fila.
//Constantes
#define tamanho 5
//Estrutura do Cliente
struct tcliente {
char nome[tamanho];
char hora[5];
};
//Estrutura da Fila
struct tfila {
tcliente dados[tamanho];
int ini;
int fim;
};

b) Defina a varivel que ser um vetor do tipo fila de clientes.


//Variveis globais
tfila fila;

144 - 145

GABARITO
c) Crie uma funo enfileirar, lembrando que preciso verificar se h espao na fila
(o nmero de cadeiras na recepo limitado).
//Adicionar um elemento no final da Fila
void fila_entrar(){
if (fila.fim == tamanho) {
printf(\nA fila est cheia, volte outro dia!\n\n);
system(pause);
}
else {
printf(\nDigite o nome do cliente que chegou: );
scanf(%s, fila.dados[fila.fim].nome);
printf(\nDigite a hora da chegada do cliente: );
scanf(%s, fila.dados[fila.fim].hora);
fila.fim++;
}
}

d) Elabore a funo desenfileirar cliente, no se esquea de que necessrio verificar se ainda existem clientes para serem atendidos.
//Retirar o primeiro elemento da Fila
void fila_sair() {
if (fila.ini == fila.fim) {
printf(\nFila vazia, mas logo aparece algum!\n\n);
system(pause);
}
else {
int i;
for (i = 0; i < tamanho; i++) {
fila.dados[i].nome = fila.dados[i+1].nome;
fila.dados[i].hora = fila.dados[i+1].hora;
}
fila.dados[fila.fim].nome = ;
fila.dados[fila.fim].hora = ;
fila.fim--;
}
}

GABARITO
e) Faa uma funo que apresente na tela a lista de todos os clientes que esto
aguardando atendimento na recepo.
//Mostrar o contedo da Fila
void fila_mostrar() {
int i;
printf([ );
for (i = 0; i < tamanho; i++) {
printf(Cliente %s , fila.dados[i].nome);
printf(chegou as %s horas \n, fila.dados[i].hora);
}
printf(]\n\n);
}

UNIDADE III
1.
#include <stdio.h>
#include <stdlib.h>
main() {
int *ptr;
ptr = (int *) malloc(sizeof (int));
*ptr = 42;
printf (Endereco: %p\nValor: %d\n\n, ptr, *ptr);
system(Pause);
return(0);
}

146 - 147

GABARITO
2.
#include <stdio.h>
#include <stdlib.h>
struct semafaro {
char cor[10];
int id;
};
semafaro s1 = {Vermelho, 1};
semafaro s2 = {Amarelo, 2};
semafaro s3 = {Verde, 3};
semafaro *ptr_s;
main(){
ptr_s = &s1;
printf(%d - %s\n, (*ptr_s).id,(*ptr_s).cor);
ptr_s = ptr_s + 1;
printf(%d - %s\n, (*ptr_s).id,(*ptr_s).cor);
ptr_s = ptr_s + 1;
printf(%d - %s\n, (*ptr_s).id,(*ptr_s).cor);
system(Pause);
return(0);
}

3. Uma varivel do tipo inteira aponta pra um nmero inteiro na memria,


j um ponteiro do tipo inteiro aponta para o endereo de um inteiro na
memria, seja o de uma varivel esttica ou dinmica.
4. Porque se tentarmos alocar indiscriminadamente um endereo qualquer a um ponteiro corremos o risco de estar manipulando uma rea da
memria que est sendo utilizada por outro programa ou at mesmo pelo
sistema operacional, o que pode causar instabilidade no computador.

GABARITO
5.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int tamanho;
int *vetor1, *vetor2;
main() {
printf (Escolha o tamanho do vetor: );
scanf(%d, &tamanho);
vetor1 = (int *) malloc(sizeof (int)*tamanho);
vetor2 = (int *) malloc(sizeof (int)*(tamanho*2));
printf (\nVetor1: \n);
for (int i = 0; i < tamanho; i++) {
vetor1[i] = pow(2,i);
printf (Posicao %d: %d\n, i, vetor1[i]);
}
printf (\nVetor2: \n);
for (int i = 0; i < tamanho*2; i++) {
vetor2[i] = pow(3,i);
printf (Posicao %d: %d\n, i, vetor2[i]);
}
system(Pause);
return(0);
}

UNIDADE IV
1. possvel criar uma lista de forma esttica usando um vetor?
Sim, a lista pode ser implementada de forma esttica em um vetor ou dinamicamente na memria. O que caracteriza a lista o fato de seus ns possurem o
endereo do prximo elemento, permitindo assim a sua organizao independente do ndice do vetor.
2. Crie a estrutura de um n para uma lista encadeada.
struct no {
int dado;
struct no *proximo;
};

148 - 149

GABARITO
3. Crie a estrutura de um n para uma lista duplamente encadeada.
struct no {
int dado;
struct no *anterior;
struct no *proximo;
};

4. Qual a vantagem de uma lista duplamente encadeada em relao a uma lista


simples?
Na lista simples, os ns possuem apenas o endereo do prximo elemento. Dessa forma, podemos navegar do primeiro ao ltimo n em um nico sentido. Na
lista duplamente encadeada, os ns possuem o endereo do elemento anterior
e do elemento posterior. Dessa forma, podemos fazer a navegao em ambos os
sentidos, tanto do incio para o final como do final para o incio.
5. Como sabemos qual o n inicial de uma lista simples?
S possvel saber onde comea uma lista dinmica se tivermos uma varivel do
tipo ponteiro que aponte para o incio da lista.
6. Como sabemos qual o n final de uma lista simples?
Sabemos se um n o ltimo de uma lista se o atributo que aponta para o prximo elemento estiver com o valor nulo (null).
7. Se o n de uma lista duplamente encadeada possui dois ponteiros, um para o
prximo elemento e um para o anterior, qual informao est contida nesses
ponteiros do primeiro n da lista?
O primeiro n de uma lista encadeada tem dois ponteiros, assim como todos
os demais ns. O ponteiro criado para apontar para o elemento anterior estar
apontando para nulo, j que como o primeiro n, no h um n anterior. O
outro ponteiro estar apontando para o prximo n. Se por acaso s haja um
n nessa lista duplamente encadeada, ambos os ponteiros estaro apontando
para nulo.

GABARITO

UNIDADE V
1. Desenhe a representao em Grafo de cada conjunto G = (V,E).
a) V={a}, E={}

b) V={a,b}, E={(a,b)}

c) V= {a,b}, E= {<b,a>}

d) V={a,b,c}, E={(a,b), (b,c)}

e) V={a,b,c}, E={<a,b>, <c,b>, <a,c>, <c,a>}

150 - 151

GABARITO
f ) V={a,b,c,d}, E={<a,b>, <d,a>}

g) V={a,b,c,d}, E={(a,b), (a,c), (a,d)}

2. Classifique cada um dos conjuntos G = (V,E) como sendo orientado, no orientado, conexo e desconexo.
Um grafo dito grafo conexo quando possvel partir de um vrtice v at um
vrtice w atravs de suas arestas incidentes. Caso contrrio, o grafo dito desconexo.
No caso dos pares de vrtices serem ordenados, ou seja, uma aresta a = (v,w)
considerada diferente da aresta a = (w,v), o grafo dito orientado (ou dgrafo).
Caso contrrio, o grafo no orientado.
a) V={a}, E={}
Conexo, no orientado. Tambm conhecido como grafo trivial por conter apenas um vrtice e nenhuma aresta.
b) V={a,b}, E={(a,b)}
Conexo, no orientado.
c) V={a,b}, E={<b,a>}
Conexo, orientado.
d) V={a,b,c} , E= {(a,b), (b,c)}
Conexo, no orientado.

GABARITO
e) V={a,b,c}, E= {<a,b>, <c,b>, <a,c>, <c,a>}
Conexo, orientado.
f ) V={a,b,c,d}, E= {<a,b>, <d,a>}
Desconexo, orientado.
g) V={a,b,c,d}, E= {(a,b), (a,c), (a,d)}
Conexo, no orientado.
3. Crie a matriz de adjacncia para cada conjunto G = (V,E).
a) V={a}, E={}
M= {}
b) V={a,b}, E={(a,b)}

a b
M=>a 0 1
b 1 0

c) V={a,b}, E={<b,a>}

a b
M= a 0 1
b 0 0
d) V={a,b,c}, E={(a,b),(b,c)}

R
S
Sa
M=S
Sb
Sc
T

a
0
1
0

b
1
0
1

c
0
1
0

V
W
W
W
W
W
X

e) V={a,b,c}, E={<a,b>,<c,b>,<a,c>,<c,a>}

R
S
Sa
M=S
Sb
Sc
T

a
0
0
1

b
1
0
1

c
1
0
0

V
W
W
W
W
W
X

152 - 153

GABARITO
f ) V={a,b,c,d}, E={<a,b>,<d,a>}

R
S
Sa
S
M = Sb
Sc
SS
d
T

a
0
0
0
1

b
1
0
0
0

c
0
0
0
0

d
0
0
0
0

V
W
W
W
W
W
WW
X

g) V={a,b,c,d}, E={(a,b),(a,c),(a,d)}

R
S
Sa
S
M = Sb
Sc
SS
d
T

a
0
1
1
1

b
1
0
0
0

c
1
0
0
0

d
1
0
0
0

V
W
W
W
W
W
WW
X

154 - 155

ANEXO

TABELA ASC II

ANEXO

Fonte: <www.lookuptables.com>

Вам также может понравиться