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

Introduo a Programao

UNIVERSIDADE FEDERAL DA PARABA

Reitora MARGARETH DE FTIMA FORMIGA MELO DINIZ Vice-Reitor EDUARDO RAMALHO RABENHORST

EDITORA DA UFPB
Diretora IZABEL FRAN A DE LIMA Vice-Diretor !OS" LUIZ DA SIL#A Superviso de Editora o ALMIR $ORREIA DE #AS$ON$ELLOS !%NIOR Superviso de Produ o !OS" AUGUSTO DOS SANTOS FILHO

!ONSEL"O EDITORIAL
Pro# Dr$ Luc%dio !a&ra' $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$(UFPB) Pro# Dr$ Da*ie''e Rous+$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$(UFPB) Pro# ,s$ Eduardo de Sa*ta*a $$$$$$$$$$$$$$$$$$$$$$$$(UFPB)

Bru*o -e##erso* de Sousa -os. -or/e Li0a Dias -1*ior A*drei de Ara12o For0i/a

Introduo a Programao

Ed&tora da UFPB !oo P'((oa )*+,

!apa - Pro2eto /r3#ico4 Re*ato Arrais e Eduardo Sa*ta*a Editora o e'etr5*ica4 Eduardo de Sa*ta*a ,edeiros A'e6a*dre Revisora Orto/r3#ica4 !a0+'e de Ara12o Si'va

$ata-ogao na .u/-&0ao Un&1'r(&dad' F'd'ra- da Para2/a B&/-&ot'0a S'tor&a- do $$EN S725i Sousa, Bruno Jefferson de. Introduo programao / Bruno Jefferson de Sousa, Jos Jorge L. Dias Junior, ndrei de ra!"o #ormiga$ editor% &duardo de Santana 'edeiros (e)andre, re*isora% +am,(e ra!"o. - Joo .essoa% &ditora da /#.B, 2012. 3 Joo .essoa% +urso de Li4en4iatura em +omputao na 'oda(idade Dist5n4ia / /#.B, 6o*em7ro de 2012. 108p. % i(. ISB6% 97:3:5322730:2231 +urso de Li4en4iatura em +omputao na 'oda(idade Dist5n4ia. /ni*ersidade #edera( da .ara;7a. 1. .rogramao de 4omputadores. 2 <ipos de Dados 7=si4os. 2. rran"os. >. #un?es. I. <;tu(o. BS3$$EN $DU **454)

