Escolar Documentos
Profissional Documentos
Cultura Documentos
Martinez - Programacao de Computadores I - 2011 PDF
Martinez - Programacao de Computadores I - 2011 PDF
2011
S UMRIO
2 Introduo computao 21
2.1 Contextualizao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.2 Arquitetura de von Neumann . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.3 Algoritmos e programas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.3.1 Algoritmos e resoluo de problemas . . . . . . . . . . . . . . . . . . . . . 26
2.3.2 Resoluo de problemas e abstrao . . . . . . . . . . . . . . . . . . . . . . 27
2.3.3 Algoritmos e computadores . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
3 Dicas iniciais 31
3.1 Interface do sistema operacional . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
3.2 Compilador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.3 Emacs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
4 Primeiros programas 41
4.1 Digitando . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
4.2 Compilando e executando . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
4.3 Olhando o primeiro programa mais de perto . . . . . . . . . . . . . . . . . . . . . 42
4.4 Prximo programa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
4.5 Documentao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
4.6 Entrada e sada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
5 Estruturas condicionais 49
i
5.1 Estrutura condicional simples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
5.2 Estrutura condicional composta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
5.2.1 Aplicao: troca de contedos . . . . . . . . . . . . . . . . . . . . . . . . . 51
5.3 Reviso de nmeros inteiros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
5.3.1 Representao de nmeros inteiros . . . . . . . . . . . . . . . . . . . . . . . 56
10 Caracteres 89
10.1 Representao grfica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
10.2 Constantes e variveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
10.3 Expresses com caracteres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
ii
12 Vetores 113
12.1 Motivao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
12.2 Definio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
12.3 Declarao com inicializao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
12.4 Exemplo com vetores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
12.5 Macros para constantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
14 Matrizes 133
14.1 Definio, declarao e uso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
14.2 Declarao e inicializao simultneas . . . . . . . . . . . . . . . . . . . . . . . . . 135
14.3 Exemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
15 Registros 143
15.1 Definio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
15.2 Declarao e inicializao simultneas . . . . . . . . . . . . . . . . . . . . . . . . . 146
15.3 Operaes sobre registros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
15.4 Exemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
iii
18.1 Argumentos e parmetros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
18.2 Escopo de dados e de funes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
iv
23 Depurao de programas 229
23.1 Depurador GDB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
23.2 Primeiro contato . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
23.3 Sintaxe dos comandos do GDB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
23.4 Pontos de parada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
23.5 Programa fonte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234
23.6 Verificao de dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
23.7 Alterao de dados durante a execuo . . . . . . . . . . . . . . . . . . . . . . . . 236
23.8 Resumo dos comandos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236
23.9 Exemplos de execuo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
24 Pr-processador 249
24.1 Funcionamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
24.2 Diretivas de pr-processamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
24.3 Definies de macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
24.4 Incluso de arquivos-cabealhos . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
24.5 Compilao condicional . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
24.6 Outras diretivas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256
v
AULA 1
Nesta aula abordaremos uma pequena histria da computao. Sabemos, no entanto, que
esta na verdade uma tentativa e que fatos histricos relevantes podem ter sido excludos in-
voluntariamente. Continuaremos a trabalhar no sentido de produzir um texto cada vez mais
amplo e completo, buscando informaes em outras fontes que, por descuido ou desconheci-
mento, infelizmente ainda no foram consultadas.
Este texto baseado principalmente nas pginas da Rede Mundial de Computadores [1, 2,
3, 4, 5] e nos livros de Philippe Breton [6] e Russel Shackelford [7].
1.1 Pr-histria
Desde muito tempo, possvel notar que o ser humano vem realizando clculos complexos
para solucionar seus mais diversos problemas. Um dos primeiros e mais notveis exemplos que
temos registro a descoberta do nmero real que representa a relao entre o comprimento da
circunferncia de um crculo e o comprimento de seu raio. A mais antiga evidncia do uso
consciente de uma aproximao precisa para esse nmero, com valor 3 + 17 , foi descoberta nos
projetos das pirmides da poca do Reino Antigo no Egito, datando assim do ano de 2630 a.C. a
2468 a.C. As mais antigas evidncias textuais do clculo de aproximaes desse nmero datam
de 1900 a.C., realizadas pelos gemetras egpcios, babilnios, hindus e gregos. A letra grega
at hoje usada como a representao desse nmero.
Alm disso, a histria do pensamento humano marcada, desde o princpio, pelos registros
de tentativas de sistematizao e estruturao do mesmo. A lgica1 uma cincia filosfico-
matemtica descrita geralmente por um conjunto de regras que procura sistematizar o pensa-
mento. A lgica enxerga o pensamento como a manifestao do conhecimento, que por sua vez
visto como a busca da verdade, e, para que essa meta seja atingida, estabelece regras a serem
seguidas, chamadas de regras do pensar corretamente. Apesar de muitos povos antigos te-
rem usado sofisticados sistemas de raciocnio, somente na China, ndia e Grcia os mtodos de
raciocnio tiveram um desenvolvimento sustentvel e possvel que a lgica tenha emergido
nesses trs pases por volta do sculo IV a.C. A lgica moderna descende da lgica clssica,
tambm conhecida como lgica aristotlica, desenvolvida por Aristteles2. A lgica moderna
baseada na lgica clssica e usada extensivamente em diversas reas do conhecimento, em
especial na Cincia da Computao. At os dias de hoje, programas e computadores so proje-
tados com base nessa estruturao do pensamento chamada lgica.
1
Do grego clssico o, ou logos, que significa palavra, pensamento, idia, argumento, relato, razo lgica ou
princpio lgico.
2
Aristotles ( a.C. a.C.), nascido na Grcia, filsofo, aluno de Plato, mestre de Alexandre, o Grande.
1
2 B REVE HISTRIA DA COMPUTAO
Do mesmo modo, quando comeou a realizar tarefas mecnicas para sua comodidade e
bem estar, o ser humano predominantemente as mulheres tinha de realizar, hora aps hora,
dia aps dia, todos os clculos repetitivos em tarefas das cincias, do comrcio e da indstria.
Tabelas e mais tabelas eram preenchidas com os resultados desses clculos, para que no fos-
sem sempre refeitos. No entanto, erros nesses clculos eram freqentes devido, em especial, ao
tdio e desconcentrao. Alm disso, esses clculos no eram realizados de forma rpida. As-
sim, muitos inventores tentaram por centenas de anos construir mquinas que nos ajudassem
a realizar essas tarefas.
O baco3 provavelmente o mais antigo instru-
mento conhecido de auxlio ao ser humano em clcu-
los matemticos. O baco mais antigo foi descoberto
na Babilnia, hoje conhecida como Iraque, e data do
ano de 300 a.C. Seu valor est baseado especialmente
no fato de auxiliar a memria humana durante as ope-
raes aritmticas mais bsicas. Algum bem treinado
no uso de um baco pode executar adies e subtra-
es com a mesma velocidade de quem usa uma cal-
culadora eletrnica. No entanto, as duas outras opera-
es bsicas so realizadas de forma bem mais lenta.
Figura 1.1: baco. Esse instrumento ainda consideravelmente utilizado
em certos pases do Oriente.
No sculo IX, as contribuies de Muh.ammad ibn Musa al-
Khwarizm4 para a matemtica, geografia, astronomia e carto-
grafia estabelecem a base para inovaes na lgebra e na trigo-
nometria. A palavra lgebra deriva de seu livro do ano de
830 chamado O Livro Compndio sobre Clculo por Comple-
tamento e Equalizao (al-Kitab al-mukhtasar fi hisab al-jabr
wal-muqabala ), onde apresenta um mtodo sistemtico para
soluo de equaes lineares e quadrticas. Por esse trabalho
conhecido como o fundador da lgebra, ttulo que divide
com Diophantus. Seu outro livro Sobre o Clculo com N-
meros Hindus (Ketab fi Istimal al-Adad al-Hindi ), escrito no
ano de 825 e traduzido em seguida para o latim, foi respon-
svel pelo espalhamento do sistema de numerao hindu pelo
Oriente Mdio e Europa. Esses e outros de seus livros foram
Figura 1.2: Pgina de lgebra.
responsveis por enormes avanos na rea da Matemtica no
mundo ocidental naquela poca. Um outro livro seu chamado
A Imagem da Terra (Kitab surat al-ard ), traduzido como Geografia, apresenta uma revi-
so do trabalho de Ptolomeu com coordenadas mais precisas especialmente do mar Mediter-
rneo, sia e frica. Seu nome al-Khwarizm foi traduzido para o latim como Algoritmi, o
que levou o surgimento da palavra algoritmo (algorithm em ingls) e algarismo em portugus.
al-Khwarizm tambm projetou dispositivos mecnicos como o astrolbio e o relgio solar.
3
Abacus uma palavra em latim que tem sua origem nas palavras gregas abax ou abakon, que quer dizer tabela e
que, por sua vez, tem sua origem possivelmente na palavra semtica abq, que significa areia (do livro The Universal
History of Numbers de Georges Ifrah, Wiley Press 2000).
4
Abu Abdalla Muh.ammad ibn Musa al-Khwarizm ( ), nascido na Prsia, matemtico, astrnomo e
gegrafo.
FACOM UFMS
1.1 P R - HISTRIA 3
Ainda sobre os primeiros dispositivos de auxlio nas atividades humanas, o primeiro rel-
gio de bolso foi criado por Peter Henlein5 por volta de 1504. No ano de 1600, William Gilbert6
ficou conhecido por suas investigaes em magnetismo e eletricidade, tendo cunhado o termo
eletricidade a partir da palavra grega elecktra. John Napier7 , em seu trabalho Mirifici Loga-
rithmorum Canonis Descriptio de 1614, inventou o logaritmo, uma ferramenta que permitia
que multiplicaes fossem realizadas via adies e divises via subtraes. A mgica consis-
tia na consulta do logaritmo de cada operando, obtido de uma tabela impressa. A inveno de
John Napier deu origem rgua de clculo, instrumento de preciso construdo inicialmente na
Inglaterra em 1622 por William Oughtred8 e utilizado nos projetos Mercury, Gemini e Apollo
da NASA, que levaram o homem lua.
Leonardo da Vinci9 e Wilhelm Schickard10 , nos sculos XVI e XVII, respectivamente, foram
os primeiros a projetar mquinas de clculo baseadas em engrenagens. A mquina proposta
por da Vinci nunca saiu do papel, mas a mquina de Schickard conhecida como a primeira
calculadora mecnica automtica ou o primeiro computador no programvel. O sucesso de
uma mquina como essa s foi obtido por Blaise Pascal11 em 1642, que aos 19 anos construiu a
Pascaline para ajudar seu pai, um recolhedor de taxas, a somar quantias. A Pascaline realizava
apenas adies e no era muito precisa. Pouco tempo aps Pascal ter proposto sua mquina
de calcular, o alemo Gottfried Leibniz12 , co-inventor do Clculo juntamente com Isaac New-
ton13 , planejou construir uma calculadora14 com as quatro operaes bsicas e que, ao invs
de engrenagens, empregava cilindros dentados com 10 dentes, possibilitando seu trabalho no
sistema numrico decimal. O sculo seguinte tem poucas inovaes diretamente relacionadas
aos computadores, como a escala de temperaturas Fahrenheit15 , o telgrafo e a eletricidade,
tambm investigada por Benjamin Franklin16 .
5
Peter Henlein ( ), nascido na Alemanha, serralheiro, arteso e relojoeiro.
6
William Gilbert ( ), nascido na Inglaterra, fsico e filsofo. lhe atribudo o ttulo de Pai da Enge-
nharia Eltrica ou Pai da Eletricidade e Magnetismo.
7
John Napier ( ), nascido na Esccia, matemtico, fsico, astrnomo e 8o Lorde de Merchistoun.
8
William Oughtred ( ), nascido na Inglaterra, matemtico.
9
Leonardo di ser Piero da Vinci ( ), nascido na Itlia, erudito, arquiteto, anatomista, escultor, enge-
nheiro, inventor, matemtico, msico, cientista e pintor.
10
Wilhelm Schickard ( ), nascido na Alemanha, erudito.
11
Blaise Pascal ( ), nascido na Frana, matemtico, fsico e filsofo.
12
Gottfried Wilhelm Leibniz ( ), nascido na Alemanha, erudito.
13
Sir Isaac Newton ( ), nascido na Inglaterra, fsico, matemtico, astrnomo e filsofo.
14
Ele chamou sua mquina de stepped reckoner.
15
Daniel Gabriel Fahrenheit ( ), nascido na Alemanha, fsico e engenheiro.
16
Benjamin Franklin ( ), nascido nos Estados Unidos, jornalista, editor, autor, filantropo, abolicionista,
funcionrio pblico, cientista, diplomata e inventor. Foi tambm um dos lderes da Revoluo Norte-americana.
FACOM UFMS
4 B REVE HISTRIA DA COMPUTAO
Joseph Jacquard17 criou, em 1801, um tear que podia tecer a partir de um padro lido auto-
maticamente de cartes de madeira perfurados e conectados por cordes. Descendentes desses
cartes perfurados so utilizados at hoje em algumas aplicaes. A inveno de Jacquard
incrementou a produtividade de tecidos da poca, mas, em contrapartida, gerou grande de-
semprego de operrios da indstria txtil.
A Mquina de Diferenas 18 , projetada por Charles Babbage19 , era uma mquina de calcular
a vapor e foi criada com o objetivo de atender estratgia expansionista do governo ingls, que
tinha a ambio de se tornar o maior imprio do planeta. Esse foi o projeto mais caro financiado
pelo governo da Inglaterra at ento, mas aps dez anos de tentativas infrutferas, o projeto
ruiu e a mquina no foi terminada. Todavia, Babbage no desistiu e projetou uma segunda
mquina chamada Mquina Analtica 20 que seria alimentada por seis mquinas a vapor, teria
o tamanho de uma casa e era uma mquina de propsito mais geral, j que seria programvel
por meio de cartes perfurados. Alm disso, sua inveno tambm permitiria que os cartes
perfurados, agora de papel, fossem empregados como um dispositivo de armazenamento. Essa
mquina teria ainda um dispositivo que a distinguia das calculadoras e a aproximava do que
conhecemos hoje como computadores: uma sentena condicional.
Ada Byron21 tornou-se amiga de Charles Babbage e ficou fascinada com o as idias da M-
quina Analtica. Apesar de nunca ter sido construda, Ada escreveu diversos programas para
essa mquina e entrou para a histria como a primeira programadora de um computador. Ada
inventou a sub-rotina e reconheceu a importncia do lao como uma estrutura de programao.
O livro Uma Investigao das Leis do Pensamento sobre as quais so fundadas as Teorias
Matemticas da Lgica e das Probabilidades (An Investigation of the Laws of Thought on
Which are Founded the Mathematical Theories of Logic and Probabilities ), publicado em 1854
por George Boole22 , tornou-se muito influente cerca de 70 anos aps sua publicao, quando
Claude Shannon23 e Victor Shestakov24 independentemente descobriram uma interpretao
para a sua lgebra em circuitos de reles eletromecnicos, demonstrando que a aplicao prtica
17
Joseph Marie Jacquard ( ), nascido na Frana, alfaiate e inventor.
18
Do ingls Difference Engine.
19
Charles Babbage ( ), nascido na Inglaterra, matemtico, filsofo, engenheiro mecnico e precursor
da Cincia da Computao.
20
Do ingls Analytic Engine.
21
Augusta Ada Byron ( ), nascida na Inglaterra, conhecida como a primeira programadora da histria.
Depois de seu casamento passou a se chamar Augusta Ada King, Condessa de Lovelace.
22
George Boole ( ), nascido na Irlanda, matemtico e filsofo.
23
Claude Elwood Shannon ( ), nascido nos Estados Unidos, engenheiro eletrnico e matemtico, co-
nhecido como o pai da Teoria da Informao. Sua dissertao de mestrado j foi considerada como a mais impor-
tante dissertao de mestrado de todos os tempos.
24
Victor Ivanovich Shestakov ( ), nascido nos Rssia, lgico e engenheiro eltrico.
FACOM UFMS
1.2 S CULO XX 5
1.2 Sculo XX
A exploso dos computadores ocorreu no sculo XX. At a metade desse sculo, compu-
tadores eletromecnicos e os primeiros computadores totalmente eletrnicos foram projetados
com fins militares, para realizar clculos balsticos e decifrar cdigos dos inimigos. Eminen-
tes cientistas, que deram origem a quase tudo do que chamamos de Cincia da Computao,
estiveram envolvidos nesses projetos. A partir da segunda metade do sculo, a exploso dos
computadores eletrnicos se deu, quando o computador pessoal passou a fazer parte de nosso
dia a dia.
FACOM UFMS
6 B REVE HISTRIA DA COMPUTAO
FACOM UFMS
1.2 S CULO XX 7
Uma das primeiras pessoas a programar o Mark I foi uma mulher, Grace Hopper31, que em
1953 inventou a primeira linguagem de programao de alto nvel chamada Flow-matic, vindo
a se tornar posteriormente a linguagem COBOL. Uma linguagem de programao de alto n-
vel projetada com o objetivo de ser mais compreensvel ao ser humano, diferentemente da
linguagem binria, de baixo nvel, compreendida pelo computador. No entanto, uma lingua-
gem de alto nvel necessita de um programa chamado compilador que traduz um programa
em linguagem de alto nvel para um programa em linguagem de baixo nvel, de modo que o
Mark I pudesse execut-lo. Portanto, Grace Hopper tambm construiu o primeiro compilador
conhecido.
31
Grace Murray Hopper ( ), nascida nos Estados Unidos, cientista da computao e oficial da Marinha
dos Estados Unidos.
32
Alan Mathison Turing ( ), nascido na Inglaterra, matemtico, lgico e criptoanalista.
33
Esta afirmao chamada Tese de Church-Turing. Uma linguagem de programao ou um computador abs-
trato Turing-completo se satisfaz essa tese. Alonzo Church, um influente matemtico e lgico norte-americano,
foi seu orientador de doutorado.
34
David Hilbert ( ), nascido na Alemanha, reconhecido como um dos mais influentes matemticos
dos sculos XIX e XX.
35
Kurt Gdel ( ), nascido no Imprio Austro-Hngaro, lgico, matemtico e filsofo.
FACOM UFMS
8 B REVE HISTRIA DA COMPUTAO
De 1940 a 1960
FACOM UFMS
1.2 S CULO XX 9
43
Margittai Neumann Jnos Lajos ( ), nascido na ustria-Hungria, matemtico e erudito. John von
Neumann tem muitas contribuies em diversas reas. Como matemtico, foi assistente de David Hilbert. Na Ci-
ncia da Computao, alm da arquitetura de von Neumann, props os autmatos celulares. Mas, infelizmente,
tambm foi um dos cientistas a trabalhar no Projeto Manhatan, responsvel pelo desenvolvimento de armas nuclea-
res, tendo sido responsvel pela escolha dos alvos de Hiroshima e Nagazaki no Japo na Segunda Guerra Mundial,
onde explodiriam as primeiras bombas nucleares da histria e pelo clculo da melhor altura de exploso para que
uma maior destruio fosse obtida.
44
First Draft of a Report on the EDVAC.
FACOM UFMS
10 B REVE HISTRIA DA COMPUTAO
Nos anos 50, os computadores eram nada populares e pertenciam a algumas poucas uni-
versidades e ao governo norte-americano. No incio da dcada, John Eckert e John Mauchly
deixam a Universidade de Pensilvnia por problemas de patenteamento de suas invenes e
fundam sua prpria empresa de computadores, a E CKERT-M AUCHLY C OMPUTER C ORPORA -
TION. Em 1951 projetam o UNIVAC, de UNIVersal Automatic Computer, o primeiro computador
eletrnico comercial produzido em larga escala e que utilizava fita magntica. O primeiro UNI-
VAC foi vendido para o escritrio do censo populacional dos Estados Unidos. Mas devido ao
domnio da IBM, que em 1955 vendia mais computadores que o UNIVAC, a empresa de John
Eckert e John Mauchly passa por muitas dificuldades at ser fechada e vendida.
Em 1955 a B ELL L ABORATORIES, uma empresa de tecno-
logia fundada em 1925, produz o primeiro computador base
de transistores. Os transistores eram menores, mais rpidos e
aqueciam muito menos que as vlvulas, o que tornava com-
putadores base de transistores muito mais eficientes e con-
fiveis. Em 1957 a IBM anuncia que no usaria mais vlvulas
e produz seu primeiro computador contendo 2.000 transis-
tores. Em 1958, descobertas experimentais que mostravam
que dispositivos semicondutores podiam substituir as vlvu-
las e a possibilidade de produzir tais dispositivo em larga es-
cala, possibilitaram o surgimento do primeiro circuito inte- Figura 1.10: Circuito integrado.
grado, ou microchip, desenvolvido simultaneamente por Jack
FACOM UFMS
1.2 S CULO XX 11
De 1960 a 1980
FACOM UFMS
12 B REVE HISTRIA DA COMPUTAO
52
Do ingls time sharing processing.
53
Do ingls batch processing.
54
Niklaus E. Wirth (), nascido na Sua, engenheiro eletrnico e cientista da computao.
55
Dennis MacAlistair Ritchie (), nascido nos Estados Unidos, fsico e matemtico.
56
Do ingls compact disk.
57
William Henry Gates III (), nascido nos Estados Unidos, empresrio.
58
Paul Gardner Allen (), nascido nos Estados Unidos, empresrio.
59
Stephan Gary Wozniak (), nascido nos Estados Unidos, engenheiro da computao e filantropo.
60
Steven Paul Jobs (), nascido nos Estados Unidos, empresrio.
FACOM UFMS
1.2 S CULO XX 13
61
Do ingls personal computer PC.
FACOM UFMS
14 B REVE HISTRIA DA COMPUTAO
Ao mesmo tempo que a indstria dos computadores avanava, progressos notveis tam-
bm foram obtidos nos fundamentos da Computao, em grande parte devido a Donald
Knuth62 , a Stephen Cook63 e a Leonid Levin64 . Knuth autor do livro A Arte da Progra-
mao de Computadores (The Art of Computer Programming), uma srie em vrios volumes,
que contribuiu para o desenvolvimento e sistematizao de tcnicas matemticas formais para
a anlise rigorosa da complexidade computacional dos algoritmos e a popularizao da nota-
o assinttica. conhecido, a partir desses trabalhos, como o Pai da Anlise de Algoritmos.
Alm das contribuies fundamentais em Teoria da Computao, Knuth o criador do sistema
processador de textos TEX. Cook e Levin so conhecidos por terem demonstrado formalmente
a existncia do primeiro problema NP-completo: o problema da satisfabilidade de frmulas
booleanas. Isso significa que qualquer problema na classe NP pode ser transformado de ma-
neira eficiente, isto , pode ser reduzido em tempo polinomial por uma mquina de Turing
determinstica, para o problema de determinar se uma frmula booleana satisfatvel. Uma
conseqncia importante do Teorema de Cook-Levin que se existe um algoritmo determins-
tico eficiente, ou de tempo polinomial, que soluciona o problema da satisfabilidade de frmulas
booleanas, ento existe um algoritmo determinstico de tempo polinomial que soluciona todos
os problemas da classe NP. A contribuio desses dois pesquisadores tem um significado fun-
damental para toda a rea da Computao e pode ser traduzida informal e simplificadamente
como a necessidade que temos de saber se um problema ou no computvel de forma efici-
ente em uma mquina geral e abstrata. Esse problema conhecido como o Problema P versus
NP, um dos sete Millenium Problems65 do Clay Mathematics Institute of Cambridge.
62
Donald Ervin Knuth (), nascido nos Estados Unidos, cientista da computao, Professor Emrito de Arte
de Programao de Computadores da Universidade de Stanford.
63
Stephen Arthur Cook (), nascido nos Estados Unidos, matemtico e cientista da computao, University
Professor da Universidade de Toronto.
64
Leonid Anatolievich Levin (), nascido na Ucrnia, cientista da computao.
65
Este problema tem um prmio estabelecido de 1 milho de dlares para o(s) pesquisador(es) que o soluciona-
FACOM UFMS
1.2 S CULO XX 15
De 1980 a 2000
FACOM UFMS
16 B REVE HISTRIA DA COMPUTAO
Windows 2.0 disponibilizado. Nessa poca a A PPLE trava uma batalha judicial por cpia de
direitos autorais do sistema operacional do MacIntosh contra a M ICROSOFT, pelo sistema ope-
racional Windows 2.03 de 1988, e a H EWLETT-PACKARD, pelo sistema operacional NewWave
de 1989.
Em 1990 Tim Berners-Lee67 prope um sistema de hipertexto que o primeiro impulso da
Rede Mundial de Computadores68 . O primeiro provedor comercial de linha discada da Internet
torna-se ativo em 1991, quando a WWW disponibilizada para o pblico em geral como uma
ferramenta de busca.
Richard Stallman69 , em 1985, escreve o Manifesto GNU
que apresenta sua motivao para desenvolver o sistema
operacional GNU, o primeiro projeto de software livre pro-
posto. Desde meados dos anos 90, Stallman tem gastado
muito de seu tempo como um ativista poltico defendendo
o software livre, bem como fazendo campanha contra pa-
tentes de software e a expanso das leis de direitos au-
torais. Os mais destacados programas desenvolvidos por
Stallman so o GNU Emacs, o GNU Compiler Collection
(gcc) e o GNU Debugger (gdb). Inspirado pelo Minix, um
sistema operacional baseado no Unix voltado para o ensino,
Linus Torvalds70 projetou em 1991 um sistema operacional
para computadores pessoais chamado Linux. O Linux um
exemplo de destaque do que chamamos de software livre e
de desenvolvimento de cdigo aberto. Seu cdigo fonte, es- Figura 1.16: O smbolo do Linux.
crito na linguagem C, disponibilizado para qualquer pes-
soa usar, modificar e redistribuir livremente.
O sistema operacional MS-DOS teve seu fim na dcada de 90, em sua ltima verso co-
mercial 6.22, tendo sido completamente substitudo pelo bem sucedido Windows. A verso
3.0 do Windows vendeu 3 milhes de cpias em 1990. Em 1992, a verso 3.1 vendeu 1 milho
de cpias em apenas 2 meses depois de seu lanamento. J em 1997, aps o lanamento do
Windows 95 em 1995, Bill Gates reconhecido como o homem mais rico do mundo. Nessa
poca de exploso do uso dos sistemas operacionais da M ICROSOFT, os vrus de computa-
dor passaram a infestar cada vez mais computadores e a impor perdas cada vez maiores de
tempo, de recursos e de dinheiro s pessoas e empresas que os utilizavam. Um dos primeiros
e mais famosos vrus de computador o Monkey Virus, um vrus de setor de boot descoberto
no Canad em 1991, que se espalhou muito rapidamente pelos Estados Unidos, Inglaterra e
Austrlia. Seguiu-se ao Windows 95 o Windows 98 em 1998 e o Windows ME em 2000.
A Rede Mundial de Computadores e a Internet tambm mostram um desenvolvimento
destacado nessa poca. O ano de 1993 registra um crescimento espantoso da Internet e 50
servidores WWW j so conhecidos at aquele momento. Em 1994, os estudantes de douto-
rado em engenharia eltrica da Universidade de Stanford Jerry Yang71 e David Filo72 fundam
a Yahoo!, uma empresa de servios de Internet que engloba um portal de Internet, uma ferra-
67
Sir Timothy John Berners-Lee (), nascido na Inglaterra, fsico.
68
Do ingls World Wide Web WWW.
69
Richard Matthew Stallman (), nascido nos Estados Unidos, fsico, ativista poltico e ativista de software.
70
Linus Benedict Torvalds (), nascido na Finlndia, cientista da computao.
71
Jerry Chih-Yuan Yang (), nascido em Taiwan, engenheiro eltrico e empresrio.
72
David Filo (?), nascido nos Estados Unidos, engenheiro da computao e empresrio.
FACOM UFMS
1.2 S CULO XX 17
menta de busca na Internet, servio de e-mail, entre outros. A Yahoo! obtm grande sucesso
entre usurios e em outubro de 2005 sua rede de servios espalhada pelo mundo recebe em
mdia 3,4 bilhes de visitas por dia. Em 1994, o World Wide Web Consortium W3C fundado
por Tim Berners-Lee para auxlio no desenvolvimento de protocolos comuns para avaliao da
Rede Mundial de Computadores. O Wiki foi criado em 1995 pelo Repositrio Padro de Por-
tland, nos Estados Unidos, e um banco de dados aberto edio, permitindo que qualquer
usurio possa atualizar e adicionar informao, criar novas pginas, etc., na Internet. Nesse
mesmo ano, a S UN M ICROSYSTEMS lana a linguagem de programao orientada a objetos
Java, amplamente utilizada hoje em dia para criar aplicaes para a Internet. Os rudimentos
da ferramenta de busca Google so desenvolvidos em 1996 como um projeto de pesquisa dos
alunos de doutorado Larry Page73 e Sergey Brin74 da Universidade de Stanford. Em 1998 a
pgina do Google disponibilizada na Internet e, atualmente, a ferramenta de busca mais
utilizada na rede. A WebTV tambm disponibilizada em 1996 possibilitando aos usurios
navegar pela Internet a partir de sua TV.
Com relao aos dispositivos eletrnicos, o Barramento Serial Universal USB75 padroni-
zado em 1995 pela I NTEL, C OMPAQ, M ICROSOFT, entre outras. O USB um barramento externo
padronizado que permite transferncia de dados e capaz de suportar at 127 dispositivos pe-
rifricos. Em 1997 o mercado comea a vender uma nova mdia de armazenamento tico de
dados, o Disco Verstil Digital DVD76 , com as mesmas dimenses do CD, mas codificado
em um formato diferente com densidade muito mais alta, o que permite maior capacidade de
armazenamento. Os DVDs so muito utilizados para armazenar filmes com alta qualidade de
som e vdeo. Em 1998 o primeiro tocador de MP3, chamado de MPMan, vendido no Japo
pela empresa S AEHAN. A dcada de 90 tambm marcada pela unio, compra e venda de di-
versas empresas de computadores. A indstria de jogos para computadores pessoais tambm
teve seu crescimento acentuado nessa poca.
Os processadores tambm foram vendidos co-
mo nunca nos anos 90. A I NTEL lana em 1993 o
sucessor do INTEL 486, conhecido como Pentium,
ou Pentium I, de 32 bits, 60 MHz e 3,1 milhes de
transistores em sua verso bsica. A partir de 1997,
a I NTEL lana seus processadores seguidamente,
ano aps ano. Em 1997 anuncia a venda dos pro-
cessadores Pentium MMX e Pentium II. O Celeron
produzido a partir de 1998 e em 1999, a I NTEL
anuncia o incio da produo do Pentium III. O
Pentium IV produzido a partir de 2000 e um
processador de 32 bits, 1,4 GHz e 42 milhes de
transistores. A AMD j produzia microprocessa-
dores desde a dcada de 70, mas entrou em forte
concorrncia com a I NTEL a partir dessa poca,
com o lanamento do K5 em 1995, concorrente do
Figura 1.17: Processador Pentium.
Pentium I, de 32 bits, 75 MHz e 4,3 milhes de tran-
sistores em sua primeira verso. Seguiu-se ao K5
73
Lawrence Edward Page (), nascido nos Estados Unidos, engenheiro da computao e empresrio.
74
Sergey Brin (), nascido na Rssia, matemtico, cientista da computao e empresrio.
75
Do ingls Universal Serial Bus.
76
Do ingls Digital Versatile Disc.
FACOM UFMS
18 B REVE HISTRIA DA COMPUTAO
o K6 em 1997, de 32 bits, 66 MHZ e 8,8 milhes de transistores, e a srie K7 de 1999, que en-
globa os processadores Athlon e Duron. A partir da dcada de 90, uma fatia considervel das
fbricas produz computadores pessoais com processadores da I NTEL ou da AMD. No incio da
dcada de 90, A PPLE, IBM e M OTOROLA se unem para projetar o processador PowerPC de 32
bits que equipou o PowerMac da A PPLE a partir de 1994. A aceitao desse novo computador
no foi como o esperado e, aps um perodo de baixas, a A PPLE ressurge em 1998 com o iMac,
um computador pessoal com projeto visual arrojado e com a filosofia do tudo-em-um-s. A
dcada de 90 marcada pela facilidade de acesso aos computadores pessoais, j que muitos
deles passam a ser vendidos por menos que 1.000 dlares.
De 2000 at hoje
O ano de 2000 inicia receoso para governos e empresas pelo medo das conseqncias po-
tencialmente desastrosas da virada do sculo nos sistemas computacionais, o que se chamou na
poca de Bug do Milnio. Alm disso, o juiz Thomas Penfield anuncia a diviso do imprio
M ICROSOFT em duas companhias com Bill Gates deixando o cargo de Executivo-Chefe.
A M ICROSOFT lana o Windows XP em 2001, o Windows Vista, em janeiro de 2007 e re-
centemente o Windows 7 em 2009. A A PPLE disponibiliza o MacOS X 10.0 em 2001 e segui-
das novas atualizaes at 2009, com o MAC OS X 10.6. O Linux tem maior penetrao e
aceitao dos usurios de computadores pessoais e diversas distribuies so disponibilizadas
como Ubuntu, Mandriva Linux, Fedora Core e SUSE Linux. Estas distribuies e os projetos
comunitrios Debian e Gentoo, montam e testam os programas antes de disponibilizar sua
distribuio. Atualmente, existem centenas de projetos de distribuio Linux em ativo desen-
volvimento, constantemente revisando e melhorando suas respectivas distribuies.
Em 2001 a D ELL passa a ser a maior fabricante de computadores pessoais do mundo. Em
2002, uma empresa de consultoria norte-americana faz uma estimativa que at aquele ano
aproximadamente 1 bilho de computadores pessoais tinham sido vendidos no mundo inteiro
desde sua consolidao.
A I NTEL tem investido mais recentemen-
te sua produo em processadores de 64 bits
com ncleos mltiplos, como por exemplo
o Xeon de 2004, o Pentium D de 2005, o
INTEL Core 2 Duo e o INTEL Core 2 Quad
de 2008. A AMD produz os processadores de
64 bits Duron em 2000 e o Sempron em 2004,
ambos da srie K7, e o Opteron em 2003 da
srie K8, este ltimo um processador de dois
ncleos, para competir com os processado-
res de mltiplos ncleos, como o Xeon da I N -
TEL. Em seguida, lana a srie K10 chamada
Phenom, com 2, 3 e 4 ncleos. A A PPLE, que
vinha utilizando o processador PowerPC em
sua linha de iMacs, anuncia que a partir de
2006 comear a usar os processadores da
I NTEL. A verso de 2006 do iMac usa o Figura 1.18: Phenom X4 da AMD.
processador INTEL Core 2 Duo. Na lista dos
FACOM UFMS
1.2 S CULO XX 19
Figura 1.19: Cray XT5-HE Opteron Six Core 2.6 GHz, o computador mais rpido do mundo
na lista TOP500 de 2009, instalado no Oak Ridge National Laboratory. Usa o processador AMD
x86_64 Opteron Six Core 2600 MHz de 10,4 GFlops e o sistema operacional Linux.
FACOM UFMS
20 B REVE HISTRIA DA COMPUTAO
Exerccios
1.1 Visite a pgina do Computer History Museum, que contm uma enorme quantidade de
informaes sobre esses dispositivos.
1.3 Leia os verbetes associados s duas mulheres que tm papel importante na Histria da
Computao: Augusta Ada Byron e Grace Murray Hopper.
1.4 Leia o verbete sobre Alan Mathison Turing, o Pai da Cincia da Computao, na Wi-
kipedia. Aproveite para ler o pedido formal de desculpas feito em 2009 pelo Primeiro-
ministro da Inglaterra, Gordon Brown, e para vasculhar a pgina com as festividades do
centenrio de seu nascimento em 2012.
1.5 Leia uma apresentao simples e motivadora do problema P versus NP na pgina do Clay
Mathematics Institute.
1.6 Leia o verbete Cook-Levin Theorem na Wikipedia e tente entender informalmente o que ele
realmente quer dizer.
1.7 Visite a pgina GNU Operating System e leia o verbete GNU na Wikipedia e veja como este
sistema vem se desenvolvendo ao longo do tempo.
1.8 Visite as pginas Free Software Foundation, Fundao Software Livre Amrica Latina e o
portal de software livre (Portal: Free Software) da Wikipedia. Procure saber quais projetos
mantidos por esta fundao mais lhe interessou.
1.9 Leia o verbete Linux na Wikipedia, o sistema operacional que usamos na universidade.
1.10 Visite a pgina TOP500 para obter informaes dos computadores mais rpidos hoje exis-
tentes.
FACOM UFMS
AULA 2
I NTRODUO COMPUTAO
Na aula 1 vimos um pequeno histrico sobre a Computao. Nesta aula, vamos mencionar
brevemente como essas mquinas so organizadas internamente alm de invertigarmos o con-
ceito de algoritmo e programa. Como veremos, John von Neumann foi o responsvel, em 1945,
pelo desenvolvimento de um modelo1 de computador que sobrevive at hoje.
Este texto baseado principalmente nas referncias [8, 9, 10].
2.1 Contextualizao
21
22 I NTRODUO COMPUTAO
se tambm s discusses do projeto desse novo computador e ficou responsvel por redigir o
documento com a descrio dessas idias. Com a publicao desse trabalho [14]5 , divulgado
contendo apenas seu nome, essa organizao interna de um computador passou a ser conhe-
cida como arquitetura de von Neumann, apesar de Turing, Zuse, Eckert e Mauchly terem
contribudo ou j apresentado idias semelhantes. Esse trabalho obteve grande circulao no
meio acadmico e seu sucesso como proposta de implementao de um novo computador foi
imediato. At nossos dias, essa organizao ainda usada nos projetos de computadores mais
conhecidos.
As idias publicadas por John von Neumann foram revolucionrias a ponto de estabelecer
um novo paradigma de concepo de computadores para a poca e que permanece vlido at
os nossos dias. Informalmente, a maneira de organizar os componentes que constituem um
computador chamada arquitetura do computador. Assim, como a maioria dos computadores
atuais segue o modelo proposto por von Neumann, veremos aqui uma breve descrio da
assim chamada arquitetura de von Neumann.
Nesse modelo, um computador constitudo por trs componentes principais: (i) a unidade
central de processamento ou UCP6 , (ii) a memria e (iii) os dispositivos de entrada e sada.
A UCP, por sua vez, composta pela unidade lgico-aritmtica ou ULA e pela unidade de
controle ou UC. Esses trs componentes principais esto conectados e se comunicam atravs
de linhas de comunicao conhecidas como barramento do computador.
Podemos ilustrar a arquitetura de von Neumann como na figura 2.1.
1111111111111111
0000000000000000
0000000000000000
1111111111111111
0000000000000000
1111111111111111
0000000000000000
1111111111111111
memria
0000000000000000
1111111111111111
0000000000000000
1111111111111111
0000000000000000
1111111111111111
11111111
00000000
00000000UCP
11111111
00000000
11111111
000
111 00
11
00000000
11111111
000
111 00
11
00000000
11111111
000
111
UC
00
11
ULA
00000000
11111111
000
111 00
11
00000000
11111111
00000000
11111111
00000000
11111111
1111
0000 11111
00000
0000
1111
0000
1111 00000
11111
00000
11111
0000
1111 00000
11111
0000
1111
entrada
0000
1111 00000
11111
sada
00000
11111
0000
1111
0000
1111 00000
11111
00000
11111
Figura 2.1: Arquitetura de von Neumann.
FACOM UFMS
2.2 A RQUITETURA DE VON N EUMANN 23
FACOM UFMS
24 I NTRODUO COMPUTAO
Uma outra representao a arquitetura de von Neumann, mais prxima ao que conhecemos
como um computador pessoal, pode ser vista na figura 2.2.
impressora
1111
0000 1
0 1
0
0
10
1 1111
0000
disco
0000
1111 0
1 0
1
0
10
1 0000
1111
rgido
0000
1111 0
1 0
1
0
10
1 0000
1111
mouse portas
0000
1111 0
1 0
1
0
10
1 placa
0000
1111
0000
1111 0
1 0
1
0
10
1 de disco
0000
1111
0
1 0
1
0
10
1
0
1 0
1
0
10
1 DVD-RW
teclado 0
1 0
1
0
10
1
0
1 0
1
0
10
1
0
1 0
1
0
10
1
0
1 0
1
0
10
1
1111
0000 0
1 0
1
0
10
1 1111
0000
0000
1111 0
1 0
1
0
10
1 0000
1111
placa
0000
1111
UCP 0
1 0
1
0
10
1 0000
1111 monitor
0000
1111 0
1 0
1
0
10
1 grfica
0000
1111
0
1 0
1
0
10
1
0
1 0
1
0
10
1
0
1 0
1
0
10
1
0
1 0
1
0
10
1
0
1 0
1
0
10
1
1111
0000 0
1 0
1
0
10
1 1111
0000
0000
1111 0
1 0
1
0
10
1 0000
1111
placa caixas
memria
0000
1111 0
1 0
1
0
10
1 0000
1111
0000
1111 0
1 0
1
0
10
1 de som
0000
1111 de som
0
1 0
1
0
10
1
0
1 0
1
0
10
1
0
1 0
1
0
10
1
0
1 0
1
0
10
1
0
1 0
1
0
10
1
0
1 0
1
0
10
1
0
1 0
1
0
10
1 1111
0000
0
1 0
1
0
10
1 0000
1111
placa
0
1 0
1
0
10
1 0000
1111
de rede
internet
0
1 0
1
0
10
1 0000
1111
0
1 0
1
0
10
1
0
1 0
1
0
10
1
barramento
H uma certa controvrsia sobre como definir de maneira formal um algoritmo. Informal-
mente, podemos dizer que um algoritmo uma seqncia precisa, sistemtica e finita de passos
ou instrues para soluo de algum problema. Uma tentativa de formalizao do termo teve
incio com a tentativa de soluo do problema Entscheidungsproblem, ou o problema da deciso,
proposto por David Hilbert9 em 1928. O termo algoritmo, como mencionamos na aula 1,
tem sua origem no cientista persa Muh.ammad ibn Musa al-Khwarizm10 . A latinizao de
seu nome deu origem ao termo algoritmo e algarismo na lngua portuguesa. Suas principais
contribuies incluem inovaes importantes na matemtica, em especial em lgebra e trigono-
metria. Um de seus mais importantes livros, Sobre o Clculo com Nmeros Hindus, do ano
de 825, foi responsvel pela disseminao do sistema hindu-arbico de numerao no Oriente
Mdio e na Europa.
9
David Hilbert ( ), nascido na Alemanha, reconhecido como um dos mais influentes matemticos
dos sculos XIX e XX.
10
Abu Abdalla Muh.ammad ibn Musa al-Khwarizm ( ), nascido na Prsia, matemtico, astrnomo e
gegrafo.
FACOM UFMS
2.3 A LGORITMOS E PROGRAMAS 25
Garantia de trmino: o problema a ser resolvido possui condies especficas que, quando
satisfeitas, a execuo do algoritmo encerrada e o problema ento tido como resol-
vido. Alm disso, estas condies devem ser satisfeitas aps uma quantidade finita de
tempo, a ser contado a partir do incio da execuo do algoritmo;
Efetividade: cada instruo deve ser bsica o suficiente para ser executada, pelo menos
em princpio, por qualquer agente usando apenas lpis e papel.
Lidamos com algoritmos desde nossa infncia em diversas situaes. Por exemplo, apren-
demos no ensino primrio o algoritmo de Euclides para obteno do mximo divisor comum
entre dois nmeros inteiros. Inicialmente, tomamos dois nmeros inteiros a e b. Se b = 0 ento
o mximo divisor comum entre a e b o nmero a. Caso contrrio, o mximo divisor comum
entre a e b dado pelo mximo divisor comum de b e do resto da diviso de a por b. O processo
ento se repete at que b seja igual a 0 (zero). Esquematicamente, podemos escrever a seguinte
seqncia de instrues para resolver o problema:
PASSO 3 Se r igual a zero ento o mximo divisor comum igual a b e a execuo das instru-
es encerra aqui. Caso contrrio, siga para a prxima instruo.
FACOM UFMS
26 I NTRODUO COMPUTAO
Um outro exemplo de instruo que no pode fazer parte de um algoritmo Escreva todos
os nmeros mpares. Neste caso, temos uma instruo que no pode ser executada porque
a execuo nunca terminar, apesar de sabermos exatamente como determinar os nmeros
mpares. Observe que se modificssemos a instruo para Escreva todos os nmeros mpares
menores do que 100, ela poderia, perfeitamente, fazer parte de um algoritmo.
Um problema para o qual existe uma soluo na forma de algoritmo dito um problema
algortmico. O problema de encontrar o mximo divisor comum de dois nmeros naturais
quaisquer , portanto, um problema algortmico. Problemas algortmicos, em geral, possuem
muitas ocorrncias. Por exemplo, para o problema de encontrar o mximo divisor comum de
dois nmeros naturais, cada ocorrncia uma dupla distinta de nmeros naturais cujo mximo
divisor comum queremos encontrar. Um algoritmo dito correto quando ele sempre termina e
produz a resposta correta para todas as ocorrncias de um dado problema.
Algoritmo, ento, pode ser imaginado como a especificao de um processo mecnico
que, quando executado, leva-nos soluo de algum problema. Embora o termo algoritmo
esteja relacionado intimamente com Computao, algoritmos tm sido parte de nossas vidas
desde a primeira vez que uma pessoa explicou para outra como fazer alguma coisa. As pes-
soas utilizam algoritmos quando seguem receitas culinrias ou instrues para programar um
tocador de msicas. Entretanto, nem todo algoritmo pode ser executado por um computador.
Um computador pode executar apenas aqueles algoritmos cujas instrues envolvam tarefas
que ele possa entender e executar. Este no o caso, por exemplo, de instrues como corte o
fil em cubos e ligue o tocador de msica.
Computadores executam algoritmos que manipulam apenas dados e no coisas fsicas, tais
como fil e tocador de msica. A execuo de um algoritmo por um computador denominada
processamento de dados e consiste de trs partes: uma entrada, um processo ou processamento
e uma sada. A entrada um conjunto de informaes que requisitada para que as instrues
do algoritmo possam ser executadas. O processamento a seqncia de instrues que compe
o algoritmo. E a sada o resultado obtido com a execuo do processo para a entrada forne-
cida. Por exemplo, a entrada e a sada para uma computao do algoritmo para o problema
de encontrar o mximo divisor comum de dois nmeros naturais so, respectivamente, dois
nmeros naturais e o mximo divisor comum entre eles.
Quando escrevemos algoritmos para serem executados por computador, temos de fazer
algumas suposies sobre o modelo de computao entradaprocessamentosada. A primeira
delas que, a fim de realizar qualquer computao, o algoritmo deve possuir um meio de
obter os dados da entrada. Esta tarefa conhecida como leitura da entrada. A segunda, que o
algoritmo deve possuir um meio de revelar o resultado da computao. Isto conhecido como
escrita dos dados da sada. Todo e qualquer computador possui dispositivos atravs dos quais
a leitura e a escrita de dados so realizadas.
FACOM UFMS
2.3 A LGORITMOS E PROGRAMAS 27
Teste de qualidade: executar o algoritmo desenvolvido com uma entrada para a qual o
resultado seja conhecido;
Talvez, o fator mais determinante para o sucesso em resolver um problema seja a abstra-
o. Abstrao12 alguma coisa independente de qualquer ocorrncia particular ou o processo
de identificar certas propriedades ou caractersticas de uma entidade material e us-las para
especificar uma nova entidade que representa uma simplificao da entidade da qual ela foi
derivada. Esta nova entidade o que chamamos de abstrao.
Para entender o papel da abstrao na resoluo de problemas, considere a seguinte ocor-
rncia de um problema que lembra nossos tempos de criana:
Maria tinha cinco mas e Joo tinha trs. Quantas mas eles tinham juntos?
Provavelmente, um adulto resolveria este problema fazendo uma abstrao das mas como
se elas fossem os nmeros 5 e 3 e faria a soma de tais nmeros. Uma criana poderia imaginar
as cinco mas de Maria como cinco palitinhos e as trs de Joo como trs palitinhos. Da,
faria uma contagem dos palitinhos para chegar soluo. Em ambos os casos, os elementos
do problema foram substitudos por outros (nmeros e palitinhos) e a soluo foi encontrada
atravs da manipulao dos novos elementos.
12
Segundo o Websters New Dictionary of American Language.
FACOM UFMS
28 I NTRODUO COMPUTAO
O processo de abstrao pode ser visto como constando de nveis. Isto diz respeito ao grau
de simplificao de uma abstrao. Por exemplo, se a planta de uma casa entregue a um
experiente mestre-de-obras sem meno de, por exemplo, como fazer uma mistura ideal de
cimento para fundao, provavelmente, isso no ser um problema para ele. Entretanto, se a
mesma planta da casa for entregue a um advogado, ele certamente no saber construir a casa.
Isso quer dizer que a planta da casa dada ao advogado deveria conter maiores detalhes do
processo de construo da casa do que aquela dada para o mestre-de-obras. Aqui, a planta da
casa uma abstrao e o nvel de detalhe da planta proporcional ao nvel de simplificao da
abstrao.
Algoritmos bem projetados so organizados em nveis de abstrao, pois um mesmo al-
goritmo deve ser entendido por pessoas com diferentes graus de conhecimento. Quando um
algoritmo est assim projetado, as instrues esto organizadas de tal forma que podemos en-
tender o algoritmo sem, contudo, ter de entender os detalhes de todas as instrues de uma s
vez. Para tal, o processo de construo de algoritmos conta com ferramentas, tais como mdu-
los, que agrupam instrues que realizam uma determinada tarefa no algoritmo, independente
das demais, tal como fazer a leitura da entrada, dispensando-nos de entender o detalhe de cada
instruo separadamente, mas sim fornecendo-nos uma viso da funcionalidade do grupo de
instrues.
FACOM UFMS
2.3 A LGORITMOS E PROGRAMAS 29
ADD CL,BH
Esta instruo equivale a seguinte sequncia de dois bytes na linguagem de mquina do pro-
cessador INTEL 8088:
00000010 11001111
FACOM UFMS
30 I NTRODUO COMPUTAO
111111
000000
000000
111111
000000
111111
000000
111111
algoritmo
000000
111111
000000
111111
000000
111111
0
1
0
1
0
1
0 programao
1
0
1
0
1
000000
111111
000000
111111
programa na
000000
111111
linguagem
000000
111111
000000
111111
0
1
000000
111111
X
0
1
0
1
0
1
0 compilao
1
0
1
0
1
000000
111111
000000
111111
000000
111111
programa
000000
111111
assembly
000000
111111
000000
111111
0
1
0
1
0
1
0
1 montagem
0
1
000000
111111
0
1
000000
111111
000000
111111
programa em
000000
111111
linguagem
000000
111111
000000
111111
de mquina
000000
111111
Figura 2.3: Passos desde a concepo de um algoritmo at o programa executvel por um
computador.
Exerccios
2.1 Leia o verbete Computer na Wikipedia, que traz muitas informaes sobre essas mquinas.
2.2 Leia o verbete von Neumann architecture na Wikipedia, sobre o modelo de organizao
interna de computadores mais conhecido.
2.3 D uma olhada no trabalho de John von Neumann na referncia [14]13 , sobre a arquite-
tura de von Neumann.
2.4 D uma olhada no trabalho de Alan Turing na referncia [11]14 com a descrio da m-
quina de Turing.
2.6 Sobre a linguagem de programao que adotaremos neste curso, visite as pginas
C History e C Programming Language e leia o verbete C (programming language) na Wiki-
pedia.
13
Artigo disponvel na seo Bibliografia complementar na pgina da disciplina no Moodle.
14
Artigo disponvel na seo Bibliografia complementar na pgina da disciplina no Moodle.
FACOM UFMS
AULA 3
D ICAS INICIAIS
Nesta aula aprenderemos dicas importantes sobre as ferramentas que mais usaremos du-
rante o desenvolvimento da parte prtica da disciplina. Em particular, veremos a definio de
uma interface do sistema operacional (shell ou Unix shell) e aprenderemos a usar alguns dentre
os tantos comandos disponveis para essa interface, aprenderemos alguns comandos e funes
do ambiente de trabalho GNU/Emacs e aprenderemos a usar o compilador da linguagem C da
coleo de compiladores GNU, o GCC .
Podemos definir uma interface de um sistema como um programa que permite a intera-
o entre o sistema e seus usurios. Dessa forma, diversos sistemas contm interfaces desse
tipo. No entanto, esse termo quase que automaticamente associado aos sistemas operacio-
nais, onde uma interface fornecida aos usurios para acesso aos servios do ncleo do sis-
tema operacional. As interfaces dos sistemas operacionais so freqentemente usadas com o
propsito principal de invocar outros programas, mas tambm possuem outras habilidades
adicionais.
H em geral dois tipos de interfaces de sistemas operacionais: as interfaces de linhas de
comando e as interfaces grficas. Neste curso, usaremos as interfaces de linhas de comando
para solicitar servios e executar certos programas nativos do sistema operacional Linux. A
seguir listamos alguns desses comandos.
Antes de mais nada, necessrio saber duas coisas sobre o sistema que temos instalado
em nossos laboratrios. Primeiro, devemos saber que o sistema operacional instalado nesses
computadores o Linux. A distribuio escolhida a Debian, verso Lenny. Essa e uma dis-
tribuio no comercial e livre do GNU/Linux, isto , uma verso gratuita e de cdigo fonte
aberto. O nome Debian vem dos nomes dos seus fundadores, Ian Murdock e de sua esposa,
Deb ra. Diversas distribuies comerciais baseiam-se, ou basearam-se, na distribuio Debian,
como Linspire, Xandros, Kurumin, Debian-BR-CDD, Ubuntu e Libranet. A segunda informa-
o importante sobre a interface grfica do Linux usada nos laboratrios. A interface grfica
completa do ambiente de trabalho a plataforma GNOME . Essa plataforma um projeto co-
laborativo internacional inteiramente baseado em software livre que inclui o desenvolvimento
de arcabouos, de seleo de aplicaes para o ambiente de trabalho e o desenvolvimento de
programas que gerenciam o disparo de aplicaes, manipulao de arquivos, o gerenciamento
de janelas e de tarefas. O GNOME faz parte do Projeto GNU e pode ser usado com diversos
sistemas operacionais do tipo Unix, especialmente aqueles que possuem um ncleo Linux.
31
32 D ICAS INICIAIS
Isso posto, um dos programas mais comuns disponveis para os usurios do sistema ope-
racional GNU/Linux chamado de terminal, como uma abreviao de terminal de linhas de
comando, que nada mais que uma interface entre o usurio e o sistema operacional. Para
disparar esse programa no gerenciador de janelas GNOME, selecione a opo Aplicaes do
menu principal, depois a opo Acessrios no sub-menu e, em seguida, a opo Terminal.
Um exemplo de uma janela de terminal de linhas de comando do GNOME apresentado na
figura 3.1.
Figura 3.1: Uma interface, ou janela, de linhas de comandos do sistema de janelas GNOME,
chamada no computador Homer pelo usurio fhvm. Esses nomes compem o sinal de pronto
do sistema.
FACOM UFMS
3.1 I NTERFACE DO SISTEMA OPERACIONAL 33
Dessa forma, para aprender gradativa e corretamente a usar os comandos e utilitrios apre-
sentados na tabela 3.1 necessrio: (i) fazer os exerccios ao final desta aula; (ii) usar com
freqncia o utilitrio man ou info , que so interfaces para o manual de referncia dos co-
mandos e ferramentas do sistema1 . Por exemplo, podemos digitar:
ou
prompt$ ls *.c
prompt$ ls ???.c
FACOM UFMS
34 D ICAS INICIAIS
Comando Descrio
cat arq mostra o contedo de arq ou da entrada padro
cd dir troca o diretrio atual para o diretrio dir
cmp arq1 arq2 compara arq1 e arq2 byte a byte
cp arq1 arq2 copia o arq1 para o arq2
cp arq(s) dir copia arq(s) para o diretrio dir
date mostra a data e a hora do sistema
diff arq1 arq2 compara arq1 e arq2 linha a linha
echo args imprime args
enscript arq converte arquivos-texto para PostScript, HTML, RTF, ANSI e outros
fmt arq formata arq
gprof arq fornece um perfil de execuo do programa arq
indent arq faz a indentao correta de um programa na linguagem C em arq
info cmd mostra a pgina (mais completa) de manual de cmd
ls arq(s) lista arq(s)
ls dir lista os arquivos no diretrio dir ou no diretrio atual
man cmd mostra a pgina de manual de cmd
mkdir dir(s) cria diretrio(s) dir(s)
mv arq1 arq2 move/renomeia o arq1 para o arq2
mv arq(s) dir move arq(s) para o diretrio dir
pwd mostra o nome do diretrio atual
pr arq converte arq, do tipo texto, para impresso
rm arq(s) remove arq(s)
rmdir dir(s) remove diretrios vazios dir(s)
sort arq(s) ordena as linhas de arq(s) ou da entrada padro
wc arq(s) conta o nmero de linhas, palavras e caracteres em arq(s) ou na entrada padro
who imprime a identificao do usurio do computador
prompt$ ls *[abc]
o argumento *[abc] representa todos os arquivos do diretrio cujos nomes terminam com o
caractere a , b ou c .
Um intervalo de caracteres pode ser obtido no interior dos colchetes se o caractere -
usado. Por exemplo:
FACOM UFMS
3.1 I NTERFACE DO SISTEMA OPERACIONAL 35
prompt$ ls *[a-z]
onde o argumento representa os nomes dos arquivos que terminam com uma das 26 letras do
alfabeto.
Por fim, importante destacar que muitos comandos do sistema operacional recebem infor-
maes de entrada a partir do terminal e tambm enviam as informaes resultantes de sada
para o terminal de comandos. Um comando em geral l as informaes de entrada de um lo-
cal chamado de entrada padro, que pr-definido como o terminal de linha de comandos, e
escreve sua sada em um local chamado de sada padro, que tambm pr-definido como o
terminal de linhas de comando.
Por exemplo, o comando sort pode ordenar nomes fornecidos linha a linha por um usu-
rio no terminal de comandos, ordenar esses nomes lexicograficamente e apresentar o resultado
no terminal de linha de comandos:
prompt$ sort
Zenaide
Carlos
Giovana
Amanda
Ctrl-d
Amanda
Carlos
Giovana
Zenaide
prompt$
Se dispomos os caracteres > arq ao final de qualquer comando ou utilitrio que normal-
mente envia sua sada para a sada padro, ou seja, para o terminal de linha de comandos,
o sada desse comando ser escrita para o arquivo com nome arq ao invs do terminal. Por
exemplo, a seqncia a seguir:
faz com que quatro nomes digitados pelo usurio sejam ordenados e, em seguida, armazenados
no arquivo nomes.txt .
Assim como a sada pode ser redirecionada para um arquivo, a entrada tambm pode ser
redirecionada a partir de um arquivo. Se, por exemplo, existe um arquivo temp.txt contendo
diversos nomes apresentados linha a linha, ento o comando a seguir:
FACOM UFMS
36 D ICAS INICIAIS
faz com que todos os nomes contidos no arquivo temp.txt sejam ordenados lexicografica-
mente e posteriormente apresentados seguida na sada padro, isto , na janela do terminal de
linha de comandos.
Podemos ainda redirecionar a entrada e a sada de um comando concomitantemente. Por
exemplo, o comando:
3.2 Compilador
FACOM UFMS
3.3 E MACS 37
onde gcc o programa compilador, programa.c um arquivo com extenso .c que contm
um programa fonte na linguagem C, -o uma opo do compilador que permite fornecer um
nome ao programa executvel resultante do processo ( executvel ), -Wall uma opo que
solicita que o compilador mostre qualquer mensagem de erro que ocorra durante a compilao,
-ansi uma opo que fora o programa fonte a estar escrito de acordo com o padro ANSI
da linguagem C e -pedantic uma opo que deixa o compilador muito sensvel a qualquer
possvel erro no programa fonte.
No momento, ainda no escrevemos um programa na linguagem C e, por isso, no con-
seguimos testar o compilador de forma satisfatria. Esta seo ento apenas um guia de
referncia rpida que ser muito usada daqui por diante.
3.3 Emacs
FACOM UFMS
38 D ICAS INICIAIS
Teclas Descrio
C-z minimiza a janela do Emacs
C-x C-c finaliza a execuo do Emacs
C-x C-f carrega um arquivo no Emacs
C-x C-s salva o arquivo atual no disco
C-x i insere o contedo de um outro arquivo no arquivo atual
C-x C-w salva o contedo do arquivo em um outro arquivo especificado
C-h r carrega o manual do Emacs
C-h t mostra um tutorial do Emacs
C-g aborta o comando parcialmente informado
C-s busca uma cadeia de caracteres a partir do cursor
C-r busca uma cadeia de caracteres antes do cursor
M-% interativamente, substitui uma cadeia de caracteres
importante observar que o Emacs, quando executado em sua interface grfica, tem a
possibilidade de executar muitos de seus comandos atravs de botes do menu ou atravs da
barra de menus. No entanto, usurios avanados preferem usar os atalhos de teclado para esse
tipo de execuo, por terem um acesso mais rpido e mais conveniente depois da memorizao
dessas seqncias de teclas.
Exerccios
3.1 Abra um terminal. A partir de seu diretrio inicial, chamado de home pelo sistema ope-
racional, faa as seguintes tarefas:
FACOM UFMS
3.3 E MACS 39
digite um texto que resume o que voc aprendeu nas aulas de Algoritmos e Progra-
mao I at aqui;
salve o arquivo no diretrio algprogi/teoricas;
busque as palavras computador, Turing, von Neumann, ENIAC, ls, cp e Emacs no
seu texto;
troque a palavra Emacs no seu texto pela palavra GNU/Emacs.
FACOM UFMS
40 D ICAS INICIAIS
FACOM UFMS
AULA 4
P RIMEIROS PROGRAMAS
4.1 Digitando
Abra o seu Emacs, pressione C-x C-f , digite em seguida um nome para seu primeiro
programa, como por exemplo primeiro.c, e ento digite o seguinte cdigo.
int main(void)
{
printf("Programar bacana!\n");
return 0;
}
Depois de ter digitado o programa, pressione as teclas C-x C-s para salv-lo em um dire-
trio adequado da sua rea de trabalho. Na linguagem C, letras minsculas e maisculas so
diferentes. Alm disso, em programas na linguagem C no h distino de onde voc inicia a
digitao das suas linhas e, assim, usamos essa caracterstica a nosso favor, adicionando espa-
os em algumas linhas do programa para facilitar sua leitura. Essa adio de espaos em uma
linha chamada indentao ou tabulao. No Emacs, voc pode usar a tecla Tab para adicio-
nar indentaes de forma adequada. Veremos que a indentao uma prtica de programao
muito importante.
Abra um terminal onde possa digitar comandos, solicitando ao sistema operacional que os
execute. Ento, compile o programa 4.1 com o compilador gcc:
41
42 P RIMEIROS PROGRAMAS
Depois disso, o programa executvel a.out estar disponvel para execuo no mesmo
diretrio. Assim, s digitar a.out (ou ./a.out) para ver o resultado da execuo:
prompt$ ./a.out
Programar bacana!
prompt$
O nome a.out um nome padro que o compilador gcc d aos arquivos executveis resul-
tantes de uma compilao. Em geral, atribumos um nome mais significativo a um programa
executvel, como por exemplo o mesmo nome do programa na linguagem C, mas sem a sua
extenso. No exemplo acima, o programa executvel associado tem o nome primeiro. O com-
pilador gcc pode gerar um executvel dessa forma como segue:
#include <stdio.h>
ser muito provavelmente includa em todo programa que voc far na linguagem C. Essa
linha fornece informaes ao compilador sobre a funo de sada de dados de nome printf ,
que usada depois no programa.
A segunda linha do programa
int main(void)
informa ao compilador onde o programa inicia de fato. Em particular, essa linha indica que
main , do ingls principal, o incio do programa principal e, mais que isso, que esse trecho do
programa na verdade uma funo da linguagem C que no recebe valores de entrada ( void )
e devolve um valor do tipo inteiro ( int ). Esses conceitos de funo, parmetros de uma
funo e valor de sada sero elucidados oportunamente. Por enquanto, devemos memorizar
que essa linha indica o incio de nosso programa.
A prxima linha contm o smbolo abre-chave { que estabelece o incio do corpo do pro-
grama. Em seguida, a prxima linha contm uma chamada funo printf :
printf("Programar bacana!\n");
FACOM UFMS
4.4 P RXIMO PROGRAMA 43
return 0;
int main(void)
{
int num1, num2, soma;
num1 = 25;
num2 = 30;
soma = num1 + num2;
printf("A soma de %d e %d %d\n", num1, num2, soma);
return 0;
}
FACOM UFMS
44 P RIMEIROS PROGRAMAS
sulta o contedo das variveis num1 e num2 , realiza a operao de adio com os dois valores
obtidos dessas variveis e, aps isso, atribui o resultado varivel soma . No nosso exemplo,
o resultado da expresso aritmtica 25 + 30, ou seja, o valor 55, ser atribudo varivel soma .
A linha seguinte contm uma chamada funo printf , mas agora com quatro argumentos:
o primeiro agora uma cadeia de caracteres de formatao, contendo no apenas caracteres a
serem impressos na sada, mas smbolos especiais, iniciados com % , conhecidos como conver-
sores de tipo da linguagem C. Neste caso, os smbolos %d permitem que um nmero inteiro
seja mostrado na sada. Note que trs conversores %d esto contidos na cadeia de caracteres
de formatao e, a cada um deles est associado uma das variveis num1 , num2 e soma , na
ordem em que aparecem. Essas variveis so os argumentos restantes da funo printf .
4.5 Documentao
Uma boa documentao de um programa, conforme [15], significa inserir comentrios apro-
priados no cdigo de modo a explicar o que cada uma das funes que compem o programa
faz. A documentao de uma funo um pequeno manual que d instrues precisas e com-
pletas sobre o uso da funo.
Comentrios so introduzidos em programas com o objetivo de document-los e de incre-
mentar a sua legibilidade. O(a) programador(a) responsvel por manter seus cdigos legveis
e bem documentados para que, no futuro, possa retom-los e compreend-los sem muito es-
foro e sem desperdcio de tempo. Na linguagem C padro, os comentrios so envolvidos
pelos smbolos /* e */ . Um comentrio completamente ignorado quando encontrado pelo
compilador e, portanto, no faz diferena alguma no programa executvel resultante.
Vejamos o programa 4.3, que nada mais que a codificao do programa 4.2 com uma
documentao do programa principal.
num1 = 25;
num2 = 30;
soma = num1 + num2;
printf("A soma de %d e %d %d\n", num1, num2, soma);
return 0;
}
Ainda conforme [15], uma boa documentao no se preocupa em explicar como uma fun-
o faz o que faz, mas sim o que ela faz de fato, informando quais so os valores de entrada da
funo, quais so os valores de sada e quais as relaes que esses valores que entram e saem
da funo e as transformaes pela funo realizadas.
FACOM UFMS
4.6 E NTRADA E SADA 45
Veremos agora um exemplo de programa na linguagem C que usa pela primeira vez a
funo de leitura de dados scanf . Ento, abra seu Emacs, pressione a seqncia de teclas
C-x C-f , d um nome para seu programa, como por exemplo soma.c , e digite o cdigo
apresentado no programa 4.4 a seguir.
return 0;
}
Vamos olhar mais de perto este programa. Observe que, pela primeira vez, usamos a funo
scanf que, como mencionamos acima, uma funo da linguagem C responsvel pela leitura
de dados.
Desconsiderando o esqueleto do programa, a primeira linha a ser notada a declarao de
variveis:
Estamos, com esta linha do programa, reservando trs compartimentos de memria que po-
dero ser utilizados para armazenamento de nmeros inteiros, cujos nomes so num1 , num2
e soma . Os contedos desses compartimentos de memria podem variar durante a execuo
do programa. De fato, no momento da declarao, os compartimentos associados aos nomes
num1 , num2 e soma j contm, cada um, algum valor que desconhecido e que referenciamos
como lixo.
Em seguida, h duas chamadas de funes para escrita e leitura:
FACOM UFMS
46 P RIMEIROS PROGRAMAS
A funo para escrita de dados printf j bem conhecida, vista nesta e nas aulas anteri-
ores. A funo de leitura scanf tem dois argumentos: uma cadeia de caracteres de forma-
tao "%d" e uma varivel num1 correspondente a este formato. Diferentemente da funo
printf , uma varivel do tipo inteiro que um argumento da funo scanf deve sempre vir
precedida com o smbolo & . Na instruo acima, a cadeia de caracteres de formatao "%d"
indica que o valor informado pelo usurio ser convertido para um inteiro. Ainda, este valor
ser ento armazenado na varivel do tipo inteiro num1 . Observe, mais uma vez, que esta
varivel precedida por um & .
A prxima seqncia de instrues equivalente e solicita ao usurio do programa a en-
trada de um outro nmero, que ser armazenado na varivel num2 :
mostra, alm dos valores das duas parcelas num1 e num2 , o resultado dessa soma armazenado
na varivel soma .
Veremos agora um segundo exemplo usando as funes de entrada e sada que acabamos
de aprender. Este segundo exemplo muito semelhante ao exemplo anterior. A diferena est
apenas no formato da expresso aritmtica: no primeiro exemplo, uma adio realizada; neste
segundo exemplo, uma multiplicao realizada. O operador aritmtico de multiplicao o
smbolo * . Ento, informe, compile e execute o seguinte programa 4.5.
FACOM UFMS
4.6 E NTRADA E SADA 47
return 0;
}
Exerccios
4.1 Escreva uma programa na linguagem C que escreva a seguinte mensagem na sada pa-
dro:
4.4 Verifique se o programa 4.7 est correto. Em caso negativo, liste os erros de digitao que
voc encontrou.
FACOM UFMS
48 P RIMEIROS PROGRAMAS
4.5 Escreva um programa que leia trs nmeros inteiros a, b e c, calcule a b + c e mostre o
resultado na sada padro para o usurio.
4.6 Escreva um programa que leia um nmero inteiro e mostre o seu quadrado e seu cubo.
Por exemplo, se o nmero de entrada 3, a sada deve ser 9 e 27.
4.7 Escreva um programa que leia trs nmeros inteiros e mostre como resultado a soma
desses trs nmeros e tambm a multiplicao desses trs nmeros.
4.8 Escreva um programa que leia um nmero inteiro e mostre o resultado da quociente
(inteiro) da diviso desse nmero por 2 e por 3.
FACOM UFMS
AULA 5
E STRUTURAS CONDICIONAIS
Como vimos na aula 4, nossa linguagem de programao usada para executar uma
seqncia de comandos ou instrues tais como uma leitura de dados, uma impresso de da-
dos e atribuio de valores a variveis. Alm de ter esse poder, os programas tambm podem
ser usados para tomar decises. Na linguagem C, uma deciso tomada com o uso de uma
estrutura condicional simples ou de uma estrutura condicional composta. Uma estrutura con-
dicional simples tem o seguinte formato:
if (condio ) {
instruo1 ;
instruo2 ;
.
.
.
instruon ;
}
49
50 E STRUTURAS CONDICIONAIS
int main(void)
{
int idade;
printf("At breve!\n");
return 0;
}
if (condio ) {
instruo1 ;
instruo2 ;
.
.
.
instruom ;
}
else {
instruo1 ;
instruo2 ;
.
.
.
instruon ;
}
FACOM UFMS
5.2 E STRUTURA CONDICIONAL COMPOSTA 51
o segundo bloco de instrues, logo aps a palavra-chave else , ser executado. Ao final da
execuo das instrues desse bloco, a instruo da prxima linha aps a estrutura condicional
composta ser executada. Veja um exemplo no programa 5.2.
/* Recebe um nmero inteiro e emite uma mensagem de acordo com esse nmero */
int main(void)
{
int idade;
return 0;
}
O programa 5.3 recebe dois nmeros inteiros quaisquer e os imprime em ordem crescente.
return 0;
}
FACOM UFMS
52 E STRUTURAS CONDICIONAIS
o identificador de uma varivel deve iniciar com uma letra do alfabeto ou com um subli-
nhado (_);
soma
num1
i
soma_total
_sistema
A3x3
frao
1
Do ingls underscore ou underline.
FACOM UFMS
5.3 R EVISO DE NMEROS INTEIROS 53
preo$
soma total
4quant
int
ou
int i;
int num1;
int num2;
int soma;
int produto;
int aux;
TotalDeDinheiroQueTenho = TotalDoDinheiroQueGuardeiAnoPassado +
TotalDeDinheiroQueGuardeiEsteAno - TotalDeImpostosEmReais;
FACOM UFMS
54 E STRUTURAS CONDICIONAIS
781 + 553 - 12 * 44
#define NUMERADOR 4
#define MIN -10000
#define MAX 100
FACOM UFMS
5.3 R EVISO DE NMEROS INTEIROS 55
#define NUM 25
int main(void)
{
int x, y, z, r;
y = 10;
r = NUM + y;
printf("A soma de %d e %d %d\n", NUM, y, r);
x = 38;
r = x - NUM;
printf("A subtrao de %d e %d %d\n", x, NUM, r);
x = 51;
y = 17;
r = x * y;
printf("A multiplicao de %d por %d %d\n", x, y, r);
x = 100;
y = NUM;
r = x / y;
printf("O quociente da diviso de %d por %d %d\n", x, y, r);
x = 17;
y = 3;
r = x % y;
printf("O resto da diviso de %d por %d %d\n", x, y, r);
x = -7;
r = -x;
printf("%d com sinal trocado %d\n", x, r);
x = 10;
y = 4;
z = 15;
r = x + y * z;
printf("A expresso %d+%d*%d %d\n", x, y, z, r);
return 0;
}
FACOM UFMS
56 E STRUTURAS CONDICIONAIS
x + y * z
dado primeiro pela avaliao da multiplicao e depois pela avaliao da adio. Parnteses
so utilizados para modificar a ordem das operaes. Por exemplo,
(x + y) * z
int i;
FACOM UFMS
5.3 R EVISO DE NMEROS INTEIROS 57
ou
2147483648, . . . , 1, 0, 1, . . . , 2147483647 .
Cada seqncia de 32 bits que comea com 0 representa um int no-negativo em notao
binria. Cada seqncia de 32 bits que comea com 1 representa o inteiro negativo k 232 ,
onde k o valor da seqncia em notao binria. Esta representao de nmeros inteiros
negativos
31 31 chamada
de complemento-de-dois. Nmeros inteiros que estejam fora do intevalo
2 , 2 1 so representados mdulo 232 .
Ressaltamos ainda que todos os valores acima podem ser obtidos usando frmulas gerais
em funo do nmero de bytes consecutivos usados para representar um int .
Exerccios
5.1 Escreva um programa que receba a temperatura ambiente em graus Clsius e mostre uma
mensagem para o usurio informando se a temperatura est muito quente. Considere
como temperatura limite o valor de 30 graus Clsius.
return 0;
}
5.3 Para transformar um nmero inteiro i no menor inteiro m maior que i e mltiplo de um
nmero inteiro j, a seguinte frmula pode ser utilizada:
m = i + j i mod j ,
FACOM UFMS
58 E STRUTURAS CONDICIONAIS
Por exemplo, suponha que usamos i = 256 dias para alguma atividade e queremos saber
qual o total de dias m que devemos ter de forma que esse nmero seja divisvel por j = 7,
para termos uma idia do nmero de semanas que usaremos na atividade. Ento, pela
frmula acima, temos que
Escreva um programa que receba dois nmeros inteiros positivos i e j e devolva o menor
inteiro m maior que i e mltiplo de j.
5.4 Escreva um programa que receba um nmero inteiro a e verifique se a par ou mpar.
5.5 Escreva um programa que receba um nmero inteiro a e verifique se a positivo, negativo
ou igual a 0.
5.6 Escreva um programa que receba trs valores, armazenando-os nas variveis x, y e z, e or-
dene esses valores de modo que, ao final, o menor valor esteja armazenado na varivel x,
o valor intermedirio esteja armazenado na varivel y e o maior valor esteja armazenado
na varivel z.
FACOM UFMS
AULA 6
6.1 Motivao
Suponha que algum queira escrever um programa para imprimir os dez primeiros nme-
ros inteiros positivos. Este problema, apesar de muito simples e pouco til primeira vista,
motiva a introduo das estruturas de repetio, como veremos adiante. Com o que aprende-
mos at o momento, bem fcil escrever um programa como esse.
#include <stdio.h>
printf("1\n");
printf("2\n");
printf("3\n");
printf("4\n");
printf("5\n");
printf("6\n");
printf("7\n");
printf("8\n");
printf("9\n");
printf("10\n");
return 0;
}
59
60 E STRUTURA DE REPETIO while
Alm de bem simples, o programa acima est correto, isto , realiza corretamente o pro-
psito de imprimir os dez primeiros nmeros inteiros positivos na sada. Mas e se quiss-
semos, por exemplo, imprimir os 1000 primeiros nmeros inteiros positivos? Um programa
semelhante ao que acabamos de apresentar ficaria um pouco mais complicado e montono de
escrever, j que teria muitas e muitas linhas de cdigo.
Uma das propriedades fundamentais dos computadores, talvez a que mais nos auxilia,
que eles possuem a capacidade de executar repetitivamente um conjunto de instrues. Essa
capacidade de repetio permite que um(a) desenvolvedor(a)/programador(a) escreva algo-
ritmos e programas mais concisos, contendo processos repetitivos que poderiam necessitar de
centenas ou milhares de linhas se no fossem assim descritos. Na linguagem C podemos ter
trs estruturas de repetio diferentes. A seguir veremos a estrutura de repetio while , mais
simples, mais didtica, mais ilustrativa e provavelmente a mais usada estrutura de repetio
da linguagem C.
while (condio) {
instruo1 ;
instruo2 ;
.
.
.
instruon ;
}
onde while uma palavra-chave da linguagem C, condio uma expresso lgica en-
volvida por parnteses que avaliada e possui o valor verdadeiro ou falso, instruo1 a
instruon fazem parte do bloco de instrues da estrutura de repetio while com as cha-
ves { e } delimitando esse bloco de instrues. Do mesmo modo como vimos nas estruturas
condicionais, se o bloco de instrues associado estrutura de repetio while tem uma nica
instruo, esses delimitadores so opcionais.
A estrutura de repetio while funciona da seguinte forma. Quando um programa en-
contra a palavra-chave while , a expresso descrita na condio avaliada. Se o resultado
da avaliao dessa expresso verdadeiro, o programa desvia seu fluxo de execuo para o
bloco de instrues interno estrutura de repetio. Ento, as instrues so executadas uma
a uma at a ltima delas. Quando o programa atinge o final do bloco de instrues, o fluxo
de execuo desviado para a linha que contm a palavra-chave while e a expresso nova-
mente avaliada. Se o resultado verdadeiro, as instrues so todas executadas novamente e
o processo se repete. Caso contrrio, isto , se o resultado da avaliao da expresso falso, o
fluxo de execuo do programa desviado para a primeira instruo aps o bloco de instrues
envolvido por chaves.
Veja o programa 6.1 para um exemplo de uso da estrutura de repetio while .
FACOM UFMS
6.2 E STRUTURA DE REPETIO while 61
numero = 1;
while (numero <= 100) {
printf("%d\n", numero);
numero = numero + 1;
}
printf("\n");
return 0;
}
Exerccios
printf("Informe n: ");
scanf("%d", &n);
soma = 0;
numero = 1;
while (numero <= n) {
soma = soma + numero;
numero = numero + 1;
}
printf("Soma dos %d primeiros inteiros %d\n", n, soma);
return 0;
}
FACOM UFMS
62 E STRUTURA DE REPETIO while
6.6 Dado um inteiro positivo n e uma seqncia de n inteiros, somar esses n nmeros.
6.7 Dado um inteiro positivo n e uma seqncia de n nmeros inteiros, determinar a soma
dos nmeros inteiros positivos da seqncia.
Exemplo:
6.8 Dado um inteiro positivo n e uma seqncia de n inteiros, somar os nmeros pares e os
nmeros mpares.
6.10 Dado um inteiro positivo n e uma seqncia de n inteiros, determinar quantos nmeros
da seqncia so positivos e quantos so no-positivos. Um nmero no-positivo se
negativo ou se igual a 0 (zero).
6.11 Dado um inteiro positivo n e uma seqncia de n inteiros, determinar quantos nmeros
da seqncia so pares e quantos so mpares.
6.12 Uma loja de discos anota diariamente durante o ms de abril a quantidade de discos ven-
didos. Determinar em que dia desse ms ocorreu a maior venda e qual foi a quantidade
de discos vendida nesse dia.
FACOM UFMS
AULA 7
Nesta aula veremos expresses aritmticas, relacionais e lgicas com nmeros inteiros. Em
aulas anteriores j tomamos contato com essas expresses, mas pretendemos formaliz-las
aqui. A compreenso destas expresses com nmeros inteiros fundamental para que pos-
samos escrever programas mais eficientes e poderosos e tambm porque podemos estender
esse entendimento a outros tipos de variveis. Importante destacar que a linguagem C no tem
um tipo lgico primitivo, que ento simulado atravs do tipo inteiro, como veremos.
Esta aula baseada nas referncias [15, 16].
63
64 E XPRESSES COM INTEIROS
Suponha ainda que as seguintes atribuies de valores constantes tenham sido executadas so-
bre essas variveis:
x = 1;
y = 2;
a = 5;
soma = 100;
parcela = 134;
2 * x * x + 5 * -x - +4
soma + parcela % 3
4 * 1002 - 4412 % 11 * -2 + a
(((204 / (3 + x)) * y) - ((y % x) + soma))
De acordo com os valores das inicializaes das variveis envolvidas e o resultado da avaliao
das prprias expresses, a avaliao de cada uma das linhas acima tem valores 7, 102, 4037 e
202, respectivamente.
A tabela abaixo, contendo as prioridades dos operadores aritmticos unrios e binrios, j
foi exibida em parte na aula 5.
Uma expresso relacional, ou simplesmente uma relao, uma comparao entre dois
valores do mesmo tipo primitivo de dados. Esses valores so representados na relao atravs
de constantes, variveis ou expresses. Essa definio bem abrangente e acomoda outros
tipos de dados alm do tipo int , o nico tipo primitivo de dados que conhecemos at o
momento. Com o tipo int a definio de relao pode ser escrita como uma comparao
entre dois valores, representados por constantes numricas, variveis numricas ou expresses
aritmticas.
Os operadores relacionais da linguagem C, que indicam a comparao a ser realizada entre
os termos da relao, so os seguintes:
FACOM UFMS
7.3 E XPRESSES LGICAS 65
Operador Descrio
== igual a
!= diferente de
< menor que
> maior que
<= menor que ou igual a
>= maior que ou igual a
int a, b, c;
a = 2;
b = 3;
c = 4;
a == 2
a > b + c
b + c <= 5 - a
b != 3
Uma proposio qualquer sentena que pode ser valorada com o valor verdadeiro ou
falso. Traduzindo essa definio para a linguagem C, uma proposio qualquer sentena que
pode ser valorada com um valor inteiro. Com o que aprendemos at agora, uma proposio
FACOM UFMS
66 E XPRESSES COM INTEIROS
uma relao, uma varivel do tipo inteiro ou uma constante do tipo inteiro. Uma expresso
condicional ou lgica, ou ainda booleana formada por uma ou mais proposies. Neste
ltimo caso, relacionamos as proposies atravs de operadores lgicos. Os operadores lgicos
da linguagem C utilizados como conectivos nas expresses lgicas so apresentados a seguir.
Operador Descrio
&& conjuno
|| disjuno
! negao
Duas proposies p e q podem ser combinadas pelo conectivo && para formar uma nica
proposio denominada conjuno das proposies originais: p && q e lemos p e q . O
resultado da avaliao da conjuno de duas proposies verdadeiro se e somente se ambas
as proposies tm valor verdadeiro, como mostra a tabela a seguir.
p q p && q
1 1 1
1 0 0
0 1 0
0 0 0
Duas proposies p e q podem ser combinadas pelo conectivo || para formar uma nica
proposio denominada disjuno das proposies originais: p || q e lemos p ou q ,
com sentido de e/ou. O resultado da avaliao da disjuno de duas proposies verdadeiro
se pelo menos uma das proposies tem valor verdadeiro, como mostra a tabela a seguir.
p q p || q
1 1 1
1 0 1
0 1 1
0 0 0
Dada uma proposio p , uma outra proposio, chamada negao de p , pode ser obtida
atravs da insero do smbolo ! antes da proposio: !p e lemos no p . Se a proposio
p tem valor verdadeiro, ento !p tem valor falso e se p tem valor falso, ento a proposio
!p tem valor verdadeiro, como mostra a tabela a seguir.
p !p
1 0
0 1
int a, b, c, x;
FACOM UFMS
7.3 E XPRESSES LGICAS 67
a = 2;
b = 3;
c = 4;
x = 1;
5
a
!x
a == 2 && a < b + c
b + c >= 5 - a || b != 3
a + b > c || 2 * x == b && 4 < x
a == 2 && a + x > b + c
2 == 2 && 3 > 3 + 4
2 == 2 && 3 > 7
1 && 0
1
FACOM UFMS
68 E XPRESSES COM INTEIROS
Observe que, como o operador lgico de conjuno && tem prioridade sobre o operador
lgico de disjuno || , o resultado da expresso acima verdadeiro. Se tivssemos realizado a
disjuno primeiramente, como poderamos intuitivamente supor devido ao posicionamento
mais esquerda do operador de disjuno, o resultado da expresso seria diferente.
Exerccios
Alguns exerccios desta aula ensinam um importante truque de programao que , na ver-
dade, o uso de uma varivel que simula um tipo lgico e que indica que algo ocorreu durante
a execuo do programa. Essa varivel chamada de indicadora de passagem.
divisor = 2;
while (divisor <= p/2) {
if (p % divisor == 0)
divisor = p;
else
divisor = divisor + 1;
}
if (divisor == p/2 + 1)
printf("%d primo\n", p);
else
printf("%d no primo\n", p);
return 0;
}
FACOM UFMS
7.3 E XPRESSES LGICAS 69
Programa 7.2: Soluo para o exerccio 7.1 usando uma varivel indicadora de passagem.
#include <stdio.h>
return 0;
}
return 0;
}
FACOM UFMS
70 E XPRESSES COM INTEIROS
7.2 Dado um nmero inteiro positivo n e uma seqncia de n nmeros inteiros, verificar se a
seqncia est em ordem crescente.
7.3 Dados um nmero inteiro n > 0 e um dgito d, com 0 6 d 6 9, determinar quantas vezes
o dgito d ocorre no nmero n.
7.4 Dado um nmero inteiro positivo n, verificar se este nmero contm dois dgitos conse-
cutivos iguais.
7.5 Dado um nmero inteiro positivo n, verificar se o primeiro e o ltimo dgito deste nmero
so iguais.
7.6 Dado um nmero inteiro positivo n e dois nmeros naturais no nulos i e j, imprimir em
ordem crescente os n primeiros naturais que so mltiplos de i ou de j ou de ambos.
Exemplo:
Para n = 6, i = 2 e j = 3 a sada dever ser 0, 2, 3, 4, 6, 8.
7.7 Dizemos que um nmero natural triangular se produto de trs nmeros naturais
consecutivos.
Exemplo:
120 triangular, pois 4 5 6 = 120.
Dado n natural, verificar se n triangular.
7.8 Dados dois nmeros inteiros positivos, determinar o mximo divisor comum entre eles
utilizando o algoritmo de Euclides.
Exemplo:
1 1 1 2
24 15 9 6 3 = mdc(24,15)
9 6 3 0
7.9 Dados dois nmeros inteiros positivos a e b, representando a frao a/b, escreva um pro-
grama que reduz a/b para uma frao irredutvel.
Exemplo:
Se a entrada 9/12 a sada tem de ser 3/4.
7.10 Dados a quantidade de dias de um ms e o dia da semana em que o ms comea, escreva
um programa que imprima os dias do ms por semana, linha a linha. Considere o dia
da semana 1 como domingo, 2 como segunda-feira, e assim por diante, at o dia 7 como
sbado.
Exemplo:
Se a entrada 31 e 3 ento a sada deve ser
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
FACOM UFMS
7.3 E XPRESSES LGICAS 71
7.11 Dados um nmero inteiro n e n seqncias de nmeros inteiros, cada qual terminada por
0, determinar a soma dos nmeros pares de cada seqncia.
7.12 Dados um nmero inteiro n > 0 e uma seqncia de n nmeros inteiros positivos deter-
minar o fatorial de cada nmero da seqncia.
7.13 Dados n nmeros inteiros positivos, calcular a soma dos que so primos.
7.14 Dado um nmero inteiro positivo n, determinar todos os inteiros entre 1 e n que so
comprimento de hipotenusa de um tringulo retngulo com catetos inteiros.
7.15 Dados dois naturais m e n, determinar, entre todos os pares de nmeros naturais (x, y)
tais que x 6 m e y 6 n, um par para o qual o valor da expresso xy x2 + y seja mximo
e calcular tambm esse mximo.
7.16 Sabe-se que um nmero da forma n3 igual soma de n nmeros mpares consecutivos.
Exemplo:
13 =1
23 =3+5
33 = 7 + 9 + 11
43 = 13 + 15 + 17 + 19
..
.
7.17 Dado um nmero inteiro positivo, determine a sua decomposio em fatores primos,
calculando tambm a multiplicidade de cada fator.
Exemplo:
7.18 Dados n inteiros positivos, determinar o mximo divisor comum entre eles.
FACOM UFMS
72 E XPRESSES COM INTEIROS
FACOM UFMS
AULA 8
Retomando o programa 6.1, isto , o primeiro exemplo com uma estrutura de repetio na
linguagem C que vimos at agora, vamos refaz-lo, desta vez usando a estrutura de repetio
for . Vejamos ento o programa 8.1 a seguir.
printf("\n");
return 0;
}
73
74 O UTRAS ESTRUTURAS DE REPETIO
int cont;
cont = 1;
imprime cont vale 2 e cont vale 2 em duas linhas consecutivas na sada. Por outro lado,
o trecho de cdigo abaixo:
int cont;
cont = 1;
FACOM UFMS
8.2 E STRUTURA DE REPETIO do-while 75
soma = 0;
for (numero = 1; numero <= 100; ++numero)
soma = soma + numero;
return 0;
}
Suponha agora que seja necessrio resolver um problema simples, muito semelhante aos
problemas iniciais que resolvemos usando uma estrutura de repetio. O enunciado do pro-
blema o seguinte:
Dada uma seqncia de nmeros inteiros terminada com 0, calcular a soma desses
nmeros.
Com o que aprendemos sobre programao at o momento, este problema parece bem sim-
ples de ser resolvido. Observe, antes de tudo, que este problema pode ser facilmente resol-
vido usando a estrutura de repetio while . E dadas as suas semelhanas, um programa que
soluciona esse problema usando a estrutura de repetio for tambm pode ser facilmente
desenvolvido.
Vejamos agora ento uma soluo um pouco diferente, dada no programa 8.3. Esta so-
luo contm uma terceira estrutura de repetio da linguagem C, a estrutura de repetio
do-while , que ainda no conhecamos.
FACOM UFMS
76 O UTRAS ESTRUTURAS DE REPETIO
soma = 0;
do {
printf("Informe um nmero: ");
scanf("%d", numero);
soma = soma + numero;
} while (numero != 0);
return 0;
}
O programa 8.3 muito semelhante aos demais programas que vimos construindo at o mo-
mento. A principal e mais significativa diferena o uso da estrutura de repetio do-while .
Quando o programa encontra essa estrutura pela primeira vez, com uma linha contendo a
palavra-chave do , o fluxo de execuo segue para a primeira instruo do bloco de instrues
dessa estrutura, envolvido por chaves. As instrues desse bloco so ento executados uma a
uma, at o fim do bloco. Logo em seguida, aps o fim do bloco com o caractere } , encontramos
a palavra-chave while e, depois, entre parnteses, uma expresso lgica. Se o resultado da
avaliao dessa expresso lgica for verdadeiro, ento o fluxo de execuo do programa des-
viado para a primeira instruo do bloco de instrues desta estrutura de repetio e todas as
instrues so executadas novamente. Caso contrrio, se o resultado da avaliao da expresso
lgica falso, o fluxo de execuo desviado para a prxima instruo aps a linha contendo
o final do bloco de execuo desta estrutura de repetio.
Note ainda que o teste de continuidade desta estrutura de repetio realizado sempre no
final, aps todas as instrues de seu bloco interno de instrues terem sido executadas. Isso
significa que esse bloco de instrues ser executado ao menos uma vez. Neste sentido, esta
estrutura de repetio do-while difere das outras estruturas de repetio while e for que
vimos anteriormente, j que nesses dois ltimos casos o resultado da avaliao da expresso
lgica associada a essas estruturas pode fazer com que seus blocos de instrues respectivos
no sejam executados nem mesmo uma nica vez.
Exerccios
8.1 Qualquer nmero natural de quatro algarismos pode ser dividido em duas dezenas for-
madas pelos seus dois primeiros e dois ltimos dgitos.
Exemplos:
FACOM UFMS
8.2 E STRUTURA DE REPETIO do-while 77
1297: 12 e 97.
5314: 53 e 14.
Escreva um programa que imprima todos os nmeros de quatro algarismos cuja raiz
quadrada seja a soma das dezenas formadas pela diviso acima.
Exemplo:
9801 = 99 = 98 + 01.
Portanto, 9801 um dos nmeros a ser impresso.
return 0;
}
8.2 Dado um nmero inteiro no-negativo n, escreva um programa que determine quantos
dgitos o nmero n possui.
#include <stdio.h>
int main(void)
{
int n, digitos;
printf("Informe n: ");
scanf("%d", n);
do {
n = n / 10;
digitos++;
} while (n > 0);
printf("O nmero tem %d dgitos\n", digitos);
return 0;
}
FACOM UFMS
78 O UTRAS ESTRUTURAS DE REPETIO
8.3 Dado um nmero natural na base binria, transform-lo para a base decimal.
Exemplo:
8.4 Dado um nmero natural na base decimal, transform-lo para a base binria.
Exemplo:
8.5 Dado um nmero inteiro positivo n que no contm um dgito 0, imprimi-lo na ordem
inversa de seus dgitos.
Exemplo:
8.6 Dizemos que um nmero natural n com pelo menos 2 algarismos palndromo se
Exemplos:
567765 palndromo;
32423 palndromo;
567675 no palndromo.
8.7 Dados um nmero inteiro n > 0 e uma seqncia de n nmeros inteiros, determinar
quantos segmentos de nmeros iguais consecutivos compem essa seqncia.
Exemplo:
z}|{ z }| { z }| { z}|{
Para n = 9, a seqncia 5 , 2, 2, 4, 4, 4, 4, 1, 1 formada por 4 segmentos
de nmeros iguais.
8.8 Dados um nmero inteiro n > 0 e uma seqncia de n nmeros inteiros, determinar o
comprimento de um segmento crescente de comprimento mximo.
Exemplos:
z }| {
Na seqncia 5, 10, 6, 2, 4, 7, 9, 8, 3 o comprimento do segmento crescente m-
ximo 4.
Na seqncia 10, 8, 7, 5, 2 o comprimento do segmento crescente mximo 1.
FACOM UFMS
AULA 9
float x, y;
double arco;
79
80 N MEROS COM PONTO FLUTUANTE
O padro IEEE 754 estabelece dois formatos primrios para nmeros de ponto flutuante:
o formato de preciso simples, com 32 bits, e o formato de preciso dupla, com 64 bits. Os
nmeros de ponto flutuante so armazenados no formato de notao cientfica, composto por
trs partes: um sinal, um expoente e uma frao. O nmero de bits reservado para representar o
expoente determina quo grande o nmero pode ser, enquanto que o nmero de bits da frao
determina sua preciso.
Um exemplo de um programa que usa constantes e variveis do tipo float apresentado
no programa 9.1. Neste programa, uma seqncia de cem nmeros do tipo ponto flutuante
informada pelo usurio. Em seguida, a mdia aritmtica desses nmeros calculada e, por fim,
mostrada na sada padro.
/* Recebe uma seqncia de 100 nmeros reais e mostra a mdia desses nmeros */
int main(void)
{
int i;
float numero, soma, media;
soma = 0.0;
return 0;
}
FACOM UFMS
9.2 E XPRESSES ARITMTICAS 81
Programa 9.2: Relao entre valores do tipo inteiro e do tipo ponto flutuante.
#include <stdio.h>
int main(void)
{
int i1, i2;
float f1, f2;
i1 = 190;
f1 = 100.5;
i2 = i1 / 100;
printf("i2 = %d\n", i2);
f2 = i1 / 100;
printf("f2 = %f\n", f2);
f2 = i1 / 100.0;
printf("f2 = %f\n", f2);
f2 = f1 / 100;
printf("f2 = %f\n", f2);
return 0;
}
i2 = 1
f2 = 1.000000
f2 = 1.900000
f2 = 1.005000
FACOM UFMS
82 N MEROS COM PONTO FLUTUANTE
Suponha, no entanto, que um programa semelhante, o programa 9.3, tenha sido desenvol-
vido, compilado e executado.
int main(void)
{
int i1, i2;
float f1;
i1 = 3;
i2 = 2;
f1 = i1 / i2;
return 0;
}
f1 = 1.000000
Mas e se quisssemos que a diviso i1/ i2 tenha como resultado um valor do tipo ponto
flutuante? Neste caso, devemos usar um operador unrio chamado operador conversor de
tipo, do ingls type cast operator, sobre alguma das variveis da expresso. No caso acima,
poderamos usar qualquer uma das atribuies abaixo:
f1 = 1.500000
FACOM UFMS
9.2 E XPRESSES ARITMTICAS 83
int main(void)
{
int i1, i2, i3, i4;
float f1, f2;
f1 = 10.8;
f2 = 1.5;
i1 = f1 / f2;
printf("i1 = %d\n", i1);
i2 = (int) f1 / f2;
printf("i2 = %d\n", i2);
i3 = f1 / (int) f2;
printf("i3 = %d\n", i3);
return 0;
}
i1 = 7
i2 = 6
i3 = 10
i4 = 10
FACOM UFMS
84 N MEROS COM PONTO FLUTUANTE
pi = 3.141592f;
return 0;
}
Exerccios
9.1 Uma pessoa aplicou um capital de x reais a juros mensais de y% durante 1 ano. Determi-
nar o montante de cada ms durante este perodo.
9.2 Os pontos (x, y) que pertencem figura H (veja a figura 9.1) so tais que x > 0, y > 0 e
x2 + y 2 6 1. Dados n pontos reais (x, y), verifique se cada ponto pertence ou no a H.
FACOM UFMS
9.2 E XPRESSES ARITMTICAS 85
int main(void)
{
int mes;
float x, y;
y
1111111111
0000000000
0000000000
1111111111
0000000000
1111111111
0000000000
1111111111
0000000000
1111111111
0000000000
1111111111
H
0000000000
1111111111
0000000000
1111111111
0000000000x
1111111111
Figura 9.1: rea H de um quarto de um crculo.
Dado um nmero inteiro n > 0, leia uma seqncia de n pontos reais (x, y) e verifique se
cada ponto pertence ou no ao conjunto H, contando o nmero de pontos da seqncia
que pertencem a H.
9.4 Dado um natural n, determine o nmero harmnico Hn definido por
n
X 1
Hn = .
k
k=1
9.5 Para n > 0 alunos de uma determinada turma so dadas 3 notas de provas. Calcular a
mdia aritmtica das provas de cada aluno, a mdia da classe, o nmero de aprovados e
o nmero de reprovados, onde o critrio de aprovao mdia > 5.0.
9.6 Dados nmeros reais a, b e c, calcular as razes de uma equao do 2o grau da forma
ax2 + bx + c = 0. Imprimir a soluo em uma das seguintes formas:
FACOM UFMS
86 N MEROS COM PONTO FLUTUANTE
x2 x4 x6 x2k
cos x = 1 + + . . . + (1)k + ...
2! 4! 6! (2k)!
com k > 0. Compare com os resultados de sua calculadora.
FACOM UFMS
9.2 E XPRESSES ARITMTICAS 87
9.13 Dados x e reais, > 0, calcular uma aproximao para sen x, onde x dado em radianos,
atravs da seguinte srie infinita
x x3 x5 x2k+1
sen x = + . . . + (1)k + ...
1! 3! 5! (2k + 1)!
x2k+1
incluindo todos os termos Tk = (2k+1)! , com k > 0, at que Tk < . Compare com os
resultados de sua calculadora.
FACOM UFMS
88 N MEROS COM PONTO FLUTUANTE
FACOM UFMS
AULA 10
C ARACTERES
Nesta aula vamos estudar um novo tipo primitivo de dados, o tipo caractere. O tipo ca-
ractere um tipo primitivo que podemos trabalhar com um conjunto pequeno e previsvel de
valores. Na linguagem C existem dois tipos de caracteres: caractere com sinal e caractere sem
sinal. Esses dois tipos so apenas interpretaes diferentes do conjunto de todas as seqncias
de 8 bits, sendo que essa diferena irrelevante na prtica. O estudo dos caracteres ser esten-
dido, mais til e melhor compreendido na aula 13, quando veremos as cadeias de caracteres.
Esta aula baseada especialmente nas referncias [15, 16].
89
90 C ARACTERES
Dos 128 caracteres padronizados da tabela ASCII e de seus smbolos grficos correspon-
dentes, 33 deles so no-imprimveis e os restantes 95 so imprimveis. Os caracteres no-
imprimveis so caracteres de controle, criados nos primrdios da computao, quando se usa-
vam mquinas teletipo e fitas de papel perfurado, sendo que atualmente grande parte deles
esto obsoletos. Na tabela a seguir, apresentamos alguns desses caracteres no-imprimveis.
Muitos deles no so mostrados por opo ou por terem cado em desuso.
FACOM UFMS
10.2 C ONSTANTES E VARIVEIS 91
Os caracteres com sinal, quando dispostos em ordem crescente, apresentam-se de tal forma
que as letras acentuadas precedem as no-acentuadas. Os caracteres sem sinal, ao contrrio, em
ordem crescente apresentam-se de forma que as letras no-acentuadas precedem as acentuadas.
Essa a nica diferena entre caracteres com e sem sinal.
Uma varivel do tipo caractere com sinal pode ser declarada na linguagem C com a palavra
reservada char . Uma varivel do tipo caractere sem sinal pode ser declarada com a mesma
palavra reservada char , mas com o especificador de tipo unsigned a precedendo. Especifi-
cadores de tipos bsicos sero estudados em detalhes em uma prxima aula. Dessa forma,
char c, d, e;
unsigned char f, g, h;
c = 122;
d = 59;
e = 51;
Mais comum e confortavelmente, podemos especificar uma constante do tipo caractere atra-
vs da representao grfica de um caractere, envolvendo-o por aspas simples. Por exemplo,
z , ; e 3 so exemplos de constantes do tipo caractere. Assim, bem mais cmodo
fazer as atribuies
c = z;
d = ;;
e = 3;
FACOM UFMS
92 C ARACTERES
Na linguagem C, um branco (do ingls whitespace) definido como sendo um caractere que
uma tabulao horizontal, uma mudana de linha, uma tabulao vertical, uma quebra de
pgina, um retorno de carro/cursor e um espao. Ou seja, os caracteres 9, 10, 11, 12, 13 e 32
so brancos e as constantes correspondentes so \t , \n , \v , \f , \r e .
A funo scanf trata todos os brancos como se fossem , assim como outras funes da
linguagem C tambm o fazem.
Para imprimir um caractere na sada padro com a funo printf devemos usar o especi-
ficador de converso de tipo caractere %c na seqncia de caracteres de formatao. Para ler
um caractere a partir da entrada padro com a funo scanf tambm devemos usar o mesmo
especificador de converso de tipo caractere %c na seqncia de caracteres de formatao. Um
exemplo de uso do tipo bsico caractere mostrado no programa 10.1.
int main(void)
{
char c;
c = a;
printf("%c\n", c);
c = 97;
printf("%c\n", c);
return 0;
}
Como vimos at aqui nesta seo, por enquanto no h muita utilidade para constantes
e variveis do tipo caractere. Mas em breve iremos us-las para construir um tipo de dados
muito importante chamado de cadeia de caracteres.
FACOM UFMS
10.3 E XPRESSES COM CARACTERES 93
unsigned char x, y, z;
x = 240;
y = 65;
z = x + y;
unsigned char x;
char c;
x = 256;
c = 136;
.
.
.
char c;
c = a;
if (a <= c && c <= z)
c = c - ;
printf("%c = %d\n", c, c);
Tente verificar a sada gerada pelas duas chamadas da funo printf no trecho de cdigo
acima.
FACOM UFMS
94 C ARACTERES
Exerccios
int main(void)
{
char c;
return 0;
}
10.2 Escreva um programa que imprima todas as letras minsculas e todas as letras maiscu-
las do alfabeto.
10.4 Scrabble um jogo de palavras em que os jogadores formam palavras usando pequenos
quadrados que contm uma letra e um valor. O valor varia de uma letra para outra, ba-
seado na sua raridade. Os valores so os seguintes: AEILNORSTU=1, DG=2, BCMP=3,
FHVWY=4, K=5, JX=8 e QZ=10.
Escreva um programa que receba uma palavra e compute o seu valor, somando os va-
lores de suas letras. Seu programa no deve fazer distino entre letras maisculas e
minsculas.
Exemplo:
10.5 Escreva um programa que receba dois nmeros inteiros a e b e um caractere op, tal que
op pode ser um dos cinco operadores aritmticos disponveis na linguagem C ( + , - , * ,
/ , % ), realize a operao a op b e mostre o resultado na sada.
FACOM UFMS
AULA 11
Como vimos at esta aula, a linguagem C suporta fundamentalmente dois tipos de dados
numricos: tipos inteiros e tipos com ponto flutuante. Valores do tipo inteiro so nmeros
inteiros em um dado intervalo finito e valores do tipo ponto flutuante so tambm dados em
um intervalo finito e podem ter uma parte fracionria. Alm desses, o tipo caractere tambm
suportado pela linguagem e um valor do tipo caractere tambm um nmero inteiro em um
intervalo finito mais restrito que o dos tipos inteiros.
Nesta aula faremos uma reviso dos tipos primitivos de dados da linguagem C e veremos os
especificadores desses tipos, seus especificadores de converso para entrada e sada de dados,
as converses entre valores de tipos distintos, alm de definir nossos prprios tipos. Esta aula
uma reviso das aulas sobre o tipo inteiro (aula 7), o tipo ponto flutuante (aula 9) e o tipo
carctere, que vimos em conjunto com nas aulas tericas da disciplina. tambm uma extenso
desses conceitos, podendo ser usada como uma referncia para tipos primitivos de dados.
As referncias usadas nesta aula so [15, 16].
95
96 T IPOS PRIMITIVOS DE DADOS
short int
unsigned short int
int
unsigned int
long int
unsigned long int
Constantes numricas, como vimos, so nmeros que ocorrem no cdigo dos programas,
em especial em expresses aritmticas. As constantes, assim como as variveis, podem ser
nmeros inteiros ou nmeros com ponto flutuante.
Na linguagem C, as constantes numricas do tipo inteiro podem ser descritas em decimal
ou base 10, octal ou base 8 ou ainda hexadecimal ou base 16. Constantes decimais contm
dgitos de 0 (zero) a 9 (nove), mas no devem iniciar com 0 (zero). Exemplos de constantes
decimais so mostrados a seguir:
75 -264 32767
Constantes octais contm somente dgitos entre 0 (zero) e 7 (sete) e devem comear necessaria-
mente com o dgito 0 (zero). Exemplos de constantes octais so mostrados a seguir:
FACOM UFMS
11.1 T IPOS INTEIROS 97
E constantes hexadecimais contm dgitos entre 0 (zero) e 9 (nove) e letras entre a e f, e sempre
devem iniciar com os caracteres 0x. As letras podem ser maisculas ou minsculas. Exemplos
de constantes hexadecimais so mostrados a seguir:
importante destacar que a descrio de constantes como nmeros na base octal e hexade-
cimal apenas uma forma alternativa de escrever nmeros que no tem efeito na forma como
so armazenados na memria, j que sempre so armazenados na base binria. Alm disso,
essas notaes so mais usadas quando trabalhamos com programas de baixo nvel.
No h necessidade de se convencionar uma nica notao para escrever constantes e po-
demos trocar de uma notao para outra a qualquer momento. Na verdade, podemos inclusive
misturar essas notaes em expresses aritmticas como a seguir:
Para indicar que uma constante do tipo inteiro no tem sinal, devemos adicionar a letra
U ou u ao final da constante. Por exemplo, as constantes apresentadas abaixo so do tipo
unsigned int :
Podemos indicar que uma constante um nmero inteiro grande e sem sinal usando uma
combinao das letras acima, em qualquer ordem. Por exemplo, as constantes abaixo so do
tipo unsigned long int :
FACOM UFMS
98 T IPOS PRIMITIVOS DE DADOS
A funo printf usada para imprimir, entre outros, nmeros inteiros. Relembrando, a
funo printf tem o seguinte formato:
%[flags][comprimento][.preciso][hl]conversor
Flag Significado
- Valor alinhado esquerda
+ Valor precedido por + ou -
espaos Valor positivo precedido por espaos
0 Nmero preenchido com zeros esquerda
FACOM UFMS
11.1 T IPOS INTEIROS 99
int main(void)
{
short int i1;
unsigned short int i2;
int i3;
unsigned int i4;
long int i5;
unsigned long int i6;
i1 = 159;
i2 = 630u;
i3 = -991023;
i4 = 98979U;
i5 = 8393202L;
i6 = 34268298UL;
return 0;
}
Assim como para a funo printf , outras opes de formatao tambm esto disponveis
para a funo scanf , mais que aquelas vistas at esta aula. Neste caso tambm vale o conceito
de especificadores de converso. Quando uma funo scanf executada, especificadores de
converso so procurados na cadeia de caracteres de formatao (de leitura), aps o smbolo
usual % .
Os especificadores de converso h e l podem ser usados em uma cadeia de caracteres de
formatao de leitura, juntamente com a chamada da funo scanf , com o mesmo sentido que
na cadeia de caracteres de formatao de escrita, na funo printf , isto , para indicar que a
leitura ser feita como um nmero inteiro curto ou longo, respectivamente. Um comprimento
tambm pode ser usado, indicando o comprimento mximo do valor a ser armazenado na
varivel correspondente.
FACOM UFMS
100 T IPOS PRIMITIVOS DE DADOS
Especificador Significado
d valor a ser lido expresso em notao decimal; o argumento correspondente do tipo
int, a menos que os modificadores de converso h ou l tenham sido usados, casos
em que o valor ser short int ou long int, respectivamente
o valor a ser lido expresso na notao octal e pode opcionalmente ser precedido por 0;
o argumento correspondente um int, a menos que os modificadores de converso
h ou l tenham sido usados, casos em que short int ou long int,
respectivamente
x valor a ser lido expresso na notao hexadecimal e pode opcionalmente ser precedido
por 0x ou 0X; o argumento correspondente um unsigned int, a menos que os
modificadores de converso h ou l tenham sido usados, casos em que short int
ou long int, respectivamente
A funo scanf executada primeiro esperando por um valor a ser informado pelo usu-
rio e, depois, formatando este valor atravs do uso da cadeia de caracteres de formatao e do
especificador de converso.
A funo scanf finaliza uma leitura sempre que o usurio informa um branco, que o
caractere 32 (espao ou ), o caractere 9 (tabulao horizontal ou \t ), o caractere 10
(tabulao vertical ou \v ), o caractere 11 (retorno de carro/cursor ou \r ), o caractere 12
(mudana de linha ou \n ) ou o caractere 13 (avano de pgina ou \f ). Nesse sentido,
considere uma entrada como no trecho de cdigo abaixo:
prompt$ ./a.out
4 7
ou
prompt$ ./a.out
4
7
ou ainda
prompt$ ./a.out
4 7
FACOM UFMS
11.2 N MEROS COM PONTO FLUTUANTE 101
fcil notar que apenas os nmeros inteiros no so capazes de nos auxiliar na soluo dos
diversos problemas, mesmo quando encontramos formas de estender seu intervalo de valores,
como no caso da linguagem C. Dessa forma, valores reais se fazem muito necessrios, mais
especificamente para descrever nmeros imensamente grandes ou pequenos. Nmeros reais
so armazenados na linguagem C como nmeros com ponto flutuante.
A linguagem C fornece trs tipos de dados numricos com ponto flutuante:
float Ponto flutuante de preciso simples
double Ponto flutuante de preciso dupla
long double Ponto flutuante de preciso estendida
O tipo float usado quando a necessidade de preciso no crtica. O tipo double for-
nece maior preciso, suficiente para a maioria dos problemas. E o tipo long double fornece
a maior preciso possvel e raramente usado.
A linguagem C no estabelece padro para a preciso dos tipos com ponto flutuante, j
que diferentes computadores podem armazenar nmeros com ponto flutuante de formas dife-
rentes. Os computadores mais recentes seguem, em geral, as especificaes do Padro 754 da
IEEE. A tabela abaixo, mostrada na aula 9, mostra as caractersticas dos tipos numricos com
ponto flutuante quando implementados sob esse padro.
Constantes com ponto flutuante podem ser descritas de diversas formas. Por exemplo, as
constantes abaixo so formas vlidas de escrever o nmero 391,0:
Uma constante com ponto flutuante deve conter um ponto decimal e/ou um expoente,
que uma potncia de 10 pela qual o valor multiplicado. Se um expoente dado, deve vir
precedido da letra e ou E . Opcionalmente, um sinal + ou - pode ocorrer logo aps a letra.
Por padro, constantes com ponto flutuante so armazenadas como nmeros de ponto flu-
tuante de preciso dupla. Isso significa que, quando um compilador C encontra em um pro-
grama uma constante 391.0 , por exemplo, ele armazena esse nmero na memria no mesmo
formato de uma varivel do tipo double . Se for necessrio, podemos forar o compilador a
armazenar uma constante com ponto flutuante no formato float ou long double . Para in-
dicar preciso simples basta adicionar a letra f ou F ao final da constante, como por exemplo
391.0f . Para indicar preciso estendida necessrio adicionar a letra l ou L ao final da
constante, como por exemplo 391.0L .
FACOM UFMS
102 T IPOS PRIMITIVOS DE DADOS
%[flags][comprimento][.preciso][lL]conversor
11.3 Caracteres
Como mencionamos quando discutimos caracteres nas nossas aulas tericas e prticas, na
linguagem C cada caractere armazenado em um nico byte na memria do computador.
Assim, um caractere sem sinal um nmero do conjunto {0, . . . , 255} e um caractere com sinal
um nmero do conjunto {128, . . . , 1, 0, 1, . . . , 127}. Ou seja, um caractere uma seqncia
de 8 bits, dentre as 256 seqncias de 8 bits possveis. A impresso de um caractere na sada
padro a sua representao como um smbolo grfico. Por exemplo, o smbolo grfico do
caractere 97 a . Alguns caracteres tm representaes grficas especiais, como o caractere
10 que representado por uma mudana de linha.
Uma varivel do tipo caractere (com sinal) pode ser declarada na linguagem C com a pa-
lavra reservada char . Uma varivel do tipo caractere sem sinal pode ser declarada com a
mesma palavra reservada char , mas com o especificador de tipo unsigned a precedendo:
char c, d, e;
unsigned char f, g, h;
Uma constante do tipo caractere sem sinal um nmero no intervalo de 0 a 255 e uma
constante do tipo caractere com sinal uma constante no intervalo de 128 a 127. Por exemplo,
para as variveis c , d e e declaradas acima, podemos fazer
FACOM UFMS
11.3 C ARACTERES 103
c = 122;
d = 59;
e = 51;
Mais comum e confortavelmente, podemos especificar uma constante do tipo caractere atra-
vs da representao grfica de um caractere, envolvendo-o por aspas simples. Por exemplo,
z , ; e 3 so exemplos de constantes do tipo caractere. Assim, bem mais cmodo
fazer as atribuies
c = z;
d = ;;
e = 3;
Na linguagem C, um branco (do ingls whitespace) definido como sendo um caractere que
uma tabulao horizontal, uma mudana de linha, uma tabulao vertical, uma quebra de
pgina, um retorno de carro/cursor ou um espao. Ou seja, os caracteres 9, 10, 11, 12, 13 e 32
so brancos e as constantes correspondentes so \t , \n , \v , \f , \r e . A
funo scanf trata todos os brancos como se fossem , assim como outras funes tambm
o fazem.
O especificador de converso %c permite que as funes scanf e printf possam ler ou
escrever um nico caractere. importante reiterar que a funo scanf no salta caracteres
brancos antes de ler um caractere. Se o prximo caractere a ser lido foi digitado como um
espao ou uma mudana de linha, ento a varivel correspondente conter um espao ou uma
mudana de linha. Para forar a funo scanf desconsiderar espaos em branco antes da
leitura de um caractere, necessrio adicionar um espao na cadeia de caracteres de formatao
de leitura antes do especificador de formatao %c , como a seguir:
FACOM UFMS
104 T IPOS PRIMITIVOS DE DADOS
Programa 11.2: Conta o nmero de vogais minsculas na frase digitada pelo usurio.
#include <stdio.h>
return 0;
}
FACOM UFMS
11.3 C ARACTERES 105
prompt$ ./a.out
-10
2 0.33
27.8e3
Como, nesse caso, a leitura busca por nmeros, a funo ignora os brancos. Dessa forma, os
nmeros acima podem ser colocados todos em uma linha, separados por espaos, ou em vrias
linhas, como mostramos acima. A funo scanf enxerga a entrada acima como uma cadeia
de caracteres como abaixo:
-102 0.33 27.8e3
onde representa o caractere espao e representa o caractere de mudana de linha (ou a
tecla Enter ). Como a funo salta os brancos, ento os nmeros so lidos de forma correta.
Se a cadeia de caracteres de formatao de leitura contm caracteres usuais alm dos es-
pecificadores de tipo, ento o casamento dessa cadeia de caracteres e da cadeia de caracteres
de entrada se d de forma ligeiramente diferente. O processamento de um caractere usual na
cadeia de caracteres de formatao de uma funo scanf depende se o caractere um branco
ou no. Ou seja,
ento, a funo scanf salta o primeiro espao, associa %d com 2 , casa / e / , salta o espao
e associa %d com 33 . Por outro lado, se a entrada
2 / 33
a funo scanf salta o espao, associa %d com 2 , tenta casar o caractere / da cadeia de
caracteres de formatao com um espao da entrada e como esses caracteres no casam, a
funo termina e o restante / 33 da entrada permanecer armazenado na memria at que
uma prxima chamada funo scanf seja realizada.
FACOM UFMS
106 T IPOS PRIMITIVOS DE DADOS
Por convenincia e simplicidade, muitas vezes preferimos usar funes mais simples de
entrada e sada de caracteres. As funes getchar e putchar so funes da biblioteca
padro de entrada e sada da linguagem C e so usadas exclusivamente com caracteres. A
funo getchar l um caractere da entrada e devolve esse caractere. A funo putchar
toma um caractere como parmetro e o exibe na sada. Dessa forma, se c uma varivel do
tipo char as linhas a seguir:
scanf("%c", &c);
printf("%c", c);
c = getchar();
putchar(c);
Observe que a funo getchar no tem parmetros de entrada, mas, por ser uma funo,
carrega os parnteses como sufixo. Alm disso, essa funo devolve um caractere, que pode
ser usado em uma expresso. Nas linhas acima, getchar usada em uma atribuio. Por
outro lado, a funo putchar tem como parmetro uma expresso do tipo caractere que, aps
avaliada, seu valor ser exibido na sada. A funo putchar no devolve qualquer valor.
FACOM UFMS
11.4 C ONVERSO DE TIPOS 107
Veremos agora os dois primeiros casos, sendo que os dois ltimos sero vistos adiante.
As converses usuais em expresses so aplicadas aos operandos de todos os operadores bi-
nrios aritmticos, relacionais e lgicos. A linguagem C faz a converso dos operandos de
maneira que fiquem mais seguramente acomodados. Logo, o menor nmero de bits que mais
seguramente acomode os operandos ser usado nessa converso, se uma converso for de fato
necessria. As regras de converso de tipos podem ento ser divididas em dois tipos:
o tipo de pelo menos um dos operandos de ponto flutuante: se um dos operandos do tipo
long double , ento o outro operando ser convertido para o tipo long double . Caso
contrrio, se um dos operandos do tipo double , ento o outro operando ser con-
vertido para o tipo double . Seno, um dos operandos do tipo float e o outro ser
convertido para esse mesmo tipo;
nenhum dos operandos do tipo ponto flutuante: primeiro, se qualquer um dos operandos
do tipo char ou short int , ser convertido para o tipo int ; depois, se um dos ope-
randos do tipo unsigned long int , ento o outro operando ser convertido para o
tipo unsigned long int . Caso contrrio, se um dos operandos do tipo long int ,
ento o outro operando ser convertido para o tipo long int . Ainda, se um dos ope-
randos do tipo unsigned int , ento o outro operando ser convertido para o tipo
unsigned int . Por fim, um dos operandos do tipo int e o outro ser convertido
para esse mesmo tipo.
importante alertar para um caso em que uma operao envolve um dos operandos com
sinal e o outro sem sinal. Pelas regras acima, o operando com sinal convertido para um ope-
rando sem sinal. Assim, se um dos operandos do tipo int e contm um nmero negativo e
o outro operando do tipo unsigned int e contm um nmero positivo, ento uma opera-
o envolvendo esses dois operandos deve ser realizada cuidadosamente. Nesse caso, o valor
do tipo int ser promovido para o tipo unsigned int , mas a converso ser feita usando
a frmula k + 232 , onde k o valor com sinal. Esse problema uma das causas de erro mais
difceis de depurar. Veja o programa 11.3 para um exemplo bastante ilustrativo.
int main(void)
{
int i;
unsigned int j;
i = -1;
j = 1;
printf("i = %+d i = %u\n", i, (unsigned int) i);
printf("j = %+d j = %u\n", (int) j, j);
if (i < j)
printf("i < j\n");
else
printf("j < i\n");
return 0;
}
FACOM UFMS
108 T IPOS PRIMITIVOS DE DADOS
prompt$ ./a.out
i = -1 i = 4294967295
j = +1 j = 1
j < i
(nome-do-tipo) expresso
onde nome-do-tipo o nome de qualquer tipo primitivo de dados que ser usado para con-
verter o valor da expresso , aps sua avaliao.
Por exemplo, supondo que f e frac so variveis do tipo float , ento o trecho de
cdigo a seguir:
f = 123.4567f;
frac = f - (int) f;
far com que a varivel frac contenha apenas o valor da parte fracionria da varivel f .
A linguagem C, como vimos at aqui, possui poucos tipos primitivos de dados. No entanto,
ela permite que um(a) programador(a) possa definir seus prprios tipos de dados, de acordo
com sua convenincia. Para tanto, devemos usar a palavra reservada typedef no seguinte
formato geral:
FACOM UFMS
11.6 O PERADOR sizeof 109
Na primeira linha, typedef uma palavra reservada da linguagem C, int o tipo primi-
tivo de dados para nmeros inteiros com sinal e Logic o nome do novo tipo de dados
criado pelo(a) programador(a). Na segunda linha, ocorre a declarao de duas variveis do
tipo Logic : a varivel primo e a varivel crescente . O nome Logic desse novo tipo
foi descrito com a primeira letra maiscula, mas isso no uma obrigatoriedade. O novo tipo
Logic criado a partir de typedef faz com que o compilador o adicione a sua lista de tipos co-
nhecidos. Isso significa que podemos, a partir de ento, declarar variveis com esse tipo novo,
us-lo como operador conversor de tipo, entre outras coisas. Observe ainda que o compilador
trata Logic como um sinnimo para int . Dessa forma, as variveis primo e crescente
so, na verdade, variveis do tipo int .
Como principais vantagens podemos dizer que definies de tipos em programas permitem
fazer com que um cdigo torne-se mais compreensvel, mais fcil de modificar e mais fcil de
transportar de uma arquitetura de computadores para outra.
O operador unrio sizeof permite que se determine quanto de memria necessrio para
armazenar valores de um tipo qualquer. A expresso abaixo:
sizeof (nome-do-tipo)
determina um valor que um inteiro sem sinal representando o nmero de bytes necessrios
para armazenar um valor do tipo dado por nome-do-tipo .
Veja o programa 11.4.
int main(void)
{
printf("Caracteres: %lu\n", sizeof(char));
printf("Inteiros:\n");
printf(" short: %lu\n", sizeof(short int));
printf(" int: %lu\n", sizeof(int));
printf(" long int: %lu\n", sizeof(long int));
printf("Nmeros de ponto flutuante:\n");
printf(" float: %lu\n", sizeof(float));
printf(" double: %lu\n", sizeof(double));
printf(" long double: %lu\n", sizeof(long double));
return 0;
}
FACOM UFMS
110 T IPOS PRIMITIVOS DE DADOS
Caracteres: 1
Inteiros:
short: 2
int: 4
long int: 8
Nmeros de ponto flutuante:
float: 4
double: 8
long double: 16
11.7 Exerccios
Exerccios para treinar os conceitos aprendidos nesta aula. Faa muitos testes com suas
entradas e sadas.
11.1 Dadas n triplas compostas por um smbolo de operao aritmtica (+, , ou /) e dois
nmeros reais, calcule o resultado ao efetuar a operao indicada para os dois nmeros.
Faremos esse exerccio usando a estrutura condicional switch , que compara uma ex-
presso com uma seqncia de valores. Essa estrutura tem o seguinte formato:
FACOM UFMS
11.7 E XERCCIOS 111
printf("Informe n: ");
scanf("%d", &n);
for ( ; n > 0; n--) {
printf("Informe a expresso (ex.: 5.3 * 3.1): ");
scanf("%f %c%f", &op1, &operador, &op2);
switch (operador) {
case +:
result = op1 + op2;
break;
case -:
result = op1 - op2;
break;
case *:
result = op1 * op2;
break;
case /:
result = op1 / op2;
break;
default:
break;
}
printf("%f %c %f = %f\n", op1, operador, op2, result);
}
return 0;
}
11.3 Os babilnios descreveram a mais de 4 mil anos um mtodo para calcular a raiz quadrada
de um nmero. Esse mtodo ficou posteriormente conhecido como mtodo de Newton.
Dado um nmero x, o mtodo parte de um chute inicial y para o valor da raiz quadrada
de x e sucessivamente encontra aproximaes desse valor calculando a mdia aritmtica
FACOM UFMS
112 T IPOS PRIMITIVOS DE DADOS
x y x/y (y + x/y)/2
3 1 3 2
3 2 1.5 1.75
3 1.75 1.714286 1.732143
3 1.732143 1.731959 1.732051
3 1.732051 1.732051 1.732051
Escreva um programa que receba um nmero real positivo x e um nmero real e calcule
a raiz quadrada de x usando o mtodo de Newton, at que o valor absoluto da diferena
entre dois valores consecutivos de y seja menor que . Mostre tambm na sada a quanti-
dade de passos realizados para obteno da raiz de x.
FACOM UFMS
AULA 12
V ETORES
Os tipos primitivos de dados na linguagem C se caracterizam pelo fato que seus valores no
podem ser decompostos. Isso significa que um valor armazenado em uma varivel de um tipo
primitivo nico e no faz parte de uma composio de valores organizada de alguma maneira.
Tipos primitivos de dados tambm so de bsicos ou elementares. Por outro lado, se os valores
de um tipo de dados podem ser decompostos ou subdivididos em valores mais simples, ento
o tipo de dados chamado de complexo, composto ou estruturado. A organizao desses
valores e as relaes estabelecidas entre eles determinam o que conhecemos como estrutura de
dados. Nesta aula iniciaremos o estudo sobre variveis compostas, partindo de uma varivel
conhecida como varivel composta homognea unidimensional ou simplesmente vetor.
Esta aula inspirada nas referncias [16, 15].
12.1 Motivao
Dadas cinco notas de uma prova dos(as) estudantes de uma disciplina, calcular a
mdia das notas da prova e a quantidade de estudantes que obtiveram nota maior
que a mdia e a quantidade de estudantes que obtiveram nota menor que a mdia.
Uma tentativa natural e uma idia inicial para solucionar esse problema consiste no uso
de uma estrutura de repetio para acumular o valor das cinco notas informadas e o clculo
posterior da mdia destas cinco notas. Esses passos resolvem o problema inicial do clculo da
mdia das provas dos estudantes. Mas e a computao das quantidades de alunos que obti-
veram nota maior e menor que a mdia j computada? Observe que aps lidas as cinco notas
e processadas para o clculo da mdia em uma estrutura de repetio, a tarefa de encontrar
as quantidades de estudantes que obtiveram nota superior e inferior mdia impossvel, j
que as notas dos estudantes no esto mais disponveis na memria. Isto , a menos que o(a)
programador(a) pea ao usurio para informar as notas dos(as) estudantes novamente, no h
como computar essas quantidades.
Apesar disso, ainda podemos resolver o problema usando uma estrutura seqencial em
que todas as cinco notas informadas pelo usurio ficam armazenadas na memria e assim po-
demos posteriormente computar as quantidades solicitadas consultando estes valores. Veja o
programa 12.1.
113
114 V ETORES
menor = 0;
if (nota1 < media)
menor = menor + 1;
if (nota2 < media)
menor = menor + 1;
if (nota3 < media)
menor = menor + 1;
if (nota4 < media)
menor = menor + 1;
if (nota5 < media)
menor = menor + 1;
maior = 0;
if (nota1 > media)
maior = maior + 1;
if (nota2 > media)
maior = maior + 1;
if (nota3 > media)
maior = maior + 1;
if (nota4 > media)
maior = maior + 1;
if (nota5 > media)
maior = maior + 1;
return 0;
}
A soluo que apresentamos no programa 12.1 uma soluo correta para o problema.
Isto , dadas as cinco notas dos(as) estudantes em uma prova, o programa computa as sadas
que esperamos, ou seja, as quantidades de estudantes com nota inferior e superior mdia
da prova. No entanto, o que aconteceria se a sala de aula tivesse mais estudantes, como por
exemplo 100? Ou 1000 estudantes? Certamente, as estruturas seqencial e condicional no
seriam apropriadas para resolver esse problema, j que o(a) programador(a) teria de digitar
centenas ou milhares de linhas repetitivas, incorrendo inclusive na possibilidade de propaga-
o de erros e na dificuldade de encontr-los. E assim como esse, outros problemas no podem
ser resolvidos sem uma extenso na maneira de armazenar e manipular as entradas de dados.
FACOM UFMS
12.2 D EFINIO 115
12.2 Definio
tipo identificador[dimenso];
onde:
float nota[100];
faz com que 100 clulas contguas de memria sejam reservadas, cada uma delas podendo
armazenar nmeros de ponto flutuante do tipo float . A referncia a cada uma dessas clulas
realizada pelo identificador do vetor nota e por um ndice. Na figura 12.1 mostramos o
efeito da declarao do vetor nota na memria de um computador.
0 1 2 98 99
memria
nota
Observe que, na linguagem C, a primeira clula de um vetor tem ndice 0, a segunda clula
tem ndice 1, a terceira tem ndice 2 e assim por diante. Para referenciar o contedo da clula 0
do vetor nota , devemos usar o identificador do vetor e o ndice 0, envolvido por colchetes, isto
, nota[0] . Assim, o uso de nota[35] em uma expresso qualquer referencia o trigsimo
FACOM UFMS
116 V ETORES
sexto elemento do vetor nota . Podemos, tambm, usar uma varivel do tipo inteiro como
ndice de um vetor ou ainda uma expresso aritmtica do tipo inteiro. Por exemplo, nota[i]
acessa a (i + 1)-sima clula do vetor nota . Ou ainda, podemos fazer nota[2*i+j] para
acessar a posio de ndice 2i + j + 1 do vetor nota . O compilador da linguagem C no
verifica de antemo se os limites dos ndices de um vetor esto corretos, trabalho que deve ser
realizado pelo(a) programador(a).
Um erro comum, aparentemente inocente, mas que pode ter causas desastrosas, mostrado
no trecho de cdigo abaixo:
int A[10], i;
for (i = 1; i <= 10; i++)
A[i] = 0;
Alguns compiladores podem fazer com que a estrutura de repetio for acima seja execu-
tada infinitamente. Isso porque quando a varivel i atinge o valor 10 , o programa armazena
o valor 0 em A[10] . Observe, no entanto, que A[10] no existe e assim 0 armazenado
no compartimento de memria que sucede A[9] . Se a varivel i ocorre na memria logo
aps A[9] , como bem provvel, ento i receber o valor 0 fazendo com que o lao inicie
novamente.
Podemos atribuir valores iniciais a quaisquer variveis de qualquer tipo primitivo no mo-
mento de suas respectivas declaraes. At o momento, no havamos usado declaraes e
inicializaes em conjunto. O trecho de cdigo abaixo mostra declaraes e inicializaes si-
multneas de variveis de tipos primitivos:
char c = a;
int num, soma = 0;
float produto = 1.0, resultado;
FACOM UFMS
12.4 E XEMPLO COM VETORES 117
Vamos agora resolver o problema da seo 12.1 do clculo das mdias individuais de es-
tudantes e da verificao da quantidade de estudantes com mdia inferior e tambm superior
mdia da classe. Solucionaremos esse problema construindo um programa que usa veto-
res e veremos como nossa soluo se mostra muito mais simples, mais eficiente e facilmente
extensvel para qualquer quantidade de estudantes que se queira. Vejamos o programa 12.2.
Observe que o programa 12.2 mais conciso e de mais fcil compreenso que o pro-
grama 12.1. O programa tambm mais facilmente extensvel, no sentido que muito poucas
modificaes so necessrias para que esse programa possa solucionar problemas semelhan-
tes com outras quantidades de estudantes. Isto , se a turma tem 5, 10 ou 100 estudantes, ou
ainda um nmero desconhecido n que ser informado pelo usurio durante a execuo do pro-
grama, uma pequena quantidade de esforo ser necessria para alterao de poucas linhas do
programa.
FACOM UFMS
118 V ETORES
soma = 0.0;
for (i = 0; i < 5; i++)
soma = soma + nota[i];
media = soma / 5;
menor = 0;
maior = 0;
for (i = 0; i < 5; i++) {
if (nota[i] < media)
menor++;
if (nota[i] > media)
maior++;
}
return 0;
}
Em geral, quando um programa contm constantes, uma boa idia dar nomes a essas
constantes. Podemos atribuir um nome ou identificador a uma constante usando a definio
de uma macro. Uma macro definida atravs da diretiva de pr-processador #define e tem
o seguinte formato geral:
FACOM UFMS
12.5 M ACROS PARA CONSTANTES 119
#define CARAC a
#define NUMERADOR 4
#define MIN -10000
#define TAXA 0.01567
#define PI 3.141592f
return 0;
}
O uso de macros com vetores bastante til porque, como j vimos, um vetor faz alo-
cao esttica da memria, o que significa que em sua declarao ocorre uma reserva prvia
de um nmero fixo de compartimentos de memria. Por ser uma alocao esttica, no h
possibilidade de aumento ou diminuio dessa quantidade aps a execuo da linha de c-
digo contendo a declarao do vetor. O programa 12.2 pode ser ainda modificado como no
programa 12.4 com a incluso de uma macro que indica a quantidade de notas a serem proces-
sadas.
A macro MAX usada quatro vezes no programa 12.4: na declarao do vetor nota , nas
expresses relacionais das duas estruturas de repetio for e no clculo da mdia. A van-
tagem de se usar uma macro que, caso seja necessrio modificar a quantidade de notas do
programa por novas exigncias do usurio, isso pode ser feito rpida e facilmente em uma
nica linha do cdigo, onde ocorre a definio da macro.
FACOM UFMS
120 V ETORES
Programa 12.4: Soluo do problema proposto na seo 12.1 usando uma macro e um vetor.
#include <stdio.h>
#define MAX 5
soma = 0.0;
for (i = 0; i < MAX; i++)
soma = soma + nota[i];
media = soma / MAX;
menor = 0;
maior = 0;
for (i = 0; i < MAX; i++) {
if (nota[i] < media)
menor++;
if (nota[i] > media)
maior++;
}
return 0;
}
Exerccios
12.1 Dada uma seqncia de n nmeros inteiros, com 1 6 n 6 100, imprimi-la em ordem
inversa de leitura.
12.2 Uma prova consta de 30 questes, cada uma com cinco alternativas identificadas pelas
letras A, B, C, D e E. Dado o carto gabarito da prova e o carto de respostas de n estu-
dantes, com 1 6 n 6 100, computar o nmero de acertos de cada um dos estudantes.
12.3 Tentando descobrir se um dado era viciado, um dono de cassino o lanou n vezes. Dados
os n resultados dos lanamentos, determinar o nmero de ocorrncias de cada face.
12.4 Um jogador viciado de cassino deseja fazer um levantamento estatstico simples sobre
uma roleta. Para isso, ele fez n lanamentos nesta roleta. Sabendo que uma roleta contm
FACOM UFMS
12.5 M ACROS PARA CONSTANTES 121
printf("Informe n: ");
scanf("%d", &n);
for (i = 0; i < n; i++) {
printf("Informe o nmero %d: ", i+1);
scanf("%d", &A[i]);
}
printf("Nmeros na ordem inversa da leitura:\n");
for (i = n-1; i >= 0; i--)
printf("%d ", A[i]);
printf("\n");
return 0;
}
37 nmeros (de 0 a 36), calcular a freqncia de cada nmero desta roleta nos n lana-
mentos realizados.
12.5 Dados dois vetores x e y, ambos com n elementos, 1 6 n 6 100, determinar o produto
escalar desses vetores.
p(x) = a0 + a1 x + . . . + an xn e q(x) = b0 + b1 x + . . . + bm xm
12.9 Dadas duas seqncias com n nmeros inteiros entre 0 e 9, interpretadas como dois n-
meros inteiros de n algarismos, 1 6 n 6 100, calcular a seqncia de nmeros que repre-
senta a soma dos dois inteiros.
Exemplo:
n = 8,
1a seqncia 8 2 4 3 4 2 5 1
2a seqncia + 3 3 7 5 2 3 3 7
1 1 6 1 8 6 5 8 8
FACOM UFMS
122 V ETORES
12.10 Dados dois nmeros naturais m e n, com 1 6 m, n 6 100, e duas seqncias ordenadas
com m e n nmeros inteiros, obter uma nica seqncia ordenada contendo todos os
elementos das seqncias originais sem repetio.
12.11 Dada uma seqncia de n nmeros inteiros, com 1 6 n 6 100, imprimi-la em ordem
crescente de seus valores.
12.12 Dizemos que uma seqncia de n elementos, com n par, balanceada se as seguintes
somas so todas iguais:
Exemplo:
2 12 3 6 16 15 uma seqncia balanceada, pois 16 + 2 = 15 + 3 = 12 + 6.
Dados n (n par e 0 6 n 6 100) e uma seqncia de n nmeros inteiros, verificar se essa
seqncia balanceada.
12.13 Dada uma seqncia x1 , x2 , . . . , xk de nmeros inteiros, com 1 6 k 6 100, verifique se
existem dois segmentos consecutivos iguais nesta seqncia, isto , se existem i e m tais
que
xi , xi+1 , . . . , xi+m1 = xi+m , xi+m+1 , . . . , xi+2m1 .
Imprima, caso existam, os valores de i e m.
Exemplo:
Na seqncia 7, 9, 5, 4, 5, 4, 8, 6 existem i = 3 e m = 2.
12.14 Dadas duas seqncias de caracteres (uma contendo uma frase e outra contendo uma
palavra), determine o nmero de vezes que a palavra ocorre na frase. Considere que
essas seqncias tm no mximo 100 caracteres cada uma.
Exemplo:
Para a palavra ANA e a frase:
ANA E MARIANA GOSTAM DE BANANA.
Temos que a palavra ocorre 4 vezes na frase.
12.15 So dadas as coordenadas reais x e y de um ponto, um nmero natural n e as coordenadas
reais de n pontos, com 1 6 n 6 100. Deseja-se calcular e imprimir sem repetio os
raios das circunferncias centradas no ponto (x, y) que passem por pelo menos um dos n
pontos dados.
Exemplo:
(x, y) = (1.0, 1.0)
n=5
Pontos: (1.0, 1.2), (1.5, 2.0), (0.0, 2.0), (0.0, 0.5), (4.0, 2.0)
Nesse caso h trs circunferncias de raios 1.12, 2.01 e 3.162.
Observaes:
FACOM UFMS
12.5 M ACROS PARA CONSTANTES 123
p
(a) A distncia entre os pontos (a, b) e (c, d) (a c)2 + (b d)2 .
(b) Dois pontos esto na mesma circunferncia se esto mesma distncia do centro.
FACOM UFMS
124 V ETORES
FACOM UFMS
AULA 13
C ADEIAS DE CARACTERES
Veremos nesta aula uma estrutura que possui tratamento especial na linguagem C: a cadeia
de caracteres. Esta estrutura similar a um vetor de caracteres, diferenciando-se apenas por
conter um caracter especial no final, aps o ltimo caracter vlido. Essa caracterstica evita, em
muitos casos, que tenhamos de manter uma varivel que contenha o comprimento do vetor
para saber o nmero de caracteres contidos nele. Outras caractersticas e diferenas importan-
tes sero vistas a seguir.
Diversas funes que manipulam cadeias de caracteres esto disponveis na biblioteca
string.
Esta aula inspirada nas referncias [15, 16].
13.1 Literais
Vimos tomando contato com cadeias de caracteres desde quando escrevemos nosso pri-
meiro programa na linguagem C. Por exemplo, na sentena abaixo:
printf("Programar bacana!\n");
o nico argumento passado para a funo printf a cadeia de caracteres (de formatao)
"Programar bacana!\n" . As aspas duplas so usadas para delimitar uma constante do
tipo cadeia de caracteres, que pode conter qualquer combinao de letras, nmeros ou caracte-
res especiais que no sejam as aspas duplas. Mesmo assim, possvel inserir as aspas duplas
no interior de uma constante cadeia de caracteres, inserindo a seqncia \" nessa cadeia. Na
linguagem C, uma constante do tipo cadeia de caracter chamada de literal.
Quando estudamos o tipo de dados char , aprendemos que uma varivel deste tipo pode
conter apenas um nico caracter. Para atribuir um caracter a uma varivel, o caracter deve ser
envolvido por aspas simples. Dessa forma, o trecho de cdigo a seguir:
char sinal;
sinal = +;
125
126 C ADEIAS DE CARACTERES
tem o efeito de atribuir o caractere cuja constante + para a varivel sinal . Alm disso,
aprendemos que existe uma distino entre as aspas simples e as aspas duplas, sendo que no
primeiro caso elas servem para definir constantes do tipo caracter e no segundo para definir
constantes do tipo cadeia de caracteres. Assim, o seguinte trecho de cdigo:
char sinal;
sinal = "+";
no est correto, j que que a varivel sinal foi declarada do tipo char , podendo conter um
nico caracter. Lembre-se que na linguagem C as aspas simples e as aspas duplas so usadas
para definir dois tipos de constantes diferentes.
Usamos literais especialmente quando chamamos as funes printf e scanf em um
programa, ou seja, quando descrevemos cadeias de caracteres de formatao. Essencialmente,
a linguagem C trata as literais como cadeias de caracteres. Quando o compilador da linguagem
C encontra uma literal com n caracteres em um programa, ele reserva n + 1 compartimentos de
memria para armazenar a cadeia de caracteres correspondente. Essa rea na memria conter
os caracteres da cadeia mais um caractere extra, o caractere nulo, que registra o final da cadeia.
O caractere nulo um byte cujos bits so todos 0 (zeros) e representado pela seqncia \0 .
importante destacar a diferena entre o caractere nulo e o caractere zero: o primeiro um
caractere no-imprimvel, tem valor decimal 0 e constante \0 ; o segundo um caractere
imprimvel, tem valor 48, smbolo grfico 0 e constante 0 .
A literal "abc" armazenada como um vetor de quatro caracteres na memria, como
mostra a figura 13.1.
a b c \0
Por outro lado, uma literal tambm pode ser vazia. A literal "" uma literal vazia, repre-
sentada na memria como na figura 13.2.
\0
Se queremos trabalhar com variveis que comportam mais que um nico caracter, temos de
trabalhar com vetores de caracteres. No exerccio 13.6, devemos definir dois vetores palavra
e frase do tipo caracter, da seguinte forma:
FACOM UFMS
13.3 C ADEIAS DE CARACTERES 127
Para ler, por exemplo, o contedo da varivel palavra , produzimos o seguinte trecho de
programa:
Para imprimir o contedo dessa mesma varivel palavra , devemos escrever um trecho de
programa da seguinte forma:
printf("Palavra: ");
for (i = 0; i < m; i++)
printf("%c", palavra[i]);
printf("\n");
Note que sempre necessitamos de uma varivel adicional para controlar o comprimento
de um vetor de caracteres quando da sua leitura. A varivel m faz esse papel no primeiro
trecho de programa acima. Alm disso, tanto para leitura como para escrita de um vetor de
caracteres, precisamos de uma estrutura de repetio para processar os caracteres um a um.
Com as cadeias de caracteres, evitamos esta sobrecarga de trabalho para o programador, como
veremos daqui por diante.
FACOM UFMS
128 C ADEIAS DE CARACTERES
#define MAX 50
char cadeia[MAX+1];
Na declarao de uma varivel que pode armazenar uma cadeia de caracteres, sempre de-
vemos reservar um compartimento a mais para que o caractere nulo possa ser armazenado.
Como diversas funes da linguagem C supem que as cadeias de caracteres so terminadas
com o caractere nulo, se isso no ocorre em algum caso, o comportamento do programa passa
a ser imprevisvel.
A declarao de um vetor de caracteres com dimenso MAX+1 no quer dizer que ele sem-
pre conter uma cadeia de caracteres com MAX caracteres. O comprimento de uma cadeia de
caracteres depende da posio do caractere nulo na cadeia, no do comprimento do vetor onde
a cadeia est armazenada.
Como em qualquer vetor, uma cadeia de caracteres tambm pode ser declarada e iniciali-
zada simultaneamente. Por exemplo,
printf("%s\n", palavra);
FACOM UFMS
13.3 C ADEIAS DE CARACTERES 129
int main(void)
{
char palavra[10] = "Ola!";
int n;
n = 0;
while (palavra[n] != \0)
n++;
printf("O comprimento da palavra %d\n", n);
return 0;
}
pode ser usada para mostrar o contedo completo da cadeia de caracteres palavra na sada
padro. Quando a funo printf encontra o especificador de converso %s , supe que o
argumento correspondente uma cadeia de caracteres, isto , um vetor de caracteres terminado
por um caractere nulo.
Podemos tambm usar a mesma cadeia de caracteres de formatao "%s" para leitura de
uma cadeia de caracteres. A funo scanf pode ser usada com o especificador de converso
%s para ler uma cadeia de caracteres at que a leitura de um branco seja realizada. Assim, a
chamada da funo scanf abaixo:
scanf("%s", palavra);
tem o efeito de ler uma cadeia de caracteres digitada pelo usurio e de armazen-la no vetor
de caracteres palavra .
muito importante ressaltar que, ao contrrio das chamadas anteriores da funo scanf ,
no caso de leitura de cadeias de caracteres, o smbolo & no adicionado como prefixo do
identificador da varivel. Veremos o porqu disto quando estudarmos apontadores.
Se na execuo da funo scanf anterior um(a) usurio(a) digita os caracteres abcdefg , a
cadeia de caracteres "abcdefg" armazenada no vetor palavra . Se, diferentemente, um(a)
usurio(a) digita os caracteres Campo Grande , ento apenas a cadeia de caracteres "Campo"
armazenada no vetor palavra , devido ao branco ( ). Os caracteres restantes da cadeia di-
gitada ficaro disponveis no buffer de entrada at que uma prxima chamada funo scanf
seja realizada.
Para evitar os brancos na leitura de uma cadeia de caracteres, usamos o especificador de
converso %[...] , que tambm usado na leitura de cadeias de caracteres, delimitando, den-
tro dos colchetes, quais so os caracteres permitidos em uma leitura. Qualquer outro caractere
diferente dos especificados dentro dos colchetes finalizam a leitura. Alm disso, podemos in-
verter essas permisses, indicando o caractere ^ como o primeiro caractere dentro dos colche-
tes. Por exemplo,
FACOM UFMS
130 C ADEIAS DE CARACTERES
scanf("%[^\n]", palavra);
realiza a leitura de uma cadeia de caracteres, armazenando seu contedo no vetor de carac-
teres palavra . O caracter que finaliza a leitura o \n . Qualquer outro caracter ser lido e
armazenado no vetor palavra .
muito importante destacar que a funo scanf termina automaticamente uma cadeia de
caracteres que lida com o especificador de converso "%s" ou "%[...]" com um caracter
nulo, fazendo assim que o vetor de caracteres se torne de fato uma cadeia de caracteres aps
sua leitura.
Veja um exemplo simples do uso dos conceitos de entrada e sada de cadeias de caracteres
no programa 13.2.
#define MAX 20
return 0;
}
Exerccios
13.1 Dada uma frase com no mximo 100 caracteres, determinar quantos caracteres espao a
frase contm.
13.2 Dada uma cadeia de caracteres com no mximo 100 caracteres, contar a quantidade de
letras minsculas, letras maisculas, dgitos, espaos e smbolos de pontuao que essa
cadeia possui.
13.3 Dadas duas cadeias de caracteres cadeia1 e cadeia2 , concatenar cadeia2 no final
de cadeia1 , colocando o caracter nulo no final da cadeia resultante. A cadeia resultante
a ser mostrada deve estar armazenada em cadeia1 . Suponha que as cadeias sejam
informadas com no mximo 100 caracteres.
FACOM UFMS
13.3 C ADEIAS DE CARACTERES 131
esp = 0;
for (i = 0; frase[i] != \0; i++)
if (frase[i] == )
esp++;
return 0;
}
13.4 Dada uma cadeia de caracter cadeia com no mximo 100 caracteres e um caractere c ,
buscar a primeira ocorrncia de c em cadeia . Se c ocorre em cadeia , mostrar a
posio da primeira ocorrncia; caso contrrio, mostrar o valor -1 .
13.5 Dadas duas cadeias de caracteres cadeia1 e cadeia2 , cada uma com no mximo 100
caracteres, compar-las e devolver um valor menor que zero se cadeia1 lexicografica-
mente menor que cadeia2 , o valor zero se cadeia1 igual ou tem o mesmo contedo
que cadeia2 , ou um valor maior que zero se cadeia1 lexicograficamente maior que
cadeia2 .
13.6 Dadas duas seqncias de caracteres (uma contendo uma frase e outra contendo uma
palavra), determine o nmero de vezes que a palavra ocorre na frase. Considere que
essas seqncias tm no mximo 100 caracteres cada uma.
Exemplo:
FACOM UFMS
132 C ADEIAS DE CARACTERES
FACOM UFMS
AULA 14
M ATRIZES
Na aula 12, tivemos contato com vetores ou variveis compostas homogneas unidimen-
sionais. No entanto, uma varivel composta homognea pode ter qualquer nmero de di-
menses. A partir desta aula, aprenderemos a trabalhar com as estruturas denominadas de
matrizes ou variveis compostas homogneas bidimensionais. Do mesmo modo como vimos
com os vetores, as matrizes so variveis porque podem ter os valores de suas clulas alterados
durante a execuo do algoritmo/programa, compostas porque representam a composio de
um conjunto de valores indivisveis, homogneas porque esses valores so de um mesmo tipo
de dados e bidimensionais porque, ao contrrio dos vetores que so lineares ou tm uma nica
dimenso, estas estruturas tm duas dimenses. A extenso de variveis compostas homog-
neas para trs ou mais dimenses simples e imediata, como veremos posteriormente. Nesta
aula, que tem como referncias os livros [15, 16], aprenderemos a declarar matrizes, a declarar
e inicializar simultaneamente as matrizes e tambm a usar matrizes para solucionar problemas.
tipo identificador[dimenso1][dimenso2];
133
134 M ATRIZES
onde tipo um dos tipos de dados da linguagem C ou um tipo definido pelo(a) progra-
mador(a), identificador o nome da varivel matriz fornecido pelo(a) programador(a) e
dimenso1 e dimenso2 determinam a quantidade de linhas e colunas, respectivamente, a
serem disponibilizadas para uso na matriz. Por exemplo, a declarao a seguir:
int A[20][30];
faz com que 600 clulas de memria sejam reservadas, cada uma delas podendo armazenar
valores do tipo int . A referncia a cada uma dessas clulas realizada pelo identificador da
matriz A e por dois ndices, o primeiro que determina a linha e o segundo que determina a
coluna da matriz. Veja a figura 14.1.
A 0 1 2 28 29
18
19
Na linguagem C, a primeira linha de uma matriz tem ndice 0, a segunda linha tem ndice
1, e assim por diante. Do mesmo modo, a primeira coluna da matriz tem ndice 0, a segunda
tem ndice 1 e assim por diante. Para referenciar o valor da clula da linha 0 e da coluna 3 da
matriz A , devemos usar o identificador da varivel e os ndices 0 e 3 envolvidos por colchetes,
ou seja, A[0][3] .
Apesar de visualizarmos uma matriz na forma de uma tabela bidimensional, essa no a
forma de armazenamento dessa varivel na memria. A linguagem C armazena uma matriz
na memria linha a linha, como mostrado na figura 14.2 para a matriz A .
FACOM UFMS
14.2 D ECLARAO E INICIALIZAO SIMULTNEAS 135
Da mesma forma como com os vetores, uma matriz pode ser inicializada no momento de
sua declarao. Na verdade, variveis compostas de qualquer dimenso podem ser iniciali-
zadas seguindo as mesmas regras. Para uma matriz, a declarao e inicializao simultneas
deve ser realizada agrupando os inicializadores de uma dimenso como abaixo:
Na declarao e inicializao acima, cada inicializador fornece valores para uma linha da ma-
triz. A linguagem C possui algumas pequenas regras para declarar e inicializar matrizes ou
variveis compostas homogneas de qualquer dimenso:
inicializa as duas primeiras linhas da matriz A . As duas ltimas linhas sero inicializa-
das com 0 (zero);
se um inicializador mais interno no longo o suficiente para inicializar uma linha, ento
o restante dos elementos na linha inicializado com 0 (zero). Por exemplo,
as chaves internas, que determinam as inicializaes das linhas, podem ser omitidas.
Neste caso, uma vez que o compilador tenha lido elementos suficientes para preencher
uma linha, ele o faz e inicia o preenchimento da prxima linha. Por exemplo,
FACOM UFMS
136 M ATRIZES
14.3 Exemplo
Dada uma matriz real B, de 5 linhas e 10 colunas, calcule o somatrio dos elementos
da oitava coluna e que calcule o somatrio da terceira linha.
return 0;
}
Exerccios
14.1 Dadas duas matrizes de nmeros inteiros A e B, de dimenses mn, com 1 6 m, n 6 100,
fazer um programa que calcule a matriz Cmn = A + B.
14.2 Faa um programa que, dada uma matriz de nmeros reais Amn , determine At . Supo-
nha que 1 6 m, n 6 100.
14.3 Dada uma matriz de nmeros reais A com m linhas e n colunas, 1 6 m, n 6 100, e um
vetor de nmeros reais v com n elementos, determinar o produto de A por v.
14.4 Um vetor de nmeros reais x com n elementos apresentado como resultado de um
sistema de equaes lineares Ax = b, cujos coeficientes so representados em uma matriz
de nmeros reais Amn e o lados direitos das equaes em um vetor de nmeros reais
b de m elementos. Dados A, x e b, verificar se o vetor x realmente soluo do sistema
Ax = b, supondo que 1 6 m, n 6 100.
FACOM UFMS
14.3 E XEMPLO 137
return 0;
}
14.5 Dadas duas matrizes de nmeros reais Amn e Bnp , com 1 6 m, n, p 6 100, calcular o
produto de A por B.
14.6 Dada uma matriz de nmeros inteiros Amn , com 1 6 m, n 6 100, imprimir o nmero de
linhas e o nmero de colunas nulas da matriz.
Exemplo:
FACOM UFMS
138 M ATRIZES
14.7 Dizemos que uma matriz de nmeros inteiros Ann uma matriz de permutao se em
cada linha e em cada coluna houver n 1 elementos nulos e um nico elemento 1.
Exemplo:
0 0 0 1
Observe que
2 1 0
1 2 0
0 0 1
no de permutao.
Dada uma matriz de nmeros inteiros Ann , com 1 6 n 6 100, verificar se A de permu-
tao.
14.8 Dada uma matriz de nmeros reais Amn , com 1 6 m, n 6 100, verificar se existem
elementos repetidos em A.
14.9 Dizemos que uma matriz quadrada de nmeros inteiros distintos um quadrado m-
gico1 se a soma dos elementos de cada linha, a soma dos elementos de cada coluna e a
soma dos elementos da diagonal principal e secundria so todas iguais.
Exemplo:
A matriz
8 0 7
4 5 6
3 10 2
um quadrado mgico.
Dada uma matriz quadrada de nmeros inteiros Ann , com 1 6 n 6 100, verificar se A
um quadrado mgico.
FACOM UFMS
14.3 E XEMPLO 139
14.11 Um jogo de palavras cruzadas pode ser representado por uma matriz Amn onde cada
posio da matriz corresponde a um quadrado do jogo, sendo que 0 indica um quadrado
branco e 1 indica um quadrado preto. Indicar em uma dada matriz Amn de 0 e 1,
com 1 6 m, n 6 100, as posies que so incio de palavras horizontais e/ou verticais nos
quadrados correspondentes (substituindo os zeros), considerando que uma palavra deve
ter pelo menos duas letras. Para isso, numere consecutivamente tais posies.
Exemplo:
Dada a matriz
0 1 0 1 1 0 1 0
0 0 0 0 1 0 0 0
0 0 1 1 0 0 1 0
1 0 0 0 0 1 0 0
0 0 1 0 0 0 1 1
a sada dever ser
1 1 2 1 1 3 1 4
5 6 0 0 1 7 0 0
8 0 1 1 9 0 1 0 .
1 10 0 11 0 1 12 0
13 0 1 14 0 0 1 1
14.12 Os elementos aij de uma matriz de nmeros inteiros Ann representam os custos de trans-
porte da cidade i para a cidade j. Dados uma matriz Ann , com 1 6 n 6 100, um nmero
inteiro m > 0 representando a quantidade de itinerrios, um nmero k representando o
nmero de cidades em cada um dos itinerrios, calcular o custo total para cada itinerrio.
Exemplo:
Dado
4 1 2 3
5 2 1 400
A=
2
1 3 8
7 1 2 5
m = 1, k = 8 e o itinerrio 0 3 1 3 3 2 1 0, o custo total desse itinerrio
FACOM UFMS
140 M ATRIZES
a c a t g u d k h
q y u s z j l l c
b m a m o r a w e
p f a x v n e t q
o c g j u a t d k
h j o a q y s c z amora
z l c a d b m o r
o b g j h c t a w
t s y z l o k e u
q b r s o a e p h
r o d o m a y s l
m u l q c k a z g
14.14 Considere n cidades numeradas de 0 a n 1 que esto interligadas por uma srie de
estradas de mo nica, com 1 6 n 6 100. As ligaes entre as cidades so representadas
pelos elementos de uma matriz quadrada Ann , cujos elementos aij assumem o valor 1 ou
0, conforme exista ou no estrada direta que saia da cidade i e chegue cidade j. Assim,
os elementos da coluna j indicam as estradas que chegam cidade j. Por conveno
aii = 1.
A figura abaixo mostra um exemplo para n = 4.
0 1 2 3
A 0 1 2 3
0 1 1 1 0
1 1 1 1 0
2 1 0 1 0
3 0 1 1 1
FACOM UFMS
14.3 E XEMPLO 141
FACOM UFMS
142 M ATRIZES
FACOM UFMS
AULA 15
R EGISTROS
15.1 Definio
Uma varivel composta heterognea ou registro uma estrutura onde podemos armaze-
nar valores de tipos diferentes sob uma mesma entidade lgica. Cada um desses possveis
valores armazenado em um compartimento do registro denominado campo do registro, ou
simplesmente campo. Um registro composto pelo seu identificador e pelos seus campos.
Suponha que queremos trabalhar com um agrupamento de valores que representam uma
determinada mercadoria de uma loja, cujas informaes relevantes so o cdigo do produto e
seu valor. Na linguagem C, podemos ento declarar um registro com identificador produto
da seguinte forma:
struct {
int codigo;
int quant;
float valor;
} produto;
1
struct e member (of a structure) so jarges comuns na linguagem C. A traduo literal dessas palavras pode nos
confundir com outros termos j usados durante o curso. Por isso, escolhemos registro e campo (do registro) como
tradues para o portugus.
143
144 R EGISTROS
produto
memria
struct {
.
.
.
bloco de declaraes
.
.
.
} identificador;
Podemos declarar outras variveis do tipo registro com os mesmos campos da varivel
produto , declarada acima, da seguinte forma:
struct {
int codigo;
int quant;
float valor;
} produto, estoque, baixa;
struct {
char sala, turma;
int horas_inicio, minutos_inicio, horas_fim, minutos_fim;
float largura, comprimento;
} aula;
FACOM UFMS
15.1 D EFINIO 145
declara um registro com identificador aula com seis campos, dois campos do tipo char ,
quatro outros campos do tipo int e dois campos do tipo float . Apesar dessa declarao
estar correta e de economizar algumas linhas de cdigo, sempre optamos pela declarao dos
campos separadamente, linha a linha, para que os campos fiquem bem destacados e, assim,
facilitem sua identificao rpida no cdigo. Dessa forma, em geral optamos pela seguinte
declarao do registro aula :
struct {
char sala;
char turma;
int horas_inicio;
int minutos_inicio;
int horas_fim;
int minutos_fim;
float largura;
float comprimento;
} aula;
produto.codigo = 12;
produto.quant = 5;
produto.valor = 34.5;
Observe acima que, quando referenciamos um campo de uma varivel do tipo registro, no
so permitidos espaos entre o identificador do registro, o operador ponto e o identificador
do campo.
Tambm podemos usar o valor de um campo de um registro em quaisquer expresses. Por
exemplo, a expresso relacional abaixo correta:
Declaraes de registros diferentes podem conter campos com mesmo identificador. Por
exemplo,
FACOM UFMS
146 R EGISTROS
struct {
char tipo;
char fatorRH;
int idade;
float altura;
} coleta;
struct {
char codigo;
int tipo;
int idade;
} certidao;
so declaraes vlidas na linguagem C. O acesso aos campos dessas variveis se diferencia jus-
tamente pelo identificador dos registros. Isto , a partir das declaraes dos registros coleta
e certidao , as atribuies abaixo esto corretas:
coleta.tipo = O;
certidao.tipo = 0;
coleta.idade = 29;
certidao.idade = coleta.idade + 2;
struct {
int codigo;
int quant;
float valor;
} produto = {1, 5, 34.5};
Neste caso, o campo codigo inicializado com o valor 1 , o campo quant inicializado
com o valor 5 e o campo valor com 34.5 . Como mencionado, as regras de declarao e
inicializao simultneas para registros so equivalentes quelas para vetores. Assim,
struct {
int codigo;
int quant;
float valor;
} produto = {0};
far a inicializao dos campos codigo e quant com 0 e do campo valor com 0.0 .
FACOM UFMS
15.3 O PERAES SOBRE REGISTROS 147
A = B;
Por outro lado, quando tratamos de registros, podemos fazer uma atribuio direta e reali-
zar a cpia de todos os seus campos nessa nica atribuio. O trecho de cdigo a seguir mostra
um exemplo com a declarao de dois registros com mesmos campos, a atribuio de valores
ao primeiro registro e uma cpia completa de todos os campos do primeiro registro para o
segundo:
.
.
.
struct {
char tipo;
int codigo;
int quant;
float valor;
} mercadoria1, mercadoria2;
.
.
.
mercadoria1.tipo = A;
mercadoria1.codigo = 10029;
mercadoria1.quant = 62;
mercadoria1.valor = 10.32 * TAXA + 0.53;
.
.
.
mercadoria2 = mercadoria1;
.
.
.
FACOM UFMS
148 R EGISTROS
15.4 Exemplo
O programa 15.1 a seguir recebe um horrio no formato de horas, minutos e segundos, com
as horas no intervalo de 0 a 23, e atualiza este horrio em um segundo.
prox = agora;
prox.ss = prox.ss + 1;
if (prox.ss == 60) {
prox.ss = 0;
prox.mm = prox.mm + 1;
if (prox.mm == 60) {
prox.mm = 0;
prox.hh = prox.hh + 1;
if (prox.hh == 24)
prox.hh = 0;
}
}
return 0;
}
Exerccios
15.1 Dada uma data no formato dd/mm/aaaa, escreva um programa que mostre a prxima
data, isto , a data que representa o dia seguinte data fornecida.
Observao: No esquea dos anos bissextos. Lembre-se que um ano bissexto se divi-
svel por 400 ou, em caso negativo, se divisvel por 4 mas no por 100.
15.2 Dados dois horrios de um mesmo dia expressos no formato hh:mm:ss, calcule o tempo
decorrido entre estes dois horrios, apresentando o resultado no mesmo formato.
FACOM UFMS
15.4 E XEMPLO 149
return 0;
}
15.3 Dadas duas datas, calcule o nmero de dias decorridos entre estas duas datas.
Uma maneira provavelmente mais simples de computar essa diferena usar a fr-
mula 15.1 para calcular um nmero de dias N baseado em uma data:
1461 f (ano, ms) 153 g(ms)
N= + + dia (15.1)
4 5
onde
ano 1, se ms 6 2 ,
f (ano, ms) =
ano, caso contrrio
e
ms + 13, se ms 6 2 ,
g(ms) =
ms + 1, caso contrrio .
Podemos calcular o valor N1 para a primeira data informada, o valor N2 para a segunda
data informada e a diferena N2 N1 o nmero de dias decorridos entre estas duas
datas informadas.
FACOM UFMS
150 R EGISTROS
D = (N 621049) mod 7
e ento
Dada uma data fornecida pelo usurio no formato dd/mm/aaaa, determine o dia da
semana para esta data.
FACOM UFMS
AULA 16
Nesta aula, vamos trabalhar com uma extenso natural do uso de registros, declarando e
usando variveis compostas homogneas de registros como, por exemplo, vetores de registros
ou matrizes de registros. Por outro lado, estudaremos tambm registros contendo variveis
compostas homogneas como campos. Veremos que combinaes dessas declaraes tambm
podem ser usadas de modo a representar e organizar os dados na memria para soluo de pro-
blemas. Alm disso, veremos ainda registros cujos campos podem ser variveis no somente de
tipos primitivos, de tipos definidos pelo usurio, ou ainda variveis compostas homogneas,
mas tambm de variveis compostas heterogneas ou registros. O conjunto dessas combina-
es de variveis que acabamos de mencionar fornece ao() programador(a) uma liberdade e
flexibilidade na declarao de qualquer estrutura para armazenamento de informaes que lhe
seja necessria na soluo de um problema computacional, especialmente daqueles problemas
mais complexos.
Esta aula baseada nas referncias [16, 15].
Como vimos nas aulas 12 e 14, podemos declarar variveis compostas homogneas a partir
de qualquer tipo bsico ou ainda de um tipo definido pelo(a) programador(a). Ou seja, pode-
mos declarar, por exemplo, um vetor do tipo inteiro, uma matriz do tipo ponto flutuante, uma
varivel composta homognea de k dimenses do tipo caracter e etc. A partir de agora, podere-
mos tambm declarar variveis compostas homogneas, de quaisquer dimenses, de registros.
Por exemplo, podemos declarar um vetor com identificador cronometro como mostrado a
seguir:
struct {
int horas;
int minutos;
int segundos;
} cronometro[10];
ou ainda declarar, por exemplo, uma matriz com identificador agenda como abaixo:
151
152 V ETORES , MATRIZES E REGISTROS
struct {
int horas;
int minutos;
int segundos;
} agenda[10][30];
struct {
int horas;
int minutos;
int segundos;
} cronometro[10], agenda[10][30];
A declarao do vetor cronometro tem um efeito na memria que pode ser ilustrado como
na figura 16.1.
0 1 2 9
cronometro
horas
minutos
segundos
cronometro[0].horas = 20;
cronometro[0].minutos = 39;
cronometro[0].segundos = 18;
FACOM UFMS
16.1 VARIVEIS COMPOSTAS HOMOGNEAS DE REGISTROS 153
Alm disso, como fizemos na aula 15, podemos fazer a atribuio direta de registros para
registros declarados da mesma maneira. Assim, por exemplo, se declaramos as variveis
cronometro e aux como abaixo:
struct {
int horas;
int minutos;
int segundos;
} cronometro[10], aux;
ento as atribuies a seguir so vlidas e realizam a troca dos contedos das posies i e j
do vetor de registros cronometro :
aux = cronometro[i];
cronometro[i] = cronometro[j];
cronometro[j] = aux;
cronometro[i] = cronometro[j];
ao invs de:
cronometro[i].horas = cronometro[j].horas;
cronometro[i].minutos = cronometro[j].minutos;
cronometro[i].segundos = cronometro[j].segundos;
As duas formas de atribuio acima esto corretas, apesar da primeira forma ser muito mais
prtica e direta.
Nesse contexto, considere o seguinte problema:
O programa 16.1 soluciona o problema acima usando o mtodo de ordenao das trocas
sucessivas ou mtodo da bolha.
FACOM UFMS
154 V ETORES , MATRIZES E REGISTROS
return 0;
}
FACOM UFMS
16.2 R EGISTROS CONTENDO VARIVEIS COMPOSTAS HOMOGNEAS 155
Na aula 15 definimos registros que continham campos de tipos bsicos de dados ou, no
mximo, de tipos definidos pelo(a) programador(a). Na seo 16.1, estudamos vetores no
mais de tipos bsicos de dados, mas de registros, isto , vetores contendo registros. Essa idia
pode ser estendida para matrizes ou ainda para variveis compostas homogneas de qualquer
dimenso. Por outro lado, podemos tambm declarar registros que contm variveis compos-
tas homogneas como campos. Um exemplo bastante comum a declarao de um vetor de
caracteres, ou uma cadeia de caracteres, dentro de um registro, isto , como um campo deste
registro:
struct {
int dias;
char nome[3];
} mes;
struct {
int dias,
char nome[3];
} mes, aux;
mes.dias = 31;
mes.nome[0] = J;
mes.nome[1] = a;
mes.nome[2] = n;
nome
dias
mes 31 J a n
0 1 2
FACOM UFMS
156 V ETORES , MATRIZES E REGISTROS
importante salientar mais uma vez que as regras para cpias de registros permanecem as
mesmas, mesmo que um campo de um desses registros seja uma varivel composta. Assim, a
cpia abaixo perfeitamente vlida:
aux = mes;
Dadas duas descries de tarefas e seus horrios de incio no formato hh:mm:ss, es-
creva um programa que verifica qual das duas tarefas ser iniciada antes. Considere
que a descrio de uma tarefa tenha no mximo 50 caracteres.
return 0;
}
FACOM UFMS
16.3 R EGISTROS CONTENDO REGISTROS 157
importante observar que a declarao de um registro pode conter um outro registro como
um campo, em seu interior. Ou seja, uma varivel composta heterognea pode conter campos
de tipos bsicos, iguais ou distintos, campos de tipos definidos pelo usurio, campos que so
variveis compostas homogneas, ou ainda campos que se constituem tambm como variveis
compostas heterogneas.
Como exemplo, podemos declarar uma varivel do tipo registro com nome ou identificador
estudante contendo um campo do tipo inteiro rga , um campo do tipo vetor de caracteres
nome e um campo do tipo registro nascimento , contendo por sua vez trs campos do tipo
inteiro com identificadores dia , mes e ano :
struct {
int rga;
char nome[51];
struct {
int dia;
int mes;
int ano;
} nascimento;
} estudante;
estudante
dia mes ano
0 1 49 50
Observe que a varivel estudante um registro que mistura campos de um tipo bsico
o campo rga que do tipo inteiro , um campo que um vetor de um tipo bsico o campo
nome do tipo vetor de caracteres e um campo do tipo registro o campo nascimento do
tipo registro, contendo, por sua vez, trs campos do tipo inteiro: os campos dia , mes e ano .
Um exemplo do uso do registro estudante e de seus campos dado a seguir atravs de
atribuies de valores a cada um de seus campos:
FACOM UFMS
158 V ETORES , MATRIZES E REGISTROS
estudante.rga = 200790111;
estudante.nome[0] = J;
estudante.nome[1] = o;
estudante.nome[2] = s;
estudante.nome[3] = e;
estudante.nome[4] = \0;
estudante.nasc.dia = 22;
estudante.nasc.mes = 2;
estudante.nasc.ano = 1988;
struct {
int rga;
char nome[51];
struct {
int dia;
int mes;
int ano;
} nascimento;
} estudante1, estudante2, aux;
aux = estudante1;
estudante1 = estudante2;
estudante2 = aux;
FACOM UFMS
16.3 R EGISTROS CONTENDO REGISTROS 159
return 0;
}
FACOM UFMS
160 V ETORES , MATRIZES E REGISTROS
Exerccios
16.1 Dadas n datas, com 1 6 n 6 100, e uma data de referncia d, verifique qual das n datas
mais prxima data d.
if (d.mes <= 2)
N1 = (1461*(d.ano-1))/4 + ((153*d.mes+13)/5) + d.dia;
else
N1 = (1461*d.ano)/4 + ((153*d.mes+1)/5) + d.dia;
for (i = 0; i < n; i++) {
if (data[i].mes <= 2)
N2 = (1461*(data[i].ano-1))/4+((153*data[i].mes+13)/5)+data[i].dia;
else
N2 = (1461*data[i].ano)/4 + ((153*data[i].mes+1)/5) + data[i].dia;
if (N1 >= N2)
dif[i] = N1 - N2;
else
dif[i] = N2 - N1;
}
menor = 0;
for (i = 1; i < n; i++)
if (dif[i] < dif[menor])
menor = i;
return 0;
}
FACOM UFMS
16.3 R EGISTROS CONTENDO REGISTROS 161
16.3 Dados um nmero inteiro n > 1 e mais n fichas de doadores de um banco de sangue, con-
tendo o cdigo do doador, seu nome, seu tipo sangneo e seu fator Rhesus, escreva um
programa que lista os doadores do banco das seguintes formas: (i) em ordem crescente
de cdigos de doadores; (ii) em ordem alfabtica de nomes de doadores e (iii) em ordem
alfabtica de tipos sangneos e fatores Rhesus.
16.5 Escreva um programa que receba o nome, o telefone e a data de nascimento de n pessoas,
com 1 6 n 6 100, e implemente uma agenda telefnica com duas listagens possveis: (i)
uma lista dos nomes e telefones das pessoas em ordem alfabtica de nomes e (ii) uma lista
dos nomes e telefones das pessoas em ordem de datas de aniversrios das pessoas.
FACOM UFMS
162 V ETORES , MATRIZES E REGISTROS
FACOM UFMS
AULA 17
I NTRODUO S FUNES
Se concordamos que uma grande tarefa pode ser solucionada atravs de sua diviso em
sub-tarefas e da combinao de suas solues parciais, ento podemos ter nosso trabalho facili-
tado focando na construo de solues para essas sub-tarefas. Em programao essas solues
menores so chamadas de mdulos de programao e fazem parte de todo processo de cons-
truo de programas para soluo de problemas reais.
Os mdulos so uma ferramenta da programao estruturada que fornecem ao() progra-
mador(a) um mecanismo para construir programas que so fceis de escrever, ler, compreen-
der, corrigir, modificar e manter. Na linguagem C, essa caracterstica em um cdigo obtida
atravs do uso de funes. Na verdade, todos os programas que codificamos at o momento
de alguma forma j fizeram uso de funes. Por exemplo, scanf e printf so funes de
entrada e sada de dados da linguagem C que j usamos muitas e muitas vezes. Alm disso,
temos construdo nossas prprias funes main para solucionar todos os problemas vistos at
aqui. Apesar do termo funo vir da matemtica, uma funo da linguagem C nem sempre
se parece com uma funo matemtica, j que pode no ter argumentos nem computar um
valor. Cada funo na linguagem C pode ser vista como um pequeno programa com suas pr-
prias declaraes de variveis e sentenas de programao. Alm de facilitar a compreenso
e a modificao de um programa e evitar a duplicao de cdigo usado mais que uma vez, as
funes podem ser usadas no s no programa para o qual foram projetadas, mas tambm em
outros programas.
Esta aula baseada nas referncias [16, 15].
Antes de aprender as regras formais para definir uma funo, vejamos trs pequenos exem-
plos de programas que definem funes.
Suponha que computamos freqentemente a mdia de dois valores do tipo double . A
biblioteca de funes da linguagem C no tem uma funo que computa a mdia, mas podemos
escrever facilmente a nossa prpria funo. Vejamos a seguir:
163
164 I NTRODUO S FUNES
Devemos fazer uma chamada funo media no ponto do cdigo onde usamos o seu valor
devolvido. Por exemplo, para computar a mdia de x e y , e escrever o resultado na sada,
poderamos escrever:
2. x e y so copiados em a e b ;
4. a funo printf imprime a cadeia de caracteres e o valor que media devolve, sendo
que esse valor devolvido torna-se um argumento da funo printf .
Observe que o valor devolvido pela funo media no salvo em lugar algum. A sentena
imprime o valor e ento o descarta. Se h necessidade de usar o valor devolvido posterior-
mente, podemos captur-lo em uma varivel, como abaixo:
m = media(x, y);
A sentena acima chama a funo media e ento salva o valor devolvido na varivel m .
FACOM UFMS
17.1 N OES INICIAIS 165
Vamos usar a funo media em no programa 17.1. Entre outras coisas, este programa
mostra que uma funo pode ser chamada tantas vezes quanto necessrio.
return 0;
}
Observe que a definio da funo media vem antes da definio da funo main , j que
teramos problemas de compilao se fizssemos o contrrio.
Nem toda funo devolve um valor como a funo media faz. Por exemplo, uma funo
cujo trabalho enviar informaes para a sada muito provavelmente no devolve valor algum.
Para indicar que uma funo no tem valor devolvido, especificamos que seu valor devolvido
do tipo void , onde void um tipo sem valor. Considere o seguinte exemplo, que imprime
na sada uma mensagem uma certa quantidade de vezes:
return;
}
FACOM UFMS
166 I NTRODUO S FUNES
imprimeContador(i);
return;
}
return 0;
}
10 e contando...
FACOM UFMS
17.1 N OES INICIAIS 167
A funo imprimeContador regressa para o ponto em que foi chamada, no corpo da es-
trutura de repetio for , imprimeContador chamada novamente e imprime a mensagem:
9 e contando...
A palavra reservada void entre parnteses aps o identificador da funo indica que
imprimeMsg no tem argumentos. Para chamar uma funo sem argumentos, devemos es-
crever o nome da funo seguido obrigatoriamente por parnteses, como mostramos abaixo:
imprimeMsg();
return 0;
}
FACOM UFMS
168 I NTRODUO S FUNES
A execuo do programa 17.3 comea com a primeira sentena na funo main , que a
declarao da varivel i do tipo int . Ems eguida, uma estrutura de repetio faz com que
a funo imprimeMsg seja executada 10 vezes. Quando imprimeMsg comea sua execuo,
ela chama a funo printf para mostrar uma mensagem na sada. Quando printf termina
sua execuo, imprimeMsg termina sua execuo e volta para main .
Uma funo da linguagem C um trecho de cdigo que pode receber um ou mais valores de
entrada armazenados em variveis, chamados de parmetros (de entrada), que realiza algum
processamento especfico e que pode devolver um nico valor de sada. Em geral, construmos
funes para resolver pequenos problemas bem especficos e, em conjunto com outras funes,
resolver problemas maiores e mais complexos. A definio de uma funo na linguagem C
fornece quatro informaes importantes ao compilador:
3. seu identificador;
uma interface, que faz a comunicao entre a funo e o meio exterior; a interface de-
finida pela primeira linha da funo, onde especificamos o tipo do valor devolvido da
funo, seu identificador e a lista de parmetros de entrada separados por vrgulas e en-
volvidos por um par de parnteses; e
Depois de ter visto vrios exemplos de funes na seo anterior, a forma geral de uma
definio de uma funo dada a seguir:
tipo identificador(parmetros)
{
declarao de variveis
sentena1 ;
.
.
.
sentenan ;
}
FACOM UFMS
17.2 D EFINIO E CHAMADA DE FUNES 169
Se a funo no tem parmetros, a palavra reservada void deve ocorrer entre os parnte-
ses.
Aps a interface, a funo contm um corpo, que uma seqncia de comandos da lingua-
gem C envolvida por chaves. O corpo de uma funo pode incluir declaraes e sentenas. Por
exemplo, a funo media poderia ser escrita como abaixo:
soma = a + b;
return soma / 2;
}
A declarao de variveis de uma funo deve vir primeiro, antes de qualquer sentena do
corpo da funo. As variveis declaradas no corpo de uma funo pertencem exclusivamente
quela funo e no podem ser examinadas ou modificadas por outras funes.
Uma chamada de funo consiste de um identificador da funo seguido por uma lista de
argumentos entre parnteses. Por exemplo, abaixo temos trs chamadas de funes:
media(x, y)
imprimeContador(i)
imprimeMsg()
FACOM UFMS
170 I NTRODUO S FUNES
Uma chamada de uma funo com valor devolvido void sempre seguida por um ;
para torn-la uma sentena. Por exemplo:
imprimeContador(i);
imprimeMsg();
Por outro lado, uma chamada de uma funo com valor devolvido diferente de void pro-
duz um valor que pode ser armazenado em uma varivel ou usado em uma expresso aritm-
tica, relacional ou lgica. Por exemplo,
if (media(x, y) > 0)
printf("Mdia positiva\n");
printf("A mdia %g\n", media(x, y));
O valor devolvido por uma funo que devolve um valor diferente de void sempre pode
ser descartado, como podemos ver na chamada a seguir:
media(x, y);
Esta chamada funo media um exemplo de uma sentena que avalia uma expresso mas
descarta o resultado. Apesar de estranho na chamada funo media , ignorar o valor devol-
vido pode fazer sentido em alguns casos. Por exemplo, a funo printf sempre devolve o
nmero de caracteres impressos na sada. Dessa forma, aps a chamada abaixo, a varivel nc
ter o valor 19:
nc = printf("Programar bacana\n");
printf("Programar bacana\n");
Uma funo que devolve um valor diferente de void deve usar a sentena return para
especificar qual valor ser devolvido. A sentena return tem a seguinte forma geral:
return expresso;
FACOM UFMS
17.3 F INALIZAO DE PROGRAMAS 171
return 0;
return estado;
return (a + b) / 2;
return a * a * a + 2 * a * a - 3 * a - 1;
Quando uma das sentenas acima executada, primeiramente a avaliao da expresso rea-
lizada e o valor obtido ento devolvido pela funo.
Se o tipo da expresso na sentena return diferente do tipo devolvido pela funo, a
expresso ser implicitamente convertida para o tipo da funo.
Como main uma funo, ela deve ter um tipo de valor de devoluo. Normalmente, o
tipo do valor a ser devolvido pela funo main int e por isso que temos definido main
da forma como fizemos at aqui.
O valor devolvido pela funo main um cdigo de estado do programa que, em alguns
sistemas operacionais, pode ser verificado quando o programa termina. A funo main deve
devolver o valor 0 (zero) se o programa termina normalmente ou um valor diferente de 0 (zero)
para indicar um trmino anormal. Por exemplo, quando uma seqncia de programas que
se comunicam entre si executada no sistema operacional LINUX, esse padro de valores
adotado e verificado nesse processo. No entanto, no h uma regra rgida para o uso do valor
devolvido pela funo main e, assim, podemos usar esse valor para qualquer propsito.
uma boa prtica de programao fazer com que todo programa na linguagem C devolva um
cdigo de estado, mesmo se no h planos de us-lo, j que um(a) usurio(a) pode decidir
verific-lo. o que vimos sempre fazendo na ltima sentena de nossas funes main , quando
escrevemos return 0; .
Executar a sentena return na funo main uma forma de terminar um programa.
Outra maneira chamar a funo exit que pertence biblioteca stdlib . O argumento
passado para exit tem o mesmo significado que o valor a ser devolvido por main , isto
, ambos indicam o estado do programa ao seu trmino. Para indicar um trmino normal,
passamos 0 (zero) como argumento, como abaixo:
exit(0);
FACOM UFMS
172 I NTRODUO S FUNES
exit(EXIT_SUCCESS);
exit(EXIT_FAILURE);
return expresso;
exit(expresso);
A diferena entre return e exit que exit causa o trmino de um programa inde-
pendente do ponto em que se encontra essa chamada, isto , no considerando qual funo
chamou a funo exit . A sentena return causa o trmino de um programa apenas se
aparece na funo main . Alguns(mas) programadores(as) usam exit exclusivamente para
depurar programas. Depurao de programas um tpico importante para uma linguagem de
programao e teremos uma breve introduo ao assunto na aula 23.
17.4 Exemplo
Construa uma funo que receba dois inteiros positivos e devolva o mximo divisor
comum entre eles.
J resolvemos o problema de encontrar o mximo divisor comum entre dois nmeros in-
teiros positivos antes, usando o algoritmo de Euclides, mas com o uso de uma nica funo,
a funo ou programa principal. Agora, faremos uma funo que recebe esses dois nmeros e
devolve o mximo divisor comum. Uma possvel funo que soluciona o problema mostrada
a seguir.
FACOM UFMS
17.4 E XEMPLO 173
while (b != 0) {
aux = a % b;
a = b;
b = aux;
}
return a;
}
Um exemplo de um programa principal que faz uma chamada funo mdc descrita acima
mostrado no programa 17.4.
while (b != 0) {
aux = a % b;
a = b;
b = aux;
}
return a;
}
return 0;
}
FACOM UFMS
174 I NTRODUO S FUNES
Nos programas que vimos nas sees 17.1 e 17.4 a definio de cada funo sempre foi
feita acima do ponto onde ocorrem suas chamadas. Ou seja, se a funo main faz chamada
a uma funo escrita pelo programador, a definio dessa funo tem de ocorrer antes dessa
chamada, acima da prpria funo main . No entanto, a linguagem C na verdade no obriga
que a definio de uma funo preceda suas chamadas.
Suponha que rearranjamos o programa 17.1 colocando a definio da funo media depois
da definio da funo main , como abaixo:
#include <stdio.h>
return 0;
}
FACOM UFMS
17.5 D ECLARAO DE FUNES 175
da funo cuja declarao completa ser dada posteriormente. A declarao de uma funo
composta exatamente pela primeira linha da definio de uma funo com um ponto e vrgula
adicionado no final:
tipo identificador(parmetros);
Desnecessrio dizer que a declarao de uma funo tem de ser consistente com a defi-
nio da mesma funo. A seguir mostramos como nosso programa ficaria com a adio da
declarao de media :
#include <stdio.h>
return 0;
}
Exerccios
FACOM UFMS
176 I NTRODUO S FUNES
que receba dois nmeros de ponto flutuante que representam a base e a altura de
um tringulo e compute e devolva a rea desse tringulo.
(b) Escreva um programa que receba uma seqncia de n pares de nmeros de ponto
flutuante, onde cada par representa a base e a altura de um tringulo, e calcule e
escreva, para cada par, a rea do tringulo correspondente. Use a funo descrita no
item (a).
printf("Informe n: ");
scanf("%d", &n);
return 0;
}
que receba dois nmeros inteiros positivos a e b e determine e devolva um valor que
representa o produto desses nmeros, usando o seguinte mtodo de multiplicao:
i. dividir, sucessivamente, o primeiro nmero por 2, at que se obtenha 1 como
quociente;
ii. em paralelo, dobrar, sucessivamente, o segundo nmero;
iii. somar os nmeros da segunda coluna que tenham um nmero mpar na pri-
meira coluna; o total obtido o produto procurado.
Por exemplo, para os nmeros 9 e 6, temos que 9 6
FACOM UFMS
17.5 D ECLARAO DE FUNES 177
9 6 6
4 12
2 24
1 48 48
54
(b) Escreva um programa que leia n > 1 pares de nmeros e calcule os respectivos
produtos desses pares, usando a funo do item (a).
17.3 Para determinar o nmero de lmpadas necessrias para cada aposento de uma residn-
cia, existem normas que fornecem o mnimo de potncia de iluminao exigida por metro
quadrado (m2 ) conforme o uso desse ambiente. Suponha que s temos lmpadas de 60
watts para uso.
Seja a seguinte tabela de informaes sobre possveis aposentos de uma residncia:
que receba dois nmeros inteiros positivos a e b e calcule e devolva o mximo divisor
comum entre eles.
FACOM UFMS
178 I NTRODUO S FUNES
(b) Usando a funo do item anterior, escreva um programa que receba n > 1 nmeros
inteiros positivos e calcule o mximo divisor comum entre todos eles.
int verifica_primo(int p)
que receba dois nmeros inteiros n e d, com 0 < d 6 9, devolva um valor que
representa o nmero de vezes que o dgito d ocorre no nmero n.
(b) Usando a funo do item anterior, escreva um programa que leia dois nmeros in-
teiros positivos a e b e responda se a permutao de b.
FACOM UFMS
17.5 D ECLARAO DE FUNES 179
a b
567890 678 b subseqncia de a
1234 2212345 a subseqncia de b
235 236 um no subseqncia do outro
17.8 Uma seqncia de n nmeros inteiros no nulos dita m-alternante se constituda por
m segmentos: o primeiro com um elemento, o segundo com dois elementos e assim por
diante at o m-simo, com m elementos. Alm disso, os elementos de um mesmo seg-
mento devem ser todos pares ou todos mpares e para cada segmento, se seus elementos
forem todos pares (mpares), os elementos do segmento seguinte devem ser todos mpa-
res (pares).
Por exemplo:
int bloco(int m)
FACOM UFMS
180 I NTRODUO S FUNES
FACOM UFMS
AULA 18
A RGUMENTOS E PARMETROS DE
FUNES
Como vimos at aqui, a interface de uma funo define muito do que queremos saber sobre
ela: o tipo de valor que a funo devolve, seu identificador e seus parmetros. Isso implica na
conseqente elevao do nvel de abstrao dos nossos programas, j que podemos entender o
que um programa faz sem a necessidade de examinar os detalhes de suas funes. Caso alguns
detalhes sejam de nosso interesse, tambm h a vantagem de que sabemos onde examin-
los. Nesta aula, baseada nas referncias [16, 15], focaremos nos argumentos e parmetros das
funes e no escopo de seus dados.
Uma diferena importante entre um parmetro e um argumento deve ser destacada aqui.
Parmetros aparecem na definio de uma funo e so nomes que representam valores a serem
fornecidos quando a funo chamada. J os argumentos so expresses que aparecem nas
chamadas das funes.
Conceitualmente, existem trs tipos de parmetros:
x = quadrado(num);
181
182 A RGUMENTOS E PARMETROS DE FUNES
*parte_int = (int) x;
*parte_frac = x - *parte_int;
return;
}
return 0;
}
Uma primeira observao importante sobre a interface da funo decompoe . Note que
os parmetros parte_int e parte_frac vem precedidos do smbolo * . Essa a forma
que definimos parmetros de entrada e sada na linguagem C. No corpo da funo decompoe ,
observe que os parmetros de entrada e sada so usados como de costume no corpo de uma
funo, isto , como vimos usando os parmetros de entrada. No entanto, os parmetros de
entrada e sada sempre devem vir precedidos pelo smbolo * no corpo de uma funo, como
mostrado acima. E por ltimo, a chamada da funo decompoe na funo main ligeira-
mente diferente. Observe que os argumentos a e b so precedidos pelo smbolo & , indicando
que as variveis a e b da funo main , de tipos inteiro e ponto flutuante respectivamente,
so passadas como parmetros de entrada e sada para a funo decompoe , ou seja, so pas-
sadas por referncia, e qualquer alterao realizada nos parmetros correspondentes da funo
refletiro nos argumentos da chamada.
FACOM UFMS
18.2 E SCOPO DE DADOS E DE FUNES 183
O escopo de uma funo e das variveis de uma funo o trecho, ou os trechos, de cdigo
em que a funo ou as variveis pode(m) ser acessada(s). Em particular, o escopo de uma
funo determina quais funes podem cham-la e quais ela pode chamar.
Variveis definidas internamente nas funes, bem como os parmetros de uma funo, so
chamadas de variveis locais da mesma, ou seja, o escopo dessas variveis circunscreve-se ao
trecho de cdigo definido pelo corpo da funo. Isso significa que elas so criadas durante a
execuo da funo, manipuladas e destrudas ao trmino de sua execuo, quando o comando
return encontrado.
As funes de um programa so organizadas por nveis. No primeiro nvel temos apenas a
funo principal main , aquela pela qual o programa ser iniciado. As funes que so chama-
das pela funo main so ditas estarem no segundo nvel. No terceiro nvel esto as funes
que so chamadas pelas funes do segundo nvel. E assim sucessivamente. Veja a figura 18.1.
main
Exerccios
FACOM UFMS
184 A RGUMENTOS E PARMETROS DE FUNES
aux = *a;
*a = *b;
*b = aux;
return;
}
scanf("%d", &n);
for (i = 0; i < n; i++)
scanf("%d", &A[i]);
return 0;
}
18.2 Em um dado pas a moeda corrente possui apenas quatro cdulas de papel: $1, $5, $10 e
$20.
void cedulas(int val, int *um, int *cin, int *dez, int *vin)
FACOM UFMS
18.2 E SCOPO DE DADOS E DE FUNES 185
18.3 Dizemos que um nmero natural n palndromo se lido da esquerda para direita e da
direita para esquerda o mesmo nmero.
Exemplos:
567765 palndromo.
32423 palndromo.
567675 no palndromo.
que receba um nmero inteiro n > 0 e devolva trs nmeros inteiros: o primeiro
dgito de n, o ltimo dgito de n e um inteiro que represente o nmero n sem seu
primeiro e ltimo dgitos.
Exemplo:
valor inicial de n primeiro dgito ltimo dgito miolo de n
732 7 2 3
14738 1 8 473
78 7 8 0
7 7 7 0
(b) Usando a funo do item (a), escreva um programa que receba um nmero inteiro
n > 0 e verifique se n palndromo. Suponha que n no contm o dgito 0.
que receba trs nmeros inteiros e devolva um nmero inteiro representando a soma
dos trs bits, e devolva tambm um outro valor do tipo inteiro representando o valor
do vai um.
(b) Escreva um programa que receba dois nmeros na base binria e, usando a funo
do item (a), calcule um nmero na base binria que a soma dos dois nmeros
dados.
FACOM UFMS
186 A RGUMENTOS E PARMETROS DE FUNES
FACOM UFMS
AULA 19
F UNES E VETORES
Nas aulas prticas e tericas vimos funes, argumentos de funes e passagem de parme-
tros para funes na linguagem C, onde trabalhamos apenas com argumentos de tipos bsicos.
Observe que chegamos a passar o valor de um elemento de um vetor como um argumento para
uma funo, por cpia e por referncia. Nesta aula veremos como realizar passagem de par-
metros de tipos complexos, mais especificamente de parmetros que so variveis compostas
homogneas unidimensionais ou vetores. Esta aula baseada nas referncias [16, 15].
Assim como fizemos com variveis de tipos bsicos, possvel passar um vetor todo como
argumento em uma chamada de uma funo. O parmetro correspondente deve ser um vetor
com a mesma dimenso. Vejamos um exemplo no programa 19.1.
Programa 19.1: Um programa com uma funo que tem um vetor como parmetro.
#include <stdio.h>
min = A[0];
for (i = 1; i < 10; i++)
if (A[i] < min)
min = A[i];
return min;
}
187
188 F UNES E VETORES
Observe a interface da funo minimo do programa acima. Essa interface indica que a fun-
o devolve um valor do tipo inteiro, tem identificador minimo e tem como seu argumento um
vetor contendo 10 elementos do tipo inteiro. Referncias feitas ao parmetro A , no interior da
funo minimo , acessam os elementos apropriados dentro do vetor que foi passado funo.
Para passar um vetor inteiro para uma funo necessrio apenas descrever o identificador
do vetor, sem qualquer referncia a ndices, na chamada da funo. Essa situao pode ser
visualizada na ltima linha do programa principal, na chamada da funo minimo(pontos) .
importante destacar tambm que a nica restrio de devoluo de uma funo relativa
s variveis compostas homogneas. De fato, um valor armazenado em uma varivel de qual-
quer tipo pode ser devolvido por uma funo, excluindo variveis compostas homogneas.
Nesta aula, o que temos visto at o momento so detalhes de como passar vetores como
parmetros para funes, detalhes na chamada e na interface de uma funo que usa vetores
como parmetros. No entanto, esses elementos por si s no so a principal peculiaridade dos
vetores neste contexto. Vejamos o programa 19.2.
Programa 19.2: Um vetor sempre um parmetro passado por referncia para uma funo.
#include <stdio.h>
return 0;
}
FACOM UFMS
19.3 V ETORES COMO PARMETROS COM DIMENSES OMITIDAS 189
Perceba que a funo dobro do programa acima modifica os valores do vetor valor , uma
varivel local do programa principal que passada como parmetro para a funo dobro na
varivel vetor , uma varivel local da funo dobro . importante observar que, quando
usamos vetores como argumentos, uma funo que modifica o valor de um elemento do ve-
tor, modifica tambm o vetor original que foi passado como parmetro para a funo. Esta
modificao tem efeito mesmo aps o trmino da execuo da funo.
Nesse sentido, podemos dizer que um vetor, uma matriz ou uma varivel composta ho-
mognea de qualquer dimenso sempre um parmetro de entrada e sada, isto , sempre
passado por referncia a uma funo.
No entanto, lembre-se que a modificao de elementos de um vetor em uma funo se
aplica somente quando o vetor completo passado como parmetro funo e no elementos
individuais do vetor. Esse ltimo caso j foi tratado em aulas anteriores.
Observe que a dimenso do parmetro vetor da funo dobro , que um vetor, foi omi-
tida. A duas definies da funo dobro , nesta seo e na seo anterior, so equivalentes. No
entanto, a definio com a dimenso omitida permite que a funo dobro possa ser chamada
com vetores de quaisquer dimenses como argumentos.
Por exemplo, se temos dois vetores de inteiros A e B, com dimenses 50 e 200, respecti-
vamente, a funo dobro pode ser chamada para computar o dobro de cada coordenada do
vetor A e, do mesmo modo, tambm pode se chamada para computar o dobro de cada coor-
denada do vetor B. Ou seja, a funo dobro pode ser chamada com vetores de dimenses
diferentes como parmetros.
dobro(A, 50);
dobro(B, 200);
FACOM UFMS
190 F UNES E VETORES
Exerccios
FACOM UFMS
19.3 V ETORES COMO PARMETROS COM DIMENSES OMITIDAS 191
Observao: no leia todos os conjuntos de uma s vez. Leia os dois primeiros conjuntos e
calcule a primeira interseco. Depois, leia o prximo conjunto e calcule uma nova inter-
seco entre esse conjunto lido e o conjunto da interseco anterior, e assim por diante.
FACOM UFMS
192 F UNES E VETORES
FACOM UFMS
AULA 20
F UNES E MATRIZES
20.1 Matrizes
Um elemento de uma matriz pode ser passado como parmetro para uma funo assim
como fizemos com uma varivel de um tipo bsico ou como um elemento de um vetor. Ou
seja, a sentena
p = paridade(matriz[i][j]);
multiplica_escalar(A, escalar);
pode ser usada para chamar uma funo que multiplica cada elemento de uma matriz A pelo
valor armazenado na varivel escalar . Assim como com vetores, uma modificao realizada
no corpo de uma funo sobre qualquer elemento de uma matriz que um parmetro dessa
funo provoca uma modificao no argumento da chamada da funo, ou seja, na matriz que
foi passada funo durante sua chamada.
O programa 20.1 recebe uma matriz A44 de nmeros inteiros e um escalar e realiza o
produto da matriz por esse escalar.
193
194 F UNES E MATRIZES
scanf("%d", &esc);
for(i = 0; i < 4; i++)
for(j = 0; j < 4; j++)
scanf("%d", &matriz[i][j]);
imprime_matriz(matriz);
multiplica_escalar(matriz, esc);
imprime_matriz(matriz);
return 0;
}
FACOM UFMS
20.2 M ATRIZES COMO PARMETROS COM UMA DIMENSO OMITIDA 195
Exerccios
aux = *a;
*a = *b;
*b = aux;
}
return 0;
}
FACOM UFMS
196 F UNES E MATRIZES
20.2 A k-sima potncia de uma matriz quadrada Ann , denotada por Ak , a matriz obtida a
partir da matriz A da seguinte forma:
k
z }| {
Ak = In A A A ,
que receba uma matriz I e uma dimenso n e preencha essa matriz com os valores
da matriz identidade de ordem n.
(b) Escreva uma funo com a seguinte interface:
20.3 Dizemos que uma matriz Ann um quadrado latino de ordem n se em cada linha e
em cada coluna aparecem todos os inteiros 1, 2, 3, . . . , n, ou seja, cada linha e coluna
permutao dos inteiros 1, 2, . . . , n.
Exemplo:
1 2 3 4
2 3 4 1
4 1 2 3
3 4 1 2
FACOM UFMS
20.2 M ATRIZES COMO PARMETROS COM UMA DIMENSO OMITIDA 197
que receba como parmetros uma matriz Ann de nmeros inteiros e um ndice i, e
verifique se na linha i de A ocorrem todos os nmeros inteiros de 1 a n, devolvendo
1 em caso positivo e 0 caso contrrio.
(b) Escreva uma funo com a seguinte interface:
que receba como parmetros uma matriz Ann de nmeros inteiros e um ndice j, e
verifique se na coluna j de A ocorrem todos os nmeros inteiros de 1 a n, devolvendo
1 em caso positivo e 0 caso contrrio.
(c) Usando as funes dos itens (a) e (b), escreva um programa que verifique se uma
dada matriz Ann de nmeros inteiros, com 1 6 n 6 100, um quadrado latino de
ordem n.
FACOM UFMS
198 F UNES E MATRIZES
FACOM UFMS
AULA 21
F UNES E REGISTROS
J vimos funes com parmetros de tipos bsicos e de tipos complexos, como vetores e
matrizes. Nesta aula, aprenderemos como comportam-se os registros no contexto das funes.
Como veremos, um registro, diferentemente das variveis compostas homogneas, comporta-
se como uma varivel de um tipo bsico qualquer quando trabalhamos com funes. Ou seja,
um registro comporta-se como qualquer outra varivel excluindo as compostas homogneas,
isto , um registro sempre um argumento passado por cpia a uma funo. Se quisermos
que um registro seja um argumento passado por referncia a uma funo, devemos explici-
tamente indicar essa opo usando o smbolo & no argumento e o smbolo * no parmetro
correspondente, como fazemos com variveis de tipos primitivos.
Esta aula baseada nas referncias [16, 15].
struct cadastro {
int codigo;
char nome[MAX+1];
int fone;
};
199
200 F UNES E REGISTROS
Observe que o caractere ponto e vrgula ( ; ) segue o caractere fecha chaves } . O ; deve
estar presente neste ponto para terminar a declarao da etiqueta do registro.
Uma vez que criamos a etiqueta cadastro , podemos us-la para declarar variveis:
struct cadastro {
int codigo;
char nome[MAX+1];
int fone;
} ficha1, ficha2;
typedef struct {
int codigo;
char nome[MAX+1];
int fone;
} Cadastro;
Observe que o nome do tipo, Cadastro , deve ocorrer no final, no aps a palavra reser-
vada struct . Alm disso, como Cadastro um nome de um tipo definido por typedef ,
no permitido escrever struct Cadastro . Todas as variveis do tipo Cadastro so com-
patveis, desconsiderando onde foram declaradas. Assim, a declarao de registros com essa
definio pode ser dada como abaixo:
FACOM UFMS
21.2 R EGISTROS E PASSAGEM POR CPIA 201
Quando precisamos declarar um nome para um registro, podemos escolher entre decla-
rar uma etiqueta de registro ou definir um tipo registro com a palavra reservada typedef .
Entretanto, em geral preferimos usar etiquetas de registros por diversos motivos que sero
justificados posteriormente.
x = raiz_quadrada(poligono.diagonal);
s = total_segundos(tempo);
pode ser usada para chamar a funo totalSegundos que provavelmente calcula o total de
segundos de uma medida de tempo armazenada no registro tempo .
Diferentemente das variveis compostas homogneas, uma modificao realizada em qual-
quer campo de um registro que um parmetro de uma funo no provoca uma modifica-
o no contedo do campo correspondente que um argumento da funo. Nesse caso, a
princpio, um argumento que um registro em uma chamada de uma funo tem o mesmo
comportamento de um argumento que uma varivel de um tipo bsico qualquer, ou seja,
uma expresso que um argumento de uma chamada de uma funo e que, na verdade ou
contm um registro, de fato um parmetro de entrada da funo, passado por cpia. Dessa
forma, voltamos a repetir que somente as variveis compostas homogneas tm um comporta-
mento deferenciado na linguagem C, no que ser refere a argumentos e parmetros de funes
neste caso especfico.
Um exemplo com uma chamada de uma funo contendo um registro como argumento
mostrado no programa 21.1.
FACOM UFMS
202 F UNES E REGISTROS
Programa 21.1: Um programa com uma funo com parmetro do tipo registro.
#include <stdio.h>
struct marca {
int hh;
int mm;
int ss;
};
segundos = converte_segundos(horario);
return 0;
}
Devemos destacar pontos importantes neste programa. O primeiro, e talvez o mais impor-
tante, a definio da etiqueta de registro marca . Em nenhuma outra oportunidade anterior
havamos desenvolvido um programa que continha uma declarao de uma etiqueta de regis-
tro. Observe ainda que a declarao da etiqueta marca do programa 21.1 foi feita fora dos
corpos das funes converte_segundos e main . Em todos os programas descritos at aqui,
no temos um exemplo de uma declarao de uma etiqueta de registro, ou mesmo uma de-
clarao de uma varivel de qualquer tipo, fora do corpo de qualquer funo. A declarao
da etiqueta marca realizada dessa maneira se deve ao fato que a mesma usada nas funes
converte_segundos e main , obrigando que essa declarao seja realizada globalmente, ou
seja, fora do corpo de qualquer funo. Todas as outras declaraes que fizemos so declara-
es locais, isto , esto localizadas no interior de alguma funo.
Os outros pontos de destaque do programa 21.1 so todos relativos ao argumento da cha-
mada da funo converte_segundos e do parmetro da mesma, descrito em sua interface.
Note que essa funo tem como parmetro o registro tempo do tipo struct marca . O argu-
mento da funo, na chamada dentro da funo main o registro horario de mesmo tipo
struct marca .
FACOM UFMS
21.3 R EGISTROS E PASSAGEM POR REFERNCIA 203
Finalmente, importante repetir que a passagem de um registro para uma funo feita
por cpia, ou seja, o parmetro correspondente um parmetro de entrada e, por isso, qualquer
alterao realizada em um ou mais campos do registro dentro da funo no afeta o contedo
dos campos do registro que um argumento na sua chamada. No exemplo acima no h
alteraes nos campos do registro tempo no corpo da funo converte_segundos , mas, caso
houvesse, isso no afetaria qualquer um dos campos do registro horario da funo main .
struct marca {
int hh;
int mm;
int ss;
};
FACOM UFMS
204 F UNES E REGISTROS
Uma observao importante sobre o programa 21.2 a forma como um registro que um
parmetro passado por referncia apresentado no corpo da funo. Como o smbolo . que
seleciona um campo de um registro tem prioridade sobre o smbolo * , que indica que o par-
metro foi passado por referncia, os parnteses envolvendo o o smbolo * e o identificador do
registro so essenciais para evitar erros. Dessa forma, uma expresso envolvendo, por exem-
plo, o campo ss do registro tempo , escrita como *tempo.ss , est incorreta e no realiza a
seleo do campo do registro que tencionamos.
Alternativamente, podemos usar os smbolos -> para indicar o acesso a um campo de um
registro que foi passado por referncia a uma funo. O uso desse smbolo simplifica bastante
a escrita do corpo das funes que tm parmetros formais que so registros passados por
referncia. Dessa forma, o programa 21.2 pode ser reescrito como o programa 21.3. Observe
que esses dois programas tm a mesma finalidade, isto , dada uma entrada, realizam o mesmo
processamento e devolvem as mesmas sadas.
Programa 21.3: Uso do smbolo -> para registros passados por referncia.
#include <stdio.h>
struct marca {
int hh;
int mm;
int ss;
};
FACOM UFMS
21.4 F UNES QUE DEVOLVEM REGISTROS 205
Uma funo pode devolver valores de tipos bsicos, mas tambm pode devolver um valor
de um tipo complexo como um registro. Observe que variveis compostas homogneas, pelo
fato de sempre poderem ser argumentos que correspondem a parmetros de entrada e sada,
isto , de sempre poderem ser passadas por referncia, nunca so devolvidas explicitamente
por uma funo, atravs do comando return . O nico valor de um tipo complexo que pode-
mos devolver um valor do tipo registro. Fazemos isso muitas vezes quando prorgramamos
para solucionar grandes problemas.
No problema da seo anterior, em que dado um horrio em um formato especfico e
queremos atualiz-lo em um segundo, usamos um registro como parmetro de entrada e sada
na funo adiciona_segundo . Por outro lado, podemos fazer com que a funo apenas re-
ceba uma varivel do tipo registro contendo um horrio como parmetro de entrada e devolva
um registro com o horrio atualizado como sada. Ou seja, teremos ento um parmetro de
entrada e um parmetro de sada que so registros distintos. Dessa forma, os programas 21.2
e 21.3 poderiam ser reescritos como no programa 21.4.
Observe que a interface da funo adiciona_segundo bastante diferente das definies
anteriores no programa 21.4. O tipo do valor devolvido o tipo struct marca uma eti-
queta de um registro , indicando que a funo devolver um registro. O corpo dessa funo
tambm diferente das funes anteriores e h a declarao de uma varivel atualizado
do tipo struct marca que ao final conter o horrio do registro tempo , parmetro de en-
trada da funo, atualizado em um segundo. Na funo principal, a chamada da funo
adiciona_segundo tambm diferente, j que descrita do lado direito de uma instruo
de atribuio, indicando que o registro devolvido pela funo ser armazenado no registro
apresentado do lado esquerdo da atribuio: novo = adiciona_segundo(agora); .
FACOM UFMS
206 F UNES E REGISTROS
struct marca {
int hh;
int mm;
int ss;
};
atualizado.ss = tempo.ss + 1;
if (atualizado.ss == 60) {
atualizado.ss = 0;
atualizado.mm = tempo.mm + 1;
if (atualizado.mm == 60) {
atualizado.mm = 0;
atualizado.hh = tempo.hh + 1;
if (atualizado.hh == 24)
atualizado.hh = 0;
}
else
atualizado.hh = tempo.hh;
}
else {
atualizado.mm = tempo.mm;
atualizado.hh = tempo.hh;
}
return atualizado;
}
return 0;
}
FACOM UFMS
21.4 F UNES QUE DEVOLVEM REGISTROS 207
Exerccios
que receba uma data no formato dd/mm/aaaa e verifique se o ano bissexto, devol-
vendo 1 em caso positivo e 0 caso contrrio. Um ano bissexto se divisvel por 4 e
no por 100 ou divisvel por 400.
(b) Escreva uma funo com a seguinte interface:
que receba uma data no formato dd/mm/aaaa e devolva a data que representa o dia
seguinte. Use as funes dos itens (a) e (b).
(d) Escreva um programa que receba uma data no formato dd/mm/aaaa e imprima a
data que representa o dia seguinte. Use as funes dos itens anteriores.
21.2 Reescreva a funo do item (c) do exerccio 21.1, de modo que a funo dia_seguinte
tenha o registro d como um parmetro de entrada e sada. Isto , a interface da funo
deve ser:
que receba duas medidas de tempo no formato hh:mm:ss e calcule o tempo decor-
rido entre essas duas medidas de tempo. Tenha cuidado com um par de medidas de
tempo que cruzam a meia noite.
(b) Escreva um programa que receba dois horrios no formato hh:mm:ss e calcule o
tempo decorrido entre esses dois horrios. Use a funo anterior.
FACOM UFMS
208 F UNES E REGISTROS
FACOM UFMS
AULA 22
B IBLIOTECA PADRO
Nas ltimas aulas aprendemos a construir nossas prprias funes. Os benefcios dessa
prtica so muitos, como percebemos. Entre eles, podemos destacar abstrao, organiza-
o e reaproveitamento de cdigo, por exemplo. Felizmente, no sempre que precisa-
mos de um trecho de cdigo que realiza um determinado processamento que temos ne-
cessariamente de programar esse trecho, construindo uma funo. A linguagem C fornece
uma biblioteca padro de funes que nos ajuda em muitas tarefas importantes, desde fun-
es de entrada e sada de dados, manipulao de cadeias de caracteres at funes mate-
mticas. Nesta aula, veremos algumas funes importantes, destacando que muitas outras
no sero cobertas aqui. Os interessados em mais informaes devem buscar a pgina do
guia de referncia da biblioteca da linguagem C. Nesta aula, cobrimos com algum detalhe os
arquivos que contm definies de macros, tipos e os prottipos das funes da biblioteca
padro de funes da linguagem C. Esses arquivos so tambm conhecidos como arquivos-
cabealhos e tm extenso .h, do ingls header.
Iniciamos com uma viso sobre os qualificadores de tipos existentes na linguagem C, funda-
mentais especialmente na declarao de parmetros sensveis alterao, tais como os vetores
e as matrizes, que so sempre parmetros por referncia. Em seguida, definimos arquivos-
cabealhos para, por fim, cobrir os arquivos-cabealhos da biblioteca padro da linguagem C.
Esta aula um guia de referncia da biblioteca padro da linguagem C, suas constantes, tipos
e funes principais. Algumas funes, por serem muito especficas, no foram listadas aqui.
A aula baseada nas referncias [17, 16].
209
210 B IBLIOTECA PADRO
cria um objeto const do tipo int com identificador n cujo valor 10 . A declarao abaixo:
podemos usar #define para criar um nome para uma constante numrica, caractere ou
cadeia de caracteres; por outro lado, podemos usar const para criar objetos somente
para leitura de qualquer tipo, incluindo vetores, estruturas, unies, apontadores, etc;
objetos criados com const esto sujeitos s mesmas regras de escopo de qualquer vari-
vel, mas constantes criadas com #define no;
o valor de um objeto criado com const pode ser visto em um depurador de programas;
o valor de uma macro no pode;
objetos criados com const no podem ser usados em expresses constantes; as constan-
tes criadas com #define podem;
podemos aplicar o operador de endereamento & sobre um objeto const , j que ele
possui um endereo; uma macro no tem um endereo.
No h uma regra bem definida que determina o uso de #define ou const na decla-
rao de constantes. Em geral, usamos a diretiva #define mais especificamente para criar
constantes que representam nmeros ou caracteres.
22.2 Arquivo-cabealho
FACOM UFMS
22.2 A RQUIVO - CABEALHO 211
#include <arquivo.h>
A segunda forma usada para todos os outros arquivos-cabealhos, incluindo aqueles que
so escritos por programadores(as):
#include "arquivo.h"
A diferena entre as duas formas se d pela maneira como o compilador busca o arquivo-
cabealho. Na primeira, o compilador busca o arquivo-cabealho no(s) diretrio(s) em que os
arquivos-cabealhos do sistema se encontram. Nos sistemas baseados no UNIX, como o LINUX,
os arquivos-cabealhos so mantidos usualmente no diretrio /usr/include . Na segunda
forma, a busca realizada no diretrio corrente e, em seguida, no(s) diretrio(s) em que os
arquivos-cabealhos do sistema se encontram.
Arquivos-cabealhos auxiliam no compartilhamento de definies de macros, de tipos e de
prottipos de funes por dois ou mais arquivos de cdigo fonte.
Abaixo apresentamos o arquivo-cabealho completo assert.h da biblioteca padro da
linguagem C.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
/*
* ISO C99 Standard: 7.2 Diagnostics <assert.h>
*/
FACOM UFMS
212 B IBLIOTECA PADRO
#ifdef _ASSERT_H
# undef _ASSERT_H
# undef assert
# undef __ASSERT_VOID_CAST
# ifdef __USE_GNU
# undef assert_perror
# endif
#endif /* assert.h */
#define _ASSERT_H 1
#include <features.h>
#ifdef NDEBUG
# ifdef __USE_GNU
# define assert_perror(errnum) (__ASSERT_VOID_CAST (0))
# endif
#ifndef _ASSERT_H_DECLS
#define _ASSERT_H_DECLS
__BEGIN_DECLS
FACOM UFMS
22.3 A RQUIVOS - CABEALHOS DA BIBLIOTECA PADRO 213
/* The following is not at all used here but needed for standard
compliance. */
extern void __assert (const char *__assertion, const char *__file,
int __line) __THROW __attribute__ ((__noreturn__));
__END_DECLS
# define assert(expr) \
((expr) \
? __ASSERT_VOID_CAST (0) \
: __assert_fail (__STRING(expr), __FILE__, __LINE__,
__ASSERT_FUNCTION))
# ifdef __USE_GNU
# define assert_perror(errnum)
\ (!(errnum) \
? __ASSERT_VOID_CAST (0) \
: __assert_perror_fail ((errnum), __FILE__, __LINE__,
__ASSERT_FUNCTION))
# endif
#endif /* NDEBUG. */
22.3.1 Diagnsticos
FACOM UFMS
214 B IBLIOTECA PADRO
verificao nos programas. Se uma verificao falha, o programa termina sua execuo.
No exemplo de trecho de cdigo a seguir, a macro assert monitora o valor do ndice i do
vetor v. Se esse valor no est no intervalo especificado, o programa terminado.
A biblioteca de manipulao, teste e converso de caracteres pode ser acessada atravs das
informaes contidas no arquivo-cabealho ctype.h.
Funes is...
int isalnum(int c)
Devolve verdadeiro se o contedo do parmetro c uma letra (de A a Z ou de a a
z) ou um dgito (de 0 a 9);
int isalpha(int c)
Devolve verdadeiro se o contedo do parmetro c uma letra (de A a Z ou de a a
z);
int iscntrl(int c)
Devolve verdadeiro se o contedo do parmetro c um caractere de controle (de 0 a 31
ou 127);
int isdigit(int c)
Devolve verdadeiro se o contedo do parmetro c um dgito (de 0 a 9);
FACOM UFMS
22.3 A RQUIVOS - CABEALHOS DA BIBLIOTECA PADRO 215
int isgraph(int c)
Devolve verdadeiro se o contedo do parmetro c um caractere imprimvel, exceto o
espao em branco, isto , caracteres 33 a 126);
int islower(int c)
Devolve verdadeiro se o contedo do parmetro c uma letra minscula (de a a z);
int isprint(int c)
Devolve verdadeiro se o contedo do parmetro c um caractere imprimvel, isto ,
caracteres de 32 a 126;
int ispunct(int c)
Devolve verdadeiro se o contedo do parmetro c um caractere de pontuao;
int isspace(int c)
Devolve verdadeiro se o contedo do parmetro c um branco (whitespace);
int isupper(int c)
Devolve verdadeiro se o contedo do parmetro c uma letra maiscula (de A a Z);
int isxdigit(int c)
Devolve verdadeiro se o contedo do parmetro c um dgito em hexadecimal (de 0 a
9, ou de a a f, ou ainda de A a F).
Funes to...
Uma funo em ctype.h com identificador da forma to... faz a converso de um carac-
tere. Se o caractere atende a uma condio, ento convertido. Caso contrrio, o caractere
devolvido sem modificaes.
Listamos abaixo as interfaces das funes da forma to... em ctype.h, acompanhadas de
explicaes:
int tolower(int c)
Se o parmetro c uma letra maiscula (de A a Z), ento o caractere convertido
para uma letra minscula e devolvido;
int toupper(int c)
Se o parmetro c uma letra minscula (de a a z), ento o caractere convertido
para uma letra maiscula e devolvido.
22.3.3 Erros
FACOM UFMS
216 B IBLIOTECA PADRO
errno = 0;
y = sqrt(x);
if (errno != 0)
exit(EXIT_FAILURE);
Nesse trecho de cdigo, observe que inicializamos a varivel errno declarada na biblioteca
errno.h. Se o valor dessa varivel diferente de zero aps a execuo da funo sqrt , isso
significa que um erro ocorreu em sua execuo, como por exemplo, quando o valor de x
negativo.
O valor armazenado na varivel errno , em geral, EDOM ou ERANGE , ambas macros
definidas em errno.h. Essas macros representam os dois tipos de erros que podem ocorrer
quando uma funo matemtica chamada: erro de domnio ou erro de intervalo, respectiva-
mente. No exemplo acima, se x tem valor negativo, ento o valor de EDOM armazenado na
varivel errno . Por outro lado, se o valor devolvido por uma funo muito grande, ultra-
passando a capacidade de representao do tipo do valor a ser devolvido pela funo, ento
o valor ERANGE armazenado em errno . Por exemplo, se 1000 argumento da funo exp,
ento isso provoca um erro de intervalo j que e1000 muito grande para ser representado por
um double .
Caractersticas dos tipos com ponto flutuante podem ser obtidas atravs da incluso do
arquivo-cabealho float.h. Esse arquivo fornece apenas macros que definem o intervalo e a
preciso dos tipos float , double e long double . No h variveis, tipos ou funes em
float.h.
Duas macros se aplicam a todos os tipos de ponto flutuante: FLT_ROUNDS e FLT_RADIX .
A primeira descreve a direo do arredondamento. A segunda especifica o comprimento da
representao do expoente.
As macros restantes descrevem as caractersticas dos tipos especficos de ponto flutuante.
22.3.5 Localizao
Constantes
Podemos usar uma das macros a seguir para especificar uma categoria:
FACOM UFMS
22.3 A RQUIVOS - CABEALHOS DA BIBLIOTECA PADRO 217
LC_COLLATE
Afeta o comportamento de duas funes de comparao de cadeias de caractere: strcoll
e strxfrm, ambas declaradas em string.h;
LC_CTYPE
Afeta o comportamento das funes em ctype.h, a menos de isdigit e isxdigit.
LC_MONETARY
Afeta a informao de formato monetrio devolvida pela funo localeconv, descrita
na prxima seo;
LC_NUMERIC
Afeta o caractere separador de decimais usado nas funes de formatao de entrada e
sada e as funes de converso numrica;
LC_TIME
Afeta o comportamento da funo strftime declarada em time.h, que converte um
horrio em uma cadeia de caracteres.
Funes
22.3.6 Matemtica
FACOM UFMS
218 B IBLIOTECA PADRO
Constantes
Uma nica macro definida neste arquivo-cabealho: HUGE_VAL . Essa macro indica que
o valor devolvido por uma funo muito grande para ser representado como um nmero de
preciso dupla. HUGE_VAL do tipo double e pode ser entendido como infinito.
Erros
Funes trigonomtricas
double cos(double x)
Devolve o cosseno de um ngulo x dado em radianos. O valor devolvido est no intervalo
[1, +1];
double sin(double x)
Devolve o seno de um ngulo x dado em radianos. O valor devolvido est no intervalo
[1, +1];
double tan(double x)
Devolve a tangente de um ngulo x dado em radianos;
double acos(double x)
Devolve o arco-cosseno de x em radianos. O valor de x deve estar no intervalo [1, +1].
O valor devolvido est no intervalo [0, ];
double asin(double x)
Devolve o arco-seno de x em radianos. O valor de x deve estar no intervalo [1, +1]. O
valor devolvido est no intervalo [/2, +/2];
double atan(double x)
Devolve o arco-tangente de x em radianos. O valor devolvido est no intervalo
[/2, +/2];
double atan2(double y, double x)
Devolve o arco-tangente em radianos de y/x baseado nos sinais de ambos os valores para
determinar o quadrante correto. O valor devolvido est no intervalo [/2, /2];
FACOM UFMS
22.3 A RQUIVOS - CABEALHOS DA BIBLIOTECA PADRO 219
double cosh(double x)
Devolve o cosseno hiperblico de x;
double sinh(double x)
Devolve o seno hiperblico de x;
double tanh(double x)
Devolve a tangente hiperblica de x. O valor devolvido est no intervalo [1, +1].
double exp(double x)
Devolve o valor de e elevado x-sima potncia;
double log(double x)
Devolve o logaritmo natural de x, isto , o logaritmo na base e;
double log10(double x)
Devolve o logaritmo de x na base 10;
double sqrt(double x)
Devolve a raiz quadrada de x. O valor armazenado em x no pode ser negativo.
FACOM UFMS
220 B IBLIOTECA PADRO
Outras funes
double ceil(double x)
double floor(double x)
double fabs(double x)
O ambiente armazenado na varivel amb por uma chamada prvia funo setjmp
recuperado. Uma salto ao ponto onde setjmp foi chamada realizado, e o contedo
armazenado em valor devolvido setjmp . Esse valor deve ser um nmero inteiro
diferente de zero.
FACOM UFMS
22.3 A RQUIVOS - CABEALHOS DA BIBLIOTECA PADRO 221
Constantes e variveis
O tipo sig_atomic_t , na verdade um apelido para o tipo int , usado para declarao
de variveis que manipulam erros.
As macros com identificadores iniciando com SIG_ so usadas com a funo signal :
SIG_DFL
Manipulador de erros padro;
SIG_ERR
Sinal de erro;
SIG_IGN
Ignora sinal.
As macros com identificadores iniciando com SIG so usadas para representar um nmero
de sinal:
SIGABRT
Trmino anormal gerado pela funo abort ;
SIGFPE
Erro de ponto flutuante, causado por diviso por zero, operao no vlida, etc;
SIGILL
Operao ilegal;
SIGINT
Sinal de ateno interativo, tal como um Ctrl-c ;
SIGSEGV
Acesso no vlido a uma poro de memria, tal como violao de segmento ou violao
de memria;
SIGTERM
Requisio de trmino.
FACOM UFMS
222 B IBLIOTECA PADRO
Funes
Listamos abaixo as interfaces das funes de entrada e sada formatadas em stdio.h, acom-
panhadas de explicaes:
FACOM UFMS
22.3 A RQUIVOS - CABEALHOS DA BIBLIOTECA PADRO 223
int getchar(void)
L um caractere (um unsigned char) da entrada padro. Se a leitura tem sucesso, o
caractere devolvido;
Constantes
NULL
Valor de um apontador nulo;
EXIT_FAILURE e EXIT_SUCCESS
Valores usados pela funo exit para devolver o estado do trmino da execuo de um
programa;
RAND_MAX
Valor mximo devolvido pela funo rand .
FACOM UFMS
224 B IBLIOTECA PADRO
Funes de ambiente
void abort(void)
Finaliza o programa anormalmente, sinalizando o trmino sem sucesso para o ambiente;
Funes matemticas
FACOM UFMS
22.3 A RQUIVOS - CABEALHOS DA BIBLIOTECA PADRO 225
int abs(int x)
Devolve o valor absoluto de x ;
int rand(void)
Devolve um nmero pseudo-aleatrio no intervalo [0, RAND_MAX ];
Constantes e tipos
A macro NULL definida em string.h, para denotar uma cadeia de caracteres vazia, assim
como o tipo typedef size_t, que permite a manipulao de variveis que contm compri-
mentos de cadeias de caracteres. Ou seja, esse tipo na verdade um tipo int .
Funes
FACOM UFMS
226 B IBLIOTECA PADRO
FACOM UFMS
22.3 A RQUIVOS - CABEALHOS DA BIBLIOTECA PADRO 227
A biblioteca que contm funes para determinar, manipular e formatar horrios e datas
pode ser acessada atravs do arquivo-cabealho time.h.
Exerccios
que receba um nmero real x e um nmero positivo real > 0, e calcule uma apro-
ximao para cos x, onde x dado em radianos, atravs da seguinte srie:
x2 x4 x6 x2k
cos x = 1 + + . . . + (1)k + ...
2! 4! 6! (2k)!
x2k
incluindo todos os termos Tk = (2k)! , at que Tk < .
(b) Escreva uma funo com a seguinte interface:
que receba um nmero real x e um nmero real > 0, e calcule uma aproximao
para sen x, onde x dado em radianos, atravs da seguinte srie:
x x3 x5 x2k+1
sen x = + . . . + (1)k + ...
1! 3! 5! (2k + 1)!
x2k+1
incluindo todos os termos Tk = (2k+1)! , at que Tk < .
(c) Escreva um programa que receba um nmero real x representando um ngulo em
radianos e um nmero real > 0 representando uma preciso, e calcule o valor de
tan x de duas formas: usando as funes dos itens acima e usando a funo tan da
biblioteca math . Compare os resultados.
FACOM UFMS
228 B IBLIOTECA PADRO
que receba duas cadeias de caracteres palavra e frase e um inteiro pos e veri-
fique se a cadeia de caracteres palavra ocorre na posio pos da cadeia de carac-
teres frase . Em caso positivo, a funo deve devolver 1. Em caso negativo, deve
devolver zero.
(b) Escreva um programa que receba duas cadeias de caracteres padrao e texto ,
com m e n caracteres respectivamente e m 6 n, e imprima o nmero de vezes que
padrao ocorre em texto .
Use todas as funes da biblioteca string que puder.
FACOM UFMS
AULA 23
D EPURAO DE PROGRAMAS
medida que temos resolvido problemas maiores e mais complexos, natural e conseqen-
temente nossos programas tm ganhado complexidade e extenso. Uso correto de estruturas
de programao, identificadores de variveis significativos, indentao, documentao, tudo
isso tem sido feito na tentativa de escrever programas corretamente. Ou seja, nosso desejo
sempre escrever programas eficientes, coesos e corretos.
Infelizmente, nem sempre isso possvel. Por falta de ateno, de experincia, de disciplina,
ou mesmo pela complexidade do problema que precisamos resolver, no incomum o desen-
volvimento de um programa que contm erros. Nesta aula, aprenderemos a usar um poderoso
depurador de programas interativo, chamado GDB, como aliado na construo de programas
corretos. Veremos algumas de suas principais caractersticas, talvez as mais teis. Interessa-
dos(as) em mais informaes e caractersticas avanadas desta ferramenta devem consultar a
pgina e o manual da mesma.
iniciar a execuo de um programa, especificando qualquer coisa que possa afetar seu
comportamento;
modificar algo no programa, permitindo que o programador corrija um erro e possa con-
tinuar a investigar outros erros no mesmo programa.
O depurador GDB pode ser usado para depurar programas escritos nas linguagens de pro-
gramao C, C++, Objective-C, Modula-2, Pascal e Fortran.
1
Richard Matthew Stallman (), nascido nos Estados Unidos, fsico, ativista poltico e ativista de software.
229
230 D EPURAO DE PROGRAMAS
GDB um software livre, protegido pela Licena Pblica Geral (GPL) da GNU . A GPL d a
seu usurio a liberdade para copiar ou adaptar um programa licenciado, mas qualquer pessoa
que faz uma cpia tambm deve ter a liberdade de modificar aquela cpia o que significa que
deve ter acesso ao cdigo fonte , e a liberdade de distribuir essas cpias. Empresas de software
tpicas usam o copyright para limitar a liberdade dos usurios; a Fundao para o Software Livre
(Free Software Foundation) usa a GPL para preservar essas liberdades. Fundamentalmente, a
Licena Pblica Geral (GPL) uma licena que diz que todas as pessoas tm essas liberdades e
que ningum pode restringi-las.
Para executar um programa com auxlio do depurador GDB, o programa fonte na lingua-
gem C deve ser compilado com o compilador GCC usando a diretiva de compilao ou opo
-g . Essa diretiva de compilao faz com que o compilador adicione informaes extras no
programa executvel que sero usadas pelo GDB.
De uma janela de comandos, voc pode chamar o depurador GDB, como a seguir:
prompt$ gdb
GNU gdb 6.8-debian
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
(gdb)
faz a chamada do depurador GDB com a carga do programa executvel consecutivos , que
foi previamente gerado pelo processo de compilao, usando o compilador GCC com a diretiva
de compilao -g .
FACOM UFMS
23.3 S INTAXE DOS COMANDOS DO GDB 231
Para sair do GDB e retornar janela de comandos basta digitar o comando quit , como a
seguir:
(gdb) quit
prompt$
Um comando do GDB composto por uma linha de entrada, contendo o nome do comando
seguido de zero ou mais argumentos. O nome de um comando do GDB pode ser truncado, caso
essa abreviao no seja ambga. O usurio tambm pode usar a tecla Tab para fazer com que
o GDB preencha o resto do nome do comando ou para mostrar as alternativas disponveis, caso
exista mais que uma possibilidade. Uma linha em branco como entrada significa a solicitao
para que o GDB repita o ltimo comando fornecido pelo usurio.
Podemos solicitar ao GDB informaes sobre os seus comandos usando o comando help .
Atravs do comando help , que pode ser abreviado por h , sem argumentos, obtemos uma
pequena lista das classes de comandos do GDB:
Type "help" followed by a class name for a list of commands in that class.
Type "help all" for the list of all commands.
Type "help" followed by command name for full documentation.
Type "apropos word" to search for commands related to "word".
Command name abbreviations are allowed if unambiguous.
(gdb)
Usando o nome de uma das classes gerais de ajuda como um argumento do comando
help , podemos obter uma lista dos comandos desta classe. Por exemplo,
FACOM UFMS
232 D EPURAO DE PROGRAMAS
List of commands:
info - Generic command for showing things about the program being debugged
macro - Prefix for commands dealing with C preprocessor macros
show - Generic command for showing things about the debugger
Tambm podemos usar o comando help diretamente com o nome de um comando que
queremos ajuda. Por exemplo,
Para colocar um programa executvel sob execuo no GDB necessrio usar o comando
run , que pode ser abreviado por r . Este programa executvel deve ter sido usado como um
parmetro na chamada do depurador ou ento deve ser carregado no GDB usando o comando
file ou exec-file .
FACOM UFMS
23.4 P ONTOS DE PARADA 233
Muitas vezes, queremos eliminar um ponto de parada que j cumpriu o seu papel na de-
purao do programa e no queremos mais que o programa seja interrompido naquele ponto
previamente especificado. Podemos usar os comandos clear ou delete para remover um
ou mais pontos de parada de um programa. Os comandos clear e delete , com um ar-
gumento numrico, removem um ponto de parada especificado. Por exemplo, os comandos
clear 1 e delete 2 removem os pontos de parada identificados pelos nmeros 1 e 2, res-
FACOM UFMS
234 D EPURAO DE PROGRAMAS
O GDB pode imprimir partes do cdigo fonte do programa sendo depurado. Quando um
programa tem sua execuo interrompida por algum evento, o GDB mostra automaticamente o
contedo da linha do cdigo fonte onde o programa parou. Para ver outras pores do cdigo,
podemos executar comandos especficos do GDB.
O comando list mostra ao() programador(a) algumas linhas do cdigo fonte carregado
previamente. Em geral, mostra 10 linhas em torno do ponto onde a execuo do programa
se encontra. Podemos explicitamente solicitar ao GDB que mostre um intervalo de linhas do
cdigo fonte, como por exemplo, list 1,40 . Neste caso, as primeiras 40 linhas do cdigo
fonte do programa carregado no GDB sero mostradas.
FACOM UFMS
23.6 V ERIFICAO DE DADOS 235
(gdb) l 1,40
1 #include <stdio.h>
2
3 /* Recebe um nmero inteiro positivo e verifica se
4 esse nmero tem dois dgitos consecutivos iguais */
5 int main(void)
6 {
7 int num, ant, prox, iguais;
8
9 printf("\nInforme um nmero: ");
10 scanf("%d", &num);
11
12 prox = num % 10;
13 iguais = 0;
14 while (num != 0 && !iguais) {
15 num = num / 10;
16 ant = prox;
17 prox = num % 10;
18 if (ant == prox)
19 iguais = 1;
20 }
21
22 if (iguais)
23 printf("Nmero tem dois dgitos consecutivos iguais\n");
24 else
25 printf("Nmero no tem dois dgitos consecutivos iguais\n");
26
27 return 0;
28 }
(gdb)
FACOM UFMS
236 D EPURAO DE PROGRAMAS
P ROGRAMA F ONTE
list [n] Mostra linhas em torno da linha n ou as prximas 10 linhas, se no
especificada
list m,n Mostra linhas entre m e n
VARIVEIS E E XPRESSES
print expr Imprime expr
display expr Adiciona expr lista de impresso automtica
info display Mostra a lista de impresso automtica
delete display n Remove a expresso de nmero n da lista de impresso automtica
info locals Mostra o contedo de todas as variveis locais na funo corrente
set var var = expr Atribui expr para a varivel var
P ONTOS DE PARADA
break n Estabelece um breakpoint na linha n
break n if expr Estabelece um breakpoint na linha n se o valor de expr for verdadeiro
break func Estabelece um breakpoint no incio da funo func
watch expr Estabelece um watchpoint na expresso expr
clear [n] Remove o ponto de parada na linha n ou na prxima linha, se no
especificada
delete [n] Remove o ponto de parada de nmero n ou todos os pontos de parada,
se no especificado
enable [n] Habilita todos os pontos de parada suspensos ou o ponto de parada n
disable [n] Desabilita todos os pontos de parada ou o ponto de parada n
info break Mostra todos os pontos de parada
E XECUO DO P ROGRAMA
file [prog] Carrega o programa executvel prog e sua tabela de smbolos ou
libera o GDB da execuo corrente, se no especificado
exec-file [prog] Carrega o programa executvel prog ou libera o GDB da execuo
corrente, se no especificado
run Inicia a execuo do programa
continue Continua a execuo do programa
step [n] Executa a prxima sentena do programa ou as prximas n sentenas
next [n] Executa a prxima sentena do programa ou as prximas n sentenas,
desconsiderando chamadas de funes do(a) programador(a)
info program Mostra o estado da execuo do programa
quit Encerra a execuo do GDB
A JUDA
help Mostra as classes de ajuda de comandos do GDB
help classe Mostra uma ajuda sobre a classe de comandos
help comando Mostra uma ajuda sobre o comando
FACOM UFMS
23.9 E XEMPLOS DE EXECUO 237
Esta uma relao dos comandos que aprendemos nesta aula, com uma explicao breve
sobre cada um. A inteno agrupar os comandos em um lugar s, para que a relao nos sirva
de referncia. Vale reiterar que o GDB possui muitos outros comandos interessantes, mas que
infelizmente no puderam ser cobertos neste texto. O(A) leitor(a) interessado(a) deve consultar
as referncias desta aula para mais informaes.
Vamos usar o GDB sobre o programa 23.1 que soluciona o exerccio 7.3. No exerccio 7.3
temos de verificar se um nmero inteiro positivo fornecido como entrada contm dois dgitos
consecutivos e iguais.
#include <stdio.h>
if (iguais)
printf("Nmero tem dois dgitos consecutivos iguais\n");
else
printf("Nmero no tem dois dgitos consecutivos iguais\n");
return 0;
}
FACOM UFMS
238 D EPURAO DE PROGRAMAS
Para verificar se o programa foi de fato carregado na chamada do GDB, podemos usar o
comando list para ver seu cdigo fonte ou ento o comando info program , para visualizar
o estado do programa:
(gdb) l 1,14
1 #include <stdio.h>
2
3 /* Recebe um nmero inteiro positivo e verifica se
4 esse nmero tem dois dgitos consecutivos iguais */
5 int main(void)
6 {
7 int num, ant, prox, iguais;
8
9 printf("\nInforme um nmero: ");
10 scanf("%d", &num);
11
12 prox = num % 10;
13 iguais = 0;
14 while (num != 0 && !iguais) {
(gdb)
ou
(gdb) run
Starting program: /ensino/disciplinas/api/2010/programas/consecutivos
FACOM UFMS
23.9 E XEMPLOS DE EXECUO 239
A execuo acima foi realizada dentro do GDB, sem a adio de qualquer ponto de parada.
Como o programa ainda continua carregado no GDB, podemos execut-lo quantas vezes qui-
sermos. Antes de iniciar a prxima execuo, vamos adicionar alguns pontos de parada no
programa:
(gdb) break 9
Breakpoint 1 at 0x400575: file consecutivos.c, line 9.
(gdb)
(gdb) run
Starting program: /ensino/disciplinas/api/programas/consecutivos
Observe que todas as variveis declaradas constam da relao apresentada pelo GDB e que seus
contedos so valores estranhos, j que nenhuma dessas variveis foi inicializada at a linha 9
do programa.
Vamos adicionar mais pontos de parada neste programa, um deles um breakpoint associado
a uma expresso lgica e o outro um watchpoint associado a uma varivel:
Agora, podemos visualizar todos os pontos de parada associados a este programa com o
comando info break :
FACOM UFMS
240 D EPURAO DE PROGRAMAS
(gdb) continue
Continuing.
(gdb) continue
Continuing.
FACOM UFMS
23.9 E XEMPLOS DE EXECUO 241
(gdb) continue
Continuing.
Hardware watchpoint 3: iguais
Old value = 0
New value = 1
main () at consecutivos.c:14
14 while (num != 0 && !iguais) {
(gdb)
Observe que o programa foi interrompido pelo watchpoint, j que o contedo da varivel
iguais foi modificado de 0 para 1 na linha 19 do programa. Assim, a prxima linha a ser
executada a linha 14, como mostrado pelo GDB.
Vamos dar uma olhada no contedo das variveis da funo main :
(gdb) continue
Continuing.
Nmero tem dois dgitos consecutivos iguais.
Mais uma anlise detalhada e mais alguns testes sobre o programa 23.1 nos permitem afir-
mar com alguma convico que este programa est correto e que soluciona o exerccio 7.3. O
fato novo que essa afirmao foi feita tambm com o GDB nos auxiliando. Para provar for-
malmente que o programa 23.1 est correto, devemos descrever algum invariante do processo
iterativo das linhas 14 at 20 do programa e ento provar por induo a sua validade. Essa
tcnica de demonstrao de correo vale para programas que possuem uma ou mais estrutu-
ras de repetio, como o caso do programa 23.1. Aprenderemos mais sobre demonstrao de
correo de programas e algoritmos em disciplinas posteriores do nosso curso.
No prximo exemplo vamos executar um programa sob o controle do GDB que no soluci-
ona o problema associado, isto , contm algum erro que, primeira vista, no conseguimos
corrigir. O programa 23.2 se prope a implementar a ordenao por seleo.
FACOM UFMS
242 D EPURAO DE PROGRAMAS
Programa 23.2: Uma verso de um programa que deveria realizar a ordenao por seleo.
#include <stdio.h>
#define MAX 10
scanf("%d", &n);
for (i = 0; i < n; i++)
scanf("%d", &A[i]);
return 0;
}
prompt$ ./ord-selecao
8
7 5 4 1 8 6 2 3
Falha de segmentao
prompt$
Esse erro no nos d nenhuma dica de onde procur-lo. E se j nos debruamos sobre o
cdigo fonte e no conseguimos encontr-lo, a melhor idia usar um depurador para nos
ajudar. Neste exemplo, mostraremos o uso do GDB sem muitas interrupes no texto, a menos
que necessrias. Ento, segue uma depurao do programa 23.2.
FACOM UFMS
23.9 E XEMPLOS DE EXECUO 243
(gdb) step 4
19 if (A[j] < menor) {
(gdb) info locals
i = 0
j = 7
n = 8
menor = 7
indice = 0
aux = -1208630704
A = {7, 5, 4, 1, 8, 6, 2, 3, 134518484, -1075407768}
(gdb) display A[j]
1: A[j] = 3
(gdb) display j
2: j = 7
(gdb) display i
3: i = 0
(gdb) watch menor
Hardware watchpoint 2: menor
(gdb) continue
Continuing.
Hardware watchpoint 2: menor
Old value = 7
New value = 3
main () at ord-selecao.c:21
21 indice = j;
3: i = 0
2: j = 7
1: A[j] = 3
FACOM UFMS
244 D EPURAO DE PROGRAMAS
(gdb) continue
Continuing.
Hardware watchpoint 2: menor
Old value = 3
New value = -1075407768
main () at ord-selecao.c:21
21 indice = j;
3: i = 0
2: j = 9
1: A[j] = -1075407768
(gdb) c
Continuing.
Hardware watchpoint 2: menor
7 5 4 1 8 6 2 3
FACOM UFMS
23.9 E XEMPLOS DE EXECUO 245
FACOM UFMS
246 D EPURAO DE PROGRAMAS
(gdb) step
45 if (sufixo(x, y))
(gdb) next
48 x = x / 10;
(gdb) list 44,50
44 while (x >= y && !subseq)
45 if (sufixo(x, y))
46 subseq = VERDADEIRO;
47 else
48 x = x / 10;
49 if (subseq)
50 printf("%d S %d\n", a, b);
(gdb) step
FACOM UFMS
23.9 E XEMPLOS DE EXECUO 247
(gdb) continue
Continuing.
FACOM UFMS
248 D EPURAO DE PROGRAMAS
#define VERDADEIRO 1
#define FALSO 0
suf = VERDADEIRO;
while (b != 0 && suf)
if (a % 10 != b % 10)
suf = FALSO;
else {
a = a / 10;
b = b / 10;
}
return suf;
}
scanf("%d", &n);
while (n > 0) {
scanf("%d%d", &a, &b);
x = a;
y = b;
if (x < y) {
aux = x;
x = y;
y = aux;
}
else {
aux = a;
a = b;
b = aux;
}
subseq = FALSO;
while (x >= y && !subseq)
if (sufixo(x, y))
subseq = VERDADEIRO;
else
x = x / 10;
if (subseq)
printf("%d S %d\n", a, b);
else
printf("N\n");
n--;
}
return 0;
}
FACOM UFMS
AULA 24
P R - PROCESSADOR
24.1 Funcionamento
programa em C
pr-processador
programa em C modificado
compilador
cdigo objeto
249
250 P R - PROCESSADOR
A maioria das diretivas de pr-processamento pertencem a uma das trs categorias a seguir:
definio de macros: a diretiva #define define uma macro, tambm chamada de cons-
tante simblica; a diretiva #undef remove a definio de uma macro;
incluso de arquivos: a diretiva #include faz com que o contedo de um arquivo es-
pecificado seja includo em um programa;
As outras diretivas #error , #line e #pragma so mais especficas e usadas com menos
freqncia. Antes de descrev-las com mais detalhes, listamos abaixo as regras que se aplicam
a todas elas:
FACOM UFMS
24.3 D EFINIES DE MACROS 251
onde lista-de-troca uma seqncia qualquer de itens. Essa lista pode incluir identifica-
dores, palavras reservadas, constantes numricas, constantes de caracteres, literais, operadores
e pontuao. Quando encontra uma definio de uma macro, o pr-processador toma nota
que o identificador representa a lista-de-troca . Sempre que identificador ocorre
posteriormente no arquivo, o pr-processador o substitui pela lista-de-troca .
Um erro freqente na definio de macros a incluso de smbolos extras, que conseqen-
temente faro parte da lista de troca. Abaixo so mostrados dois exemplos de erros como esse.
A traduo do trecho de cdigo acima realizada pelo pr-processador gera o seguinte trecho
de cdigo modificado, correspondente s duas ltima linhas:
FACOM UFMS
252 P R - PROCESSADOR
Podemos usar macros para dar nomes a valores numricos, caracteres e literais, como ilus-
trado abaixo:
#define COMPRIMENTO 80
#define VERDADEIRO 1
#define FALSO 0
#define PI 3.141592
#define ENTER \n
#define ERRO "Erro: memria insuficiente\n"
Usar a diretiva #define para criar nomes para constantes tem diversas vantagens, como
tornar os programas mais fceis de ler e de modificar, ajudar a evitar inconsistncias e erros
tipogrficos, permitir pequenas mudanas na sintaxe da linguagem, renomear tipos e controlar
a compilao condicional.
Vamos recordar a aula 22. A diretiva #include ordena o pr-processador a abrir um ar-
quivo especificado e a inserir seu contedo no arquivo atual. Assim, se queremos que vrios
arquivos de cdigo fonte tenham acesso mesma informao, devemos colocar essa infor-
mao em um arquivo e ento usar a diretiva #include para trazer o contedo do arquivo
em cada arquivo de cdigo fonte. Arquivos que so includos dessa forma so chamados de
arquivos-cabealhos, do ingls header files ou tambm include files. Por conveno, um arquivo
como esse tem a extenso .h .
A diretiva #include pode ser usada de duas formas. A primeira forma usada para
arquivos-cabealhos que pertencem biblioteca padro da linguagem C:
#include <arquivo.h>
A segunda forma usada para todos os outros arquivos-cabealhos, incluindo aqueles que
so escritos por programadores(as):
#include "arquivo.h"
A diferena entre as duas formas se d pela maneira como o compilador busca o arquivo-
cabealho. Na primeira, o compilador busca o arquivo-cabealho no(s) diretrio(s) em que os
arquivos-cabealhos do sistema se encontram. Nos sistemas baseados no UNIX, como o LINUX,
os arquivos-cabealhos so mantidos usualmente no diretrio /usr/include . Na segunda
forma, a busca realizada no diretrio corrente e, em seguida, no(s) diretrio(s) em que os
arquivos-cabealhos do sistema se encontram.
Arquivos-cabealhos auxiliam no compartilhamento de definies de macros, de tipos e de
prottipos de funes por dois ou mais arquivos de cdigo fonte.
FACOM UFMS
24.4 I NCLUSO DE ARQUIVOS - CABEALHOS 253
#define PAR 0
#define IMPAR 1
#define Algoritmo main
#define inicio {
#define fim }
#define escreva printf
#define leia scanf
#define se if
#define senao else
#define enquanto while
#define devolva return
se (numero % 2 == 0)
paridade = PAR;
senao
paridade = IMPAR;
devolva paridade;
fim
s_par = 0;
s_impar = 0;
i = 1;
enquanto (i <= n)
inicio
escreva("Informe um nmero: ");
leia("%d", &numero);
se (par_impar(numero) == PAR)
somapar = somapar + numero;
senao
somaimpar = somaimpar + numero;
i++;
fim
escreva("\nSoma dos nmeros pares: %d\n", s_par);
escreva("Soma dos nmeros mpares: %d\n", s_impar);
devolva 0;
fim
FACOM UFMS
254 P R - PROCESSADOR
#if expresso-constante
#define DEBUG 1
.
.
.
#if DEBUG
printf("Valor de i = %d\n", i);
printf("Valor de j = %d\n", j);
#endif
Durante o pr-processamento, a diretiva #if verifica o valor de DEBUG . Como seu va-
lor diferente de zero, o pr-processador mantm as duas chamadas funo printf no
programa, mas as linhas contendo as diretivas #if e #endif sero eliminadas aps o pr-
processamento. Se modificamos o valor de DEBUG para 0 (zero) e recompilamos o programa,
ento o pr-processador remove todas as 4 linhas do programa. importante notar que a dire-
tiva #if trata identificadores no definidos como macros que tm o valor 0 (zero). Assim, se
esquecemos de definir DEBUG , o teste
#if DEBUG
FACOM UFMS
24.5 C OMPILAO CONDICIONAL 255
#if !DEBUG
#ifdef identificador
Linhas a serem includas se o identificador est definido como uma macro
#endif
#ifndef identificador
Linhas a serem includas se o identificador no est definido como uma macro
#endif
As diretivas #elif e #else podem ser usadas em conjunto com as diretivas #if ,
#ifdef e #ifndef quando aninhamento de blocos so necessrios. O formato geral dessas
diretivas apresentado abaixo:
#elif expresso-constante
#else
#if expresso1
Linhas a serem includas se expresso1 diferente de zero
#elif expresso2
Linhas a serem includas se expresso2 diferente de zero
#else
Linhas a serem includas em caso contrrio
#endif
FACOM UFMS
256 P R - PROCESSADOR
As diretivas #error , #line e #pragma so mais especficas e por isso menos usadas.
A diretiva #error faz com que o pr-processador imprima uma mensagem de erro na
sada padro. A diretiva #error tem o seguinte formato geral:
#error mensagem
onde mensagem uma seqncia qualquer de caracteres. Um exemplo de uso dessa diretiva
apresentado no trecho de cdigo a seguir:
#ifdef LINUX
.
.
.
#else
#error Sistema operacional no especificado
#endif
Se o pr-processador encontra uma diretiva #error , isso sinal de que uma falha grave
ocorreu no programa e alguns compiladores terminam imediatamente a compilao.
A diretiva #line usada para alterar a forma como as linhas do programa so numeradas.
O formato geral dessa diretiva apresentado abaixo:
#line n
#line n "arquivo"
#pragma diretiva
FACOM UFMS
R EFERNCIAS B IBLIOGRFICAS
[6] P. Breton, Histria da Informtica. Editora da UNESP, 1991. Traduo de Elcio Fernandes
do original Histoire de Linformatique, 1987, Editions La Decouvert. 1
257
258 REFERNCIAS BIBLIOGRFICAS
[12] K. Zuse, Verfahren zur selbstttigen Durchfhrung von Rechnungen mit Hilfe von Re-
chenmaschinen. Patentanmeldung Z 23 139 GMD Nr. 005/021, 1936. 2.1
[13] H. Lukoff, From Dits to Bits... a Personal History of the Electronic Computer. Hawley
Books, 1979. 2.1
[14] J. von Neumann, First draft of a report on the EDVAC, tech. rep., Moore School of Elec-
trical Engineering University of Pennsylvania, 1945. 2.1, 2.3
[15] P. Feofiloff, Algoritmos em linguagem C. Editora Campus/Elsevier, 2009. 4.5, 4.5, 5, 5.3.1,
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21
[20] B. W. Kernighan and D. M. Ritchie, C Programming Language. Prentice Hall, 2nd ed.,
1988.
[21] D. E. Knuth, The Art of Computer Programming, vol. 17. Addison-Wesley, 3rd ed., 1997.
[22] S. G. Kochan, Unix Shell Programming. Sams Publishing, 3rd ed., 2003.
[23] K. A. Lambert, D. W. Nance, and T. L. Naps, Introduction to Computer Science with C++.
West Publishing Company, 1996.
[25] G. J. Pothering and T. L. Naps, Introduction to Data Structures and Algorithm Analysis
with C++. West Publishing Company, 1995.
FACOM UFMS