Baixe o app para aproveitar ainda mais
Prévia do material em texto
CENTRO FEDERAL DE EDUCAÇÃO TECNOLÓGICA CELSO SUCKOW DA FONSECA – CEFET-RJ RODRIGO REIS GOMES PROGRAMAÇÃO DE ALGORITMOS APOSTILA NOVA FRIBURGO 2012 LISTA DE TABELAS Tabela 1: Alguns comandos de alguns arquivos de cabeçalho . . . . . . . . . . . . . 13 Tabela 2: Tipos de dados da linguagem C . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 Tabela 3: Alguns valores válidos em C e seus tipos de dado . . . . . . . . . . . . . . 17 Tabela 4: Especificadores de formato para os comandos printf e scanf . . . . . . 21 Tabela 5: Caracteres especiais de barra invertida . . . . . . . . . . . . . . . . . . . . . . 26 Tabela 6: Operadores aritméticos da linguagem C . . . . . . . . . . . . . . . . . . . . . . 33 Tabela 7: Resultados de expressões aritméticas de operandos constantes . . . 33 Tabela 8: Resultados de expressões aritméticas para x = 2 e y = 5.0 . . . . . . . . 34 Tabela 9: Algumas funções numéricas do arquivo de cabeçalho math.h . . . . . . 34 Tabela 10:Exemplos de uso de funções numéricas predefinidas em C. . . . . . . . 34 Tabela 11:Operadores relacionais da linguagem C . . . . . . . . . . . . . . . . . . . . . . 35 Tabela 12:Exemplos de expressões relacionais em C . . . . . . . . . . . . . . . . . . . . 35 Tabela 13:Alguns caracteres da tabela ASCII . . . . . . . . . . . . . . . . . . . . . . . . . . 36 Tabela 14:Operadores lógicos da linguagem C . . . . . . . . . . . . . . . . . . . . . . . . . 36 Tabela 15:Exemplos de expressões com operadores lógicos . . . . . . . . . . . . . . 37 Tabela 16:Prioridade dos operadores em C . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 Tabela 17:Operadores de posição de memória . . . . . . . . . . . . . . . . . . . . . . . . . 90 Tabela 18:Procedimento para efetuar a passagem de parâmetro por referência . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 Tabela 19:Forma de uso do comando fopen . . . . . . . . . . . . . . . . . . . . . . . . . . 104 Tabela 20:Modos existentes para manipulação de arquivos . . . . . . . . . . . . . . 105 Tabela 21:Forma de uso do comando fwrite . . . . . . . . . . . . . . . . . . . . . . . . . . 105 Tabela 22:Forma de uso do comando rewind . . . . . . . . . . . . . . . . . . . . . . . . . 105 Tabela 23:Forma de uso do comando fread . . . . . . . . . . . . . . . . . . . . . . . . . . 105 Tabela 24:Forma de uso do comando fseek . . . . . . . . . . . . . . . . . . . . . . . . . . 106 Tabela 25:Forma de uso do comando feof . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 Tabela 26:Forma de uso do comando fclose . . . . . . . . . . . . . . . . . . . . . . . . . 106 Tabela 27:Forma de uso do comando remove . . . . . . . . . . . . . . . . . . . . . . . . 106 LISTA DE FIGURAS Figura 1: Estruturas usadas em um algoritmo específico para somar dois números . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 Figura 2: Execução do programa MeuPrograma.c (versão 1) . . . . . . . . . . . . . 14 Figura 3: Execução do programa MeuPrograma.c (versão 2) . . . . . . . . . . . . . 19 Figura 4: Execução do programa MeuPrograma.c (versão 3) . . . . . . . . . . . . . 22 Figura 5: Execução do programa MeuPrograma.c (versão 4) . . . . . . . . . . . . . 23 Figura 6: Execução do programa MeuPrograma.c (versão 5) . . . . . . . . . . . . . 24 Figura 7: Execução do programa MeuPrograma.c (versão 6) . . . . . . . . . . . . . 26 Figura 8: Execução do programa MeuPrograma.c (versão 7) . . . . . . . . . . . . . 28 Figura 9: Execução do programa MeuPrograma.c (versão 8) . . . . . . . . . . . . . 30 Figura 10: Execução do programa MeuPrograma.c (versão 9) . . . . . . . . . . . . . 53 Figura 11: Exemplos de arranjos de diferentes dimensões . . . . . . . . . . . . . . . . 62 Figura 12: A individualização de elementos de um vetor . . . . . . . . . . . . . . . . . . 64 Figura 13: A individualização de elementos de uma matriz . . . . . . . . . . . . . . . . 67 Figura 14: Representação esquemática de uma função . . . . . . . . . . . . . . . . . . 82 Figura 15: Execução do programa MeuPrograma.c (versão 10) . . . . . . . . . . . . 89 Figura 16: Passo a passo do cálculo recursivo do fatorial . . . . . . . . . . . . . . . . . 94 SUMÁRIO 1 ALGORITMOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.1 Definição . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.2 Características . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.3 Exemplos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 1.4 Exercícios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 2 PROGRAMAS DE COMPUTADOR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 2.1 Linguagens de programação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 2.2 Exercícios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 3 Primeiros passos em C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 3.1 Módulos e o módulo main . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 3.2 Blocos de comando . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 3.3 O comando printf como saída de textos constantes . . . . . . . . . . . . . 11 3.4 Inclusão de arquivos de cabeçalho. . . . . . . . . . . . . . . . . . . . . . . . . . . 12 3.5 O comando getch como entrada de caractere . . . . . . . . . . . . . . . . . . 13 3.6 Variável, constante e identificador . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 3.7 Palavras reservadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 3.8 Tipos de dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 3.9 Declaração de variáveis e constantes . . . . . . . . . . . . . . . . . . . . . . . . . 17 3.10 Entrada e saída com os comandos printf e scanf . . . . . . . . . . . . . . . . 18 3.10.1 Especificadores de formato . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 3.11 Comentários . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 3.12 Formatação de saída numérica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 3.13 Caracteres de barra invertida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 3.14 Textos como tipos de dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 3.14.1 O comando gets como entrada de dados textuais . . . . . . . . . . . . . . . . . . 29 3.15. Exercícios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 4 EXPRESSÕES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 4.1 Atribuição . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 4.2 Operadores aritméticos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 4.3 Funções numéricas predefinidas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 4.4 Operadores relacionais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 4.5 Operadores lógicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 4.6 Prioridade dos operadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . 37 4.7 Exercícios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 5 ESTRUTURAS DE DECISÃO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 5.1 Comando if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 5.2 Comando switch (decisão múltipla) . . . . . . . . . . . . . . . . . . . . . . . . . . 45 5.3 Exercícios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 6 ESTRUTURAS DE REPETIÇÃO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 6.1 Repetição com teste no início (comando while) . . . . . . . . . . . . . . . . . 52 6.2 Repetição com variável de controle (comando for) . . . . . . . . . . . . . . 55 6.3 Repetição com saída forçada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 6.4 Repetição com teste no final (comando do while) . . . . . . . . . . . . . . . 56 6.5 Exercícios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 7 ARRANJOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 7.1 Vetor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 7.2 Matriz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 7.3 Arranjo multidimensional . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 7.4 Exercícios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 8 MANIPULAÇÃO DE TEXTOS EM C . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 8.1 Textos como vetores de caracteres . . . . . . . . . . . . . . . . . . . . . . . . . . 74 8.2 Comandos predefinidos para textos . . . . . . . . . . . . . . . . . . . . . . . . . . 75 8.3 Comandos predefinidos para caracteres . . . . . . . . . . . . . . . . . . . . . . 78 8.4 Exercícios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 9 PROGRAMAÇÃO MODULAR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 9.1 Funções . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 9.2 Procedimentos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 9.3 Exemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 9.4 Variáveis locais e variáveis globais . . . . . . . . . . . . . . . . . . . . . . . . . . 87 9.5 Passagem de parâmetros por valor e por referência . . . . . . . . . . . . . 90 9.6 Recursividade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 9.6 Exercícios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 10 TIPOS DE DADOS DEFINIDOS PELO PROGRAMADOR . . . . . . . . . . . 97 10.1 Tipos enumerados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 10.2 Tipos de registros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 10.3 Estruturas mistas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 10.4 Declaração de novos tipos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 10.5 Exemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 10.6 Exercícios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 11 ARQUIVOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 11.1 Arquivos de registros tipados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 11.1.1 Exemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 11.2 Arquivos de texto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 11.2.1 Exemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 11.3 Exercícios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 BIBLIOGRAFIA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 APÊNDICE A: PONTEIROS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 12 APÊNDICE B: OPERADORES BIT A BIT . . . . . . . . . . . . . . . . . . . . . . 11 8 APÊNDICE C: RESPOSTAS DOS EXERCÍCIOS . . . . . . . . . . . . . . . . . 1 20 1 1 ALGORITMOS A palavra algoritmo, à primeira vista, pode parecer estranha. Embora passível de designação desconhecida, fazemos uso constantemente de algoritmos em nosso cotidiano: a maneira como uma pessoa toma banho é um algoritmo. Outros algoritmos frequentemente encontrados são: • Instruções para se utilizar um aparelho eletrodoméstico; • Uma receita para preparo de algum prato. 1.1 Definição São vários os conceitos para algoritmo. Seguem alguns: “Um conjunto finito de regras que provê uma sequência de operações para resolver um tipo de problema específico.” [KNUTH] “Sequência ordenada e não ambígua, de passos que levam à solução de um dado problema.” [TREMBLAY] “Processo de cálculo, ou de resolução de um grupo de problemas semelhantes, em que se estipulam, com generalidade e sem restrições, as regras formais para a obtenção do resultado ou da solução do problema.” [AURÉLIO] 1.1 Características Todo algoritmo deve apresentar cinco características absolutamente primordiais. 2 • Ter fim; • Não dar margem à dupla interpretação (não ambíguo); • Capacidade de receber dado(s) de entrada do mundo exterior; • Poder gerar informações de saída para o mundo externo ao do ambiente do algoritmo; • Ser efetivo (todas as etapas especificadas no algoritmo devem ser alcançáveis em um tempo finito). 1.3 Exemplos Os algoritmos são comuns em nosso cotidiano. Por exemplo, consideremos uma receita de bolo. Em uma receita de bolo, uma série de ingredientes necessários é enumerada; ademais, são descritos uma sequência de passos a serem cumpridos para se atingir o objetivo: ter o bolo pronto. ALGORITMO 1: Receita de Bolo Providencie manteiga, ovos, 2 quilos de farinha; Misture os ingredientes; Despeje a mistura na fôrma de bolo; Leve a fôrma ao forno; Espere 20 minutos; Retire a fôrma do forno; Deixe esfriar; Prove. Outra atividade algorítmica comum em nosso dia a dia é o ato de trocar uma lâmpada queimada. Apesar de ser aparentemente bastante óbvio, muitas vezes fazemos esse tipo de atividade sem percebermos determinados detalhes. Podemos descrever de maneira simples: 3 ALGORITMO 2: Troca de lâmpada Pegue uma escada; Posicione-a embaixo da lâmpada queimada; Pegue uma lâmpada nova; Suba na escada com a lâmpada nova; Retire a lâmpada velha; Coloque a lâmpada nova; Desça com a lâmpada velha; Jogue a lâmpada velha no lixo; Guarde a escada. Seguem outros exemplos de algoritmos. O próximo refere-se ao processo que deve existir para chupar uma bala. O seguinte representa um modo diferente para somar dois números; este último faz uso dos elementos presentes na figura 1. ALGORITMO 3: Chupar uma bala Pegar a bala; Retirar o papel; Chupar a bala; Jogar o papel no lixo. ALGORITMO 4: Somar dois números Desenhar três retângulos: o retângulo A, o retângulo B e o retângulo Resultado; Escrever o primeiro número no retângulo A; Escrever o segundo número no retângulo B; Somar o número do retângulo A com número do retângulo B Colocar ovalor obtido no retângulo Resultado. 4 Figura 1: Estruturas usadas em um algoritmo específico para somar dois números. Já se deparou com alguém lhe abordando na rua e lhe perguntando sobre como chegar a algum lugar? Sua resposta à dúvida desta pessoa nada mais é do que um algoritmo. 1.4 Exercícios 1 – Elabore um algoritmo que mova os três discos da haste a para a haste b ou para a haste c. Só é possível movimentar um único disco – 1, 2, ou 3 – de cada vez para qualquer haste, contanto que nunca seja colocado um disco maior sobre um disco menor. O objetivo é transferir os três discos para a haste destino, tal como se apresentam ordenados na haste a, conforme a figura a seguir: 2 – Você dispõe de uma balança e nove bolas – das quais oito possuem um mesmo peso e uma é mais pesada que as demais. 5 Descreva um algoritmo para descobrir qual é a bola mais pesada, utilizando-se apenas de duas pesagens na balança. 3 – Um homem precisa atravessar um rio com um barco que possui capacidade para transportar apenas ele mesmo e mais uma de suas três cargas que são: um lobo, um bode e um molho de alfafa. O lobo e o bode não podem ficar sozinhos em uma margem, pois o lobo comerá o bode. O bode e a alfafa também não podem ficar sozinhos em uma margem, pois o bode comerá a alfafa. O que o homem deve fazer para conseguir atravessar o rio sem perder suas cargas? 4 – Você está em uma sala que contém três interruptores. Cada interruptor está ligado a uma lâmpada presente em uma sala ao lado. As três lâmpadas estão inicialmente apagadas. Descreva um algoritmo para descobrir qual interruptor está ligado a qual lâmpada, sabendo que você só pode ir uma única vez à sala ao lado. 5 – Um algoritmo não pode conter um comando como “Escreva todos os números inteiros positivos”. Por quê? 6 – Faça um algoritmo para somar dois números e multiplicar o resultado pelo primeiro número. 6 7 – Três jesuítas e três canibais precisam atravessar um rio. Para tal, dispõem de um barco com capacidade para duas pessoas. Por medidas de segurança não se permite que em alguma margem a quantidade de jesuítas seja inferior à de canibais. Como fazer a travessia? 8 – Como você descreveria um algoritmo para resolver o problema proposto no exercício 1.4.1, porém com quatro discos? 7 2 PROGRAMAS DE COMPUTADOR Nós podemos descrever algoritmos através da língua portuguesa, já que o Português é a linguagem que conhecemos e usamos em nossa comunicação. No entanto, os computadores só compreendem uma linguagem composta de combinações de valores zero e um, conhecida como linguagem de máquina. Esta linguagem é bastante complicada para nós, seres humanos. Por exemplo, suponhamos que as letras o e i sejam reconhecidas pela máquina pelos símbolos 10010110 e 01101001, respectivamente. Vamos supor também que 00001111 seja o comando responsável por escrever algo na tela do computador. Pois bem. Para escrever a palavra oi no monitor, seria necessário enviar a seguinte mensagem ao computador: 0000111110010110 01101001 Complicado, não? Dá para se ter ideia que, para descrever um algoritmo ao computador fazendo uso da linguagem de máquina, é necessário ter ao lado uma lista de códigos compreendidos pela máquina. Além disso, para compreender um algoritmo já escrito em linguagem de máquina, também é primordial ter a mesma lista de códigos em mãos. Para eliminar este inconveniente, foram criadas as linguagens de programação. 2.1 Linguagens de programação As linguagens de programação, em sua grande maioria, são formadas por um subconjunto do Inglês – já que foram criadas por pessoas oriundas de países de língua inglesa. As linguagens de programação possuem um módulo chamado compilador – ou interpretador, dependendo da linguagem – que é responsável por traduzir programas de computadores – que descrevem qualquer algoritmo escrito 8 em tais linguagens – em linguagem de máquina, a única linguagem conhecida pelo computador. A compilação de um programa é feita para que a linguagem de programação verifique se não há erros de escrita, utilizando como base: a) uma análise léxica, que verifica se as palavras usadas no programa são realmente palavras que fazem parte da linguagem de programação; b) uma análise sintática, que verifica se a sintaxe – a ordem das palavras – usada no programa é válida; c) uma análise semântica, que faz outras checagens e que, no momento, não convém ser explicada. Para se fazer uma analogia com a língua portuguesa, eu é uma palavra válida e casa também é uma palavra válida, no entanto, eu casa não é uma construção sintaticamente correta. Depois do arquivo que contém o programa descrito em uma linguagem de programação ser compilado e o mesmo não apresentar erros léxicos, sintáticos ou semânticos, surge um novo arquivo – que chamamos de arquivo executável. A execução deste segundo arquivo – geralmente, com uma extensão exe – nada mais é do que o ato do programa criado “rodar” (ou funcionar), podendo ter a interação de um usuário que fornece dados ao programa e recebe resultados oriundos do programa. Alguns exemplos de linguagens de programação são: Pascal, C, C++, Java e Haskell. Neste documento, abordaremos a linguagem C. 2.2 Exercícios 1 – O que é uma linguagem de programação? 9 2 – Por que uma linguagem de programação é importante para quem cria programas de computador? 3 – Cite um exemplo de uma linguagem de programação. 4 – O que significa compilar um programa? 5 – O que significa executar um programa? 10 3 PRIMEIROS PASSOS EM C C é uma linguagem de programação que exige do programador estruturar seu programa em diferentes módulos. 3.1 Módulos e o módulo main Um módulo nada mais é do que um bloco de comandos. O capítulo 9 trata especificamente de módulos construídos pelo programador. Entretanto, em C, espera-se que todo programa tenha um módulo principal, chamado de módulo main. Até o capítulo 9, serão estudados programas C exclusivamente com o módulo main. 3.2 Blocos de comando Um programa de computador é constituído de comandos a serem definidos pelo programador. Estes comandos precisam ser definidos em uma área delimitada, ou seja, é preciso que se saiba onde os comandos se iniciam e quando os comandos terminam. Estes delimitadores de início e fim de comandos são conhecidos como blocos de comandos. Em C, estes delimitadores são os caracteres { e }. O caractere { indica o início de um bloco de comando enquanto o caractere } indica o término de um bloco de comando. Assim sendo, o programa mais simples que pode ser criado em C é o seguinte: main() { } 11 O programa anteriormente descrito tem a definição do módulo principal main (atenção: após a identificação do módulo, é preciso abrir e fechar parênteses!) e o início e término do bloco de comandos associados ao módulo principal. Este programa, no entanto, não faz absolutamente nada, já que não há comando algum inserido no bloco de comandos. Para começar a dar sentido ao programa, vamos fazer com que ele escreva a palavra oi no monitor do computador. 3.3 O comando printf como saída de textos constantes Para darmos uma ordem para o computador escrever algum texto em seu monitor, podemos fazer uso do comando printf. O comando printf deve ser usado escrevendo o texto a ser exibido entre parênteses. Veja a sintaxedeste comando, ou seja, como ele deve ser empregado: printf(texto a ser escrito); Ocorre que em C, qualquer texto deve ser escrito entres aspas. Então, para escrevermos a palavra oi, precisamos usar o comando printf assim: printf("oi"); Outra observação a ser feita é a respeito do uso do ponto e vírgula ao final do comando. Em C, o caractere de ponto e vírgula significa o término de um comando. É análogo ao ponto que usamos no final de cada frase em Português. Assim sendo, após cada comando em C, é obrigatório inserir ponto e vírgula. 12 Um programa em C para escrever “oi” no monitor do computador é apresentado a seguir: main() { printf("oi"); } Este programa será compilado perfeitamente em alguns compiladores C. Porém, outros compiladores estão preparados para as palavras reservadas definidas pela linguagem C que foi padronizada pelo instituto norte-americano de padrões, também conhecida como ANSI-C ou C padrão. O comando printf não faz parte do C padrão, mas isso não impede seu uso nos compiladores de ANSI-C. Basta incluirmos ao programa em construção um arquivo especial conhecido como stdio.h. É neste arquivo que está definido o comando printf e outros mais. 3.4 Inclusão de arquivos de cabeçalho Em C, podemos criar ou usar arquivos que disponibilizam uma série de funcionalidades. Estes arquivos têm extensão h e são conhecidos como arquivos de cabeçalho. Como já mencionado na seção anterior, o comando printf está definido no arquivo de cabeçalho stdio.h. A inclusão de arquivos de cabeçalho é feita antes da definição de qualquer módulo de um programa C. Cada arquivo a ser incluído em um programa C precisa seguir a seguinte sintaxe: #include <nome do arquivo de cabeçalho> Com a inclusão do arquivo de cabeçalho stdio.h, o programa da seção 3.3 fica assim: 13 #include <stdio.h> main() { printf("oi"); } Após compilarmos e executarmos o programa acima, no entanto, não perceberemos que uma janela foi aberta, que a palavra oi foi escrita nesta janela e que esta mesma janela foi fechada porque estas ações são tomadas em um espaço de tempo muito curto para a percepção dos olhos humanos. Para solucionarmos este empecilho, precisamos incluir um atraso no final do programa. Neste capítulo, usaremos outros comandos que se encontram nos seguintes arquivos de cabeçalho: Tabela 1: Alguns comandos de alguns arquivos de cabeçalho. Comando Arquivo de cabeçalho printf stdio.h scanf stdio.h gets stdio.h getch conio.h 3.5 O Comando getch como entrada de caractere O comando getch, presente no arquivo de cabeçalho conio.h, serve para ler uma única tecla, tão logo ela seja apertada pelo usuário e, desta forma, ele pode ser usado para produzir um atraso na execução do programa. A execução do programa fica interrompida até que o usuário aperte uma tecla para ser lida pelo comando getch. O comando getch tem a seguinte sintaxe: getch(); 14 O programa em desenvolvimento neste capítulo, após a inclusão do comando getch para a introdução de um atraso antes do término de sua execução, fica assim: #include <stdio.h> #include <conio.h> main() { printf("oi"); getch(); } Agora, a execução do programa implicará na abertura de uma janela, na escrita da palavra oi nesta janela e no aguardo do apertar de uma tecla pelo usuário. Veja: Figura 2: Execução do programa MeuPrograma.c (versão 1). O caractere _ que aparece após a palavra oi é, na verdade, o cursor que fica piscando. O cursor sempre fica posicionado após o último caractere exibido. Depois que o usuário do programa teclar alguma coisa, a janela exibidora do programa será imediatamente fechada. 3.6 Variável, constante e identificador Em programação, por várias vezes, precisaremos de estruturas capazes de armazenar valores ao longo da execução de um programa. Mais ainda: é imprescindível que o valor armazenado em tais estruturas possa ser modificado enquanto o programa estiver em execução. Tais estruturas são chamadas de variáveis. 15 No computador, existe um dispositivo chamado memória que é dividido em vários pedaços ou endereços e que, em cada endereço, pode ser armazenado algum valor. Uma variável nada mais é do que um endereço de memória cujo conteúdo pode variar ao longo de um programa em execução. Outra estrutura existente em linguagens de programação, similar a uma variável, é a constante. Uma constante é também um endereço da memória do computador, porém, o espaço de memória ocupado por uma constante jamais poderá ter seu conteúdo modificado ao longo da execução de um programa. O programador pode definir quantas variáveis e quantas constantes ele achar necessário. Ele só precisa dar um nome válido a cada variável ou constante que ele criar. O nome de uma constante ou de uma variável é também conhecido como um identificador. Em C, um identificador deve ser definido respeitando as seguintes regras: a) O primeiro caractere deve ser uma letra (de a a z ou de A a Z) ou ainda o caractere _ (sublinha); b) Os demais caracteres podem ser uma letra (de a a z ou de A a Z) ou ainda o caractere _ (sublinha), ou ainda um algarismo (de 0 a 9); c) Não é permitido o uso de acento ou cedilha; d) O identificador não pode ser uma palavra reservada da linguagem de programação. 3.7 Palavras reservadas Uma palavra reservada é uma palavra que faz parte de uma linguagem de programação. Segue uma lista de algumas palavras reservadas da linguagem C padrão. 16 auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void volatile while Estas palavras não podem ser usadas como identificadores. 3.8 Tipos de dados Cada variável ou constante, ao ser criada pelo programador, precisa ter um tipo de dado associado a ela. Por exemplo, se o programador precisa de uma variável para representar o ano de nascimento de uma pessoa, o tipo desta variável precisa ser um número inteiro. Se o programador precisa de uma variável para representar o salário de um funcionário, o tipo desta variável precisa ser um número real. Em C, existem os seguintes tipos de dados: Tabela 2: Tipos de dados da linguagem C. Tipo Tamanho Valores char 08 bits ‘a’, ‘Z’, ‘ ‘, ‘+’, etc. int 16 bits -32767 a 32767 unsigned int 16 bits 0 a 65535 long int 32 bits -214483647 a 2147483647 unsigned long int 32 bits 0 a 4294967295 float 32 bits Seis dígitos de precisão double 64 bits Dez dígitos de precisão long double 80 bits Dez dígitos de precisão Na seção 3.3, foi informado que em C qualquer texto é representado entre aspas. Chegou o momento de informar que um único caractere é representado em C entre apóstrofos e que números reais são representados pelos tipos float, double ou long double. Ainda sobre números reais, as partes inteira e fracionária dom número são separadas por um ponto. 17 A tabela abaixo ilustra exemplos de valores de alguns tipos de dados em C. Tabela 3: Alguns valores válidos em C e seus tipos de dado. Valor Tipo ‘c’ char ‘7’ char ‘+’ char 8 Int 1995 Int 7.0 float 21.06 float 3.9 Declaração de variáveis e constantes Em C, para se declarar uma variável, é preciso seguir a seguinte sintaxe: tipo identificador; Assim, primeiramente, o programador precisa definir o tipo da variável. Em seguida, precisa escolher um nome para a variável, seguindo as regras para a definição de identificadores(vide seção 3.6) e terminar a definição usando o caractere de ponto e vírgula. Caso o programador precise declarar mais de uma variável do mesmo tipo, ele pode fazê-lo separando os identificadores por vírgulas, da seguinte forma: tipo identificador1, identificador2, ..., identificadorN; No entanto, nada impede que ele defina cada uma das variáveis de mesmo tipo em linhas diferentes: tipo identificador1; tipo identificador2; ... tipo identificadorN; 18 Alguns exemplos de declaração de variáveis vêm a seguir: int dia, mes, ano; char sexo; float salario; Quanto às constantes, suas declarações são ligeiramente diferentes e precisam seguir a seguinte sintaxe: const tipo identificador = valor; A palavra reservada const indica que uma constante será declarada. Em seguida, deve ser informado o tipo da constante, seu nome – também seguindo as regras para definição de um identificador – e, finalmente, o caractere = deve preceder o valor que a constante terá durante toda a execução do programa. A declaração é encerrada com o caractere de ponto e vírgula. Seguem alguns exemplos de declaração de constantes: const float pi = 3.1415; const float salarioMinimo = 622.00; A declaração de variáveis e constantes em C deve ser feita no início de um módulo, logo após o caractere {. 3.10 Entrada e saída com os comandos printf e scanf Veja o seguinte programa C: #include <stdio.h> #include <conio.h> main() { int dia, mes, ano; printf("Digite o dia de seu nascimento: "); scanf("%d", &dia); 19 printf("Digite o mes de seu nascimento: "); scanf("%d", &mes); printf("Digite o ano de seu nascimento: "); scanf("%d", &ano); printf("Voce nasceu em %d/%d/%d.", dia, mes, ano); getch(); } A saída gerada por este programa é a seguinte: Figura 3: Execução do programa MeuPrograma.c (versão 2) Os comandos mais utilizados em C para um programa obter ou fornecer dados do ou para seu usuário são printf, que já foi visto de forma introdutória na seção 3.3, e scanf. O comando printf é usado para a saída de dados. Certo. Isso já é sabido, mas quando o dado a ser fornecido ao usuário do programa for uma variável ou uma constante, devemos usar o comando printf da seguinte forma: printf(texto, lista de expressões a serem escritas); Preste atenção na penúltima linha de comando do programa acima. O texto “Voce nasceu em %d/%d/%d.” é seguido de três identificadores, todos separados por vírgulas. Cada identificador representa uma expressão. As vírgulas são usadas para separar as expressões que constituem a lista de expressões a serem escritas. O comando scanf é usado para a entrada de dados e tem a seguinte sintaxe: 20 scanf(texto, &identificador1, ..., &identificadorN); Não é aconselhável usar scanf para ler o valor de várias variáveis porque cabe ao usuário, durante a execução do programa, escrever cada valor de acordo com a formatação esperada pelo programador. Se isto não for feito, o scanf não funcionará perfeitamente. Como não é boa prática deixar nas mãos do usuário uma possibilidade do programa não funcionar, é preferível usar o scanf para ler uma única variável, respeitando a sintaxe a seguir: scanf(texto, &identificador); No programa desta seção, percebe-se que há, à primeira vista, caracteres estranhos embutidos nos textos dos comandos printf e scanf. No exemplo usado, trata-se de alguns caracteres %d. Quando o caractere % estiver presente em um texto, ele estará, na verdade, indicando um especificador de formato. Ao usar o comando printf ou o comando scanf para escrever uma expressão ou para ler um identificador, é preciso especificar o formato deste valor. A seção 3.10.1 lista os especificadores de formato existentes. Cada especificador de formato que aparece em um texto está ligado respectivamente a cada valor presente na lista de identificadores do comando scanf ou na lista de expressões do comando printf. Deste modo, no comando printf("Voce nasceu em %d/%d/%d.", dia, mes, ano); o primeiro %d está associado ao identificador dia, o segundo %d está associado ao identificador mes e o terceiro %d está ligado ao identificador ano. 3.10.1 Especificadores de formato A tabela abaixo reúne os especificadores de formato e seus significados quando usados em printf e quando usados em scanf: 21 Tabela 3: Especificadores de formato para os comandos printf e scanf. Código Significado em “printf” Significado em “scanf” %c Caractere Caractere %d Inteiro decimal com sinal Inteiro decimal com sinal %i Inteiro decimal com sinal Inteiro decimal com sinal %e Número com notação científica com e minúsculo Número em ponto flutuante decimal %E Número com notação científica com E maiúsculo ------------------------------------------- %f Ponto flutuante decimal Número em ponto flutuante decimal %g Usa %e ou %f, o que for mais curto Número em ponto flutuante decimal %G Usa %E ou %F, o que for mais curto ------------------------------------------- %o Número octal sem sinal Número octal sem sinal %s Texto (string de caractere) Texto (string de caractere) %u Inteiro decimal sem sinal Inteiro decimal sem sinal %x Hexadecimal (letras minúsculas) Hexadecimal %X Hexadecimal (letras maiúsculas) ------------------------------------------- %p Ponteiro Ponteiro %% Escreve o símbolo % ------------------------------------------- 3.11 Comentários Os comentários, em uma linguagem de programação, são ignorados pelo compilador, ou seja, não são traduzidos para linguagem de máquina. Eles servem apenas como forma de anotação e organização para o programador. Em C, um comentário vem a seguir dos caracteres //, se ele estiver escrito em uma única linha. Se o comentário compreender várias linhas, ele deve aparecer entre os caracteres /* e */. Veja um programa com alguns comentários: #include <stdio.h> #include <conio.h> main() { int numero; printf("Escreva um numero inteiro: "); 22 scanf("%d", &numero); // E se o usuário digitar um número real? /* Se o usuário inserir um número real (com casas decimais), somente a parte inteira deste número será considerada. */ printf("Voce escolheu o numero %d.", numero); getch(); } 3.12 Formatação de saída numérica Apesar do programa da Seção 3.11 pedir ao usuário que ele forneça um número inteiro, o teclado está livre para o usuário escrever qualquer coisa, dentre elas, um número real. Se isso realmente ocorrer, veja como será a saída do programa: Figura 4: Execução do programa MeuPrograma.c (versão 3) Como o programa foi feito para trabalhar com um número inteiro, a parte decimal do número fornecido pelo usuário foi descartada. O programa a seguir, por sua vez, trabalha com um número real. Ele é uma modificação do programa da seção 3.11, declarando uma variável do tipo float e utilizando o especificador de formato %f. 23 #include <stdio.h> #include <conio.h> main() { float numero; printf("Escreva um numero qualquer: "); scanf("%f", &numero); // A saída não está formatada! printf("Voce escolheu o numero %f.", numero); getch(); } O indesejável neste programa está no fato de um número do tipo float ser representado por padrão por seis casas decimais. Vamos a uma saída deste programa: Figura 5: Execução do programa MeuPrograma.c (versão 4) Para formatarmos a saída de um número, definimos o tamanho mínimo deste número por completo, incluindo, no caso de um float, o ponto que separa as partes inteira e fracionária.Para a formatação de saída de um float, é necessário também informar a quantidade desejada de casas decimais. Vejamos o exemplo a seguir: 24 #include <stdio.h> #include <conio.h> main() { float numero; printf("Escreva um numero qualquer: "); scanf("%f", &numero); printf("Voce escolheu o numero %8.2f.", numero); getch(); } Neste exemplo, oito será o tamanho mínimo do número a ser escrito pelo comando “printf” (incluindo o caractere ‘.’) e dois será a quantidade de dígitos após a casa decimal. A saída deste programa será: Figura 6: Execução do programa MeuPrograma.c (versão 5) Como a quantidade de casas decimais está definida, o compilador já se encarrega do arredondamento do número a ser exibido pelo comando printf. Ainda, como foi escolhido oito como o tamanho mínimo para o número e este tem tamanho igual a cinco, então três espaços o antecede na sua saída. 25 3.13 Caracteres de barra invertida Há uma série de caracteres especiais conhecidos como caracteres de barra invertida que podem ser incluídos em um texto, dentre eles, o caractere \n, responsável por quebrar ou pular uma linha. Vejamos o programa a seguir, que inclui o caractere de quebra de linha em textos: #include <stdio.h> #include <conio.h> main() { int posicao; char letra; printf("Escreva uma letra:\n"); scanf("%c", &letra); // Repare na quebra de linha! printf("Qual a posicao desta letra no alfabeto?\n"); scanf("%d", &posicao); // Repare na quebra de linha! printf("A letra %c esta na posicao %d no alfabeto.", letra, posicao); getch(); } Nos dois primeiros comandos printf, surgiu o caractere \n. Durante a execução do programa, este caractere faz com que seja quebrada uma linha no exato local onde o \n está presente em um texto. Veja o passo a passo da execução deste programa: 26 Figura 7: Execução do programa MeuPrograma.c (versão 6) Há ainda, em C, os seguintes caracteres de barra invertida: Tabela 5: Caracteres especiais de barra invertida. Código Significado \b Retrocesso (BS) \f Alimentação de formulário (FF) \r Retorno de carro (CR) \t Tabulação horizontal (HT) \” Aspas \’ Apóstrofo \0 Nulo \\ Barra invertida \v Tabulação vertical \a Alerta (beep) Mas, atenção! No último programa, a variável do tipo char foi a primeira variável a ter seu valor lido. Quando precisarmos ler o valor de uma variável do tipo char, depois de já termos lido o valor de outra variável, precisaremos fazê-lo da seguinte forma: scanf("\n%c", &identificador); 27 Após o usuário escrever o valor de uma variável, ele tecla <ENTER>. Após já termos lido um valor em um programa, é preciso inserir em um comando para ler um caractere, o caractere de quebra de linha antes do especificador de formato %c. O caractere \n serve para consumir a quebra de linha já fornecida pelo usuário pela tecla <ENTER>. O próximo caractere a ser digitado pelo usuário será o que casará com o especificador de formato %c. A interpretação do comando é: leia o caractere <ENTER> e outro caractere a ser atribuído à variável identificador. 3.14 Textos como tipos de dados Para declararmos uma variável (ou uma constante) do tipo texto em C, devemos fazer uso da seguinte sintaxe: char * identificador; O operador * indica uma variável apontadora (ou um ponteiro1), porém, neste estágio de aprendizado, deve ser entendido apenas como um artifício de repetição do tipo char associado ao identificador. Em outras palavras, o identificador declarado terá como tipo uma sequência de caracteres. Sempre que usado char *, é preciso também usar a linha de comando identificador = (char *)malloc(sizeof(char)); antes de manipular a variável do tipo char *. É também preciso usar a linha de comando free(ideficador); depois de ter feito todo o uso da variável do tipo char *. É importante saber que os comandos malloc e free estão definidos no arquivo de cabeçalho stdlib.h. 1 Um ponteiros é um tipo de variável que pode ser estudada no apêndice A. 28 O programa a seguir faz uso do operador * para declarar uma variável do tipo texto. Veja: #include <stdio.h> #include <conio.h> #include <stdlib.h> main() { char * nome; nome = (char *)malloc(sizeof(char)); printf("Digite seu nome: "); scanf("%s", nome); /* Atenção: para lermos variáveis de texto, não incluimos '&' antes do identificador no comando "scanf". Inconveniente: O comando "scanf" entende o caractere espaço como o final de um valor. */ printf("Bem vindo ao mundo da computacao, %s.", nome); free(nome); getch(); } Veja a execução deste programa: Figura 8: Execução do programa MeuPrograma.c (versão 7) 29 Podemos identificar que o comando scanf tem um uso diferenciado ao tratar identificadores do tipo texto. Na verdade, quando o identificador é um ponteiro, ele não deve ser precedido do & no comando scanf. Além disso, sempre que o comando scanf for usado para ler um identificador do tipo texto, a execução do programa terá um efeito indesejável se o texto fornecido pelo usuário tiver ao menos um espaço. Este problema reside no fato do comando scanf entender o caractere espaço como sendo o final de um valor. 3.14.1 O Comando gets como entrada de dados textuais A fim de ler um texto que inclui espaços, a linguagem C fornece um comando especial para a entrada de textos. Trata-se do comando gets, cuja sintaxe é a seguinte: gets(identificador); Finalizando, segue um exemplo de programa com o comando gets. #include <stdio.h> #include <conio.h> #include <stdlib.h> main() { char * nome; nome = (char *)malloc(sizeof(char)); printf("Digite seu nome: "); gets(nome); printf("Bem vindo ao mundo da computacao, %s.", nome); free(nome); getch(); } O passo a passo da execução deste programa é ilustrado na figura 9. 30 Figura 9: Execução do programa MeuPrograma.c (versão 8) 3.15 Exercícios 1 – Escreva um programa em C para escrever um texto qualquer no monitor do computador. 2 – O que é uma variável e o que é uma constante? 3 – O que são identificadores? 4 – Quais as regras básicas para a formação de um identificador? 5 – Quais dos nomes abaixo são válidos para um identificador? a) A1BC b) XA,1d c) NomeDoAluno d) 198_Aberto e) float f) média_final 6 – Escreva o tipo de dado ideal para representar os seguintes dados: 31 a) O conceito de um aluno (‘A’, ‘B’, ‘C’ ou ‘D’) ‘A’, se a nota do aluno for maior que 9 ‘B’, se a nota do aluno for maior que 7 e menor ou igual a 9 ‘C’, se a nota do aluno for maior que 4 e menor ou igual a 7 ‘D’, se a nota do aluno for menor ou igual a 4 b) A altura de uma pessoa em metros c) O número de filhos de uma pessoa 7 – Identifique os tipos dos seguintes dados: a) 0.4 b) ‘ç’ c) ‘8’ d) 208 8 – Qual a finalidade de um comentário dentro de um programa? Como podemos escrever um comentário em C? 9 – Escreva um programa em C para ler: - o nome (com o sobrenome) de uma pessoa; - sua data de nascimento (constituída de dia, mês e ano); - sua altura (em metros); - seu peso (em Kg); - seu sexo (‘M’ ou ‘F’) O programa deve, após a leitura destes dados, escrevê-los na tela do computador. 10 – Escreva um programa para ler o nome e o sobrenome de uma pessoa e escrevê-los na seguinte forma: sobrenome seguido por uma vírgula e pelo nome. Veja um exemplo:entrada: “Rodrigo” “Reis” saída: “Reis, Rodrigo” 32 4 EXPRESSÕES Uma expressão em C é qualquer combinação válida de operadores que operam sobre operandos, os quais podem ser: constantes, variáveis e funções. Existem quatro tipos de operadores, são eles: aritméticos, relacionais, lógicos e bit a bit2. Além desses existem alguns outros especiais para tarefas particulares. 4.1 Atribuição A operação de atribuição permite que se forneça um valor a uma variável. Para a operação de atribuição, utilizamos a seguinte sintaxe: identificador = expressão; Como resultado deste comando, o valor da expressão é atribuído ao identificador. Vejamos alguns exemplos: A = 2; NOTA = 10; SEXO = ‘M’; Estado = “RJ”; X = 2.5; B = A; No comando de atribuição, a expressão e o identificador que receberá o valor da expressão devem ser do mesmo tipo, exceto: (a) quando forem de tipos que reflitam valores numéricos inteiros e reais ou; (b) quando forem de tipos que reflitam um inteiro e um caractere. Se o identificador for um inteiro e a expressão atribuidora resultar num real, o identificador receberá apenas a parte inteira da expressão atribuidora. Se o identificador for um real e a expressão atribuidora resultar num inteiro, o identificador terá sua parte fracionária igual a zero. Se o identificador for um inteiro e a expressão atribuidora resultar em um 2 Os operadores bit a bit são detalhados no Apêndice B. 33 caractere, o identificador receberá um valor que corresponda ao código ASCII3 do caractere em questão. Se o identificador for um caractere e a expressão atribuidora resultar em um inteiro, o identificador receberá o caractere associado ao código ASCII dado pela expressão atribuidora módulo4 256. 4.2 Operadores aritméticos Os operadores aritméticos compõem as expressões aritméticas, aquelas que retornam – ou seja, produzem como resultado – um valor numérico inteiro ou real. A tabela 6 lista os operadores aritméticos existentes na linguagem C, bem como sua características. As tabelas 7 e 8 mostram alguns exemplos dessas operações e seus resultados. Tabela 6: Operadores aritméticos da linguagem C. Operador Operação Tipo do operador Tipo do(s) operando(s) Forma do operador Resultado + Adição Binário Inteiro ou real Identificador ou valor Inteiro ou real - Subtração Binário Inteiro ou real Identificador ou valor Inteiro ou real * Multiplicação Binário Inteiro ou real Identificador ou valor Inteiro ou real / Divisão Binário Inteiro ou real Identificador ou valor Inteiro ou real % Resto da divisão Binário Inteiro Identificador ou valor Inteiro -- Decremento Unário Inteiro Identificador Inteiro ++ Incremento Unário Inteiro Identificador Inteiro - Menos unário Unário Inteiro ou real Identificador Inteiro ou real Tabela 7: Resultados de expressões aritméticas de operandos constantes. Expressão Resultado 1 + 2 3 5.0 -1 4.0 2 * 1.5 3.0 5 / 2 2 5 / 2.0 2.5 5 % 2 1 3 A tabela ASCII (American Standard Code for Information Interchange) relaciona 256 caracteres com códigos numéricos inteiros que variam de 0 a 255. A tabela 13 da seção 4.4 mostra alguns valores da tabela ASCII. 4 A operação módulo corresponde ao resto da divisão inteira. Ver seção 4.2. 34 Tabela 8: Resultados de expressões aritméticas para x = 2 e y = 5.0. Expressão Resultado x + 2 4 x - y -3.0 y * 2 10.0 -x -2 ++x Modifica o valor de x para 3 --x Modifica o valor de x para 1 4.3 Funções numéricas predefinidas As funções numéricas predefinidas também compõem expressões aritméticas e estão disponíveis no arquivo de cabeçalho math.h. Elas recebem argumentos (ou parâmetros) reais e fornecem um resultado também real. Na tabela 9, podemos observar algumas destas funções e suas características. A tabela 10 exibe expressões que exemplificam o uso destas funções: Tabela 9: Algumas funções numéricas do arquivo de cabeçalho math.h. Função Finalidade Tipo do(s) argumento(s) Tipo do resultado fabs(x) Valor absoluto Real Real floor(x) Arredondamento para baixo Real Real ceil(x) Arredondamento para cima Real Real sqrt(x) Raiz quadrada Real Real pow(x, y) Potenciação (xy) Real, Real Real exp(x) Exponencial (ex) Real Real log(x) Logaritmo natural Real Real log10(x) Logaritmo na base 10 Real Real Tabela 10: Exemplos de uso de funções numéricas predefinidas em C. Expressão Resultado Expressão Resultado fabs(-2.5) 2.5 pow(2.0 , 3.0) 8.0 fabs(8.0) 8.0 pow(3.0 , 2.0) 9.0 floor(5.234) 5.0 exp(1.0) 2.718282 ceil(2.78) 3.0 log(2.718282) 1.0 sqrt(9.0) 3.0 log10(10.0) 1.0 35 4.4 Operadores relacionais Os operadores relacionais constituem uma expressão lógica, ou seja, uma expressão que retorna um valor booleano5. Em C, um valor booleano é um subconjunto do tipo int, podendo assumir apenas dois valores: zero (referindo-se a falso) ou um (referente a verdadeiro). Não há, em C, um tipo específico para declararmos variáveis do tipo booleano. Desta forma, quando precisarmos de uma variável para receber tais valores, devemos declará-la com o tipo int. Tabela 11: Operadores relacionais da linguagem C. Operador Operação == Igual > Maior < Menor >= Maior ou igual <= Menor ou igual != Diferente Os operadores relacionais são usados em C para comparar valores numéricos ou caracteres. Vejamos alguns exemplos de expressões relacionais. Tabela 12: Exemplos de expressões relacionais em C. Expressão Resultado 1 == 2 0 2.0 == 2 1 5 > 2 1 3 <= 3 1 3.4 != 5.7 1 2 + 3 != 5 0 'A' == 'a' 0 Em C, a comparação entre textos é feita caractere a caractere dos textos envolvidos. Para que isso fique mais claro, é preciso informar que existe uma tabela conhecida como tabela ASCII e esta tabela associa um caractere a um 5 O nome booleano provém da álgebra de Boole. O tipo booleano representa dois valores: verdadeiro ou falso. 36 código numérico, conhecido como código ASCII. Alguns dos códigos ASCII são listados a seguir. Tabela 13: Alguns caracteres da tabela ASCII. Caractere Código ASCII ‘a’ 97 ‘b’ 98 ‘c’ 99 ... ‘y’ 121 ‘z’ 122 Caractere Código ASCII ‘A’ 65 ‘B’ 66 ‘C’ 67 ... ‘Y’ 89 ‘Z’ 90 Caractere Código ASCII ‘0’ 48 ‘1’ 49 ‘2’ 50 ... ‘8’ 56 ‘9’ 57 Exemplificando, na comparação de “JOAO” com “JOSE”, temos que: (ASCII('J') = 74) = (ASCII('J') = 74) (ASCII('O') = 79) = (ASCII('O') = 79) (ASCII('A') = 65) < (ASCII('S') = 83) E, consequentemente, “JOAO” < “JOSE”. 4.5 Operadores lógicos Os operadores lógicos também constituem uma expressão lógica. O resultado e os operandos de um operador lógico são do tipo booleano. A tabela 14 mostra os operadores lógicos presentes na linguagem C. Tabela 14: Operadores lógicos da linguagem C. Operador Operação ! não (negação) && e (conjunção) || ou (disjunção) 37 O operador binário && só retorna o valor 1 quando ambos os operandos forem 1. O operador binário || só retorna o valor 0 quando ambos os operandos forem 0. O operador ! opera sobre um único operando e inverte seu valor lógico. Tabela 15: Exemplos de expressões com operadores lógicos. Expressão Resultado (1 > 2) && (3 > 2) 0 (1 > 2) || (3 > 2) 1 ! (1 > 2) 1 4.6 Prioridade dos operadores Em uma expressão, podem constar vários operadores. Aí, fica a dúvida: Para a expressão 1 + 4 * 5, por exemplo, qual seu resultado? O resultado desta expressão é 21, pois primeiro é calculada a multiplicaçãopara depois ser efetuada a adição. Se fosse da vontade do programador calcular a adição de um por quatro para, em seguida, calcular a multiplicação do valor obtido por cinco, ele deveria ter escrito a expressão desta forma: (1+4) *5. Em C, os parênteses podem ser usados para que determinados cálculos sejam efetuados prioritariamente. Os parênteses mais internos têm maior precedência em relação aos parênteses mais externos. Veja a ordem de cálculo em uma expressão com parênteses dentro de parênteses na expressão a seguir: (4 + 6 * 2 / (4 -1)) + 7 (4 + 6 * 2 / 3) + 7 (4 + 12 / 3) + 7 (4 + 4) + 7 8 + 7 15 38 Na tabela 16, podemos conferir a ordem de prioridade dos operadores estudados neste capítulo. Tabela 16: Prioridade dos operadores em C. Prioridade Operadores 1ª Parênteses mais internos 2ª Funções 3ª ++ -- - (menos unário) 4ª * / % 5ª + - 6ª > < >= <= 7ª == != 8ª ! 9ª && 10ª || 11ª = 12ª Operador mais à esquerda na expressão Mais um exemplo: para calcular o valor da expressão (‘A’ > ‘B’) || (‘B’ == ‘C’), de acordo com a ordem de prioridades, primeiramente é necessário reduzir as expressões entre parênteses a um valor final. Como a expressão (‘A’ > ‘B’) é a que se encontra mais à esquerda na expressão, ela é a primeira a retornar um valor. A expressão passa a ser então 0 || (‘B’ == ‘C’). Novamente, há uma expressão entre parênteses que precisa ser calculada, transformando a expressão atual em 0 || 0. Só neste momento, o operador || é considerado para efeito de cálculo do valor da expressão original, gerando como resultado final o valor 0. 4.7 Exercícios 1 – A ordem das atribuições é importante? A=B e C=A tem o mesmo efeito de C=A e A=B? Em quais dos seguintes pares é importante a ordem dos comandos? a) X = Y; Y = X; b) X = Y; Z = X; c) X = Z; X = Y; d) Z = Y; X = Y; 39 2 – O que são expressões aritméticas? 3 - Determine os valores finais de A, B e C após a execução do trecho do programa abaixo: A = 0; B = 1; C = A + B; A = A + 1; B = A + B + C; 4 - O que são Funções Numéricas Predefinidas? 5 – Escreva o resultado das seguintes funções: a) fabs(-4.0) b) fabs(5.2) c) floor(1.8) d) floor(2.2) e) ceil(1.8) f) ceil(2.2) g) sqrt(25.0) h) sqrt(9.0) i) pow(4.0, 2.0) j) pow(10.0, 2.0) k) log10(100.0) l) log10(1000.0) 6 - Escreva a expressão para calcular o valor de 25. 7 – Sabendo que os valores de X, Y e Z são 1, 2 e 5, respectivamente, qual o resultado das expressões aritméticas abaixo? a) Z % Y / Y b) X + Y + Z / 3 c) floor(X / Z) + ceil(Z / Y) * floor(Z / Y) d) sqrt(Z / Y + X * Y) e) Z - fabs(X - sqrt(8*Y) 8 – Escreva um programa para ler um número inteiro positivo e exibir o dobro do mesmo. 40 9 – Escreva um programa para calcular a área de um triângulo, sendo dadas a sua base e a sua altura. 2 ALTURABASEÁREA ×= 10 – Escreva um programa para calcular e exibir o comprimento de uma circunferência, sendo dado o valor de seu raio. C= 2piR Defina pi, como sendo uma constante de valor igual a 3.1415. 11 – Escreva um programa para ler uma temperatura dada na escala Fahrenheit e exibir o equivalente em Celsius. ( ) 9 532 ×−= FC 12 – Escreva um programa para ler o valor de duas variáveis inteiras e trocar o conteúdo delas. 13 – Escreva um programa para calcular e exibir o valor de xy, sendo dados a base (x) e o expoente (y). 14 – Escreva o resultado das seguintes comparações: a) 1 != 1.0 b) ‘ ’ == ‘x’ c) 0 == 0 d) 1 != 1 e) 8.0 > 8.00 f) ‘5’ < ‘7’ 41 15 – Preencha a tabela abaixo, conhecida como Tabela Verdade: A B A && B A || B !A !B 1 1 1 0 0 1 0 0 16 – Sabendo que os valores de A e B são 1 e 0, respectivamente, qual o resultado das expressões lógicas abaixo? a) !A && B || A && !B b) ! (! (A || B) && (A || B)) c) A || B && !A || !B d) (A || B) && (!A || !B) 42 5 ESTRUTURAS DE DECISÃO Até o presente momento, estamos acostumados com programas que levam em conta estruturas sequenciais, isto é, o primeiro comando a ser executado é o que se encontra logo após o símbolo { do bloco main e os comandos subsequentes vão sendo executados um a um, até que se encontre o símbolo } do bloco main. No entanto, pode acontecer de enviarmos uma instrução ao computador, pedindo que seja executado um conjunto específico de comandos somente se uma determinada condição for satisfeita. Esta situação é permitida através das chamadas estruturas de decisão. As estruturas de decisão ou estruturas condicionais são utilizadas para tomar uma decisão baseada no resultado da avaliação de uma condição de controle e selecionar uma ou mais ações possíveis para serem executadas pelo computador. Em C, há dois tipos de estrutura de decisão: o comando if, usado para escolher um dentre dois caminhos de execução; o comando switch, usado para assumir uma dentre múltiplas decisões. Tais comandos serão vistos nas próximas seções. 5.1 Conando if O comando if deve ser utilizado de uma das seguintes formas: if (condição) { comandoDoIf1; comandoDoIf2; ... comandoDoIfN; } if (condição) { comandoDoIf1; comandoDoIf2; ... comandoDoIfN; } else { comandoDoElse1; comandoDoElse2; ... comandoDoElseM; } 43 Neste caso, condição deve ser necessariamente uma expressão que retorna um valor lógico. Se a condição resultar no valor 1, será executada a lista de comandos presentes entre o { e o } mais próximos após a cláusula if; caso contrário, será executado o conjunto de comandos presentes entre o { e o } mais próximos após a cláusula else, obviamente, se a mesma existir, já que ela é opcional. Mas atenção: caso haja apenas um comando a ser executado, seja na cláusula if, seja na cláusula else, então o { e o } que delimitam o bloco com este único comando podem ser suprimidos. Isso faz com que as seguintes sintaxes sejam também válidas para o comando IF: a) if (condição) comandoDoIf; b) if (condição) comandoDoIf; else comandoDoElse; c) if (condição) { comandoDoIf1; comandoDoIf2; ... comandoDoIfN; } else comandoDoElse; d) if (condição) comandoDoIf; else { comandoDoElse1; comandoDoElse2; ... comandoDoElseM; } O exemplo a seguir serve para ilustrar um desvio na programação. Neste documento, a partir de agora, sempre que surgir uma numeração, antecedendo algum código computacional em uma linha, servirá apenas para identificá-lo. 01 #include <stdio.h> 02 #include <conio.h> 03 main() 04 { 05 //Programa que lê um inteiro e o exibe se for positivo 06 int N; 07 printf("Programa que le um inteiro e o exibe se for positivo\n\n "); 08 printf("Escreva um numero inteiro: "); 09 scanf("%d", &N); 10 if (N > 0) 11 printf("%d", N); 12 getch(); 13 } 44 No exemplo acima, o comando printf da linha 11 só será executado se a condição N>0 for verdadeira, ou seja, igual a 1. Caso contrário, após o teste desta condição presente na linha 10, o processamento avança para a linha 12. Vejamos agora um exemplo de um comando if que inclui a cláusula else: 01 #include <stdio.h> 02 #include <conio.h> 03 main() 04 { 05 //Programa que lê um inteiro e diz se é ou não maior que zero 06 int N; 07printf("Programa que le um inteiro e diz se e ou nao maior que zero\n\n"); 08 printf("Escreva um numero inteiro: "); 09 scanf("%d", &N); 10 if (N > 0) 11 printf("%d e maior que zero", N); 12 else printf("%d nao e maior que zero", N); 13 getch(); 14 } Neste exemplo, a mensagem que será exibida dependerá do resultado da expressão lógica N>0. Se for verdadeira, ou seja, igual a 1, será executado o comando printf da linha 11. Caso contrário, será executado o printf presente na linha 12. Em nenhuma hipótese serão executados os dois comandos. De acordo com a sintaxe do comando if, quaisquer comandos podem ser inseridos entre o { e o }, seja na cláusula if, seja na cláusula else. Assim, nada impede que outro comando if seja um destes comandos. Quando este cenário surge, temos o que é conhecido em computação como estruturas de decisão aninhadas. Vejamos um exemplo: 01 #include <stdio.h> 02 #include <conio.h> 03 main() 04 { 05 //Programa que vê se um inteiro é maior, menor ou igual a zero 06 int N; 07 printf("Programa que ve se um inteiro e maior, menor ou igual a zero\n\n"); 08 printf("Escreva um numero inteiro: "); 45 09 scanf("%d", &N); 10 if (N > 0) 11 printf("%d e maior que zero", N); 12 else if (N < 0) 13 printf("%d e menor que zero", N); 14 else printf("%d e igual a zero", N); 15 getch(); 16 } Um else sempre está associado ao if anterior e mais próximo a ele. Desta forma, é conveniente escrever um else sempre na mesma coluna do if associado a ele. 5.2 Comando switch (decisão múltipla) A cada comando if só é permitido seguir por um dentre dois caminhos: um caminho é o que corresponde a uma condição de teste que resulta em um valor verdadeiro, ou seja, igual a 1; o outro caminho é o que corresponde a uma condição de teste que resulta em um valor falso, ou seja, igual a 0. Tal limitação é contornada através de comandos if aninhados, mas um programa fica muito mais compreensível quando substituímos o aninhamento de comandos if por outra estrutura de decisão conhecida como comando de decisão múltipla. O comando de decisão múltipla é utilizado quando se deseja oferecer mais de dois caminhos que possam ser tomados, dependendo do valor de uma expressão – expressão esta que deva obrigatoriamente resultar num valor char ou um int. A estrutura de decisão múltipla – também conhecida como estrutura de seleção – é implementada em C com o comando switch e obedece a seguinte sintaxe: switch (expressão) { case constante1 : comando1DaConstante1; comando2DaConstante1; ... comandoWDaConstante1; break; 46 case constante2 : comando1DaConstante2; comando2DaConstante2; ... comandoXDaConstante2; break; ... case constanteN : comando1DaConstanteN; comando2DaConstanteN; ... comandoYDaConstanteN; break; default : comando1DoDefault; comando2DoDefault; ... comandoZDoDefault; } O valor do resultado da expressão é testado e, em seguida, procura-se, em cada cláusula case, uma constante com o mesmo valor deste resultado. Quando uma coincidência for encontrada, a sequência de comandos associados àquele case será executada até que o comando break ou o fim do comando switch seja alcançado. A cláusula default será executada se nenhuma coincidência for detectada. A cláusula default é opcional e, se ela não fizer parte do comando switch, na falha de todos os testes case, nenhuma ação será realizada. Tecnicamente, os comandos break são também opcionais dentro de um comando switch. Um comando break faz com que o processamento da execução do programa salte para a próxima linha de código após o término do bloco que define os comandos do switch. É importante reforçar que se o comando break for omitido na lista de comandos associados a alguma cláusula case, então a execução continuará pelos comandos associados a cada outro case definido posteriormente, até que um break seja encontrado ou até o fim do bloco de comandos do switch. Veja o exemplo a seguir: 01 #include <stdio.h> 02 #include <conio.h> 47 03 main() 04 { 05 float X, Y; 06 char OP; 07 printf("Simulador de uma calculadora basica de numeros reais\n\n"); 08 printf("Digite o primeiro operando: "); 09 scanf("%f", &X); 10 printf("Digite o segundo operando : "); 11 scanf("%f", &Y); 12 printf("Digite o operador : "); 13 scanf("\n%c", &OP); 14 //O '\n' serve para consumir o <ENTER> digitado na entrada da segunda variável. 15 switch(OP) 16 { 17 case '+' : printf("Resultado: %f", X+Y); 18 break; 19 case '-' : printf("Resultado: %f", X-Y); 20 break; 21 case '*' : 22 case 'x' : 23 case 'X' : printf("Resultado: %f", X*Y); 24 break; 25 case '/' : printf("Resultado: %f", X/Y); 26 break; 27 default : printf("\nOperador invalido (%c).", OP); 28 } 29 getch(); 30 } Neste exemplo, se o conteúdo da variável OP for igual a uma das constantes especificadas em algum case, o comando printf correspondente será executado mas, se nenhuma das constantes representar o valor de OP, o printf do default será o executado. Como já mencionado no início desta seção, qualquer comando switch pode ser transcrito utilizando-se comandos if aninhados, porém, a quantidade de diversas condições provoca a dificuldade de compreensão do programa. Vejamos o exemplo da transcrição do programa acima: 01 #include <stdio.h> 02 #include <conio.h> 03 main() 04 { 05 float X, Y; 06 char OP; 07 printf("Simulador de uma calculadora basica de numeros reais"\n\n"); 08 printf("Digite o primeiro operando: "); 48 09 scanf("%f", &X); 10 printf("Digite o segundo operando : "); 11 scanf("%f", &Y); 12 printf("Digite o operador : "); 13 scanf("\n%c", &OP); 14 if (OP == '+') 15 printf("Resultado: %f", X+Y); 16 else if (OP == '-') 17 printf("Resultado: %f", X-Y); 18 else if ((OP == '*') || (OP == 'x') || (OP == 'X')) 19 printf("Resultado: %f", X*Y); 20 else if (OP == '/') 21 printf("Resultado: %f", X/Y); 22 else printf("\nOperador invalido (%c).", OP); 23 getch(); 24 } 5.3 Exercícios 1 – Qual a utilidade da estrutura de decisão? 2 – Deseja-se calcular a conta de consumo de energia elétrica de um consumidor. Para isto, escreva um programa que leia o código do consumidor, o preço do Kw e a quantidade de Kw consumido para, em seguida, exibir o código do consumidor e o total a pagar. - total a pagar = preço x quantidade - total a pagar mínimo = R$ 11,20 3 – Os comandos (i) e (ii) são equivalentes? Explique sua resposta. (i) A = B == C; (ii) if (B == C) A = 1; else A = 0; 4 – Escreva um programa para ler dois números e exibir o maior deles. 5 – Escreva um programa para ler dois números e exibi-los em ordem crescente. 49 6 – Escreva um programa para ler um número inteiro e determinar se ele é par ou ímpar. 7 – Observe o trecho de programa abaixo, considerando L1, L2 e L3 como variáveis booleanas. if (L1) { printf("A"); } else { if (L2) { if (L3) { printf("B"); } else { printf("C");printf("D"); } } else { printf("E"); } } Agora, responda as seguintes questões: a) Se, para L1, L2 e L3, forem lidos 1, 1 e 1, o que será escrito pelo algoritmo? b) Se, para L1, L2 e L3, forem lidos 0, 1 e 1, o que será escrito pelo algoritmo? c) Se, para L1, L2 e L3, forem lidos 0, 1 e 0, o que será escrito pelo algoritmo? d) Que valores deveriam ser lidos para que fosse escrito apenas "E"? 8 – Escreva um programa para ler três números inteiros distintos e determinar o menor deles. 9 – Faça um programa que, dadas as três notas de um aluno, determine e exiba a sua média final e o seu conceito, sabendo que: 50 -a média final é calculada pela média aritmética das três notas; -o conceito é determinado de com base na tabela abaixo: MÉDIA FINAL CONCEITO >= 8,0 A >= 5,0 e < 8,0 B < 5,0 C 10 – Escreva um programa para determinar o grau de obesidade de uma pessoa, sendo fornecidos o peso e a altura da pessoa. O grau de obesidade é determinado pelo índice da massa corpórea (Massa = Peso / Altura2) através da tabela abaixo: MASSA CORPÓREA GRAU DE OBESIDADE < 26 Normal >= 26 e < 30 Obeso >= 30 Obeso Mórbido 11 – Um clube de futebol deseja aumentar o salário de seus jogadores. O reajuste deve obedecer à seguinte tabela: SALÁRIO ATUAL (R$) AUMENTO 0,00 a 1.000,00 20% 1.000,01 a 5.000,00 10% Acima de 5.000,00 0% Escreva um programa para ler o nome e o salário atual de um jogador, e exibir o nome e o salário reajustado. 12 – Quais são os comandos de decisão em C? 13 – Em que situações é mais indicado o uso do comando “switch”? 14 – Faça um programa para calcular a conta final de um hóspede de um hotel, considerando que: 51 a) serão lidos o nome do hóspede, o tipo do apartamento utilizado (A, B, C ou D), o número de diárias utilizadas pelo hóspede e o valor do consumo interno do hóspede; b) o valor da diária é determinado pela seguinte tabela: TIPO DO APTO. VALOR DA DIÁRIA (R$) A 150,00 B 100,00 C 75,00 D 50,00 c) o valor total das diárias é o número de diárias usadas multiplicado pelo valor da diária; d) o subtotal é calculado pela soma do valor total das diárias e o valor do consumo interno; e) o valor da taxa de serviço equivale a 10% do subtotal; f) o total geral resulta da soma do subtotal com a taxa de serviço. Escreva a conta final contendo: o nome do hóspede, o tipo do apartamento, o número de diárias utilizadas, o valor unitário da diária, o valor total das diárias, o valor do consumo interno, o subtotal, o valor da taxa de serviço e o total geral. 15 – Escreva um programa para ler uma data válida em números e escrevê-la em forma de texto. Veja um exemplo do comportamento deste programa abaixo: entrada: 14 07 1995 saída: “14 de julho de 1995” 52 6 ESTRUTURAS DE REPETIÇÃO A estrutura ou laço de repetição permite que uma sequência de comandos seja executada repetidamente enquanto uma determinada condição seja satisfeita. Em C, há basicamente dois tipos de estrutura de repetição: com teste no início e com teste no final. Outras possibilidades são também abordadas, tais como o laço de repetição com variável de controle e com saída forçada. 6.1 Repetição com teste no início (comando while) A estrutura de controle definida pelo comando while permite que um conjunto de comandos seja executado repetidamente, enquanto uma condição de controle seja verdadeira, ou seja, tenha seu valor igual a 1. Segue a sintaxe do comando while: // atribuição de um valor inicial a uma variável de controle while (condição) { // comandos a serem repetidos // um deles deve modificar o valor da variável de controle } Os comandos a serem repetidos encontram-se entre as chaves que delimitam o bloco de comandos do laço de repetição. A condição deve ser uma expressão lógica. No caso de existir um único comando a ser repetido, os caracteres { e } podem ser suprimidos. Uma estrutura de repetição pode perfeitamente ser um comando a ser repetido, o que caracteriza uma repetição aninhada. 53 Como o teste da condição é realizado no início do laço, a lista de comandos a serem repetidos pode, eventualmente, não ser executada sequer uma única vez. Seja o seguinte exemplo: 01 #include <stdio.h> 02 #include <conio.h> 03 main() 04 { 05 int N; 06 printf("Lista dos numeros entre 1 e 100\n\n"); 07 N = 1; 08 while (N <= 100) 09 { 10 printf("%8d", N); 11 N = N + 1; //++N; 12 } 13 getch(); 14 } Neste exemplo, os comandos presentes nas linhas 10 e 11 serão executados repetidas vezes enquanto a variável N possuir um valor inferior ou igual a 100. O algoritmo terá como saída a sequência dos números inteiros de 1 a 100. O comando N = N +1; da linha 11 poderia ser substituído pelo comando ++N. Lembre-se do operador ++, introduzido na seção 4.2. Na linha 10, encontra-se o especificador de formato %8d. Este especificador significa um número decimal de tamanho 8. A execução deste programa resultará no seguinte: 54 Figura 10: Execução do programa MeuPrograma.c (versão 9) Toda estrutura de repetição deve possuir uma condição de parada. Quando isso não acontece, ocorre o que chamamos de loop infinito. É fundamental a atribuição de um valor inicial às variáveis envolvidas na condição de teste para entrada no laço de repetição. Isso porque, se o programador não fizer tal atribuição, o próprio computador se encarregará disto, não tendo o programador como prever tais valores. No programa exemplo, esta atribuição foi efetuada na linha 08. Exemplificando, vejamos as seguintes linhas de código: 01 #include <stdio.h> 02 #include <conio.h> 03 main() 04 { 05 int NUM, SOMA, CONT; 06 printf("Escreve a soma de 10 numeros fornecidos pelo usuario\n\n"); 07 SOMA = 0; 08 CONT = 1; 09 while (CONT <= 10) 10 { 11 printf("Digite um numero inteiro: "); 12 scanf("%d", &NUM); 13 SOMA = SOMA + NUM; 14 CONT = CONT + 1; 15 } 16 printf("A soma e %d.\n", SOMA); 17 getch(); 18 } Se a linha 08 não existisse, permitir-se-ia ao computador atribuir à variável CONT um valor diferente de um, o que resultaria na entrada de uma quantidade diferente de dez valores por parte do usuário. Ademais, no que tange à exatidão do algoritmo, o zero é o elemento neutro da adição. Sem a atribuição presente na linha 07, estaríamos correndo o risco de o computador atribuir um valor diferente de zero à variável SOMA, o que, 55 evidentemente, provocaria a saída de um resultado não correspondente à soma dos valores fornecidos pelo usuário. 6.2 Repetição com variável de controle (comando for) Em C, há um comando de repetição muito parecido com o while. Na verdade, é um comando que substitui o while com a vantagem de se escrever menos. Veja a correlação entre o while e este comando – o comando for: variávelDeControle = valorInicial; while (condição) { // comandos variávelDeControle = novoValor; } for (variávelDeControle = valorInicial; condição; variávelDeControle = novoValor) { // comandos } O primeiro programa da seção anterior pode ser escrito com o uso do comando for como a seguir: 01 #include <stdio.h> 02 #include <conio.h> 03 main() 04 { 05 int N; 06 printf("Lista dos numeros entre 1 e 100\n\n"); 07 for (N = 1; N <= 100; N = N + 1) 08 { 09 printf("%8d", N); 10 } 11 getch(); 12 } 6.3 Repetição com saída forçada Pode ocorrer de não conhecermos
Compartilhar