Todo( o( d&r'&to( ' r'(.on(a/&-&dad'( do( autor'(5

EDITORA DA UFPB $a&6a Po(ta- 7*8+ 9 $&dad' Un&1'r(&t:r&a !oo P'((oa 9 Para2/a 9 Bra(&$EP; 785*7+ 9 <=* 7ttp488999$editora$u#p&$&r Im.r'((o no Bra(&Printed in Brazil

Introduo Programao

Introduo Programao

Ed. v1.0.0
i

Introduo Programao

Sumrio

Algoritmos 1.1 1.2 1.3 1.4 Introduo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . O que um algoritmo? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Caractersticas de um algoritmo . . . . . . . . . . . . . . . . . . . . . . . . . . . . Formas de representao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.4.1 1.4.2 1.4.3 1.5 1.6 Descrio Narrativa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Fluxograma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Linguagem Algortmica . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1 1 2 4 4 5 5 6 8 9 11 11 12 13 15 16 16 17 18 19 21 22 23 25 26 27 28 29 30

Recapitulando . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Exerccios Propostos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Introduo Programao 2.1 2.2 2.3 2.4 2.5 2.6 2.7 Introduo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Nveis das Linguagens de Programao . . . . . . . . . . . . . . . . . . . . . . . . Tradutores e Interpretadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Paradigmas de Programao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Linguagem C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Ncleo de um programa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Memria e Variveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.7.1 2.7.2 2.7.3 2.7.4 2.8 2.9 Identicadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Tipos de dados primitivos . . . . . . . . . . . . . . . . . . . . . . . . . . . Declarao de variveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . Constantes simblicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Comentrios e indentao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Matemtica Bsica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.10.1 Funo printf() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.10.2 Funo scanf() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

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

2.11 Recapitulando . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.12 Exerccios Propostos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .


ii

Introduo Programao 3 Estruturas de Controle 3.1 3.2 3.3 Introduo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Estrutura Sequencial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Estrutura de Deciso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3.1 Deciso simples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3.1.1 3.3.1.2 3.3.1.3 3.3.2 3.3.3 3.4 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.6 3.3.2.1 Expresses lgicas . . . . . . . . . . . . . . . . . . . . . . . . . . Exerccio resolvido . . . . . . . . . . . . . . . . . . . . . . . . . 32 32 32 33 33 34 36 38 39 40 42 42 43 44 45 46 47 48 48 49 50 50 52 52 52 53 53 55 57 57 58 59 59 61 61

Vericao da condio com expresses aritmticas na Linguagem C 37 Exerccio resolvido . . . . . . . . . . . . . . . . . . . . . . . . .

Deciso composta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Comando de deciso mltipla . . . . . . . . . . . . . . . . . . . . . . . . . Comando while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.4.1.1 Exerccio resolvido . . . . . . . . . . . . . . . . . . . . . . . . . Comando do-while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Comando for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Lao innito . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Exerccio Resolvido . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Comandos de desvio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.4.6.1 3.4.6.2 Comando break . . . . . . . . . . . . . . . . . . . . . . . . . . . Comando continue . . . . . . . . . . . . . . . . . . . . . . . . . .

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

3.5 3.6 4

Recapitulando . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Exerccios Propostos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Arranjos 4.1 4.2 Introduo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Vetores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2.1 4.2.2 4.2.3 4.3 4.3.1 4.3.2 4.3.3 4.4 4.5 4.6 Declarao de Vetores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Acessando os elementos de um vetor . . . . . . . . . . . . . . . . . . . . . Exerccio resolvido . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Lendo e imprimindo Strings . . . . . . . . . . . . . . . . . . . . . . . . . . Manipulando strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Exerccio resolvido . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

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

Matrizes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Recapitulando . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Exerccios Propostos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .


iii

Introduo Programao 5 Funes 5.1 O que so funes? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.1.1 5.2 5.3 Um exemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 63 64 67 69 70 73 76 78 78 80 81 82 85 87 90 90 92

Parmetros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Retorno de Valores com Funes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.3.1 Funes, Procedimentos e o Tipo void . . . . . . . . . . . . . . . . . . . .

5.4 5.5

Um Exemplo Matemtico: Equao de Segundo Grau . . . . . . . . . . . . . . . . . Escopo de Variveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.5.1 5.5.2 Escopo dos Parmetros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Sombreamento e Sobreposio de Escopos . . . . . . . . . . . . . . . . . .

5.6

Passagem de Parmetros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.6.1 5.6.2 Passagem Por Valor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Passagem Por Referncia . . . . . . . . . . . . . . . . . . . . . . . . . . . .

5.7 5.8 5.9

Prottipos e Declarao de Funes . . . . . . . . . . . . . . . . . . . . . . . . . . Funes Recursivas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Recapitulando . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

5.10 Exerccios Propostos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 ndice Remissivo

iv

Introduo Programao

Prefcio
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 nalidade 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, especicamente, 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 m, 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 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.

Introduo Programao

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 nal do captulo Verique 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. Conra os signicados delas.

Nota Esta caixa utilizada para realizar alguma reexo.

Dica Esta caixa utilizada quando desejamos remeter a materiais complementares.

Importante Esta caixa utilizada para chamar ateno sobre algo importante.
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

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

Ateno Esta caixa utilizada para alertar sobre algo potencialmente perigoso.

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

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 e tabelas Figura 1 [ix] Tabela 1 [ix]
Nota Na verso impressa, o nmero que aparece entre chaves [ ] corresponde ao nmero da pgina onde est o contedo referenciado. Nas verses digitais do livro voc poder clicar no link da referncia.

Cdigos e comandos
Os cdigos ou comandos so apresentados com a seguinte formao: cc -S main.c teste.c No exemplo a seguir, temos outra apresentao de cdigo fonte. Desta vez de um arquivo main.c, que se encontra dentro do diretrio code/estruturas-de-controle. O diretrio estruturas-de-controle faz referncia ao captulo onde o cdigo ser apresentado. Cdigo fonte code/estruturas-de-controle/for_cont.c Exemplo do comando for

vii

Introduo Programao

#include <stdio.h> int main() { int cont; for (cont = 1; cont <= 10; cont++) printf("Isto sera mostrado 10 vezes.\n"); return 0; }

Baixando os cdigos fontes


Existem duas formas de acessar os cdigos fontes contidos neste livro. Acesso on-line individual Voc pode acessar individualmente os arquivos deste livro pelo endereo: https://github.com/edusantana/introducao-a-programacao-livro/tree/master/livro/capitulos/code. Baixando todos os cdigos Voc tambm pode baixar o cdigo fonte do livro inteiro, que contm todos os cdigos mencionados no livro. Existem duas formas de baixar o cdigo inteiro, atravs de um arquivo zip ou clonando o repositrio. Arquivo zip https://github.com/edusantana/introducao-a-programacao-livro/archive/master.zip. pois de baixar o arquivo, descompacte-o. De-

Clonando o repositrio Use o comando: git clone https://github.com/edusantana/introducao-a-programacao-livro


Nota Independente do mtodo utilizado para acessar os arquivos, os cdigos fontes esto organizados por captulos no diretrio livro/capitulos/code.

Ateno Os cdigos acessados por estes mtodos so referentes verso mais nova do livro (em produo). possvel que eles sejam diferentes da verso do livro que voc esteja lendo.

Contribuindo com o livro


Voc pode contribuir com a atualizao e correo deste livro. A tabela a seguir resume os mtodos de contribuies disponveis:

viii

Introduo Programao Tabela 1: Mtodos para contribuio do livro Mtodo de contribuio

Habilidades necessrias

Descrio

Inscrio no site do github Issue track Preenchimento de um formulrio

Consiste em acessar o repositrio do livro e submeter um erro, uma sugesto ou uma crtica atravs da criao de um Issue. Quando providncias forem tomadas voc ser noticado disso.

Submisso de correo

Realizar fork de projetos Atualizar texto do livro Realizar PullRequest

Consiste em acessar os arquivos fontes do livro, realizar a correo desejada e submet-la para avaliao. Este processo o mesmo utilizado na produo de softwares livres.

Importante Quando for enviar sua contribuio lembre-se de informar qual a verso e pgina do livro que est se referindo.

Contribuio atravs do Issue track Para contribuir com um erro, sugesto ou crtica atravs de um envio de uma mensagem acesse: https://github.com/edusantana/introducao-a-programacao-livro/issues/new

Figura 1: Exemplo de contribuio atravs do Issue track


ix

Introduo Programao

Baixando a edio mais nova deste livro


Ns estamos constantemente atualizando o nosso material didtico. Todas as verses deste livro encontram-se disponveis para download.

Dica Acesse https://github.com/edusantana/introducao-a-programacao-livro/releases para baixar a verso mais nova deste livro.

Introduo Programao

Captulo 1 Algoritmos
O BJETIVOS DO CAPTULO Ao nal deste captulo voc dever ser capaz de: Denir 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. Enm, 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 lmes, 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 conana 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 denir algoritmo como uma sequncia nita, 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 denem um processo nito. 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 m de encher uma terceira vasilha com seis litros de gua. A gura 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, especicamente, possuem as seguintes caractersticas: Denio Os passos de um algoritmo devem ser bem denidos, objetivando a clareza e evitando ambiguidades. Finitude Um algoritmo deve chegar ao seu m aps um nmero nito de passos. Efetividade Um algoritmo deve ser efetivo, ou seja, suas operaes devem ser bsicas o suciente para que possam, em princpio, serem executadas de maneira exata e em um tempo nito. 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 signicados, 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]) reetem 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 uxogramas.
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 uxogramas A vantagem de se fazer uso dos uxogramas est na facilidade de compreend-los. Descries de algoritmos mediante formas grcas so mais facilmente compreendidas do que descries que envolvem apenas textos. Alm do mais, os uxogramas possuem um padro mundial no que se refere sua simbologia, tornando sua utilizao independente das peculiaridades das linguagens naturais. Para exemplicar o uso de uxogramas, a Figura 1.4 [6] mostra um algoritmo para calcular a mdia nal de um aluno com base em suas notas e classic-lo como aprovado ou reprovado. Analisando-a com mais cuidado, possvel perceber que os uxogramas tendem a crescer bastante quando descrevem algoritmos constitudos de muitos passos, o que diculta 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 nota1

Obter nota2

M=(nota1 + nota2)
2

Sim

M7
N o

Aprovado

Reprovado

Fim

Figura 1.4: Fluxograma para calcular a mdia de um aluno

1.4.3

Linguagem Algortmica

A linguagem que o computador capaz de compreender tem grande inuncia 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 cam 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. Decodica 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 1 2 3

x = 2
4

y = 3
5

z=x.y
6 7

10

11

2
12

3
13

6
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 decodicao 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 decodicada, 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 decodicao, 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 denem 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 denio 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 exveis 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 nalizar, 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 uxogramas, a desvantagem ca 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, enm, 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 nito de passos, e que estes devem ser simples o suciente para serem executados de maneira exata e em um tempo nito. 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 uxograma 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 especco. 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 uxograma, 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 uxograma, 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 1 2 3

x=10
4

y=5
5

z=x/y+z
6 7

10

11

10
12

5
13

3
14 15

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.

10 / 92

Introduo Programao

Captulo 2 Introduo Programao


O BJETIVOS DO CAPTULO Ao nal 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 ecaz 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 especicados para que possam ser corretamente decodicados 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 signicado 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 diculdade, 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 ns meramente didticos, no sendo elaborado com base em nenhuma mquina real.

Com o intuito de tornar menos complicada, mais eciente 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 desao: 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 desao 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 classicados 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 m 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 m 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 modicaes no cdigo fonte
14 / 92

Introduo Programao do programa desde sua ltima execuo. A vantagem da interpretao ca 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 signica representar solues a partir de uma forma particular de raciocinar na elaborao dos algoritmos. Como os paradigmas mencionados sustentam a atividade de programas, eles inuenciam 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 especicar 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 denir 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 ecincia 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 inuenciou 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 ecientemente parte do sistema Unix na linguagem C. A partir de meados dos anos 80, C comeou a ganhar popularidade e, devido sua exibilidade 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 m da execuo de um programa. De forma mais especca, 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 denimos a funo main e demarcamos o seu incio com o caractere { (abre-chaves). Todo contedo de uma funo em C ca 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 nalidade 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 m 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 identica de forma particular. Esse nmero chamado de endereo e tem a mesma funo que os endereos de nossas casas, que identicar de forma nica nossas residncias, a m 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, signica 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 0 1 2 ... n

Varivel x y z ... var

Valor 100 20,5 aula ... -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

Identicadores

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

Introduo Programao palavras que possuem signicado 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 identicadores 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 identicadores. Abaixo, alguns exemplos de identicadores vlidos:
B b X2 computacao COMPUTACAO nota1 nota_2 cpf RG

Identicadores 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 identicadores com letras minsculas e usar letras maisculas ou sublinha para separar palavras. Por exemplo, para escolher um identicador 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 denirmos tipos derivados no Captulo 5. Existem trs tipos primitivos na linguagem C: nmeros inteiros, nmeros de ponto utuante (nmeros fracionrios) e caracteres. Os nmeros fracionrios so chamados de nmeros de ponto utuante devido forma como eles so armazenados no computador. Portanto, sempre que voc ouvir o termo ponto utuante, 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 char Tamanho (em bytes) 4 4 8 1 Funo Armazenar um nmero inteiro. Armazenar nmeros de ponto utuante. Armazenar nmeros de ponto utuante 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 qualicado 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 qualicao de tipo realizada quando os qualicadores 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 denida com antecedncia. Para isso, o programador precisa denir o identicador 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 cm), devemos declarar a varivel altura como sendo do tipo oat. 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 m 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 modicadas 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 identicador seja associado a uma constante atravs da diretiva #define, cuja sintaxe descrita abaixo: #define nome_constante valor_constante; Dessa forma, a denio 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 denio de constantes diz respeito facilidade de modicao 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 modicar o programa a m 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 denio da constante, conforme sugere o quadro abaixo: #define VALOR_LOCACAO 80.0 #define VALOR_LOCACAO 100.0 Apesar das regras para denio dos nomes das constantes simblicas serem as mesmas daquelas utilizadas para identicadores, uma boa prtica de programao deni-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 cando cada vez mais difcil de ser lido e consequentemente de ser entendido. comum um programador ter grandes diculdades 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 reetir 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 cando 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 (a+b) , em C se tornaria: quando houver necessidade. Por exemplo, a expresso matemtica (x+y) 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 nanas 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 nalidade de auxili-lo no controle de suas nanas?

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 especicado 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 especicadores de formato e tm o objetivo de denir 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-utuante) e so denominados de especicadores de preciso. No exemplo anterior eles foram os responsveis pela exibio da varivel altura com duas casas decimais. A tabela abaixo lista os especicadores de formato mais comuns utilizados na funo printf(). Tabela 2.5: Especicadores de formatos mais utilizados na funo printf() Cdigo %d ou %i %ld ou %li %u %c %s %f Formato Inteiro (int) decimal Inteiro (long int) decimal Inteiro sem sinal Caractere Cadeira de caracteres Nmero de ponto-utuante

2.10.2

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 especica 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 vericar 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 nal 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-utuante. O espao requerido porque ele utilizado na especicao do formato (entre o %d e o %.2f h um espao). Assim como printf(), a funo scanf() tambm possui uma lista de especicadores de formato. Os mais utilizados seguem abaixo: Tabela 2.6: Especicadores de formatos mais utilizados da funo scanf() Cdigo %d ou %i %ld ou %li %u %c %s %f Signicado 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-utuante

2.11

Recapitulando

Neste captulo voc pde conhecer um pouco mais sobre o funcionamento dos computadores, mais especicamente sobre a forma com a qual eles decodicam as instrues que lhes so passadas. Vimos, portanto, que as linguagens de programao podem ser classicadas 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. Enm, 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. Dena 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 identicadores 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 prexo e suxo 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.

31 / 92

Introduo Programao

Captulo 3 Estruturas de Controle


O BJETIVOS DO CAPTULO Ao nal 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 uxo 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 signica que suas instrues so executadas na sequncia em que elas aparecem, sem nenhuma alterao no seu uxo, a no ser, claro, que exista alguma instruo explcita para a mudana deste uxo. 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 uxo 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. Signica 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 verica 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 denida como uma expresso, que pode ser lgica ou aritmtica. Ao ser executada, a expresso vericada. 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 m 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 > <
34 / 92

Descrio Maior que Menor que

Introduo Programao Operador >= <= == != Descrio Maior ou igual a Menor ou igual a Igual a Diferente de

Considere o cdigo menorq20.c [35] abaixo. Este reete 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 vericada 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 code/estruturas-de-controle/menorq20.c menorq20.c
1 2 3 4 5 6 7 8 9 10 11 12

#include <stdio.h> int main() { int x; scanf("%d", &x); if (x < 20) printf("O valor de x e menor que 20."); return 0; }

Em outros casos, necessitamos utilizar operadores lgicos nas expresses para avaliar mais de uma expresso relacional. Por exemplo, digamos que no problema acima queremos vericar se o valor digitado para a varivel x est dentro do intervalo entre 10 e 20. Neste caso, precisamos que a condio verique 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 code/estruturas-de-controle/entre10e20.c entre10e20.c
1 2 3 4

#include <stdio.h> int main() { int x;


35 / 92

Introduo Programao

5 6 7 8 9 10 11 12

scanf("%d", &x); if (x > 10 && x < 20) printf("x esta entre 10 e 20."); return 0; }

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 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

3.3.1.2

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 nal 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 nal 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 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

3.3.1.3

Vericao 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 vericar se esta verdadeira ou falsa, temos que ter o cuidado de analisar o valor resultante. Vamos vericar o exemplo no cdigo abaixo. Cdigo fonte code/estruturas-de-controle/if5.c if5.c
1 2 3 4 5

#include <stdio.h> int main() { int x = 5;

37 / 92

Introduo Programao
if (x) printf("Isto sera mostrado"); if (x - 5) printf("Isto nao sera mostrado"); return 0; }

6 7 8 9 10 11 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 vericao 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 exemplica 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 denir 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 vericada. 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 code/estruturas-de-controle/nota7.c nota7.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14

#include <stdio.h> int main() { float nota; scanf("%f", &nota); if (nota >= 7) printf("Aprovado"); else printf("Reprovado"); return 0; }

3.3.2.1

Exerccio resolvido

ER 3.2. Escreva um programa para ler 2 nmeros inteiros do teclado (A e B), vericar e imprimir qual deles o maior, ou a mensagem "A=B", caso sejam iguais. Resposta: Cdigo fonte code/estruturas-de-controle/comparaab.c comparaab.c
1 2 3 4 5 6 7

#include <stdio.h> int main() { int a, b; scanf("%i", &a); scanf("%i", &b);


39 / 92

Introduo Programao

8 9 10 11 12 13 14 15 16 17

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

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 denidas nas declaraes case.
Importante O comando break tem a funo de interromper um determinado uxo 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 nal 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 signica 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 code/estruturas-de-controle/semana.c semana.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37

#include <stdio.h> int main() { int semana; printf("Digite um numero de 1 a 7: "); scanf("%d", &semana); 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; } return 0; }

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 code/estruturas-de-controle/whilenota.c whilenota.c
42 / 92

Introduo Programao

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

#include <stdio.h> int main() { float nota; scanf("%f", &nota); while (nota != -1) { if (nota >= 7) printf("Aprovado\n"); else printf("Reprovado\n"); scanf("%f", &nota); } return 0; }

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 signica que enquanto o valor de cont for menor ou igual a 10, o bloco de instrues ser executado. Para que o lao tenha m, a varivel cont precisa ser incrementada at que alcance o valor 11. Cdigo fonte code/estruturas-de-controle/mostrado10vezes.c mostrado10vezes.c
1 2 3 4 5 6 7 8 9 10 11 12

#include <stdio.h> int main() { int cont = 1; while (cont <= 10) { printf("Isto sera mostrado 10 vezes.\n"); cont++; } return 0; }

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 que 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 code/estruturas-de-controle/notas_alunos_c.c notas_alunos.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

#include <stdio.h> int main() { float nota = 0, soma = 0; int cont = 0; while (nota != -1) { printf("Entre com a nota: "); scanf("%f", &nota); if (nota != -1) { soma += nota; cont++; } } printf("Media das notas: %.2f", return 0; } soma / cont);

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 code/estruturas-de-controle/do_while.c do_while.c
1 2 3 4 5 6 7 8 9 10 11 12

#include <stdio.h> int main() { int cont = 1; do { printf("Isto sera mostrado 10 vezes.\n"); cont++; } while (cont <= 10); return 0; }

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 denida em expresso2. O lao car 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 m da execuo das instrues (nesse caso, especicamente, 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 vericada 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 code/estruturas-de-controle/for_cont.c
45 / 92

Introduo Programao for_cont.c


1 2 3 4 5 6 7 8 9 10

#include <stdio.h> int main() { int cont; for (cont = 1; cont <= 10; cont++) printf("Isto sera mostrado 10 vezes.\n"); return 0; }

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 m da execuo dessa instruo, a varivel cont decrementada e passa a valer 9. Novamente a condio cont > 0 vericada 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 code/estruturas-de-controle/for_cont_decremento.c for_cont_decremento.c
1 2 3 4 5 6 7 8 9 10

#include <stdio.h> int main() { int cont; for (cont = 10; cont > 0; cont--) printf("Valor de cont: %i\n", cont); return 0; }

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 innito

Quando a condio de parada de uma determinada estrutura de repetio nunca alcanada, as intrues do lao so executadas indenidamente, e consequentemente o programa nunca chega ao seu m. 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 innito. O exemplo abaixo ilustra esse tipo de lao: Cdigo fonte code/estruturas-de-controle/laco_innito.c laco_innito.c
46 / 92

Introduo Programao

1 2 3 4 5 6 7 8 9 10

#include <stdio.h> int main() { int cont; for (cont = 1; ; cont++) printf("Laco infinito.\n"); return 0; }

Observe que na linha 6 temos um comando for cuja condio de parada no foi denida. Consequentemente, o lao entra em loop e a execuo da instruo na linha 7 executada indenidamente.
Ateno Ao criar uma estrutura de repetio, observe bem a condio de parada para vericar se ela realmente ser alcanada em algum momento. Sem esse cuidado voc corre o risco de criar um lao innito, 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 nal da leitura, o menor deles. Entretanto, ele possui um problema. Identique e corrija o erro. Cdigo fonte code/estruturas-de-controle/menor_deles.c menor_deles.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

#include <stdio.h> int main() { int quantidade = 1; float valor, menor; printf("Informe um valor: "); scanf("%f", &menor); while (quantidade < 50) { printf("Informe um valor: "); scanf("%f", &valor); if (valor < menor) menor = valor; } printf("Menor valor lido: %f", menor); return 0; }

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 m, necessrio que a varivel quantidade atinja o valor 50 em algum momento, e no isso que est acontecendo. Portanto, temos um lao innito. Para corrigir o problema, devemos incluir uma linha dentro do lao a m 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 innito, uma vez que ele atingir o valor 50 em algum momento, tornando falsa a condio quantidade < 50 do lao. Cdigo fonte code/estruturas-de-controle/menor_deles_resposta.c menor_deles_resposta.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

#include <stdio.h> int main() { int quantidade = 1; float valor, menor; printf("Informe um valor: "); scanf("%f", &menor); while (quantidade < 50) { printf("Informe um valor: "); scanf("%f", &valor); if (valor < menor) menor = valor; quantidade++; // Solucao do problema } printf("Menor valor lido: %.2f", menor); return 0; }

3.4.6

Comandos de desvio

Vimos no ltimo exemplo o que um lao innito. 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 code/estruturas-de-controle/break_interrompe.c break_interrompe.c
1 2 3 4 5 6 7 8 9 10 11 12

#include <stdio.h> int main() { int cont; for (cont = 1; ; cont++) { printf("Valor de cont: %i\n", cont); if (cont == 10) break; } return 0; }

3.4.6.2

Comando continue

O comando continue faz com que o uxo 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 signica 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 signica 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 uxo 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 code/estruturas-de-controle/continue_desvio.c continue_desvio.c
1 2 3 4 5 6 7 8 9 10

#include <stdio.h> int main() { int cont; for (cont = 1; cont <= 20; cont++) { if (cont % 2 == 0) continue; printf("Valor de cont: %i\n", cont); }

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 signica que o uxo 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 uxo 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 innito. 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 verique 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 nal 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.

51 / 92

Introduo Programao

Captulo 4 Arranjos
O BJETIVOS DO CAPTULO Ao nal 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 identicam. 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

4 3

Figura 4.1: Vetor com cinco elementos.


52 / 92

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 denido 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 identicar o vetor. A quantidade_elementos representa a quantidade mxima de elementos que o vetor poder armazenar. Observe que essa quantidade deve car 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 deniu 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 m, temos na ltima linha um vetor com identicador 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 identicar 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 caria 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: Congurao 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 ns. 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 xar 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 signica 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 caram 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 nal 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 2 3 4 5 6 7 8

int main() { float nota[20]; int i; for (i = 0 ; i < 20 ; i++ ) scanf("%f", &nota[i]); ...

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 eciente. Veriquemos como cou o trecho de cdigo anterior com a incluso da soluo para o subproblema 2.
1 2 3 4 5 6 7 8 9 10 11 12

int main() { float nota[20], media, soma = 0; int i; for (i = 0 ; i < 20 ; i++ ) { scanf("%f", &nota[i]); soma += nota[i]; } media = soma / 20; ...

Perceba que inclumos na declarao as variveis media e soma, para armazenar, respectivamente, os valores da mdia e da soma das notas. Verique 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 car fora do lao. O subproblema 3 consiste em apresentar na tela as notas da turma que caram 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 nal do programa est descrita abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

int main() { float nota[20], media, soma = 0; int i; for (i = 0 ; i < 20 ; i++) { scanf("%f", &nota[i]); soma += nota[i]; } media = soma / 20; for (i = 0 ; i < 20 ; i++) if (nota[i] > media) printf("%f ", nota[i]); return 0; }

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 especco 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. Signica 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 m. Esse caractere o \0, que signica 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-denidas 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 2 3 4 5 6 7 8 9 10 11 12

int main() { char s[7]; gets(s); puts(s); printf("%c", s[4]); printf("%c", s[2]); return 0; }

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 code/cap4/manipulacao_string.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

#include <stdio.h> int main() { char str1[100], str2[100]; gets(str1); gets(str2); printf("%d", strlen(str1)); printf("%d", strlen(str2)); strcat(str1, str2); printf("%d", strlen(str1)); return 0; }

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 anterior com a adio do contedo de str2. Por m, a linha 13 exibe o tamanho de str1 aps a sua concatenao com str2.
58 / 92

Introduo Programao

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 m 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 signica que o bloco de instrues ser repetido at o nal da string, uma vez que strlen() retorna a quantidade de caracteres de uma string. Dentro do for, vericamos 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 code/cap4/resolvido4-2.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

int main() { char s[40]; int i; gets(s); for (i=0; i < strlen(s); i++) { if (s[i] == ) s[i] = -; } puts(s); return 0; }

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 gura 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 am,1 am,2 am,3 ... am,n
Coluna

Linha

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

Matriz 3x3

[ ] ]
3 1 6 5 9 1 2 0 1
Matriz 2x3

Figura 4.5: 4.5. Exemplos de matrizes Podemos representar essas matrizes na linguagem C acrescentando mais um ndice entre colchetes no identicador 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 code/cap4/matriz_populando.c
1 2 3 4

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]); return 0; }

5 6 7 8 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 car 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.

62 / 92

Introduo Programao

Captulo 5 Funes
O BJETIVOS DO CAPTULO Ao nal deste captulo voc dever ser capaz de: Criar e usar funes e procedimentos em C Identicar 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 identicamos uma parte do algoritmo que deve ser realizada vrias vezes para chegar ao resultado. Ou, ao trabalhar com vrios algoritmos diferentes, identicamos 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 especca; sem funes ou procedimentos, um programa maior e mais complicado caria 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 simplica
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 identicarmos 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, nalmente, passar as roupas para evitar que quem 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 ca 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 nal 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 nal, desta forma, produzindo o seguinte cdigo: Cdigo fonte code/funcoes/media_sem_proc.c Clculo da mdia de um aluno em uma disciplina
#include <stdio.h> int main () { float nota1, nota2, nota3, media;
64 / 92

Introduo Programao

printf("Entre a nota da primeira prova: "); scanf("%f", &nota1); printf("\n"); // 1x printf("=============================================\n"); // 2x printf("\n"); // 3x printf("Entre a nota da segunda prova: "); scanf("%f", &nota2); printf("\n"); printf("=============================================\n"); printf("\n"); printf("Entre a nota da terceira prova: "); scanf("%f", &nota3); printf("\n"); printf("=============================================\n"); printf("\n"); media = (nota1 + nota2 + nota3) / 3.0; printf("Media: %f\n", media); return 0; }
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 code/funcoes/media_proc.c Clculo da mdia usando procedimento
65 / 92

Introduo Programao

#include <stdio.h> void imprime_separador() { // 1x printf("\n"); // 2x printf("=============================================\n"); // 3x printf("\n"); // 4x } int main () { float nota1, nota2, nota3, media; printf("Entre a nota da primeira prova: "); scanf("%f", &nota1); imprime_separador(); // 5x

printf("Entre a nota da segunda prova: "); scanf("%f", &nota2); imprime_separador(); printf("Entre a nota da terceira prova: "); scanf("%f", &nota3); imprime_separador(); media = (nota1 + nota2 + nota3) / 3.0; printf("Media: %f\n", media); return 0; }

Denio do procedimento imprime_separador. no corpo do procedimento.

x , 3x , 4x Cdigo x

Chamada do procedimento imprime_separador.

A linha void imprime_separador() inicia a denio 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 exvel, 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 code/funcoes/media_param.c Uso de um procedimento com parmetro
#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"); } int main () { float nota1, nota2, nota3, media; printf("Entre a nota da primeira prova: "); scanf("%f", &nota1); imprime_separador(nota1); // 2x

printf("Entre a nota da segunda prova: "); scanf("%f", &nota2); imprime_separador(nota2); printf("Entre a nota da terceira prova: "); scanf("%f", &nota3); imprime_separador(nota3); media = (nota1 + nota2 + nota3) / 3.0;
67 / 92

Introduo Programao
printf("Media: %3.2f\n", media); imprime_separador(media); return 0; }
x x

Denio 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/funcoes/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 denido 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 especicar 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 exveis 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
1

Denio da funo f. A denio comea com int f(...), signicando 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 especicar o tipo do valor que retornado pela funo e, por isso, toda funo comea com o tipo de retorno antes do nome. Especicar os tipos dos parmetros e o tipo do valor de retorno tambm similar s funes na matemtica, para as quais devemos especicar os conjuntos domnio e contra-domnio.

5.3.1

Funes, Procedimentos e o Tipo void

Neste ponto pode surgir uma pergunta: se preciso especicar 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 signica o void no incio da denio 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 nal. Tambm pode-se utilizar return ao nal do procedimento, mas este uso supruo 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 code/funcoes/retorno_proc.c Uso de return em um procedimento
#include <stdio.h> void possui_negativo(float n1, float n2, float n3) { if (n1 < 0.0) { printf("Numero negativo encontrado!\n"); return; // 1x } if (n2 < 0.0) { printf("Numero negativo encontrado!\n"); return; }
70 / 92

Introduo Programao

if (n3 < 0.0) { printf("Numero negativo encontrado!\n"); return; } printf("Nenhum numero negativo encontrado\n"); } int main() { float nota1, nota2, nota3; printf("Entre as trs notas, separadas por espacos: "); scanf("%f %f %f", &nota1, &nota2, &nota3); possui_negativo(nota1, nota2, nota3); printf("Media: %f\n", (nota1 + nota2 + nota3) / 3.0); return 0; } // 2x

