Vous êtes sur la page 1sur 74

Disciplina: Iniciao Computao

Prof. Augusto Antonio Pinheiro Neto Curso de Licenciatura em Matemtica UFPBVIRTUAL pinheironeto@di.ufpb.br Ambiente Virtual de Aprendizagem: Moodle www.ead.ufpb.br Site da UFPBVIRTUAL www.virtual.ufpb.br Telefone UFPBVIRTUAL (83) 3216 7257

Carga Horria: 60 horas

Crditos: 04

Ementa
Componentes bsicos de um computador Linguagem de programao

Descrio
Nesta disciplina apresentaremos a configurao bsica de um computador, de modo que o aluno tenha uma compreenso geral de sua arquitetura. Estudaremos em seguida uma linguagem de programao imperativa, permitindo capacitar o aluno na programao de resolues de problemas numricos.

Objetivos
Ao final da disciplina o aluno dever ser capaz de: compreender a arquitetura bsica de um computador, programar as operaes de entrada\sada, programar operaes bsicas como: atribuio de valores a variveis ou constantes, permutao de valores entre duas variveis, uso de acumuladores de soma e de produtos, programar os diversos tipos de deciso e de repetio (laos), compreender os principais tipos de dados inerentes linguagem estudada, trabalhar com funes (elemento de programao) elaborar algoritmos de resoluo de diversos tipos de problemas numricos, programar esses algoritmos

267

Contedo Unidade I Componentes bsicos de um computador


1. Unidades funcionais bsicas 2. Unidades de Entrada e/ou Sada 3. Dispositivos de Entrada de Dados 4. Dispositivos de Sada de Dados 5. Dispositivos de Entrada e Sada de Dados 6. Memria principal 7. Tipos de memria 8. Unidade Central de Processamento Unidade de Controle Unidade de Aritmtica e Lgica Registradores Clock 9. Sistemas Operacionais 10. Os arquivos em informtica

Unidade II

Algoritmos
1. Algoritmos 2. Abordagem dividir para conquistar 3. Algoritmo TrocarPneuFurado Refinamento do passo 1 Refinamento do passo 1.5 4. Algoritmo TrocarLmpadaQueimada 5. Exerccios 6. Solucionando um problema Fases de resoluo Fase de implementao 7. Atitude tudo

Unidade III

Introduo programao
1. Conceitos bsicos 2. Memria e variveis 3. Dando nome s variveis 4. Tipos de variveis 5. Declarando uma varivel 6. Atribuindo valor a uma varivel 7. Constantes

268

8. Exibindo o contedo de uma varivel 9. Recebendo uma entrada 10. Teste

Unidade IV

Operaes aritmticas bsicas


1. Primeiros passos 2. A diviso 3. O mdulo 4. Clculo entre variveis 5. Abreviaes: incremento e decremento 6. Outras abreviaes 7. A biblioteca matemtica 8. Teste

Unidade V

Praticando entrada e sada


1. Algumas consideraes sobre a funo scanf 2. Algumas consideraes sobre a funo printf

Unidade VI

Estruturas de controle: condicionais


1. A estrutura if ... else O teste if O teste else O teste else if 2. Alguns erros comuns 3. Para melhor compreender as condies 4. A estrutura switch 5. Condies condensadas 6. Teste

Unidade VII

Estruturas de controle: repeties


1. O lao while 2. O lao do ... while 3. O lao for 4. Teste

Unidade VIII

Funes
1. Qual o objetivo de uma funo? 2. A estrutura de uma funo 3. Criando uma funo

269

4. Chamando uma funo 5. Mais exemplos I. Converso Celsius/Fahrenheit II. Transformar segundos em horas, minutos e segundos III. rea de um retngulo IV. Um menu 6. Teste

Unidade IX

Ponteiros
1. Um pouco mais sobre as funes A memria e os endereos Endereo e valor 2. Utilizao de ponteiros I. Criar um ponteiro II. Enviar um ponteiro a uma funo III. Outro modo de enviar um ponteiro a uma funo 3. Um problema estranho? 4. Resumo 5. Teste

Unidade X

Arrays
1. Os arrays e a memria 2. Declarando um array 3. Como acessar um elemento 4. Atribuindo valores a um array 5. Arrays e ponteiros 6. Listando um array 7. Inicializando um array 8. Passagem de arrays como parmetros 9. Arrays de duas ou mais dimenses 10. Teste

270

Iniciao Computao Unidade I Componentes bsicos de um computador


1. Situando a temtica
Os computadores esto cada vez mais presentes no dia-a-dia dos cidados. Mesmo aqueles que no os utilizam diretamente tm essas mquinas ligadas s suas vidas. Basta nascer para que as informaes referentes ao novo cidado passem a fazer parte de algum banco de dados, por exemplo, o do hospital onde a criana nasceu. Ao registr-la, o pai (a me) estar contribuindo para alimentar outro banco de dados, o do cartrio de registros civis. Ao iniciar seus estudos oficiais, novas informaes sero transferidas para os computadores, desta vez os da escola. E assim ser por toda a vida, imagino. A informao deve ser armazenada e disseminada no momento necessrio. Seria bom ento entender um pouco sobre essas mquinas que nos acompanham por toda a vida.

2. Problematizando a temtica
Os computadores so sistemas eletrnicos de processamento de dados, compostos de uma parte fsica, denominada hardware e de uma parte lgica, denominada software. O hardware formado por um conjunto de funes lgicas, geralmente associadas a um ou mais equipamentos fsicos, capazes de executar determinadas tarefas. Iniciamos os nossos estudos sobre programao apresentando uma noo sobre a configurao bsica de um computador.

3. Conhecendo a temtica
3.1 Unidades funcionais bsicas As funes lgicas associadas ao hardware de um computador so geralmente agrupadas em blocos chamados de unidades funcionais. Um computador possui as seguintes unidades funcionais bsicas, compostas de circuitos eletrnicos especficos:

UC Entrada

UAL

CPU
Registradores

Sada

Teclado Mouse Leitor de disquete Scanner Tela sensvel Leitor de CD, DVD

Memria Principal

Monitor (Vdeo) Impressora Gravador de disquete Gravador de CD, DVD

3.2 Unidades de Entrada e/ou Sada As unidades de Entrada so blocos funcionais compostos por circuitos eletrnicos com a finalidade especfica de transmitir dados do meio exterior para a memria do computador. As unidades de Sada realizam a operao inversa, transmitem dados da memria do computador

271

para o meio exterior. A transmisso fsica desses dados se d por meio de dispositivos especiais. Na figura acima so listados alguns dispositivos que tm a finalidade de realizar essas tarefas. Os dispositivos que realizam tarefas relacionadas funo de entrada so conhecidos como dispositivos de entrada de dados. De modo anlogo, os dispositivos que realizam tarefas relacionadas funo de sada so conhecidos como dispositivos de sada de dados. Alguns dispositivos so capazes de executar entrada e sada de dados. 3.3 Dispositivos de Entrada de Dados Exemplos de alguns dispositivos de entrada de dados: teclado, mouse, scanner. Existem outros, como microfone (dispositivo de entrada de som), monitores de vdeo sensveis ao toque, light-pen, joystick, etc.

Teclado

Mouse

Scanner

3.4 Dispositivos de Sada de Dados Os dispositivos mais comuns de sada de dados so as impressoras e os monitores de vdeo. Entretanto, existem outros dispositivos nesta classe como plotters (traadores de grfico), projetores, caixas de som, etc.

Impressora

projetor Monitor

3.5 Dispositivos de Entrada e Sada de Dados Alguns dispositivos possuem as funes de entrada e sada. Eles so bem conhecidos e podemos citar, por exemplo, leitor/gravador de discos (disquetes, CDs, DVDs, etc),

Leitor/Gravador de CDs

Leitor/Gravador de disquetes

Leitor/Gravador de HDs

272

3.6 Memria Principal Por memria, compreende-se todo dispositivo capaz de guardar qualquer dado ou informao. A memria principal de um computador o local onde esto armazenados os programas e dados que so utilizados durante um processamento. Todo dado ou programa a ser processado deve estar na memria principal do computador. Caso esses dados estejam armazenados em disquetes, Cds ou HDs, ser necessrio, primeiro, transferi-los para a memria principal. A memria principal do computador possui a caracterstica de ser voltil, isto , caso o computador seja indevidamente desligado (falta de energia eltrica, por exemplo), todo o seu contedo ser perdido, ou seja, tornar-se- inacessvel. A memria principal de um computador existe na forma de pentes de memria como mostrado nas figuras a seguir. Atualmente, os pentes de memria, mais encontrados, instalados nos microcomputadores so os de 256 MBytes, 512 MBytes, ou 1GBytes. Memria 256 MB Memria DDR2533 1GB

3.7 Tipos de memria As memrias esto representadas em duas grandes categorias de chips: RAM (random access memory): so chips de memria que podem ser lidos e/ou gravados pela CPU. A memria principal deste tipo. ROM (read only memory) : so chips de memria que podem apenas ser lidos pela CPU. Uma memria ROM permanente e sua gravao feita pelo fabricante do computador, ou pelo fabricante de memrias. Um conjunto especfico de programas, necessrios inicializao de um computador, denominado BIOS, localizado na placa me do computador, est encapsulado em uma memria deste tipo. 3.8 Unidade Central de Processamento A unidade central o elemento funcional central de todo computador. o corao, ou melhor, o crebro do computador. Nesta unidade so realizadas todas as operaes. Todas as informaes tratadas pelo computador transitam por esta unidade funcional. A unidade central tambm conhecida por CPU (Central Processing Unit), Unidade Central de Processamento e dividida classicamente em trs partes: I - Unidade de Controle, responsvel pela extrao das instrues da memria do computador e por sua anlise. Essa unidade controla dois registros especiais denominados CONTADOR DE INSTRUO (PC) que contm o endereo de memria da prxima instruo a ser executada e REGISTRO DE INSTRUES que contm a instruo extrada da memria. a unidade de controle que gerencia todos os eventos necessrios operao do computador. II - Unidade de Aritmtica e Lgica (UAL) controla um conjunto de registros que devem conter os cdigos dos operandos e do operador, necessrios realizao de uma operao aritmtica ou lgica. Exemplos de operaes aritmticas: adio, subtrao, multiplicao ou diviso de nmeros. Exemplos de operaes lgicas: comparao de dois valores alfabticos, operaes envolvendo operadores os booleanos, AND, OR e NOT.

273

Nos dias atuais, uma CPU est completamente embutida em uma pastilha, denominada chip, de dimenses reduzidas. As primeiras CPUs integradas em um nico chip foram a CPU 4004 e a CPU 8008. Hoje esses chips so mais conhecidos no mercado pelo nome de processador ou microprocessador. Em 1974 a Intel fabricou o 8080, o primeiro microprocessador a ser usado em larga escala nos chamados "computadores pessoais". Antes dele, os microcomputadores eram usados apenas em laboratrios cientficos, em fbricas e em universidades. III - Registradores, memrias especiais, de alta velocidade, localizadas no interior de um microprocessador, enquanto a memria principal externa a este. Cada registrador possui uma funo especfica. Dentre os registradores destacam-se os seguintes: Contador de programa (PC - Program Counter), que aponta para a prxima instruo a executar. Registro de instruo (IR - Instruction Register) que armazena a instruo em execuo. Outros registros que permitem o armazenamento de resultados intermedirios. Clock Clock um circuito oscilador que tem a funo de sincronizar a velocidade de transferncia de dados entre duas partes durante um processamento. Por exemplo, a transferncia de dados entre o processador e a memria principal. Essa velocidade de transferncia (freqncia) medida em ciclos por segundo, ou Hertz. A velocidade de acesso dentro do processador maior que na memria principal. Os processadores Pentium-100, Pentium II-300, acessam a memria principal a 66 MHz. 3.9 Sistemas Operacionais Sistemas operacionais so conjuntos de programas que permitem explorar (fazer funcionar) o computador. Atualmente os sistemas operacionais mais conhecidos so Windows e Linux. Um computador um conjunto de materiais inertes. So as diversas camadas de software que fazem com que ele funcione. Quando ligado rede eltrica, uma primeira camada de software, sempre a mesma, posta em ao. Esta camada foi gravada diretamente no hardware: a BIOS (Basic Input/Output System). Esta camada realiza certo nmero de verificaes e de testes (presena de diversos perifricos, volume de memria, etc). Aps isso o sistema operacional assume o controle. o sistema operacional que permite aos humanos dialogar com os computadores. Segundo o grau de convivialidade do sistema, esse dilogo ser mais ou menos amigvel, podendo ser textual, grfico ou uma mistura desses. A partir do sistema operacional o usurio pode ento lanar os aplicativos (programas especficos). 3.10 Os arquivos em informtica Todo arquivo visto e tratado do mesmo modo pelo sistema operacional em vista de seu armazenamento em disco. Tecnicamente, um arquivo um conjunto de bits formando uma entidade identificada por um nome e uma extenso seguindo a forma: nome.ext. Somente a sua extenso capaz de determinar a natureza e assinalar ao sistema operacional o que esse arquivo capaz de fazer. Assim, um arquivo .doc reconhecido como um programa Word, um arquivo .xls reconhecido como um arquivo do Excel e esses softwares so carregados na memria para execuo. Alguns arquivos de imagens (.jpeg ou .jpg, .gif, .png, etc.) necessitam de um visualizador de imagens instalado no computador para que essas imagens possam ser exibidas na tela. Por padro, est previsto que esses arquivos podem ser abertos no Internet Explorer, capaz de exibi-los a partir de pginas da Internet. Dependendo do sistema operacional, existem regras com mais ou menos restries para dar nomes aos arquivos. No MS-DOS, antigo sistema operacional, os nomes de arquivo deveriam ter no mximo 8 caracteres com uma extenso de trs caracteres. A partir do Windows 95 os nomes dos arquivos passaram a ter at 256 caracteres (incluindo o caminho onde se encontra o arquivo, por exemplo, C:\programas\C\programa1.exe).

274

Unidade II - Algoritmos
1. Situando a temtica
Programar uma cincia ou uma arte? A computao uma cincia, porem programar est mais para arte. A programao requer certo dom. Mas isto podemos desenvolver com esforo e pacincia. Assim como aprendemos a pintar, tambm podemos aprender a programar. Alguns requisitos so necessrios, verdade. Para desenvolvermos programas que realizem algumas proezas matemticas, necessrio que tenhamos algum conhecimento para matemtico, seno, como program-las? Qualquer que seja a natureza de nossos programas, existem algumas regras bsicas a serem seguidas. Primeiramente, preciso entender o enunciado do problema a ser resolvido e ento partirmos para encontrar uma soluo. O estudo do domnio de um problema conhecido no mundo da computao como anlise. A apresentao de uma soluo para esse problema faz parte do que se chama projeto. Como os domnios (lgebra, geometria, trigonometria, etc) so vastos e variados, procuramos seguir uma metodologia de resoluo de problemas. o que faremos a seguir no estudo dos algoritmos.

2. Problematizando a temtica
Suponhamos o seguinte problema: trocar o pneu furado de um carro (voc j passou por este tipo de problema?). Parece que estamos diante de um problema simples, mas tentemos explicar a um rob como proceder para realizar tal tarefa. Veremos um enfoque denominado dividir para conquistar, que nos ajudar bastante nessa e outras tarefas.

3. Conhecendo a temtica
3.1 Algoritmos Definio: conjunto finito, ordenado e no ambguo de passos necessrios para realizar uma tarefa. Esse conjunto apresenta as seguintes caractersticas: possui um ponto de parada, isto , sua execuo finita; recebe dados de entrada e, em funo desses, produz dados de sada. Algoritmo Receita de bolo Um algoritmo pode ser correto ou no. Um algoritmo correto produz uma sada correta e pra, enquanto que um algoritmo incorreto produz uma sada incorreta ou no pra. 3.2 Abordagem dividir para conquistar Essa abordagem, muito utilizada em informtica, consiste em dividir o problema inicial em vrios subproblemas, recursivamente. Cada subproblema , logicamente, mais simples que o problema inicial. Esse procedimento de diviso continua at que sejam encontrados subproblemas, que possam ser resolvidos de forma simples ou trivial.

275

3.3 Algoritmo Trocar Pneu Furado 1. pegue o macaco e levante o carro 2. retire o pneu furado 3. pegue o estepe, coloque-o na roda e aperte os parafusos 4. abaixe o carro e reaperte os parafusos 5. guarde o pneu furado e o macaco Refinamento do passo 1 1.1 remova o macaco do porta-malas 1.2 coloque o macaco sob o carro, prximo ao pneu furado 1.3 desaperte os parafusos da roda 1.4 insira a manivela no macaco (ou monte-o de acordo com o modelo do macaco) 1.5 coloque um calo sob o carro para impedi-lo de se mover 1.6 levante o carro com o macaco at que haja espao suficiente para colocar o estepe Refinamento do passo 1.5 1.5.1 se o carro estiver em uma ladeira, de frente para o topo desta, ento coloque o calo atrs de um pneu em bom estado caso contrrio, coloque o calo na frente de um pneu em bom estado O passo 1.6 revela a existncia de um procedimento repetitivo: enquanto no houver espao suficiente para colocar o estepe, faa o seguinte: levante o carro com o macaco. Outro procedimento que pode ser associado ao passo 1.6 : repita o levantamento do carro com o macaco at que haja espao suficiente para colocar o estepe.

3.4 Algoritmo Trocar Lmpada Queimada 1. Remova a lmpada queimada 2. Coloque a nova lmpada

Refinamento
1. 2. 3. 4. 5. 6. 7. Posicione uma escada em baixo da lmpada queimada Escolha uma nova lmpada com a mesma voltagem da queimada Suba na escada at que a lmpada possa ser alcanada Gire a lmpada queimada no sentido anti-horrio at que ela se solte Posicione a nova lmpada no soquete Gire-a no sentido horrio at que ela se firme Desa da escada

276

