Baixe o app para aproveitar ainda mais
Prévia do material em texto
ALGORITMOS E PROGRAMAÇÃO II 2 ALGORITMOS E PROGRAMAÇÃO II Algoritmos e Programação II 3 ALGORITMOS E PROGRAMAÇÃO II Sumário 1 INTRODUÇÃO À LINGUAGEM C ........................................................................ 6 1.1 ESTRUTURA BÁSICA DE UM PROGRAMA EM LINGUAGEM C ................................................. 6 1.2 IDENTIFICADORES ................................................................................................................ 7 1.3 TIPOS DE DADOS ................................................................................................................. 8 1.4 MODELADORES ................................................................................................................... 8 1.5 DECLARAÇÃO, INICIALIZAÇÃO E ESCOPO DE VARIÁVEIS ..................................................... 9 1.6 DEFINIÇÃO DE CONSTANTES ............................................................................................... 9 1.7 CÓDIGOS DE FORMATO .................................................................................................. 10 1.8 CARACTERES ESPECIAIS .................................................................................................... 12 1.9 COMANDO DE ATRIBUIÇÃO ............................................................................................. 12 1.10 OPERADORES E FUNÇÕES .............................................................................................. 13 1.11 COMENTÁRIOS .............................................................................................................. 14 1.12 FUNÇÕES DE ENTRADA E SAÍDA DE DADOS .................................................................... 15 1.13 FUNÇÕES DE TELA .......................................................................................................... 18 1.14 EXEMPLO DO USO DAS FUNÇÕES DE ENTRADA E SAÍDA E DE TELA ................................ 19 2 ESTRUTURAS BÁSICAS DE CONTROLE ............................................................. 23 2.1 ESTRUTURA SEQUENCIAL .................................................................................................. 23 2.2 ESTRUTURA CONDICIONAL ............................................................................................... 24 2.3 ESTRUTURA DE REPETIÇÃO ................................................................................................ 29 3 VARIÁVEIS INDEXADAS UNIDIMENSIONAIS ................................................... 41 3.1 ESTRUTURA ....................................................................................................................... 42 3.2 DECLARAÇÃO ................................................................................................................... 42 3.3 MANIPULAÇÃO ................................................................................................................ 43 3.4 EXEMPLOS DO USO DE VETORES ...................................................................................... 44 4 STRINGS ............................................................................................................ 54 4.1 DECLARAÇÃO E INICIALIZAÇÃO ........................................................................................ 54 4.2 ENTRADA DE DADOS ........................................................................................................ 55 4.3 SAÍDA DE DADOS ............................................................................................................. 57 4.4 FUNÇÕES PARA MANIPULAÇÃO DE STRINGS .................................................................... 58 5 VARIÁVEIS INDEXADAS BIDIMENSIONAIS ...................................................... 67 5.1 ESTRUTURA ....................................................................................................................... 67 5.2 DECLARAÇÃO ................................................................................................................... 68 5.3 MANIPULAÇÃO ................................................................................................................ 69 5.4 EXEMPLOS ........................................................................................................................ 71 6 ESTRUTURAS ..................................................................................................... 81 6.1 DECLARAÇÃO ................................................................................................................... 81 6.2 MANIPULAÇÃO ................................................................................................................ 82 6.3 VETORES DE ESTRUTURAS ................................................................................................. 84 7 PONTEIROS ....................................................................................................... 89 7.1 USANDO PONTEIROS PARA MANIPULAR VETORES ............................................................ 91 8 FUNÇÕES .......................................................................................................... 95 8.1 PASSAGEM DE PARÂMETROS POR VALOR ........................................................................ 96 4 ALGORITMOS E PROGRAMAÇÃO II 8.2 PASSAGEM DE PARÂMETROS POR REFERÊNCIA ................................................................. 99 8.3 VETORES COMO ARGUMENTO DE FUNÇÕES ................................................................. 101 8.4 MATRIZES COMO ARGUMENTO DE FUNÇÕES ................................................................ 103 8.5 ESTRUTURAS COMO ARGUMENTO DE FUNÇÕES ............................................................ 104 8.6 ESTRUTURAS COMO RETORNO DE FUNÇÕES .................................................................. 105 9 ARQUIVOS ...................................................................................................... 111 9.1 FUNÇÕES PARA MANIPULAÇÃO DE ARQUIVOS .............................................................. 111 9.2 PROGRAMA EXEMPLO DA MANIPULAÇÃO DE REGISTROS E ARQUIVOS .......................... 115 10 DEV-C++: INSTALAÇÃO E CONFIGURAÇÃO .............................................. 128 10.1 INSTALANDO O DEV-C++ ......................................................................................... 128 10.2 INSTALANDO A BIBLIOTECA CONIO.H .......................................................................... 133 10.3 CONFIGURANDO A INTERFACE DO EDITOR DO DEV-C++ ......................................... 138 10.4 UTILIZANDO O DEV-C++ ........................................................................................... 142 5 ALGORITMOS E PROGRAMAÇÃO II Apresentação Esta disciplina dá continuidade ao estudo de lógica de programação iniciado em Algoritmos e Programação I e introduz o aluno no universo da programação, de forma que no final do semestre ele estará capacitado a construir programas em linguagem C. Para isso, vamos estudar variáveis indexadas, estruturas, ponteiros, funções e arquivos. Só é possível aprender a programar, programando! Portanto, resolver os exercícios propostos no final de cada capítulo, utilizando um compilador C, é fundamental para atingir o objetivo desta disciplina. Optou-se por usar o Dev-C++, que é um ambiente de desenvolvimento integrado, com enorme potencial para desenvolver programas em linguagem C e C++ no sistema operacional Windows. Diante do exposto, sugere-se que o aluno vá direto ao capítulo 10 para instalar e configurar o Dev-C++ no seu computador. Assim, a cada capítulo estudado, será possível executar os exemplos e realizar os exercícios propostos.A disciplina possui conteúdos cumulativos, ou seja, no final do semestre ainda estaremos utilizando conceitos estudados nas primeiras semanas de aula. Portanto, é importante organizar o estudo, resolver os problemas propostos periodicamente e não deixar as dúvidas para depois. As referências bibliográficas sugerem obras de autores que fundamentam os estudos realizados e oferecem ao aluno possibilidades de aprofundamento com leituras complementares. 6 ALGORITMOS E PROGRAMAÇÃO II 1 Introdução à Linguagem C Vanessa Lindemann* A linguagem C, criada por Dennis Ritchie na década de 70, resultou de um processo evolutivo de linguagens e, durante alguns anos, teve seu padrão baseado na versão 5 do sistema operacional UNIX. Com a popularização dos microcomputadores, várias versões de C foram criadas, gerando muitas discrepâncias entre elas. Para resolver essa situação, em 1983, o ANSI (American National Standards Institute) estabeleceu um comitê para definir um padrão que guiasse todas as implementações da linguagem C. A popularização da linguagem C deve-se a vários fatores, dentre os quais destacam-se (a) o conjunto de operadores e tipos de dados disponíveis; (b) a portabilidade, podendo ser usada em máquinas de portes e de sistemas operacionais diferentes; (c) as características de linguagens de alto nível, aliadas às características de linguagens de baixo nível (também conhecidas como linguagem de máquina, manipulam bits, bytes e endereços). C é uma linguagem de propósitos gerais, estruturada e compilada (o compilador lê o código-fonte do programa inteiro e converte-o em um código executável). Ela é utilizada para a construção de sistemas operacionais, compiladores, interpretadores, editores de textos, planilhas eletrônicas, aplicativos para dispositivos móveis, programas para a automação industrial, gerenciadores de bancos de dados, etc. As próximas seções são dedicadas à apresentação de conceitos e definições importantes e necessárias para o início da programação em linguagem C. 1.1 Estrutura básica de um programa em linguagem C Um programa em linguagem C consiste em uma ou mais funções. A função principal, denominada main, indica onde o programa inicia. A estrutura básica de um programa em C é apresentada a seguir. #include <nome da biblioteca> main( ) { // declaração de variáveis // bloco de comandos } Bibliotecas são arquivos contendo várias funções que podem ser incorporadas aos programas escritos em C (estes arquivos são chamados * Doutora em Informática na Educação pela UFRGS (2008); professora dos cursos da área da Computação da ULBRA. 7 ALGORITMOS E PROGRAMAÇÃO II arquivos de cabeçalho − cabeçalho em inglês é header, o que explica a extensão .h usada logo após o nome dos arquivos). A diretiva #include faz com que as funções inseridas na biblioteca especificada possam ser utilizadas no programa. As bibliotecas stdio.h e conio.h, por exemplo, permitem a utilização de funções de entrada e saída padrão e de funções de tela, respectivamente. São exemplos de funções de tela, os comandos usados para limpar a tela, posicionar o cursor em uma determinada posição na tela, trocar a cor da fonte e/ou do fundo. A diretiva #include pode ser usada de duas formas: #include "nome da biblioteca" ou #include <nome da biblioteca>. A diferença entre se usar " " e < > é somente a ordem de procura pelo arquivo especificado nos diretórios. Usa-se " " para informar o nome do arquivo com o caminho completo, ou se o arquivo estiver no diretório de trabalho. Quando o arquivo estiver no caminho padrão do compilador (como é o caso de arquivos como stdio.h e string.h, por exemplo), usa-se os símbolos < e >. Os parênteses ao lado da palavra main indicam que ela é uma função, enquanto as chaves delimitam o seu início e o seu fim. O bloco de comandos que estiver entre as chaves é executado sequencialmente quando a função for chamada. Uma boa prática de programação do padrão ANSI é declarar a função main como int main(void) e, no seu final, antes de fechar a chave que delimita o corpo da função, incluir a instrução return 0; − essa prática evita que, ao executar os programas, alguns compiladores emitam uma mensagem do tipo A função deve retornar um valor. Como o compilador do Dev-C++, utilizado nesta disciplina, não emite esta mensagem, optou-se por não adotar esta prática nos exemplos deste livro. É importante salientar que a linguagem C é case sensitive, ou seja, é sensível a letras maiúsculas e minúsculas (por exemplo, uma variável declarada como a é diferente de A) e todos os programas devem, obrigatoriamente, ser escritos em letras minúsculas. Outro detalhe importante é que cada instrução primitiva é finalizada com um ponto-e- vírgula (vale destacar que não há ponto e vírgula após as diretivas de compilação #include e #define, nem após as estruturas de controle apresentadas no próximo capítulo). 1.2 Identificadores Em linguagem C, os nomes utilizados para referenciar variáveis, constantes e funções definidas pelo usuário são chamados de identificadores. A criação de um identificador deve seguir as seguintes regras: podem ser formados por letras, números e sublinhado; devem iniciar com uma letra 8 ALGORITMOS E PROGRAMAÇÃO II ou com o sublinhado; letras minúsculas e maiúsculas são consideradas caracteres distintos; não podem ser palavras reservadas; podem conter qualquer tamanho, porém apenas os 32 primeiros caracteres são significativos. Além disso, é importante criar identificadores considerando a sua aplicação para facilitar a leitura do código-fonte e, consequentemente, o trabalho do programador. A quantidade de horas trabalhadas por uma pessoa durante uma semana de trabalho, por exemplo, pode ser armazenada em uma variável chamada qtde_horas; enquanto uma função que irá verificar se uma data é válida ou não pode ter como identificador valida_data. 1.3 Tipos de dados Os tipos de dados básicos em linguagem C são: int (número inteiro), float (número real, representado em ponto flutuante), double (número real, representado em ponto flutuante com maior precisão), char (caractere) e void (vazio, sem valor). A linguagem C não possui tipo de dado lógico (que pode assumir verdadeiro ou falso), pois considera qualquer valor diferente de 0 (zero) como verdadeiro; e também não possui um tipo especial para armazenar cadeias de caracteres (strings), estas são armazenadas em um vetor de caracteres. A Tabela 1.1 apresenta a lista de tipos básicos utilizados em C. Tabela 1.1 − Tipos de dados básicos da linguagem C Tipo Faixa de valores Tamanho char -127 a 127 8 bits int -32.767 a 32.767 16 bits float 3.4 E-38 a 3.4 E+38 32 bits double 1.7 E-308 a 1.7 E+308 64 bits void vazio, sem valor 0 A faixa de valores apresentada está de acordo com o padrão ANSI e é considerada a faixa mínima. Dependendo do processador e do compilador C que estiver sendo utilizado, o tamanho e a faixa de valores podem variar. 1.4 Modeladores É possível forçar que o resultado de uma expressão seja de um tipo específico usando o conceito de modelador. A forma geral de um modelador é (tipo)expressão onde tipo é um dos tipos padrão da linguagem C. 9 ALGORITMOS E PROGRAMAÇÃO II Sendo r uma variável declarada do tipo float, as expressões a seguir resultam em valores diferentes. A primeira expressão resulta 4, enquanto que a segunda, com o uso do modelador, resulta 4.5. r=9/2; r=(float)9/2; 1.5 Declaração, inicialização e escopo de variáveis Variável é uma posição de memória, identificada por um nome (identificador), usada para armazenar um dado de um determinado tipo por vez. As variáveis são declaradas após a especificaçãode seus tipos, como pode ser observado nos exemplos a seguir. float total; int idade, cont; A primeira linha da declaração de variáveis do exemplo cria uma variável chamada total, que irá armazenar valores do tipo real; na segunda linha, são criadas duas variáveis para armazenar valores do tipo inteiro, idade e cont. Cada uma destas variáveis armazenará um único valor por vez. As variáveis podem ser inicializadas no momento da sua declaração, colocando o sinal de atribuição seguido da informação desejada, como no exemplo apresentado a seguir, em que cont é inicializada com 0 e resposta com S. É importante destacar que os dados atribuídos a variáveis do tipo caractere são envolvidos por apóstrofes. int cont=0; char resposta='S'; O local em que as variáveis são declaradas definem o seu escopo, que pode ser global ou local. As variáveis de escopo global, denominadas variáveis globais, são declaradas fora de qualquer função, inicializadas automaticamente com 0 (zero) e podem ser usadas em qualquer ponto do programa. As variáveis locais são declaradas dentro de uma função, não são inicializadas automaticamente e valem enquanto esta função estiver ativa. As variáveis de escopo local têm preferência em relação às de escopo global. 1.6 Definição de constantes Uma constante irá representar um valor fixo, previamente definido pelo programador e inalterável no programa. Uma das formas de definir constantes em C é através da diretiva #define, seguida do nome da constante e do valor que esta representará no programa. No exemplo a 10 ALGORITMOS E PROGRAMAÇÃO II seguir, apresenta-se a declaração da constante pi cujo valor é definido como 3.141516. Desta forma, o programador usará pi no programa ao invés de usar 3.141516. #define pi 3.141516 1.7 Códigos de formato Os códigos de formato são constantes que definem o formato dos dados a serem lidos e exibidos na tela. A Tabela 1.2 apresenta alguns dos códigos de formato disponíveis em C. Tabela 1.2 − Códigos de formatação Código Formato %c Caractere %i Inteiro %f Ponto flutuante %lf Ponto flutuante longo (double) %s Cadeia de caracteres (string) Eles são usados em funções de entrada e de saída de dados (descritas na seção 1.12). A função de entrada scanf, por exemplo, possui dois argumentos: o código de formato e uma variável. No exemplo apresentado a seguir, o valor digitado pelo usuário será armazenado na variável denominada peso, declarada e formatada como float. scanf("%f",&peso); A função printf, exemplificada a seguir, também contém dois argumentos: o primeiro é uma mensagem, apresentada entre aspas; o segundo é uma variável, denominada dias. O valor armazenado na variável dias será exibido na posição em que aparece o código de formato usado na mensagem, neste caso o %i. printf("Sua idade em dias e: %i", dias); Os códigos de formato podem ter modificadores que especifiquem o tamanho do campo, o número de casas decimais e um indicador de justificação à esquerda. Especificador de largura mínima do campo: um valor entre o símbolo % e o caractere de formato indica a largura mínima do campo, preenchendo a saída com brancos (padrão) ou com zeros (coloca-se um 0 antes do especificador de tamanho). Quando um valor é maior que o mínimo definido, 11 ALGORITMOS E PROGRAMAÇÃO II este será impresso por completo. Exemplos: %05d preencherá um número com menos de cinco dígitos com zeros à esquerda, de maneira que seu tamanho total seja cinco. Especificador do número de casas decimais: para definir o número de casas decimais a serem exibidas em um ponto flutuante, usa-se um ponto entre o especificador de tamanho e o número de casas decimais desejadas. Por exemplo: %6.2f exibirá um valor com, no mínimo, seis dígitos de comprimento no total, com duas casas decimais (o ponto usado antes das casas decimais ocupa o espaço de um dígito, como pode ser observado nos exemplos apresentados na Tabela 1.3). Especificador para justificar informação à esquerda: por definição, toda saída é justificada à direita. O uso do sinal – depois do % faz com que a saída seja justificada à esquerda. Exemplo: %-6.2f justificará à esquerda um valor de ponto flutuante, com no mínimo seis dígitos no total, com duas casas decimais. A Tabela 1.3 apresenta exemplos da utilização dos especificadores de tipos. O caractere especial \n, usado nos exemplos, inicia uma nova linha antes de exibir o valor na tela. Tabela 1.3 − Exemplo da utilização dos especificadores de tipos Código Resultado float valor=136.472; printf("\n %f",valor); printf("\n %8.1f",valor); printf("\n %08.1f",valor); printf("\n %-8.1f",valor); 136.472000 136.5 000136.5 136.5 int valor=790; printf("\n %i",valor); printf("\n %5i",valor); printf("\n %05i",valor); printf("\n %-5i",valor); 790 790 00790 790 printf("\n O total é %2i.",350); printf("\n O total é %4i.",350); printf("\n O total é %5i.",350); O total é 350. O total é 350. O total é 350. 12 ALGORITMOS E PROGRAMAÇÃO II 1.8 Caracteres especiais Os caracteres especiais são usados para representar alguma formatação em particular e caracteres especiais que seriam impossíveis de usar diretamente no código-fonte. Esses caracteres devem ser precedidos da barra invertida, como o \n que representa nova linha. A Tabela 1.4 apresenta os caracteres e seus significados. Tabela 1.4 − Códigos de caracteres especiais Código Significado Código Significado \a alerta (beep) \v tab vertical \b retrocesso (backspace) \\ exibe barra invertida \f avanço de página \’ exibe aspa única \n nova linha \“ exibe aspas duplas \r retorna ao início da linha \? exibe ponto de interrogação \t tab horizontal \0 nulo 1.9 Comando de atribuição O comando de atribuição, representado pelo sinal de igualdade, é utilizado para atribuir valores a variáveis. É importante lembrar que os valores atribuídos a uma variável devem ser compatíveis com o seu tipo. Alguns exemplos de atribuição podem ser observados a seguir. total=345.60; resp='s'; cont=cont+1; Os caracteres são representados entre apóstrofes ( ' ) e as cadeias de caracteres entre aspas ( " ). Entretanto, caso seja necessário atribuir uma cadeia de caracteres a uma variável, utiliza-se a função strcpy, como ilustra o exemplo a seguir. strcpy(nome,"Ana Paula Rocha"); Para utilizar strcpy (abreviação de string copy) é preciso inserir no programa, através da diretiva #include, a biblioteca string.h. Essa e outras funções para manipulação de strings serão descritas no capítulo 4. É possível atribuir um valor a duas ou mais variáveis através de um único comando, como na instrução primitiva x=y=10, em que as variáveis x e y recebem 10. 13 ALGORITMOS E PROGRAMAÇÃO II 1.10 Operadores e funções A linguagem C possui operadores e funções predefinidas destinadas a cálculos matemáticos e à manipulação de caracteres. Os operadores aritméticos e relacionais são apresentados nas Tabelas 1.5 e 1.6, respectivamente. Os operadores lógicos são apresentados na Tabela 1.7 e os operadores reduzidos na Tabela 1.8. Tabela 1.5 − Operadores aritméticos Operador Exemplo Descrição + a + b Soma o conteúdo de a e de b. - a – b Subtrai o conteúdo de b do conteúdo de a. * a * b Multiplica o conteúdo de a pelo conteúdo de b. / a / b Divide o conteúdo de a pelo conteúdo de b. % a % b Obtém o resto da divisão de a por b.* * O operador % só pode ser utilizado com operandos do tipo inteiro. Tabela 1.6 − Operadores relacionais Operador Exemplo Descrição == a==b Testa se o conteúdo de a é igual ao conteúdo de b. != a!=b Testa se o conteúdo de a é diferente do conteúdo de b. <= a<=b Testase o conteúdo de a é menor ou igual que o conteúdo de b. >= a>=b Testa se o conteúdo de a é maior ou igual que o conteúdo de b. < a<b Testa se o conteúdo de a é menor que o conteúdo de b. > a>b Testa se o conteúdo de a é maior que o conteúdo de b. Tabela 1.7 − Operadores lógicos Operador Símbolo Descrição e && Conjunção ou || Disjunção não ! Negação Tabela 1.8 − Operadores reduzidos Expressão Equivalente com operadores reduzidos total=total+valor; total+=valor; num=num*5; num*=5; d=d-valor; d-=valor; x=x/5; x/=5; 14 ALGORITMOS E PROGRAMAÇÃO II Além dos operadores apresentados anteriormente, a linguagem C disponibiliza operadores de pré e pós incremento e decremento, descritos na Tabela 1.9. Tabela 1.9 − Operadores pré e pós-fixado Operador Descrição Pré-fixado Pós-fixado ++ Incrementa ++n n++ -- Decrementa --n n-- O operador ++ incrementa um ao valor do seu operando, enquanto –- decrementa um. Estes operadores podem ser usados antes (pré-fixados) ou depois (pós-fixados) do nome da variável. Em ambos os casos a variável é incrementada ou decrementada. Entretanto, ++n incrementa o valor da variável n antes que n seja usada e n++ usa o valor de n e depois o incrementa. Resumindo: ++i è incrementa o valor de i em um e depois o utiliza; i++ è utiliza o valor de i e depois incrementa-o em um. Logo, conclui-se que: z=a; a=a+1; é equivalente a z=a++; z=a; a=a-1; é equivalente a z=a--; a=a+1; z=a; é equivalente a z=++a; a=a-1; z=a; é equivalente a z=--a; 1.11 Comentários Os comentários são textos que podem ser inseridos no programa com o objetivo de documentá-lo e não são analisados pelo compilador. Os comentários de uma linha são precedidos do símbolo //, enquanto o comentário de várias linhas é envolvido por /* e */, conforme pode ser observado nos exemplos a seguir. // Este é um comentário de uma linha. /* Este é um comentário com mais de uma linha. */ 15 ALGORITMOS E PROGRAMAÇÃO II 1.12 Funções de entrada e saída de dados As funções de entrada e saída de dados garantem a comunicação do programa com o usuário e/ou outros dispositivos. Nesta seção serão abordadas apenas algumas funções de entrada e saída de dados necessárias para prover a comunicação do usuário com o programa, considerando o teclado como periférico de entrada e a tela como periférico de saída. As funções de saída de dados são utilizadas para exibir dados na tela, seja uma mensagem, o resultado de uma expressão ou o conteúdo armazenado em uma variável. A função de saída mais utilizada em C para este fim é a printf, cuja sintaxe é apresentada a seguir. printf(<string de controle>,<lista de argumentos>); A string de controle possui uma descrição de tudo que a função vai exibir na tela, incluindo não apenas a mensagem, mas também o formato de variáveis e/ou resultado de expressões e suas respectivas posições nesta mensagem. Isto é feito através do uso dos códigos de formatação vistos na Tabela 1.2. Para cada código de formatação incluído na mensagem é necessário ter um argumento na lista de argumentos, conforme ilustram os exemplos do Quadro 1.1. Quadro 1.1 − Exemplos da sintaxe da função printf Variáveis Exemplos de função de saída float media; char nome[60]; 01 printf("%.1f",media); 02 printf("Digite o nome do aluno: "); 03 printf("Média final = %.1f",media); 04 printf("%s obteve média %.1f",nome,media); No exemplo 01 do Quadro 1.1, a função printf possui a string de controle onde aparece o código de formatação %.1f e a variável media como argumento. Neste caso, o comando de saída exibirá apenas o valor armazenado na variável media, formatado através do código de formato %.1f. O código de formato %f indica que será exibido um valor do tipo float, e o modificador .1 define que este valor será exibido com uma casa decimal. Se a variável media estiver armazenando 8, por exemplo, o valor será exibido como 8.0. No segundo exemplo, o comando de saída contém apenas um literal na string de controle, que será reproduzido no dispositivo de saída. 16 ALGORITMOS E PROGRAMAÇÃO II No exemplo 03, a string de controle contém um literal e um código de formatação ("Média final = %.1f") e a lista de argumentos possui uma variável (media), resultando em Média final = 9.3 (considerando que a variável media esteja armazenando 9.333). O valor armazenado na variável media é exibido na posição em que aparece o código de formato %.1f, considerando apenas a primeira casa decimal. Por fim, supondo que a variável nome armazene Joana e a variável media armazene 5.77, a saída do exemplo 04 seria Joana obteve média 5.8 (o valor 5.77 será arredondado para 5.8). Neste caso, a string de controle da função printf contém um literal com dois códigos de formato (%s e %.1f) e, consequentemente, a lista de argumentos possui duas variáveis (nome e media). Estas variáveis devem ser listadas na mesma ordem em que seus respectivos códigos de formato aparecem na string de controle. As funções de entrada de dados são utilizadas para receber dados digitados pelo usuário. Os dados recebidos são armazenados em variáveis já declaradas no programa. As funções de entrada mais utilizadas em C são scanf, getch, getche e fgets. Em geral, a função scanf é utilizada para ler dados numéricos, as funções getch e getche para ler um único caractere por vez e a função fgets para ler cadeias de caracteres (strings). A sintaxe destas funções é apresentada a seguir. scanf(<string de controle>,<lista de argumentos>); <variável> = getch(); <variável> = getche(); fgets(<variável>,<tamanho máximo da variável>,stdin); Na função scanf, a string de controle irá indicar o formato dos dados a serem armazenados nas variáveis contidas na lista de argumentos. Isto é feito através do uso dos códigos de formatação vistos na Tabela 1.2. Para cada código de formatação incluído na string de controle é necessário ter uma variável na lista de argumentos, precedida do símbolo &, conforme ilustram os exemplos do Quadro 1.2. O símbolo &, chamado operador de endereço, associa a variável a um endereço de memória. Quadro 1.2 − Exemplos da sintaxe da função scanf Variáveis Exemplos de função de entrada float peso; int idade; 01 scanf("%f",&peso); 02 scanf("%i",&idade); 17 ALGORITMOS E PROGRAMAÇÃO II No exemplo 01 do Quadro 1.2, a função scanf possui a string de controle onde aparece o código de formatação %f e o endereço da variável peso como argumento. Neste caso, o comando de entrada fará a leitura do valor digitado pelo usuário e armazenará na variável peso. O código de formato %f indica que será armazenado um valor do tipo float. O segundo exemplo faz a leitura da variável idade, que é do tipo int. As funções getch e getche retornam um caractere. Nos exemplos apresentados no Quadro 1.3, a variável letra receberá o caractere digitado pelo usuário. A diferença entre os exemplos é que a função getche, além de capturar o caractere digitado, o escreve na tela. Em ambos os casos, o usuário não terá que teclar <ENTER> depois de digitar o caractere. Quadro 1.3 − Exemplos da sintaxe das funções getch e getche Variáveis Exemplos de função de entrada char letra; 01 letra=getch(); 02 letra=getche(); A função fgets é usada para ler uma cadeia de caracteres, ou seja, uma string. Ela possui três argumentos: o primeiro argumento é a variável que irá armazenar a string digitada pelo usuário; o segundo indica o tamanho máximo da string; e o terceiro, neste caso o stdin, indica que a entrada de dados será realizada via teclado (std = standard + in = input, ou seja, entrada padrão). Os exemplos apresentados no Quadro 1.4ilustram o uso da função fgets. Quadro 1.4 − Exemplos da sintaxe da função fgets Variáveis Exemplos de função de entrada char fone[15]; char nome[60]; 01 fflush(stdin); fgets(fone,15,stdin); 02 fflush(stdin); fgets(nome,60,stdin); Como pode ser observado nos exemplos do Quadro 1.4, a função fflush é usada antes da função fgets, com o objetivo de liberar o buffer do teclado. O primeiro exemplo lê a variável fone, que terá no máximo 14 caracteres, enquanto o exemplo 02 lê a variável nome, que terá no máximo 59 caracteres. Ao definir o tamanho máximo de uma string é preciso considerar que o espaço de um dos seus caracteres será reservado para o \0 (caractere nulo), necessário para indicar seu final. Mais detalhes sobre esta 18 ALGORITMOS E PROGRAMAÇÃO II função, bem como outras funções específicas para a manipulação de strings, serão abordados no capítulo 4. As funções printf, scanf e fgets pertencem à biblioteca stdio.h, enquanto as funções getch e getche fazem parte da biblioteca conio.h. 1.13 Funções de tela A Tabela 1.10 apresenta algumas funções de tela, utilizadas para organizar a interface do programa com o usuário. Estas funções fazem parte da biblioteca conio.h. Tabela 1.10 − Funções de tela Sintaxe da função Descrição clrscr() Limpa a tela e posiciona o cursor no canto superior esquerdo. clreol() Limpa a linha. gotoxy(col,lin) Posiciona o cursor na coluna e linha determinadas (a tela padrão possui 80 colunas e 25 linhas). textcolor(cor) Seleciona a cor do texto. textbackground(cor) Seleciona a cor do fundo da tela (para que todo o fundo fique da cor selecionada, deve-se utilizar a função para limpar a tela logo após esta). delline() Exclui a linha em que o cursor está posicionado, movendo todas as linhas que estiverem abaixo desta, uma posição para cima. insline() Insere uma linha na posição em que o cursor está posicionado, movendo todas as linhas que estiverem abaixo desta, uma posição para baixo. A lista de cores básicas, disponíveis para serem utilizadas nas funções textcolor e textbackground é exibida na Tabela 1.11. É possível utilizar tanto o código da cor, quanto seu nome em inglês, como parâmetro das funções. Exemplos: textcolor(4) ou textcolor(RED). Nos dois exemplos, a cor selecionada para o texto é a mesma, o vermelho. 19 ALGORITMOS E PROGRAMAÇÃO II Tabela 1.11 − Lista de cores Código Cor Código Cor Código Cor 0 PRETO 6 MARROM 12 ALARANJADO 1 AZUL 7 CINZA CLARO 13 MAGENTA CLARO 2 VERDE 8 CINZA ESCURO 14 AMARELO 3 CIANO 9 AZUL CLARO 15 BRANCO 4 VERMELHO 10 VERDE CLARO 5 MAGENTA 11 CIANO CLARO 1.14 Exemplo do uso das funções de entrada e saída e de tela A Figura 1.1 apresenta um programa que lê duas notas fornecidas pelo usuário, calcula e escreve a média entre elas. Neste exemplo, é possível observar o uso de vários dos conceitos e funções estudados neste capítulo. Figura 1.1 − Exemplo do uso das funções de tela, entrada e saída 20 ALGORITMOS E PROGRAMAÇÃO II Na linha 2, um comentário foi usado para descrever o problema que o programa resolve. Em seguida, nas linhas 4 e 5, são listadas as bibliotecas necessárias para executar as funções utilizadas na solução do problema. A função principal (main) aparece entre as linhas 7 e 23. No início da função tem-se a declaração de variáveis de escopo local (todas do tipo float), seguida das funções que selecionam a cor do texto e do fundo de tela, e do comando de limpar a tela. A função gotoxy é utilizada várias vezes, antes das funções de saída, para posicionar as mensagens em determinadas posições da tela. No final do programa, usa-se o getch para que, ao executar, o programa mantenha a tela de exibição dos resultados até que o usuário digite qualquer tecla para retornar à tela de edição do compilador. Referências Bibliográficas DEITEL, Paul; DEITEL, Harvey. C: como programar. 6.ed. São Paulo: Pearson Prentice Hall, 2011. FORBELLONE, André Luiz Villar; EBERSPÄCHER, Henri Frederico. Lógica de Programação: a construção de algoritmos e estruturas de dados. 3.ed. São Paulo: Prentice Hall, 2005. ISAIA FILHO, Eduardo; LINDEMANN, Vanessa. Algoritmos e Programação I. Canoas: Ed. ULBRA, 2013. Atividades Parte I - Questões objetivas (1) A sintaxe da declaração de uma variável em C inclui o nome da variável seguido de um tipo. (a) Certo (b) Errado (2) São nomes válidos para variáveis na linguagem C: (a) if, a*b_2, H789, &ya (b) A, b, Y, count (c) 9xy, a36, x*y, --j (d) 2_ou_1, \fim, h, j (e) i, j, int, obs 21 ALGORITMOS E PROGRAMAÇÃO II (3) Em C, os nomes cont e Cont não podem ser empregados para representar a mesma variável ao longo de um programa. (a) Certo (b) Errado (4) Uma string é uma sequência de caracteres armazenada em um vetor de caracteres. (a) Certo (b) Errado (5) O que faz o seguinte programa em C ? #include <stdio.h> main( ){ int i=2; printf("Valor de i = %i\n",i); } (a) Imprime: Valor de i = 2 e pula para a próxima linha. (b) Imprime: Valor de i = 2\n. (c) Pula para a próxima linha e imprime: Valor de i = 2. (d) Imprime: Valor de i = 2. (e) Nenhuma das alternativas anteriores. (6) Qual o resultado das variáveis j, k e l depois da seguinte sequência de operações? int j,k,l; j=k=10; l=++j; j=-j; k++; j=j+k-l--; (a) j = -10, k = 10, l = 10 (b) j = -11, k = 11, l = 10 (c) j = -10, k = 11, l = 10 (d) j = 11, k= 11, l = 11 (e) Nenhuma das alternativas anteriores (7) Na Linguagem C, os códigos de formatação de tipo de dados NÃO estão corretamente associados na alternativa: (a) int - %i (b) double - %d (c) float - %f 22 ALGORITMOS E PROGRAMAÇÃO II (d) char - %c (e) Nenhuma das respostas anteriores. Respostas dos exercícios da Parte I 1 - b; 2 - b; 3 - a; 4 - a; 5 - a; 6 - b; 7 - b. Parte II - Resolução de problemas Resolva os problemas descritos a seguir, utilizando a Linguagem C. (1) O custo final de um carro novo para o consumidor é a soma do custo de fábrica, dos impostos e da porcentagem do distribuidor. Supondo que os impostos totalizam 45% sobre o custo de fábrica e a porcentagem do distribuidor seja de 20% sobre o valor total, escreva um programa que leia o custo de fábrica de um carro, calcule e escreva o custo final ao consumidor. (2) Sabe-se que para iluminar de maneira correta os cômodos de uma casa, para cada m2, deve-se usar 18W de potência. Faça um programa que receba as duas dimensões de um cômodo (em metros), calcule e apresente a sua área (em m2) e a potência de iluminação que deverá ser utilizada. (3) Uma empresa que promove espetáculos teatrais precisa de um programa para definir o valor mínimo para o convite, considerando o custo total do espetáculo e o número de lugares disponíveis para o público no local da apresentação. (4) Sabe-se que: 1 pé = 12 polegadas; 1 jarda = 3 pés; 1 milha = 1760 jardas. Faça um programa que receba uma medida em pés, faça as conversões conforme a descrição acima e mostre os resultados em polegadas, jardas e milhas. (5) Considerando uma aplicação de P reais à taxa de juros i constante por um período de N meses, calcule e escreva qual será o montante M após o término da aplicação, sendo M = P * (1 + i) N. 23 ALGORITMOS E PROGRAMAÇÃO II 2 Estruturas Básicas de Controle Vanessa Lindemann* Ao criar um programa, tem-se como objetivo a solução de um determinado problema.Para que este problema seja resolvido, as instruções primitivas devem estar organizadas de forma a representar um conjunto de ações, que seguirá um fluxo de execução determinado por três estruturas básicas de controle: sequencial, condicional e repetitiva - temas abordados nas próximas seções. 2.1 Estrutura sequencial A estrutura sequencial contém um conjunto de instruções que serão executadas de forma linear, de cima para baixo, da esquerda para a direita, sem nenhum desvio entre os símbolos de início e fim do programa. Figura 2.1 − Exemplo da estrutura de controle sequencial * Doutora em Informática na Educação pela UFRGS (2008); professora dos cursos da Computação da ULBRA. 24 ALGORITMOS E PROGRAMAÇÃO II A Figura 2.1 apresenta um programa que calcula o salário de um funcionário, cuja estrutura é sequencial. O programa inicia com um comentário, que descreve o problema a ser resolvido, seguido da lista de bibliotecas necessárias. A função principal (main) vai da linha 6 à 27, onde são declaradas as variáveis (linhas 7, 8 e 9), ocorre a entrada de dados (entre as linhas 12 e 17), o processamento (linhas 18, 19 e 20) e a saída de dados (entre as linhas 22 e 25). Estas instruções são executadas sequencialmente, do início ao final do programa, sem nenhum desvio. 2.2 Estrutura condicional A estrutura condicional é utilizada para desviar o fluxo de execução do algoritmo para diferentes partes da solução. Também chamada de estrutura de seleção, ela divide-se em estrutura SE e estrutura ESCOLHA. A estrutura SE é mais flexível, podendo utilizar na sua condição todos os operadores relacionais (<, >, <=, >=, =, <>) e, quando forem necessárias, mais de uma condição com os operadores lógicos (E e OU) entre elas. Esta estrutura também é classificada como estrutura condicional SE simples, composta ou encadeada. A sintaxe da estrutura condicional SE simples, em linguagem C, é apresentada a seguir. if(<condição ou lista de condições>) <instrução ou bloco de instruções> A condição é avaliada e, se retornar zero, que nesta situação em C significa falso, a instrução não será executada. Quando resultar qualquer valor diferente de zero, que em C nesta situação é considerado verdadeiro, a instrução será executada. Esta estrutura pode conter mais de uma condição com operadores lógicos entre elas e, também, pode conter um bloco de instruções a ser executado, ao invés de uma instrução única. Vale lembrar que um bloco é composto por duas ou mais instruções, delimitado por início e fim (em C, representados pelos símbolos { e }). O Quadro 2.1 apresenta três exemplos da estrutura condicional SE simples em linguagem C. Quadro 2.1 − Exemplos da sintaxe da estrutura condicional SE simples em C Com instrução única Com bloco de instruções Mais de uma condição e bloco if(a>b) printf("%i",a); if(a>b){ a=a-b; printf("%i",a); } if(a>b && a!=0 && b!=0){ a=a/b; printf("%i",a); } 25 ALGORITMOS E PROGRAMAÇÃO II A sintaxe da estrutura condicional SE composta, em linguagem C, pode ser observada a seguir. if(<condição ou lista de condições>) <instrução ou bloco de instruções> else <instrução ou bloco de instruções> Quando a condição avaliada resultar qualquer valor diferente de zero, a instrução da cláusula if será executada; caso contrário, quando resultar zero, é a instrução da cláusula else que será executada. O Quadro 2.2 exemplifica a utilização da estrutura condicional SE composta em linguagem C. O programa apresentado lê um valor inteiro e verifica se ele é par ou ímpar. Na coluna da esquerda a solução aparece em português estruturado, enquanto a coluna da direita apresenta a mesma solução em linguagem C. Quadro 2.2 − Exemplo da estrutura de controle condicional SE Problema: ler um valor do tipo inteiro e verificar se ele é par ou ímpar. Português estruturado – SE Linguagem C - if algoritmo exemplo variáveis valor: inteiro início escrever("Digite um valor: ") ler(valor) se(valor mod 2 = 0)então escrever(valor," é par.") senão escrever(valor," é ímpar.") fim #include <stdio.h> #include <conio.h> main() { int valor; clrscr(); gotoxy(10,10); printf("Digite um valor: "); scanf("%i",&valor); gotoxy(10,14); if(valor%2==0) printf("%i é par.", valor); else printf("%i é ímpar.", valor); getch(); } 26 ALGORITMOS E PROGRAMAÇÃO II Outro exemplo do uso da estrutura condicional SE composta pode ser observado na Figura 2.2, onde o programa lê duas notas, calcula a média do aluno e emite uma mensagem de aprovado ou reprovado. Figura 2.2 − Exemplo da estrutura de controle condicional SE composta, em linguagem C A aplicação da estrutura condicional SE encadeada, cuja sintaxe em linguagem C é apresentada a seguir, pode ser observada na Figura 2.3 que verifica se um valor digitado pelo usuário é positivo, negativo ou nulo. if(<condição ou lista de condições>) <instrução ou bloco de instruções> else if(<condição ou lista de condições>) <instrução ou bloco de instruções> else <instrução ou bloco de instruções> 27 ALGORITMOS E PROGRAMAÇÃO II Figura 2.3 − Exemplo da estrutura de controle condicional SE encadeada, em linguagem C Em situações de igualdade para uma mesma variável, em que é necessário comparar a variável com vários valores, utiliza-se a estrutura condicional SE encandeada (por exemplo, comparar uma variável op com as quatro operações básicas + - * e /). Neste caso, tem-se uma seleção de múltipla escolha. O uso da estrutura condicional ESCOLHA, apresentado a seguir, pode simplificar bastante a "cascata" de estruturas SE necessária nestas situações. A estrutura ESCOLHA pode ser utilizada nestes casos desde que a variável avaliada seja do tipo inteiro ou caractere. A sintaxe da estrutura condicional ESCOLHA, em linguagem C, é apresentada a seguir. switch(<variável>){ case <1>: <instruções> break; case <2>: <instruções> break; case <n>: <instruções> break; default: <instruções> } Se a variável avaliada tiver um dos valores listados nas opções, as instruções correspondentes ao respectivo case serão executadas. Quando a variável for diferente de todas as opções listadas, a instrução (ou bloco de 28 ALGORITMOS E PROGRAMAÇÃO II instruções) da cláusula default será executada. A cláusula default é opcional nesta estrutura. No final de cada case aparece o break, usado para encerrar a execução da estrutura condicional. Para demonstrar a aplicação da estrutura condicional ESCOLHA em linguagem C, o Quadro 2.3 apresenta um exemplo que executa as operações básicas de uma calculadora. Na coluna da esquerda a solução aparece em português estruturado e na da direita em linguagem C. Quadro 2.3 − Exemplo da estrutura de controle condicional ESCOLHA, em linguagem C Problema: construir uma calculadora que contenha as operações: +, - , * e /. Português estruturado - ESCOLHA Linguagem C - switch algoritmo exemplo variáveis valor1,valor2,r: real operador: caractere início escrever("Digite o 1º valor: ") ler(valor1) escrever("Digite o operador: ") ler(operador) escrever("Digite o 2º valor: ") ler(valor2) escolha(operador) caso "+": r ß valor1+valor2 caso "-": r ß valor1-valor2 caso "*": r ß valor1*valor2 caso "/": se(valor2<>0)então r ß valor1/valor2 senão r ß 0 senão inícioescrever("Operador inválido") r ß 0 fim fim escrever ("Resultado = ", r) fim #include <stdio.h> #include <conio.h> main(){ float valor1,valor2, r; char operador; clrscr(); gotoxy(10,5); printf("Digite o primeiro valor:"); scanf("%f",&valor1); gotoxy(10,8); printf("Digite o operador: "); gotoxy(29,8); operador=getche(); gotoxy(10,11); printf("Digite o segundo valor: "); scanf("%f",&valor2); switch(operador){ case'+': r=valor1+valor2; break; case'-': r=valor1-valor2; break; case'*': r=valor1*valor2; break; case'/': if(valor2!=0) r = valor1 / valor2; else r = 0; break; default: gotoxy(10,15); printf("Operador inválido!"); r=0; } gotoxy(10,18); printf("Resultado = %3.2f", r); getch(); } 29 ALGORITMOS E PROGRAMAÇÃO II Outro exemplo do uso da estrutura condicional ESCOLHA pode ser observado na Figura 2.4. Neste exemplo, o usuário digita o código de um produto e a quantidade adquiria e o programa calcula o total a pagar. Figura 2.4 − Exemplo da estrutura de controle condicional ESCOLHA, em linguagem C 2.3 Estrutura de repetição Enquanto as estruturas condicionais, estudadas na seção anterior, têm como objetivo escolher entre diferentes fluxos de execução a partir da avaliação de uma expressão, as estruturas de repetição possibilitam que uma ou mais instruções sejam executadas mais de uma vez no programa. As estruturas de controle de repetição dividem-se em ENQUANTO, REPITA/ATÉ e PARA. Elas diferenciam-se em relação ao momento em que a condição de interrupção será avaliada, que pode ser antes ou depois da primeira iteração. 30 ALGORITMOS E PROGRAMAÇÃO II A estrutura de controle de repetição ENQUANTO permite executar uma ou mais instruções repetidamente enquanto sua condição de interrupção resultar verdadeiro. A sintaxe da estrutura de repetição ENQUANTO, em linguagem C, é apresentada a seguir. while(<condição>) <instrução ou bloco de instruções> Como pode ser observado, a condição de interrupção é verificada antes da execução da instrução ou bloco de instruções a ser repetido. Se o resultado desta condição for diferente de zero (que, em linguagem C, significa verdadeiro), a instrução ou bloco de instruções é executado e, logo após esta iteração, o fluxo de execução retorna para o início da estrutura while e a condição de interrupção é avaliada novamente. Este processo é repetido até que a condição avaliada resulte zero (ou seja, falso em linguagem C). Neste caso, o fluxo de execução do programa continuará a partir da instrução imediatamente após à estrutura while. Vale destacar que, como a condição de interrupção é avaliada no início da estrutura de controle, quando esta resultar zero na primeira vez em que for verificada, a instrução ou bloco de instruções da estrutura não será executado nenhuma vez. Ao contrário da estrutura ENQUANTO, a condição de interrupção da estrutura REPITA/ATÉ é verificada no final de cada iteração. Em linguagem C, a sintaxe da estrutura de repetição equivalente à estrutura REPITA/ATÉ, considerando o fato de que a condição de interrupção é avaliada no final de cada iteração, é apresentada a seguir. do{ <instrução ou bloco de instruções> } while(<condição>) Uma ou mais instruções serão executadas repetidamente enquanto a condição de interrupção da estrutura resultar verdadeiro (em linguagem C, verdadeiro significa qualquer valor diferente de zero). Como a condição só é avaliada no final de cada iteração, a instrução ou bloco de instruções a ser repetido será executado pelo menos uma vez, independente do valor inicial da condição de interrupção. Depois de cada iteração, se o resultado da condição for verdadeiro, o fluxo de execução retorna para o início da estrutura. Este processo é repetido enquanto a condição de interrupção resultar verdadeiro. A estrutura de repetição PARA, diferente das anteriores, é controlada por uma variável de controle, como pode ser observado na sintaxe apresentada a seguir, em linguagem C. 31 ALGORITMOS E PROGRAMAÇÃO II for(v=vi;v<vf;v++) <instrução ou bloco de instruções> Onde: v representa a variável de controle; vi indica o valor inicial da variável de controle; vf indica o valor final da variável de controle; e v++ indica que a variável será incrementada em um a cada iteração. As estruturas de controle de repetição são exemplificadas nos quadros a seguir. Para facilitar o entendimento, a coluna da esquerda dos Quadros 2.4, 2.5 e 2.6 apresenta a solução em português estruturado e a da direita em linguagem C. Quadro 2.4 − Exemplo da estrutura de controle de repetição ENQUANTO Problema: ler 10 valores do tipo inteiro, calcular e escrever a média destes valores. Português estruturado – ENQUANTO Linguagem C – while algoritmo exemplo variáveis valor, soma, cont: inteiro media: real início cont ß 0 soma ß 0 enquanto(cont<10)faça início escrever("Digite um valor:") ler(valor) cont ß cont + 1 soma ß soma + valor fim media ß soma / 10 escrever("Média = ", media) fim #include <stdio.h> #include <conio.h> main() { int valor, soma, cont; float media; cont = 0; soma = 0; while(cont<10) { clrscr(); gotoxy(10,10); printf("Digite um valor: "); scanf("%i",&valor); cont = cont + 1; soma = soma + valor; } media = soma / 10; gotoxy(10,14); printf("Media = %.2f", media); getch(); } 32 ALGORITMOS E PROGRAMAÇÃO II Quadro 2.5 − Exemplo da estrutura de controle de repetição REPITA Problema: ler 25 valores, calcular e escrever o percentual de valores negativos. Português estruturado – REPITA Linguagem C – do while algoritmo exemplo variáveis cont: inteiro valor, negativo, perc: real início cont ß 0 negativo ß 0 repita escrever("Digite um valor: ") ler(valor) cont ß cont + 1 se (valor < 0) então negativo ß negativo + 1 até(cont=25) perc ß (negativo*100)/25 escrever("% negativos= ",perc) fim #include <stdio.h> #include <conio.h> main() { int cont; float valor, negativo, perc; cont = 0; negativo = 0; do{ clrscr(); gotoxy(10,10); printf("Digite um valor: "); scanf("%f",&valor); cont = cont + 1; if(valor < 0) negativo = negativo + 1; } while(cont<25); perc = (negativo*100)/25; gotoxy(10,14); printf("%% negativos= %.2f", perc); getch(); } O exemplo utilizando a estrutura for, do Quadro 2.6, apresenta a solução de um problema em que o número de repetições é conhecido previamente. Nestes casos, na estrutura for(cont=1;cont<=10; cont++), a primeira instrução inicializa a variável de controle (cont=1), a segunda verifica a condição de interrupção avaliando a mesma variável (cont<=10) e a terceira incrementa a variável de controle em um a cada iteração (cont++). É importante destacar que a primeira instrução, usada para inicializar a variável de controle, é executada uma única vez, no início da execução da estrutura. 33 ALGORITMOS E PROGRAMAÇÃO II Quadro 2.6 − Exemplo da estrutura de controle de repetição PARA Problema: ler um valor inteiro, entre 1 e 10, e escrever a sua tabuada. Português estruturado – PARA LinguagemC – for algoritmo exemplo variáveis valor, cont: inteiro início escrever("Digite um valor: ") ler(valor) se(valor>=1)e(valor<=10) para cont de 1 até 10 faça escrever(cont*valor) senão escrever("Valor inválido.") fim #include <stdio.h> #include <conio.h> main() { int valor, cont; clrscr(); gotoxy(10,5); printf("Digite um valor: "); scanf("%i",&valor); if(valor>=1 && valor<=10) for(cont=1;cont<=10;cont++){ gotoxy(10,cont+7); printf(" %i",cont*valor); } else{ gotoxy(10,7); printf("Valor inválido."); } getch(); } Em português estruturado, a estrutura PARA só pode ser utilizada para resolver problemas em que o número de repetições é previamente conhecido, como no exemplo anterior. Em linguagem C, entretanto, a estrutura for é mais flexível, podendo utilizada em outras situações como exemplificado nas Figuras 2.5 e 2.6. O exemplo apresentado na Figura 2.5 lê vários valores e calcula a média dos mesmos. A entrada de dados é encerrada quando o usuário digitar zero. Na linha 14 do programa apresentado na Figura 2.5, a estrutura for(cont=1;valor!=0;cont++) inicializa a variável cont, que é usada para contar a quantidade de valores digitados pelo usuário; na segunda instrução da estrutura, que verifica a condição de interrupção, é a variável valor que é avaliada; e, por fim, a variável cont é incrementada em um a cada iteração. Diferente do exemplo anterior, nesta situação a estrutura for manipula duas variáveis: cont e valor. 34 ALGORITMOS E PROGRAMAÇÃO II Figura 2.5 − Exemplo da estrutura PARA, em linguagem C No exemplo apresentado na Figura 2.6, o enunciado do problema não define quantos valores serão lidos, nem indica a condição de interrupção. Nesta situação, é necessário perguntar ao usuário, ao final de cada iteração, se ele deseja continuar a execução do programa − por isso, foi criada a variável resp para armazenar a resposta do usuário. A estrutura for(cont=1;resp!='N'||resp!='n';cont++), linha 11, inicializa a variável cont, que é usada para contar a quantidade de valores digitados pelo usuário; na segunda instrução, que verifica a condição de interrupção, é a variável resp que é avaliada; e, por fim, a variável cont é incrementada em um a cada iteração. 35 ALGORITMOS E PROGRAMAÇÃO II Figura 2.6 − Exemplo da estrutura PARA, em linguagem C Além dos exemplo apresentados até aqui, a linguagem C permite muitas outras possibilidades para a estrutura for, como demonstram os exemplos do Quadro 2.7. 36 ALGORITMOS E PROGRAMAÇÃO II Quadro 2.7 − Exemplos da flexibilidade da estrutura for Flexibilidade Exemplo de aplicação Qualquer uma das três partes da estrutura for pode conter uma ou mais instruções, separadas por vírgula. //Escreve nos. de 0 a 98 em incremento de 2. main() { int x,y; for(x=0,y=0;x+y<100;x=x+1,y=y+1) printf("%i ",x+y); } É possível utilizar caracteres para definir valores iniciais e seus limites, ao invés de inteiros. /* Imprime as letras minúsculas do alfabeto e seus respectivos códigos decimais da tabela ASCII. */ main() { char ch; for(ch='a';ch<'z';ch++) printf("Valor ASCII de %c é %d.\n",ch,ch); } É possível fazer chamada a funções em qualquer uma das partes da estrutura. /* Lê caracteres, um a um até que seja digitado X, e imprime o caractere seguinte a partir do código ASCII. */ main() { char ch; for(ch=getch();ch!='X';ch=getch()) printf("%c ",ch+1); } Qualquer uma das três partes da estrutura pode ser omitida, embora os pontos- e-vírgulas permaneçam. Se a parte de inicialização ou a de incremento forem omiti- das, elas serão desconside- radas. Quando a segunda parte é omitida, a condição de teste é considerada sempre verdadeira. /* Lê caracteres, um a um até que seja digitado X, e imprime o caractere seguinte a partir do código ASCII. */ main() { char ch; for( ; (ch=getch())!='X'; ) printf("%c ",ch+1); } /* Entra em laço infinito */ main() { for( ; ; ) printf("Laço infinito./n"); } 37 ALGORITMOS E PROGRAMAÇÃO II Referências Bibliográficas DEITEL, Paul; DEITEL, Harvey. C: como programar. 6.ed. São Paulo: Pearson Prentice Hall, 2011. FORBELLONE, André Luiz Villar; EBERSPÄCHER, Henri Frederico. Lógica de Programação: a construção de algoritmos e estruturas de dados. 3.ed. São Paulo: Prentice Hall, 2005. ISAIA FILHO, Eduardo; LINDEMANN, Vanessa. Algoritmos e Programação I. Canoas: Ed. ULBRA, 2013. Atividades Parte I - Questões objetivas (1) Na programação estruturada, são necessárias apenas três estruturas de controle para implementar algoritmos. São elas: (a) seleção, repetição e aninhamento. (b) empilhamento, aninhamento e operação. (c) sequência, aninhamento e seleção. (d) sequência, seleção e repetição. (e) função, operação e programa. (2) if(var) é equivalente a if(var!=0). (a) Certo (b) Errado (3) Para que faixa de valores da variável x o seguinte segmento de código imprime a letra C? if(x<=200) if(x<=100) if(x<0) printf("A") else printf("B") else printf("C") else printf("D") (a) 0<x<100 (b) x<=100 (c) 100<x<=200 38 ALGORITMOS E PROGRAMAÇÃO II (d) x>200 (e) 100<=x<=200 (4) Tendo em vista a sintaxe da linguagem de programação C, e supondo que todas as variáveis da expressão while(9<=H && P!=0 || F%2==0) sejam do tipo inteiro, o laço de repetição NÃO será executado se: (a) H < 9 e P ≠ 0 e F for par. (b) H = 9 e P = 0 e F for impar. (c) H ≥ 9 e P ≠ 0 e F ≠ 0. (d) H > 9 e P = 0 e F = 0. (e) Nenhuma das respostas anteriores. (5) Considerando que x e y são números inteiros positivos, assinale a alternativa que descreve a tarefa executada pelo programa em C descrito a seguir. #include<stdio.h> main(){ int x,y,z,w; printf("Digite os valores de x e y: "); scanf("%d %d",&x,&y); z=1; while(z*y<=x) z=z+1; z=z-1; w=x-z*y; printf("%d %d \n",z,w); } (a) Exibe, respectivamente, o valor correspondente às variáveis x e y. (b) Exibe, respectivamente, o quociente e o resto da variável x pela variável y. (c) Exibe, respectivamente, os dois primeiros números primos menores que x e y. (d) Exibe, respectivamente, o resto e o quociente da variável x pela variável y. (e) Exibe, respectivamente, o valor correspondente às variáveis x e y. 39 ALGORITMOS E PROGRAMAÇÃO II (6) Quanto vale k no final da execução do seguinte trecho de código? k=0; for(i=1; i<=n; i++) for(j=i; j<=n; j++) k=k+1; (a) n3 (b) (n2–n)/2 (c) n (d) n(n+1)/2 (e) n-1 Respostas dos exercícios da Parte I 1 - d; 2 - a; 3 - c; 4 - b; 5 - b; 6 - d. Parte II - Resolução de problemas Resolva os problemas descritos a seguir, utilizando a Linguagem C. (1) Escreva um programa que leia 20 valores, encontre e escreva o maior entre eles. (2) Construa um programa que leia um valor inteiro e positivo, calcule e escreva o seu fatorial. Exemplos: 4! = 1 x 2 x 3 x 4 = 24 5! = 1 x 2 x 3 x 4 x 5 = 120 Por definição, 0! = 1 (3) Em uma eleição presidencial existem 4 candidatos. Os votos são informados através de códigos, que obedecem a seguinte regra: 1, 2, 3, 4 = voto para os respectivos candidatos; 5 = voto nulo; 6 = voto branco. Elaboreum programa que leia o voto de cada um dos eleitores, calcule e escreva: total de votos para cada candidato; total de votos nulos; total de votos em branco. Como finalizador do conjunto de dados tem- se o valor 0 (zero). (4) Elabore um programa que repita a leitura de uma data até que ela seja válida. Para cada data incorreta escrever a mensagem "DATA INVÁLIDA". Quando a data for informada corretamente deve ser impressa a mensagem "DATA VÁLIDA" e o programa deve ser encerrado. Para resolver este problema, use três variáveis para representar a data: dia, mês e ano; não esqueça de considerar ano bissexto, quando o mês de fevereiro tem 29 dias. 40 ALGORITMOS E PROGRAMAÇÃO II (5) Durante uma pesquisa realizada entre os habitantes de uma região, foram coletados os seguintes dados: idade, gênero e salário. Faça um programa que calcule e informe: a média salarial do grupo; a maior idade do grupo; a quantidade de mulheres com salário superior a R$ 5.000,00. 41 ALGORITMOS E PROGRAMAÇÃO II 3 Variáveis Indexadas Unidimensionais Vanessa Lindemann* Uma variável simples representa um espaço da memória do computador onde é possível armazenar um único valor por vez. Os dados armazenados podem ser do tipo inteiro, real, caractere ou cadeia de caracteres. Estes conceitos, aliados às instruções primitivas de entrada e saída de dados e às estruturas de controle de fluxo sequencial, condicionais e repetitivas, estudados nos capítulos anteriores, permitem resolver diversos problemas como visto até aqui. O uso de variáveis simples, entretanto, gera algumas limitações como a exemplificada a seguir. Quadro 3.1 − Exemplo da limitação do uso de variáveis simples Problema: ordenar três valores do tipo inteiro. Português estruturado Linguagem C algoritmo exemplo variáveis a, b, c: inteiro início escrever("Digite 3 valores: ") ler(a, b, c) escrever("Valores ordenados: ") se(a<b)então se(b<c)então escrever(a,b,c) senão se(a<c) então escrever(a,c,b) senão escrever(c,a,b) senão se(b<c)então se(a<c)então escrever(b,a,c) senão escrever(b,c,a) senão escrever(c,b,a) fim #include <stdio.h> #include <conio.h> main() { int a, b, c; clrscr(); gotoxy(10,5); printf("Digite 3 valores: "); scanf("%i %i %i",&a,&b,&c); gotoxy(10,8); printf("Valores ordenados: "); if(a<b) if(b<c) printf("%i %i %i",a,b,c); else if(a<c) printf("%i %i %i",a,c,b); else printf("%i %i %i",c,a,b); else if(b<c) if(a<c) printf("%i %i %i",b,a,c); else printf("%i %i %i",b,c,a); else printf("%i %i %i",c,b,a); getch(); } * Doutora em Informática na Educação pela UFRGS (2008); professora dos cursos da Computação da ULBRA. 42 ALGORITMOS E PROGRAMAÇÃO II O programa descrito no Quadro 3.1 ordena três valores do tipo inteiro. Neste método de ordenação, utilizando variáveis simples, ordenar n elementos implica em gerar n! resultados diferentes. Logo, é impossível, por exemplo, utilizar o mesmo método para ordenar 10 valores armazenados em variáveis simples − além de ter que utilizar 10 variáveis com nomes diferentes, seriam necessários exibir 10! (3.628.800) resultados. Uma forma de resolver este problema é utilizar uma variável indexada unidimensional, que representa um conjunto de dados ordenado e homogêneo, armazenado de forma contínua na memória, acessível através de um único nome e um índice. Estas variáveis também são conhecidas como matrizes unidimensionais, arranjos unidimensionais ou vetores (nome que será adotado neste livro). 3.1 Estrutura A estrutura de um vetor, cujo tamanho é 10, é ilustrada na Figura 3.1. À esquerda, a representação do vetor em algoritmo, onde os índices variam de 1 a 10; à direita, a representação em linguagem C, em que os índices variam de 0 a 9. Algoritmo Linguagem C notas 1 2 3 4 5 6 7 8 9 10 notas 0 1 2 3 4 5 6 7 8 9 Índices: 1 a 10 Índices: 0 a 9 Figura 3.1 − Exemplos da estrutura de um vetor de tamanho 10 3.2 Declaração Para declarar um vetor é necessário definir o tipo dos dados que serão armazenados nele, o nome (identificador) através do qual ele será manipulado e o tamanho da variável, que indica quantos valores ele poderá armazenar. A sintaxe da declaração de um vetor, em linguagem C, é apresentada a seguir. <tipo> <identificador>[<tamanho>]; Onde: tipo representa um dos tipos básicos; identificador é o nome que será usado para manipular a variável; tamanho indica a quantidade de elementos que a variável irá armazenar. A Tabela 3.1 exemplifica como declarar um vetor para armazenar 10 elementos do tipo real, em português estruturado e o equivalente em Linguagem C. 43 ALGORITMOS E PROGRAMAÇÃO II Tabela 3.1 − Exemplo da declaração de um vetor Português estruturado Linguagem C notas: vetor [1..10] de real float notas[10]; Um vetor pode ser inicializado no momento de sua declaração. Ao executar int vet[5]={0} a variável vet é criada e terá todas as suas posições inicializadas com zero; ao executar int vet[5]={1,2,3,4,5} a variável será inicializada com um valor diferente em cada posição. 3.3 Manipulação Para acessar um elemento de um vetor, além de referenciar o seu nome, é necessário indicar a posição do elemento desejado. A posição do elemento do vetor, denominada índice, deve ser indicada entre colchetes e pode ser uma constante, uma expressão aritmética ou uma variável. Ao isolar um elemento do vetor, é possível realizar instruções primitivas de entrada, de saída e de atribuição. Alguns exemplos da instrução primitiva de atribuição são apresentados na Tabela 3.2 e ilustrados na Figura 3.2. Tabela 3.2 − Exemplo de atribuição a um elemento específico do vetor Português estruturado Linguagem C notas[3] ß 9.5 notas[2] = 9.5; i ß 3 notas[i] ß 9.5 i = 2; notas[i] = 9.5; notas 9.5 0 1 2 3 4 5 6 7 8 9 Figura 3.2 − Variável notas depois da instrução de atribuição, em Linguagem C Tabela 3.3 − Exemplo da entrada de dados em um vetor Português estruturado Linguagem C escrever (“Informe os 10 elementos do vetor: ”) para i de 1 até 10 faça ler(notas[i]) gotoxy(10,5); printf(“Informe os 10 elementos do vetor: “); for(i=0; i<10; i++){ gotoxy(i*5+10,8); scanf(“%f”,¬as[i]); } 44 ALGORITMOS E PROGRAMAÇÃO II A Tabela 3.3 exemplifica a entrada de dados da variável notas, declarada na Tabela 3.1. A Figura 3.3 ilustra o resultado desta variável, supondo que o usuário tenha digitado 9, 8.3, 5.1, 6, 7.9, 5.2, 9, 8, 9.7 e 5, nesta ordem. notas 9 8.3 5.1 6 7.9 5.2 9 8 9.7 5 0 1 2 3 4 5 6 7 8 9 Figura 3.3 − Ilustração da variável notas depois da entrada de dados, em Linguagem C A função gotoxy(coluna,linha) é utilizada para posicionar o cursor em uma determinada posição da tela. Ela é usada antes de instruções primitivas de entrada e saída para organizar os dados na tela. No exemplo de entrada de dados da Tabela 3.3, em linguagem C, a função gotoxy(10,5) posiciona o cursor na coluna 10 e na linha 5, antes da instrução de saída, que irá imprimir na tela a mensagem "Informe os 10 elementos do vetor: ". Esta mensagem será exibida uma única vez, a partir da coluna 10, na linha 5.Neste mesmo exemplo, a função gotoxy(i*5+10,8) aparece novamente, antes da instrução primitiva de entrada de dados. Neste caso, ela é usada para definir o local em que os dados de entrada, digitados pelo usuário, serão exibidos na tela. Como o usuário irá digitar 10 notas, para que todas sejam exibidas na tela uma ao lado da outra, o primeiro parâmetro da função, que representa a coluna, não pode ser uma constante (ou seja, não pode ser um valor fixo). No exemplo, utiliza-se a expressão i*5+10 para definir a coluna em que cada valor digitado pelo usuário será exibido. Considerando que a variável i varia entre 0 e 9, os valores seriam lidos nas colunas: 10, 15, 20, 25, 30, 35, 40, 45, 50 e 55 − sempre na linha 8. Observa-se, portanto, que o valor que multiplica a variável i na expressão define o intervalo entre as colunas (no exemplo, o intervalo entre um valor e outro é de 5), enquanto o valor que é somado à variável i na expressão, define a primeira coluna a ser utilizada (no exemplo, coluna 10). 3.4 Exemplos do uso de vetores Esta seção é dedicada à resolução de alguns problemas, cujas soluções utilizam variáveis indexadas unidimensionais, ou seja, vetores. No primeiro exemplo, a solução é apresentada em português estruturado e, em seguida, o equivalente em linguagem C. Nos demais exemplos, utiliza-se apenas a representação em linguagem C. 45 ALGORITMOS E PROGRAMAÇÃO II þ Exemplo 3.1 Problema: o professor de Algoritmos e Programação precisa de um programa que leia a nota final de 10 alunos, calcule e escreva a média geral da turma. Quadro 3.2 − Solução para o problema do exemplo 3.1 Problema: ler a nota final de 10 alunos, calcular e escrever a média geral da turma. Português estruturado Linguagem C algoritmo exemplo31 variáveis notas: vetor[1..10] de real soma, media: real i: inteiro início soma ß 0 escrever("Digite as 10 notas: ") para i de 1 até 10 faça início ler(notas[i]) soma ß soma + notas[i] fim media ß soma/10 escrever("Média turma =",media) fim #include <stdio.h> #include <conio.h> main() { float notas[10]; float soma, media; int i; soma=0; clrscr(); gotoxy(10,5); printf("Digite as 10 notas: "); for(i=0;i<10;i++) { gotoxy(i*5+10,8); scanf("%f",¬as[i]); soma = soma + notas[i]; } media = soma/10; gotoxy(10,14); printf("Média turma = %.1f",media); getch(); } Na solução apresentada no Quadro 3.2, criou-se um vetor, com capacidade para armazenar 10 valores do tipo real. Para realizar a entrada de dados e, em seguida, somar as notas digitadas pelo usuário, foi utilizada a estrutura de repetição PARA. Por fim, a média da turma foi calculada (dividindo a variável que acumulou todas as notas pela quantidade de notas, neste caso 10) e exibida para o usuário. 46 ALGORITMOS E PROGRAMAÇÃO II þ Exemplo 3.2 Problema: o professor de Algoritmos e Programação precisa de um programa que leia a nota final de 10 alunos, calcule a média geral da turma e, a seguir, informe quantos alunos obtiveram nota superior à média da turma. Figura 3.4 − Solução, em linguagem C, para o problema do exemplo 3.2 Até a linha 18, a solução apresentada na Figura 3.4 é a mesma do exemplo anterior: o programa emite uma mensagem ao usuário solicitando que ele digite 10 notas, estas são lidas e armazenadas em um vetor, acumuladas na variável soma e, em seguida, a média é calculada. Entre as linhas 19 e 21, o programa percorre o vetor novamente, comparando cada elemento com a variável media e, sempre que o valor comparado for maior que a média calculada, incrementa a variável cont em um. Por fim, o 47 ALGORITMOS E PROGRAMAÇÃO II programa exibe a média da turma e a quantidade de alunos com nota superior a ela. Os exemplos 3.1 e 3.2 também podem ser usados para justificar o uso de variáveis indexadas. No primeiro caso, até seria possível resolver o problema sem utilizar um vetor: uma variável simples poderia ser lida dez vezes, acumulando cada valor lido na variável soma para, no final, calcular a média. No exemplo 3.2, entretanto, esta solução não seria possível, já que para verificar a quantidade de alunos com nota superior à média da turma é necessário ter a nota de todos os alunos para comparar com a variável media e, neste caso, o programa só teria a nota do último aluno armazenada. þ Exemplo 3.3 Problema: faça um algoritmo que leia um vetor de 20 posições, com elementos do tipo inteiro. A seguir, troque os elementos de lugar: o 1º com o 20º, o 2º com o 19º, o 3º com o 18º, ... Finalmente, escreva o vetor modificado. A entrada e a saída de dados deste exemplo são ilustradas na Figura 3.5. Vetor v 2 4 9 12 6 98 7 35 11 42 55 1 3 64 13 5 20 8 14 24 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Vetor v modificado 24 14 8 20 5 13 64 3 1 55 42 11 35 7 98 6 12 9 4 2 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Figura 3.5 − Ilustração do resultado do exemplo 3.3 Como pode ser observado na Figura 3.6, este problema foi resolvido em três etapas: a entrada de dados, que ocorre entre as linhas 10 e 14; a troca dos elementos do vetor, realizada pelas instruções entre as linhas 15 e 20; e, por fim, a saída de dados, que apresenta o vetor modificado, executada entre as linhas 23 e 27. 48 ALGORITMOS E PROGRAMAÇÃO II Figura 3.6 − Solução, em linguagem C, para o problema do exemplo 3.3 Para realizar a troca é necessário que todos os dados tenham sido armazenados no vetor, já que o primeiro elemento será trocado com o último, o segundo com o penúltimo e assim sucessivamente. Além disso, deve-se criar uma variável auxiliar. O Quadro 3.3 ilustra a necessidade da variável auxiliar no processo de troca. No exemplo, foram utilizadas duas variáveis simples, A e B. Supondo que A armazena 5 e B 2, se forem executadas as instruções A=B e B=A, o resultado será A e B armazenando 2. Logo, sem a variável auxiliar, as duas variáveis ficariam com o mesmo valor. A solução correta, utilizando a variável auxiliar, é apresentada no Quadro 3.4, onde AUX=A, A=B e B=AUX. 49 ALGORITMOS E PROGRAMAÇÃO II Quadro 3.3 − Troca de conteúdo entre duas variáveis, sem usar variável auxiliar Teste-de-mesa Instruções variáveis A B 5 2 A = B 2 B = A 2 Saída A = 2 B = 2 Não funcionou! Quadro 3.4 − Troca de conteúdo entre duas variáveis, usando uma variável auxiliar Teste-de-mesa Instruções variáveis AUX A B 5 2 AUX = A 5 A = B 2 B = AUX 5 Saída A = 2 B = 5 É importante observar que nas etapas de entrada e saída de dados do exemplo 3.3 o número de iterações é 20, enquanto na etapa de trocas é 10. Isto ocorre porque o vetor possui 20 elementos e, a cada iteração, dois elementos são trocados. As trocas ocorrem entre os elementos v[i] e v[19-i]. Assim, quando i for 0, 19-i será 19, de forma que serão trocados os elementos v[0] com v[19]; quando i for 1, 19-i será 18, então serão trocados os elementos v[1] com v[18]; quando i for 2, 19-i será 17, trocando v[2] com v[17]; esse processo será repetido até a variável i chegar em 9, quando 19-i será 10 e serão trocados os elementos v[9] com v[10]. þ Exemplo 3.4 Problema: escreva um programa que leia um vetor (P) de 20 posições, com elementos do tipo inteiro. A seguir, encontre a posição do menor elemento do vetor, conte e informe quantos dos elementos do vetor são múltiplos deste valor. 50 ALGORITMOS E PROGRAMAÇÃO II A entrada e a saída de dados deste exemplo são
Compartilhar