x x

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/funcoes/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 vericar 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 vericasse o valor retornado e tomasse uma deciso. Se zermos essas alteraes camos com o seguinte programa: Cdigo fonte code/funcoes/retorno_func.c Reescrevendo o exemplo anterior para usar uma funo
71 / 92

Introduo Programao

#include <stdio.h> 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; } int main() { float nota1, nota2, nota3; printf("Entre as trs notas, separadas por espacos: "); scanf("%f %f %f", &nota1, &nota2, &nota3); 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); return 0; } // 4x // 1x

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 identicar 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 nal da funo e o valor 0 retornado para indicar que nenhum nmero negativo foi encontrado. O programa principal verica o valor de retorno da funo possui_negativo e imprime informaes adequadas na tela para cada caso.

x x x

Resultado de duas execues do programa code/funcoes/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 simplicado 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 denio 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 coecientes 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 identicar 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 [$\Delta = 0$], ambos os valores sero iguais. Como exemplo do uso da frmula de Bhaskara, considere a equao: x 2 5x + 6 = 0 Nesta equao os coecientes so a = 1, b = 5 e c = 6. Calculamos o usando os valores dos coecientes: = 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 code/funcoes/equacao.c Clculo de razes de uma equao de segundo grau
#include <stdio.h> #include <math.h> float calculo_delta(float a, float b, float c) { return (b * b) - (4 * a * c); } // 1x