1. Posicione uma escada em baixo da lmpada queimada 2. Selecione uma nova lmpada para a substituio 2.1. Se a voltagem no for a mesma da lmpada queimada, repita os passos abaixo at encontrar uma que sirva 2.1.1. Descarte a lmpada selecionada 2.1.2. Selecione uma nova 3. Repita at que a lmpada possa ser alcanada 3.1.1. Suba um degrau da escada 4. Repita at que a lmpada fique livre do soquete 4.1.1. Gire a lmpada no sentido anti-horrio 5. Posicione a nova lmpada no soquete 6. Repita at que a lmpada esteja firme 6.1.1. Gire a lmpada no sentido horrio 7. Desa da escada

Esses passos e refinamentos seriam importantes para a realizao dessas tarefas por uma mquina. Um ser humano faz essas coisas intuitivamente, mas as mquinas...

3.5 Exerccios 1 Elabore um algoritmo para fazer pipoca em uma panela de fogo, usando manteiga, sal e milho. 2 Elabore um algoritmo para realizar uma chamada telefnica local. 3 Elabore um algoritmo para realizar uma chamada telefnica de longa distncia (interurbana). 4 Elabore um algoritmo que simule sua sada de casa pela manh. Comece com o passo dormindo na cama e inclua todas as suas atividades matinais. 5 Elabore um algoritmo para calcular as razes reais de uma equao do 2 grau. Se a equao no tiver razes reais, isto deve ser mencionado como resposta.

3.6 Solucionando um problema

Problema
Passo nico

Fase de resoluo do problema

Algoritmo
Fase de implementao da soluo

Programa de computador 277

Fase de resoluo elaborao de um algoritmo para resolver o problema proposto, incluindo testes para verificar se a soluo boa. Fase de implementao ao encontrarmos o algoritmo adequado soluo do problema, precisamos codific-lo em uma linguagem de programao. Geralmente, essa codificao fcil de ser feita desde que o programador compreenda bem a sintaxe e a semntica dos comandos da linguagem escolhida para a implementao.

3.7 Atitude tudo Luis o tipo de cara que voc gostaria de conhecer. Ele estava sempre de bom humor e sempre tinha algo de positivo para dizer. Se algum lhe perguntasse como ele estava, a resposta seria logo: Se melhorar estraga. Ele era um gerente especial em um restaurante, pois seus garons o seguiam de restaurante em restaurante apenas pelas suas atitudes. Ele era um motivador nato. Se um colaborador estava tendo um dia ruim, Luis estava sempre dizendo como ver o lado positivo da situao. Fiquei to curioso com seu estilo de vida que um dia lhe perguntei: Voc no pode ser uma pessoa positiva todo o tempo. Como faz isso? Ele me respondeu: A cada manh, ao acordar, digo para mim mesmo: Luis, voc tem duas escolhas hoje: Pode ficar de bom humor ou de mau humor. Eu escolho ficar de bom humor. Cada vez que algo ruim acontece, posso escolher bancar a vtima ou aprender alguma coisa com o ocorrido. Eu escolho aprender algo. Toda vez que algum reclamar, posso escolher aceitar a reclamao ou mostrar o lado positivo da vida. Certo, mas no fcil argumentei. fcil sim, disse-me Luis. A vida feita de escolhas. Quando voc examina a fundo, toda situao sempre oferece escolha. Voc escolhe como reagir s situaes. Voc escolhe como as pessoas afetaro o seu humor. sua a escolha de como viver sua vida. Eu pensei sobre o que o Luis disse e sempre lembrava dele quando fazia uma escolha. Anos mais tarde, soube que Luis cometera um erro, deixando a porta de servio aberta pela manh. Foi rendido por assaltantes. Dominado, enquanto tentava abrir o cofre, sua mo tremendo pelo nervosismo, desfez a combinao do segredo. Os ladres entraram em pnico e atiraram nele. Por sorte foi encontrado a tempo de ser socorrido e levado para um hospital. Depois de 18 horas de cirurgia e semanas de tratamento intensivo, teve alta ainda com fragmentos de balas alojadas em seu corpo. Encontrei Luis mais ou menos por acaso. Quando lhe perguntei como estava, respondeu: Se melhorar estraga. Contou-me o que havia acontecido perguntando: Quer ver minhas cicatrizes? Recusei ver seus ferimentos, mas perguntei-lhe o que havia passado em sua mente na ocasio do assalto. A primeira coisa que pensei foi que deveria ter trancado a porta de trs, respondeu. Ento, deitado no cho, ensangentado, lembrei que tinha duas escolhas: poderia viver ou morrer. Escolhi viver! Voc no estava com medo? Perguntei. Os para-mdicos foram timos. Eles me diziam que tudo ia dar certo e que ia ficar bom. Mas quando entrei na sala de emergncia e vi a expresso dos mdicos e enfermeiras, fiquei apavorado. Em seus lbios eu lia: "Esse a j era". Decidi ento que tinha que fazer algo. O que fez? Perguntei. Bem, havia uma enfermeira que fazia muitas perguntas. Perguntou-me se eu era alrgico a alguma coisa. Eu respondi: "sim". Todos pararam para ouvir a minha resposta. Tomei flego e gritei: - "Sou alrgico a balas!" Entre risadas lhes disse: - "Eu estou escolhendo viver, operem-me como um ser vivo, no como morto." Luis sobreviveu graas persistncia dos mdicos, mas tambm graas sua atitude. Aprendi que todo dia temos opo de viver plenamente. Afinal de contas, "ATITUDE TUDO". Agora voc tem duas opes: 1. Aps ler estas aulas, esquec-las. 2. Dar o melhor de si, com todas as dificuldades que possam aparecer e escolher aprender. Boa escolha e bons estudos. (Texto de autor desconhecido, obtido na Internet.)

278

4. Avaliando o que foi construdo


Pensar por etapas, foi o que vimos. No adianta querer que os computadores se comportem como os humanos. Eles fazem, realmente, operaes aritmticas e de comparaes, muito mais rpido do que ns o fazemos, mas preciso dizer-lhes, felizmente, o deve ser feito, como e quando. Os algoritmos se resumem nisso, informar ao computador de modo inequvoco essas formas e temporalidade.

5. Referncias
1. Salvetti, Dirceu D., Barbosa, Lisbete M., Algoritmos. Pearson Education do Brasil, 1998 2. Pinheiro Neto. Augusto A., Notas de aula, 2001.

279

Unidade III - Iniciao a Programao


1. Situando a temtica
Poderamos dizer que a palavra programar vem do Latim programmeus. Voc acredita? Pois bem, verdade. Mas o que nos interessa que a palavra programar, em nosso contexto, significa simplesmente: escrever programas de computador. Os programas solicitam aos computadores a realizao de aes. Veremos como dialogar com um computador, procurando ensinar-lhe como realizar essas aes, ou seja, vamos aprender a codificar em uma linguagem de programao um algoritmo apresentado como soluo para um problema.

2. Problematizando a temtica
O computador uma mquina estranha, o mnimo que se pode dizer. Ele entende apenas aquilo que est codificado somente com 0s e 1s. Esse tipo de linguagem denominado linguagem de mquina, ou de baixo nvel. Imaginemos, por exemplo, que a operao de somar seja representada por 11001100 e que desejemos somar 2 com 3. Para transmitir essa ordem a um computador, temos que escrever uma instruo equivalente a esta: 11001100 00000010 00000011. Felizmente, as linguagens de programao atuais esto bem mais prximas das linguagens naturais, aquelas que os homens utilizam para se comunicarem. Existem diversas linguagens de programao que podem ser utilizadas na implementao de algoritmos. Estudaremos a seguir uma das mais importantes hoje em dia, a linguagem C.

3. Conhecendo a temtica
3.1 Conceitos bsicos Linguagens de alto nvel As linguagens atuais com as quais se escreve programas para computadores so estruturadas (possuem estruturas de controle), mais prximas da linguagem natural e com certo formalismo matemtico. Essas linguagens so chamadas de linguagens de Alto Nvel. Exemplos de linguagens de alto nvel. C, C++, Java, Pascal, Visual Basic, Delphi, PHP, etc... Programa fonte e programa executvel Os programas escritos em linguagens de alto nvel, aqueles escritos pelo programador, so geralmente chamados de programas fonte, pois ali so codificados os conhecimentos necessrios para a soluo de determinada tarefa. Uma vez traduzido para a linguagem de mquina, aquela dos 0s e 1s, o programa resultante recebe o nome de programa executvel. Tradutores Tradutores so programas especiais que traduzem um programa fonte para linguagem de mquina. Alguns programas so ditos compilados e outros interpretados. O que isso? Existem tradutores que, quando da traduo do programa fonte, traduzem cada linha e a executam imediatamente. Nesse caso diz-se que houve uma interpretao do programa fonte e esse tipo de tradutor denominado interpretador. Quando a traduo se d por inteiro e to somente aps seu trmino o programa executado, diz-se que ocorreu uma compilao e esse tipo de tradutor denominado compilador. Programas compilados so mais rpidos do que programas interpretados. Importante! Existe um compilador diferente para cada linguagem de alto nvel. Isso lgico. As linguagens sendo diferentes, no se traduz C do mesmo modo que Delphi, por exemplo.

280

Fazendo um esquema grfico do que acabamos de dizer temos: Programa escrito em linguagem de Alto Nvel Programa Fonte Programa traduzido em linguagem de mquina

Programa de traduo para linguagem binria

Compilador/ Interpretador

Fonte

Programa Executve l

Veremos em seguida que mesmo para uma nica linguagem como C, por exemplo, existem vrios compiladores diferentes. H compiladores escritos pela Microsoft, GNU, etc. Felizmente esses compiladores so quase idnticos. Linguagens de altssimo nvel So fceis de utilizar, possuem vrios elementos de linguagem que podem ser arrastados para a rea do programa e o seu cdigo ento gerado automaticamente, digamos "grande pblico", como Visual Basic. Essas linguagens apresentam alguns inconvenientes: elas custam caro e so limitadas plataforma. Se o compilador for voltado plataforma Windows, por exemplo, no espere fazer um programa desenvolvido com ele funcionar sob Linux ou Macintosh. Enfim, no podemos fazer tudo que desejarmos com esse tipo de linguagem. Perceba que estamos de certa forma limitados. As linguagens de alto nvel so um pouco mais difceis que Visual Basic, mas com uma linguagem deste tipo, como C ou C++, aprendemos muito mais sobre programao e funcionamento dos computadores. Aps aprendermos uma linguagem deste tipo, somos capazes de aprender mais facilmente uma outra linguagem de programao. O programador torna-se ento mais autnomo. Em particular C e C++ so linguagens muito populares. Elas so utilizadas para programar uma grande parte dos softwares mais conhecidos. Enfim, programando em C ou C++, o programador est livre de comprar softwares carssimos. Programar em C ou C++ , geralmente, gratuito. Qualidades de um programador Um programador deve ter certas qualidades: pacincia: se um programa no funcionar da primeira vez, preciso saber perseverar! bom senso: no preciso ser to forte em matemtica, mas isso no impede de se ter

que refletir! Calma: no se d tapa no computador

. Isso no faz o programa funcionar.

Em resumo, no so necessrios conhecimentos especiais para programar. Algum fraco em matemtica pode at se sair bem, o essencial a pacincia para refletir. O mnimo que deve estar disponvel para um programador:

Um editor de texto para escrever o cdigo fonte do programa. Em teoria um software como o Bloco de Notas do Windows, edit em linha de comando do DOS ou o vi em Linux suficiente. O ideal dispor de um editor de texto inteligente que colore o cdigo, o que permite acompanh-lo mais facilmente. Um compilador para transformar (compilar) o cdigo fonte em binrio. Um depurador (debugger) para ajudar a encontrar alguns erros no programa, erros de utilizao da memria do computador (erros de lgica do programador no so detectados).

281

comum utilizarmos um programa 3-em-1 que combina editor de texto, compilador e depurador. Esses programas so tambm chamados de IDE "Integrated Development Environment". Exemplos de IDE para programar em C: Bloodshed Dev-C++ e Code::Blocks. Em nosso curso escreveremos os programas fonte no bloco de notas (notepad) se o sistema operacional for Windows ou no KEdit (ou outro editor de texto que acompanhe a verso instalada) se o sistema operacional for Linux. Isto nos restringe aos conhecimentos da linguagem de programao, o que mais interessante para quem est iniciando. Aps conhecermos bem a sintaxe e a semntica da linguagem, usar uma interface tipo IDE ser fcil. Acredite.

3.2 Memria e variveis Para que tenhamos uma idia, eis aqui diferentes tipos de memria existentes dentro de um computador, da mais rpida para a mais lenta: 1. Os registros: uma memria ultra-rpida situada dentro do processador. 2. A memria cache: faz a ligao entre os registros e a memria RAM. 3. A memria RAM: a memria principal com a qual trabalhamos geralmente. 4. O disco rgido: que voc conhece seguramente, onde guardamos os arquivos para posterior uso. Ao dizermos que uma memria lenta, estamos considerando a escala de tempo de um computador. Afinal, 8 milissegundos so quase imperceptveis aos humanos, mas muito tempo para acessar um disco rgido, por exemplo! A memria principal Fotografando de perto a memria principal (RAM) de um computador, no vemos grandes coisas. mais importante sabermos como ela funciona internamente.

Vejamos o esquema abaixo. Ele bastante simples, mas do necessitamos saber para programar.

Endereo 0 1 2 3 ... n-1

Valor 145 3.8028322 0.8272555 39014768 ... 940.5118

Como podemos ver preciso distinguir duas coisas:

282

Endereos: um endereo um nmero que permite ao computador se orientar na memria. Tudo comea pelo endereo 0 (justamente no incio da memria) e termina no endereo 2n-1, onde n o tamanho do barramento de endereos. Quanto mais memria existir no computador mais endereos existiro e mais coisas podero ali ser armazenadas. Em cada endereo podemos armazenar um nico valor (um nmero): o computador armazena na memria esses nmeros para poder recuper-los depois, quando necessrio.

O endereamento de memria uma tcnica que permite ao processador acess-la. A interface utilizada para isto , na maioria das vezes, chamada barramento (BUS), um conjunto de fios dedicados a uma utilizao particular. No caso do acesso memria, esse barramento chamado de barramento de endereos. A memria RAM s pode armazenar nmeros. Como fazer ento para armazenar outros caracteres (palavras, por exemplo)? Boa pergunta. Na verdade, as letras no passam de nmeros para os computadores! Uma frase uma simples sucesso de nmeros. Existe uma tabela, denominada ASCII, que faz a correspondncia entre os nmeros e as letras e outros caracteres. Essa tabela diz, por exemplo, que o nmero 65 corresponde letra A. Variveis Em C, uma varivel constituda de dois atributos: Um valor: o nmero que ela armazena, por exemplo, 25. Um nome: que permite reconhec-la. Programando em C no preciso lembrar o endereo de memria que guarda certo valor (ufa!), basta lembrar o nome da varivel que contm aquele valor. O compilador far a converso entre o nome da varivel e o endereo onde ela est armazenada (ainda bem). Isso parece um pouco confuso no momento (qual o interesse de armazenar um nmero se preciso lembrar o seu endereo), mas, tudo vai tomar sentido em seguida.

3.3 Dando nome s variveis Em C cada varivel deve ter um nome. Se uma varivel guarda o valor da vida mdia de um cidado, ns bem que gostaramos de cham-la vida mdia. Infelizmente isso no possvel. Existem certas restries. Veja a seguir as regras que devemos seguir ao darmos um nome a uma varivel.

S podem existir letras (minsculas ou maisculas), dgitos e sublinha _. O nome de uma varivel deve comear por uma letra. Espaos so proibidos Acentos no so permitidos ( etc).

Enfim, e isto muito importante, a linguagem C (como C++) faz diferena entre as letras maisculas e minsculas. Ento Brasil, bRasil e brasil so nomes que representariam trs variveis distintas. Veja alguns exemplos de nomes vlidos de variveis: Vidamedia, vida_media, vida_Media, VidaMedia, num_de_telefone, bola215, etc Cada programador tem sua maneira prpria de nomear as variveis. Uma maneira bastante utilizada : Comear os nomes de variveis por maisculas. Se houver vrias palavras no nome da varivel, colocar uma maiscula no incio de cada palavra. VidaMedia, por exemplo.

283

3.4 Tipos de variveis Um computador como se pode constatar nada mais do que uma grande mquina de calcular. Ele s sabe trabalhar com nmeros. O problema que existem vrios tipos de nmeros. Nmeros inteiros positivos: 45; 578; 2457 Nmeros inteiros negativos: -87; -513 Nmeros decimais, isto , nmeros com vrgula: 1,7741; 9810,7 Nmeros decimais negativos: -98,45; -1,0045 Nosso pobre computador precisa de ajuda. Quando pedimos a ele para armazenar um nmero, devemos dizer-lhe de que tipo o nmero. No que ele no seja capaz de reconhec-lo, mas isso o ajuda a organizar-se e no perder tempo e espao de memria com algo que poderia ser evitado. Quando declaramos uma varivel em um programa devemos ento indicar o seu tipo. Vejamos os principais tipos de variveis existentes em C: Nome do tipo Valores que podem ser armazenados Char -128 a 127 Int -2 147 483 648 a 2 147 483 647 Long -2 147 483 648 a 2 147 483 647 Float -3.4 x 1038 a 3.4 x 1038 Double -1.7 x 10308 a 1.7 x 10308 Esses no so todos os tipos, mas j d pra comear. Os trs primeiros tipos permitem armazenar nmeros inteiros (1, 2, 3, 4...). Os dois ltimos permitem armazenar nmeros decimais (13.8, 16.911...). Os tipos float e double permitem armazenar nmeros bastante grandes. Se voc no est habituado com as potncias de dez, ento imagine que o tipo double permite armazenar o nmero 1 seguido por 308 zeros, isto , 100000000000000.... (eu no vou aqui escrever 308 zeros )

