Sei sulla pagina 1di 103

Bruno Jefferson de Sousa

Jos Jorge Lima Dias Jnior


Andrei de Arajo Formiga

Introduo a Programao

Editora da UFPB
Joo Pessoa
2014

Introduo Programao

Introduo Programao

Introduo Programao

Sumrio

Algoritmos

1.1

Introduo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1.2

O que um algoritmo? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1.3

Caractersticas de um algoritmo . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1.4

Formas de representao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1.4.1

Descrio Narrativa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1.4.2

Fluxograma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1.4.3

Linguagem Algortmica . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1.5

Recapitulando . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1.6

Exerccios Propostos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Introduo Programao

11

2.1

Introduo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

11

2.2

Nveis das Linguagens de Programao . . . . . . . . . . . . . . . . . . . . . . . .

12

2.3

Tradutores e Interpretadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

13

2.4

Paradigmas de Programao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

15

2.5

Linguagem C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

16

2.6

Ncleo de um programa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

16

2.7

Memria e Variveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

17

2.7.1

Identificadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

18

2.7.2

Tipos de dados primitivos . . . . . . . . . . . . . . . . . . . . . . . . . . .

19

2.7.3

Declarao de variveis . . . . . . . . . . . . . . . . . . . . . . . . . . . .

21

2.7.4

Constantes simblicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

22

2.8

Comentrios e indentao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

23

2.9

Matemtica Bsica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

25

2.10 Entrada e sada de dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

26

2.10.1 Funo printf() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

27

2.10.2 Funo scanf() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

28

2.11 Recapitulando . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

29

2.12 Exerccios Propostos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

30

ii

Introduo Programao
3

Estruturas de Controle

32

3.1

Introduo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

32

3.2

Estrutura Sequencial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

32

3.3

Estrutura de Deciso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

33

3.3.1

Deciso simples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

33

3.3.1.1

Expresses lgicas . . . . . . . . . . . . . . . . . . . . . . . . . .

34

3.3.1.2

Exerccio resolvido . . . . . . . . . . . . . . . . . . . . . . . . .

36

3.3.1.3

Verificao da condio com expresses aritmticas na Linguagem C 37

3.3.2

Deciso composta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

38

3.3.2.1

Exerccio resolvido . . . . . . . . . . . . . . . . . . . . . . . . .

39

Comando de deciso mltipla . . . . . . . . . . . . . . . . . . . . . . . . .

40

Estrutura de Repetio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

42

3.4.1

Comando while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

42

3.4.1.1

Exerccio resolvido . . . . . . . . . . . . . . . . . . . . . . . . .

43

3.4.2

Comando do-while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

44

3.4.3

Comando for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

45

3.4.4

Lao infinito . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

46

3.4.5

Exerccio Resolvido . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

47

3.4.6

Comandos de desvio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

48

3.4.6.1

Comando break . . . . . . . . . . . . . . . . . . . . . . . . . . .

48

3.4.6.2

Comando continue . . . . . . . . . . . . . . . . . . . . . . . . . .

49

3.5

Recapitulando . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

50

3.6

Exerccios Propostos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

50

3.3.3
3.4

Arranjos

52

4.1

Introduo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

52

4.2

Vetores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

52

4.2.1

Declarao de Vetores . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

53

4.2.2

Acessando os elementos de um vetor . . . . . . . . . . . . . . . . . . . . .

53

4.2.3

Exerccio resolvido . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

55

Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

57

4.3.1

Lendo e imprimindo Strings . . . . . . . . . . . . . . . . . . . . . . . . . .

57

4.3.2

Manipulando strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

58

4.3.3

Exerccio resolvido . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

59

4.4

Matrizes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

59

4.5

Recapitulando . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

61

4.6

Exerccios Propostos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

61

4.3

iii

Introduo Programao
5

Funes

63

5.1

O que so funes? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

63

5.1.1

Um exemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

64

5.2

Parmetros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

67

5.3

Retorno de Valores com Funes . . . . . . . . . . . . . . . . . . . . . . . . . . . .

69

5.3.1

Funes, Procedimentos e o Tipo void . . . . . . . . . . . . . . . . . . . .

70

5.4

Um Exemplo Matemtico: Equao de Segundo Grau . . . . . . . . . . . . . . . . .

73

5.5

Escopo de Variveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

76

5.5.1

Escopo dos Parmetros . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

78

5.5.2

Sombreamento e Sobreposio de Escopos . . . . . . . . . . . . . . . . . .

78

Passagem de Parmetros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

80

5.6.1

Passagem por Valor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

81

5.6.2

Passagem por Referncia . . . . . . . . . . . . . . . . . . . . . . . . . . . .

82

5.6.2.1

Realizando troca de valores com variveis globais . . . . . . . . .

83

5.7

Prottipos e Declarao de Funes . . . . . . . . . . . . . . . . . . . . . . . . . .

85

5.8

Funes Recursivas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

87

5.9

Recapitulando . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

90

5.10 Exerccios Propostos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

90

ndice Remissivo

92

5.6

iv

Introduo Programao

Prefcio
BAIXANDO A VERSO MAIS NOVA DESTE LIVRO
Acesse https://github.com/edusantana/introducao-a-programacao-livro/releases para verificar se h uma verso mais o Histrico de revises, na incio do livro, para verificar o
que mudou entre uma verso e outra.
Este livro destinado a alunos de cursos como Cincia da Computao, Sistemas de Informao,
Engenharia da Computao e, sobretudo, Licenciatura em Computao. Ele tem o objetivo de apresentar os principais conceitos da programao de computadores, de modo que sua utilizao mais
adequado a disciplinas introdutrias como a de Introduo Programao. De forma alguma o presente livro tem a pretenso de cobrir todos os assuntos relacionados rea de programao. Sua
principal finalidade a de servir como guia para os alunos que esto dando os primeiros passos nessa
rea que to importante para a cincia da computao.
A disciplina de Introduo Programao a primeira de uma sequncia de disciplinas que tm o objetivo de tornar os alunos capazes dominar os fundamentos e as tcnicas relacionadas programao
de computadores. Durante o curso de Licenciatura em Computao, especificamente, os alunos tero
a chance de conhecer em detalhes algumas das linguagens de programao mais utilizadas atualmente
e estaro habilitados a ministrar cursos de programao para diversos pblicos.
Mais importante do que conhecer as peculiaridades das linguagens de programao aprender como
funciona a lgica aplicada na elaborao de solues desenvolvidas a partir de algoritmos computacionais. Sendo assim, o principal objetivo deste livro ensin-los a resolver problemas com base
nos comandos e mecanismos presentes nas linguagens de programao, desenvolvendo assim o que
chamamos de lgica de programao. No decorrer do livro, o leitor aprender gradativamente a dar
instrues ao computador atravs de programas que ele prprio ser capaz de criar. Para isso, conhecer a linguagem de programao C, uma das mais utilizadas e mais importantes linguagens na rea
de Cincia da Computao.
No Captulo 1 ser abordado o conceito de algoritmo, e suas principais formas de representao sero
apresentadas. No Captulo 2, descrevemos todo o processo de traduo de um programa escrito em
linguagem de alto nvel para um programa equivalente em cdigo de mquina, isto , a linguagem que
os computadores conhecem. Alm disso, ser apresentado ao leitor a estrutura de um programa na
linguagem C, o que o habilitar o leitor a desenvolver seu primeiro programa. O Captulo 3 consiste
no contedo do livro que mais desenvolve a lgica de programao. nele que se encontram as
principais instrues de uma linguagem de programao: as estruturas de controle. No Captulo 4
ser apresentado o conceito de arranjos e, por fim, no Captulo 5, explicaremos como programas
complexos podem ser divididos em programas menores, mais fceis de serem solucionados, atravs
da utilizao das funes.
Recomendamos ao aluno, iniciante na programao de computadores, que no se limite leitura e ao
contedo deste livro. Pesquise na internet outros materiais, leia outros livros e faa todos os exerccios
v

Introduo Programao
propostos. Programao, assim como matemtica, requer muito exerccio, muita prtica. Como
mencionado anteriormente, a programao de computadores uma das subreas mais importantes da
carreira que voc escolheu seguir. Boa parte das disciplinas do seu curso depende do conhecimento
adquirido em Introduo Programao. Portanto, dedique o mximo que puder ao aprendizado de
uma rea que vai permiti-lo transformar sonhos em realidade.

Pblico alvo
O pblico alvo desse livro so os alunos de Licenciatura em Computao, na modalidade a distncia
1 . Ele foi concebido para ser utilizado numa disciplina de Introduo Programao, no primeiro
semestre do curso.

Como voc deve estudar cada captulo


Leia a viso geral do captulo
Estude os contedos das sees
Realize as atividades no final do captulo
Verifique se voc atingiu os objetivos do captulo
NA SALA DE AULA DO CURSO
Tire dvidas e discuta sobre as atividades do livro com outros integrantes do curso
Leia materiais complementares eventualmente disponibilizados
Realize as atividades propostas pelo professor da disciplina

Caixas de dilogo
Nesta seo apresentamos as caixas de dilogo que podero ser utilizadas durante o texto. Confira os
significados delas.

Nota
Esta caixa utilizada para realizar alguma reflexo.

Dica
Esta caixa utilizada quando desejamos remeter a materiais complementares.
1 Embora ele tenha sido feito para atender aos alunos da Universidade Federal da Paraba, o seu uso no se restringe
a esta universidade, podendo ser adotado por outras universidades do sistema UAB.

vi

Introduo Programao

Importante
Esta caixa utilizada para chamar ateno sobre algo importante.

Cuidado
Esta caixa utilizada para alertar sobre algo que exige cautela.

Ateno
Esta caixa utilizada para alertar sobre algo potencialmente perigoso.

Os significados das caixas so apenas uma referncia, podendo ser adaptados conforme as intenes
dos autores.

Vdeos
Os vdeos so apresentados da seguinte forma:

Figura 1: Como baixar os cdigos fontes: http://youtu.be/Od90rVXJV78