float raiz_positiva(float a, float b, float delta) { return (-b + sqrt(delta)) / 2 * a; } float raiz_negativa(float a, float b, float delta) { return (-b - sqrt(delta)) / 2 * a; } int main() { float a, b, c; float delta;

// 2x

// 3x

printf("Entre os coeficientes A, B e C, nesta ordem: "); scanf("%f %f %f", &a, &b, &c); delta = calculo_delta(a, b, c); 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)); return 0; }
x x 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/funcoes/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 verica 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 code/funcoes/equacao2.c Clculo de razes de uma equao de segundo grau
#include <stdio.h> #include <math.h> float calculo_delta(float a, float b, float c) { return (b * b) - (4 * a * c); } 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; } int main() { float a, b, c; float delta;
75 / 92

Introduo Programao

printf("Entre os coeficientes A, B e C, nesta ordem: "); scanf("%f %f %f", &a, &b, &c); delta = calculo_delta(a, b, c); 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)); return 0; }

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 code/funcoes/media_erro.c Clculo da mdia usando cdigo incorreto
#include <stdio.h> float calc_media() { return (nota1 + nota2 + nota3) / 3.0; } int main() { float nota1, nota2, nota3; printf("Entre as trs notas: "); scanf("%f %f %f", &nota1, &nota2, &nota3); printf("Media: %f\n", calc_media()); return 0; } // 1x