Observemos que int e long so parecidos. Antes no era assim (um int era menor que um long), mas hoje as memrias evoluram e temos bastante espao para escrever nmeros grandes sem grandes preocupaes com a memria. Por razes de compatibilidade, a linguagem C guarda os dois tipos. Na prtica utilizamos principalmente os tipos char, long e double. Voc ver que na maior parte do tempo manipularemos nmeros inteiros (tanto melhor, pois so mais fceis de utilizar). Ateno com os nmeros decimais. O computador no conhece a vrgula decimal. Em seu lugar utilizaremos o ponto. No devemos escrever 273,45, mas 273.45! Isso ainda no tudo! Alm dos tipos que armazenam nmeros inteiros (char, int, long,...) j vistos, existem outros ditos unsigned (sem sinal) que podem armazenar apenas nmeros positivos. Para utiliz-los basta escrever a palavra unsigned antes do nome do tipo. unsigned char 0 a 255 unsigned int 0 a 4 294 967 295 unsigned long 0 a 4 294 967 295 A vantagem de utilizar tipos unsigned que podemos armazenar nmeros duas vezes maiores (char pra em 128 enquanto unsigned char vai at 255, por exemplo). Por que criar trs tipos para os nmeros inteiros? Um s tipo no seria suficiente? Sim, mas no incio foram criados vrios tipos para economizar memria. A tabela a seguir mostra o espao necessrio para armazenar os tipos.

284

Nome do tipo Nmero de bits Char 8 Int 32 Long 32 Float 32 double 64 3.5 Declarando uma varivel Uma declarao de varivel muito simples, agora que voc sabe tudo que necessrio. Basta indicar, na ordem: 1. 2. 3. 4. O tipo da varivel que vai ser criada Teclar espao Indicar o nome desejado para a varivel Enfim, no esquea o ponto-e-vrgula

Por exemplo, se desejamos criar uma varivel de nome TotalDePontos do tipo long, basta digitar a linha seguinte: long TotalDePontos; Isso tudo! Outros exemplos: long NotaDeFisica; double TotalRecebido; unsigned long NumeroDeEspacosNaLeituraDeUmTextoLongo; Ateno! A declarao das variveis deve ser feita no incio das funes. O texto no quadro abaixo um cdigo de programa escrito em C. Um programa em C formado por vrios trechos de cdigo com um formato especial denominado funo. Todo programa possui uma funo principal chamada main, essa a nica no programa abaixo. No se preocupe, aprenderemos aos poucos a escrever um programa.

Algumas explicaes Na verdade se passa alguma coisa, mas no possvel v-la. Quando a execuo do programa chega linha de declarao da varivel TotalDePontos ele solicita ao computador permisso para utilizar um espao de sua memria principal. Se tudo vai bem, o computador responde pois no, faa como se estivesse em sua casa . O nico problema que poderia acontecer seria no haver mais espao disponvel na memria do computador, mas isso ser um caso extremo. possvel declarar mais de uma varivel em uma mesma linha do programa. Por exemplo, long a, b, c; Isso criar trs variveis de tipo long denominadas a, b e c. 3.6 Atribuindo valor a uma varivel tudo que h de mais simples. Para atribuir o valor 8 varivel TotalDePontos basta escrever: TotalDePontos = 8;

#include <stdio.h> int main(int argc, char *argv[]) { // Incio da funo long TotalDePontos; system("PAUSE"); return 0; // Fim da funo }

Se executarmos este programa ficaremos pasmos ao ver que ele no faz nada.

285

De modo geral, um comando de atribuio tem a forma: varivel = expresso; Nosso programa completo se parece agora com

O valor de uma nova varivel Eis uma questo muito interessante. Quando se declara uma varivel, qual o seu valor inicial? De fato, quando o computador l a linha long TotalDePontos; ele reserva uma pequena parte da memria para armazenar um valor do tipo long. Mas que valor esse? Existe um valor padro (0, por exemplo)? Bem, a resposta no. No existe um valor padro. O computador reserva um espao na memria para armazenar um novo valor, mas no apaga o que j existia naquele espao. Imediatamente a varivel recebe o valor que se encontrava no espao que foi reservado, que pode ser qualquer coisa. Assim, o melhor inicializar as variveis quando de suas declaraes, sempre que possvel. Procedemos assim: long TotalDePontos = 8; Agora a varivel foi declarada e recebeu imediatamente o valor 8. Foi apagado o que poderia haver na posio de memria que lhe foi alocada e colocado ali o valor 8. 3.7 Constantes Ocorre s vezes que se tem a necessidade de armazenar um mesmo valor durante toda a execuo de um programa. O valor de pi (3.14), por exemplo. Isso quer dizer que uma vez declarada e inicializada, a varivel dever conservar o seu valor impedindo que qualquer pessoa possa modific-lo. Essas variveis particulares recebem o nome de constantes, por motivos bvios. Para declarar uma constante em um programa deve-se utilizar a palavra const antes do tipo e obrigatoriamente, inicializar a varivel. Exemplo de declarao de uma constante: const long PI = 3.14; No uma obrigao, mas por conveno, escreve-se os nomes das constantes com letras maisculas. Isso nos permite distinguir facilmente os nomes de constantes dos de variveis. Fora isso uma constante utilizada do mesmo modo que uma varivel. Ao tentar modificar o valor de uma constante no corpo de um programa o compilador acusar um erro (por qu?). 3.8 Exibindo o contedo de uma varivel Utilizamos a funo printf para exibir valores na tela do computador. printf("Total de pontos = %d ", TotalDePontos); O smbolo especial % seguido da letra d um especificador de formato. Este especificador permite a exibio de um nmero inteiro na tela do computador. Existem vrios especificadores de formato que sero visto mais tarde. Por enquanto usaremos os especificadores para nmeros inteiros e nmeros decimais. Smbolo Significado %d Nmero inteiro (ex: 56) %f Nmero decimal (ex: 13.75)

#include <stdio.h> int main(int argc, char *argv[]) { // Incio da funo long TotalDePontos; TotalDePontos = 8 ; system("PAUSE"); return 0; // Fim da funo }

Nada exibido na tela do computador at agora. Em algum lugar da memria do computador o valor 8 armazenado, esse lugar conhecido no programa pelo nome da varivel TotalDePontos e isso tudo.

286

Por enquanto saiba que, se quisermos exibir um nmero inteiro, precisamos utilizar o especificador %d e para exibir um nmero decimal precisamos utilizar o especificador %f. Os especificadores de formato so geralmente utilizados dentro de um texto explicativo, como no exemplo anterior. preciso, entretanto indicar para a funo printf qual o valor a ser exibido. Para isso preciso escrever o nome da varivel que contm esse valor aps o texto contendo o especificador, aps uma vrgula. Vejamos outros exemplos: printf("O valor de a eh %d ", a1); printf("Foram encontrados %d resultados ", r); No primeiro exemplo %d indica que um valor inteiro deve ser exibido na tela do computador e esse valor est armazenado em a1. No segundo exemplo esse valor est armazenado na varivel r. Por enquanto veremos os programas prontos e aprenderemos cada vez mais sobre suas estruturas. Pelo que temos visto podemos tirar algumas concluses: Um programa comea sempre com a instruo #include<stdio.h>, isto indica que uma biblioteca de funes de nome stdio deve ser includa automaticamente no programa e isto feito, no se preocupe. O cabealho da funo principal ser sempre int main(). Aps // vem um comentrio, que no executado, serve apenas de documentao. system("PAUSE"); fixa a tela de modo que possamos ver a resposta. return 0 indica um fim normal do programa.

#include <stdio.h> int main() { long TotalDePontos = 5; // No incio o alunos possui 5 pontos printf("Voce possui %d pontos \n", TotalDePontos); printf("**** H U M M M ****\n"); // O aluno errou uma questo TotalDePontos = 4; // Ele acaba de perder um ponto! printf("Ah, agora voce so tem %d pontos!\n\n", TotalDePontos); system("PAUSE"); return 0; }
Este programa produz a seguinte sada: Voce possui 5 pontos **** H U M M M **** Ah, agora voce so tem 4 pontos! Pressione uma tecla para continuar... Exibir vrias variveis em um nico printf possvel exibir o valor de vrias variveis em um nico printf. Para tanto, suficiente indicar %d ou %f onde se deseja que os valores sejam impressos e em seguida indicar as variveis que contm esses valores, obedecendo ordem em que os especificadores foram indicados, separadas por vrgula. Exemplo. printf("Voce tem %d pontos e faltam %d perguntas", TotalDePontos, p); 3.9 Recuperando uma entrada As variveis vo comear a ficar mais interessantes agora. Vamos solicitar ao usurio (aquele que est operando o computador) que digite um nmero. Vamos aprender a recuperar essa entrada e a armazenar em um determinado lugar na memria principal. Para solicitar ao usurio que entre

287

com uma determinada informao pelo teclado utiliza-se a funo scanf. Essa funo se parece com a funo printf. Deve-se colocar um %d ou %f, entre aspas, para indicar um inteiro ou um decimal a ser digitado. Veja um exemplo. scanf("%d", &idade); Coloca-se apenas %d (ou %f) entre as aspas. No esquecer de colocar o smbolo & antes do nome da varivel que vai receber o valor. E por que esse & antes do nome da varivel? preciso que voc acredite em mim. Eu explicarei isso mais tarde. No o fao agora para no embolar o meio de campo. Quando o programa encontra um scanf ele faz uma pausa e espera que o usurio digite um valor. Esse valor ser armazenado na varivel idade. Veja um pequeno exemplo.

#include <stdio.h> int main() { long idade = 0; // inicializa a varivel com 0 printf("Qual a sua idade? "); scanf("%d", &idade); // Solicita a entrada de idade com scanf printf("Ah ! Voce tem %d anos!\n\n", idade); system("PAUSE"); return 0; }

Sada: Qual a sua idade? 20 Ah! Voce tem 20 anos! Pressione uma tecla para continuar...

Pronto! Voc compreendeu o princpio. Graas funo scanf o computador pode interagir com o usurio. Observe que nada nos impede de digitar outra coisa que um nmero inteiro: Se digitarmos um nmero decimal como 34.56, por exemplo, ele ser truncado imediatamente e s a parte inteira armazenada. Neste caso, 34 armazenado na varivel idade. Se digitarmos letras, a varivel no muda de valor. Permanece ento com o valor 0 (valor com que foi inicializada). Se a varivel no tivesse sido inicializada, o programa imprimiria qualquer coisa. Percebem a importncia da inicializao das variveis?

3.10 Testes 1. Quando se declara uma varivel, qual memria utilizada? ( ) Registros ( ) Memria cache ( ) Memria RAM ( ) Disco rgido 2. Qual memria no apagada quando o computador desligado? ( ) Registros ( ) Memria cache ( ) Memria RAM ( ) Disco rgido 3. Qual desses no um nome vlido de varivel? ( ) scanf ( ) coordenadaDaJanela ( ) desconto_total

288

4. Qual dos tipos de dado abaixo permite armazenar o nmero 15.3? ( ) char ( ) long ( ) double ( ) int 5. Qual dos tipos abaixo permite armazenar o nmero - 1458 ? ( ) long ( ) unsigned int ( ) unsigned double 6. Se a varivel SaldoBanco um long que vale 150345 reais (pensemos grande), o que a linha de cdigo printf("Voce tem %d reais na conta ", saldoBanco); exibir na tela? ( ) Voce tem %d reais na conta ( ) Voce tem 150345 reais na conta ( ) Voce tem d reais na conta saldoBanco 7. Para armazenar um nmero decimal digitado no teclado, qual das linhas de cdigo abaixo a boa? ( ) scanf("%f", num); ( ) scanf("%d", num); ( ) scanf("%f", &num); ( ) scanf("%d", &num);

4. Avaliando o que foi construdo


Foram apresentados alguns conceitos bsicos necessrios para a construo de um programa: memria, variveis e constantes, alm das instrues capazes de realizar as operaes de entrada e sada desses elementos de programao. Uma operao de entrada consiste em receber um valor via teclado e armazen-lo na memria principal do computador. A operao correspondente sada consiste em exibir, geralmente na tela do computador, um valor que esteja armazenado em uma varivel. Vimos tambm que as linguagens utilizadas pelos programadores atualmente so classificadas em um nvel to mais alto quanto mais afastadas estiverem da codificao binria. Assim que linguagens como C, Pascal, Ada, Java, PHP, etc., so denominadas de alto nvel.

5. Referncias

1. Ascencio, Ana F G., Campos, Edilene A V., Fundamentos da Programao de Computadores: Algoritmos, Pascal, C/C++ e Java, 2 edio, Pearson Education, 2007. 2. Hutchison, Robert C., Just, Steven B., Programming using the C language. MGraw-Hill Book Company, 1988. 3. Kernighan, Brian W., Ritche, Dennis M., Le langage C, Masson, 1986.

289

Unidade IV - Operaes Aritmticas Bsicas


1. Situando a temtica
Nesta unidade aprenderemos a realizar a maior parte dos clculos que um computador pode executar. A idia retomar o conceito de variveis visto na unidade anterior e realizar as operaes bsicas que as envolvem como somar, multiplicar, permutar, etc.

2. Problematizando a temtica
J sabemos que o computador uma calculadora muito potente com a qual podemos realizar as seguintes operaes bsicas com muita simplicidade: Adio Subtrao Multiplicao Diviso Mdulo (eu explicarei o que isto) Quando desejamos fazer outras operaes mais complicadas, temos que as programar, isto , explicar ao computador como faz-las. Felizmente existe uma biblioteca de funes matemticas j prontas que acompanha a linguagem C. Neste caso no necessrio programar as operaes, mas simplesmente conhecer a interface das funes correspondentes, ou seja, saber como utilizlas.

3. Conhecendo a temtica
3.1 Primeiros passos Vamos comear pela adio. Para fazer uma adio se utiliza o smbolo + (sem brincadeira). O resultado de um clculo, geralmente, deve ser armazenado em uma varivel. Ateno! Na maioria das vezes, representaremos apenas a parte do programa fonte que estiver sendo discutida. Lembre-se de completar o cdigo do programa comeando por #include <stdlib.h> #include <stdio.h> .............................. Vejamos um exemplo de um trecho de programa que realiza uma soma. .............................. long resposta = 0; .............................. resposta = 13 + 7; No necessrio ser um gnio em matemtica para saber que a varivel resposta armazenar o valor 20 aps a execuo desse trecho de programa. Claro que nada exibido na tela como resposta. Para ver o resultado na tela, como j sabemos, necessrio utilizar a funo printf. Em algum lugar do programa poderamos ter printf(17 + 3 = %d, resposta);. O resultado na tela seria 17 + 3 = 20. Isso tudo para a adio. Para as outras operaes o procedimento o mesmo apenas o smbolo do operador muda. Os operadores so representados pelos smbolos: Adio: + Subtrao: Multiplicao: * Diviso: / Mdulo: %

290

As trs primeiras operaes so realizadas de modo natural, conhecido por quase todos. Apenas as operaes de diviso e de mdulo merecem um pouco de reflexo, pois existem algumas consideraes especficas relacionadas com os tipos envolvidos. 3.2 A diviso As divises funcionam normalmente em um computador quando no sobram restos. Por exemplo, 8/2 4, mas 7/2 que deveria ser 3.5 3 e sobra um resto 1. Observe................................. long resposta = 0; ............................. resposta = 7/2; printf ("7 / 2 = %d", resposta); .............................. Sada. 7/2=3 Eis aqui um problema. Sabemos que 7/2=3.5, mas o resultado apresentado foi 3. Ocorre que a varivel resposta do tipo long, portanto inteiro, por isso o computador truncou o resultado ficando apenas com a sua parte inteira. Se resposta tivesse sido declarada como float ou double o resultado seria 3.500000. Faa as modificaes no programa fonte e execute-o novamente para ver o resultado. Se quisermos que o computador mostre o bom resultado (3.5) ser necessrio transformar os nmeros 7 e 2 para decimais. Isso feito escrevendo-se 7.0 e 2.0 (so os mesmos nmeros, mas agora o computador vai entend-los como nmeros decimais e, portanto efetuar uma diviso de decimais). Na verdade, basta escrever um dos nmeros no formato decimal (com ponto decimal). A linguagem C reconhecer a expresso como sendo do tipo decimal e efetuar a operao corretamente. ..................................... double resposta = 0; .................................... resposta = 7.0 / 2.0; printf ("7 / 2 = %f", resposta); ...................................... Sada 7 / 2 = 3.500000 Observe que o especificador de formato utilizado foi %f, para nmeros decimais. Mas ateno, s vezes se deseja realmente que o resultado seja um valor inteiro, nesse caso o resultado inicial (3) estaria correto. Esta propriedade dos nmeros inteiros muito importante. Tenha sempre em mente que 5/2=2, 8/5=1, 6/7=0, etc. Para obter um resultado decimal necessrio que os operandos sejam nmeros decimais: 5.0/2.0=2.5, 8.0/5.0=1.6, 6.0/7.0=0.857143, etc. De fato, na diviso 5/2, o computador responde questo quantas vezes o nmero 2 est dentro do nmero 5? Resposta, 2 (duas vezes). Voc agora deve estar se perguntando como fazer ento para recuperar o resto da diviso? Esse o nosso prximo passo. 3.3 Primeiros passos O mdulo uma operao matemtica que permite se obter o resto da diviso de dois nmeros inteiros. Talvez seja uma operao menos conhecida que as anteriores, mas de grande importncia nos clculos realizados por computadores. Como mostrado anteriormente, o operador de mdulo representado por %. Veja os exemplos: 7%2=1 ler: o resto da diviso de 7 por 2 28 % 5 = 3 ler: o resto da diviso de 28 por 5

291

10 % 2 = 0

ler: o resto da diviso de 10 por 2

Ao executar a operao 7%2, o computador calcula o resto da diviso de 7 por 2, que 1. A operao 10%2 fornece como resultado 0, pois esse o resto da diviso de 10 por 2, ou seja, a diviso exata. 3.4 Clculo entre variveis O interessante, agora que sabemos as cinco operaes bsicas, utiliz-las entre vrias variveis. Nada nos impede de escrever, resposta = num1 + num2, por exemplo, onde num1, num2 e resposta so variveis declaradas. Esta linha, obviamente faz a soma das variveis num1 e num2 e coloca o resultado na varivel resposta. Agora as coisas comeam a ficar mais interessantes. Voc j capaz de fazer coisas espantosas, como uma calculadora. Creia-me. Imagine um programa que solicita ao usurio a entrada de dois nmeros. Esses dois nmeros devero ser armazenados em variveis. Em seguida escreva uma expresso que calcule a soma desses nmeros e armazene o resultado em uma varivel chamada resposta. Ento exiba o resultado obtido na tela do computador. Experimente escrever esse programa sozinho. Uma possvel resposta seria:

#include <stdio.h> #include <stdlib.h> int main() { long resposta = 0, num1 = 0, num2 = 0; // ** solicitar num1 e num2 ao usurio ** printf("Entre com o valor de num1: "); scanf("%d", &num1); printf("Entre com o valor de num2: "); scanf("%d", &num2);

// ********* Calcular ************ resposta = num1 + num2; // ** Mostrar o resultado na tela ** printf ("%d + %d = %d\n", num1, num2, resposta); system("PAUSE"); return 0; }

Sada Entre com o valor de num1: 52 Entre com o valor de num2: 30 52 + 30 = 82 Experimente agora seguir o mesmo procedimento para que a sua calculadora execute as outras operaes bsicas, ou seja, modifique o programa acima para que ele execute as operaes de subtrao, multiplicao e diviso. 3.5 Abreviaes: incremento e decremento Existem em C tcnicas que permitem abreviar a escrita de certas operaes. Essas abreviaes tm por objetivo agilizar a digitao e tornar o cdigo mais conciso. Incremento Quase sempre, um programador se depara com um problema bem simples, mas de grande importncia: aumentar de 1 o valor de certa varivel. Imagine que um programa trabalhe com uma varivel denominada Total e que se deseje aumentar de 1 o valor dessa varivel. Como faz-lo se o seu valor atual no conhecido? Soluo: Total = Total + 1; O que se passa em um computador ao encontrar uma instruo como esta? Bem, ele sempre avaliar a expresso que se encontra do lado direito da instruo de atribuio (representada pelo

292

smbolo =) e armazenar o seu resultado na varivel que se encontra do lado esquerdo. Assim, na unidade de aritmtica e lgica (UAL), ele somar 1 ao valor atual da varivel Total e substituir o valor armazenado em Total pelo valor da expresso calculada.

Na memria total Antes 30

Na UAL

Na memria total

30+1

Depois

31

Observe que nessa instruo escreve-se duas vezes o nome de uma mesma varivel (Total). Os programadores achando isso muito cansativo resolveram ento abrevi-la. A instruo seguinte faz exatamente a mesma coisa que a anterior e escreve-se menos: Total++; Este recurso muito usado nos programas escritos em C. Voc ter oportunidade de comprovar este fato. Decremento Esta operao o inverso daquela denominada incremento. Trata-se de retirar 1 do valor de uma varivel. Ento, de modo anlogo operao de incremento tem-se: Total = Total - 1; equivalente a Total--; 3.6 Outras abreviaes Existem outras abreviaes que funcionam sob o mesmo princpio que o de incremento (decremento) visto anteriormente, porem de forma mais geral. Essas abreviaes funcionam para todas as operaes bsicas. A tabela abaixo mostra essas abreviaes. Operao total = total +5 total = total -5 total = total *5 total = total /5 total = total %5 Abreviao total += 5 total -= 5 total *= 5 total /= 5 total %= 5

Exemplo. Supor total = 5 inicialmente. long total = 5; total += 4; // total vale 9 total -= 3; // ... total vale 6 total *= 5; // ... total vale 30 total /= 3; // ... total vale 10 total %= 3; // ... total vale 1(pois 10=3*3+1) A vantagem aqui que podemos utilizar todas as operaes bsicas e podemos somar, multiplicar, etc por qualquer nmero. Essas abreviaes so importantes quando temos operaes repetitivas com essa estrutura em um programa. Todavia, o incremento a abreviao mais utilizada. 3.7 A biblioteca matemtica Em C existe um conjunto de funes j prontas para uso bastando apenas ao usurio compreender as suas interfaces, o meio de comunicao do programa com essas funes. Esse

293

conjunto de funes foi escrito por outros programadores e servem, de certo modo, para evitar que os programadores atuais reinventem a roda a cada novo programa. J utilizamos as funes printf et scanf da biblioteca stdio.h. Existem outras bibliotecas de programas, dentre elas uma denominada math.h, que contm diversas funes matemticas j prontas, isto , j programadas. Tenha em mente, por exemplo, que a linguagem C no sabe calcular potncia. Se escrevermos 43 o computador no saber executar essa operao, pois ele no sabe o que isso significa. Para a realizao desse clculo necessrio indicar no incio do programa a incluso de uma biblioteca que contenha a funo responsvel por ele. Essa indicao feita por: #include <math.h> Uma vez feita essa indicao, podemos utilizar todas as funes dessa biblioteca. As principais funes existentes na biblioteca math so: fabs Esta funo retorna o valor absoluto de um nmero, isto , |x| (sua notao matemtica). O valor absoluto de um nmero o seu valor positivo: Ao passar o valor -78 para a funo, ela retornar 78. Ao passar o valor 175 para a funo, ela retornar 175. ........................................................ double absoluto = 0, x=-42; absoluto = fabs(x); // absoluto receber o valor 42 ........................................................ A funo fabs retorna um valor double por isso devemos declarar a varivel absoluto (aquela que vai receber o retorno da funo) como sendo do tipo double. Existe uma funo similar a fabs na biblioteca "stdlib.h", a funo abs. Essa funo funciona do mesmo modo que fabs, mas somente para valores inteiros. Devemos ento declarar a varivel que vai receber o retorno da funo como sendo do tipo int. ceil Esta funo retorna o menor nmero inteiro maior que o nmero decimal que lhe passado como argumento. Por exemplo, ao passar 18.33 como argumento para a funo ela retorna 19. Esta funo retorna um valor do tipo double. ......................................................... double teto = 0, valor1 = 18.33; teto = ceil(valor1); // teto valer 19 //Programa floor, ceil floor Esta funo funciona como a precedente, mas retorna o maior inteiro menor do que o valor decimal passado como argumento. Por exemplo, ao passar 18.99 como argumento para a funo ela retorna 18. Vejamos um programa que exemplifica as duas funes.

#include <stdio.h> int main(void) { double base=0, valor2=18.99; float teto=0, valor1=18.33; teto=ceil(valor1); base=floor(valor2); printf("Base = %f\n", base); printf("Teto = %f\n", teto); printf("Tamanho de base (em bytes) = %d\n", sizeof(base)); printf("Tamanho de teto (em bytes) = %d\n", sizeof(teto)); getch(); return 0; } 294

Outras funes. funo pow(n, p) sqrt(n) sin(x) cos(x) tan(x) asin(x) acos(x) atan(x) exp(x) log(x) log10(x) argumentos (double|float|int, double|float|int) (double|float|int) em radianos em radianos em radianos double double double double double double retorna double|float|int (np) double ( n ) double (seno de x) double (cosseno de x) double (tangente de x) double (arco seno de x) double (arco cosseno de x) double (arco tangente de x) double ( e x ) double (loge x) double (log10 x)

3.8 Testes 1. Qual o smbolo de multiplicao na linguagem C? ( )* ( )+ ( )/ ( )2. Qual o resultado da operao 17 % 5? ( )0 ( )1 ( )2 ( )3 ( )4 ( )% ( )5 ( ) 15

3. Qual o valor da varivel resultado aps a instruo resultado = (8 / 3) - 2;? ( ) -2 ( ) 0 ( )1 ( )2 4. Qual o nome da operao seguinte em programao? x++; ( ) incremento ( ) argumento ( ) suplemento 5. Qual o valor da varivel numero aps as operaes seguintes? long numero = 4; numero--; numero *= 4; numero %= 12; numero += 1;

( ( ( ( (

)0 )1 )4 ) 12 ) 14

6. Qual das funes abaixo se deve utilizar para que 13.25 seja arredondado para 14? ( ) pow ( ) ceil ( ) floor ( ) sqrt

4. Avaliando o que foi produzido


Essas so as operaes e funes que provavelmente todos os programadores mais utilizam ao trabalharem com as operaes aritmticas. A sua compreenso importantssima, pois elas formam a base de programas mais complexos. Teremos oportunidade na seqncia deste curso de utiliz-las como operaes elementares.

295

5. Referncias

1. Ascencio, Ana F G., Campos, Edilene A V., Fundamentos da Programao de Computadores: Algoritmos, Pascal, C/C++ e Java, 2 edio, Pearson Education, 2007. 2. Hutchison, Robert C., Just, Steven B., Programming using the C language. MGraw-Hill Book Company, 1988. 3. Kernighan, Brian W., Ritche, Dennis M., Le langage C, Masson, 1986.

296

Unidade V- Praticando Entrada e Sada


1. Situando a temtica
As funes que realizam as operaes de entrada ou sada no pertencem linguagem C. A biblioteca padro de entrada/sada stdio contm tudo que necessrio para as operaes de entrada ou sada em um programa C. Essa biblioteca formada por um conjunto de funes que fornecem linguagem um sistema de interfaces cmodas para a realizao das operaes de entrada ou sada.

2. Problematizando a temtica
As funes mais utilizadas para entrada ou sada so: scanf printf L valores de variveis a partir da entrada padro, geralmente o teclado. Escreve sobre a sada padro. Na ausncia de indicao em contrrio, essa sada a tela do computador.

Sempre que um programa precisar de dados iniciais vindos do mundo exterior, esses devero ser inseridos no programa por uma funo de leitura. isso que faz a funo scanf. De modo anlogo, os dados produzidos como resultado de processamento interno so exibidos, enviados para o mundo exterior, via a funo printf. Vejamos alguns detalhes sobre essas funes.

3. Conhecendo a temtica
3.1 Algumas consideraes sobre a funo scanf Consideremos o comando scanf(%d, &n);. Trata-se aqui da leitura de um valor que dever ser armazenado na varivel n. Para administrar corretamente a varivel n, a funo scanf precisa conhecer o seu tipo. No exemplo acima, o primeiro parmetro da funo, representado pela seqncia de caracteres %d indica ao compilador C que a varivel de tipo inteiro (int). Se a varivel n pertencesse a um outro tipo, outro caractere seria usado no lugar de d. Essa seqncia de caracteres conhecida pelo nome especificador de formato. O segundo parmetro da funo (&n) indica o endereo na memria do computador, onde a varivel n ser armazenada. O computador se encarrega de calcular esse endereo. O programador apenas deve escrever o parmetro &n para que o computador saiba que no programa o valor armazenado naquele endereo ser conhecido por n. O endereo de uma varivel x representado, portanto, pela expresso &x. 3.2 Algumas consideraes sobre a funo printf O primeiro argumento dessa funo sempre uma seqncia de caracteres. Explicamos o funcionamento dessa funo com a ajuda de alguns exemplos. 1. printf(bom dia); Quando essa instruo encontrada, a funo printf se encarrega de escrever na tela do computador a seqncia bom dia. printf("Eh agradavel escrever um programa " "em C, \nquando o utilizamos \"corretamente\".\n");

2.

297

As aspas no fim da primeira linha e no incio da segunda permitem escrever uma seqncia de caracteres em mais de uma linha. Esse comando produz como sada: Eh agradavel escrever um programa em C, quando o utilizamos "corretamente". A seqncia de caracteres \n diz ao compilador para executar um salto de linha (passar para a prxima linha da tela) A seqncia de caracteres \" indica o uso de aspas. Nesse caso as aspas faro parte da sada que ser impressa. 3. printf(%d, 5); A funo printf substitui o especificador de formato %d pelo primeiro parmetro situado aps a vrgula, neste caso o inteiro 5. Lembre que o caractere d em um especificador de formato representa um nmero inteiro.

Seja o programa

#include <stdio.h> int main() { int altura=185; float peso=80.5; char nome[10]="Joao"; printf("%s mede %d cm e pesa %f kg", nome, altura, peso); getch(); return 0; }
4. printf("%s mede %d cm e pesa %f kg", nome, altura, peso); Supor que as variveis nome, altura e peso refiram-se a uma pessoa e valham a seqncia de caracteres Joo, o inteiro 185 e o nmero real 80.5, respectivamente. A funo printf substitui os especificadores de formato respeitando a ordem em os mesmos se encontram na instruo. Assim %s substitudo pelo primeiro parmetro situado aps a vrgula, neste caso a seqncia Joo, %d substitudo por 185 e %f por 80.5. Note que %s o especificador de formato para seqncia de caracteres e %f o especificador de formato para nmeros em ponto flutuante (nmeros com ponto decimal).

Observemos o seguinte comando: 5. printf("os valores sao \n%5d\n%5d\n%.3f\n", v1, v2, v3); v1 e v2 so duas variveis de tipo int que contm os valores 4 e 256 e v3 uma varivel de tipo float contendo o valor 7.54756, por exemplo. As indicaes numricas permitem precisar o modo como esses valores so mostrados na tela. %5d: exibe o valor correspondente, um valor inteiro, ocupando 5 posies preenchidas a partir da direita. %.3f: exibe o valor correspondente como uma varivel de tipo float com 3 casas decimais, com arredondamento. A sada ento: 00004 00256 7.548

getch(): aguarda a prxima tecla ser pressionada. Isto permite ao usurio ver na tela o resultado exibido pelo programa.

298

A instruo return 0; ao fim da funo main permite enviar o valor 0 ao sistema o que significa, por conveno, que o programa terminou normalmente. O envio desse valor obrigatrio em C, pois a funo main declarada como sendo do tipo int, logo espera um valor desse tipo. 3.3 Vamos praticar um pouco Digitemos o programa abaixo. Antes de execut-lo, procure entender como sero a sua entrada e a sua sada. O objetivo que ele seja auto-explicativo.

/* Este programa l 3 valores inteiros */ #include<stdio.h> int main() { int a,b,c; printf("digite 3 numeros inteiros separados por espaco\n"); scanf("%d %d %d",&a,&b,&c); printf("\n valor de a = %d",a); printf("\n valor de b = %d",b); printf("\n valor de c = %d\n ",c); getch(); return 0; }

Alguns comentrios. - algumas palavras esto sem acentuao, pois isto no permitido na linguagem C, salvo nos comentrios; - o texto entre os smbolos /* e */ um comentrio e, portanto, no ser compilado; - a primeira chamada funo printf serve para orientar o usurio sobre o que ele deve fazer quando da execuo deste programa (o que ele deve fazer mesmo?). Experimente retirar esse comando do programa. Ele funcionar corretamente, mas o usurio saber o que o computador estar esperando como entrada de dados? - na instruo scanf("%d %d %d",&a,&b,&c); os especificadores de formato (%d) podem ser separados por espao ou no, isto no tem influncia no programa; - a cada especificador de formato na funo scanf corresponde, em ordem, um argumento a ser lido do teclado; - as prximas chamadas funo printf servem para imprimir (exibir na tela do computador) os valores das variveis a, b e c; - no incio de cada chamada a printf h uma ordem para o computador mudar de linha (\n); - getch() permite que o usurio veja o resultado na tela (fixa a tela de execuo do programa). Experimente retirar esse comando do programa e tire suas prprias concluses.

Na plataforma Moodle voc encontrar vrios exerccios que permitiro consolidar a aprendizagem sobre entrada e sada de dados. Essas operaes so importantssimas e s a prtica leva um programador a se sentir vontade em sua utilizao. Ento, mos obra. 4. Avaliando o que foi construdo
As operaes de entrada e sada so bsicas no desenvolvimento de um programa. So elas que implementam a interface entre o homem e a mquina. Se por um lado preciso alimentar o

299

computador com dados do mundo exterior a fim de que ele possa realizar alguns processamentos indicados no algoritmo implementado como soluo de um problema, por outro precisamos ver os resultado obtidos. Bem formatar esses procedimentos de entrada e sada implica em apresentar um trabalho legvel e compreensvel. De nada adianta um programa que tenha um bom desempenho nos seus procedimentos internos se no somos capazes de aliment-los de forma adequada e amigvel, com facilidade.

5. Referncias
1. Ascencio, Ana F G., Campos, Edilene A V., Fundamentos da Programao de Computadores: Algoritmos, Pascal, C/C++ e Java, 2 edio, Pearson Education, 2007. 2. Hutchison, Robert C., Just, Steven B., Programming using the C language. Mcgraw-Hill Book Company, 1988. 3. Kernighan, Brian W., Ritche, Dennis M., Le langage C, Masson, 1986.

300

Unidade VI - Estrutura de Controle Condicionais


1. Situando a temtica
Vimos anteriormente que existem vrias linguagens de programao. Algumas delas se parecem muito. A linguagem PHP, por exemplo, foi inspirada na linguagem C. A propsito, a linguagem PHP muito utilizada na criao de pginas dinmicas na Internet. No o caso da linguagem C. Dando continuidade aos conceitos bsicos de programao, veremos agora os condicionais, tambm conhecidos como condio ou seleo . Esse conceito utilizado para selecionar que trecho de um programa deve ser executado sob certas condies. Sem as condies os programas de computador teriam um comportamento "retilneo", isto , no seria possvel a realizao de determinadas operaes que envolvem testes de variveis.

2. Problematizando a temtica
Uma condio o resultado de um teste de comparao. Imaginemos que um programa deve executar a funo A ou a funo B de acordo com o valor da mdia aritmtica calculada a partir de trs notas. Se o valor da mdia for maior ou igual a 7, ento deve ser executada a funo A, caso contrrio deve ser executada a funo B. Assim, em que condio deve ser executada a funo A? Obviamente essa funo dever ser executada se o resultado da comparao entre a mdia calculada e o valor 7 for "a mdia superior ou igual a 7". Os smbolos de comparao utilizados na linguagem C so listados na tabela abaixo. Smbolo Significado == > < >= <= != igual a superior a inferior a superior ou igual a inferior ou igual a diferente de Ateno especial necessria para a comparao de igualdade. Note que o smbolo de comparao formado por dois smbolos de atribuio (==). Um erro comum entre os iniciantes consiste em fazer essa comparao utilizando um nico smbolo de atribuio, o que evidentemente no um teste de igualdade em C. As condies so representadas em C por estruturas de controle ditas estruturas de seleo, implementadas pelas instrues if e switch.

3. Conhecendo a temtica
3.1 A estrutura if ... else O teste if Este teste consiste em realizar uma operao de comparao e indicar o que deve ser feito quando o resultado da comparao verdadeiro. Isto codificado assim: onde expr uma expresso de comparao. A parte do programa escrita entre as chaves { e } denominada um bloco de instrues, tambm chamada simplesmente bloco. A semntica dessa instruo : se o valor da expresso expr for True (verdadeiro), ento o computador dever executar o bloco de instrues pertencente instruo e, em seguida, executar a prxima instruo aps o if. Caso o valor da expresso condicional seja False (falso), a prxima instruo aps o if ser executada.