Nota
Na verso impressa ir aparecer uma imagem quadriculada.
Isto o qrcode
(http://pt.wikipedia.org/wiki/C%C3%B3digo_QR) contendo o link do vdeo. Caso voc tenha
um celular com acesso a internet poder acionar um programa de leitura de qrcode para
acessar o vdeo.
Na verso digital voc poder assistir o vdeo clicando diretamente sobre o link.

vii

Introduo Programao

Compreendendo as referncias
As referncias so apresentadas conforme o elemento que est sendo referenciado:
Referncias a captulos
Prefcio [v]
Referncias a sees
Como voc deve estudar cada captulo [vi], Caixas de dilogo [vi].
Referncias a imagens
Figura 2 [ix]
Nota
Na verso impressa, o nmero que aparece entre chaves [ ] corresponde ao nmero da
pgina onde est o contedo referenciado. Na verso digital do livro voc poder clicar no
link da referncia.

Feedback
Voc pode contribuir com a atualizao e correo deste livro. Ao final de cada captulo voc ser
convidado a faz-lo, enviando um feedback como a seguir:
Feedback sobre o captulo
Voc pode contribuir para melhoria dos nossos livros. Encontrou algum erro? Gostaria de
submeter uma sugesto ou crtica?
Para compreender melhor como feedbacks funcionam consulte o guia do curso.

Nota
A seo sobre o feedback, no guia do curso, pode ser acessado em: https://github.com/edusantana/guia-geral-ead-computacao-ufpb/blob/master/livro/capitulos/livroscontribuicao.adoc.

viii

Introduo Programao

Figura 2: Exemplo de contribuio

ix

Introduo Programao

Captulo 1
Algoritmos
O BJETIVOS DO CAPTULO
Ao final deste captulo voc dever ser capaz de:
Definir algoritmo
Descrever suas principais caractersticas
Criar algoritmos utilizando diferentes formas de representao
comum pensarmos em uma estratgia para executar uma tarefa do nosso dia a dia, mesmo que ela
seja muito simples. Ao escovar os dentes, por exemplo, ns seguimos diferentes estratgias. Uns
comeam com a escovao dos molares e depois partem para os dentes da frente, outros fazem o
inverso. Enfim, existem vrias formas de escovarmos os dentes, assim como existem vrias maneiras
de realizarmos diversas atividades. Voc sabia que o conjunto de passos para resolver um certo
problema ou realizar determinada tarefa chama-se algoritmo? E que eles so importantssimos para a
programao de computadores?
Neste captulo estudaremos as caractersticas dos algoritmos, suas formas de representao e, sobretudo, a relao entre eles e a programao de computadores.

1.1

Introduo

Fonte inspiradora de livros e filmes, o americano Monty Roberts (Figura 1.1 [2]), conhecido como
o encantador de cavalos, revolucionou a forma de domar cavalos. Ao estudar o comportamento
de cavalos selvagens, percebeu que existe entre eles uma linguagem corporal compartilhada. Entendendo tal linguagem, conseguiu rapidamente ganhar a confiana de cavalos arredios e instru-los a
se comportarem como desejava. Alm de no usar de violncia, essencial no emprego dos mtodos
convencionais, seu mtodo capaz de domar cavalos em poucos dias, ao contrrio da maioria, que
normalmente necessita de vrias semanas.

1 / 92

Introduo Programao

Figura 1.1: Monty Roberts.


Assim como os cavalos, os computadores tambm so instrudos por meio de uma linguagem particular. Para que eles se comportem como desejamos, basta que sejam comandados a partir de uma
linguagem que sejam capazes de entender.
Diferentemente do que ensina o senso o comum, os computadores no possuem inteligncia. Seu
nico trabalho processar dados, conforme uma sequncia de instrues que fazem parte do vocabulrio da linguagem que eles conseguem compreender. A iluso de que eles realizam tarefas de
forma inteligente proporcionada atravs desse conjunto ordenado de instrues, que denominado
de algoritmo. Neste caso, o domador do computador, responsvel por elaborar o algoritmo que vai
orient-lo na execuo de uma determinada tarefa, chamado de programador de computadores.

1.2

O que um algoritmo?

A palavra algoritmo derivada do nome Mohammed ibn Musa Al-Khowarizmique, que foi um
matemtico, astrlogo, astrnomo e autor persa. Ele fez parte de um centro acadmico conhecido
como a Casa da Sabedoria, em Bagd, por volta de 800 d.C. Seus trabalhos introduziram o clculo
hindu aos rabes e, a partir da, ao resto da Europa.
No obstante os algoritmos representam um conceito central na Cincia da Computao, sua atuao
no se limita a essa rea do conhecimento. Rotineiramente, lidamos com algoritmos na realizao
das mais variadas tarefas. Eles podem ser utilizados para lavar um carro, preparar um bolo, tomar
banho, montar um guarda-roupa, etc. Perceba que os algoritmos no devem ser confundidos com as
atividades. Eles se referem aos passos seguidos para que estas sejam realizadas. Como exemplo de
algoritmos, podemos citar as instrues para montagem de equipamentos, para utilizao de cosmticos como shampoos e condicionadores, para sada de emergncia em meios de transporte, receitas
culinrias, manuais de uso, entre outros.
A partir do que foi exposto, podemos definir algoritmo como uma sequncia finita, ordenada e no
ambgua de passos para solucionar determinado problema ou realizar uma tarefa.
Na cincia da computao, esse conceito foi formalizado em 1936, por Alan Turing e Alonzo Church,
da seguinte forma:
D EFINIO DE A LGORTIMO
Um algoritmo um conjunto no ambguo e ordenado de passos executveis que definem
um processo finito.
O exemplo a seguir mostra como pode ser elaborado um algoritmo para realizar uma atividade com a
qual lidamos corriqueiramente:
A LGORITMO PARA FRITAR UM OVO
2 / 92

Introduo Programao
1. Retire o ovo da geladeira.
2. Coloque a frigideira no fogo.
3. Coloque leo na frigideira.
4. Quebre ovo, separando a casca.
5. Ponha a clara e a gema na frigideira.
6. Espere um minuto.
7. Apague o fogo.
8. Retire o ovo da frigideira.
Agora considere o seguinte problema. Suponha que voc dispe de duas vasilhas de nove e quatro
litros respectivamente. Como elas no possuem marcao, no possvel ter medidas intermedirias
sobre o volume ocupado. O problema consiste, ento, em elaborar uma sequncia de passos, por meio
da utilizao das vasilhas de nove e quatro litros, a fim de encher uma terceira vasilha com seis litros
de gua. A figura abaixo ilustra dois possveis passos de um algoritmo para resolver o problema.

(a)

Capacidade: 9 litros
Utilizao: 9 litros

Capacidade: 4 litros Capacidade: 6 litros


Utilizao: 0 litros
Utilizao: 0 litros

(b)

Capacidade: 9 litros
Utilizao: 0 litros

Capacidade: 4 litros Capacidade: 6 litros


Utilizao: 4 litros
Utilizao: 5 litros

Figura 1.2: Ilustra dois passos possveis envolvendo as operaes de encher e esvaziar as vasilhas.
Em (a) apenas a primeira vasilha est cheia. J em (b) os nove litros da primeira vasilha so colocados
nas outras duas.
Uma soluo para o problema pode ser alcanada a partir do seguinte algoritmo:
A LGORITMO PARA ENCHER VASILHAS
1. Encha a vasilha de nove litros.
2. Usando a vasilha de nove litros, encha a de quatro.
3. Coloque a quantidade que sobrou (cinco litros) na terceira vasilha (v3 = 5).
3 / 92

Introduo Programao
4. Esvazie a vasilha de quatro litros.
5. Encha novamente a vasilha de nove litros.
6. Usando a vasilha de nove litros, encha a de quatro.
7. Esvazie a de quatro litros.
8. Usando a sobra da de nove litros (cinco litros), encha novamente a de quatro litros.
9. Coloque a sobra da de nove litros (agora um litro) na terceira vasilha (v3 = 5 + 1 = 6).

1.3

Caractersticas de um algoritmo

Todo algoritmo, seja ele computacional ou no, recebe uma entrada, processa-a e gera uma sada
segundo seu conjunto de passos. No caso do algoritmo para fritar ovo, a entrada corresponde
frigideira, ao ovo e ao leo. O processamento ocorre com a execuo de seus passos, gerando como
sada o ovo frito.
Os algoritmos computacionais, especificamente, possuem as seguintes caractersticas:
Definio
Os passos de um algoritmo devem ser bem definidos, objetivando a clareza e evitando ambiguidades.
Finitude
Um algoritmo deve chegar ao seu fim aps um nmero finito de passos.
Efetividade
Um algoritmo deve ser efetivo, ou seja, suas operaes devem ser bsicas o suficiente para que
possam, em princpio, serem executadas de maneira exata e em um tempo finito.
Entradas
Um algoritmo deve possuir zero ou mais entradas. Estas so insumos ou quantidades que so
processados pelos algoritmos durante a execuo de seus passos.
Sadas
Um algoritmo deve possuir uma ou mais sadas. Elas representam o resultado do trabalhado
realizado pelos algoritmos.

1.4

Formas de representao

As formas mais comumente utilizadas para representar algoritmos so as seguintes:


Descrio narrativa
Fluxograma
Linguagem Algortmica
Todas elas apresentam pontos fortes e fracos, no existindo consenso entre os especialistas sobre a
melhor forma de representao. Apresentaremos as nuances de cada uma nas prximas sees.
4 / 92

Introduo Programao

1.4.1

Descrio Narrativa

Os algoritmos so expressos em linguagem natural (portugus, ingls, francs, espanhol, etc.). Sua
principal desvantagem se encontra no fato da linguagem natural estar bem distante da linguagem
utilizada pelos computadores. Logo, a traduo de uma para a outra se torna uma atividade bastante
dispendiosa. Alm disso, linguagens naturais so mais propensas a ambiguidades. Muitas vezes uma
palavra pode ter vrios significados, dependendo do contexto no qual so utilizadas. Em contrapartida,
bem mais fcil elaborar um algoritmo por meio de uma linguagem com a qual j temos uma certa
familiaridade, do que atravs de linguagens que no so utilizadas com frequncia no dia a dia.
Os exemplos de algoritmos mostrados anteriormente (Algoritmo para fritar um ovo [2] e Algoritmo
para encher vasilhas [3]) refletem esta forma de representao.

1.4.2

Fluxograma

Consiste em usar formas geomtricas padronizadas para descrever os passos a serem executados pelos
algoritmos. As formas apresentadas na Figura 1.3 so as mais comumente utilizadas em fluxogramas.
Processamento.

Incio/Fim.

Sentido do fluxo
de execuo do
algoritmo.

Entrada de dados.

Ponto de deciso.

Sada de dados.

Figura 1.3: Formas geomtricas utilizadas em fluxogramas


A vantagem de se fazer uso dos fluxogramas est na facilidade de compreend-los. Descries de
algoritmos mediante formas grficas so mais facilmente compreendidas do que descries que envolvem apenas textos. Alm do mais, os fluxogramas possuem um padro mundial no que se refere
sua simbologia, tornando sua utilizao independente das peculiaridades das linguagens naturais.
Para exemplificar o uso de fluxogramas, a Figura 1.4 [6] mostra um algoritmo para calcular a mdia
final de um aluno com base em suas notas e classific-lo como aprovado ou reprovado. Analisando-a
com mais cuidado, possvel perceber que os fluxogramas tendem a crescer bastante quando descrevem algoritmos constitudos de muitos passos, o que dificulta tanto sua construo como sua visualizao. Alm dessa desvantagem, por impor regras para sua utilizao de acordo com cada forma
geomtrica, h uma limitao no seu poder de expresso, se comparado com a descrio narrativa.

5 / 92

Introduo Programao

Incio

Obter nota2

Obter nota1

Sim

M=(nota1 + nota2)

M7

Aprovado

No

Reprovado

Fim

Figura 1.4: Fluxograma para calcular a mdia de um aluno e classific-lo

1.4.3

Linguagem Algortmica

A linguagem que o computador capaz de compreender tem grande influncia na elaborao de


algoritmos projetados para ele. Seus passos no podem conter instrues desconhecidas ou fazer
referncia a smbolos ou expresses que os computadores no conseguem decifrar. Tal linguagem,
tantas vezes mencionada neste captulo, se baseia em conceitos e em arquiteturas de hardware que
determinam o funcionamento bsico de um computador. Dentre as existentes, a mais utilizada nos
computadores atuais a arquitetura de von Neumann. Seu autor, John Von Neumann (Figura 1.5 [6]),
props um modelo em que as instrues e os dados ficam juntos na memria.
O processador busca as instrues na memria e as executa uma de cada vez, segundo o seguinte ciclo
de execuo:
1. Busca instruo;
2. Decodifica instruo;
3. Executa instruo;
4. Volta para o passo 1 para buscar a instruo seguinte na memria.

Figura 1.5: John von Neumann


6 / 92

Introduo Programao
Para esclarecer como funciona a execuo de um algoritmo baseado no ciclo de execuo mencionado, considere uma memria com 32 posies para armazenamento, organizada conforme Figura 1.6
[7].
0

x = 2

y = 3

z=x.y

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

Figura 1.6: Representao de uma memria com 32 posies para armazenamento.


Os nmeros do canto superior direito de cada clula indicam os endereos de memria correspondentes a cada posio da memria representada. Nas trs primeiras clulas constam as instrues
que sero executadas e, da oitava dcima, constam valores armazenados nas posies de memria
nomeadas por x, y e z, respectivamente.
Supondo que a execuo do algoritmo em questo inicia-se com a busca da instruo no endereo 0
(zero), o ciclo de execuo continua com a decodificao da instruo x = 2, que, aps sua realizao,
resulta no armazenamento do valor 2 na posio de memria de nmero 8, nomeada de x. O passo
4 ento executado, dando incio busca da prxima instruo. Com isso, a instruo y = 3
encontrada e decodificada, gerando como resultado o armazenamento do valor 3 na posio de nmero
9, nomeada de y. O mesmo ocorre com a instruo z = x.y, que, aps sua decodificao, armazena
o valor 6 (produto de x por y) na posio de endereo 10 e rotulada de z. O algoritmo em descrio
narrativa para a execuo das instrues anteriores encontra-se logo abaixo:
A LGORITMO PARA MULTIPLICAR DOIS NMEROS
1. Escreva 2 na posio de memria nomeada de x.
2. Escreva 3 na posio de memria nomeada de y.
3. Multiplique x e y e o resultado escreva em z.
Modelos como o mencionado anteriormente no apenas definem a forma como os dados so processados pelo computador, mas tambm a linguagem que eles so capazes de compreender. Assim sendo,
a linguagem utilizada pelos computadores est restrita a um conjunto limitado de instrues, cujo
funcionamento depende de sua arquitetura de hardware. As linguagens de programao imperativas
(Pascal, C, Cobol etc), por exemplo, foram criadas em funo da arquitetura de von Neumman.
7 / 92

Introduo Programao
A linguagem algortmica, tambm chamada de pseudocdigo ou pseudo-linguagem, por sua vez,
consiste no emprego de uma linguagem intermediria entre a linguagem natural e uma linguagem de
programao. Esse meio termo resulta em uma linguagem que se aproxima das construes de uma
linguagem de programao, sem exigir, no entanto, rigidez na definio das regras para utilizao de
suas instrues. Geralmente, essa forma de representao de algoritmos uma verso reduzida de
linguagens de alto nvel como C e Pascal. Segue abaixo o algoritmo da Figura 1.4 [6] em pseudocdigo:
1
2
3
4
5
6
7
8
9
10
11

ALGORITMO
DECLARE nota1, nota2, M : NUMRICO
LEIA nota1
LEIA nota2
M (nota1 + nota2) / 2
SE M >= 7.0 ENTO
ESCREVA Aprovado
SENO
ESCREVA Reprovado
FIM-SE
FIM_ALGORITMO.

As palavras em letras maisculas correspondem a palavras reservadas que fazem parte do conjunto
de regras que a linguagem algortmica deve seguir.
Embora sejam mais flexveis do que as linguagens de programao em relao ao seu uso (a instruo
LEIA, por exemplo, muitas vezes substituda por LER, OBTER, etc.), algumas palavras so necessrias, pois facilitam o entendimento e aproximam o pseudocdigo de um programa de computador. As
palavras INCIO e FIM, por exemplo, indicam onde comea e termina o algoritmo. J as instrues
LEIA e ESCREVA referem-se a operaes de entrada e sada de dados (ex.: ler dados do teclado ou
exibir uma frase no monitor), presentes na maioria das linguagens de programao.
Seguindo com a explicao do algoritmo, perceba que a linha com a instruo M (nota1 +
nota2) / 2 contm dois smbolos ainda no apresentados. O smbolo / diz respeito operao
aritmtica da diviso, ao passo que o smbolo expressa uma operao de atribuio, que pode ser
lida da seguinte forma: A posio de memria, representada simbolicamente por M, recebe o valor
da soma de nota1 e nota2, dividido por dois. Para finalizar, a linha 6 apresenta uma estrutura de
controle condicional essencial para as linguagens de programao. Operaes de atribuio, expresses e estruturas de controle fazem parte do ncleo das linguagens de programao imperativas e so,
portanto, fundamentais para o aprendizado da programao. Todos esses assuntos sero abordados de
forma mais aprofundada em captulos posteriores.
A principal vantagem da forma de representao em linguagem algortmica est na facilidade com
a qual um pseudocdigo pode ser transcrito para uma linguagem de programao. Assim como os
fluxogramas, a desvantagem fica por conta da limitao do seu poder de expresso, devido s regras
impostas para a elaborao das instrues.

1.5

Recapitulando

Neste captulo voc estudou algoritmos, suas principais caractersticas e suas formas de representao.
Apesar de ser um tema mais abordado na cincia da computao, algoritmos esto presentes nas mais
diversas reas e em vrias atividades do cotidiano. Lidamos com eles, por exemplo, quando tomamos

8 / 92

Introduo Programao
banho, cozinhamos, planejamos uma rota para fugirmos do trnsito, consultamos um manual de montagem, enfim, sempre que nos deparamos com um conjunto lgico de passos para realizarmos uma
tarefa ou solucionarmos um problema, estamos em contato com algoritmos. por meio deles que
os computadores passam a iluso de que so inteligentes, realizando tarefas capazes de impressionar
qualquer ser humano. No entanto, sabemos que eles apenas processam dados, segundo um conjunto
de instrues que lhe so passadas os algoritmos.
Voc viu que os algoritmos computacionais, aqueles elaborados para serem executados em computadores, devem ser claros, ter um nmero finito de passos, e que estes devem ser simples o suficiente
para serem executados de maneira exata e em um tempo finito. Alm disso, os algoritmos computacionais devem possuir zero ou mais entradas e uma ou mais sadas.
As formas de representao de algoritmos mais comuns so a linguagem algortmica, o fluxograma e
o pseudocdigo. Da primeira ltima h uma aproximao em relao s linguagens de programao,
ou seja, o pseudocdigo a forma de representao que mais se assemelha s linguagens utilizadas
na programao de computadores. Na direo inversa, h uma maior liberdade na elaborao de
algoritmos, aumentando, assim, a capacidade de express-los.
No prximo captulo abordaremos o processo de traduo de um programa escrito em uma linguagem de alto nvel, os paradigmas de programao existentes, e introduziremos os conceitos bsicos
da programao de computadores. Alm disso, voc ter o primeiro contato com a linguagem de
programao a ser estudada neste livro: a linguagem C.

1.6

Exerccios Propostos

1. Explique, com suas prprias palavras, o que algoritmo.


2. Rotineiramente, usamos algoritmos para as mais diversas tarefas. Cite trs algoritmos que
podemos encontrar no dia a dia.
3. Em que consiste a caracterstica de efetividade de um algoritmo?
4. Suponha que o quarto passo de um determinado algoritmo ordene que a execuo retorne ao
primeiro. Qual caracterstica no est sendo satisfeita por esse algoritmo?
5. Discorra sobre as formas de representao de algoritmos mais comuns, destacando suas vantagens e desvantagens.
6. Suponha que voc foi premiado com um rob capaz de auxili-lo nas tarefas domsticas. Antes
que execute determinada atividade, voc precisa instru-lo corretamente atravs de um algoritmo especfico. Sabendo disso, escreva algoritmos, em linguagem natural, para ensin-lo a
realizar cada uma das tarefas abaixo:
a. Trocar a lmpada do seu quarto.
b. Trocar o pneu do seu carro.
c. Fazer uma vitamina de banana com aa.
d. Lavar e secar os pratos.
e. Calcular quanto voc precisar tirar na terceira nota para passar por mdia em Introduo
Programao.

9 / 92

Introduo Programao
7. Escreva um algoritmo, utilizando fluxograma, que receba como entrada o peso e altura de uma
pessoa, calcule seu IMC (ndice de Massa Corprea) e exiba sua situao, segundo os seguinte
critrio:
Se o IMC > 25, a pessoa est acima de seu peso, caso contrrio, est abaixo. Onde o IMC =
(Peso)/(Altura2 )
8. Usando fluxograma, faa um algoritmo que receba como entrada a idade de uma pessoa expressa em anos, meses e dias (Ateno: so 3 entradas) e mostre-a expressa apenas em dias.
Considere anos de 365 dias e meses de 30 dias.
9. Considere as instrues armazenadas na memria a seguir:
0

y=5

x=10

z=x/y+z

10

11

14

15

10

5
12

3
13

Considerando que a instruo inicial se encontra no endereo 0 (zero) e as posies 8, 9 e 10


correspondem a x, y e z, respectivamente, explique como funciona a execuo das instrues
acima, segundo a arquitetura de von Neumann. Antes da execuo da instruo de endereo 2
(z=x/y + z), a posio de memria referente a z possua o valor 1 (um).
10. Escreva um algoritmo, em pseudocdigo, que receba como entrada a base e a altura de um
tringulo, calcule e exiba sua rea.
Feedback sobre o captulo
Voc pode contribuir para melhoria dos nossos livros. Encontrou algum erro? Gostaria de
submeter uma sugesto ou crtica?
Para compreender melhor como feedbacks funcionam consulte o guia do curso.

10 / 92

Introduo Programao

Captulo 2
Introduo Programao
O BJETIVOS DO CAPTULO
Ao final deste captulo voc dever ser capaz de:
Entender o processo de traduo de programas escritos em linguagem de alto nvel para
cdigo de mquina
Compreender o conceito de varivel e sua relao com a memria do computador
Criar instrues que envolvam operaes aritmticas
Utilizar instrues de entrada e sada da linguagem C
Escrever um programa simples em C
Agora que voc j conhece as caractersticas de um algoritmo computacional e capaz de criar algoritmos utilizando suas diferentes formas de representao, est na hora de voc escrever seu primeiro
programa. Porm, antes que isso ocorra, voc deve aprender alguns conceitos bsicos, como o de
varivel, e conhecer o processo de traduo de um programa escrito em linguagem de alto nvel (a
linguagem C, por exemplo) para cdigo de mquina, ou seja, para a linguagem que o computador trabalha. Alm desses conceitos, este captulo tambm aborda a elaboraes de expresses aritmticas
em C, bem como alguns de seus comandos bsicos.

2.1

Introduo

Voc viu no captulo anterior que existe uma linguagem que os computadores so capazes de compreender e que utilizada na elaborao de algoritmos para instru-los a executarem as mais diversas
tarefas. Essa linguagem chamada de linguagem de programao e consiste no principal assunto
deste captulo.
Assim como as linguagens naturais (portugus, ingls, espanhol, etc.), as linguagens de programao
tm o objetivo de prover um meio eficaz de comunicao. Elas so constitudas de um conjunto de
palavras especiais (vocabulrio), que associadas a um conjunto de regras de utilizao, determinam
como os algoritmos devem ser especificados para que possam ser corretamente decodificados pelo
computador.
As linguagens de programao diferem das naturais de vrias formas. Primeiramente, apesar de ser
possvel de serem utilizadas como meio de comunicao entre pessoas, seu principal propsito
11 / 92

Introduo Programao
possibilitar a comunicao entre uma pessoa e um computador. Alm disso, as linguagens naturais
so mais tolerantes a erros. Um erro gramatical, por exemplo, no impossibilita uma conversa entre
duas pessoas. J no caso das linguagens de programao, a simples omisso de um ponto e vrgula
capaz at de impedir que a comunicao seja iniciada.
O contedo da comunicao por meio de uma linguagem de programao tem um significado especial
para a cincia da computao. Enquanto que nos expressamos nas linguagens naturais atravs de textos e da emisso de sons, nas linguagens de programao nos expressamos atravs de programas, que
nada mais so do que algoritmos escritos em uma linguagem de programao. O estudo das tcnicas
para elaborao de programas consiste em um dos pilares da cincia da computao, conferindo uma
importncia particular disciplina de Introduo Programao.
Antes que voc conhea as peculiaridades de uma linguagem de programao estruturada, como suas
principais instrues e regras para a construo de um programa, estudaremos os paradigmas de
programao existentes e o processo de traduo de um programa escrito em linguagem de alto nvel
para um programa em cdigo de mquina.

2.2

Nveis das Linguagens de Programao

Os computadores representam as informaes atravs da manipulao de dois estados. Esse sistema


de representao, denominado de sistema binrio, decorre do fato da grande maioria dos componentes
eletrnicos poder assumir apenas dois valores. Por exemplo, uma lmpada pode estar no estado
"ligado"ou "desligado", um capacitor pode estar "carregado"ou "descarregado"e um circuito eltrico
pode estar energizado ou no.
A representao binria utiliza os algarismos "0"e "1", chamados de dgitos binrios. Eles so os valores que um bit (menor unidade de informao em um computador) pode assumir e esto associados
aos valores de tenso presentes nos circuitos eltricos do computador. Para representar o bit zero, por
exemplo, normalmente utiliza-se um valor prximo a zero volts. Para o bit um, utiliza-se um valor
um pouco maior, da ordem de poucos volts.
Repare que trabalhar com uma combinao de zeros e uns no uma tarefa fcil para um ser humano.
Para que voc perceba a dificuldade, imagine como seria escrever um pseudocdigo substituindo
comandos como "LEIA", "ESCREVA"e expresses aritmticas por uma combinao de zeros e uns.
O quadro de cdigo binrio hipottico abaixo ilustra tal situao, apresentando um algoritmo em
pseudocdigo que calcula a mdia de duas notas lidas da entrada padro e sua verso hipottica em
cdigo binrio.
Algoritmo em pseudocdigo
ALGORITMO
DECLARE nota1,
nota2,
M : NUMRICO
LEIA nota1
LEIA nota2
M <= (nota1 + nota2) / 2
FIM_ALGORITMO.

Ilustrao de um cdigo binrio hipottico referente a um algoritmo escrito em pseudocdigo.


10100001
10100011 10010001
12 / 92

Introduo Programao
10010010
10010011 11000001
10100100 10010001
10100100 10010010
10010011 11110011 10010001 11110001 10010010 11110010 00000010
10100010

Importante
O cdigo binrio acima apresentado tem fins meramente didticos, no sendo elaborado
com base em nenhuma mquina real.

Com o intuito de tornar menos complicada, mais eficiente e menos sujeita a erros a tarefa de programar computadores, foram criadas linguagens de programao mais prximas s linguagens naturais.
Elas so compostas de um conjunto de palavras-chave, normalmente em ingls, e smbolos que estabelecem os comandos e instrues que podem ser utilizados pelo programador na construo de seus
programas.
As linguagens com essa caracterstica so chamadas de linguagens de alto nvel, ao passo que as mais
prximas da linguagem de mquina (representao binria), so denominadas de linguagens de baixo
nvel. So exemplos de linguagens de alto nvel: Pascal, C (linguagem abordada neste livro), Java,
C++ e Python. Como exemplo de linguagem de baixo nvel, temos a linguagem Assembly.

2.3

Tradutores e Interpretadores

Se por um lado as linguagens de programao facilitam o trabalho dos programadores, por outro
impossibilitam que os programas desenvolvidos nessas linguagens sejam compreendidos pelos computadores, visto que eles so capazes de manipular apenas cdigos binrios. Dessa forma, os cientistas
do passado se depararam com o seguinte desafio: como executar um programa em linguagem de programao, seja ela de baixo ou alto nvel, em um computador que trabalha apenas como nmeros
binrios?
primeira vista, o desafio em questo parece ser complexo demais para ser solucionado por um
iniciante na cincia da computao. Todavia, voc vai perceber que a soluo para o problema est
mais prxima da sua realidade do que imagina. Suponha que voc recebeu uma proposta milionria
para trabalhar em uma empresa de desenvolvimento de software da China. Seus patres pagaro
suas passagens, hospedagem, transporte e todo o aparato necessrio para que voc possa ter uma
vida tranquila no pas asitico. Apesar de a proposta ser atraente, existe um problema: todos os
funcionrios da empresa falam somente o chins, inclusive seus patres. Alm disso, o contrato a ser
assinado tambm est escrito em chins. O que voc faria em tal situao?
Recusaria a proposta? isso mesmo que voc est pensando, um tradutor seria a soluo para seus
problemas.
Do mesmo modo que voc precisaria de um tradutor para poder lidar com uma linguagem que no
consegue entender, os computadores tambm necessitam de um tradutor para traduzir um programa
escrito em linguagem de programao para um programa correspondente em linguagem de mquina.
Dois softwares bsicos so responsveis por realizar a traduo em questo: os tradutores e os interpretadores.
13 / 92

Introduo Programao
Os tradutores podem ser classificados como montadores e compiladores. Quando o processo de traduo converte um programa que se encontra no nvel de linguagem de montagem (representao
simblica da linguagem de mquina, ex.: linguagem Assembly) para a linguagem de mquina, o
tradutor utilizado o montador. J na traduo de programas em linguagem de alto nvel para a linguagem de montagem, o software responsvel o compilador. Perceba que no h traduo direta da
linguagem de alto nvel para a linguagem de mquina. Para que esta seja alcanada, so necessrios
vrios passos intermedirios, sendo um deles a traduo para a linguagem de montagem.

Figura 2.1: Passos no processo de compilao


No processo de compilao, cada parte de um programa (mdulo) escrito em linguagem de alto nvel
traduzido para um mdulo objeto diferente, que consiste em sua representao em linguagem de
montagem. Esse passo no processo de compilao corresponde ao passo 1 da Figura 2.1 [14]. Antes
de serem traduzidos para linguagem de mquina pelo montador, necessrio que os vrios mdulos
objetos sejam integrados de modo a formarem um nico cdigo. Essa tarefa realizada no passo 2. O
passo 3 o responsvel por carregar o programa na memria, a fim de tornar suas instrues prontas
para serem executadas pelo processador.
Os interpretadores, alm de realizar a traduo de um programa para a linguagem de mquina, ainda
executam suas instrues. Assim que traduz uma instruo, ela imediatamente executada, gerando
assim um ciclo de traduo e execuo que prossegue de instruo a instruo at o fim do programa
(Figura 2.2 [14]).

Figura 2.2: Processo de Interpretao


Por no traduzir um programa escrito em linguagem de alto nvel diretamente para linguagem de mquina, o processo de compilao tende a ser mais rpido que o processo de interpretao. Alm disso,
uma vez compilado, um programa pode ser executado vrias vezes sem a necessidade de haver uma
recompilao. J na interpretao, cada vez que um programa tiver que ser reexecutado, todo o processo de interpretao dever ser refeito, independente de ter ocorrido modificaes no cdigo fonte
14 / 92

Introduo Programao
do programa desde sua ltima execuo. A vantagem da interpretao fica por conta da possibilidade
de testar os programas ao mesmo tempo em que so desenvolvidos.
Importante
A linguagem utilizada neste livro (linguagem C) como ferramenta para inici-lo na programao de computadores uma linguagem compilada, portanto, os programas que voc ir
desenvolver passaro pelos passos explanados anteriormente.

Nota
Para saber mais sobre o processo de montagem e compilao, leia a Seo 3 do Captulo 5
do Livro de Introduo ao Computador.

2.4

Paradigmas de Programao

Um paradigma de programao est relacionado com a forma de pensar do programador na construo de solues para os problemas com os quais se depara. Programar seguindo um determinado
paradigma de programao significa representar solues a partir de uma forma particular de raciocinar na elaborao dos algoritmos. Como os paradigmas mencionados sustentam a atividade de
programas, eles influenciam todo o processo de desenvolvimento de software. Alguns dos paradigmas de programao mais utilizados esto relacionados abaixo:
Paradigma imperativo
Representa a computao como aes, enunciados ou comandos que alteram o estado (variveis) de um programa. Consiste na elaborao de programa a partir de comandos que dizem o
que o computador deve fazer a cada momento.
Paradigma estruturado
Soluciona problemas a partir de sua quebra em problemas menores, de mais fcil soluo, denominados de sub-rotinas ou subprogramas. Normalmente, o trabalho de cada sub-rotina consiste
em receber dados como entrada, processar esses dados e retornar o resultado do processamento
para o mdulo de software que o executou. Este paradigma ainda defende que todo processamento pode ser realizado pelo uso de trs tipos de estruturas: sequencial, condicional e de
repetio. o paradigma adotado neste livro.
Paradigma declarativo
Descreve as caractersticas da soluo desejada sem especificar como o algoritmo em si deve
agir. Em contraste com o paradigma imperativo, que informa ao computador como as instrues
devem ser executadas, o paradigma declarativo preocupa-se apenas em definir o que deve ser
feito, deixando a cargo de outros softwares decidirem como alcanar a soluo descrita.
bastante utilizado no desenvolvimento das pginas web (linguagem html) e na descrio de
documentos multimdia atravs da linguagem Nested Context Language NCL, adotada pelo
padro brasileiro de TV Digital.
Paradigma orientado a objetos
Enxerga o problema como uma coleo de objetos que se comunicam por meio da troca de mensagens. Os objetos so estruturas de dados que possuem estado (variveis) e comportamento
(lgica).
15 / 92

Introduo Programao

2.5

Linguagem C

A linguagem C foi desenvolvida por Dennis Ritchie, entre os anos 1971 e 1973, nos laboratrios da
AT&T. O objetivo de Ritchie era criar uma linguagem para a implementao de sistemas operacionais
e softwares bsicos que combinasse a eficincia das linguagens de baixo nvel com caractersticas das
linguagens de alto nvel, como legibilidade, portabilidade e manutenibilidade.
A criao da linguagem C resultado de um processo evolutivo de linguagens, iniciado com uma linguagem chamada BCPL, desenvolvida por Martin Richards. Essa linguagem influenciou a linguagem
B, inventada por Ken Thompson, que por sua vez levou ao desenvolvimento de C.
Em 1973, Dennis Ritch no deixou dvidas que seu objetivo foi alcanado, desenvolvendo eficientemente parte do sistema Unix na linguagem C. A partir de meados dos anos 80, C comeou a ganhar
popularidade e, devido sua flexibilidade em atuar com caractersticas de linguagens de alto e baixo
nvel, foi reconhecida como uma linguagem de propsito geral, sendo utilizada na implementao de
uma grande variedade de sistemas.
Devido importncia auferida na rea da programao de computadores, C hoje uma das linguagens mais utilizadas em cursos de programao do mundo inteiro. Sendo assim, ela a linguagem
que guiar voc na compreenso das nuances da arte de programar e servir como ferramenta para
elaborao dos seus primeiros programas. A linguagem C ser apresentada, de forma conveniente, a
partir da prxima seo.

2.6

Ncleo de um programa

A organizao da sequncia de instrues em um programa obedece a um conjunto de regras estabelecidas pela linguagem de programao. Um programa em C estruturado em funes, que so,
basicamente, trechos de cdigo que podem ser chamados vrias vezes para realizar uma certa tarefa.
Assim, todas as instrues pertencentes a um programa em C devem estar contidas em uma funo.
Alm de ser um meio de agrupar trechos de um cdigo, uma funo em programao tem caractersticas semelhantes a uma funo matemtica, no sentido de que recebe parmetros como entrada (seria
o domnio da funo) e retorna um valor como sada (imagem).
Em C existe uma funo especial, denominada de main (principal), que determina o incio e o fim da
execuo de um programa. De forma mais especfica, a execuo de um programa tem seu incio com
a execuo da primeira instruo da funo main e termina com a execuo da sua ltima instruo.
Dessa maneira, todo programa em C deve possuir tal funo.
Importante
Voc conhecer mais sobre as funes no Captulo 6 deste livro. Por enquanto necessrio apenas que voc saiba que todo programa em C deve ter uma funo main e que a
execuo de um programa inicia e termina com a execuo de seus comandos.

Iniciaremos nosso estudo com um programa extremamente simples, que apenas imprime uma mensagem na tela:
#include <stdio.h>
int main() {
16 / 92

Introduo Programao
printf("Meu primeiro programa!");
return 0;
}

Analisemos o que ocorre em cada linha de cdigo:


#include <stdio.h>
Esta linha de cdigo solicita ao compilador que inclua no programa a biblioteca padro para comandos de entrada e sada da linguagem C. Uma biblioteca consiste em um conjunto de arquivos que
contm funes que podem ser incorporadas a outros programas. Neste caso, a incluso da biblioteca
stdio.h permite que o programa utilize suas funes para ler dados da entrada padro (teclado) e
para escrever dados na sada padro (tela).
int main(){
Com esta linha de cdigo definimos a funo main e demarcamos o seu incio com o caractere {
(abre-chaves). Todo contedo de uma funo em C fica delimitado por chaves ( {} ).
printf("Meu primeiro programa!");
O programa tem seu incio com a execuo desta instruo, uma vez que ela a primeira instruo da
funo main.
A funo printf tem a finalidade de escrever na tela os dados recebidos por parmetro. Como
resultado de sua execuo, neste caso, ser exibida a frase "Meu primeiro programa!"no canto superior
esquerdo do monitor do computador.
O ponto-e-vrgula no fim da instruo serve para separar esta instruo da prxima, dessa maneira,
cada instruo deve terminar com sua utilizao.
return 0;
Essa instruo encerra a execuo do programa, de modo que deve ser sempre a ltima da funo
main (antes do fecha-chaves, claro). O nmero 0 (zero) serve para indicar ao sistema operacional que o programa terminou com sucesso (nmeros diferentes de zero indicariam um erro). Voc
entender melhor como isso funciona quando abordarmos detalhadamente as funes, no captulo 6.

2.7

Memria e Variveis

A memria principal do computador ou memria RAM (Figura 2.3 [18]) constituda por componentes eletrnicos capazes de armazenar dados. Cada dgito binrio (0 ou 1) ocupa uma poro de
memria chamada de bit, e um conjunto de 8 bits denominado de byte. A memria dividida em
clulas de memria de um byte de tamanho, que podem ser acessadas a partir de um nmero nico
que as identifica de forma particular. Esse nmero chamado de endereo e tem a mesma funo que
os endereos de nossas casas, que identificar de forma nica nossas residncias, a fim de possibilitar
o envio e o recebimento de correspondncias. No caso do computador, as correspondncias so os
dados que sero armazenados nas clulas de memria.

17 / 92

Introduo Programao

Figura 2.3: Figure 2.3: Memria RAM.


Uma varivel em programao representa, atravs de smbolos, o contedo de uma clula ou posio
de memria. Por exemplo, se uma varivel de nome x possui o valor 10, significa dizer que a posio
de memria, representada pelo smbolo x, armazena o valor 10. Em programao, podemos enxergar
a memria como um conjunto de posies que possuem um endereo e uma representao simblica
(varivel), como ilustrado na Figura 2.4 [18].

Endereo

Varivel

Valor

100

20,5

aula

...

...

...

var

-1700,23

Figura 2.4: Representao da memria em funo dos endereos, das posies de memria e das
variveis.
Nota
As variveis podem ter nomes diversos, desde smbolos comuns na matemtica, como o
caso das variveis x, y e z, at nomes como var, endereco, cpf, etc. As regras para dar
nome s variveis sero apresentadas na prxima seo. Perceba tambm que os valores
que as variveis podem armazenar no se limitam apenas a valores numricos inteiros. Elas
podem armazenar, por exemplo, um conjunto de caracteres, como o caso da varivel z, e
valores fracionrios, como o caso das variveis y e var.

2.7.1

Identificadores

Os nomes que damos s variveis, rotinas, constantes e demais componentes num programa escrito
numa dada linguagem de programao so chamados de identificadores. Na seo anterior, por exemplo, utilizamos os identificadores x, y, z e var para dar nome s variveis da Figura 2.4 [18]. As
18 / 92

Introduo Programao
palavras que possuem significado especial nas linguagens de programao, como o caso dos nomes dados s estruturas de controle (for, while, if, etc.), tipos de variveis, dentre outros, so
chamadas de palavras-chave.
As regras bsicas para formao de identificadores so:
Os caracteres utilizados so os nmeros, letras maisculas, minsculas e o caractere especial sublinha (_);
O primeiro caractere deve ser uma letra ou o sublinha;
No so permitidos espaos em branco;
Palavras reservadas no podem ser utilizadas como identificadores.
Abaixo, alguns exemplos de identificadores vlidos:
B
b
X2
computacao
COMPUTACAO
nota1
nota_2
cpf
RG

Identificadores invlidos:
3B -> No pode comear com nmero.
X 2 -> No pode conter espao em branco.
Computaao -> No permitido utilizar o caractere cedilha.
COMPUTACO -> Caracteres especiais como o til (~) no so permitidos.
while -> while uma palavra reservada.
function -> function tambm uma palavra reservada.

Uma boa prtica de programao escolher nomes que indiquem a funo de uma varivel, como
por exemplo: soma, ano, idade, media, dataNascimento, numero_filhos,
nota1, nota2, notaFinal, salario, etc. Tambm uma prtica bastante difundida
iniciar os identificadores com letras minsculas e usar letras maisculas ou sublinha para separar
palavras. Por exemplo, para escolher um identificador para uma varivel que deve armazenar a
data de nascimento de uma pessoa, as duas opes citadas correspondem dataNascimento e
data_nascimento, respectivamente.
Importante
A linguagem C faz distino entre letras maisculas e minsculas, sendo assim, variveis de
nomes var e Var so consideradas como duas variveis diferentes.

2.7.2

Tipos de dados primitivos

Vimos anteriormente que as variveis podem armazenar valores de diversos tipos, tais como nmeros
inteiros, fracionrios e um conjunto de caracteres. Os tipos de dados ou tipo de variveis so representados de forma diferente em cada linguagem de programao, algumas dando suporte a mais tipos
19 / 92

Introduo Programao
que outras. Embora haja certa variao de uma linguagem para outra, a maioria delas d suporte a
um grupo de tipos bsicos, incorporados na prpria linguagem, chamados de tipos primitivos. Em C
h a possibilidade da criao, por parte do programador, de tipos particulares, denominados de tipos
derivados. Estudaremos as formas de definirmos tipos derivados no Captulo 5.
Existem trs tipos primitivos na linguagem C: nmeros inteiros, nmeros de ponto flutuante (nmeros
fracionrios) e caracteres. Os nmeros fracionrios so chamados de nmeros de ponto flutuante
devido forma como eles so armazenados no computador. Portanto, sempre que voc ouvir o termo
ponto flutuante, tenha em mente que o tipo de dados em questo diz respeito aos nmeros fracionrios.
Os tipos de dados primitivos em C esto descritos na tabela abaixo:
Tabela 2.1: Tipos primitivos da linguagem C
Tipo
int
float
double

Tamanho (em bytes)


4
4
8

char

Funo
Armazenar um nmero inteiro.
Armazenar nmeros de ponto flutuante.
Armazenar nmeros de ponto flutuante com
maior preciso.
Armazenar um caractere.

Como as variveis de tipos primitivos distintos so representadas na memria de formas diferentes,


elas exigem uma quantidade de bytes distinta para seu armazenamento. Uma varivel do tipo int,
por exemplo, ocupa normalmente quatro bytes na memria, ao passo que uma varivel do tipo char
ocupa apenas 1 (um) byte.
importante salientar que o tipo char na linguagem C, diferentemente de outras linguagens, pode
tambm armazenar nmeros inteiros que requerem apenas um byte de memria. O que ocorre
que h uma correspondncia entre um caractere e um nmero inteiro, conforme uma tabela padro.
Por exemplo, quando atribumos a variveis do tipo char valores como a, b e c, na verdade estamos
atribuindo os valores inteiros 97, 98 e 99. Os nmeros inteiros que correspondem aos caracteres esto
todos listados em uma tabela padro, conhecida como tabela ASCII.
O tipo int pode ainda ser qualificado de acordo com as seguintes palavras-chave:
short ou long
se referem ao tamanho das variveis;
signed ou unsigned
indicam, respectivamente, se as variveis do tipo int podero ser positivas e negativas (com
sinal) ou apenas positivas (sem sinal) .
A qualificao de tipo realizada quando os qualificadores so antepostos aos tipos. Por exemplo,
uma varivel do tipo unsigned long int armazena inteiros positivos de tamanhos grandes, enquanto
que uma varivel do tipo signed short int armazena inteiros positivos e negativos de tamanhos menores.
A tabela a seguir ilustra os valores que normalmente podem ser armazenados nas variveis do tipo int
e diversas de suas variaes.

20 / 92

Introduo Programao
Tabela 2.2: Intervalos de valores de tipos inteiros utilizados
por grande parte dos compiladores de C.
Tipo
int
short int
long int
unsigned int
unsigned short int
unsigned long int
signed char
unsigned char
long long int
unsigned long long int

Tamanho (em bytes)


4
2
4
4
2
4
1
1
8
8

Valores que podem ser armazenados


-231 a 231 - 1
-215 a 215 - 1
-231 a 231 - 1
0 a 232 - 1
0 a 216 - 1
0 a 232 - 1
-27 a 27 - 1
0 a 28 - 1
-263 a 263 - 1
0 a 264 - 1

Nota
Os tamanhos e valores presentes nas tabelas anteriores podem variar de compilador para
compilador. Desse modo, eles servem apenas como um guia de referncia para de norte-lo
na escolha dos tipos adequados aos programas que voc desenvolver.

2.7.3

Declarao de variveis

Cada varivel utilizada na elaborao de um programa precisa ser definida com antecedncia. Para
isso, o programador precisa definir o identificador da varivel e o seu tipo por meio do que chamamos
de declarao de variveis. Sua forma geral a seguinte:
tipo_da_varivel identificador;
O exemplo a seguir declara, na linguagem C, as variveis x e y como sendo do tipo int.
int x, y;
A declarao de variveis, alm de estabelecer uma interpretao sobre os bits armazenados na memria, tambm responsvel por alocar espao para armazenamento desses bits. No exemplo anterior,
a declarao das variveis x e y resulta na alocao de 4 bytes (provavelmente) para cada uma delas,
bem como determina que os bits a serem armazenados no espaos alocados devero ser interpretados
como nmeros inteiros. Seguem abaixo alguns exemplos de declaraes de variveis:
int idade;
int numeroFilhos;
int dia, mes, ano;
float altura;
float nota, media;
Os tipos das variveis tem uma relao muito prxima com a funo que elas exercem em um programa. Caso precisemos armazenar e realizar clculos sobre a idade de algum, deveremos declarar
a varivel idade como int, visto que a idade corresponde a um nmero inteiro positivo. Do mesmo
21 / 92

Introduo Programao
modo, como sabemos que a altura de uma pessoa um nmero fracionrio (ex.: 1,80 m), devemos
declarar a varivel altura como sendo do tipo float. Variveis do mesmo tipo podem ser declaradas
em uma mesma linha, sendo separadas por vrgulas, como na declarao das variveis dia, mes e
ano do exemplo anterior. J variveis de tipos diferentes devem ser declaradas obrigatoriamente de
forma separada.
Um programa elaborado com base no paradigma estruturado pode ser visto como uma sequncia de
transies de estado do incio at o fim de sua execuo. Se pudssemos tirar uma "foto"da execuo
de um programa em determinado momento, o que observaramos seria o conjunto de suas variveis
e os valores nelas armazenados no momento, isto , o estado do programa. Se os programas podem
mudar de estado, ento deve existir um comando nas linguagens de programao que permitam alterar
o contedo de uma varivel. Tal comando denominado de atribuio, e o exemplo a seguir mostra
como ele utilizado em pseudocdigo.
idade 18
Essa instruo deve ser lida como "a varivel idade recebe o valor 18 (dezoito)". Em C, o comando
correspondente :
idade = 18;

Nota
Podemos utilizar o comando de atribuio no momento da declarao de uma varivel. Esse
procedimento chamado de inicializao de variveis.

Embora C e outras linguagens de programao utilizem o operador aritmtico da igualdade para representar a atribuio, as semnticas de ambos no podem ser confundidas. Por exemplo, em matemtica
a equao x=x+1, onde x pertece aos Reais, nunca pode ser satisfeita, visto que um nmero
real no poder ser igual a ele prprio mais um. J em programao, o comando x = x + 1 quer
dizer que a varivel x ir receber o contedo armazenado nela prpria mais um. Supondo que x possua contedo igual a 10 antes da execuo da atribuio em questo, aps sua execuo x seria igual
a 11 (x = 10 + 1 = 11). A tabela abaixo ilustra o cenrio apresentado.
Comando
int x;
x = 10;
x = x + 1;

Valor atual de x
Indefinido
10
11

Essa forma de atribuio um artifcio bastante empregado na programao, sendo denominado de


incremento.

2.7.4

Constantes simblicas

Muitas vezes declaramos algumas variveis que no devem ser modificadas durante a execuo de
um programa. o caso das variveis abaixo:
PI = 3.14159;
ACELERACAO_GRAVIDADE = 9.8;
22 / 92

Introduo Programao
VELOCIDADE_LUZ = 300000;
No faz sentido alterar o valor de uma varivel que representa a acelerao da gravidade, por exemplo,
pois o valor da constante gravitacional, como seu prprio nome j diz, permanece sempre o mesmo.
Para casos como esse prefervel que usemos constantes simblicas no lugar de variveis. A linguagem C permite que um identificador seja associado a uma constante atravs da diretiva #define,
cuja sintaxe descrita abaixo:
#define nome_constante valor_constante;
Dessa forma, a definio da constante PI mencionada acima poderia ser realizada atravs da linha de
cdigo:
#define PI = 3.14159;
Quando o programa que contm essa instruo compilado, o compilador substitui todas as ocorrncias de PI pelo seu valor associado.
Outra utilidade proveniente da definio de constantes diz respeito facilidade de modificao de
um programa. Imagine que voc desenvolveu um programa para o registro contbil de uma locadora
de veculos e que em vrios trechos de cdigo voc usou o valor da diria de locao para realizar
diversos clculos. Suponha agora que o dono da locadora aumentou o valor da diria de locao e
que voc foi chamado para modificar o programa a fim de adequ-lo ao novo valor. Dessa forma,
voc ter que alterar cada ocorrncia contendo o valor antigo e o seu trabalho ser proporcional ao
nmero de ocorrncias desse valor. Utilizando constantes simblicas, voc precisaria apenas alterar a
definio da constante, conforme sugere o quadro abaixo:
#define VALOR_LOCACAO 80.0
#define VALOR_LOCACAO 100.0
Apesar das regras para definio dos nomes das constantes simblicas serem as mesmas daquelas
utilizadas para identificadores, uma boa prtica de programao defini-las com letras maisculas,
separando as palavras que as compem, se houverem, pelo caractere sublinha (_).

2.8

Comentrios e indentao

medida que um programa cresce, ele vai ficando cada vez mais difcil de ser lido e consequentemente de ser entendido. comum um programador ter grandes dificuldades para compreender seus
prprios programas aps passar alguns dias sem trabalhar em suas linhas de cdigo. Por isso, algumas medidas devem ser tomadas no sentido de preparar um cdigo-fonte legvel. Existem vrias
formas de aprimorar a legibilidade de um programa, contudo nos restringiremos aos comentrios e
indentao.
Explicar o cdigo-fonte em linguagem natural uma estratgia bvia para facilitar sua compreenso.
Esse o papel dos comentrios em uma linguagem de programao. Em C, qualquer sequncia de
caracteres localizada entre os delimitadores /* e */ um comentrio. Por exemplo:
z = x + y; /* z o resultado da soma entre x e y. */
A explicao da linha de cdigo acima, embora desnecessria devido simplicidade da instruo,
um comentrio na linguagem C. Outras linguagens podem usar delimitadores distintos para expressar
23 / 92

Introduo Programao
os comentrios. A linguagem C ainda possui o delimitador //, muitas vezes chamado de delimitador
de comentrio de linha. Os caracteres colocados sua frente e na mesma linha em que ele se encontra
so considerados comentrios e ignorados pelo compilador. Exemplo de sua utilizao:
int idade; // Varivel inteira para representar
// a idade de uma pessoa.
Perceba que para comentar mais de uma linha com o delimitador //, precisamos utiliz-lo em cada
linha que se deseja comentar. Dessa maneira, quando se deseja comentar mais de uma linha mais
adequado o uso dos delimitadores /* e */.
Outra forma de tornar um programa mais legvel organizar as instrues de modo a refletir a hierarquia entre elas. Por exemplo:
#include <stdio.h>
/* Cdigo no-indentado */
int main() {
int x, y, z;
x = 10;
y = 2;
z = x / y;
if (x > 5) {
printf("x maior que cinco.");
}
return 0;
}

Repare que a declarao de variveis, os comandos de atribuio e os comandos if (apresentado no


Captulo 3) e return esto todos dentro da funo main. Dizemos ento que eles so hierarquicamente subordinados funo referida. Da mesma forma, o comando printf est subordinado ao
comando if. Uma maneira de destacar a hierarquizao das instrues alinhar os comandos com
o mesmo nvel de hierarquia (inserindo espaos nas instrues de nvel inferior), o que chamamos de
indentao. Para que voc visualize o resultado do processo de indentao, considere o cdigo do
exemplo anterior depois de corretamente indentado:
#include <stdio.h>
/* Cdigo indentado */
int main() {
int x, y, z;
x = 10;
y = 2;
z = x / y;
if (x > 5) {
printf("x maior que cinco.");
}
return 0;
24 / 92

Introduo Programao
}

2.9

Matemtica Bsica

O computador foi criado com o intuito inicial de realizar contas. Portanto, importante que saibamos
como instru-lo a computar as operaes aritmticas bsicas. E essa no vai ser uma tarefa difcil, j
que as expresses aritmticas em programao so bastante semelhantes s expresses utilizadas na
matemtica. Em C, os operadores matemticos utilizados so os seguintes:
Tabela 2.3: Operadores aritmticos
Operador
+
*
/
%

Operao
Adio
Subtrao
Multiplicao
Diviso
Resto da diviso

A utilizao dos operadores em C ocorrem da forma com a qual estamos acostumados: colocamos
um operador entre dois operandos e vamos construindo as expresses. medida que as expresses
vo ficando mais complexas, podemos utilizar os parnteses para agrupar operadores e operandos.
Diferentemente do que ocorre na matemtica, em C no se utilizam colchetes e chaves para o agrupamento de expresses que j esto entre parnteses. Estes devem ser os substitutos dos primeiros
, em C se tornaria:
quando houver necessidade. Por exemplo, a expresso matemtica (x+y)(a+b)
2
((x+y)-(a+b))/2
Veja alguns exemplos de como os operadores aritmticos devem ser usados em C (os resultados so
apresentados ao lado de cada operao):
x
x
y
z
z
z

=
=
=
=
=
=

4 *
x /
x %
x *
x *
((2

5; // 20
2; // 10
4; // 2
y - 5; // 15
(y - 5); // -30
+ 3) * 4 - 2)/2; // 9

A precedncia dos operadores aritmticos, isto , a ordem em que eles so avaliados, pode ser alterada
do mesmo modo que o fazemos quando tralhamos com expresses na matemtica: utilizamos os
parnteses para que algumas operaes sejam realizadas antes que outras. o que ocorre na expresso
acima na expresso z=x*(y-5). Caso os parnteses fossem omitidos1 , a primeira operao a ser
realizada seria a que multiplica x por y, depois, do seu resultado seria subtrado cinco. Com a insero
dos parnteses, ocorre primeiro a subtrao para depois ser realizada a multiplicao.
A linguagem C possui ainda operadores especiais que resultam da combinao de operadores aritmticos com operadores de atribuio. So eles:
1 Expresso

resultante: z=x*y-5

25 / 92

Introduo Programao
Tabela 2.4: Operadores aritmticos de atribuio e operadores de incremento.
Operador
x += y
x -= y
x *= y
x /= y
x %= y
x++
++x
x---x

Operao equivalente
x = x + y
x = x - y
x = x * y
x = x / y
x = x % y
x = x + 1
x = x + 1
x = x - 1
x = x - 1

Os primeiros cinco operadores so denominados de operadores aritmticos de atribuio, ao passo


que os quatro ltimos so chamados de operadores de incremento.
Aqui cabe destacar as diferenas entre os operadores de incremento quanto localizao dos operadores aritmticos. Considere os exemplos a seguir:
x = 0;
y = 6;
z = 2;
(a) x = y / ++z; // incremento antes
// y = 6, z = 3, x = 2
x = 0;
y = 6;
z = 2;
(b) x = y / z++; // incremento depois
// y = 6, z = 3, x = 3

Nos exemplos apresentados, temos dois algoritmos que se diferenciam apenas pela utilizao dos
operadores de incremento de adio. Na expresso (a), a varivel y dividida por ++z, enquanto
que na expresso (b) ela dividida por z++. A diferena sutil, mas determinante no resultado
da expresso. No primeiro caso, z incrementada antes da diviso, logo x=6(2 + 1)=63=2.
Na expresso (b), z incrementado depois da diviso, o que resulta em x=62=3. Repare que em
ambos os casos o valor de z incrementado, de modo que aps as instrues (a) e (b) o valor de z
igual a 3.

2.10

Entrada e sada de dados

Imagine que voc desenvolveu um programa para controlar suas finanas pessoais e com ele intenciona conter seus gastos e ainda guardar uma parte do que ganha na poupana. Esse programa necessita
de interao? Como voc informar suas receitas e despesas? Como ele apresentar o resultado dos
seus clculos com a finalidade de auxili-lo no controle de suas finanas?

26 / 92

Introduo Programao
As respostas de todas essas perguntas convergem para a seguinte concluso: um programa de computador praticamente intil se no apresentar algum tipo de interao com o usurio. No cenrio
anterior, por exemplo, voc precisa informar ao programa quais so as suas receitas e despesas. Alm
disso, necessrio que ele o deixe a par dos resultados dos seus clculos, caso contrrio ele no ter
serventia alguma.
Os mecanismos que as linguagens de programao oferecem para interao com o usurio esto
presentes em suas bibliotecas de entrada e sada. Em C, as funes responsveis pelas operaes
bsicas de entrada e sada se encontram na biblioteca stdio, que utilizada por meio da diretiva:
#include <stdio.h>
Vimos no seo 2.6 uma forma de exibir na tela uma sequncia de caracteres atravs da funo
printf(), que, alm de imprimir caracteres, tambm capaz de exibir o contedo de variveis de
diversos tipos. Os detalhes de sua utilizao, bem como uma funo similar para entrada de dados
so apresentados no nas sees posteriores.

2.10.1

Funo printf()

A funo de sada printf() permite que dados sejam escritos na sada padro, que normalmente
a tela do computador. Uma chamada da funo printf tem o seguinte formato:
int printf(string_de_formato, arg1, arg2, ..., argn)
Isso quer dizer que a funo printf ir escrever na sada padro os argumentos arg1,arg2,...,argn de acordo com o que est especificado no parmetro
string_de_formato. Alm disso, o tipo int indica que a funo retorna um nmero inteiro, que neste caso corresponde ao nmero de caracteres impressos. O exemplo a seguir ilustra a
utilizao da funo printf():
#include <stdio.h>
int main() {
int idade;
float altura;
idade = 18;
altura = 1.90;
printf("Tenho %d anos e %.2f de altura.", idade, altura);
return 0;
}

Aps a execuo do cdigo acima ser exibida na tela a seguinte frase:


Tenho 18 anos e 1.90 de altura.
Os caracteres %d e %.2f so denominados de especificadores de formato e tm o objetivo de definir
o formato das variveis que sero escritas na sada padro. De outro modo, podemos entend-los
como "guardadores de lugar"para as variveis a serem exibidas. No exemplo acima, no lugar do %d
ser colocada a primeira varivel passada por parmetro (idade) e no lugar do %.2f a segunda
varivel (altura). Alm disso, elas devero ser dos tipos int e float, respectivamente. O ponto
27 / 92

Introduo Programao
seguido de um nmero antes do cdigo de formato indica a quantidade de casas decimais a serem
exibidas (quando aplicados a variveis do tipo ponto-flutuante) e so denominados de especificadores
de preciso. No exemplo anterior eles foram os responsveis pela exibio da varivel altura com
duas casas decimais.
A tabela abaixo lista os especificadores de formato mais comuns utilizados na funo printf().
Tabela 2.5: Especificadores de formatos mais utilizados na
funo printf()
Cdigo
%d ou %i
%ld ou %li
%u
%c
%s
%f

2.10.2

Formato
Inteiro (int) decimal
Inteiro (long int) decimal
Inteiro sem sinal
Caractere
Cadeira de caracteres
Nmero de ponto-flutuante

Funo scanf()

A funo de entrada scanf() possibilita a leitura de dados da entrada padro, ou seja, do teclado.
O que ela faz interromper a execuo do programa at que o usurio digite algo e depois pressione a
tecla Enter. Depois que o programa retoma sua execuo, o contedo digitado armazenado em uma
ou mais variveis. Uma chamada da funo scanf tem o seguinte formato:
int scanf(string_de_formato, arg1, arg2, ..., argn)
O parmetro string_de_formato especifica os tipos de dados que sero lidos e os parmetros
arg, arg2, ..., argn correspondem aos endereos das variveis nas quais sero armazenados os valores digitados pelo usurio. A funo scanf() retorna um valor inteiro que indica o
nmero de variveis que tiveram valores atribudos, sendo utilizado para verificar algum problema na
entrada de dados. O exemplo a seguir ilustra a utilizao da funo scanf():
#include <stdio.h>
int main() {
int idade;
float altura;
printf("Informe sua idade: ");
scanf("%d", &idade)
printf("Informe sua altura: ");
scanf("%f", &altura);
printf("\nVoc tem %d anos e %.2f de altura.", idade, altura);
return 0;
}

28 / 92

Introduo Programao
Ao contrrio do exemplo da seo anterior, os dados a serem exibidos no esto pr-determinados,
isto , as variveis no possuem valores a priori. As atribuies apenas ocorrem quando o usurio
entra com valores via teclado. No exemplo, depois que a sequncia de caracteres "Informe sua
idade: " exibida, a execuo do programa interrompida at que o usurio digite um valor.
Quando isso ocorre, ele armazenado no endereo da varivel idade, obtido quando ela precedida
pelo caractere &. Por conseguinte, o printf() ao final do cdigo ir exibir os dados informados
pelo usurio e no os dados pr-determinados pelo programador.
Importante
A tecla Enter tambm possui um caractere que a representa, a saber, o caractere especial
\n. Portanto, quando o \n escrito na sada padro, o efeito gerado o mesmo da digitao
da tecla Enter.

A funo scanf() tambm pode ler numa mesma linha diversos dados, armazenando-os em diferentes variveis. As leituras do cdigo anterior, por exemplo, podem ser reescritas da seguinte forma:
printf("Informe sua idade e sua altura:");
scanf("%d %.2f", &idade)

Para que esse cdigo funcione como desejado, o usurio precisa digitar um nmero inteiro seguido
de um espao e depois um nmero de ponto-flutuante. O espao requerido porque ele utilizado na
especificao do formato (entre o %d e o %.2f h um espao). Assim como printf(), a funo
scanf() tambm possui uma lista de especificadores de formato. Os mais utilizados seguem abaixo:
Tabela 2.6: Especificadores de formatos mais utilizados da
funo scanf()
Cdigo
%d ou %i
%ld ou
%li
%u
%c
%s
%f

2.11

Significado
Leitura de um inteiro (int) decimal
Leitura deum inteiro (long int) decimal
Leitura de um inteiro sem sinal
Leitura de um nico caractere
Leitura de uma cadeira de caracteres
Leitura de um nmero de ponto-flutuante

Recapitulando

Neste captulo voc pde conhecer um pouco mais sobre o funcionamento dos computadores, mais
especificamente sobre a forma com a qual eles decodificam as instrues que lhes so passadas.
Vimos, portanto, que as linguagens de programao podem ser classificadas em linguagens de alto
nvel ou baixo nvel, de acordo com sua proximidade em relao linguagem que os computadores
podem compreender: o cdigo de mquina.
Como programar em linguagem de baixo nvel uma tarefa rdua, foram criadas as linguagens de alto
nvel para facilitar a vida dos programadores. Desse modo, surgiu a necessidade de um software que
29 / 92

Introduo Programao
fosse capaz de realizar a traduo de programas escritos em linguagem de alto nvel para programas
equivalente em cdigo de mquina. Esses softwares so os tradutores e interpretadores.
Aprendemos que a maneira de pensar de um programador na resoluo de um problema est relacionada com um paradigma de programao. Se um programador utilizar a linguagem C, por exemplo,
ele vai raciocinar segundo os paradigmas imperativo e estruturado.
Falando em linguagem C, conhecemos a estrutura de um programa escrito nessa linguagem, seus tipos
primitivos, como podem ser elaborados nomes para as variveis e como estas podem ser declaradas.
Enfim, voc deu os primeiros passos para a elaborao do seu primeiro programa.
No prximo captulo voc vai estudar as estruturas de controle em C. Elas simplesmente so as instrues mais importantes para o desenvolvimento da lgica de programao. Por isso, estude atentamente o prximo captulo e tente elaborar o maior nmero de programas possvel para consolidar o
aprendizado.

2.12

Exerccios Propostos

1. Diferencie linguagem de programao de alto nvel de linguagem de programao de baixo


nvel. D exemplos de linguagens que se enquadram em ambos os tipos.
2. Qual o principal objetivo dos tradutores e interpretadores?
3. Defina montador e compilador, enfatizando suas diferenas.
4. Explique como funcionam os interpretadores.
5. Quais as vantagens da compilao em relao interpretao?
6. O que um paradigma de programao? Cite exemplos.
7. Quais dos seguintes itens no podem ser utilizados como identificadores na linguagem C? Explique por qu?
a. 3x
b. Inflao
c. COMPUTACAO
d. nota_1
e. nota 2
f. prof.
g. $4
h. RG
i. main
j. return
8. Descreva os tipos primitivos de C, destacando os valores que eles podem armazenar.
9. Qual a diferena entre os operadores prefixo e sufixo de incremento?
10. Qual valor de (x1 + x2) aps a execuo dos grupos de comandos abaixo:
30 / 92

Introduo Programao
a. y = 6;
b. z = 8;
c. c = 2;
d. x1 = ((y * z) - z)/c;
e. x2 = (z / 2)/ y++;
11. Considerando as atribuies x = 20 e y = 2, calcule o resultado de cada uma das expresses
abaixo:
a. (x-- + x * (x % y))
b. (x-- + x * (x % y))
c. (x-- + x * (x % 3))
d. (--x + x * (x % 3))
e. (--x + x * (x % x))
12. Faa um programa em C que solicite ao usurio que digite o ano de seu nascimento, armazene
o valor digitado em uma varivel e em seguida imprima na sada padro a sua idade.
Feedback sobre o captulo
Voc pode contribuir para melhoria dos nossos livros. Encontrou algum erro? Gostaria de
submeter uma sugesto ou crtica?
Para compreender melhor como feedbacks funcionam consulte o guia do curso.

31 / 92

Introduo Programao

Captulo 3
Estruturas de Controle
O BJETIVOS DO CAPTULO
Ao final deste captulo voc dever ser capaz de:
Entender as estruturas sequenciais, de seleo e de repetio;
Escrever estruturas de seleo utilizando os comandos if, if-else e switch da linguagem
C;
Escrever estruturas de repetio utilizando os comandos for, while e do-while da linguagem C.

3.1

Introduo

Vimos no Captulo 1 [1] que os algoritmos so instrues que contm passos para solucionar um
determinado problema. Vimos tambm que estes algoritmos podem ser representados atravs de
linguagens de programao, como por exemplo, a linguagem C, que estamos aprendendo aqui. Estes
passos so executados na sequncia que eles aparecem. Entretanto, em muitas situaes, necessrio
alterar o fluxo de execuo destas instrues. Pode ser que seja necessrio executar um passo, ou um
conjunto deles, apenas se uma determinada condio for verdadeira, ou talvez, pode ser que seja
preciso repetir um conjunto de passos vrias vezes at uma determinada condio. Neste sentido, este
captulo ir explicar as diferentes estruturas de controle existentes nos algoritmos e seus respectivos
comandos na linguagem C.

3.2

Estrutura Sequencial

Um algoritmo que possui uma estrutura sequencial significa que suas instrues so executadas na
sequncia em que elas aparecem, sem nenhuma alterao no seu fluxo, a no ser, claro, que exista
alguma instruo explcita para a mudana deste fluxo. Vejamos o cdigo em C na Figura 3.1 [33]
abaixo.

32 / 92

Introduo Programao
Execuo das
Intrues
void main(){
int x, y, soma;
scanf(&x);
scanf(&y);
soma = x + y;
printf("%d",soma);
}

Figura 3.1: Estrutura sequencial na linguagem C


Este algoritmo ir ler dois valores e guard-los, respectivamente, nas variveis x e y. Aps isso,
a varivel inteira soma receber a soma dos valores de x e y. Em seguida, ser mostrada na sada
padro, o resultado desta soma. Perceba que os passos do algoritmo so executados de cima para
baixo.
Entretanto, em alguns momentos os problemas que queremos resolver requerem a alterao no fluxo
normal de execuo do algoritmo. Na prxima seo, iremos aprender como executar um conjunto
de instrues de acordo com uma determinada condio.

3.3

Estrutura de Deciso

Como foi dito, muitas vezes necessrio criar blocos de instrues no algoritmo que so executados
apenas se uma determinada condio for verdadeira. Veja o algoritmo abaixo:
"Se hoje no chover, ento Joo ir praia".
No algoritmo acima, Joo ir praia se, e somente se, no chover hoje. Significa que esta instruo
de Joo ir praia s ser executada se a condio de no chover for verdadeira. Este tipo de estrutura
chamado de estrutura de deciso, tambm conhecido como estrutura de seleo ou condicional.
Podemos ter trs tipos de estrutura de deciso: deciso simples, deciso composta e deciso mltipla.
Vamos ver adiante estes trs tipos e quais so os comandos na linguagem C, respectivamente, para
cada um destes tipos.

3.3.1

Deciso simples

Quando queremos que uma determinada instruo ou um conjunto de instrues execute apenas se
uma determinada condio for verdadeira. A estrutura da deciso simples a seguinte:
SE condio ENTO instruo
Uma condio deve ter como resultado apenas dois valores possveis: verdadeiro ou falso. A instruo
s ser executada se a condio tiver o valor verdadeiro.
Vamos analisar o exemplo a seguir. Este algoritmo l um valor digitado pelo usurio e armazena na
varivel x. Em seguida, o comando SE verifica se o valor de x menor que 20. Caso seja, a instruo
ESCREVA executada, mostrando na tela a frase "o valor de X menor que 20".

33 / 92

Introduo Programao

Exemplo 3.1 Algoritmo que comparava valor lido com 20


LEIA x
SE x < 20 ENTO
ESCREVA "O valor de x menor que 20."
Para cada linguagem de programao h uma sintaxe para criar estruturas de controle. Na Linguagem
C, a estrutura de deciso simples possui a seguinte forma:
if (expresso)
instruo;

Na linguagem C, a condio definida como uma expresso, que pode ser lgica ou aritmtica. Ao
ser executada, a expresso verificada. Se o resultado desta for verdadeiro, a instruo que vem aps
a expresso executada.
Entretanto, muitas vezes queremos que mais de uma instruo seja executada caso a condio seja
verdadeira. Neste caso, devemos utilizar um bloco de instrues dentro do comando if, como
mostrado abaixo.
Estrutura de deciso simples com blocos na linguagem C
if (expresso) {
instruo 1;
instruo 2;
...
}

As duas formas, com e sem bloco, se diferenciam apenas pelo fato de que a primeira possui apenas uma instruo a ser executada caso a condio seja verdadeira. No segundo caso, um bloco de
instrues ser executado. Na linguagem C, um bloco de instrues deve estar entre chaves.
Importante
Sempre que voc precisar executar um bloco de instrues, utilize as chaves para delimitar
o incio e o fim deste bloco.

Como foi dito, a expresso pode conter uma expresso lgica ou aritmtica. As expresses aritmticas
foram vistas no captulo 2. Vamos ver agora como funcionam as expresses lgicas na linguagem C.
3.3.1.1

Expresses lgicas

As expresses lgicas so usualmente utilizadas para fazer comparaes entre operandos. Para isso,
estas expresses so compostas por operadores lgicos e relacionais, e possuem apenas dois valores
possveis: verdadeiro ou falso. Por exemplo, quando queremos saber se um valor maior, menor,
igual ou diferente de um outro valor.
Na linguagem C, os seguintes operadores relacionais podem ser utilizados:
Operador
>
<

Descrio
Maior que
Menor que
34 / 92

Introduo Programao
Operador
>=
<=
==
!=

Descrio
Maior ou igual a
Menor ou igual a
Igual a
Diferente de

Considere o cdigo menorq20.c [35] abaixo. Este reflete o mesmo algoritmo de Exemplo 3.1 [34],
sendo que agora, implementado na linguagem C. Na linha 6, estamos pedindo para o usurio entrar
com o valor de x. Na linha 8, temos um comando if, onde h uma expresso relacional x < 20.
Portanto, essa expresso verificada e caso seja verdadeira, ser mostrado na sada padro "O valor
de x menor que a 20."(linha 9). Caso a expresso seja falsa, o algoritmo se encerra sem mostrar
nada na sada padro, pois a instruo aps o comando if no executada.
Cdigo fonte
menorq20.c
1

#include <stdio.h>

2
3
4

int main() {
int x;

scanf("%d", &x);

6
7

if (x < 20)
printf("O valor de x e menor que 20.");

8
9
10

return 0;

11
12

Em outros casos, necessitamos utilizar operadores lgicos nas expresses para avaliar mais de uma
expresso relacional. Por exemplo, digamos que no problema acima queremos verificar se o valor
digitado para a varivel x est dentro do intervalo entre 10 e 20. Neste caso, precisamos que a
condio verifique as duas expresses relacionais: (x > 10) e (x < 20). Portanto, precisamos
conectar as duas expresses relacionais utilizando um operador lgico E. A tabela abaixo apresenta
os operadores lgicos possveis:
Operador em C

Operador em
linguagem
algortmica
E
OU
NO

&&
||
!

Portanto, o algoritmo para resolver o problema acima, na linguagem C, o seguinte:


Cdigo fonte
entre10e20.c
1

#include <stdio.h>

2
3
4

int main() {
int x;
35 / 92

Introduo Programao

scanf("%d", &x);

6
7

if (x > 10 && x < 20)


printf("x esta entre 10 e 20.");

8
9
10

return 0;

11
12

Perceba que agora a condio do comando if` possui duas expresses relacionais conectadas por um
operador lgico E (&&). Nesse caso, se ambas as expresses forem verdadeiras, ser mostrada na
sada padro "x esta entre 10 e 20". Caso alguma das expresses seja falsa, nada ser mostrado, pois
o resultado da expresso completa falso. Vejamos a tabela abaixo, denominada de tabela verdade,
que mostra a relao lgica entre duas expresses e seus respectivos resultados.
Expresso 1
Verdadeiro
Verdadeiro
Falso
Verdadeiro
Verdadeiro
Falso
Verdadeiro
Falso

3.3.1.2

Operador
E
E
E
OU
OU
OU
NO
NO

Expresso 2
Verdadeiro
Falso
Falso
Verdadeiro
Falso
Falso
-

Resultado
Verdadeiro
Falso
Falso
Verdadeiro
Verdadeiro
Falso
Falso
Verdadeiro

Exerccio resolvido

ER 3.1. Considere quatro variveis a, b, c e d com valores iniciais de 5, 7, 3 e 9. Dada as condies


abaixo, indique se o resultado final da expresso ser verdadeiro ou falso.
a. (a != 3 || b < 10 || c == 5)
b. (d > 8 && c == 3 || a >=10)
c. !(d == 12 && a != 10)
d. (c == 4 || d <= 6) && (a >= 5 && b != 9) || (!(a < 5))
Resposta:
a. Neste caso temos trs expresses lgicas. A primeira (a != 3) verdadeira. A segunda (b
< 10) verdadeira, e a terceira (c == 5) falsa. Como as expresses esto conectadas por
um operador OU (||), ento basta que uma das expresses seja verdadeira para o resultado da
expresso completa ser verdadeira.
b. Temos neste caso trs expresses. Para um melhor entendimento, vamos utilizar uma tabela.
As duas primeiras expresses (d > 8 e c == 3) so verdadeiras e esto conectadas pelo
operador lgico &&, logo R1 && R2 verdadeiro. A terceira expresso (a >= 10), por sua
vez, falsa. Ento, resolvendo R3 || R4, temos o resultado final como verdadeiro.

36 / 92

Introduo Programao
Rs
R1
R2
R3
R4
R5

Expresso
d > 8
c == 3
R1 && R2
a >= 10
R3 || R4

Resultado
VERDADEIRO
VERDADEIRO
VERDADEIRO
FALSO
VERDADEIRO

c. Utilizando novamente a tabela, temos que a primeira expresso (d == 12) falsa. A segunda
expresso (a != 10) verdadeira. A relao entre R1 && R2 falsa, pois apenas R2
verdadeira. A ltima expresso uma negao de R3, ou seja, se R3 falso, ento R4
verdadeiro.
R
R1
R2
R3
R4

Expresso
d == 12
a != 10
R1 && R2
!R3

Resultado
FALSO
VERDADEIRO
FALSO
VERDADEIRO

d. Vamos utilizar novamente a tabela para nos auxiliar. Temos que prestar bastante ateno nos
parnteses das expresses que podem ser utilizadas para explicitar a precedncia da avaliao.
Rs
R1
R2
R3
R4
R5
R6
R7
R8
R9
R10

3.3.1.3

Expresso
c == 4
d <= 6
R1 || R2
a >= 5
b != 9
R4 && R5
a < 5
!R7
R3 && R6
R9 || R8

Resultado
FALSO
FALSO
FALSO
VERDADEIRO
VERDADEIRO
VERDADEIRO
FALSO
VERDADEIRO
FALSO
VERDADEIRO

Verificao da condio com expresses aritmticas na Linguagem C

Anteriormente, dissemos que a expresso dentro de um comando if pode ser lgica ou aritmtica.
Vimos como funciona nos casos de expresses lgicas. Nos casos de expresses aritmticas, na
linguagem C, Falso assume o valor zero, e Verdadeiro assume qualquer valor diferente de zero. Neste
sentido, quando utilizamos uma expresso aritmtica dentro da condio de um comando if para
verificar se esta verdadeira ou falsa, temos que ter o cuidado de analisar o valor resultante. Vamos
verificar o exemplo no cdigo abaixo.
Cdigo fonte
if5.c
1

#include <stdio.h>

2
3
4

int main() {
int x = 5;

37 / 92

Introduo Programao
if (x)
printf("Isto sera mostrado");

6
7
8

if (x - 5)
printf("Isto nao sera mostrado");

9
10
11

return 0;

12
13

Inicialmente a varivel inteira x recebe o valor 5 (linha 4). Na linha 6 existe uma estrutura de deciso
simples, onde h a verificao da expresso que est entre parnteses. Nesse caso, a expresso
apenas a prpria varivel x, logo o resultado da expresso o valor desta, que 5. Considerando o que
foi dito, quando o resultado for diferente de zero, ele considerado verdadeiro. Logo, o resultado
da expresso tambm verdadeiro, e ento a instruo que vem aps a condio executada.
J na linha 9, tambm h outra estrutura de deciso simples, na qual a condio a ser avaliada
a expresso x - 5. O resultado dessa expresso zero, fazendo com seja avaliada como falsa.
Consequentemente, a instruo que vem aps a condio no executada.

3.3.2

Deciso composta

Em alguns momentos, ao termos uma estrutura de deciso, queremos que uma outra instruo ou
um outro bloco de instrues seja executado caso a condio de deciso seja falsa. Esta estrutura
chamada de deciso composta.
O pseudocdigo abaixo exemplifica uma estrutura de deciso composta.
Exemplo 3.2 Pseudocdigo com deciso composta
LEIA nota
SE nota >= 7 ENTO
ESCREVA "Aprovado"
SENO
ESCREVA "Reprovado"
Na linguagem C, utilizamos a palavra else, aps a instruo ou bloco de instrues do if, para
definir que queremos executar um outro conjunto de instrues, caso a expresso condicional seja
falsa.
if (expresso)
instruo 1;
else
instruo 2;

Quando possumos apenas uma instruo a ser executada, no precisamos utilizar o delimitador de
bloco de instrues (as chaves). Neste caso, a condio verificada. Caso seja positiva, a instruo 1
executada, caso contrrio, a instruo 2 executada. Caso queiramos que um conjunto de instrues
seja executado, devemos utilizar ento as chaves, como mostra o cdigo abaixo.
if (condio) {
instruo 1;
instruo 2;
...
38 / 92

Introduo Programao
} else {
instruo 3;
instruo 4;
...
}

Neste caso temos dois blocos de instrues: um para o bloco do if, que ser executado caso a
condio seja verdadeira, e o bloco de instrues do else, caso a condio seja falsa.
Importante
Tabule as instrues que esto dentro dos blocos, colocando-os mais a direita (utilize a tecla
TAB do teclado). Esta organizao do cdigo chama-se indentao. Dessa maneira, seu
cdigo se torna mais legvel, e consequentemente mais fcil de encontrar possveis erros.

Vamos traduzir o pseudocdigo apresentado no Exemplo 3.2 [38] para a linguagem C.


Cdigo fonte
nota7.c
1

#include <stdio.h>

2
3
4

int main() {
float nota;

scanf("%f", &nota);

6
7

if (nota >= 7)
printf("Aprovado");
else
printf("Reprovado");

8
9
10
11
12

return 0;

13
14

3.3.2.1

Exerccio resolvido

ER 3.2. Escreva um programa para ler 2 nmeros inteiros do teclado (A e B), verificar e imprimir
qual deles o maior, ou a mensagem "A=B", caso sejam iguais.
Resposta:
Cdigo fonte
comparaab.c
1

#include <stdio.h>

2
3
4

int main() {
int a, b;

5
6
7

scanf("%i", &a);
scanf("%i", &b);
39 / 92

Introduo Programao

if (a > b)
printf("A e maior que B.");
else if (b > a)
printf("B e maior que A.");
else
printf("A = B");

9
10
11
12
13
14
15

return 0;

16
17

3.3.3

Comando de deciso mltipla

Uma outra forma de escrever uma estrutura de condio utilizando o comando de deciso mltipla
switch. Este tipo de estrutura condicional tem a mesma funo do if-else-if, com a diferena
que o comando switch no aceita expresses, apenas constantes. A vantagem de se utilizar este
comando a legibilidade do cdigo quando conhecemos os possveis valores para uma determinada
varivel. Vamos ver o formato de uso do comando switch.
switch (varivel) {
case VALOR1:
instruao1;
instruo2;
break;
case VALOR2:
instruao3;
instruo4;
break;
default:
instruao5;
instruo6;
break;
}

Uma varivel do tipo char ou int colocada entre parnteses aps o comando switch. Os
valores desta varivel que sero avaliados logo em seguida, atravs das declaraes case. Para cada
possvel valor da varivel, existe uma declarao case correspondente. Caso o valor seja aquele que
corresponde na declarao case, ento as instrues abaixo dela sero executadas at encontrar o
comando break. A declarao default opcional, e executada apenas se a varivel no for
igual a nenhuma das constantes definidas nas declaraes case.
Importante
O comando break tem a funo de interromper um determinado fluxo de execuo. Este
comando ser melhor explicado na seo 3.4.5 que fala sobre os comandos de desvio. O importante a saber por hora que o comando break deve ser utilizado ao final das instrues
de cada declarao case. Caso no seja colocado, as instrues das outras declaraes
case tambm sero executadas.

Para um melhor entendimento, vamos analisar o cdigo semana.c [41] abaixo. A ideia deste programa
que o usurio digite o valor numrico correspondente ao dia da semana e o programa mostre por
40 / 92

Introduo Programao
extenso este dia. Uma varivel chamada semana do tipo int declarada (linha 4) e guardar o valor
que o usurio ir digitar (linha 7). Em seguida, o comando switch foi utilizado (linha 9). Para cada
dia da semana existe uma declarao case correspondente. Isto significa que se o usurio digitou o
valor 1, a instruo da linha 11 ser executada, mostrando na sada a string "Domingo". Caso o valor
digitado seja 2, a instruo da linha 14 executada, mostrando na sada a string "Segunda-feira". A
mesma ideia acontece para os outros 5 dias da semana. Caso o valor digitado pelo usurio no esteja
entre 1 e 7, as instrues da declarao default sero executadas, mostrando a string "Numero fora
do intervalo permitido.".
Cdigo fonte
semana.c
1

#include <stdio.h>

2
3
4

int main() {
int semana;

printf("Digite um numero de 1 a 7: ");


scanf("%d", &semana);

6
7
8

switch (semana) {
case 1:
printf("Domingo");
break;
case 2:
printf("Segunda-feira");
break;
case 3:
printf("Terca-feira");
break;
case 4:
printf("Quarta-feira");
break;
case 5:
printf("Quinta-feira");
break;
case 6:
printf("Sexta-feira");
break;
case 7:
printf("Sabado");
break;
default:
printf("Numero fora do intervalo permitido.");
break;
}

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

return 0;

36
37

41 / 92

Introduo Programao

3.4

Estrutura de Repetio

Considere um algoritmo em que voc precise repetir um determinado conjunto de passos, por exemplo, um algoritmo para retirar uma lmpada do bocal. Um passo deste algoritmo realizar um movimento com a mo para girar a lmpada. Este passo deve ser repetido at que a lmpada desencaixe do
bocal. Neste sentido, existem as estruturas de repeties nas linguagens de programao para permitir
que uma instruo ou um bloco de instrues seja repetido em um algoritmo computacional. Estas
estruturas tambm so conhecidas como estruturas de iterao ou estruturas de lao.
Vamos tomar como base Exemplo 3.2 [38], onde uma nota solicitada ao usurio. Caso a nota seja
maior que 7, mostrado Aprovado na tela, caso contrrio, mostrado "Reprovado". O algoritmo
utilizado, at ento, s permite que uma nota seja digitada, ou seja, quando o usurio digita a nota, o
programa apresenta o resultado e em seguida fecha. Mas digamos que agora queremos que o programa
continue executando, solicitando notas e apresentando o resultado, at que o usurio digite o valor -1
para sair do programa. Este algoritmo mostrado no pseudocdigo abaixo. Perceba que temos uma
condio nota <> -1 que ser avaliada antes de executar as instrues que esto dentro do bloco
do ENQUANTO. Desse modo, enquanto a nota digitada pelo usurio for diferente de -1, o programa
ir solicitar uma nota e apresentar o resultado.
Exemplo 3.3 Pseudocdigo com estrutura de repetio
LEIA nota
ENQUANTO nota <> -1 FAA
SE nota >= 7 ENTO
ESCREVA "Aprovado"
SENO
ESCREVA "Reprovado"
LEIA nota
FIM-ENQUANTO
Na linguagem C h trs opes diferentes para se criar estruturas de repetio. So os comandos
while, do-while e for. Veremos cada um deles em detalhes a seguir.

3.4.1

Comando while

Podemos usar o comando while quando desejamos que uma ou mais instrues sejam repetidas
at que uma determinada condio seja atendida. A estrutura do while na linguagem C bastante
parecida com a do pseudocdigo apresentado anteriormente. Veja abaixo:
while (expresso) {
instruo 1;
instruo 2;
...
}

As instrues sero executadas repetidamente enquanto a expresso for verdadeira. Assim que essa
condio tornar-se falsa, o lao para. Vejamos o exemplo abaixo, que consiste no pseudocdigo do
Exemplo 3.3 [42] escrito na linguagem C.
Cdigo fonte
whilenota.c
42 / 92

Introduo Programao

#include <stdio.h>

2
3
4

int main() {
float nota;

scanf("%f", &nota);
while (nota != -1) {
if (nota >= 7)
printf("Aprovado\n");
else
printf("Reprovado\n");

6
7
8
9
10
11
12

scanf("%f", &nota);

13

14
15

return 0;

16
17

Vamos tentar entender o cdigo acima. Inicialmente, uma varivel nota, do tipo float, declarada
(linha 4). Logo depois ocorre a leitura da primeira nota. Caso ela seja diferente de -1, o bloco de
instrues dentro do while (linhas 8 a 14) ser executado. O comando while far com que as
instrues em seu corpo sejam executadas, repetidamente, enquanto a condio nota != -1 for
verdadeira.
Vejamos outro exemplo. O programa mostrado10vezes.c [43] abaixo escreve 10 vezes na tela "Isto
sera mostrado 10 vezes.". A condio de parada do comando while cont <= 10, o que significa que enquanto o valor de cont for menor ou igual a 10, o bloco de instrues ser executado.
Para que o lao tenha fim, a varivel cont precisa ser incrementada at que alcance o valor 11.
Cdigo fonte
mostrado10vezes.c
1

#include <stdio.h>

2
3
4

int main() {
int cont = 1;

while (cont <= 10) {


printf("Isto sera mostrado 10 vezes.\n");
cont++;
}

6
7
8
9
10

return 0;

11
12

3.4.1.1

Exerccio resolvido

ER 3.3: Escreva um programa que leia vrias notas de alunos de uma turma. O programa deve ler
notas at que o usurio digite o valor -1. Aps isso, o programa deve mostrar a mdia dessas notas.
Resposta:
43 / 92

Introduo Programao
Neste programa no sabemos previamente a quantidade de notas que o usurio precisa. Precisamos,
nesse caso, utilizar um lao de repetio que fique lendo notas at que o valor -1 seja passado pelo
usurio. Desse modo, podemos utilizar o comando while (linha 7) com a condio de parada nota
!= -1, ou seja, o usurio seguir entrando com as notas enquanto os valores digitados forem diferentes de -1. Dentro do lao, solicitado que o usurio digite a nota (linha 8). Na linha 9, o valor
digitado pelo usurio armazenado na varivel nota. Para calcular a mdia das notas, precisamos de
duas informaes: a soma de todas as notas e a quantidade de notas lidas. Utilizamos a varivel soma
para armazenar a soma das notas (linha 12) e a varivel cont para armazenar a quantidade de notas
(linha 13). A mdia das notas ser mostrada depois do lao, ou seja, quando o usurio digitar -1 para
a nota. Como o clculo da mdia precisa da quantidade total das notas, seu clculo e o comando para
sua exibio devem ser executados aps o trmino do lao (linha 17).
Cdigo fonte
notas_alunos.c
1

#include <stdio.h>

2
3
4
5

int main() {
float nota = 0, soma = 0;
int cont = 0;

while (nota != -1) {


printf("Entre com a nota: ");
scanf("%f", &nota);

7
8
9
10

if (nota != -1) {
soma += nota;
cont++;
}

11
12
13
14

15
16

printf("Media das notas: %.2f",

17

soma / cont);

18

return 0;

19
20

3.4.2

Comando do-while

Assim como o while, o comando do-while tambm uma estrutura de repetio. Com semelhanas que vo alm dos seus nomes, sobretudo em termos de funcionalidade, a principal diferena
entre eles que, no caso do do-while, o bloco de instrues dentro do lao executado pelo menos
uma vez, mesmo que a condio seja falsa. Isso acontece porque a condio de parada s avaliada
depois que as instrues so executadas. Segue abaixo a estrutura do comando do-while.
do {
instruo 1;
instruo 2;
...
} while (condio);

44 / 92

Introduo Programao
O comando comea com a palavra do, seguida do bloco de instrues a ser repetido. Aps a execuo dessas instrues, a condio avaliada. Caso seja verdadeira, as instrues so executadas
novamente, caso contrrio, o lao se encerra. Para entender melhor, observe o exemplo abaixo. Este
exemplo faz exatamente o mesmo que o exemplo mostrado10vezes.c [43], porm, utilizando o comando do-while.
Cdigo fonte
do_while.c
1

#include <stdio.h>

2
3
4

int main() {
int cont = 1;

do {
printf("Isto sera mostrado 10 vezes.\n");
cont++;
} while (cont <= 10);

6
7
8
9
10

return 0;

11
12

3.4.3

Comando for

Este comando tambm serve para criar um lao de repetio e geralmente utilizado quando conhecemos a quantidade de vezes que queremos que as instrues sejam repetidas.
O formato do comando for o seguinte:
for (expresso1; condio; expresso2) {
instruo1;
instruo2;
...
}

Em expresso1, uma varivel, geralmente um contador, recebe um valor inicial. Essa varivel
ser incrementada ou decrementada de acordo com a expresso definida em expresso2. O lao
ficar executando as instrues (instruo1 e instruo2) at que a condio seja falsa.
Vejamos o exemplo abaixo para entender a sequncia de operaes que so realizadas durante a execuo do comando for. O programa for_cont.c [46] abaixo tem o mesmo resultado de do_while.c
[45] mostrado anteriormente. Inicialmete, uma varivel inteira declarada (linha 4). Diferentemente
do programa do_while.c [45], no atribumos nenhum valor inicial varivel, visto que ela ser inicializada na primeira expresso do comando for. Na linha 6 existe um comando for, cuja primeira
expresso a inicializao da varivel cont. Em seguida, a condio cont <= 10 avaliada.
Como inicialmente cont = 0, expresso avaliada como verdadeira, e a instruo na linha 7
executada. No fim da execuo das instrues (nesse caso, especificamente, h apenas uma instruo)
contidas dentro do for, a terceira expresso do for avaliada, que nesse caso um incremento
(cont++). Ento a varivel cont incrementada e passa a valer 2. Em seguida, a condio
verificada novamente e, caso seja verdadeira, executa novamente a instruo dentro do for. Essa
sequncia de passos repetida at que a condio seja avaliada como falsa.
Cdigo fonte
45 / 92

Introduo Programao
for_cont.c
1

#include <stdio.h>

2
3
4

int main() {
int cont;

for (cont = 1; cont <= 10; cont++)


printf("Isto sera mostrado 10 vezes.\n");

6
7
8

return 0;

9
10

Para entender melhor o funcionamento do comando for, vamos ver outro exemplo que utiliza decremento (--) ao invs do incremento. A ideia muito parecida com a do exemplo anterior, entretanto,
ao invs de incremento, temos um decremento da varivel cont. No comando for, a varivel cont
inicializada com o valor 10. Em seguida, a condio cont > 0 avaliada. Como o valor de
cont 10, a condio verdadeira, e a instruo dentro do for executada (linha 7). Ao fim da
execuo dessa instruo, a varivel cont decrementada e passa a valer 9. Novamente a condio
cont > 0 verificada e continua sendo verdadeira, o que faz com que a instruo da linha 7 seja
executada novamente. O lao continua at a varivel cont passar a valer 0, caso no qual a condio
cont > 0 ser falsa.
Cdigo fonte
for_cont_decremento.c
1

#include <stdio.h>

2
3
4

int main() {
int cont;

for (cont = 10; cont > 0; cont--)


printf("Valor de cont: %i\n", cont);

6
7
8

return 0;

9
10

Uma particularidade do comando for que nenhum dos trs elementos que o compe obrigatrio, ou seja, podemos omitir qualquer um desses elementos ou at mesmo uma combinao deles.
Contudo, essa uma prtica que deve ser evitada.

3.4.4

Lao infinito

Quando a condio de parada de uma determinada estrutura de repetio nunca alcanada, as intrues do lao so executadas indefinidamente, e consequentemente o programa nunca chega ao seu
fim. Tal comportamento algo que deve ser evitado em programao (na grande maioria das situaes) e, por ser um problema to recorrente, recebe um nome especial: lao infinito. O exemplo
abaixo ilustra esse tipo de lao:
Cdigo fonte
laco_infinito.c
46 / 92

Introduo Programao

#include <stdio.h>

2
3
4

int main() {
int cont;

for (cont = 1; ; cont++)


printf("Laco infinito.\n");

6
7
8

return 0;

9
10

Observe que na linha 6 temos um comando for cuja condio de parada no foi definida. Consequentemente, o lao entra em loop e a execuo da instruo na linha 7 executada indefinidamente.
Ateno
Ao criar uma estrutura de repetio, observe bem a condio de parada para verificar se ela
realmente ser alcanada em algum momento. Sem esse cuidado voc corre o risco de criar
um lao infinito, e seu programa, possivelmente, no ter o resultado esperado.

3.4.5

Exerccio Resolvido

E.R 3.4. Analise o programa abaixo. O objetivo do programa ler 50 valores e mostrar, ao final da
leitura, o menor deles. Entretanto, ele possui um problema. Identifique e corrija o erro.
Cdigo fonte
menor_deles.c
1

#include <stdio.h>

2
3
4
5

int main() {
int quantidade = 1;
float valor, menor;

printf("Informe um valor: ");


scanf("%f", &menor);

7
8
9

while (quantidade < 50) {


printf("Informe um valor: ");
scanf("%f", &valor);
if (valor < menor)
menor = valor;
}

10
11
12
13
14
15
16

printf("Menor valor lido: %f", menor);

17
18

return 0;

19
20

Resposta:
47 / 92

Introduo Programao
Vamos analisar o cdigo considerando seu objetivo: ler 50 valores e apresentar o menor deles. Vamos
iniciar nossa anlise na estrutura de repetio while, na linha 10. A condio quantidade <
50. Logo percebemos que a varivel quantidade, que tem o valor inicial de 1 na sua declarao,
no alterada em nenhum momento dentro do lao, o que sugere algum problema. Para o lao ter um
fim, necessrio que a varivel quantidade atinja o valor 50 em algum momento, e no isso que
est acontecendo. Portanto, temos um lao infinito. Para corrigir o problema, devemos incluir uma
linha dentro do lao a fim de incrementar o valor da varivel quantidade.
O cdigo abaixo apresenta a soluo do problema com a incluso da linha 12, na qual a varivel
quantidade incrementada. Dessa forma, o lao deixou de ser infinito, uma vez que ele atingir
o valor 50 em algum momento, tornando falsa a condio quantidade < 50 do lao.
Cdigo fonte
menor_deles_resposta.c
1

#include <stdio.h>

2
3
4
5

int main() {
int quantidade = 1;
float valor, menor;

printf("Informe um valor: ");


scanf("%f", &menor);

7
8
9

while (quantidade < 50) {


printf("Informe um valor: ");
scanf("%f", &valor);

10
11
12
13

if (valor < menor)


menor = valor;

14
15
16

quantidade++; // Solucao do problema

17

18
19

printf("Menor valor lido: %.2f", menor);

20
21

return 0;

22
23

3.4.6

Comandos de desvio

Vimos no ltimo exemplo o que um lao infinito. Em alguns momentos, precisamos utilizar um
comando para realizar um desvio dentro do lao de repetio. Esses comandos so: break e
continue. Ambos podem ser utilizados em qualquer estrutura da repetio.
3.4.6.1

Comando break

O comando break interrompe a execuo do lao, fazendo com que as instrues dentro do lao
aps esse comando no sejam executadas. Vamos ver o exemplo break_interrompe.c [49]. Apesar de
no haver condio de parada no for, ele ir parar quando o comando break for executado, ou seja,
48 / 92

Introduo Programao
quando o valor da varivel cont for igual a 10. Caso houvesse mais alguma outra instruo aps a
linha 8, dentro do bloco de instrues do for, ela no seria executada.
Cdigo fonte
break_interrompe.c
1

#include <stdio.h>

2
3
4

int main() {
int cont;

for (cont = 1; ; cont++) {


printf("Valor de cont: %i\n", cont);
if (cont == 10) break;
}

6
7
8
9
10

return 0;

11
12

3.4.6.2

Comando continue

O comando continue faz com que o fluxo de execuo salte para a avaliao da condio de
parada do lao, no caso do while e do-while, e para a expresso de incremento e decremento, no
caso do comando for. Isso significa que as instrues aps esse comando no so executadas.
Agora vamos analisar o programa continue_desvio.c [49] abaixo. Esse programa mostra na tela os
nmeros mpares no intervalo de 1 a 20. A varivel cont inicializada com o valor 1 no for.
Como a condio verdadeira, as instrues dentro do bloco so executadas. Agora ateno para o
comando if (linha 7). Na condio do if, h uma expresso cont % 2 == 0, o que significa
que se o resto da diviso inteira entre a varivel cont e 2 for 0, o comando continue executado.
Entretanto, o resto da diviso ser 1. Nesse caso, a a instruo da linha 8 executada, mostrando o
valor 1 na sada. Em seguida, a expresso de incremento do for avaliada, e cont passa a valer 2.
Como cont ainda menor ou igual a 20, as instrues do bloco so executadas novamente. Mais
uma vez, na linha 6, a condio do if avaliada. Todavia, o resto da diviso de cont e 2 agora
igual a 0, e ento a instruo continue executada. Com sua execuo, o fluxo de volta para o
for, e a expresso de incremento avaliada. Note que a instruo da linha 7, nesse caso, no ser
mais executada. O valor de cont ento incrementado para 3, repetindo o que foi explicado quando
cont era igual a 1.
Cdigo fonte
continue_desvio.c
1

#include <stdio.h>

2
3
4

int main() {
int cont;

5
6
7
8
9

for (cont = 1; cont <= 20; cont++) {


if (cont % 2 == 0) continue;
printf("Valor de cont: %i\n", cont);
}

10

49 / 92

Introduo Programao
return 0;

11
12

3.5

Recapitulando

Este captulo apresentou as estruturas de controle da linguagem C e como elas podem ser utilizadas.
A estrutura sequencial significa que o fluxo de execuo das instrues segue uma linha sequencial,
que no caso da linguagem C, de cima para baixo e da esquerda para a direita.Entretanto, podemos
mudar o fluxo de execuo desas instrues utilizando as estruturas de deciso e de repetio. No
caso da estrutura de deciso, aprendemos a utilizar os comandos if, else e switch para executar
uma instruo ou um bloco de instrues caso uma determinada condio seja verdadeira.
Aprendemos tambm a construir laos de repetio com os comandos while, do-while e for.
Vimos que todos esses comandos proporcionam a repetio de instrues at que uma determinada
condio seja falsa. Diante disso, importante ter bastante ateno na condio de parada dessas
estruturas de repetio, para no criar um lao infinito.
No prximo captulo estudaremos os arranjos: uma estrutura de dados que tem o objetivo de representar um conjunto de valores do mesmo tipo. Vamos tambm aprender a manipular as cadeias de
caracteres, tambm conhecidas como strings.

3.6

Exerccios Propostos

1. Escreva um programa que verifique se um nmero digitado pelo usurio menor, igual ou maior
que zero.
2. Dado o algoritmo abaixo, explique o que acontece se o valor lido para a varivel x for: 3, 1 e
0. Explique o porqu.
#include <stdio.h>
int main() {
int x;
scanf(&x);
if (x) printf("verdadeiro");
return 0;
}

3. Escreva um programa que informe se um dado ano ou no bissexto. Obs.: um ano bissexto
se ele for divisvel por 400 ou se ele for divisvel por 4 e no por 100.
4. Escreva um programa que mostre todos os nmeros pares no intervalo de 1 a 40 de forma
decrescente, utilizando o comando while. Depois faa o mesmo, mas desta vez, utilizando o
comando for.

50 / 92

Introduo Programao
5. Um determinado banco abriu uma linha de crdito para os funcionrios pblicos. Porm, o
valor mximo da prestao no poder ultrapassar 30% do salrio deste funcionrio. Faa um
programa para ajudar este banco. O programa deve permitir o usurio entrar com o salrio do
funcionrio e o valor da prestao e informar se o emprstimo pode ou no ser concedido.
6. Escreva um programa que leia o ms do ano em valor numrico e exiba este ms por extenso
(utilize o comando switch).
7. Faa trs programas que mostrem de 1 a 10 na tela, utilizando, em cada um, uma estrutura de
lao de repetio diferente.
8. Escreva um programa que mostre na tela os nmeros mltiplos de 3 no intervalo de 2 a 100.
9. Escreva um programa para ler dois nmeros inteiros M e N e, a seguir, imprimir os nmeros
pares existentes no intervalo [M, N].
10. A organizao de um evento esportivo deseja um programa que faa a leitura do nome e a
pontuao de cada um dos 10 participantes e exiba o nome do vencedor. Elabore este programa.
11. O supermercado Excelente Preo est precisando ser informatizado. Neste sentido, o dono quer
um programa que leia os preos dos produtos at que seja informado o valor zero. No final o
programa deve informar o total da compra e perguntar a forma de pagamento. As opes da
forma de pagamento so: 1) A vista; 2) No carto de crdito. Se a opo escolhida for a vista,
ento o programa informa o valor da compra com um desconto de 5%. Caso a compra seja no
carto de crdito, o programa informa o valor da compra dividido em 4 vezes.
Feedback sobre o captulo
Voc pode contribuir para melhoria dos nossos livros. Encontrou algum erro? Gostaria de
submeter uma sugesto ou crtica?
Para compreender melhor como feedbacks funcionam consulte o guia do curso.

51 / 92

Introduo Programao

Captulo 4
Arranjos
O BJETIVOS DO CAPTULO
Ao final deste captulo voc dever ser capaz de:
Apresentar os conceitos de vetores e matrizes
Apresentar o conceito de strings e como manipul-las

4.1

Introduo

At agora vimos que uma varivel armazena um nico valor por vez. Por exemplo, em um programa
para ler as notas de vrios alunos, cada nota armazenada em uma varivel, e assim que as notas de
um novo aluno so lidas, as notas do aluno anterior so perdidas. Em alguns problemas, necessrio
armazenar todos ou um conjunto de valores lidos sem que haja perda de informao. Nesse caso, seria
invivel declarar uma varivel distinta para armazenar cada valor, quando a quantidade de valores a
serem manipulados for relativamente grande. Para situaes como essas utilizamos Arranjos (em
ingls Arrays), que consistem em estruturas de dados capazes de agrupar em uma nica varivel
vrios elementos de um mesmo tipo. O conceito de Arranjos, bem como as diferentes formas de
utiliz-los sero discutidos em detalhes no decorrer deste captulo, que ainda apresentar as cadeias
de caracteres, conhecidas como strings.

4.2

Vetores

Os arranjos podem ter diferentes dimenses. Um tipo especial de arranjo com apenas uma dimenso
chamado de vetor. Portanto, vetores so arranjos unidimensionais que representam um conjunto
de variveis com o mesmo tipo, as quais so acessadas atravs de um ndice que as identificam. A
Figura 4.1 [52] ilustra o conceito de vetor, apresentando um vetor de inteiros com cinco elementos,
cada um com seu ndice correspondente. O ndice do primeiro elemento sempre zero.

Vetor

ndices

valores

0
4

1
2

2
7

3
9

Figura 4.1: Vetor com cinco elementos.


52 / 92

4
3

Introduo Programao

Nota
O conceito de arranjo nas diferentes linguagens de programao o mesmo. Entretanto, em
algumas linguagens alguns detalhes podem ser diferentes. Na linguagem C, por exemplo, o
ndice inicial sempre zero. J na linguagem Pascal, o ndice inicial definido pelo prprio
programador.

4.2.1

Declarao de Vetores

Na linguagem C, devemos declarar um vetor da seguinte forma:


tipo_vetor nome_vetor[quantidade_elementos];
O tipo_vetor o tipo de cada elemento do vetor. O nome_vetor o nome da varivel que ir
identificar o vetor. A quantidade_elementos representa a quantidade mxima de elementos
que o vetor poder armazenar. Observe que essa quantidade deve ficar entre colchetes. Os ndices
do vetor iro de zero at quantidade_elementos - 1. O compilador ir reservar o espao de
memria correspondente ao que o programador definiu em quantidade_elementos.
Vamos ver alguns exemplos de declaraes de vetores:
int idades[50];
char nomes[200];
float precos[30];
No exemplo acima temos trs declaraes de vetores diferentes. Na primeira linha temos a declarao
de um vetor chamado idades que ter no mximo 50 elementos do tipo int, com ndices de 0 a 49.
Na segunda linha temos um vetor chamado nomes com 200 elementos do tipo char, com ndices
de 0 a 199. Por fim, temos na ltima linha um vetor com identificador precos, com espao para
armazenar 30 elementos do tipo float, cujos ndices variam de 0 a 29.

4.2.2

Acessando os elementos de um vetor

Uma vez que um vetor foi declarado, poderemos armazenar e ler os valores dos elementos desse vetor.
Para isso, devemos identificar o elemento do vetor que queremos acessar atravs do nome do vetor
seguido do ndice do elemento entre colchetes. Observe o exemplo abaixo:
1
2
3
4
5
6

...
int main() {
int v[5], i;
for (i = 0 ; i < 5 ; i++)
scanf("%d", &v[i]);
...

Na linha 3, um vetor v de 5 elementos do tipo int declarado. Em seguida, temos um comando


for que ir se repetir 5 vezes, com a varivel i variando de 0 a 4. No corpo da estrutura de repetio,
na linha 5, ocorre a leitura de valores inteiros, na qual cada valor lido armazenado em um elemento
do vetor v com ndice igual ao valor da varivel i em cada iterao. Para um melhor entendimento,
considere a situao hipottica a seguir. Suponha que o usurio digitou os seguintes valores na leitura
de dados: 4, 3, 7, 2 e 9. Nesse caso, o vetor ficaria da seguinte forma aps a leitura dos valores:

53 / 92

Introduo Programao

Vetor v

v[0]
v[1]
v[2]
v[3]
v[4]

=
=
=
=
=

4
3
7
2
9

Figura 4.2: Configurao do vetor v aps a leitura dos valores.


Uma vez que os elementos de um vetor foram inicializados, isto , receberam algum valor atravs de
uma operao de escrita na memria, podemos acessar tais valores para diversos fins. Por exemplo,
podemos implementar um lao para percorrer todo o vetor e imprimir na tela os valores da cada um
de seus elementos. O trecho de cdigo a seguir ilustra como os elementos de um vetor so acessados
e mostra como um lao para percorrer um vetor pode ser implementado:
1
2
3
4
5
6
7

...
printf("%d", v[0]); //mostra o valor 4 na sada
printf("%d", v[2]); // mostra o valor 7 na sada
for (i = 0 ; i < 5 ; i++)
printf("%d ", v[i]); //mostra todos os valores
printf("%d", v[5]);
...

Na linha 2 estamos pedindo para ser mostrado o valor do elemento de ndice 0 do vetor v. Sendo
assim, o valor 4 mostrado na tela. Na linha 3, mostrado o valor do elemento de ndice 2 do
vetor v, cujo valor 7. J na linha 4 temos um lao de repetio que ir mostrar todos os valores
dos elementos do vetor v. Em seguida, na linha 6, estamos tentando acessar o elemento de ndice
5, que no existe. O programa ir compilar normalmente, entretanto, ocorrer um erro em tempo de
execuo assim que o programa tentar acessar o elemento inexistente do vetor.
Cuidado
Tenha cuidado ao acessar elementos de um vetor cujo ndice no existe. Caso isso acontea,
o programa ir compilar, entretanto, ocorrer um erro em tempo de execuo.

Vamos fazer um outro exemplo para fixar melhor o assunto. Digamos que queremos um programa
para ler 20 valores do tipo inteiro e que aps isso, sejam mostrados esses mesmos valores na ordem
inversa da qual foram lidos. O exemplo abaixo mostra a soluo do problema.
1
2
3
4
5
6
7
8

int main() {
int i, valores[20];
for (i = 0 ; i < 20 ; i++ ) //primeira etapa
scanf("%d", &valores[i]);
for (i = 19 ; i >= 0 ; i--) //segunda etapa
printf("%d ", valores[i]);
return 0;
}

Podemos dividir o problema em duas etapas. A primeira para montar um vetor com 20 valores
digitados pelo usurio. A segunda parte para mostrar os valores desse vetor na ordem inversa da
qual foram lidos. Inicialmente, declaramos o vetor ``valores` com 20 elementos do tipo int. Para
54 / 92

Introduo Programao
resolver cada etapa do problema, utilizamos um lao de repetio com o comando for. Na linha
3, o lao for utilizado para ler os valores, cada um sendo armazenado em um elemento do vetor.
Na linha 5, temos um outro lao for, cuja varivel de controle i inicializada com o valor 19, que
representa o ndice do ltimo elemento do vetor. A condio de parada do lao que a varivel i
seja maior ou igual a zero e a ltima expresso do for o decremento da varivel i. Isso significa
que o valor da varivel i ir de 19 a 0 dentro do lao de repetio. Consequentemente, os valores dos
elementos do vetor valores iro ser mostrados na ordem inversa da que foram lidos.

4.2.3

Exerccio resolvido

ER 4.1
Escreva um programa que leia 20 notas de alunos de uma turma. O programa deve calcular a
mdia da turma e apresentar na tela apenas as notas dos alunos que ficaram acima da mdia
calculada.
Resposta
A primeira etapa para resolver esse problema analisar se precisamos realmente utilizar um
arranjo. Mas antes disso, vamos tentar dividir o problema em subproblemas menores para
facilitar a elaborao da soluo.
Subproblema
Subproblema 1
Subproblema 2
Subproblema 3

Descrio
Ler 20 notas de uma turma
Calcular a mdia da turma considerando as 20 notas lidas
Apresentar na tela as notas da turma que esto acima da mdia
calculada

O primeiro subproblema ler 20 notas dos alunos. A princpio conseguiramos ler as 20 notas utilizando um lao de repetio e apenas uma varivel. Entretanto, se utilizarmos apenas uma varivel
para ler as notas, s teremos a ltima nota armazenada ao final do lao. Como precisamos de todas
as notas para saber quais delas esto acima da mdia calculada, a soluo do subproblema 3 requer
que um vetor seja utilizado ao invs de apenas uma varivel. Resolveremos, a partir de agora, a questo gradativamente a partir das solues dos subproblemas. Vejamos o trecho de cdigo abaixo que
resolve o subproblema 1 da questo.
1

int main() {

float nota[20];
int i;

3
4
5

for (i = 0 ; i < 20 ; i++ )


scanf("%f", &nota[i]);

6
7
8

...

Como foi explicado, precisaremos de um vetor para armazenar todas as notas da turma. Portanto, na
linha 3 declaramos um vetor de float chamado notas com 20 elementos. Utilizamos a estrutura
de repetio for para ler as 20 notas passadas como entrada para o programa (linha 6 e 7).
O subproblema 2 consiste em calcular a mdia das 20 notas lidas. Para isso, precisamos primeiramente somar todas as notas lidas. Uma vez que temos essas notas armazenadas em um vetor, poderamos resolver esse subproblema de duas maneiras. Uma delas criar, aps o lao de leitura das notas,
55 / 92

Introduo Programao
um outro lao para acessar os elementos do vetor para realizar a soma das notas. A segunda forma,
mais interessante, somar as notas medida que forem lidas, no mesmo lao de repetio. Dessa
forma, teremos apenas um lao de repetio, tornando nosso cdigo mais eficiente. Verifiquemos
como ficou o trecho de cdigo anterior com a incluso da soluo para o subproblema 2.
1

int main() {

float nota[20], media, soma = 0;


int i;

3
4
5

for (i = 0 ; i < 20 ; i++ ) {


scanf("%f", &nota[i]);
soma += nota[i];
}

6
7
8
9
10

media = soma / 20;

11
12

...

Perceba que inclumos na declarao as variveis media e soma, para armazenar, respectivamente,
os valores da mdia e da soma das notas. Verifique tambm, na linha 8, que a soma das notas
realizada medida que cada nota lida. O clculo da mdia, na linha 11, s pode ser feita depois que
todas as notas forem lidas e acumuladas na varivel soma. Desse modo, ela deve ficar fora do lao.
O subproblema 3 consiste em apresentar na tela as notas da turma que ficaram acima da mdia.
Uma vez que j temos a mdia calculada, podemos resolver facilmente esse problema. Para tanto,
precisamos percorrer todo o vetor e comparar cada elemento deste com a mdia. Caso o valor do
elemento seja maior que a mdia, ele deve ser apresentado na tela. A verso final do programa est
descrita abaixo:
1
2
3

int main() {
float nota[20], media, soma = 0;
int i;

for (i = 0 ; i < 20 ; i++) {


scanf("%f", &nota[i]);
soma += nota[i];
}

5
6
7
8
9

media = soma / 20;

10
11

for (i = 0 ; i < 20 ; i++)


if (nota[i] > media)
printf("%f ", nota[i]);

12
13
14
15

return 0;

16
17

As linhas 12 a 14 resolvem o subproblema 3, utilizando o comando for para percorrer todo o vetor
de notas e comparar cada elemento com a mdia. Para realizar tal comparao, utilizamos o comando
if. Caso o elemento nota[i] seja maior que a mdia, ele ser exibido na tela.

56 / 92

Introduo Programao

4.3

Strings

Na maioria dos programas que implementamos, precisamos lidar com cadeias de caracteres no processamento e armazenamento das informaes que nos so fornecidas. Nas linguagens de programao,
essas cadeias so chamadas de strings. Como no h, na linguagem C, um tipo de dados especfico
para representar as strings, utilizamos vetores de elementos do tipo char para a manipulao de cadeias de caracteres. Em outras palavras, quando queremos declarar uma varivel para armazenar uma
cadeia de caracteres, declaramos um vetor do tipo char.
No exemplo abaixo, temos a declarao de trs strings: nome, logradouro e bairro. Perceba
que cada string um array de char. Significa dizer que a string nome tem a capacidade de
armazenar 60 caracteres, a string logradouro 200 caracteres e a string bairro 40 caracteres.
char nome[60];
char logradouro[200];
char bairro[40];
Na linguagem C, toda string tem um caractere especial que determina o seu fim. Esse caractere
o \0, que significa NULO, e ele inserido automaticamente pelo compilador no ltimo elemento
do vetor de elementos do tipo char. Por essa razo, deve-se levar isso em considerao na hora de
declarar suas strings. Assim sendo, se voc deseja que uma string armazene N caracteres, voc deve
declar-la com um tamanho N+1.

4.3.1

Lendo e imprimindo Strings

Para ler e imprimir strings na linguagem C, podemos utilizar as funes scanf() e printf() que
j conhecemos. Entretanto, como muitas vezes precisamos manipular strings no nosso programa, as
linguagens de programao possuem funes pr-definidas para serem utilizadas pelo programador,
facilitando a manipulao das cadeias de caracteres. A linguagem C, por exemplo, possui as funes gets() e puts(), elaboradas especialmente para ler e imprimir strings, respectivamente.
Vejamos um exemplo.
1

int main() {

char s[7];

3
4

gets(s);
puts(s);

5
6
7

printf("%c", s[4]);
printf("%c", s[2]);

8
9
10

return 0;

11
12

Na linha 3, declaramos uma string s que armazena 6 caracteres (alm do caractere NULO). Em
seguida, utilizamos a funo gets(),que faz a leitura de uma string, esperando que o usurio a
digite e tecle ENTER. Na linha 6, utilizamos a funo puts(), que imprime na sada padro a string
s lida. Digamos que o usurio digite a string BRASIL. Dessa forma, a cadeia de caracteres ser
armazenada na memria da seguinte forma:

57 / 92

Introduo Programao

Vetor

ndices

valores

0
B

1 2 3
R A S

4
I

5 6
L \0

Figura 4.3: Cadeia de caracteres.


Como uma string em C trata-se na verdade de um vetor de caracteres, podemos acess-los individualmente do mesmo modo que acessamos os elementos de um vetor qualquer. Ao serem executadas
as linhas 8 e 9 do cdigo anterior, por exemplo, so exibidos na sada padro os caracteres I e A,
respectivamente.

4.3.2

Manipulando strings

Existem ainda outras funes interessantes para manipular strings na linguagem C. A tabela abaixo
apresenta algumas dessas funes, todas presentes na biblioteca string.h.
Funo
strlen(s)
strcpy(s1, s2)
strcat(s1, s2)
strchr(s, c)

Descrio
Retorna a quantidade de caracteres da string s
Copia o contedo da string s2 para s1
Concatena (junta) o contedo da string s2 em s1
Retorna a posio (inteiro) do caractere c na string s

Para entender melhor o uso destas funes, considere o exemplo a seguir.


Cdigo fonte
manipulacao_string.c
1

#include <stdio.h>

2
3
4

int main() {
char str1[100], str2[100];

gets(str1);
gets(str2);

6
7
8

printf("%d", strlen(str1));
printf("%d", strlen(str2));

9
10
11

strcat(str1, str2);
printf("%d", strlen(str1));

12
13
14

return 0;

15
16

Inicialmente declaramos duas strings: str1 e str2. Nas linhas 6 e 7, utilizamos o comando
gets() para que o usurio informe as duas strings que sero armazenadas nas variveis mencionadas. As linhas 9 e 10 imprimem os tamanhos das strings str1 e str2, enquanto que a linha 12
responsvel por concatenar as strings str2 e str1, ou seja, str1 passa a ter o contedo ante-

58 / 92

Introduo Programao
rior com a adio do contedo de str2. Por fim, a linha 13 exibe o tamanho de str1 aps a sua
concatenao com str2.

4.3.3

Exerccio resolvido

ER 4.2
Escreva um programa que leia uma string e substitua todos os espaos por um trao (caractere
-).
Resposta
Primeiramente, declaramos uma string s com capacidade para armazenar 40 caracteres e utilizamos a funo gets(), na linha 5, a fim de que o usurio digite uma string. Tendo a string
digitada armazenada na varivel s, podemos agora manipul-la. Para resolver essa questo,
importante ter entendido o conceito de que uma string um vetor de caracteres. Na linha 7,
utilizamos um for para percorrer os elementos da string. Veja que a condio de parada do
comando for i < strlen(s). Isso significa que o bloco de instrues ser repetido at
o final da string, uma vez que strlen() retorna a quantidade de caracteres de uma string.
Dentro do for, verificamos se o caractere da posio i igual a um espao. Caso seja, esse
elemento do array recebe o caractere -. Finalmente, depois do comando for, utilizamos a
funo puts() para imprimir a nova string com os espaos trocados por -.
Cdigo fonte
resolvido4-2.c
1
2
3

int main() {
char s[40];
int i;

gets(s);

5
6

for (i=0; i < strlen(s); i++) {


if (s[i] == )
s[i] = -;
}

7
8
9
10
11

puts(s);

12
13

return 0;

14
15

4.4

Matrizes

Como foi dito no incio do captulo, arranjos podem ter vrias dimenses. Quando possuem mais
de uma dimenso, eles so chamados de matrizes. O conceito de matrizes em programao bem
semelhante ao homnimo da matemtica. A figura a seguir apresenta o formato de uma matriz m x n,
onde m representa o nmero de linhas e n o nmero de colunas.

59 / 92

Introduo Programao

[ ]
a1,1 a1,2 a1,3 ... a1,n
a2,1 a2,2 a2,3 ... a2,n
a3,1 a3,2 a 3,3 ... a3,n

Linha

am,1 am,2 am,3 ... am,n


Coluna

Figura 4.4: Matriz M x N


Analisemos os exemplos abaixo. A primeira matriz 3 x 3, pois possui 3 linhas e 3 colunas. A
segunda matriz 2 x 3, pois possui 2 linhas e 3 colunas. Se quisermos saber o elemento da primeira
matriz que possui ndice A2,3 , basta seguirmos em direo 2 linha e depois em direo 3 coluna.
Logo o valor de A2,3 1.

[
4
8
9

2
0
1

[
]
]
5
9

3
1
6

1
2

0
1

Matriz 2x3

Matriz 3x3

Figura 4.5: 4.5. Exemplos de matrizes


Podemos representar essas matrizes na linguagem C acrescentando mais um ndice entre colchetes no
identificador do arranjo. Abaixo temos alguns exemplos de como declaramos matrizes:
int matriz[3][3];
int outra_matriz[2][3];
float matriz_de_float[30][20];
char nomes[10][50];
Na primeira linha temos a declarao de uma matriz de inteiros com 3 linhas e 3 colunas, na segunda
novamente uma matriz de inteiros, s que agora com 2 linhas e 3 colunas, e na terceira uma matriz
de elementos do tipo float com 30 linhas e 20 colunas. Agora ateno para ltima linha. Trata-se
da declarao de um arranjo de strings. Lembre-se que uma string um arranjo de caracteres. Se
declararmos uma matriz de char, ento teremos na prtica um vetor de strings, onde cada linha da
matriz uma cadeia de caracteres.
J sabemos como declarar matrizes, agora aprenderemos a mont-las a partir da leitura de dados da
entrada padro. Para isso, precisaremos utilizar dois comandos for aninhados. Considere o exemplo
abaixo:
Cdigo fonte
matriz_populando.c
1
2
3

int main() {
int matriz[20][30];
int i, j;
60 / 92

Introduo Programao

for (i=0; i < 20; i++)


for (j = 0; j < 30; j++)
scanf("%d", &matriz[i][j]);

5
6
7
8

return 0;

9
10

Na linha 2, temos uma declarao de uma matriz 20 x 30. Se quisermos pedir para o usurio digitar os
valores da matriz, precisaremos utilizar um for para percorrer as linhas e um for para percorrer as
colunas da matriz. Portanto, na linha 5, temos o primeiro for onde i ir variar de 0 a 19, justamente
os ndices que representam a posio dos elementos nas linhas da matriz. Na linha 6, temos um outro
for dentro do primeiro, onde j ir variar de 0 a 29, que so justamente os ndices que representam
a posio dos elementos nas colunas da matriz. Perceba que quando i = 0, j ir variar de 0 a
29. Depois i passa a valer 1 e novamente o j ir variar de 0 a 29 novamente. Isso acontecer
repetidamente at i atingir o valor 19. Em suma, o cdigo anterior preenche os elementos da matriz
linha por linha. Inicia preenchendo a linha de ndice 0, em seguida preenche a linha de ndice 1,
seguindo de forma sucessiva at que a linha de ndice 19 seja preenchida.

4.5

Recapitulando

Como vimos neste captulo, arranjos consistem em um conjunto de elementos do mesmo tipo, que
podem ter diferentes dimenses e so acessados por um ndice. Os arranjos de uma dimenso so
chamados de vetores e quando possuem mais de duas dimenses so chamados de matrizes.
Aprendemos tambm que strings so cadeias (arranjos) de caracteres, ou seja, um vetor de elementos
do tipo char. Devido sua importncia para a programao de computadores, as linguagens de
programao disponibilizam um conjunto de funes para facilitar sua manipulao. Algumas das
funes mais utilizadas na linguagem C foram conhecidas neste captulo, contudo, deve ficar claro ao
leitor que existe um nmero bem maior de funes com tal objetivo.

4.6

Exerccios Propostos

1. Crie um programa que armazene nmeros em dois vetores inteiros de cinco elementos cada,
depois gere e imprima o vetor soma dos dois.
2. Crie um programa que armazene 10 nmeros em um vetor A, e gere um vetor B onde cada
elemento o quadrado do elemento de A.
Exemplo:
A[1] = 4
A[2] = 3
A[3] = 6

B[1] = 16
B[2] = 9
B[3] = 36

3. Escreva um programa para ler uma string qualquer e exiba as seguintes informaes: quantidade
de caracteres, primeira e ltima letra.
4. Escreva um programa para ler uma frase de no mximo 70 caracteres e exibir a quantidade de
vogais dessa frase.
61 / 92

Introduo Programao
5. Escreva um programa que leia uma string qualquer e mostre-a invertida.
Exemplo:
Entrada: casa <ENTER>
Sada: asac
6. Um palndromo uma cadeia de caracteres que representa a mesma palavra nos sentidos direto
e inverso. Por exemplo, asa um palndromo, porque o inverso dela tambm asa. Faa
um programa que leia uma string e diga se esta ou no um palndromo.
7. Escreva um programa para ler 9 nmeros inteiros para preencher uma matriz D 3x3, ou seja,
com 3 linhas e 3 colunas (considere que no sero informados valores duplicados). A seguir,
ler um nmero inteiro X e escrever uma mensagem indicando se o valor de X existe ou no na
matriz D.
Feedback sobre o captulo
Voc pode contribuir para melhoria dos nossos livros. Encontrou algum erro? Gostaria de
submeter uma sugesto ou crtica?
Para compreender melhor como feedbacks funcionam consulte o guia do curso.

62 / 92

Introduo Programao

Captulo 5
Funes
O BJETIVOS DO CAPTULO
Ao final deste captulo voc dever ser capaz de:

Criar e usar funes e procedimentos em C


Identificar quando escrever uma funo ou um procedimento
Entender as regras de escopo para variveis em C
Entender os diferentes tipos de passagem de parmetro e quando utiliz-los
Trabalhar com funes recursivas

Quando elaboramos um algoritmo para resolver um problema, e quando escrevemos um programa


para implementar este algoritmo, muitas vezes identificamos uma parte do algoritmo que deve ser
realizada vrias vezes para chegar ao resultado. Ou, ao trabalhar com vrios algoritmos diferentes,
identificamos algumas partes em comum entre eles. Nestes casos, uma boa ideia isolar essas partes
que se repetem, de maneira que elas possam ser realizadas sem repetir o mesmo cdigo vrias vezes.
Esse objetivo pode ser atingido com o uso de funes e procedimentos.
Neste captulo, vamos estudar as funes e procedimentos como uma forma de reaproveitar o cdigo
de tarefas que se repetem em um programa. Funes so importantes para a modularizao de um
programa, ou seja, para dividir o programa em partes menores, cada parte com uma funo especfica;
sem funes ou procedimentos, um programa maior e mais complicado ficaria organizado em uma
nica parte que faz tudo e mais difcil de entender. Neste captulo, vamos entender quando utilizar
as funes ou procedimentos para melhor dividir o cdigo dos nossos programas.
Importante
Neste captulo, vamos descartar a utilizao de pseudocdigo. Agora que voc j possui
um conhecimento bsico sobre a linguagem C e, provavelmente, escreveu alguns programas
nela, consideramos que no haver mais necessidade de apresentar sintaxes para pseudocdigos. Portanto, deste captulo em diante, o contedo apresentadao utilizar somente a
sintaxe da linguagem C.

5.1

O que so funes?

Funes e procedimentos podem ser compreendidos como trechos reutilizveis de cdigo. Uma funo ou procedimento pode, ento, ser utilizado vrias vezes por um mesmo programa. Isso simplifica
63 / 92

Introduo Programao
a criao de programas maiores, dividindo-os em unidades menores que trabalham em conjunto. Funes e procedimentos so bastante semelhantes e, posteriormente, vamos entender as diferenas entre
eles.
Reviso
Lembre-se que durante o curso voc j utilizou funes diversas vezes, o que ns sabemos
sobre funes at agora?
Uma funo implementa um comportamento que pode ser reutilizado;
Para executar uma funo, utilizamos o nome da funo e passamos alguns parmetros
entre parnteses e separados por vrgula. Exemplo: printf("R$ %1.2f", preco);
A funo printf utilizada para imprimir texto na sada;
As funes scanf e getchar para ler dados da entrada;
As funes strlen, strcpy, strcat e strchr so utilizadas para manipular strings;
As funes so agrupadas em mdulos. Exemplo: stdio;

Quando realizamos um processo com um determinado objetivo, comum identificarmos partes que se
repetem. Quando se trata de processos no mundo fsico, muitas vezes criamos mquinas que ajudam
a realizar as partes que se repetem.
Por exemplo, pense no processo de limpar as roupas que usamos para podermos us-las novamente.
Este processo envolve lavar as roupas com gua e sabo, secar as roupas lavadas e, finalmente, passar
as roupas para evitar que fiquem amassadas. Para reduzir a quantidade de trabalho necessria para
realizar esse processo, foi inventada uma mquina de lavar, que realiza a lavagem das roupas. Uma
pessoa que tem uma mquina de lavar pode us-la repetidamente e, sempre que precisa de roupas
limpas, precisa apenas se encarregar de enxugar e passar as roupas; a lavagem fica por conta da
mquina. Dizemos inclusive que a funo da mquina lavar as roupas.
As funes e os procedimentos funcionam desta forma, capturando partes menores de um algoritmo
que podem ser utilizadas por outros algoritmos, economizando o trabalho de sempre refazer uma
determinada tarefa.

5.1.1

Um exemplo

Vejamos um exemplo. Queremos criar um programa que calcule a mdia final de um aluno em uma
disciplina com trs provas; o programa deve pedir ao usurio que entre com as notas das trs provas,
calcular a mdia aritmtica das trs notas e apresentar o resultado. O programador que resolveu o
problema decidiu imprimir um separador na tela entre cada entrada de dados e o resultado final, desta
forma, produzindo o seguinte cdigo:
Cdigo fonte
Clculo da mdia de um aluno em uma disciplina
1

#include <stdio.h>

2
3
4

int main () {
float nota1, nota2, nota3, media;
64 / 92

Introduo Programao

printf("Entre a nota da primeira prova: ");


scanf("%f", &nota1);

6
7
8

printf("\n");
// 1x
printf("=============================================\n"); // 2x
printf("\n");
// 3x

9
10
11
12

printf("Entre a nota da segunda prova: ");


scanf("%f", &nota2);

13
14
15

printf("\n");
printf("=============================================\n");
printf("\n");

16
17
18
19

printf("Entre a nota da terceira prova: ");


scanf("%f", &nota3);

20
21
22

printf("\n");
printf("=============================================\n");
printf("\n");

23
24
25
26

media = (nota1 + nota2 + nota3) / 3.0;


printf("Media: %f\n", media);

27
28
29

return 0;

30
31

}
x, 2x, 3x Cdigo

que imprime um separador na tela.

Resultado da execuo do programa


Entre a nota da primeira prova: 7.0
=============================================
Entre a nota da segunda prova: 8.0
=============================================
Entre a nota da terceira prova: 9.6
=============================================
Media: 8.200000
fcil de notar que o cdigo usado para imprimir um separador se repete trs vezes no programa. Podemos melhorar esse programa utilizando um procedimento que ter a tarefa de imprimir o separador.
Isso teria o seguinte resultado:
Cdigo fonte
Clculo da mdia usando procedimento
65 / 92

Introduo Programao

1
2
3
4
5
6
7

#include <stdio.h>
void imprime_separador() {
// 1x
printf("\n");
// 2x
printf("=============================================\n"); // 3x
printf("\n");
// 4x
}

8
9
10

int main () {
float nota1, nota2, nota3, media;

11

printf("Entre a nota da primeira prova: ");


scanf("%f", &nota1);

12
13
14

imprime_separador();

15

// 5x

16

printf("Entre a nota da segunda prova: ");


scanf("%f", &nota2);

17
18
19

imprime_separador();

20
21

printf("Entre a nota da terceira prova: ");


scanf("%f", &nota3);

22
23
24

imprime_separador();

25
26

media = (nota1 + nota2 + nota3) / 3.0;


printf("Media: %f\n", media);

27
28
29

return 0;

30
31

Definio do procedimento imprime_separador.

x, 3x, 4x Cdigo

no corpo do procedimento.

Chamada do procedimento imprime_separador.

A linha void imprime_separador() inicia a definio do procedimento chamado


imprime_separador; o corpo do procedimento o conjunto de comandos entre chaves que
vem logo aps o nome do procedimento. Os parnteses e a palavra void no incio sero explicados
depois. Dizemos que o uso de um procedimento uma chamada ao mesmo. No exemplo anterior, o
cdigo do programa chama imprime_separador trs vezes.
importante notar que alm de economizar a repetio de linhas de cdigo, o programa usando o
procedimento imprime_separador tambm mais fcil de entender porque transmite melhor as
partes que compem o programa. A melhor modularizao do cdigo do programa um motivo extremamente importante para usar funes e procedimentos, principalmente medida que os programas
se tornam maiores e mais complexos.

66 / 92

Introduo Programao

5.2

Parmetros

O exemplo usando imprime_separador o caso mais simples, mas menos interessante do uso
de procedimentos e funes, quando o cdigo a ser reutilizado sempre o mesmo. Na maioria das
situaes de interesse, queremos utilizar uma funo ou procedimento em situaes com algumas
diferenas. Para tornar um procedimento (ou funo) mais flexvel, preciso que informaes sejam
passadas para o procedimento. Isso feito com o uso de parmetros.
J vimos muitas vezes o uso de procedimentos com parmetros. Por exemplo, printf um procedimento da biblioteca padro da linguagem C que imprime a string passada como parmetro. Assim,
printf("ola, mundo!");
uma chamada ao procedimento printf com parmetro "ola, mundo!".
Como exemplo do uso de parmetros em um procedimento, voltemos ao exemplo do clculo das
mdias. Vamos utilizar o separador para fazer uma visualizao simples das notas e da mdia, imprimindo uma barra de tamanho proporcional a cada valor.
Cdigo fonte
Uso de um procedimento com parmetro
1
2
3
4
5
6
7
8
9
10
11
12

#include <stdio.h>
#include <math.h>
void imprime_separador(float nota) {
// 1x
int i;
printf("\n");
for (i = 0; i < (int) lround(nota * 5.0); i++) {
printf("=");
}
printf(" %3.2f / 10.0\n", nota);
printf("\n");
}

13
14
15

int main () {
float nota1, nota2, nota3, media;

16
17
18

printf("Entre a nota da primeira prova: ");


scanf("%f", &nota1);

19
20

imprime_separador(nota1);

// 2x

21
22
23

printf("Entre a nota da segunda prova: ");


scanf("%f", &nota2);

24
25

imprime_separador(nota2);

26
27
28

printf("Entre a nota da terceira prova: ");


scanf("%f", &nota3);

29
30

imprime_separador(nota3);

31
32

media = (nota1 + nota2 + nota3) / 3.0;


67 / 92

Introduo Programao
printf("Media: %3.2f\n", media);

33
34

imprime_separador(media);

35
36

return 0;

37
38

}
x

Definio do procedimento imprime_separador, com o parmetro nota, do tipo float.

Chamada do procedimento imprime_separador, passando o argumento nota1.

Resultado da execuo do programa code/cap5/media_param.c


Entre a nota da primeira prova: 6.2
=============================== 6.20 / 10.0
Entre a nota da segunda prova: 7.8
======================================= 7.80 / 10.0
Entre a nota da terceira prova: 9.2
============================================== 9.20 / 10.0
Media: 7.73
======================================= 7.73 / 10.0
Como se pode ver no resultado da execuo do programa, o novo procedimento
imprime_separador imprime uma barra de tamanho proporcional nota passada como
argumento (so 5 caracteres = para cada ponto da nota). Note a diferena de nomenclatura: o
procedimento imprime_separador definido com um parmetro de nome nota, mas
chamado com um argumento, o valor que comunicado ao procedimento. No exemplo acima,
imprime_separador chamado com os argumentos nota, nota2, nota3 e media.
necessrio especificar o tipo de cada parmetro que deve ser passado para o procedimento; no caso,
o parmetro nota do procedimento imprime_separador do tipo float.
Na chamada de um procedimento com um parmetro, o controle do programa executa o cdigo do
procedimento, atribuindo o valor passado como argumento varivel nota dentro do procedimento
imprime_separador. Ou seja, o seguinte cdigo
int main() {
float nota1;
printf("Entre a nota da primeira prova: ");
scanf("%f", &nota1);
imprime_separador(nota1);
// resto do programa ...
}
68 / 92

Introduo Programao
funciona como se fosse o seguinte (utilizando o procedimento):
int main() {
float nota1;
printf("Entre a nota da primeira prova: ");
scanf("%f", &nota1);
float nota = nota1;
// 1x
int i;
// 2x
printf("\n");
for (i = 0; i < (int) lround(nota * 5.0); i++) {
printf("=");
}
printf(" %3.2f / 10.0\n", nota);
printf("\n");
// resto do programa ...
}
x

Atribuio do valor do argumento nota1 para o parmetro nota.

Resto do corpo do procedimento imprime_separador.

Este exemplo apenas uma ilustrao; na prtica, o chamado do procedimento no funciona exatamente desta forma. Em particular, a varivel nota, que designa o parmetro do procedimento, s
existe enquanto o procedimento executa. Isso ser detalhado mais tarde.
O uso de parmetros nos procedimentos os tornam muito mais flexveis para uso em diferentes situaes. Mas assim como til que o cdigo que chama o procedimento comunique informaes para
o procedimento chamado, muitas vezes tambm til que o procedimento comunique algo de volta
para o cdigo que o chamou; neste caso, passamos dos procedimentos para as funes.

5.3

Retorno de Valores com Funes

At agora s temos usado procedimentos como ferramenta de modularizao do cdigo, mas muitas
vezes til chamar um procedimento que retorna alguma informao de volta para o cdigo que o
chamou. Esta a diferena entre procedimentos e funes: as funes retornam algum valor. Desta
forma, as funes em linguagem C so similares s funes da matemtica: uma funo como
f : Z Z,

f (x) = x2 + 2

tem um parmetro x (um inteiro), e retorna um determinado valor que depende do parmetro passado;
por exemplo,
f (5) = 52 + 2 = 27
fcil escrever a mesma funo em linguagem C:
int f(int x) {
return x * x + 2;
}

// 1x
// 2x

69 / 92

Introduo Programao
x

Definio da funo f. A definio comea com int f(...), significando que o tipo de
retorno da funo int.
A palavra-chave return determina o valor de retorno da funo f, que ser o resultado da
expresso x * x + 2.

A funo f do exemplo faz o mesmo que a verso matemtica: dado o valor do parmetro x, retorna
um valor que igual a x ao quadrado, somado a dois. Note que preciso especificar o tipo do valor
que retornado pela funo e, por isso, toda funo comea com o tipo de retorno antes do nome.
Especificar os tipos dos parmetros e o tipo do valor de retorno tambm similar s funes na
matemtica, para as quais devemos especificar os conjuntos domnio e contra-domnio.

5.3.1

Funes, Procedimentos e o Tipo void

Neste ponto pode surgir uma pergunta: se preciso especificar o tipo do valor retornado por uma
funo antes do nome da funo (por exemplo int f(...)), por que nos procedimentos usa-se a
palavra-chave void?
A verdade que, embora algumas linguagens de programao faam uma distino entre procedimentos e funes, na linguagem C existem apenas funes. Como a diferena entre procedimentos e
funes apenas o fato de retornar ou no um valor, os procedimentos em C so considerados funes
que retornam um valor vazio. isso que significa o void no incio da definio de um procedimento
como imprime_separador, que vimos anteriormente; a rigor, imprime_separador uma
funo, mas retorna um valor vazio, ou seja, nenhum valor. O tipo void na linguagem C um tipo
especial que denota a ausncia de valores.
Como procedimentos em C so funes, tambm possvel usar return em procedimentos, mas
apenas para terminar sua execuo e retornar imediatamente. Isso s vezes til para terminar um
procedimento em pontos diferentes do seu final. Tambm pode-se utilizar return ao final do procedimento, mas este uso suprfluo e no recomendado.
O seguinte exemplo demonstra o uso do return em procedimentos. Continuando no tema relacionado ao clculo de mdias, queremos detectar se uma das notas entradas pelo usurio uma nota
invlida antes de fazer o clculo da mdia. Neste caso, o programa deve apenas imprimir se algum
valor negativo foi entrado pelo usurio. O procedimento possui_negativo ser responsvel por
imprimir uma mensagem caso um dos valores seja negativo.
Cdigo fonte
Uso de return em um procedimento
1

#include <stdio.h>

2
3
4
5
6
7

void possui_negativo(float n1, float n2, float n3) {


if (n1 < 0.0) {
printf("Numero negativo encontrado!\n");
return;
// 1x
}

8
9
10
11
12

if (n2 < 0.0) {


printf("Numero negativo encontrado!\n");
return;
}
70 / 92

Introduo Programao

13

if (n3 < 0.0) {


printf("Numero negativo encontrado!\n");
return;
}

14
15
16
17
18

printf("Nenhum numero negativo encontrado\n");

19
20

// 2x

21
22
23

int main() {
float nota1, nota2, nota3;

24

printf("Entre as trs notas, separadas por espacos: ");


scanf("%f %f %f", &nota1, &nota2, &nota3);

25
26
27

possui_negativo(nota1, nota2, nota3);

28
29

printf("Media: %f\n", (nota1 + nota2 + nota3) / 3.0);

30
31

return 0;

32
33

Uso do return para sair prematuramente do procedimento.


Este comando de impresso ser executado se nenhuma das condies testadas em
possui_negativo for verdade, ou seja, se nenhum dos valores dos parmetros for negativo.

Resultado de duas execues do programa code/cap5/retorno_proc.c


Entre as trs notas, separadas por espacos: 4.5 5.6 8.9
Nenhum numero negativo encontrado
Media: 6.333333
Entre as trs notas, separadas por espacos: 4.5 -6.7 9.9
Numero negativo encontrado!
Media: 2.566667
O procedimento possui_negativo deve verificar se um dos trs nmeros passados como argumentos, mas basta achar um nmero entre eles para que o resultado possa ser impresso imediatamente
e o procedimento pode retornar; por isso, usamos return assim que o primeiro valor negativo encontrado.
Esse exemplo ainda tem um problema: como pode ser visto nos exemplos de execuo, mesmo que
o usurio entre um valor negativo, a mdia aritmtica das trs notas ainda impressa na tela (o
usurio apenas avisado que um dos valores foi negativo). Isso uma indicao que seria melhor que
possui_negativo fosse uma funo, e que o programa principal verificasse o valor retornado e
tomasse uma deciso. Se fizermos essas alteraes ficamos com o seguinte programa:
Cdigo fonte
Reescrevendo o exemplo anterior para usar uma funo
71 / 92

Introduo Programao

#include <stdio.h>

2
3
4
5

int possui_negativo(float n1, float n2, float n3) {


if (n1 < 0.0 || n2 < 0.0 || n3 < 0.0) // 2x
return 1; // 3x

return 0;

7
8

// 1x

// 4x

9
10
11

int main() {
float nota1, nota2, nota3;

12

printf("Entre as trs notas, separadas por espacos: ");


scanf("%f %f %f", &nota1, &nota2, &nota3);

13
14
15

if (possui_negativo(nota1, nota2, nota3) == 1)


// 5x
printf("Nao e possivel calcular a media, uma ou mais notas
sao negativas\n");
else
printf("Media: %f\n", (nota1 + nota2 + nota3) / 3.0);

16
17

18
19

20

return 0;

21
22

A funo possui_negativo agora retorna um inteiro de valor 1 caso um dos valores dos
parmetros seja negativo, e 0 caso contrrio (todos so positivos).

Teste para identificar se um ou mais dos parmetros informados so negativos.

A funo retorna 1 se um dos nmeros passados para a funo for negativo.

Caso nenhum dos nmeros seja negativo, o controle passa para o comando return ao final da
funo e o valor 0 retornado para indicar que nenhum nmero negativo foi encontrado.
O programa principal verifica o valor de retorno da funo possui_negativo e imprime
informaes adequadas na tela para cada caso.

Resultado de duas execues do programa code/cap5/retorno_func.c


Entre as trs notas, separadas por espacos: 6.8 9.7 -2.3
Nao e possivel calcular a media, uma ou mais notas sao negativas
Entre as trs notas, separadas por espacos: 6.8 9.7 7.2
Media: 7.900000
Como pode-se ver nos dois exemplos de execuo do programa, a sada agora mais adequada.
Caso uma das notas informadas seja negativa, o programa no imprime um valor de mdia, apenas
avisando o usurio do erro na entrada de dados. O cdigo da funo possui_negativo tambm
foi simplificado pelo uso do operador lgico OU.

72 / 92

Introduo Programao
Como funes e procedimentos so tratados de maneira uniforme na linguagem C (e em muitas
outras linguagens atuais), a partir de agora vamos usar o termo funo tanto para funes como
para procedimentos. Isso no deve gerar nenhuma confuso. Em caso de dvida, basta olhar para a
definio da funo no cdigo-fonte do programa; se a funo for declarada com o tipo de retorno
void, ento um procedimento.

5.4

Um Exemplo Matemtico: Equao de Segundo Grau

Nesta seo, veremos mais um exemplo do uso de funes em um programa para calcular as razes
de uma equao de segundo grau. Neste exemplo, as funes no sero utilizadas vrias vezes, mas o
programa principal ser mais claro e mais fcil de entender graas melhor modularizao conseguida
com o uso das funes.
Lembremos que um polinmio de segundo grau uma soma de trs termos em potncias de uma
varivel, por exemplo
P(x) = ax2 + bx + c
onde a, b e c so coeficientes constantes. Uma equao de segundo grau formada ao igualar um
polinmio de segundo grau a zero, ou seja
ax2 + bx + c = 0
Sabemos que uma equao de segundo grau pode ter at duas razes reais; cada raiz um valor
da varivel x que satisfaz a equao. Essas razes podem ser encontradas pela chamada frmula de
Bhaskara. A frmula consiste em calcular um valor auxiliar chamado de (delta), e usar o valor
calculado para identificar quantas razes reais distintas podem ser encontradas para a equao:
se < 0, a equao no tem razes reais;
se = 0, a equao possui uma raiz real;
se > 0, a equao possui duas razes reais distintas.
A frmula para calcular
= b2 4ac
No caso >= 0, as razes da equao so dadas por

b
x=
2a

uma das razes sendo obtida pelo uso do sinal positivo em b , enquanto que a outra raiz
calculada pelo uso do sinal negativo. Se = 0, ambos os valores sero iguais.
Como exemplo do uso da frmula de Bhaskara, considere a equao:
x2 5x + 6 = 0
Nesta equao os coeficientes so a = 1, b = 5 e c = 6. Calculamos o usando os valores dos
coeficientes:
= b2 4ac = (5)2 4 1 6 = 25 24 = 1

73 / 92

Introduo Programao
E assim, podemos calcular as razes:

b 5 1 5 1
x=
=
=
2a
2
2
Ou seja, as razes so 6/2 = 3 e 4/2 = 2.
Agora vamos escrever um programa que resolve equaes do segundo grau, usando o processo mostrado acima.
Cdigo fonte
Clculo de razes de uma equao de segundo grau
1
2

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

3
4
5
6

float calculo_delta(float a, float b, float c) {


return (b * b) - (4 * a * c);
}

// 1x

7
8
9
10

float raiz_positiva(float a, float b, float delta) {


return (-b + sqrt(delta)) / 2 * a;
}

11
12
13
14

float raiz_negativa(float a, float b, float delta) {


return (-b - sqrt(delta)) / 2 * a;
}

// 2x

// 3x

15
16
17
18

int main() {
float a, b, c;
float delta;

19

printf("Entre os coeficientes A, B e C, nesta ordem: ");


scanf("%f %f %f", &a, &b, &c);

20
21
22

delta = calculo_delta(a, b, c);

23
24

if (delta < 0.0)


printf("Delta negativo, nao existem raizes\n");
else if (delta == 0)
printf("Delta = 0, uma raiz: %f\n", raiz_positiva(a, b, delta) );
else
printf("Raizes: %f e %f\n", raiz_positiva(a, b, delta), raiz_negativa(a, b, delta));

25
26
27
28

29
30

31

return 0;

32
33

}
x

Funo que calcula o valor do .

Funo que calcula a raiz positiva da equao.

Funo que calcula a raiz negativa da equao.

74 / 92

Introduo Programao
Resultado de trs execues do programa code/cap5/equacao.c
Entre os coeficientes A, B e C, nesta ordem: 1.0 -5.0 6.0
Raizes: 3.000000 e 2.000000
Entre os coeficientes A, B e C, nesta ordem: 1.0 -6.0 9.0
Delta = 0, uma raiz: 3.000000
Entre os coeficientes A, B e C, nesta ordem: 4.0 -3.0 7.0
Delta negativo, nao existem raizes
Podemos ver neste exemplo funes para calcular o valor do e das duas razes da equao. O
programa obtm o valor do e verifica se a equao tem nenhuma, uma ou duas razes, e imprime o
resultado de acordo com isso. Embora cada funo seja usada apenas uma vez, o programa principal
mais claro e mais fcil de entender porque cada funo faz uma parte do processo necessrio, ao
invs de ter todo o cdigo junto na funo main. Funes so importantes no s para reutilizar
cdigo e diminuir esforo de programao, mas tambm para melhorar a modularizao do programa
e torn-lo mais fcil de ser lido. Em situaes prticas, muitas vezes necessrio ler um cdigo que
j foi produzido antes e entend-lo, seja para consertar defeitos encontrados ou para extender suas
funcionalidades. Tornar um programa mais legvel auxilia e reduz o custo relacionado manuteno
do mesmo.
Entretanto, este ltimo exemplo pode parecer estranho do ponto de vista da modularizao, j
que duas de suas funes so quase idnticas. As funes que calculam o valor das razes,
raiz_positiva e raiz_negativa, mudam apenas em uma operao. Podemos pensar em
como reescrever o programa para usar apenas uma funo ao invs de duas funes quase idnticas.
A repetio desnecessria de cdigo pode ser um problema para a manuteno de um programa.
A chave para criar uma s funo que calcula os dois valores criar um novo parmetro que indica
qual das duas razes deve ser calculada. Vamos usar um parmetro chamado sinal que indica, pelo
seu valor, se ser usada uma soma ou subtrao no clculo da raiz. Se sinal for 1, ser usada uma
soma, e se for -1 ser usada uma subtrao. O cdigo resultante mais compacto e evita repeties:
Cdigo fonte
Clculo de razes de uma equao de segundo grau
1
2

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

3
4
5
6

float calculo_delta(float a, float b, float c) {


return (b * b) - (4 * a * c);
}

7
8
9
10
11
12
13

float raiz(float a, float b, float delta, int sinal) {


if (sinal == 1)
return (-b + sqrt(delta)) / 2 * a;
else
return (-b - sqrt(delta)) / 2 * a;
}

14
15
16
17

int main() {
float a, b, c;
float delta;
75 / 92

Introduo Programao

18

printf("Entre os coeficientes A, B e C, nesta ordem: ");


scanf("%f %f %f", &a, &b, &c);

19
20
21

delta = calculo_delta(a, b, c);

22
23

if (delta < 0.0)


printf("Delta negativo, nao existem raizes\n");
else if (delta == 0)
printf("Delta = 0, uma raiz: %f\n", raiz(a, b, delta, 1));
else
printf("Raizes: %f e %f\n", raiz(a, b, delta, 1), raiz(a, b,
delta, -1));

24
25
26
27
28
29

30

return 0;

31
32

comum quando escrevemos programas nos concentrarmos, inicialmente, em faz-lo funcionar, ou


seja, resolver o problema desejado. Entretanto, importante depois reler o cdigo escrito e revis-lo
para torn-lo mais claro, mais legvel e mais fcil de manter. Esse processo de revisar o cdigo de
um programa sem mudar sua funcionalidade muito importante na programao de computadores, e
normalmente recebe o nome de refatorao.

5.5

Escopo de Variveis

Quando trabalhamos com programas compostos por vrias funes, nos deparamos com questes
relativas visibilidade das variveis em diferentes partes do programa. Ou seja, se uma varivel
visvel ou acessvel em certas partes de um programa.
Um programador iniciante poderia escrever o seguinte programa para calcular a mdia aritmtica de
trs notas:
Cdigo fonte
Clculo da mdia usando cdigo incorreto
1

#include <stdio.h>

2
3
4
5

float calc_media() {
return (nota1 + nota2 + nota3) / 3.0;
}

// 1x

6
7
8

int main() {
float nota1, nota2, nota3;

printf("Entre as trs notas: ");


scanf("%f %f %f", &nota1, &nota2, &nota3);

10
11
12

printf("Media: %f\n", calc_media());

13
14

return 0;

15
16

76 / 92

Introduo Programao
x

Esta linha contm erros e o programa no ser compilado.

O raciocnio do programador "se as variveis nota1, nota2 e nota3 existem na funo main
e a funo calc_media chamada dentro de main, as variveis nota1, nota2 e nota3 no
deveriam ser visveis dentro de calc_media ?"
Acontece que isso no vlido na linguagem C, e qualquer compilador da linguagem vai acusar
erros de compilao neste programa, avisando que as variveis nota1, nota2 e nota3 no foram
declaradas.
Para entender como funciona a visibilidade das variveis em um programa na linguagem C, precisamos falar sobre as regras de escopo desta linguagem. O escopo de uma varivel a parte do programa
na qual ela visvel e pode ser acessada.
A linguagem C usa um conjunto de regras de escopo que recebe o nome de escopo esttico ou escopo
lxico. Essas regras so bastante simples de entender e aplicar, como veremos a seguir.
Em programas na linguagem C existem dois tipos de escopo (regies de visibilidade):
escopo global;
escopos locais.
Existe apenas um escopo global e, como indicado pelo seu nome, ele contm elementos que so
visveis em todo o programa. J os escopos locais so vrios e particulares: basicamente, cada funo
define um escopo local que corresponde com o corpo da funo.
Desta forma, variveis declaradas no escopo global (ou seja, "fora"de qualquer funo) so visveis
em todo programa, enquanto variveis declaradas dentro de uma funo so visveis apenas dentro
da mesma funo. No exemplo anterior, as variveis nota1, nota2 e nota3 so visveis apenas
dentro da funo main, e por isso no podem ser acessadas dentro da funo calc_media.
Isso pode ser resolvido mudando as variveis nota1, nota2 e nota3 para o escopo global, ou seja,
tornando-as variveis globais, como no seguinte programa:
Cdigo fonte
Clculo de razes de uma equao de segundo grau
1

#include <stdio.h>

2
3

float nota1, nota2, nota3;

// 1x

4
5
6
7

float calc_media() {
return (nota1 + nota2 + nota3) / 3.0;
}

// 2x

8
9
10
11

int main() {
printf("Entre as trs notas: ");
scanf("%f %f %f", &nota1, &nota2, &nota3);

12

printf("Media: %f\n", calc_media());

13
14

return 0;

15
16

77 / 92

// 3x

Introduo Programao
x

Declarao das variveis nota1, nota2 e nota3 como variveis globais. Note que elas esto
declaradas "fora"de qualquer funo.
Cdigo dentro de calc_media que usa as variveis globais. Neste programa, as variveis
esto visveis e no ocorrer um erro durante a compilao.
Cdigo dentro de main que usa as variveis globais. Variveis globais so visveis em todo o
programa, incluindo na funo principal.

Este programa agora compila corretamente e funciona para o clculo da mdia. Mas importante
observar que esse tipo de prtica no recomendada. Entre as boas prticas da programao est a
sugesto de usar variveis globais apenas quando absolutamente necessrio. Como variveis globais
podem ser acessadas e ter seu valor alterado por qualquer parte do programa, fica difcil saber que
partes podem influenciar ou serem influenciadas pelas variveis globais, o que torna todo o programa
mais difcil de entender. Para o exemplo das notas, melhor e mais de acordo com boas prticas de
programao comunicar as notas para a funo calc_media usando parmtros, como segue:
Cdigo fonte
Clculo de razes de uma equao de segundo grau
1

#include <stdio.h>

2
3
4
5

float calc_media(float n1, float n2, float n3) {


return (n1 + n2 + n3) / 3.0;
}

6
7
8

int main() {
float nota1, nota2, nota3;

printf("Entre as trs notas: ");


scanf("%f %f %f", &nota1, &nota2, &nota3);

10
11
12

printf("Media: %f\n", calc_media(nota1, nota2, nota3));

13
14

return 0;

15
16

Este cdigo funciona corretamente e evita o uso desnecessrio de variveis globais.

5.5.1

Escopo dos Parmetros

Uma pergunta que pode surgir (especialmente aps o exemplo anterior) qual o escopo dos parmetros das funes? A resposta simples: para questes de visibilidade, o escopo dos parmetros das
funes o escopo local da funo da qual eles pertencem. Ou seja, os parmetros de uma funo
funcionam exatamente como variveis locais declaradas dentro da funo.

5.5.2

Sombreamento e Sobreposio de Escopos

O que acontece se duas variveis tiverem o mesmo nome em um s programa? A resposta depende
de onde as variveis em questo so declaradas.
78 / 92

Introduo Programao
No podem existir duas variveis de mesmo nome em um mesmo escopo; um programa que tente
declarar duas variveis de mesmo nome no mesmo escopo ocasionar um erro quando for compilado.
Assim, no podem existir duas variveis globais de nome x ou duas variveis de nome y em uma
mesma funo.
Em escopos diferentes a regra muda: variveis de mesmo nome podem existir em um programa se
forem declarados em escopos distintos. Isso bastante til: imagine um programa com 20 ou 30
mil linhas de cdigo (o que hoje em dia considerado um programa de pequeno a mdio porte); um
programa deste tamanho precisa usar um grande nmero de variveis, se cada uma delas precisasse
ter um nome diferente de todas as outras, seria muito difcil dar nomes a vrios milhares de variveis.
Imagine que um programa deste tamanho pode ter mais de mil laos for, cada um com uma varivel
de controle, e cada uma dessas variveis teria que ter um nome diferente. Por isso, as regras de
escopo tambm so teis para estabelecer espaos locais onde os nomes no entram em conflitos com
os nomes de outros escopos locais.
Quando temos duas variveis de mesmo nome em diferentes escopos locais, ou seja, duas funes
diferentes, o resultado simples, j que essas variveis de mesmo nome nunca seriam visveis no
mesmo local do programa. Mas e se tivermos duas variveis de mesmo nome, sendo uma varivel
local e uma global? Neste caso, dentro da funo que declara a varivel com mesmo nome da global,
existiro duas variveis que poderiam ser visveis com o mesmo nome. O que acontece nesses casos
chamado de sombreamento: a varivel do escopo local esconde a varivel do escopo global. Vamos
ilustrar essa regra com um exemplo:
Cdigo fonte
Exemplo de sombreamento de variveis globais
1

#include <stdio.h>

2
3

int x = 5;

// 1x

4
5
6
7

void f() {
int x = 60;
int y = x * x;

// 2x
// 3x

printf("x = %d, y = %d\n", x, y);

9
10

11
12
13

int g() {
int y = x * x;

// 4x

14

return y;

15
16

17
18
19

int main() {
f();

20

printf("g = %d\n", g());

21
22

return 0;

23
24

Declarao da varivel global x.


79 / 92

Introduo Programao
x

Declarao da varivel local x na funo f.

Declarao da varivel local y na funo f.

Declarao da varivel local y na funo g.

Vemos no exemplo que existe uma varivel global chamada x e uma varivel local x na funo f.
A funo f tambm tem uma varivel local chamada y, e h uma varivel local de mesmo nome na
funo g. As variveis chamadas y em f e g no interferem, pois so escopos totalmente diferentes.
J as variveis chamadas x interferem, j que uma est no escopo global e outra est no escopo local
da funo f. A questo : o que impresso pelo programa? Isso depende dos valores de x dentro
da funo f e na funo g (que usa x para calcular o valor de y, que retornado). A execuo do
programa imprime o seguinte:
Resultado da execuo do programa code/cap5/sombra.c
x = 60, y = 3600
g = 25
A primeira linha o que impresso na funo f. Como existe uma varivel local x declarada em f,
dentro da funo f a varivel x tem o valor 60, como declarado; o valor de y calculado em f , ento,
60 60 = 3600. J na funo g no existe uma varivel x local, ento o valor de x dentro de g o
valor da varivel global x, que igual a 5; desta forma, y em g tem valor 5 5 = 25. Isso explica a
sada do programa como visto acima.
Nota
Uma consequncia da regra de sombreamento que dentro de funes que tenham variveis
locais que escondem variveis globais de mesmo nome, impossvel acessar ou utilizar
as variveis globais escondidas. No exemplo anterior, dentro da funo f impossvel ter
acesso varivel global x.

5.6

Passagem de Parmetros

Com o que vimos at agora sobre parmetros de funes, eles funcionam de maneira simples: o
cdigo que chama uma funo especifica expresses para cada um dos argumentos da funo. Os
valores de cada expresso so calculados e transmitidos como o valor dos parmetros declarados na
funo.
Entretanto, isso no suficiente para todos os casos em que podemos querer usar parmetros. Por
exemplo, digamos que temos uma situao em que necessrio trocar o valor de duas variveis, e
que isso necessrio vrias vezes ao longo do programa. Para evitar repetio, a melhor soluo
escrever uma funo que realiza a troca do valor de duas variveis. O exemplo a seguir mostra o que
acontece quando tentamos fazer isso apenas com o que vimos at agora:
Cdigo fonte
Tentativa de trocar o valor de duas variveis usando uma funo
1

#include <stdio.h>

2
3

void troca_variaveis(int a, int b) {


80 / 92

Introduo Programao
int temp = a;
a = b;
b = temp;

4
5
6
7

printf("Dentro de troca_variaveis: a = %d, b = %d\n", a, b);

8
9

10
11
12
13

int main() {
int x = 5;
int y = 7;

14

printf("Antes da troca: x = %d, y = %d\n", x, y);


troca_variaveis(x, y);
printf("Depois da troca: x = %d, y = %d\n", x, y);

15
16
17
18

Resultado da execuo do programa


Antes da troca: x = 5, y = 7
Dentro de troca_variaveis: a = 7, b = 5
Depois da troca: x = 5, y = 7
Como se v no resultado da execuo do programa, embora as variveis a e b realmente troquem de
valor dentro da funo troca_variaveis, isso no afeta o valor das variveis x e y em main.
Isso acontece porque, normalmente, os parmetros em C so passados por valor, ou seja, apenas o
valor de x e y so copiados para a e b. Precisamos que as variveis na funo troca_variaveis,
de alguma maneira, afetem as variveis que foram usadas como parmetro, e para isso necessrio
usar o modo de passagem de parmetros chamado de passagem por referncia. A seguir, vamos ver
em maiores detalhes como funcionam esses dois modos de passagem de parmetros.

5.6.1

Passagem por Valor

A passagem de parmetros por valor a situao padro na linguagem C. Este modo de passagem de
parmetros comunica apenas valores entre o cdigo chamador e a funo chamada.
A passagem por valor funciona da seguinte forma: para uma funo f com N parmetros, uma chamada de f deve conter N expresses como argumentos (se o nmero de argumentos no corresponder
ao nmero de parmetros declarados, o compilador acusar um erro no programa). Ento o seguinte
processo de chamada de funo acontece:
1. O valor de cada uma das N expresses usadas como argumento calculado e guardado;
2. N variveis locais so criadas para a funo chamada, uma para cada parmetro da funo, e
usando o nome declarado na funo;
3. Os valores calculados no passo 1 so atribudos s variveis criadas no passo 2.
4. O corpo da funo f executado.
Como as variveis criadas para os parmetros so locais, elas deixam de existir quando a funo
chamada termina, e isso no tem nenhum efeito nas expresses que foram usadas para atribuir valor
aos parmetros ao incio da funo. Isso significa que o programa para troca de valor de variveis
81 / 92

Introduo Programao
mostrado acima funciona de maneira similar ao seguinte programa (no qual colocamos o cdigo da
funo troca_variaveis diretamente na funo main):
Cdigo fonte
Troca do valor de duas variveis usando outra varivel temporria
#include <stdio.h>
int main() {
int x = 5;
int y = 7;
printf("Antes da troca: x = %d, y = %d\n", x, y);
// troca_variaveis
int a = x, b = y;
int temp = a;
a = b;
b = temp;
printf("Dentro de troca_variaveis: a = %d, b = %d\n", a, b);
// fim de troca_variaveis
printf("Depois da troca: x = %d, y = %d\n", x, y);
}

Neste caso, fica claro que as variveis x e y so usadas apenas para obter o valor inicial das variveis
a e b, e portanto a mudana de valor das duas ltimas no deve afetar x e y.
A passagem de parmetros por valor simples e funciona bem na maioria dos casos. Mas em algumas
situaes pode ser desejvel ter uma forma de afetar variveis externas uma determinada funo e,
para isso, usa-se a passagem de parmetros por referncia.

5.6.2

Passagem por Referncia

A passagem de parmetros por referncia funciona passando para a funo chamada referncias para
variveis ao invs de valores de expresses. Isso permite funo chamada afetar as variveis usadas
como argumento para a funo.
Vamos ilustrar como isso funciona demonstrando como criar uma funo que troca o valor de duas
variveis e realmente funciona:
Cdigo fonte
Funo para trocar o valor de duas variveis usando passagem por referncia
#include <stdio.h>
void troca_variaveis(int *a, int *b) {
int temp = *a;
// 2x
*a = *b;
*b = temp;

// 1x

printf("Dentro de troca_variaveis: a = %d, b = %d\n", *a, *b);


}
82 / 92

Introduo Programao

int main() {
int x = 5;
int y = 7;
printf("Antes da troca: x = %d, y = %d\n", x, y);
troca_variaveis(&x, &y);

// 3x

printf("Depois da troca: x = %d, y = %d\n", x, y);


}
x

Definio do procedimento. Os parmetros a e b so declarados usando int * ao invs de


simplesmente int. Isso indica passagem por referncia.
Ao usar as variveis a e b que foram passadas por referncia, necessrio usar *a e *b para
acessar ou modificar seu valor.
Na chamada da funo troca_variaveis preciso passar referncias para as variveis x e
y, isso conseguido usando &x e &y.

Resultado da execuo do programa code/cap5/troca_ref.c


Antes da troca: x = 5, y = 7
Dentro de troca_variaveis: a = 7, b = 5
Depois da troca: x = 7, y = 5
A primeira coisa a notar que so necessrias algumas mudanas sintticas para usar parmetros
por referncia. A declarao dos parmetros no incio da funo agora define os parmetros a e b
como tendo tipo int *. Quando esses parmetros so usados na funo troca_variaveis, eles
precisam ser precedidos de asterisco (*a ao invs de a). E para chamar a funo, preciso passar
referncias para as variveis x e y ao invs de passar seu valor, por isso usamos &x e &y na chamada.
De maneira simplificada, a passagem por referncia funciona da seguinte forma: ao escrever um
argumento como &x para a funo troca_variaveis, no estamos passando o valor de x
para a funo, mas sim uma referncia para a prpria varivel x. Isso significa que, dentro de
troca_variveis, o parmetro a se torna um nome diferente para a mesma varivel x; desta
forma, alteraes feitas em a (atravs da sintaxe *a) so alteraes tambm no valor da varivel original x. por isso que o programa acima funciona, como pode ser visto no resultado da execuo:
a funo troca_variaveis recebe referncias para as variveis x e y, e por isso pode alterar o
valor destas variveis diretamente, trocando o valor das duas.
A passagem de parmetros por referncia usada quando uma funo precisa alterar o valor de uma
varivel que existe fora da prpria funo e que no necessariamente uma varivel global. O mesmo
efeito de ter uma funo alterando uma varivel externa poderia ser atingido usando variveis globais
ao invs de passagem por referncia, mas com grande perda de flexibilidade. Alm disso, o uso
desnecessrio de variveis globais no recomendado, como comentado antes.
5.6.2.1

Realizando troca de valores com variveis globais

Uma outra forma de trocar os valores de duas variveis, dentro de uma funo, poderia ser elaborada utilizando variveis globais. Por exemplo, poderamos trocar os valores das variveis x e y no
exemplo anterior se ambas fossem alteradas para serem variveis globais:
83 / 92

Introduo Programao
Cdigo fonte
Funo para trocar o valor de duas variveis globais
#include <stdio.h>
int x = 5;
int y = 7;

// 1x

void troca_variaveis() {
int temp = x;
x = y;
y = temp;

// 2x

printf("Dentro de troca_variaveis: x = %d, y = %d\n", x, y);


}
int main() {
printf("Antes da troca: x = %d, y = %d\n", x, y);
troca_variaveis();
printf("Depois da troca: x = %d, y = %d\n", x, y);
}

x e y agora so variveis globais.

troca_variaveis no utiliza parmetros, j que acessa diretamente as variveis globais.

Resultado da execuo do programa


Antes da troca: x = 5, y = 7
Dentro de troca_variaveis: x = 7, y = 5
Depois da troca: x = 7, y = 5
O programa funciona, mas note que agora troca_variaveis s altera o valor de duas variveis
especficas, x e y, enquanto que a verso usando passagem por referncia era geral e podia trocar o
valor de quaisquer duas variveis inteiras. Se um programa precisa trocar os valores de vrios pares
de variveis, em vrios locais diferentes, seria preciso criar uma funo de troca para cada par, e
fazer todas as variveis serem globais. Isso acarretaria em muita repetio, e muito uso desnecessrio
de variveis globais que tornariam a manuteno do cdigo muito mais difcil. Neste caso, muito
mais recomendado usar a passagem por referncia para chegar a um cdigo mais geral, mais fcil de
manter e com menos repetio.
Nota
A passagem por referncia vem sido usada neste livro h vrios captulos, pois a funo
scanf (Seo 2.10.2 [28]) usa esse modo de passagem de parmetros. Em toda chamada
a scanf passamos referncias para as variveis que vo receber os valores, e no os
valores dessas variveis. Isso faz sentido j que scanf precisa alterar o valor das variveis
passadas como parmetro, e ao mesmo tempo scanf no utiliza o valor original dessas
variveis para nada.

84 / 92

Introduo Programao

Nota
Com a passagem por referncia e por valor na linguagem C acontece algo semelhante ao
que vimos com os conceitos de procedimento e funo: a rigor na linguagem C s existe a
passagem por valor, mas a passagem por referncia pode ser obtida pelo uso de ponteiros,
um conceito avanado da linguagem C. Como se trata de um conceito avanado, no vamos
detalhar mais sobre eles aqui neste livro.

5.7

Prottipos e Declarao de Funes

Em todos os exemplos que vimos neste captulo at agora, ns sempre definimos uma funo antes
de cham-la em outra funo. Nesses exemplos, a funo main sempre aparece no final do arquivo,
j que as chamadas para as outras funes apareciam apenas em main.
Mas em muitos casos pode ser necessrio chamar uma funo que definida posteriormente no arquivo, sem precisar mudar as funes de lugar. O mesmo ocorre em programas maiores, quando
usamos vrios arquivos de cdigo-fonte para um programa (mas este caso no ser detalhado aqui).
Se tentarmos usar uma funo antes de sua definio vamos observar um erro de compilao. No
exemplo abaixo, a inteno definir uma funo que imprime a situao de um aluno em uma disciplina cuja mdia 7.0. Para isso necessrio passar para a funo as trs notas do aluno na disciplina.
Mas se definirmos a funo aps main, como abaixo:
Cdigo fonte
Chamando uma funo antes de sua definio
#include <stdio.h>
int main() {
float nota1, nota2, nota3;
printf("Entre as trs notas: ");
scanf("%f %f %f", &nota1, &nota2, &nota3);
situacao(nota1, nota2, nota3);
return 0;

// 1x

}
void situacao(float n1, float n2, float n3) {
float media = (n1 + n2 + n3) / 3.0;

// 2x

printf("Media %f, ", media);


if (media >= 7.0)
printf("Aluno aprovado\n");
else if (media < 4.0)
printf("Aluno reprovado por media\n");
else
printf("Aluno na prova final");
}
x

A funo main chama situacao antes de sua definio.


85 / 92

Introduo Programao
x

A definio de situacao comea aps a funo main.

Ao tentar compilar esse programa, um erro similar ao seguinte ser acusado:


Resultado da execuo do programa
situacao.c:12:6: error: conflicting types for situacao
void situacao(float n1, float n2, float n3) { // 1x
Isso acontece porque o compilador no pode identificar se a funo foi realmente definida em algum
lugar e, principalmente, se o tipo dos parmetros e o tipo do retorno da funo esto sendo usados
corretamente.
Esse problema pode ser resolvido atravs do uso de prottipos para declarar uma funo antes que
seja definida. Um prottipo de funo uma declarao que especifica as seguintes informaes:
1. O tipo de retorno da funo;
2. O nome da funo;
3. O nmero de parmetros;
4. Os tipos de cada um dos parmetros.
Com essas informaes, o compilador pode identificar se a funo est sendo usada de maneira correta
com relao aos tipos, e evita os erros anteriores.
Para consertar o erro no exemplo anterior basta adicionar uma linha com o prottipo da funo:
Cdigo fonte
Usando prottipos de funes
#include <stdio.h>
// Prototipo da funcao situacao
void situacao(float, float, float);

// 1x

int main() {
float nota1, nota2, nota3;
printf("Entre as trs notas: ");
scanf("%f %f %f", &nota1, &nota2, &nota3);
situacao(nota1, nota2, nota3);

// 2x

}
void situacao(float n1, float n2, float n3) {
float media = (n1 + n2 + n3) / 3.0;
printf("Media %f, ", media);
if (media >= 7.0)
printf("Aluno aprovado\n");
else if (media < 4.0)
printf("Aluno reprovado por media\n");
else
printf("Aluno na prova final");
}
86 / 92

Introduo Programao
x

Prottipo da funo situacao. Note que o prottipo inclui o tipo de retorno (void), o nome
da funo, que a funo aceita trs parmetros, e que todos eles possuem tipo float. No
preciso especificar o nome dos parmetros em um prottipo, mas possvel especificar os
nomes, se desejado; incluir os nomes dos parmetros pode ser til como uma forma simples de
documentao.

x, 2x A

chamada a situacao em main agora pode acontecer sem problema.

Resultado da execuo do programa


Entre as trs notas: 6.8 5.2 9.0
Media 7.000000, Aluno aprovado
Nesse exemplo, seria possvel consertar o problema simplesmente movendo a funo situacao
completa para antes da funo main, mas em programas maiores o uso de prottipos toma grande
importncia.

5.8

Funes Recursivas

Uma funo pode ser chamada a partir de qualquer outra funo no mesmo programa. Dessa forma,
podemos pensar em uma funo chamando a si mesma. Isso possvel e til em muitos casos.
Quando uma funo f chama a si mesma em algum ponto, dizemos que f uma funo recursiva.
Recursividade se refere a um objeto auto-referente, ou seja, que referencia a si prprio; isso inclui as
funes recursivas mas tambm outros tipos de objetos.
Um exemplo o clculo do fatorial de um nmero. O fatorial de um nmero inteiro positivo N (cuja
notao N!) definido como o produto de todos os nmeros de 1 at N:
N! = N (N 1) 2 1
Por exemplo, o fatorial de 3 3! = 3 2 1 = 6, e o fatorial de 4 4! = 4 3 2 1 = 24, e assim
por diante. Para nmeros N maiores que 1, sempre podemos fazer a seguinte relao:
N! = N (N 1)!
ou seja, 4! = 4 3! = 4 6 = 24. Isso indica a estrutura recursiva do clculo do fatorial: o fatorial de
um nmero N igual a N vezes o fatorial do nmero anterior a N, N-1.
Seguindo essa ideia, podemos escrever uma funo recursiva que calcula o valor do fatorial de um
nmero. Como a funo chama a si mesma, muito importante saber quando a cadeia de chamadas
da funo a ela mesma termina. No caso do fatorial, quando queremos calcular o fatorial do nmero
1 ou do nmero 0, podemos responder diretamente: 1! = 0! = 1, sem usar a recursividade. Esse
o chamado caso-base da recurso. Sem isso, a funo nunca pararia de chamar a si mesmo, e
o programa seria finalizado com algum erro dependente do sistema operacional e do compilador
utilizados.
O programa com a funo que calcula o fatorial o seguinte:
Cdigo fonte
Clculo do fatorial usando uma funo recursiva

87 / 92

Introduo Programao

#include <stdio.h>
// prototipo
int fatorial(int);

// 1x

int main() {
int n;
printf("Entre o numero para calcular o fatorial: ");
scanf("%d", &n);
printf("%d! = %d\n", n, fatorial(n));
return 0;
}
int fatorial(int n) {
if (n == 0 || n == 1)
return 1;
else
return n * fatorial(n - 1);
}

// 2x
// 3x

Prottipo da funo fatorial.

Caso-base na funo fatorial: para n igual a 0 ou 1, retorna 1.

Caso recursivo na funo fatorial: se n for maior que 1, retorne n multiplicado pelo fatorial
de n - 1.

Resultado de trs execues do programa code/cap5/fatorial.c


Entre o numero para calcular o fatorial: 4
4! = 24
Entre o numero para calcular o fatorial: 5
5! = 120
Entre o numero para calcular o fatorial: 6
6! = 720
O cdigo calcula o fatorial de um nmero inteiro recursivamente. Se o nmero for 0 ou 1, a resposta
direta: 1. Se o nmero for maior do que 0 ou 1, a resposta obtida pela multiplicao do nmero pelo
fatorial do nmero anterior a ele. Note que esse processo sempre termina se o parmetro n da funo
fatorial for um inteiro positivo, pois em cada chamada recursiva o argumento da funo fatorial ser
um nmero menor que o anterior, at eventualmente chegar a 1, cuja resposta direta. Como a funo
tem um parmetro declarado como inteiro, o compilador C no permitiria passar como parmetro um
nmero no-inteiro, ento, isso no pode criar problema para essa funo recursiva. Entretanto, um
erro que pode acontecer neste caso se o usurio especificar um nmero negativo:
Clculo do fatorial usando nmero negativo, usando o programa code/cap5/fatorial.c
88 / 92

Introduo Programao

Entre o numero para calcular o fatorial: -4


Segmentation fault: 11
A falha de segmentao (segmentation fault) mostrada quando se passa um argumento negativo para
a funo fatorial o resultado da recurso infinita que ocorre na funo: como em cada etapa
o nmero diminudo de um, um nmero negativo nunca vai chegar a 1 (ou 0) e portanto nunca vai
parar no caso-base. Mesmo a noo matemtica do fatorial no est definida para nmeros negativos.
Uma forma de consertar o programa acima seria imprimir um erro quando fatorial fosse chamado
com um argumento negativo, ou retornar um valor qualquer, sem chamar a funo recursivamente.
Uma forma de fazer isso seria mudando o teste do caso base:
Cdigo fonte
Clculo do fatorial com alterao do teste do caso base
#include <stdio.h>
// prototipo
int fatorial(int);
int main() {
int n;
printf("Entre o numero para calcular o fatorial: ");
scanf("%d", &n);
printf("%d! = %d\n", n, fatorial(n));
return 0;
}
int fatorial(int n) {
if (n <= 1)
// 1x
return 1;
else
return n * fatorial(n - 1);
}

Caso-base da funo fatorial. O teste agora se o parmetro menor ou igual a 1, o que


inclui os nmeros negativos. Neste caso, a funo retorna 1 sem fazer chamadas recursivas.

Resultado de duas execues do programa code/cap5/fatorial2.c


Entre o numero para calcular o fatorial: 5
5! = 120
Sandman:funcoes andrei$ ./fat
Entre o numero para calcular o fatorial: -4
-4! = 1
Neste caso, a funo sempre retorna 1 para nmeros negativos, o que um resultado estranho, mas
como o fatorial no est definido para nmeros negativos, isso no chega a ser um grande problema.
89 / 92

Introduo Programao
A recursividade um conceito de programao considerado avanado, mas se torna bastante importante em programas mais complexos. Alguns paradigmas de programao como a programao
funcional e a programao lgica so bastante baseadas no uso de funes recursivas, e muitos processos se tornam muito mais fceis de implementar usando funes recursivas. Por isso, apesar de
no entrarmos em mais detalhes sobre funes recursivas aqui, importante ter em mente que esse
um dos conceitos que se tornam importantes para a evoluo de um programador.

5.9

Recapitulando

Neste captulo, vimos uma importante ferramenta para a criao de programas na linguagem C: funes. As funes (e os procedimentos, que so tratados na linguagem C como funes) possibilitam
a reutilizao de trechos de cdigo em vrias partes de um programa, e permitem isolar determinadas componentes do programa em unidades mais autocontidas, melhorando a modularizao do
programa. raro que um programa no-trivial na linguagem C no faa uso de funes.
Vimos exemplos do uso de procedimentos (funes que no retornam valores) com e sem parmetros.
Vimos tambm como usar parmetros para funes e como retornar valores a partir de uma funo.
As regras que regem a visibilidade de variveis locais, globais e parmetros de funes foram apresentadas, assim como os diferentes modos de passagem de parmetros e como utiliz-los: passagem
por valor e por referncia.
Tambm vimos como declarar funes usando prottipos, para poder utilizar essas funes antes de
sua definio (ou em arquivos diferentes de onde elas esto definidas). Um exemplo simples de funo
recursiva foi mostrado, como forma de introduo ao conceito.
Compreender o contedo deste captulo extremamente importante para aprender a programar bem
na linguagem C.

5.10

Exerccios Propostos

1. Escreva uma funo que calcula a mdia final de um aluno que fez prova final em uma disciplina. A funo deve receber a mdia parcial do aluno (mdia das notas nas provas regulares da
disciplina) e a nota obtida na prova final. O clculo para a mdia final
onde MF a mdia final, MP a mdia parcial e PF a nota da prova
MF = 6MP+4PF
10
final. Escreva um programa que utiliza esta funo, pedindo os dados necessrios ao usurio e
imprimindo o valor da mdia final na tela.
2. s vezes til limpar a "tela"antes de imprimir informaes adicionais no console. Uma forma
de limpar a tela imprimir mais de 24 linhas em branco (dependendo do tamanho do console).
Em geral, imprimir 30 linhas em branco deve ser suficiente. Escreva uma funo (procedimento) que limpe a tela imprimindo 30 linhas em branco.
3. Escreva uma funo que recebe dois parmetros a e b e troca o valor de a com o valor de b se
o valor de a for maior do que o de b; o objetivo ter, ao final, o menor dos dois valores em a e
o maior em b. Por exemplo, se a = 5 e b = 3, ento os valores das duas variveis devem ser
trocados, mas se a = 2 e b = 7, ento a ordem j est correta e no necessrio trocar os
valores. Utilize passagem de parmetros por referncia para poder afetar o valor das variveis.
Escreva um programa para testar a funo.
90 / 92

Introduo Programao
4. O que impresso pelo seguinte programa?
Cdigo fonte
#include <stdio.h>
int x = 5;
int y = 9;
int f(int x) {
int z = x * x;
return z * y;
}
int main() {
int y = 3;
printf("%d \n", x);
printf("%d \n", f(y));
return 0;
}

Feedback sobre o captulo


Voc pode contribuir para melhoria dos nossos livros. Encontrou algum erro? Gostaria de
submeter uma sugesto ou crtica?
Para compreender melhor como feedbacks funcionam consulte o guia do curso.

91 / 92

Introduo Programao

Captulo 6
ndice Remissivo
A
argumento, 68
atribuio, 26

mdulos, 64
matrizes, 59
N
No, 35
NULO, 57

B
break, 48
C
Constantes, 22
Constantes simblicas, 23
continue, 49

O
Ou, 35
P
parmetro, 68
Passagem de Parmetros, 80
Passagem por Referncia, 82
Passagem por Valor, 81
procedimentos, 63

D
do-while, 44
E
E, 35
Enquanto, 42
Entrada padro, 17
escopo, 77
ESCREVA, 33
Expresses lgicas, 34

S
Sada padro, 17
Se, 33
stdio, 27
strings, 57
switch, 40

F
for, 45
funo recursiva, 87
Funes, 63
funes, 64

V
variveis globais, 83
vetor, 52
W
while, 42

I
if, 34, 37
if-else, 38
incremento, 26
indentao, 24, 39
L
Lao infinito, 46
LEIA, 33
M
92 / 92

Potrebbero piacerti anche