76 / 92

Introduo Programao
1

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 dene 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 code/funcoes/media_globais.c Clculo de razes de uma equao de segundo grau
#include <stdio.h> float nota1, nota2, nota3; // 1x // 2x

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

int main() { printf("Entre as trs notas: "); scanf("%f %f %f", &nota1, &nota2, &nota3); printf("Media: %f\n", calc_media()); return 0; }

// 3x

77 / 92

Introduo Programao
1

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, ca difcil saber que partes podem inuenciar ou serem inuenciadas 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 code/funcoes/media_param2.c Clculo de razes de uma equao de segundo grau
#include <stdio.h> float calc_media(float n1, float n2, float n3) { return (n1 + n2 + n3) / 3.0; } int main() { float nota1, nota2, nota3; printf("Entre as trs notas: "); scanf("%f %f %f", &nota1, &nota2, &nota3); printf("Media: %f\n", calc_media(nota1, nota2, nota3)); return 0; }

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 conitos 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 code/funcoes/sombra.c Exemplo de sombreamento de variveis globais
#include <stdio.h> int x = 5; // 1x // 2x // 3x

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

printf("x = %d, y = %d\n", x, y); } int g() { int y = x * x; return y; } int main() { f(); printf("g = %d\n", g()); return 0; } // 4x