if (expr) { Bloco de instrues } prxima instruo

301

Graficamente, a semntica deste teste representada assim:

.....
True Bloco

expr False

prxima instruo

Problema1. Testar a varivel idade, correspondente idade de uma pessoa. Se o valor dessa idade for maior do que ou igual a 18, imprimir uma mensagem informando esse fato.

if (idade>=18) { printf( voce eh maior de idade ) ; } prxima instruo;

Observao. Quando h somente uma instruo entre as chaves, estas se tornam facultativas. Pode-se ento escrever: if(idade>=18) printf( voce eh maior de idade ) ; prxima instruo;

Eis ao lado um cdigo completo (cdigo1) que pode ser testado. Este cdigo pode servir de base para testar os exemplos dos prximos testes. No deixe de faz-los.

#include <stdio.h> int main() { long idade = 25; if (idade >= 18) { printf("Voce eh maior de idade!\n"); } system("PAUSE"); // ou getch() return 0; }

Uma questo de legibilidade A disposio das chaves no muito importante. O programa funcionar tambm se voc escrever assim if(idade>=18) {printf("Voce eh maior de idade!\n");}, mas vemos claramente que a disposio anterior mais legvel. Essa a recomendao do estilo C. O teste else o uso de else para dizer "caso contrrio" Agora que sabemos fazer um teste simples, hora de ir um pouco mais longe. Se o teste no funcionar, isto , se o resultado da avaliao da expresso de comparao for False e a soluo que est sendo codificada exigir que seja dito explicitamente ao computador o que fazer, trata-se de outro tipo de teste: if ... else. Para codificar este teste basta adicionar aps o bloco correspondente ao resultado True, outro bloco, agora precedido da palavra reservada else. Esse bloco conhecido como bloco else. Por exemplo,

302

Se o resultado da expresso de comparao for verdadeiro (True), ser executada a instruo printf("voce eh maior de idade") e a execuo do programa far um salto para "prxima instruo". Se o resultado for falso (False), ser executada a instruo printf("voce eh menor de idade") e a execuo do programa continuar em "prxima instruo". Observe que apenas um dos blocos de instrues executado. A execuo de um impede a execuo do outro. Relembrando! De modo geral, o que executado quando o resultado da expresso de comparao verdadeiro denomina-se Bloco True e o que executado quando esse resultado falso, denomina-se Bloco False. Um bloco constitudo por uma ou mais instrues. Quando um bloco possui apenas uma instruo, o uso das chaves facultativo. if (idade>=18) { printf("voce eh maior de idade ") ; } else { printf("voce eh menor de idade") ; } prxima instruo; Graficamente a semntica deste teste representada assim:

.....
True Bloco True

expr False Bloco False

prxima instruo O teste else if ... para dizer "caso contrrio, se ..." Quando o primeiro teste no funcionar e a situao exigir, Bloco False poder conter outro if ... else. Vejamos o exemplo a seguir. if (idade >= 18) { printf("voce eh maior de idade"); } else if ( idade >= 12 ) { printf("voce eh um adolescente"); } else { printf("Paciencia, voce ainda eh uma criana"); } prxima instruo O computador faz os testes em ordem. 1. se a expresso (idade>=18) avaliada True, a instruo printf("voce eh maior de idade"); executada e o controle da execuo passa para prxima instruo.

2. se a expresso (idade>=18) avaliada False, o Bloco Else executado. Notar que esse bloco um if ... else. Assim, a segunda expresso de comparao (idade > 12) avaliada. Se True, printf("voce eh um adolescente"); executada. Se False, printf("Paciencia, voce ainda eh uma criana"); executada. Em qualquer dos casos, aps a execuo de printf, prxima instruo ser executada.

303

Ateno! O else e o else if no so obrigatrios, mas geralmente facilitam o modo de escrever e tornam o programa mais legvel. Graficamente a semntica deste teste representada assim:

.....
expr False expr False Bloco False True Bloco True True Bloco True

prxima instruo

Problema2. Ler um valor inteiro n e imprimir a mensagem "n pertence ao intervalo i", onde i = 1, 2, 3 ou 4 de acordo com a tabela ao lado. Uma soluo pode ser o cdigo abaixo. Observar o modo como feito o teste de pertinncia a um intervalo. Este no o nico modo, logo sero vistos outros. Procure entender bem o funcionamento desses testes, pois esse entendimento indispensvel para a seqncia do curso. #include <stdio.h> int main() { long n; printf("Digitar um valor inteiro. \n"); scanf("%d",&n); printf("valor de n = %d\n",n); /**** testar a pertinncia a um intervalo ****/ if(n<0) // n pertence ao intervalo 1? {printf("%d pertence ao intervalo 1\n",n);} else if(n<20) // n pertence ao intervalo 2? {printf("%d pertence ao intervalo 2\n",n);} else if (n<100) // n pertence ao intervalo 3? {printf("%d pertence ao intervalo 3\n",n);} else {printf("%d pertence ao intervalo 4\n",n);} printf("Saida do IF\n"); system("pause"); // ou getch(); return 0;

i 1 2 3 4

intervalo n<0 0 n < 20 20 n <100 n >= 100

304

Teste com vrias condies Para realizar testes com vrias condies, necessrio o emprego de alguns conectivos lgicos. Consideremos uma afirmao que, sem ambigidade, apenas pode ser verdadeira ou falsa. Uma afirmao desse tipo denominada uma proposio. Pois bem, os conectivos lgicos so empregados na realizao de operaes sobre proposies. Alguns exemplos de proposies: 3 maior do que 2 5 maior do que 10 (no precisa ficar assustado, esta uma proposio falsa) H vida fora da Terra (mesmo que no se consiga provar, o resultado dessa afirmao s pode ser verdadeiro ou falso, logo se trata de uma proposio) Existem algumas afirmaes que no so proposies, por exemplo, esta afirmao falsa. As proposies so objetos de estudo de um ramo da matemtica denominado Clculo Proposicional. No h necessidade de preocupao neste momento com a teoria das proposies, pois as que sero vistas neste texto so de compreenso natural e imediata, geralmente so afirmaes matemticas corriqueiras. As tabelas abaixo mostram os principais conectivos dessa lgica. Conectivo NOT (smbolo: !) A !A True False False True Conectivo OR (smbolo: ||) B A || B True True False True True True False False

A True True False False

Conectivo AND (smbolo: &&) A B A && B True True True True False False False True False False False False

Essas tabelas se tornaro mais compreensveis com os exemplos a seguir.

Teste AND Para saber se o valor de n pertence ao intervalo 2 do problema anterior (0 n < 20) basta escrever: if(n>=0 && n<20) ... Em portugus se diria: se n maior do que ou igual a 0 e menor do que 20 ... Trata-se de uma condio composta. Ela ser verdadeira apenas se as duas condies envolvidas forem verdadeiras. Teste OU Para saber se uma pessoa possui mais de 20 anos ou se o seu saldo bancrio superior a 5000 reais basta escrever: if(idade>20 || saldo>5000) ... Observe que se pelo menos uma das condies for verdadeira ento a condio composta tambm o ser. Teste NOT Para saber se uma pessoa no menor de idade basta escrever: if(!(idade>=18)) ... Observe que se a condio (idade>=18) verdadeira a sua negao (!(idade>=18)) falsa. A comparao !(idade>=18) corresponde em portugus expresso idade no maior ou igual a 18.

305

3.2 Alguns erros comuns Uso de = em teste de igualdade. Para testar se uma pessoa tem exatamente 18 anos, devemos escrever if(idade == 18) Uso de ponto-e-vrgula no fim da linha que contm um if. Lembrar que if um teste de condio. Coloca-se ponto-e-vrgula no fim de uma instruo e no de um teste de condio.

3.3 Para melhor compreender as condies Acompanhe o cdigo abaixo. #include <stdio.h> int main() { if (0) { printf("falso"); } else { printf("verdadeiro"); } system(pause); } A execuo deste cdigo com as modificaes indicadas para if(expr) fornecer os seguintes resultados: expr resultado 0 falso 1 verdadeiro 2 verdadeiro 5 verdadeiro Resumindo, quando a expresso comparao vale 0 o resultado de sua avaliao False e para qualquer outro valor dessa expresso a sua avaliao True. Por isso os resultados obtidos acima. De fato, toda vez que a linguagem C realiza um teste, ela devolve o valor 1 quando o resultado verdadeiro e 0 quando o resultado falso.

Atribuir o resultado de uma comparao a uma varivel Acompanhe o cdigo abaixo. #include<stdio.h> int main() { int p = 14; int b = 10; b = (p >= b); printf("b = %d\n", b); system(pause); } A comparao p >= b retorna o nmero 1, pois ela verdadeira. Assim, b passa a valer 1, como resultado da atribuio. Isso pode ser verificado com o resultado exibido por printf. Experimente mudar o valor de b para 20 no cdigo ao lado. O resultado exibido deve ser 0, pois desta vez o teste falso.

Um valor boolean Importante! A varivel b do cdigo acima representa um valor boolean. Diz-se que uma varivel que s pode receber os valores 0 ou 1 do tipo boolean. Na verdade, em C no existe este tipo. H uma conveno na linguagem C de modo que 0 associado ao boolean False e qualquer outro valor associado ao boolean True. Em C++, a linguagem C orientada a objeto, um novo tipo foi criado especialmente para conter esses valores. Em C, geralmente as variveis que guardaro valores boolean so declaradas do tipo int. Os valores Booleans nas condies Geralmente fazemos testes sobre variveis booleans. Se a varivel "maior" vale 1 ou qualquer outro valor diferente de 0 e temos a instruo if(maior) {printf(maior de idade)}; ... o resultado exibido a expresso maior de idade, pois a varivel "maior" diferente de zero, portanto True. Quando sabido que a varivel pode conter um nmero fazemos o teste na forma if(varivel == 1). Se a varivel s pode conter os valores 0 ou 1, fazemos o teste na forma if(varivel). Sempre que possvel, bom encurtar os caminhos.

306

3.4 A estrutura switch A condio "if... else" o tipo de condio mais utilizada. Entretanto, quando existem muitas comparaes a serem feitas podemos utilizar outro tipo de estrutura: switch. Analise o seguinte trecho de programa if (idade == 2) { printf("Ola bebe!");} else if (idade == 6) { printf("Oi crianca!");} else if (idade == 12) { printf ("Oi jovem!");} else if (idade == 16) { printf ("Oi adolescente!");} else if (idade == 18) { printf ("Salve adulto!");} else if (idade == 68) { printf ("Ola vovo !");} else { printf ("????????????? ");} Existem seis comparaes a serem feitas. Para no repetir essas comparaes, nova forma de represent-las foi desenvolvida. O trecho de programa abaixo mostra essa nova forma. switch (idade) { case 2: printf ("Ola bebe!"); break; case 6: printf ("Oi crianca!"); break; case 12: printf ("Oi jovem!"); break; case 16: printf ("Oi adolescente!"); break; case 18: printf ("Salve adulto!"); break; case 68: printf ("Ola vovo!"); break; default: printf ("?????????????"); break; } Sempre que possvel, bom escrever utilizando o comando switch, mais prtico. necessrio colocar uma instruo break, obrigatoriamente ao fim de cada caso. Esquecer de faz-lo faz com que o computador continue a executar as instrues seguintes, o que no faz parte da lgica da instruo switch. Enfim, o caso "default" corresponde ao else j visto. Se a varivel no vale nenhum dos valores testados acima o computador executa esta opo.

307

Exemplo de um menu O programa abaixo pode ser utilizado como modelo para a construo de outros menus.

// em um restaurante #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { long menu; printf("=== Menu ===\n\n"); printf("1. Pao com queijo\n"); printf("2. Pao com manteiga\n"); printf("3. Cuscus\n"); printf("4. Ovo frito\n"); printf("\n Sua escolha? "); scanf("%d", &menu); printf("\n"); switch (menu) { case 1: printf("Voce escolheu Pao com queijo!"); break; case 2: printf("Voce escolheu Pao com manteiga!"); break; case 3: printf("Voce escolheu Cuscus!)"); break; case 4: printf("Voce escolheu Ovo frito!"); break; default: printf("Voce no fez a escolha correta!"); break; } printf("\n\n"); system("PAUSE");

308

3.5 Condies condensadas Existe ainda um terceiro modo de programar uma comparao, ainda que pouco utilizado. Tratase da condio condensada. como um if else s que tudo em uma mesma linha. Observar atentamente os dois trechos de programa abaixo: Um teste if ... else Se a varivel maior for avaliada como True, isto , se for diferente de zero, ento a varivel idade receber o valor 18, caso contrrio receber o valor 17. if (maior) idade = 18; else idade = 17;

O mesmo teste, condensado A semntica desta instruo idntica do comando if ... else. Se maior for diferente de 0 (True), idade recebe o valor 18. Se maior possui o valor 0, ento idade recebe o valor 17. Trata-se apenas de uma forma condensada de escrever a estrutura if ... else.

idade = (maior) ? 18 : 17;

3.6 Teste 1. O que significa o smbolo <= ? ( ) Superior ( ) Inferior ( ) Superior ou igual ( ) Inferior ou igual ( ) Diferente de 2. Se a varivel n vale 0, o que exibido pelo trecho de programa abaixo? if (n != 0) printf ("Siga em frente."); else printf ("Aguarde um pouco."); .

( ) Siga em frente. ( ) Aguarde um pouco

3. Observe o trecho de programa abaixo. O que ser impresso? int temDinheiro = 0, maior = 0; long dinheiroEmBolso = 10000, idade = 19; ... temDinheiro = dinheiroEmBolso > 10000; maior = !(idade < 18); if (temDinheiro && maior) printf ("Pode abrir conta em banco!"); else printf ("Impossivel abrir conta"); ( ) Pode abrir conta em banco! ( ) Impossivel abrir conta

309

4. Qual o problema na instruo abaixo? switch (k) { case 5: printf ("Bom dia"); case 12: printf ("Boa tarde"); default: printf ("Ate logo"); } ( ) faltam as instrues break ( ) falta um ponto-e-vrgula no fim de switch ( ) faltam as chaves em cada "case" ( ) "case default" e no "default"

5. Quanto valer a varivel resp aps as instrues abaixo? A varivel a vale 200 e b um Boolean que vale False. resp = (b || a >= 200) ? 20 : 30; resp = (resp == 20 && (b && a >= 200)) ? 40 : 50; ( ) 20 ( ) 30 ( ) 40 ( ) 50

4. Avaliando o que foi construdo


Compreender bem as estruturas de seleo uma condio indispensvel para escrever bons programas. Parece que tudo indispensvel, no? Mas assim mesmo. Existe uma seqncia lgica no aprendizado de uma linguagem de programao. como na matemtica. praticamente impossvel calcular uma derivada, conscientemente, se no conhecemos os conceitos de funo, limites e de continuidade. Como veremos a seguir, as estruturas de repetio traro embutidas estruturas de seleo.

5. Referncias
1. Ascencio, Ana F G., Campos, Edilene A V., Fundamentos da Programao de Computadores: Algoritmos, Pascal, C/C++ e Java, 2 edio, Pearson Education, 2007. 2. Hutchison, Robert C., Just, Steven B., Programming using the C language. MGraw-Hill Book Company, 1988. 3. Kernighan, Brian W., Ritche, Dennis M., Le langage C, Masson, 1986.

310

Unidade VII - Estruturas de Controle (Repeties)


1. Situando a temtica
Aps termos visto como realizar uma operao de seleo chegado o momento de entendermos as repeties ou "laos". O que um lao? Trata-se de uma tcnica que permite repetir as mesmas instrues vrias vezes. Da mesma forma que para as comparaes, existem vrias formas de realizar os laos. Veremos trs dessas formas. while do ... while for Os laos, em geral, funcionam assim: 1. O computador executa as instrues de cima para baixo (como de hbito) 2. Ao atingir o fim do lao, retorna para a primeira instruo deste. 3. Pode haver saltos para fora do lao 4. Existe uma condio embutida nos laos 5. Essa condio controla a repetio das instrues e a sada do lao

instrues instrues .................. instrues

A existncia da condio nos laos necessria para impedir que as instrues fiquem sendo executadas indefinidamente. Ento, ao criarmos um lao, criamos tambm, implicitamente, uma condio. A condio significa: repetir este lao enquanto (at que) a condio seja verdadeira .

2. Problematizando a temtica
Suponhamos que necessitemos imprimir todos os nmeros naturais de 1 at 100. Uma maneira de faz-lo chamarmos 100 vezes a funo printf tendo como argumento em cada chamada o nmero natural desejado. uma soluo, mas com certeza a menos indicada. Imagine se tivssemos de imprimir os 1000 primeiros nmeros naturais. As repeties nos oferecem um modo confortvel de realizarmos esta tarefa, como veremos.

3. Conhecendo a temtica
3.1 O lao while A estrutura de um lao while while ( <condio> ) { } Bloco de instrues Sua interpretao muito simples: enquanto a condio for avaliada True, o bloco de instrues do lao executado. Quando a condio for avaliada False, o controle do programa passa para a prxima instruo, fora do lao. Evidentemente, pode ser que as instrues do lao no sejam executadas nenhuma vez. Por qu?

311

Exemplo1. Faamos um pequeno teste: escrever um programa que leia um nmero inteiro a partir do teclado. Enquanto esse nmero no for negativo, voltar a ler um nmero inteiro a partir do teclado.

#include<stdio.h> main() { int n=0; while (n>=0) { printf("Digitar um numero positivo ou nulo: "); scanf("%d", &n); } printf("Obrigado! \n") ; system(" pause ") ; return 0 ; }

Ao executar este programa entremos com os seguintes nmeros: Digitar um numero positivo ou nulo: 13 Digitar um numero positivo ou nulo: 21 Digitar um numero positivo ou nulo: 143 Digitar um numero positivo ou nulo: -3 Obrigado!

O programa continuar executando as instrues do lao enquanto o valor digitado for positivo ou nulo e sair do mesmo to logo seja digitado um nmero negativo. Graficamente, a semntica da instruo while pode ser representada assim:

condio true Bloco de instrues

false

prxima instruo

Semntica While Vamos fazer algo mais interessante, executar um lao certo nmero de vezes. Para isso deve-se criar uma varivel que "contar" o nmero de vezes que o lao ser executado. Essa varivel dever valer 0 antes do lao e ser incrementada dentro deste cada vez que o mesmo for executado. A operao "incremento" como sabemos, consiste em aumentar de 1 o valor de uma varivel. Por exemplo, x++ incrementa o valor da varivel x de uma unidade.

Exemplo2. Imprimir (exibir na tela) os nmeros inteiros a partir de 0 at 9.

Acompanhe o trecho de programa abaixo. Completando este trecho de programa, teremos a seguinte sada (experimente faz-lo):

312

.................... long cont = 0; while (cont < 10) { printf("cont = %d\n ",cont); cont++; } .....................

cont = o cont = 1 cont = 2 cont = 3 cont = 4 cont = 5 cont = 6 cont = 7 cont = 8 cont = 9

Procure explicar como isto aconteceu. Ao compreendermos o que se passou poderemos nos divertir aumentado o valor do limite 10 para 100, 1000, etc.

Ampliando o seu Conhecimento

Ateno com os laos infinitos


Ao criarmos um lao temos que ter a certeza de que ele ir parar em algum momento. Observemos que neste tipo de lao se a condio sempre verdadeira, o programa nunca pra.

Exemplo de um lao infinito. while (1) { printf("laco infinito\n"); } Lembremo-nos dos booleans: 1 = True, 0 = False. Aqui a condio sempre verdadeira, portanto o programa imprimir a frase "lao infinito" sem parar. Na verdade a interveno humana pode parar este programa bastando teclar Ctrl + C.

Evitemos a todo custo cairmos em um lao infinito, a menos que este seja o nosso propsito. s vezes esses laos so necessrios. Na programao de jogos, por exemplo. 3.2 O lao do ... while Este tipo de lao bastante similar ao lao while, porm menos utilizado. A diferena entre as duas instrues est na colocao fsica da condio dentro dos laos. Neste tipo de lao a condio aparece aps o bloco enquanto que em while a condio colocada antes do bloco. Isto quer dizer que as instrues internas ao lao do ... while so executadas pelo menos uma vez. Graficamente, a semntica da instruo do ... while pode ser representada assim:

Bloco de instrues

true

condio

false

prxima instruo

Semntica Do ... While

313

Exemplo3. Resolver o mesmo problema de Exemplo2, agora utilizando a instruo do ... while.

Qual a diferena operacional entre este programa e aquele do Exemplo2? Muito simples, no programa do exemplo2 o bloco de instrues poder nunca ser executado bastando para isto que a condio seja falsa no incio. Caso o valor de cont seja inicializado com 30, por exemplo, a condio ser falsa na primeira vez em que for avaliada. No programa do exemplo3 o bloco de instrues ser executado pelo menos uma vez. responsabilidade do programador gerenciar bem a execuo dos laos. Para no esquecer! No devemos esquecer de colocar ponto-e-vrgula no fim da instruo do ... while. Este esquecimento um erro comum entre os principiantes. 3.3 O lao for Em teoria, o lao while permite realizar todas as repeties que algum deseje programar. Entretanto, como para as condies, existe uma forma condensada, mais rpida para escrever: o lao for. Os laos for, que sero vistos nesta seo, e os laos while so os mais utilizados em programao. Estudaremos o lao for a partir de um exemplo. Exemplo4. Resolver o mesmo problema de Exemplo2, agora utilizando a instruo for.

..................... long cont = 0; do { printf("cont = %d\n",cont); cont++; } while (cont<10); .....................

Uma soluo para este problema dada pelo trecho de programa ao lado. Complete-o e verifique que a sua sada igual do Exemplo1.

Uma soluo para este problema dada pelo trecho de programa ao lado. Complete-o e verifique que a sua sada igual do Exemplo2.

............................. long cont; for (cont = 0; cont < 10; cont++) { printf("cont = %d\n",cont); } ...............................

O lao for outra forma de escrever um lao while. Algumas observaes


A varivel cont no foi inicializada a zero quando de sua declarao, mas poderia ter sido. No h mais incremento cont++ dentro do bloco de instrues

Vejamos o que h entre os parnteses pois l que se encontra todo o interesse do lao for. Na verdade, existem trs instrues, separadas por vrgulas, dentro desses parnteses:

A inicializao: esta instruo utilizada para preparar a varivel cont. Em nosso caso, ela foi inicializada com zero.

314

A condio: como para o lao while, a condio que diz se o bloco deve ser repetido. Enquanto a condio for verdadeira o bloco executado. O incremento: esta ltima instruo executada ao fim de cada execuo do bloco para atualizar a varivel de controle. s vezes utilizado um decremento no lugar de um incremento. s vezes tambm, se utiliza outras operaes como cont += 2; para avanar de 2 em 2, por exemplo.

Enfim, o lao for ser muito til. Saibamos utiliz-lo bem. 3.4 Teste 1. Qual destes laos no existe em C? ( ) for ( ) repeat ( ) do.. while ( ) while

2. Quantas vezes a mensagem "Estude Matematica" ser exibida? long cont = 12; do { printf ("Estude Matematica\n"); cont++; } while (cont < 13); ( ) 0 vezes ( ) 1 vez ( ) 2 vezes ( ) 12 vezes ( ) 13 vezes

3. Quantas vezes a mensagem "Sistemas operacionais" ser exibida? long cont = 10; while (cont < 11) { printf ("Sistemas operacionais\n"); } ( ) 0 vezes ( ) 1 vez ( ) 14 vezes ( ) 15 vezes ( ) infinitas vezes

4. Qual dos laos for poderia exibir as mensagens seguintes? Linha n 1 Linha n 3 Linha n 5 Linha n 7 ) for (cont = 1; cont < 9 ; cont += 2) ) for (cont = 1; cont <= 7 ; cont ++) ) for (cont = 0; cont < 9 ; cont += 2) ) for (cont = 1; cont < 8 ; cont ++)