Declarao da varivel global x.


79 / 92

Introduo Programao
2

Declarao da varivel local x na funo f. Declarao da varivel local y na funo f. Declarao da varivel local y na funo g.

x x

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/funcoes/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 especica 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 suciente 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 code/funcoes/troca.c Tentativa de trocar o valor de duas variveis usando uma funo
#include <stdio.h> void troca_variaveis(int a, int b) {
80 / 92

Introduo Programao
int temp = a; a = b; b = temp; printf("Dentro de troca_variaveis: a = %d, b = %d\n", a, b); } int main() { int x = 5; int y = 7; 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); }

Resultado da execuo do programa code/funcoes/troca.c 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 signica 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 code/funcoes/troca_main.c Tentativa de trocar o valor de duas variveis usando uma funo
#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, ca 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 code/funcoes/troca_ref.c 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

Denio 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 modicar 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/funcoes/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 dene 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 simplicada, 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 signica 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 exibilidade. Alm disso, o uso desnecessrio de variveis globais no recomendado, como comentado antes. Por exemplo, poderamos trocar os valores das variveis x e y no exemplo anterior se ambas fossem alteradas para serem variveis globais: Cdigo fonte code/funcoes/troca_glob.c Funo para trocar o valor de duas variveis usando passagem por referncia
83 / 92

Introduo Programao

#include <stdio.h> int x = 5; int y = 7; // 1x // 2x

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

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 x

x e y agora so variveis globais. troca_variaveis no utiliza parmetros, j que acessa diretamente as variveis globais.

Resultado da execuo do programa code/funcoes/troca_glob.c 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 especcas, 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 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 denimos uma funo antes de cham-la em outra funo. Nesses exemplos, a funo main sempre aparece no nal 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 denida 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 denio vamos observar um erro de compilao. No exemplo abaixo, a inteno denir 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 denirmos a funo aps main, como abaixo: Cdigo fonte code/funcoes/situacao.c Chamando uma funo antes de sua denio
#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; } 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"); }
x

// 1x

// 2x

A funo main chama situacao antes de sua denio.


85 / 92

Introduo Programao
2

A denio de situacao comea aps a funo main.

Ao tentar compilar esse programa, um erro similar ao seguinte ser acusado: Resultado da execuo do programa code/funcoes/situacao.c 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 identicar se a funo foi realmente denida 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 denida. Um prottipo de funo uma declarao que especica 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 identicar 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 code/funcoes/situacao_prot.c Usando prottipos de funes
#include <stdio.h> // Prototipo da funcao situacao void situacao(float, float, float); int main() { float nota1, nota2, nota3; printf("Entre as trs notas: "); scanf("%f %f %f", &nota1, &nota2, &nota3); situacao(nota1, nota2, nota3); } 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