( ( ( (

E para concluir, um lembrete que todos compreendero, com certeza.

#include<stdio.h> int main() { int cont = 0; for(cont=1; cont<=100; cont++) printf("Eu devo entregar minhas tarefas em dia."); } 315

4. Avaliando o que foi construdo


As estruturas de repetio facilitam bastante a realizao das tarefas, como visto. preciso que o programador esteja familiarizado com essas estruturas, pois elas so necessrias na maioria dos programas que so desenvolvidos. Com os conhecimentos adquiridos at aqui o aluno capaz de programar a soluo de boa parte dos problemas numricos. Esses recursos sero complementados na prxima unidade com o estudo das funes.

5. Referncias
1. Ascencio, Ana F G., Campos, Edilene A V., Fundamentos da Programao de Computadores: Algoritmos, Pascal, C/C++ e Java, 2 edio, Pearson Education, 2007. 2. Hutchison, Robert C., Just, Steven B., Programming using the C language. MGraw-Hill Book Company, 1988. 3. Kernighan, Brian W., Ritche, Dennis M., Le langage C, Masson, 1986.

316

Unidade VIII - Funes


1. Situando a temtica
Conclumos a parte dos conhecimentos bsicos da linguagem C com esta noo fundamental que so as funes. Todos os programas em C se baseiam sobre este princpio. Aprenderemos a estruturar um programa em pequenas partes. Um programa grande em C feito de pequenas partes que so encaixadas adequadamente formando um todo. Essas partes so as funes. Lembremos a estrutura de um programa em C.

# include < stdio.h > Diretivas de pr processador # include < stdlib.h > int main(int argc, char * argv[]) { funo system(" pause" ); return 0; }
As diretivas de pr-processador comeam sempre por # e so geralmente colocadas no incio do arquivo fonte. Em seguida aparece a funo main, a funo principal de todo programa. Nas unidades anteriores permanecemos sempre dentro desta funo, ou seja, todos os clculos e outros processamentos foram feitos no interior da funo main. Na prtica, quase nenhum programa escrito unicamente dentro da funo main. Vamos ento aprender a dividir a soluo de um problema em vrias partes, cada uma dessas partes ser uma funo.

2. Problematizando a temtica
Um programa que realiza vrias tarefas pode ser escrito como uma nica funo, a funo principal, main. Entretanto, essa estratgia torna o programa difcil de ser lido e mesmo desenvolvido. Por isso, costume dos analistas subdividirem um problema complexo em subproblemas, menos complexos obviamente, e resolver cada um desses por meio de uma funo. Esse mtodo conhecido como dividir para conquistar. Aprenderemos a programar essas unidades de programa agora.

3. Conhecendo a temtica
3.1 Objetivo de uma funo Uma funo executa aes e retorna um resultado. As aes realizadas por uma funo dependem, geralmente, de alguns parmetros iniciais denominados de entrada e o resultado produzido denominado sada. Esquematicamente, podemos representar uma funo assim:

entrada

Processamento Funo

sada

317

Uma funo ento um elemento lgico de programao que comporta trs etapas: 1. Entrada: informaes necessrias ao processamento so passadas funo. 2. Processamento: operaes realizadas, geralmente a partir das entradas. 3. Sada: terminado o processamento, a funo retorna um resultado. Imaginemos uma funo que calcule a soma de dois valores inteiros. Podemos represent-la esquematicamente como abaixo, onde a e b so valores inteiros. a a

Somar a e b

a+b

Em geral as funes so mais complexas que o exemplo acima, mas esses so os conceitos a conservar: entrada de parmetros, processamento a ser realizado e sada do resultado produzido. 3.2 A estrutura de uma funo A estrutura de uma funo bem simples. Vejamos um modelo. tipo nomedaFuno(parmetros) { Algumas consideraes:

tipo: tal como as variveis, toda funo possui um tipo. O tipo de uma funo indica o tipo do instrues resultado que ela retornar. Mas existe funo } que no retorna valor algum para o programa que a chamou. Neste caso a funo dever ser de um tipo especial void significando esse fato; nomedaFuno: o nome da funo, evidentemente, e deve obedecer s mesmas regras que os nomes de variveis; parmetros: uma lista de parmetros entre parnteses, separados por vrgula, que contm as entradas necessrias ao processamento da funo. Uma funo pode conter qualquer nmero de parmetros, dependendo da lgica e do bom senso do programador. { ... }: aps o cabealho da funo (tipo, nome e parmetros), segue um par de chaves que contm o corpo da funo, as instrues que a compem. 3.3 Criando uma funo Vamos escrever a funo que soma dois valores inteiros, vista anteriormente e dar-lhe o nome soma2. Eis a nossa primeira funo. O que vemos nessa funo? long tipo dos parmetros e de retorno da funo, por isso a varivel resposta tambm desse tipo soma2 o nome dado funo return instruo que indica funo para retornar um resultado ao programa que a chamou. Esta instruo geralmente se encontra no fim da funo. Como a varivel resposta declarada dentro do corpo da funo, seu escopo ser a prpria funo. O escopo de uma varivel o seu campo de abrangncia (onde ela vlida). Uma varivel declarada assim chamada local e no pode ser utilizada fora da funo onde declarada. A varivel resposta ento uma varivel local funo soma2. A funo soma2 definida acima, ser chamada de dentro da funo principal (main) de um programa. long soma2(long p1, long p2) { long resposta = 0; resposta = p1+p2; return resposta; }

318

3.4 Chamando uma funo #include<stdio.h> long soma2(long p1,long p2) { long resposta = 0; resposta = p1+p2; return resposta; } int main() { long a,b, soma; printf("\n digite um valor para a = "); scanf("%d",&a); printf("\n digite um valor para b = "); scanf("%d",&b); soma=soma2(a,b); printf(" soma = %d\n", soma); system("pause"); return 0; } Para chamar uma funo a partir da funo main ou de qualquer outra funo, basta escrever o seu nome em uma expresso ou como um parmetro em um comando printf. No programa ao lado a funo soma2 est sendo chamada a partir da funo main. Observe que o nome da funo aparece em uma expresso, do lado direito de um comando de atribuio. O nome de uma funo nunca pode aparecer do lado esquerdo em uma atribuio. Lembre que uma atribuio do tipo varivel = expresso. Uma funo pode chamar outra, que pode chamar outra, etc. Cabe ao programador no perder o domnio sobre a execuo do cdigo.

Os parmetros declarados no cabealho de uma funo so ditos parmetros formais, pois servem apenas para dizer ao compilador o tipo e a ordem em que os parmetros efetivos sero transmitidos funo. Parmetros efetivos so aqueles que aparecem na chamada da funo. No programa acima os parmetros efetivos so a e b e os parmetros formais so p1 e p2. Os parmetros efetivos e os formais podem ter os mesmos nomes, porm representam identificadores distintos.

Ampliando o seu Conhecimento


Prottipo de uma funo. O prottipo de uma funo o seu cabealho seguido de ponto-e-vrgula. Exemplo. long soma2(long p1,long p2); Um prottipo pode tambm indicar apenas os tipos dos parmetros: Exemplo. long soma2(long,long); Na definio da funo os parmetros formais sero explicitados.

Uma funo pode ser definida tambm aps a funo principal. Neste caso, o seu prottipo deve ser declarado antes da funo main. Aps a funo main coloca-se ento a funo que est sendo definida. Usar ou no os prottipos uma deciso do programador. O seu uso indica ao compilador que a funo por ele representada ser definida (codificada) aps a funo main. Caso uma funo seja codificada aps a funo main, sem o uso de prottipo, o compilador acusar um erro, pois quando o nome da funo aparecer, pela primeira vez, na funo main, ele no o reconhecer como nome de uma funo e o tratar como uma varivel no declarada acusando, portanto erro por falta de declarao de varivel.

319

O exemplo anterior ficaria assim: #include<stdio.h> /* declarao do prottipo */ long soma2(long p1, long p2); int main() { long a,b, soma; printf("\n digite um valor para a = "); scanf("%d",&a); printf("\n digite um valor para b = "); scanf("%d",&b); soma=soma2(a,b); printf(" soma = %d\n", soma); system("pause"); return 0; } /* definio da funo soma2 */ long soma2(long p1,long p2) { long resposta = 0; resposta = p1+p2; return resposta; } Ampliando o seu Conhecimento
No somos obrigados a armazenar o resultado produzido por uma funo em uma varivel. Podemos retornar esse resultado na forma indicada de uma expresso. Vejamos,

#include <stdio.h> long soma2(long p1, long p2) { return p1+p2; }


Neste caso, no foi necessrio declararmos a varivel resposta uma vez que no a utilizamos.

Tambm possvel chamar uma funo a partir de um comando printf. printf(" soma = %d\n", soma2(a,b));

Observe que acima a funo soma2 est sendo chamada a partir da lista de parmetros da instruo printf.

3.5 Mais exemplos I. Converso Celsius/Fahrenheit Lembremo-nos que a relao entre as escalas Celsius e Fahrenheit dada por:

C F 32 = . 100 180

Ento, de posse dessa informao vamos escrever uma funo que transforme uma temperatura dada em Celsius para Fahrenheit. Escreveremos apenas a funo. Escreva o programa principal (a funo main). /* funo converso: Celsius em Fahrenheit */ float converte(long C) { long F = 0; F = 180*C/100+32; return F; } Antes de escrever a funo principal, responda ao pequeno questionrio a seguir.

1. 2. 3. 4.

Qual o parmetro formal, na funo converte? Quantos parmetros efetivos devem existir na chamada da funo converte? Qual o tipo do parmetro efetivo? Como ser feita a chamada funo converte (comando de atribuio ou parmetro na funo printf)?

Pronto! Agora s escrever a funo main.

320

II. Transformar segundos em horas, minutos e segundos A funo abaixo transforma n segundos em horas, minutos e segundos. Essa funo no retornar nenhum valor. Ela imprimir o resultado obtido sem a necessidade de retorn-lo para a funo main. /* funo tempo: segundos em horas, minutos e segundos */ void tempo(int s) { int ss, mm, hh, t; ss = s%60; // resto da diviso de s por 60 t = s/60; // quociente inteiro de s por 60 mm = t%60; // resto da diviso de t por 60 hh = t/60; // quociente inteiro de t por 60 printf(%d segundos = %d horas, %d minutos e %d segundos, s,hh,mm,ss); }

Antes de escrever a funo principal, responda ao pequeno questionrio a seguir. 1. 2. 3. 4. 5. Qual o tipo da funo tempo? Qual o parmetro formal, na funo tempo? Quantos parmetros efetivos devem existir na chamada da funo tempo? Qual o tipo do parmetro efetivo? Como ser feita a chamada funo tempo (expresso ou parmetro na funo printf)?

Pronto! Agora s escrever a funo main. Uma dica: a chamada funo tempo pode ser assim tempo(n);. III. rea de um retngulo A rea de um retngulo dada por: largura * altura. Nossa funo AreaRetangulo deve receber dois parmetros, largura e altura e retornar a rea calculada. /* funo AreaRetangulo */ float AreaRetangulo(float larg, float alt) { return larg * alt; } Escreva a funo main(). Modifique a funo AreaRetangulo para que ela imprima a rea calculada e no precise retorn-la funo main.

IV. Um menu Acompanhe o exemplo abaixo. Trata-se da elaborao de um menu, onde podemos escolher qual operao ser executada: o clculo da rea de um crculo, de um quadrado, de um retngulo ou de um trapzio. Este roteiro poder ser utilizado para a elaborao de outros menus. Basta fazer as adaptaes que se fizerem necessrias.

321

/* funo menu */ long menu() { int escolha= 0; while (escolha < 1 || escolha> 4) { printf("Menu :\n"); printf("1 : Para calcular a area de um circulo\n"); printf("2 : Para calcular a area de um quadrado\n"); printf("3 : Para calcular a area de um retangulo\n"); printf("4 : Para calcular a area de um trapezio\n"); printf("Sua escolha ? "); scanf("%d", &escolha); } return escolha; }

Texto da funo menu

int main(int argc, char *argv[]) { float r,l, la, lb, area; switch (menu()) { case 1: printf("Raio do circulo ="); scanf("%f",&r); printf("\nArea = %f\n", 3.14*r*r); break; case 2: printf("Lado do quadrado ="); scanf("%f",&l); area=l*l; printf("\nArea = %f\n",area); break; case 3: printf("Lados do retangulo\n"); printf("lado a = "); scanf("%f",&la); printf("lado b = "); scanf("%f",&lb); printf("\nArea = %f\n",la*lb); break; case 4: printf("Bases do trapezio\n"); printf("base maior a = "); scanf("%f",&la); printf("base menor b = "); scanf("%f",&lb); printf("altura l = "); scanf("%f",&l); printf("\nArea = %f\n",(la+lb)*l/2); break; } system("PAUSE"); return 0; }

Texto da funo main

322

3.6 Teste 1. O que acontece aps um return?


( ) A funo pra e retorna o resultado indicado ( ) A funo continua e retorna o resultado indicado ( ) A funo continua e no retorna resultado

2. Em que caso a instruo return no obrigatria?


( ) Quando a funo no possui parmetro de entrada ( ) Quando a funo de tipo void ( ) Quando a funo deve retornar zero

3. O que so os parmetros de uma funo?


( ) Indicaes sobre o nome da funo ( ) Indicaes sobre o valor que ela deve retornar ( ) Variveis que lhe so enviadas para serem usadas internamente

4. Qual das afirmaes falsa?


( ) Uma funo no obrigada a retornar um valor ( ) Uma funo pode retornar um valor de qualquer tipo de varivel ( ) Uma funo pode retornar vrios valores pela instruo return

5. O que h de errado na funo abaixo? long quadrado(long num) { long resposta = 0; resposta = num * num; } ( ) A funo no retorna nenhum valor ( ) Falta um ponto-e-vrgula em algum lugar da funo

4. Avaliando o que foi construdo


As funes em linguagem de programao, como voc j percebeu, surgiram para facilitar a programao de problemas considerados complexos. Esses problemas requerem uma soluo longa o que dificulta o seu desenvolvimento e sua compreenso. Os programas so entes abstratos, frutos da imaginao. Por isso mesmo no so fabricados, no sentido em que o so os produtos das engenharias convencionais, como uma casa, um navio, etc. Assim, quando nos referimos a um programa de computador, sempre usamos o termo desenvolvimento em lugar de fabricao. De fato, desenvolvemos uma soluo para um dado problema, um algoritmo. nessa fase do projeto de soluo que o problema quebrado em subproblemas. A soluo de cada subproblema ento implementada como uma funo. Mais uma vez, s as repeties, os exerccios, conduzem ao domnio da tcnica.

323

5. Referncias
1. Ascencio, Ana F G., Campos, Edilene A V., Fundamentos da Programao de Computadores: Algoritmos, Pascal, C/C++ e Java, 2 edio, Pearson Education, 2007. 2. Hutchison, Robert C., Just, Steven B., Programming using the C language. MGraw-Hill Book Company, 1988. 3. Kernighan, Brian W., Ritche, Dennis M., Le langage C, Masson, 1986.

324

Unidade IX - Ponteiros
1. Situando a temtica
Nesta unidade estudaremos um novo tipo de dado, os ponteiros. Veremos como eles funcionam e para que servem. quase impossvel hoje em dia escrever programas em C sem fazer uso dos ponteiros. Mesmo sem saber ns j o utilizamos quando realizamos leituras com a funo scanf. A noo de ponteiros importante para lidarmos com outro tipo de dado muito utilizado denominado array. Mesmo que o escopo deste texto no cubra outros tipos de dados abstratos de grande utilizao na computao, importante saber, principalmente para aqueles que pretendem avanar mais no estudo de resoluo de problemas com o uso de computador, que vrios desses tipos de dados so implementados base de ponteiros. A ttulo de ilustrao sobre esses tipos citamos: rvores e listas encadeadas.

2. Problematizando a temtica
Um problema estranho Escrever uma funo que retorne 2 ou mais valores. Isso parece ser "Impossvel"! Sabemos que uma funo tem as seguintes caractersticas: Retorna um nico valor ou no retorna valor algum Se uma funo do tipo T ento ela retorna um valor do tipo T Vamos adquirir os conhecimentos necessrios para solucionar problemas deste tipo.

3. Conhecendo a temtica
3.1 Um pouco mais sobre funes Retomemos o problema de transformar segundos em horas, minutos e segundos, apresentado na unidade IX. /* funo tempo: segundos em horas, minutos e segundos */ void tempo(int s) { int ss, mm, hh, t; ss = s%60; // resto da diviso de s por 60 t = s/60; // quociente inteiro de s por 60 mm = t%60; // resto da diviso de t por 60 hh = t/60; // quociente inteiro de t por 60 printf(%d segundos = %d horas, %d minutos e %d segundos, s,hh,mm,ss); } Observamos que a funo do tipo void, isto , no retorna valor algum. De fato, o resultado calculado impresso na prpria funo. Por que no foi possvel retornar esses valores para a funo main? Quando passamos uma varivel para uma funo, como argumento, uma cpia dessa varivel feita e passada para a funo. Assim, se na funo main existir uma varivel de nome s, que represente o nmero de segundos a ser transformado, a varivel s na funo tempo no a mesma que aquela de main. Trata-se apenas de uma cpia. Tudo se passa da mesma forma caso as variveis correspondentes tenham nomes distintos.

325

De modo geral, a transmisso de parmetros se passa assim: int main() int a,b,c ..................... x = f(a,b,c); int f(int x, int y, int z)

cpia de c cpia de b cpia de a

Observemos que na funo main, ao ser executada a instruo x = f(a,b,c); so criadas cpias dos parmetros reais (as variveis a, b e c) e essas cpias so passadas para a funo f. Na funo f, as cpias transmitidas recebem os nomes x, y e z, respectivamente, parmetros formais. Assim, se alguma alterao ocorrer nos valores de x, y ou z essa alterao no afetar os valores de a, b ou c, pois isso ocorreu apenas na cpia dessas variveis ficando os seus originais intactos. A soluo do problema proposto, como veremos, apenas um exemplo da utilidade dos ponteiros. A memria e os endereos
Endereo Valor

0 1 2 3

145 3.8028322 0.8272555 39014768

mais ou menos assim que podemos representar a memria principal (RAM) de um computador. A memria composta de clulas. Cada clula possui um nmero, seu endereo. A memria possui um grande nmero de endereos, comeando sempre por 0. Em cada endereo podemos armazenar UM e UM S nmero. Observemos tambm que na memria podemos armazenar apenas nmeros. Ela no pode armazenar letras, frases, etc. Para contornar esse problema foi inventada uma tabela, denominada ASCII, j vista na unidade II.

Endereo e valor Ao criarmos uma varivel soma do tipo long, por exemplo, ... ... escrevemos: long soma = 300; e o programa solicita ao sistema operacional n-1 940.5118 permisso para utilizar a memria. Como resposta o sistema operacional indica em qual endereo o programa pode armazenar um valor de tipo long para a varivel soma. Alis, este um dos papis principais de um sistema operacional, gerenciar a alocao de memria para os programas. Voltemos nossa instruo. O valor 300 armazenado em alguma parte da memria, digamos no endereo 1540. A partir de ento, a palavra soma no programa substituda, via compilador, pelo endereo 1540. A cada ocorrncia da palavra soma no programa, o computador verifica ento o endereo 1540. Para o programador tudo bastante transparente. Basta escrever soma em uma expresso aritmtica, em uma instruo de leitura (scanf) ou impresso (printf). Vejamos, printf("A variavel soma vale: %d", soma); Resultado na tela: A varivel soma vale: 300

Sabemos exibir o valor de uma varivel, mas poderamos exibir o seu endereo? Para exibir o endereo de uma varivel deve-se utilizar o especificador de formato %p (p da palavra ponteiro) na instruo printf. De outro modo, enviamos funo printf no a varivel soma, mas seu endereo. E para fazer isso devemos colocar o smbolo & antes do nome da varivel. J fazemos

326

isto habitualmente quando utilizamos a funo scanf. Ento para imprimir o endereo da varivel soma devemos escrever printf("O endereo da variavel soma eh: %p", &soma); Resultado na tela: O endereo da varivel soma eh: 0023FF74

O que aparece na tela um nmero sim. Um nmero hexadecimal, no lugar dos nmeros decimais aos quais estamos acostumados. Esse o endereo da varivel soma na memria do computador, designado pelo sistema operacional como explicado acima. Se trocarmos %p por %d na instruo printf acima obtemos um nmero decimal como sada. Entretanto, %p foi implementado especialmente para exibir endereos, por isso preferimos esta notao. Ateno! Ao executarmos um programa em computadores diferentes, o endereo de uma varivel ser certamente diferente de um computador para outro. Isso depende dos programas que esto carregados na memria dos computadores. No esqueamos que o sistema operacional que se encarrega de gerenciar a memria. , portanto impossvel saber a priori em que endereo uma varivel ser alocada. Em resumo, soma: exibe o VALOR da varivel. &soma: exibe o ENDEREO da varivel. Com soma o computador l o valor da varivel na memria e reenvia esse valor. Com &soma, o computador nos dir em que endereo se encontra a varivel. 3.2 Utilizao de ponteiros At este ponto utilizamos variveis apenas para conter nmeros. A partir de agora vamos aprender a criar variveis que contero endereos: exatamente a isto que chamamos de ponteiros. Ponteiro uma varivel que contm um endereo. Poderamos nos perguntar, mas os endereos no so nmeros tambm? Sim, mas neste caso esses nmeros tm um significado particular: eles representam o endereo de outra varivel na memria. I. Criar um ponteiro Para criar uma varivel de tipo ponteiro, devemos colocar o smbolo * no incio do nome da varivel. Exemplo. Podemos tambm escrever: long *nomeDoPonteiro; long *p1, *p2, *p3; long* p1, p2, p3; Como temos visto ao longo deste curso, muito importante iniciarmos as variveis quando de suas declaraes. ainda mais importante faz-lo com os ponteiros. Para iniciar um ponteiro devemos escrever: A constante NULL indica que o ponteiro p1 no contm nenhum endereo. Essa instruo reservar um espao na memria do computador como se estivssemos criando uma varivel normal. A diferena entre uma varivel ponteiro e as outras variveis j vistas que o contedo desta ser o endereo de outra varivel. Exemplo. A primeira linha significa: "Criar uma varivel de tipo long com valor 300". A segunda linha significa: "Criar long soma = 300; uma varivel de tipo ponteiro cujo valor o endereo da long *pointSoma = &soma; varivel soma". long *p1 = NULL;

327

Observao. No existe um tipo ponteiro como existem os tipos int, long, etc. Ento, no podemos escrever, por exemplo, ponteiro pointSoma; em seu lugar escrevemos long *pointSoma; como visto acima. Isto quer dizer que a varivel pointSoma um apontador para uma varivel de tipo long. Se a varivel soma fosse de tipo int, ento pointSoma deveria ser um apontador para uma varivel de tipo int e escreveramos assim: int *pointSoma; Representao grfica.
Endereo Valor

0 soma 135 pointSoma 15648 n-1

145 3.8028322 300 39014768 135 940.5118

No esquema ao lado verificamos que a varivel soma est alocada na posio 135 da memria enquanto que a varivel pointSoma esta alocada na posio 15648 dessa memria. Observemos que o contedo da posio 15648 exatamente o endereo da varivel soma, isto , 135. Esses valores variam de computador para computador e a cada execuo do programa.

Bem, acabamos de entrar no mundo maravilhoso dos ponteiros. Estudemos o programa fonte abaixo: /* ponteiros1*/ #include<stdio.h> main() { int *pontx = NULL; int x; printf("Entre com um valor inteiro x: "); scanf("%d",&x); printf("\nendereco de x = %p",&x); printf("\nvalor de x = %d",x); pontx=&x; printf("\nendereco de x = %d",pontx); getch(); return 0; } pontx um ponteiro para uma varivel do tipo int &x o endereo da varivel x pontx=&x; o endereo de x armazenado em pontx (varivel ponteiro)

A atribuio do endereo de x a pontx poderia ter sido feita assim tambm: int *pontx = &x; Execute o programa ponteiros1.

E como faramos para imprimir o contedo da varivel apontada por pontx? Experimente incluir a instruo abaixo no cdigo do programa ponteiros1. printf("\nvalor de x = %d", *pontx); Como podemos verificar pela execuo do programa ponteiros1, o valor impresso o mesmo que o de x. Ento a expresso *variavelp onde variavelp uma varivel ponteiro, indica o contedo da varivel apontada por variavelp. Em resumo, dado o trecho de programa abaixo, temos:

x ...................... int x=100, *p=NULL; p=&x; 328 35846 100 p 16315 35846

x uma varivel de tipo int [valor de x = 100] &x o endereo da varivel x [endereo de x = 35846] p uma varivel que aponta para uma varivel de tipo int, seu valor um endereo [valor de p = 35846] &p o endereo da varivel p [endereo de p = 16315] *p indica o contedo da varivel apontada por p, isto , o valor de x [valor de *p = 100]

II. Enviar um ponteiro a uma funo O grande interesse dos ponteiros, mas no o nico, consiste em envi-los a uma funo, como parmetro claro, de modo que a funo possa modificar diretamente uma varivel em memria e no apenas sua cpia. Como isto funciona? Vejamos um primeiro exemplo.

void triplicar(long *ponteiroN); int main(int argc, char *argv[]) { long numero = 20; triplicar(&numero); // Passa o endereo de nmero para a funo printf("%d", numero); // Exibe o valor de nmero getch(); return 0; } void triplicar(long *ponteiroN) { *ponteiroN *= 3; // Multiplica por 3 o valor da varivel numero } A funo triplica possui um parmetro de tipo long* (isto , um ponteiro sobre o tipo long). Vejamos o que se passa. 1. Uma varivel "numero" criada na funo main e lhe atribudo o valor 20. 2. A funo triplicar chamada e lhe passado o endereo da varivel numero. 3. A funo triplicar recebe esse endereo na varivel ponteiroN. O contedo da varivel ponteiroN passa ento a ser o endereo de "numero". 4. Como a funo triplicar possui um ponteiro para a varivel numero, poder modificar diretamente o valor dessa varivel na memria. Para isto basta utilizar *ponteiroN para designar a varivel numero. Na funo triplicar utilizamos uma operao de multiplicao *ponteiroN *= 3; para multiplicar por 3 o valor de numero. 5. A instruo printf("%d", numero); na funo main imprimir 60 como o novo valor de numero. O interesse na utilizao de ponteiros se justifica pelo fato de podermos modificar o valor de vrias variveis na memria do computador, o que na verdade uma simulao do retorno de vrios valores por uma funo. Ento, no estamos mais limitados a escrever funes que retornem um nico valor. Interessante no? Enfim, tudo depende do programa que escrevemos. s vezes necessrio retornar um valor por uma funo, um cdigo que dever ser testado na funo main, por exemplo.

329

III. Outro modo de enviar um ponteiro para uma funo No cdigo fonte que vimos no havia ponteiro na funo main. Entretanto, possvel passar um ponteiro para uma funo em sua chamada, como um parmetro real. Vejamos outra verso do programa anterior. void triplicar1(long *ponteiroN); int main(int argc, char *argv[]) { long numero = 20; long *p = &numero; // p recebe o endereo de numero triplicar1(p); // envia p (endereo de numero) a funo triplicar1 printf("%d", *p); // exibe o valor de numero getch(); return 0; } O importante que o endereo da varivel numero tenha sido passado para a funo triplicar1. A diferena entre as duas verses que na primeira foi passado o endereo de numero para a funo triplicar e na segunda um ponteiro foi transmitido. Na verdade, as duas verses fazem a mesma coisa, transmitem um endereo. No incio desta unidade dissemos que mesmo sem saber j utilizvamos o conceito de ponteiro. Agora podemos passar isso a limpo. Trata-se da funo scanf. Ao utiliz-la, devemos informar um endereo de modo que o valor teclado seja armazenado nesse endereo. S pra lembrarmos acompanhemos o texto abaixo. long numero = 0; scanf("%d", &numero);

3.3 Um problema estranho? No incio desta unidade falamos sobre certo problema estranho. hora de tentarmos resolv-lo. Afinal de contas esse problema mesmo estranho? Tratava-se de escrever uma funo que retornasse 2 ou mais valores. Agora temos as ferramentas para solucion-lo. O problema consistia em transformar segundos em horas, minutos e segundos. Mos obra. Apresentamos abaixo uma soluo para esse problema. bom que o leitor tente encontrar sua prpria soluo antes de verificar a que segue.

void novotempo(long* pontHoras, long* pontMinutos, long* pontSegundos) { /* No esquecer de colocar um * antes do nome do ponteiro para poder modificar o valor das variveis e no os seus endereos. */ *pontHoras = *pontSegundos / 3600; *pontMinutos = (*pontSegundos % 3600)/60; *pontSegundos = (*pontSegundos % 3600) % 60;

330

/* programa novotempo */ #include<stdio.h> void novotempo(long* pontHoras, long* pontMinutos, long* pontSegundos); int main(int argc, char *argv[]) { long horas = 0, minutos = 0, segundos=0, segtemp=0; // Entrar com o nmero de segundos printf("Digite o numero de segundos a transformar: "); scanf(("%", &segundos); segtemp=segundos novotempo(&horas, &minutos, &segundos); // Os valores horas, minutos e segundos foram modificados! printf("\n%d segundos corresponde a:\n", segtemp); printf("%d horas\n", horas); printf("%d minutos\n", minutos); printf("%d segundos\n", segundos); getch(); return 0;

Ao digitarmos o valor 27000 para a varivel segundos na execuo do programa acima, teremos a seguinte sada:

Exerccio. Procure explicar como os procedimentos foram realizados no programa novotempo. Explicando-os de forma coerente significa que o conceito de ponteiros foi bem assimilado. 3.4 Resumo Os ponteiros no so simples de trabalhar, reconheamos. No nos preocupemos muito com isto agora. difcil pra todo mundo. O melhor que temos a fazer repassar esta unidade tantas vezes quanto necessrio a fim de consolidarmos este conceito. E para terminar, mais um pequeno resumo. Em C podemos criar duas coisas na memria: variveis e ponteiros.

variveis: com elas que temos trabalhado at aqui. Criar uma varivel muito simples: basta indicar seu nome e seu tipo. long minhaVariavel = 0; // varivel criada na memria (valor 0) Se escrevemos &minhaVariavel, obtemos o endereo da varivel na memria

331

ponteiros: so variveis um pouco particulares, pois elas tomam por valor o endereo de outras variveis. Para criar um ponteiro vazio (que no contm endereo de nenhuma varivel) escrevemos assim: long *meuPonteiro = NULL; Um ponteiro torna-se til quando lhe atribumos por valor o endereo de uma varivel. long *meuPonteiro = &minhaVariavel;

observemos que *meuPonteiro funciona exatamente com se tivssemos escrito minhaVariavel. printf("%d", *meuPonteiro); ento equivalente a printf("%d", minhaVariavel);

O resultado exatamente o mesmo salvo que no primeiro caso passamos por um ponteiro para acessar a varivel. 3.5 Teste 1. Qual dos tipos abaixo corresponde a um ponteiro? ( ) int ( ) double* ( ) long 2. Se digitamos &bola, o que obtemos? ( ) O endereo de bola ( ) O valor de bola ( ) O valor da varivel apontada por bola 3. Se digitamos *total, o que obtemos? ( ) O endereo de total ( ) O valor de total ( ) O valor da varivel apontada por total 4. Por qual valor devemos inicializar um ponteiro? ( ) NOTHING ( ) NULL ( ) MAIN ( ) ADDRESS 5. Examine o cdigo seguinte: long num = 25; long *ponteiro = &num; Supor que num se encontre no endereo 1400 da memria do computador e ponteiro se encontre no endereo 3800. Se na seqncia do programa for solicitada a impresso de *ponteiro, que valor ser exibido na tela?

( ( ( ( (

) 3800 ) 25 ) 1400 )0 ) impresso impossvel

332

4. Avaliando o que foi construdo


O conceito de ponteiro considerado por muitos como aquele em que o programador leva mais tempo para assimilar. Devemos considerar sua grande importncia dentro da programao, pois somente com a sua utilizao podemos trabalhar com estruturas de dados dinmicas, aquelas podem aumentar ou diminuir durante a execuo de um programa dependendo unicamente da disponibilidade de memria. As principais estruturas de dados dinmicas utilizadas em computao so as filas, pilhas e rvores. O estudo dessas estruturas foge ao escopo deste texto, mas podero ser encontradas nos livros sobre estruturas de dados.

5. Referncias
1. Ascencio, Ana F G., Campos, Edilene A V., Fundamentos da Programao de Computadores: Algoritmos, Pascal, C/C++ e Java, 2 edio, Pearson Education, 2007. 2. Hutchison, Robert C., Just, Steven B., Programming using the C language. MGraw-Hill Book Company, 1988. 3. Kernighan, Brian W., Ritche, Dennis M., Le langage C, Masson, 1986.

333

Unidade X - Arrays
1. Situando a temtica
Nesta unidade aprenderemos a criar variveis do tipo array. Os arrays so muito utilizados em C, pois eles so muito prticos. Comearemos explicando o funcionamento dos arrays na memria de um computador. A compreenso desse funcionamento conduz o programador a construir programas mais confiveis. Afinal de contas sempre bom compreender o porqu das coisas.

2. Problematizando a temtica
Ao trabalharmos com um conjunto de valores, podemos faz-lo de modo a utilizar cada valor uma nica vez. Se for este o caso, medida que esses valores forem sendo lidos o processamento necessrio executado e ficaremos satisfeitos. O que ocorre na prtica porm diferente. Imaginemos que se deseje calcular a distncia entre cada elemento de um conjunto e a mdia aritmtica desses valores. Obviamente, precisaremos de cada valor para calcular a mdia. Em seguida, precisaremos outra vez de cada valor para calcular as diferenas. E onde esto esses valores agora? Se o conjunto possuir 100 elementos, por exemplo, podemos dar um nome a cada elemento, mas isso seria um trabalho enorme. Os arrays permitem resolver este tipo de problema sem maiores preocupaes.

3. Conhecendo a temtica
3.1 Os arrays e a memria Arrays so seqncias de variveis de mesmo tipo, situadas em posies contguas na memria. Concretamente, trata-se de vrias variveis de mesmo tipo, portando o mesmo nome e diferenciadas apenas por um ou mais ndices. O nmero de ndices de uma varivel determina a dimenso do array a que ela pertence. Assim, se para identificar uma determinada varivel precisamos utilizar dois ndices, ento essa varivel pertence a um array de duas dimenses. Geralmente chamamos de elementos as variveis de um array. Exemplo. Seja um array de 4 elementos alocado na posio (endereo) 1800. Dizer que um array est armazenado no endereo 1800 apenas uma forma de nos expressarmos. Na verdade, o array comea nessa posio. Vejamos o esquema abaixo. Ao solicitarmos em um programa a criao de um array com 4 elementos, o programa solicita ao sistema operacional espao suficiente na memria para a alocao desse array. Os quatro elementos devem ficar em endereos contguos, um vizinho ao outro, e devem ser todos de um mesmo tipo. Em resumo, sobre os arrays devemos guardar que: Quando um array criado, ele ocupa um espao contguo na memria: os endereos ocupados esto em seqncia, no existe buraco entre eles. Todos os elementos de um array so de um mesmo tipo. Um array de int conter apenas variveis de tipo int e nada mais.

Endereo

Valor

... 2293600 2293601 2293602 2293603 ...


52 10 -65 94

334

3.2 Declarando um array Como sabemos todas as variveis em C devem ser declaradas antes de serem usadas. Comecemos com um exemplo. Vamos declarar um array de 4 elementos de tipo long.

long x[4];

suficiente colocar entre colchetes o nmero de elementos do array. Neste caso, x o nome do array. No existe limite para o nmero de elementos de um array, salvo a memria disponvel.

3.3 Como acessar um elemento de um array Para acessar um elemento de um array devemos escrever: nomeDoArray[n] onde n a posio (ndice) do elemento dentro do array. Ateno. Os elementos de um array so indexados a partir de 0 (zero). Assim, os elementos do array x declarado acima so referenciados por: x[0], x[1], x[2] e x[3]. Observe que no existe o elemento de ndice 4 na declarao acima. Uma tentativa de faz-lo resulta em um erro de execuo. 3.4 Atribuindo valores a um array Para atribuir um valor a um elemento de um array necessrio fazer uma referncia ao elemento desejado e atribuir-lhe um valor como fazemos com qualquer outra varivel. Lembremo-nos que cada elemento uma varivel. Exemplo. long x[4]; x[0] = 52; x[1] = 10; x[2] = -65; x[3] = 94; 3.5 Arrays e ponteiros Existe alguma relao entre arrays e ponteiros? Se escrevermos apenas o nome do array, sem ndice, teremos um ponteiro. Vejamos o programa ao lado. Resultado: temos o endereo 2293600 onde comea o array x. Ao solicitarmos a impresso de x obtivemos o endereo do primeiro elemento do array x, portanto o valor de x o endereo de outra varivel, no caso x[0]. Lembremo-nos do conceito de ponteiro. Se, no lugar de printf("%d", x); tivssemos escrito printf("%d", x[0]); teramos obtido como reposta 52, o valor de x[0]. /* Programa array1 #include<stdio.h> int main() { long x[4]; x[0]=52; x[1]=10; x[0]=-65; x[0]=94; printf("%d", x); getch(); return 0; } */

Ateno! Como o nome de um array um ponteiro, podemos utilizar o smbolo * para conhecer o valor do primeiro elemento de um array. Assim, printf("%d", *x); e printf("%d", x[0]); so equivalentes. Experimente.

335

Tambm possvel obter o valor do segundo elemento escrevendo *(x+1) (endereo do array +1). Para os demais elementos o raciocnio o mesmo, *(x+2) referencia o valor do terceiro elemento e assim por diante. 3.6 Listando um array Para listar todos os elementos de um array devemos fazer uso de um comando de repetio. Seria muito incmodo escrever um printf para cada elemento. Imagine s se o array possusse 800 elementos! Vejamos um exemplo com uso do comando for.

/* programa array2 */ #include<stdio.h> int main(int argc, char *argv[]) { long x[4], i = 0; x[0] = 15; x[1] = -45; x[2] = 218; x[3] = 14; for (i = 0 ; i < 4 ; i++) { printf("%d\n", x[i]); } getch(); return 0; }

A execuo deste programa produzir a seguinte sada: 15 -45 218 14 Nosso lao percorre todo o array com a ajuda de uma varivel de controle i. Estude o programa array2 ao lado e procure entender o que se passa. Observe que a varivel de controle i introduzida no cdigo vale 0, 1, 2 e 3. Exerccio. Modifique o cdigo fonte do programa array2 de modo que a sada seja Listagem do array: 15 -45 218 14

Ateno! No tente exibir o valor de x[4]. Um array com 4 elementos possui ndices 0, 1, 2 e 3. Se tentarmos exibir x[4] ocorrer um erro de execuo e o sistema operacional encerrar o programa avisando que o este tentou acessar um endereo que no lhe pertence. 3.7 Inicializando um array Agora que sabemos percorrer um array somos capazes de inicializar todos os seus elementos com zero, por exemplo, com o uso de um lao. Tente faz-lo antes de ver o programa ao lado. A sada deve ser algo como: x=0000000000 Outro modo de inicializar um array Podemos tambm inicializar um array de modo mais automtico. Essa tcnica consiste em escrever x[4]={valor1, valor2, valor3, valor4} quando da declarao do array. De modo geral, basta escrever os valores entre chaves e separados por vrgula. /* programa array3 inicializa um array */ int main(int argc, char *argv[]) { long x[10], i = 0; // inicializao do array for (i = 0 ; i < 10 ; i++) { x[i] = 0; } // verificao exibio dos valores de x for (i = 0 ; i < 10 ; i++) { printf("x = "); printf("%d ", x[i]); } getch(); return 0; }

Melhor que isso, se fizermos x[4]={10, -32}, os dois primeiros elementos sero iniciados com 10 e -32, respectivamente e os demais sero inicializados com zero. Exerccio. Como inicializar todos os valores a zero utilizando a tcnica acima?

336

3.8 Passagem de arrays como parmetros Ns certamente teremos necessidade de imprimir todos os valores de um array. Por que no escrevermos uma funo para executar essa operao? Isto nos permitir ver como passar um array para uma funo, como parmetro real, claro. Ser necessrio passarmos duas informaes para a funo, o array (seu endereo) e o seu tamanho. De fato, nossa funo dever ser capaz de inicializar um array de qualquer tamanho, por isso a necessidade de conhecer o tamanho do array. Vejamos um cdigo para isso. #include<stdio.h> // Prottipo da funo de impresso void imprimir(long *v, long comp); int main(int argc, char *argv[]) { long vetor[4] = {10, 15, 3}, i = 0; // imprimir o contedo do vetor imprimir(vetor, 4); getch(); return 0;

void imprimir(long *v, long comp) { long i; for (i = 0 ; i < comp ; i++) { printf("%d\n", v[i]); }

Observemos que: 1. vetor em main um ponteiro 2. v em imprimir um ponteiro A funo imprimir toma como parmetro um ponteiro para o tipo long e o tamanho de um array para saber at onde esto os seus elementos. Importante: existe outro modo de indicar que uma funo recebe array. Em vez de indicar que a funo espera um long *v, podemos escrever assim: void imprimir(long v[], long comp) Este comando equivalente ao usado no cdigo apresentado acima, mas a presena dos colchetes lembra ao programador que a funo est aguardando um array. Isto permite evitar confuses. Esta forma bastante utilizada. Exerccios importante escrever vrias funes que trabalhem sobre arrays para que nos tornemos prticos sobre este assunto. 1. Criar uma funo de nome somaVetor que retorne a soma de todos os elementos de um array. Utilize um return para retornar o valor calculado. Como incentivo aqui est o prottipo da funo somaVetor. long somaVetor(long vetor[ ], long comp); 2. Criar uma funo mediaVetor que calcule e retorne a mdia aritmtica dos elementos do vetor. (Ateno. O valor de uma mdia sempre um nmero decimal). 3. Criar uma funo copiarVetor que tenha como argumentos 2 arrays. O contedo do primeiro array dever ser copado para o segundo. Prottipo: void copiarVetor(long v1[ ], long v2[ ], long comp); 4. Criar uma funo maxVetor1 que dever atribuir o valor 0 a cada elemento do array que lhe passado como parmetro, desde que esse elemento tenha um valor que seja superior a um valor mximo tambm recebido por parmetro. Prottipo: void maxVetor1(long v[ ], long comp, long max);

337

5. Criar uma funo ordenaVetor que classifique os elementos de um array em ordem crescente. Se um array inicialmente possui os elementos {21, 30, 17, 8}, nesta ordem, ao fim da operao ele dever se apresentar como {8, 17, 21, 30}. 3.9 Arrays de duas ou mais dimenses Para utilizarmos arrays de duas ou mais dimenses precisamos declar-los como fazemos para qualquer outra varivel. A declarao de um array de duas dimenses semelhante declarao de arrays com uma nica dimenso. Devemos indicar explicitamente quantos elementos existem em cada dimenso. Vejamos como declarar um array de inteiros de nome X, com 10 elementos em uma dimenso e 8 elementos em outra: int X[10][8] ;. Simples no? Os arrays de uma e duas dimenses recebem nomes especiais. Os arrays de uma dimenso so chamados de vetor e os de duas dimenses recebem o nome de matriz. Exemplo de programao usando matriz. Vamos escrever um programa para preencher uma matriz de nome Nota, que represente as notas de 10 alunos de uma turma em 3 disciplinas. Trata-se de distribuir essas notas em uma estrutura de duas dimenses. Acompanhe o nosso raciocnio. Consideraremos uma matriz de 3 linhas, cada linha representando uma disciplina, e 10 colunas, uma para cada nota de um aluno. Nossa estrutura tem a seguinte aparncia.

notas disciplinas
Como imaginamos, a matriz deve ser declarada como int Nota[3][10]. Atribuindo valor aos elementos de um array A atribuio de valores aos elementos de uma matriz se d do mesmo modo que para as outras variveis j vistas, ou seja, podemos faz-lo por atribuio direta ou por leitura via teclado (como uso da funo scanf). No podemos esquecer que as matrizes possuem dois ndices. Assim, podemos escrever Nota[0,3]=8,5; para indicarmos que o aluno 3 obteve 8,5 como nota na disciplina 1. As disciplinas sero representadas por 0, 1, 2 (linha 0, linha 1, linha2). No se desespere. Lembre-se que os ndices dos arrays comeam em 0(zero). Por isso, a primeira linha tem ndice 0, a segunda ndice 1, e assim por diante. O mesmo ocorre com relao s colunas. Ento o elemento da terceira linha e sexta coluna representado por Nota[2,5]. A atribuio de valores via teclado se d como auxlio de um comando de #include<stdio.h> repetio. Lembremos do que j foi dito antes: cada int main(){ conceito estudado importante e deve ser acumulado, para int i,j; uso futuro, medida que os programas vo ficando mais int X[3][4]; complexos. Vejamos um modelo para a leitura de dados via for (i=0; i<3; i++) teclado e atribuio aos elementos de uma matriz. { printf("Leitura da linha %d\n", i); for (j=0; j<4; j++) { printf("elemento %d ", j); scanf("\n%f", X[i,j]) ; } Leia o cdigo ao lado e procure compreender cada passo. Evidentemente este programa l uma matriz 3x4, de inteiros de nome X. Escreva outro programa para realizar a mesma tarefa de modo que os dados de entrada apaream na tela assim : Primeira linha : 10 23 15 17 Segunda linha : 76 56 29 2 Terceira linha : -5 43 -2 45

} getch(); return 0; }

338

Observe bem, aps a leitura de um nmero, no h mudana de linha, a menos que esse nmero seja o ltimo da sua linha. Na plataforma Moodle, o aluno encontrar vrios outros exemplos com matrizes assim como muitos exerccios. 3.10 Teste 1. Qual das linhas abaixo cria um array de double com 10 elementos? ( ) double* vetor[10]; ( ) double vetor{10}; ( ) double vetor[10]; ( ) double vetor[9]; 2. Qual o valor do primeiro ndice de um array? ( )0 ( )1 ( ) -1 3. Qual dos prottipos abaixo no permite a passagem do array vetor como parmetro? ( ) void f(long vetor[], long comp); ( ) void f(long vetor, long comp); ( ) void f(long *vetor, long comp); 4. Qual o outro modo de inicializar o array vetor com estes valores? long vetor[4]; vetor[0] = 10; vetor[1] = 23; vetor[2] = 505; vetor[3] = 8; ( ) long vetor[4] = 10, 23, 505, 8; ( ) long vetor[4] = [10, 23, 505, 8]; ( ) long vetor[4] = (10, 23, 505, 8); ( ) long vetor[4] = {10, 23, 505, 8};

Para no esquecer.

No esquecer JAMAIS que um array comea no ndice 0 e no no ndice 1. Quando passar um array para uma funo, como parmetro claro, passar TAMBEM o seu tamanho, seno a funo no poder reconhecer o tamanho do array.

339

4. Avaliando o que foi construdo


Conclumos este texto com uma apresentao sobre os arrays. Esse tipo de dados possui larga utilizao na soluo de problemas que necessitam a reutilizao de variveis dentro de um mesmo programa. Conforme visto, os arrays so utilizados na implementao de vetores e matrizes em C. Existem outros tipos de dados que devero ser estudados por aqueles que pretendem aprofundar-se no estudo desta linguagem. O tratamento de caracteres, registros e arquivos (files) so assuntos fortemente recomendados para leitura. A base de programao adquirida at aqui suficiente para que o aluno continue o seu desenvolvimento em programao, agora de forma autnoma.

4. Referncias
1. Ascencio, Ana F G., Campos, Edilene A V., Fundamentos da Programao de Computadores: Algoritmos, Pascal, C/C++ e Java, 2 edio, Pearson Education, 2007. 2. Hutchison, Robert C., Just, Steven B., Programming using the C language. MGraw-Hill Book Company, 1988. 3. Kernighan, Brian W., Ritche, Dennis M., Le langage C, Masson, 1986.

340

Vous aimerez peut-être aussi