// 1x

// 2x

Introduo Programao
1

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 especicar o nome dos parmetros em um prottipo, mas possvel especicar os nomes, se desejado; incluir os nomes dos parmetros pode ser til como uma forma simples de documentao. chamada a situacao em main agora pode acontecer sem problema.

x , 2x A

Resultado da execuo do programa code/funcoes/situacao_prot.c 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 !) denido 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 nalizado com algum erro dependente do sistema operacional e do compilador utilizados. O programa com a funo que calcula o fatorial o seguinte: Cdigo fonte code/funcoes/fatorial.c Clculo do fatorial usando uma funo recursiva

87 / 92

Introduo Programao

#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 == 0 || n == 1) return 1; else return n * fatorial(n - 1); } // 1x

// 2x // 3x

x x x

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/funcoes/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 especicar um nmero negativo: Clculo do fatorial usando nmero negativo, usando o programa code/funcoes/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 innita 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 denida 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 code/funcoes/fatorial2.c Clculo do fatorial usando uma funo recursiva
#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/funcoes/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 denido 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 denio (ou em arquivos diferentes de onde elas esto denidas). 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 nal de um aluno que fez prova nal 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 nal. O clculo para a mdia nal
+4PF onde MF a mdia nal, MP a mdia parcial e PF a nota da prova MF = 6MP10 nal. Escreva um programa que utiliza esta funo, pedindo os dados necessrios ao usurio e imprimindo o valor da mdia nal 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 suciente. 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 nal, 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 code/funcoes/exercicio4.c Clculo do fatorial usando uma funo recursiva
#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; }

91 / 92

Introduo Programao

Captulo 6 ndice Remissivo


A argumento, 68 atribuio, 26 B break, 48 C Constantes, 22 Constantes simblicas, 23 continue, 49 D do-while, 44 E E, 35 Enquanto, 42 Entrada padro, 17 escopo, 77 ESCREVA, 33 Expresses lgicas, 34 F for, 45 funo recursiva, 87 Funes, 63 funes, 64 I if, 34, 37 if-else, 38 incremento, 26 indentao, 24, 39 L Lao innito, 46 LEIA, 33 M
92 / 92

mdulos, 64 matrizes, 59 N No, 35 NULO, 57 O Ou, 35 P parmetro, 68 procedimentos, 63 S Sada padro, 17 Se, 33 stdio, 27 strings, 57 switch, 40 V vetor, 52 W while, 42

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