Exercícios de Equivalência - DAINF



a . l . g . o . r . i . t . m . o . s

Sumário

1. Introdução 4

2. Variáveis 5

2.1. A Memória RAM 5

2.2. Nomeando Variáveis 6

2.3. Sintaxe do Comando de Declaração de Variáveis 6

2.4. Atribuição de Valores a Variáveis 6

2.5. Sintaxe da Atribuição de Valores a Variáveis 7

3. ENTRADA e SAÍDA DE DADOS 8

3.1. Saída de Dados 8

3.2. Entrada de Dados 8

4. Operadores Aritméticos 10

5. Comandos de Seleção 12

5.1. Seleção Simples 12

5.2. Seleção Múltipla 13

6. Comandos de Repetição ou Laço 16

6.1. Enquanto/While 16

6.2. Execute ... Enquanto/Do ... While 19

6.3. Para/for 20

7. Matriz de Variáveis / Array 22

7.1. Declaração de uma Variável Matricial 22

7.2. Aplicação 23

8. Estruturas de Dados Heterogêneas 27

9. Funções 28

9.1. Aplicação: Conversão de temperatura 28

9.2. Criação de funções 31

9.3. Aplicação: Jogo da Velha 33

9.4. Escopo de Variáveis 40

9.5. Funções Recursivas 41

10. Métricas de Qualidade de Programas 42

11. Compilador Borland C++ 3.1 43

11.1. Instruções para Editar/Compilar/Executar um Programa 43

12. Referências Bibliográficas 44

Lista de Exemplos

Exemplo 1: declaração e atribuição de valores a variáveis. 5

Exemplo 2: utilização do comando escreva. 8

Exemplo 3: utilização do comando leia. 8

Exemplo 4: utilização de operadores aritméticos. 10

Exemplo 5: utilização do SE. 12

Exemplo 6: utilização do comando MultiplasOpcoes. 14

Exemplo 7: utilização do comando Enquanto. 16

Exemplo 8: utilização do comando Execute ... Enquanto. 19

Exemplo 9: utilização do comando "para". 20

Exemplo 10: utilização de variáveis matriciais do tipo real. 23

Exemplo 11: utilização de variáveis matriciais do tipo caracter. 23

Exemplo 12: rescrevendo o exercício 4 da seção 6.1. 23

Exemplo 13: rescrevendo o exemplo anterior. 25

Exemplo 14: Celsius para Farenheit e vice-versa. 28

Lista de Figuras

Figura 1: representação da RAM como um vetor de bytes 5

Figura 2: representação da RAM após a atribuição do valor 10 a variável i. 6

Figura 3: representação esquemática de um vetor de inteiros na memória. 22

Figura 4: representação esquemática de um vetor de reais na memória. 22

Figura 5: representação esquemática de um variável matricial bidimensional tipo caracter na memória. 22

Figura 6: Representação esquemática da matriz de preços de produtos. 24

Figura 7: Representação esquemática da matriz de nomes de produtos. 26

Figura 8: Função TransformarParaFarenheit (Caixa Preta) 29

Figura 9: Função TransformarParaCelsius (Caixa Preta) 29

Figura 10: Diagrama de Funções para o problema da conversão de temperaturas. 29

Lista de Tabelas

Tabela 1: tipos de dados x tamanho e domínio 5

Tabela 2: Operadores aritméticos. 10

Tabela 3: Operadores relacionais. 12

Tabela 4: Operadores lógicos. 12

Introdução

Definição: Um algoritmo é um conjunto de passos que pode ser executado mecanicamente em uma quantidade finita de tempo e que resolve algum problema.

Normalmente, algoritmos são especificados através de uma pseudo-linguagem, ou seja, uma linguagem com alguma liberdade de sintaxe e parecida com a linguagem corrente (português). Como desejamos executar nossos algoritmos no computador, adotaremos uma linguagem com sintaxe rígida. Estudaremos os elementos que constituem a linguagem que será utilizada na construção de algoritmos. São eles:

❑ variáveis

❑ comandos de entrada e saída

❑ operadores aritméticos

❑ comandos de seleção

❑ comandos de repetição/laço

❑ matrizes de variáveis

❑ estruturas de dados heterôgeneas

❑ funções

Variáveis

Na programação, assim como na lógica de predicados, uma variável pode assumir qualquer valor do seu conjunto domínio. As linguagens de programação contêm alguns conjuntos domínio predefinidos os quais denominamos de tipos de dados nativos. Exemplificando:

Exemplo 1: declaração e atribuição de valores a variáveis.

1. inteiro i;

2. i = 10;

Linha 1: declaração ou criação de uma variável do tipo inteiro (um tipo nativo da linguagem) chamada i. Portanto, i pode "teoricamente" assumir qualquer valor do domínio Z.

Linha 2: a variável i assume ou recebe o valor 10 (comando de atribuição)

Quando uma variável é declarada uma quantidade de memória lhe é reservada. A quantidade de memória alocada depende do tipo do dado utilizado. Na linguagem que utilizaremos, um inteiro ocupará 2 bytes. Portanto, poderemos representar inteiros no intervalo [-32.768, 32.767]. Num computador, existe limitação para os valores máximo e mínimo de uma variável dependente da quantidade de bytes reservado para o tipo da variável. A tabela seguinte mostra os tipos de dados que faremos uso com os respectivos tamanhos:

|Tipo |tamanho (bytes) |domínio |

|caracter |1 |caracteres (a, b, ..., 1, 2, ..., *, & , $, #, ...) |

|inteiro |2 |subconjunto de Z |

|real |4 |subconjunto de R |

|lógico |1 |V ou F |

Tabela 1: tipos de dados x tamanho e domínio

1 A Memória RAM

A memória RAM armazena os códigos executáveis dos programas e os dados a eles associados (valores das variáveis, constantes e outros necessários ao funcionamento do programa). De forma esquemática podemos representar a memória como um vetor de bytes (fig. 1).

| | |(1 byte ( |

|endereç|0 | |

|o | | |

|físico | | |

| |1 | |

| |2 | |

| |... |... |

| |n | |

Figura 1: representação da RAM como um vetor de bytes

Retomando o Exemplo 1, a grosso modo, pediu-se ao compilador para reservar 2 bytes (o tamanho de um dado do tipo inteiro) na memória e identificar estes 2 bytes pelo nome i. Supondo que o compilador reserve a partir do endereço físico (posição) 3 os 2 bytes necessários para a variável i teríamos a seguinte situação após o comando de atribuição i = 10.

| | |(1 byte ( |

|endereç|0 | |

|o | | |

|físico | | |

| |1 | |

| |2 | |

| |3 |0000 0000 |

| |4 |0000 1010 |

| |... |... |

| |n | |

Figura 2: representação da RAM após a atribuição do valor 10 a variável i.

Assim, cada vez que referenciamos a variável i no algoritmo na verdade estamos fazendo referência ao conteúdo das posições 3 e 4 da memória RAM.

2 Nomeando Variáveis

REGRA 1: Dê nomes significativos. Para identificar, por exemplo, uma variável que receberá a média aritmética de notas de provas utilize o nome media (sem acento) ao invés de z, x ou k.

Padrões para Nomear Variáveis

1) primeira letra identifica o tipo de dado: i, c, r , l (minúscula)

2) demais palavras iniciam por letra maiúscula (alguns programadores preferem separar com "_")

Exemplos:

rMediaFinal, cNomeAluno, iCodigo, r_media_final, c_nome_aluno

3 Sintaxe do Comando de Declaração de Variáveis

::= ;

::= , |

::= |

::= < caracter_não_esp >|< caracter_não_esp >

::=||-|_

::=0|1|...|9

::= a|...| z| A|...|Z

::= inteiro |real | logico |caracter

Exemplos:

real rAux;

logico lSexoMasc;

inteiro iCont, iSeq;

4 Atribuição de Valores a Variáveis

Uma variável pode receber um valor na sua declaração ou em qualquer parte do algoritmo.

Na declaração:

inteiro i = 10;

No algoritmo:

inteiro i;

...

i = 10;

5 Sintaxe da Atribuição de Valores a Variáveis

::= = ;

::= | ;

...

Obs.: não serão detalhadas as categorias sintáticas (expressão aritmética) e (constantes).

ENTRADA e SAÍDA DE DADOS

Normalmente, um algoritmo dependerá de informações externas que deverão de algum modo ser inseridas no computador. Por exemplo, um programa que emite extrato bancário precisa que o usuário forneça o número da agência, a conta corrente e a senha. Estes dados podem ser via cartão magnético ou teclado. Outros meios de entrada de dados num computador são: disquete, disco rígido, scanner e mouse.

Uma vez que os dados de entrada tenha sido processados mostram-se ou gravam-se os resultados num dispositivo de saída: impressora, monitor de vídeo, discos e etc. Os programas de extrato bancário imprimem o saldo da conta-corrente e os lançamentos efetuados.

Nesta seção, são apresentados os comandos que permitem fazer entrada de dados pelo teclado e saída via monitor de vídeo.

1 Saída de Dados

Sintaxe:

::=escreva ""; | escreva ;

::=|

::=||

::=~|!|@|#|...

::=0|1|...|9

::= a|...| z |A|...|Z

Semântica:

Escreve o texto ou o resultado de uma expressão aritmética no monitor de vídeo.

Exemplo 2: utilização do comando escreva.

1. // Programa: saida.cpp linha de comentário

2. // Autor : linha de comentário

3. #include "tradutor.h" traduz comandos de português para c++

4. programa sempre segue o include acima

5. inicio início da parte principal do programa

6. inteiro iNrAluno;

7. escreva "Digite o numero do aluno";

8. fim fim da parte principal do programa.

2 Entrada de Dados

Sintaxe:

::=leia ;

::= já definido em 2.3

Semântica:

Obtêm informação do teclado e coloca o valor digitado na posição de memória identificada pela variável .

Exemplo 3: utilização do comando leia.

1. // Programa: entrada.cpp linha de comentário

9. // Autor : linha de comentário

10. #include "tradutor.h" traduz comandos de português para c++

11. programa sempre segue o include acima

12. inicio início da parte principal do programa

13. inteiro iNrAluno;

14. escreva "Digite o numero do aluno";

15. leia iNrAluno;

16. fim fim da parte principal do programa.

Exercício:

Altere o algoritmo acima para mostrar o valor digitado após a seguinte mensagem:

"Voce digitou o número: "

Obs.: utilize os caracteres \n num texto para fazer o cursor mudar de linha (retorno de carro e mudança de linha).

Operadores Aritméticos

Os operadores mais utilizados são mostrados na tabela seguinte:

|Operador | |

|+ |Adição |

|- |Subtração |

|* |Multiplicação |

|/ |Divisão |

|% |Módulo (Resto da divisão) |

Tabela 2: Operadores aritméticos.

Exemplo 4: utilização de operadores aritméticos.

1. // Programa: media.cpp

17. // Autor :

18. #include "tradutor.h"

19. programa

20. inicio

21. real rNota1, rNota2;

22. escreva "\nDigite a primeira nota:";

23. leia rNota1;

24. escreva "\nDigite a Segunda nota:";

25. leia rNota2;

26. escreva "\nMedia calculada: ";

27. escreva (rNota1 + rNota2) / 2;

28. fim

Exercícios:

1. Faça um algoritmo que transforme uma velocidade fornecida em m/s pelo usuário para Km/h. Para tal, multiplique o valor em m/s por 3,6.

1. #include "tradutor.h"

2. programa

3. inicio

4. real rVelMS;

5. escreva "Digite velocidade em m/s: ";

6. leia rVelMS;

7. escreva "\nVelocidade m KM/H: ";

8. escreva rVelMS * 3.6;

9. fim

2. Faça um algoritmo para calcular a nota semestral de um aluno. A nota semestral é obtida pela média aritmética entre a nota de 2 bimestres. Cada nota de bimestre é composta por 2 notas de provas. Faça um desenho esquemático da memória RAM (vide fig. 1 e 2) com as variáveis que você criou. Mostre, neste desenho, o conteúdo (o valor) de cada variável após a execução do programa.

1. #include "tradutor.h"

29. programa

30. inicio

31. real rNota1, rNota2, rBim1, rBim2;

32. escreva "Bimestre 1\n";

33. escreva "==========\n";

34. escreva "Nota 1: ";

35. leia rNota1;

36. escreva "\nNota 2: ";

37. leia rNota2;

38. rBim1 = (rNota1 + rNota2) / 2;

39. escreva "\nNota primeiro bimestre: ";

40. escreva rBim1;

41. escreva "\n\nBimestre 2\n";

42. escreva "===========\n";

43. escreva "Nota 1: ";

44. leia rNota1;

45. escreva "\nNota 2: ";

46. leia rNota2;

47. rBim2 = (rNota1 + rNota2) / 2;

48. escreva "\nNota segundo bimestre: ";

49. escreva rBim2;

50. escreva "\n\nNota semestral:

51. escreva (rBim1 + rBim2) / 2;

52. fim

Desenho esquemático da memória após a seguinte rodada:

Bimestre 1

==========

Nota 1: 8.5 (8.5 foi digitado pelo usuário)

Nota 2: 7.5 (7.5 foi digitado pelo usuário)

Nota primeiro bimestre: 8 (calculado pelo programa)

Bimestre 2

===========

Nota 1: 8 (8 foi digitado pelo usuário)

Nota 2: 6 (7 foi digitado pelo usuário)

Nota segundo bimestre: 7 (calculado pelo programa)

Nota semestral: 7.57 (calculado pelo programa)

| | |(1 byte ( |

|endereç|0 |8 |

|o | | |

|físico | | |

| | | |

| |1 | |

| |2 | |

| |3 | |

| |4 |6 |

| |5 | |

| |6 | |

| |7 | |

| |8 |8 |

| |9 | |

| |10 | |

| |11 | |

| |12 |7 |

| |13 | |

| |14 | |

| |15 | |

Comandos de Seleção

A linguagem que estamos estudando comporta os seguintes comandos de seleção: Seleção simples (SE ou IF) e o de Seleção Múltipla (CASE).

1 Seleção Simples

O comando de seleção simples (SE) permite que um bloco de comandos seja ou não executado dependendo do resultado de um teste. O teste pode ser uma comparação entre duas variáveis, uma variável e uma constante, uma expressão aritmética e uma constante e etc. Logicamente, para fazermos testes, também chamados de expressões condicionais, precisamos de operadores relacionais e operadores lógicos. A tabela abaixo mostra aqueles que utilizaremos:

|Operador Relacional | |

|> |Maior |

|< |Menor |

|= |Maior ou igual |

|== |Igual |

|!= |Diferente |

Tabela 3: Operadores relacionais.

|Operador Lógico | |

|e |Conjunção |

|ou |Disjunção |

|! |Negação |

Tabela 4: Operadores lógicos.

Sintaxe:

::= |

::= se () entao inicio fim

::=se () entao inicio fim

senao inicio fim

::= /* não será detalhada */

::= |

::= | | | | ...

Note que o comando está separado em duas linhas somente para facilitar a leitura. Normalmente, ele vai seguir uma identação diferente. Observe também que um pode ser qualquer um daqueles que já estudamos, o próprio SE (se aninhados) e outros que veremos adiante.

Semântica:

Quando a expressão condicional é verdadeira, o bloco de comandos que segue a palavra "então" é executada, caso contrário, é executado o bloco que segue a palavra senão.

Exemplo 5: utilização do SE.

1. // Programa: trafego.cpp

2. // Autor :

3. // O programa verifica se dois aviões estão na mesma pista.

4. // Caso estejam, emite mensagem de alerta.

5. //

6. #include "tradutor.h"

7. programa

8. inicio

9. inteiro iNrPista1, iNrPista2;

10. escreva "Informe a pista para o voo 1\n";

11. leia iNrPista2;

12. escreva "Informe a pista para o voo 2\n";

13. leia iNrPista2;

14. se ( iNrPista1 == iNrPista2) entao

15. inicio

16. escreva "ALERTA: possivel colisao\n";

17. fim

18. fim

Exercícios:

1. Altere o exemplo acima para que emita mensagem "Voo 1 e 2 liberados" caso as pistas fornecidas sejam diferentes.

2. Altere o programa media.cpp para apresentar as seguintes mensagens:

"Reprovado" quando a média for menor que 4;

"Exame" quando a média estiver no intervalo [4, 7[

"Aprovado" caso nenhuma das situações anteriores.

3. Faça uma pequena calculadora da seguinte forma. Peça ao usuário um número real, em seguida a operação desejada e, finalmente, o segundo número. Resolva a operação pedida (se existir) e apresente o resultado. Veja abaixo a saída desejada:

Calculadora

===========

Digite o primeiro operando: 10.5 (10.5 foi digitado pelo usuário)

Digite a operação: * (* foi digitado pelo usuário)

Digite o segundo operando: 2 (2 foi digitado pelo usuário)

Resultado: 21 (calculado pelo programa)

4. Elabore o seguinte jogo. Peça dois números inteiros de 0 a 5. Estes dois primeiros números são como se fossem os números sorteados. Depois, peça ao apostador 2 palpites (2 números inteiros). Se ele acertou os 2 números mostre uma mensagem indicando que ele venceu. Se ele acertou somente um dos números então apresente uma mensagem mostrando qual número ele acertou e, caso não acerte nenhum deles, apresente "Você perdeu".

2 Seleção Múltipla

Sintaxe:

::= MultiplasOpcoes( )

inicio

fim

::= | | | (

::= caso : saia; |

caso :

::= casoContrario

Semântica:

O comando MultiplasOpcoes permite executar um bloco de comandos associado a um em função do resultado da . Assim, se o resultado da coincidir com o valor associado do então o respectivo é executado. Os exemplos seguintes elucidam a explicação.

Exemplo 6: utilização do comando MultiplasOpcoes.

Este exemplo resolve o exercício 3 da calculadora (item 5.1, seleção simples).

1. // Programa: calc.cpp

53. // Autor :

54. // O programa realiza operações aritméticas entre dois operandos.

55. //

56. #include "tradutor.h"

57. programa

58. inicio

59. real rOper1, rOper2;

60. caracter cOperacao;

61.

62. escreva "Digite o primeiro operando: " ;

63. leia rOper1;

64. escreva "\nDigite a operação: ";

65. leia cOperacao;

66. escreva "\nDigite o segundo operando: " ;

67. leia rOper2;

68. escreva "\nResultado: ";

69.

70. multiplasOpcoes ( cOperacao )

71. inicio

72. caso '+':

73. escreva rOper1 + rOper2;

74. saia;

75. caso '-':

76. escreva rOper1 - rOper2;

77. saia;

78. caso '*':

79. escreva rOper1 * rOper2;

80. saia;

81. caso '/':

82. escreva rOper1 + rOper2;

83. saia;

84. casoContrario:

85. escreva "Operacao invalida";

86. fim

87.

88. fim

Exercícios:

1. Leia do teclado números inteiros de 1 a 7. Mostre o nome do dia da semana correspondente por extenso.

2. Leia mês e ano do teclado e mostre o número de dias correspondente ao mês lido.

3. Apresente o menu abaixo. Se o usuário escolher Aplicações Financeiras, apresente a mensagem "Não há aplicações financeiras", se escolher Saldo apresente a mensagem "Saldo de conta corrente ou poupança?" e caso seja Extrato, apresente a mensagem "Extrato de conta corrente ou poupança?"

Banco Tabajara

===============

1. Saldo

2. Extrato

3. Aplicações Financeiras

4. Altere o exercício anterior. Se o usuário selecionar a opção Saldo ou Extrato apresente o seguinte menu:

a) Poupança

b) Conta Corrente

Se o usuário escolher Poupança, apresente a mensagem "Imprimindo saldo da poupança" ou "Imprimindo extrato da poupança" dependendo da primeira opção escolhida. Adote procedimento idêntico para extrato.

Se o usuário escolher Aplicações Financeiras, apresente a mensagem "Não há aplicações financeiras".

Comandos de Repetição ou Laço

Os comandos de repetição permitem que um bloco de comandos seja executado uma ou mais vezes. Existem, basicamente, três comandos básicos pertencentes a este grupo:

1. Enquanto ou while: repete uma bloco de comandos enquanto uma determinada condição for verdadeira.

2. Execute ... Enquanto ou do ... while: executa pelo menos uma vez um bloco de comandos e, depois, enquanto uma determinada condição for verdadeira.

3. Para ou for: repete um bloco de comandos x vezes, onde x é uma quantidade determinada.

1 Enquanto/While

Sintaxe:

::= enquanto( )

inicio

fim |

enquanto( )

::= /* não será detalhada */

::= |

::= | | | | |

Semântica:

O ou o é executado enquanto a for verdadeira. Quando ela torna-se falsa a execução do programa passa ao comando seguinte.

Exemplo 7: utilização do comando Enquanto.

Queremos converter velocidades de m/s para Km/h até que o usuário decida parar. Esta decisão será tomada quando o programa apresentar a mensagem "Deseja continuar [s/n] ?". Se escolher 's' continuamos a execução do programa, caso contrário, a interrompemos.

1. #include "tradutor.h"

2. programa

3. inicio

4. real rVelMS;

5. caracter cOpcao = 's'; // não esqueça de inicializar a variável.

6. escreva "Conversor m/s -> Km/h\n";

7. escreva "Deseja prosseguir [s/n]?";

8. leia cOpcao;

9. enquanto (cOpcao == 's')

10. inicio

11. escreva "Digite velocidade em m/s: ";

12. leia rVelMS;

13. escreva "\nVelocidade m KM/H: ";

14. escreva rVelMS * 3.6;

15. escreva "Deseja continuar [s/n]?";

16. leia cOpcao;

17. fim

18.

19. fim

Exercícios:

1. Faça um algoritmo que leia temperaturas até que o usuário decida em contrário. Você identificará esta decisão quando ele digitar 999 para uma temperatura. Calcule e mostre: a menor temperatura digitada, a maior temperatura e a temperatura média.

2. Escreva um algoritmo para encontrar o n-ésimo termo de uma Progressão Aritmética (PA). Ler a1 (o primeiro termo), r (a razão) e n ( o número de termos). O n-ésimo termo é calculado pela fórmula an = a1 + r * (n - 1). Consistências: não permitir que o usuário introduza para a1 valores superiores a 200 e inferiores a 0. Enquanto os valores estiverem fora desta faixa apresente a mensagem "Primeiro termo deve estar no intervalo [0, 200] e peça novamente por a1.

3. Faça um algoritmo para automatizar a caixa de uma pizzaria. A pizzaria oferece as seguintes opções para os clientes:

|Produto |Médio(a) |Grande |

|Napolitana |R$5,00 |R$6,00 |

|Lombinho |R$5,50 |R$6,50 |

|Portuguesa |R$5,50 |R$6,00 |

|Coca |R$0,80 |R$1,20 |

|Guaraná |R$0,70 |R$1,25 |

Cada cliente que chega é atendido por um caixa. Ele pode escolher diversos produtos em diferentes quantidades. No final da compra, o caixa apresenta o valor total da mesma. Consistências: as quantidades digitadas para cada produto devem ser maiores que zero e inferiores a 100. Caso seja fornecido um valor fora deste intervalo, apresente a mensagem "Redigite a quantidade" e repita a leitura.

4. Altere o algoritmo acima para totalizar as vendas do caixa de um dia.

1. //---------------------------------------------------------------------------

89. // Autor: Tacla

90. // Data : 30 julho 1999

91. // Exercício Pizzaria

92. //---------------------------------------------------------------------------

93. #include "tradutor.h"

94.

95. programa

96. inicio

97. real rTotCaixa=0, rTotCliente=0;

98. inteiro iOpcao, iTam, iQtd, iContCliente=0;

99.

100. execute

101. inicio

102. limpaJanela;

103. escreva "\nProduto \tMedio \tGrande";

104. escreva "\n===========================================";

105. escreva "\n0. Napolitana\tR$5,00\tR$6,50";

106. escreva "\n-------------------------------------------";

107. escreva "\n1. Lombinho \tR$5,50\tR$6,50";

108. escreva "\n-------------------------------------------";

109. escreva "\n2. Portuguesa\tR$5,50\tR$6,00";

110. escreva "\n-------------------------------------------";

111. escreva "\n3. Coca \tR$0,80\tR$1,20";

112. escreva "\n-------------------------------------------";

113. escreva "\n4. Guarana \tR$0,70\tR$1,25";

114. escreva "\n-------------------------------------------";

115. escreva "\n-1. Fechar a conta do cliente";

116. escreva "\n-2. Fechar o caixa";

117. escreva "\n-------------------------------------------";

118.

119. escreva "\nOpcao: ";

120. leia iOpcao;

121.

122. se ( iOpcao >= 0 )

123. inicio

124. escreva "\nTamanho 0-Medio 1-Grande: ";

125. leia iTam;

126. enquanto ( iTam < 0 || iTam > 1 )

127. inicio

128. escreva "\nRedigite o tamanho: ";

129. leia iTam;

130. fim

131.

132. escreva "\nQuantidade: ";

133. leia iQtd;

134. enquanto ( iQtd < 0 || iQtd > 100 )

135. inicio

136. escreva "\nRedigite a quantidade: ";

137. leia iQtd;

138. fim

139. fim

140.

141. multiplasOpcoes (iOpcao)

142. inicio

143. caso 0:

144. se (iTam == 0) // Napolitana media

145. rTotCliente = rTotCliente + 5.00 * iQtd;

146. senao // Napolitana grande

147. rTotCliente = rTotCliente + 6.00 * iQtd;

148. saia;

149.

150. caso 1:

151. se (iTam == 0) // Lombinho media

152. rTotCliente = rTotCliente + 5.50 * iQtd;

153. senao // Lombinho grande

154. rTotCliente = rTotCliente + 6.50 * iQtd;

155. saia;

156.

157. caso 2:

158. se (iTam == 0) // Portuguesa media

159. rTotCliente = rTotCliente + 5.50 * iQtd;

160. senao // Portuguesa grande

161. rTotCliente = rTotCliente + 6.00 * iQtd;

162. saia;

163.

164. caso 3:

165. se (iTam == 0) // Coca media

166. rTotCliente = rTotCliente + 0.80 * iQtd;

167. senao // Coca grande

168. rTotCliente = rTotCliente + 1.20 * iQtd;

169. saia;

170.

171. caso 4:

172. se (iTam == 0) // Guarana media

173. rTotCliente = rTotCliente + 0.70 * iQtd;

174. senao

175. rTotCliente = rTotCliente + 1.25 * iQtd;

176. saia;

177.

178. caso -1:

179. escreva "\n\n========================";

180. escreva "\nPreco a pagar: R$ ";

181. escreva rTotCliente;

182. escreva "\n========================";

183. escreva "\ntecle [enter]";

184. getch( );

185. rTotCaixa = rTotCaixa + rTotCliente;

186. iContCliente = iContCliente + 1;

187. rTotCliente = 0;

188. saia;

189.

190. caso -2:

191. se ( rTotCliente > 0 )

192. inicio

193. escreva "\n\n*** Feche primeiramente a conta do cliente ***";

194. iOpcao = 0;

195. fim

196. senao

197. inicio

198. escreva "\n\n========================";

199. escreva "\nTotal do movimento: R$ ";

200. escreva rTotCaixa;

201. escreva "\n Total de clientes: ";

202. escreva iContCliente;

203. escreva "\n Gasto por cliente: R$ ";

204. se ( iContCliente > 0 )

205. escreva rTotCaixa / iContCliente;

206. escreva "\n========================";

207.

208. fim

209. escreva "\ntecle [enter]";

210. getch( );

211. saia;

212. fim

213. fim

214. enquanto ( iOpcao != -2 );

215.

216. fim

217. //---------------------------------------------------------------------------

2 Execute ... Enquanto/Do ... While

Sintaxe:

::= execute

inicio

fim

enquanto( ); |

execute

enquanto( ) ;

::= /* não será detalhada */

::= |

::= | | | | | |

Semântica:

O ou o é executado uma vez. Depois, é executado enquanto a for verdadeira. Quando ela torna-se falsa a execução do programa passa ao comando seguinte.

Exemplo 8: utilização do comando Execute ... Enquanto.

Refazendo o exemplo anterior temos:

1. #include "tradutor.h"

218. programa

219. inicio

220. real rVelMS;

221. caracter cOpcao; // note que não precisamos inicializar a variável.

222.

223. execute

224. inicio

225. escreva "Digite velocidade em m/s: ";

226. leia rVelMS;

227. escreva "\nVelocidade m KM/H: ";

228. escreva rVelMS * 3.6;

229. escreva "Deseja continuar [s/n]?";

230. leia cOpcao;

231. fim

232. enquanto (cOpcao == 's');

233.

234. fim

Exercícios:

1. Faça uma algoritmo que converta temperaturas de graus Celsius para Farenheit e vice-versa de acordo com a escolha do usuário. A fórmula para conversão é C = 5/9 * (F - 32), Onde F é o valor em Farenheit e C será o valor em graus Celsius. O algoritmo deve ser executado pelo menos uma vez, ou seja, depois que o programa for chamado o usuário terá que fazer uma conversão. Depois da primeira conversão, perguntar ao usuário se deseja prosseguir.

3 Para/for

Sintaxe:

::= para(; ; )

inicio

fim |

para(; ; )

::= /* vide 2.4 */

::= /* não será detalhada */

::= |

::= | | | | | | ...

Semântica:

1. O comando inicia com a execução da atribuição .

2. Se a for verdadeira executa-se ou o . Caso contrário, o comando é finalizado.

3. Depois, executa-se a expressão e volta-se ao passo 2.

Exemplo 9: utilização do comando "para".

O programa abaixo imprime números de 0 a 5.

1. #include "tradutor.h"

2. programa

3. inicio

4. inteiro iContador;

5. para (iContador = 0; iContador < 6; iContador = iContador + 1)

6. inicio

7. escreva "\nLinha numero ";

8. escreva iContador;

9. fim

10. fim

Exercícios:

1. Faça um contador que apresente todos os inteiros compreendidos entre um valor inicial e um final fornecidos pelo usuário. Consistências: o valor final deve ser maior que o inicial.

2. Faça um contador regressivo para o qual o usuário fornece um número inicial e o programa apresenta todos os números pares inferiores ao número inicial. Consistências: o número inicial deve ser maior ou igual a 2.

3. Peça ao usuário um valor inicial , um valor final e um outro número, denominado . Assegure que o é maior que e que é menor que - . Apresente todos os números compreendidos entre o valor inicial. A cada mensagens imprima a mensagem "--- Mais ? ---" e utilize a função getch( ) para que o programa só prossiga após o usuário teclar algo.

4. Faça um contador que apresente todos os inteiros compreendidos entre um valor inicial e um final fornecidos pelo usuário. Consistências: o valor final deve ser maior que o inicial. Peça ao usuário um número para um subcontador. Para cada valor apresentado, o programa deve fazer uma subcontagem de valores. Exemplo:

Contador

========

Forneça o valor inicial: 5 // 5 foi digitado pelo usuário

Forneça o valor final : 7 // 7 foi digitado pelo usuário

Forneça o valor de subcontagem: 3 // 3 foi digitado pelo usuário

Contagem // saída produzida pelo programa

========

5

5.1

5.2

5.3

6

6.1

6.2

6.3

7

7.1

7.2

7.3

Matriz de Variáveis / Array

Uma matriz é um conjunto de variáveis de mesmo tipo e mesmo nome. Para diferenciar os elementos deste conjunto utilizamos índices. A quantidade de dimensões de uma matriz varia de acordo com a natureza do problema, porém, as mais empregadas são as unidimensionais e as bidimensionais. As unidimensionais também são denominadas de vetores.

1 Declaração de uma Variável Matricial

Exemplos:

a) inteiro iCodigo[3];

Declaração de uma variável matricial com 3 elementos do tipo inteiro.

| | |(1 byte ( |

|endereç|70 | |

|o | | |

|físico | | |

| |71 | |

| |72 | |

| |73 | |

| |74 | |

| |75 | |

Figura 3: representação esquemática de um vetor de inteiros na memória.

b) real rNota[2];

Declaração de uma variável matricial com 2 elementos do tipo real.

| | |(1 byte ( |

|endereç|70 | |

|o | | |

|físico | | |

| |71 | |

| |72 | |

| |73 | |

| |74 | |

| |75 | |

| |76 | |

| |77 | |

Figura 4: representação esquemática de um vetor de reais na memória.

c) caracter cLetra[2][3]

Declaração de uma variável matricial com 5 linhas e 3 colunas.

| | |(1 byte ( |

|endereç|70 | |

|o | | |

|físico | | |

| |71 | |

| |72 | |

| |73 | |

| |74 | |

| |75 | |

Figura 5: representação esquemática de um variável matricial bidimensional tipo caracter na memória.

*** Importante ***: note que os índices iniciam sempre a partir do zero. Portanto, se for usar uma matriz 3 x 2, os índices das linhas devem estar no intervalo [0, 2] e os das colunas, no intervalo [0, 1]. Se estes limites forem ultrapassados, o programa arruinará as variáveis vizinhas ou até mesmo o código executável.

2 Aplicação

Seguem alguns exemplos de aplicação de variáveis matriciais.

Exemplo 10: utilização de variáveis matriciais do tipo real.

Imagine que queremos calcular a média de vários alunos. A média é resultado da média aritmética entre 4 notas de provas e trabalhos. Poderíamos utilizar uma variável matricial para armazenar estas notas ao invés de criarmos 4 variáveis reais com diferentes nomes:

1. // Programa: media.cpp

2. // Autor :

3. #include "tradutor.h"

4. programa

5. inicio

6. real rNota[4];

7. para (i=0; i < 4; i=i+1)

8. inicio

9. escreva "\nDigite a nota ";

10. escreva i;

11. escreva ": ";

12. leia rNota[i];

13. fim

14. escreva "\nMedia calculada: ";

15. escreva (rNota[0] + rNota[1] + rNota[3] + rNota[4]) / 4;

16. fim

Exemplo 11: utilização de variáveis matriciais do tipo caracter.

O programa abaixo imprime um jogo da velha.

1. // Programa: velha.cpp

2. // Autor :

3. #include "tradutor.h"

4. programa

5. inicio

6. caracter cPosicao[3][3] = {'X', 'O', 'O',

7. ' ', 'X', 'O',

8. ' ', ' ', 'X'};

9. inteiro i, j;

10. para (i=0; i < 3; i=i+1)

11. inicio

12. para (j=0; j < 3; j=j+1)

13. inicio

14. escreva " ";

15. escreva cPosicao[i][j];

16. escreva " |";

17. fim

18. escreva "\n---+---+---+\n"

19. fim

20. fim

Exemplo 12: rescrevendo o exercício 4 da seção 6.1.

Note naquela solução, existe um certo grau de dificuldade para modificar o preço de um produto. Primeiramente, deve-se mudar o preço no menu e, depois, procurá-lo no comando multiplasOpcoes e, finalmente, alterá-lo. É grande a probabilidade de errarmos ao fazermos uma alteração deste tipo. A solução apresentada neste exemplo resolve parcialmente o problema centralizando os preços dos produtos numa matriz 5 x 2. Cada linha da matriz é destinada a um produto, a coluna 0, para o preço do produto tamanho médio e a coluna 1 para o grande. A figura seguinte representa esquematicamente esta matriz, denominada de rPrecoProduto. Para saber o preço do pizza de Portuguesa Grande basta acessar o elemento rPrecoProduto[2][1].

| | |0 |1 |

|Napolitana |0 |5 |6 |

|Lombinho |1 |5.50 |6.50 |

|Portuguesa |2 |5.50 |6 |

|Coca |3 |0.80 |1.20 |

|Guaraná |4 |0.70 |1.25 |

Figura 6: Representação esquemática da matriz de preços de produtos.

1. //---------------------------------------------------------------------------

2. // Autor: Tacla

3. // Data : 30 julho 1999

4. // Exercício Pizzaria - pg. 16 em algoritmos.doc

5. // Reformulado para trabalhar com matriz de valores de produtos.

6. //---------------------------------------------------------------------------

7. #include "tradutor.h"

8. programa

9. inicio

10. real rTotCaixa=0, rTotCliente=0;

11. real rPrecoProd[5][2] = { { 5.00, 6.50 },

12. { 5.50, 6.50 },

13. { 5.50, 6.00 },

14. { 0.80, 1.20 },

15. { 0.70, 1.25 } };

16.

17. inteiro iOpcao, iTam, iQtd, iContCliente=0;

18.

19. execute

20. inicio

21. limpaJanela;

22. escreva "\nProduto \tMedio \tGrande";

23. escreva "\n===========================================";

24. escreva "\n0. Napolitana\tR$5,00\tR$6,00";

25. escreva "\n-------------------------------------------";

26. escreva "\n1. Lombinho \tR$5,50\tR$6,50";

27. escreva "\n-------------------------------------------";

28. escreva "\n2. Portuguesa\tR$5,50\tR$6,00";

29. escreva "\n-------------------------------------------";

30. escreva "\n3. Coca \tR$0,80\tR$1,20";

31. escreva "\n-------------------------------------------";

32. escreva "\n4. Guarana \tR$0,70\tR$1,25";

33. escreva "\n-------------------------------------------";

34. escreva "\n-1. Fechar a conta do cliente";

35. escreva "\n-2. Fechar o caixa";

36. escreva "\n-------------------------------------------";

37.

38. escreva "\nOpcao: ";

39. leia iOpcao;

40.

41. se ( iOpcao >= 0 && iOpcao < 5)

42. inicio

43. escreva "\nTamanho 0-Medio 1-Grande: ";

44. leia iTam;

45. enquanto ( iTam < 0 || iTam > 1 )

46. inicio

47. escreva "\nRedigite o tamanho: ";

48. leia iTam;

49. fim

50.

51. escreva "\nQuantidade: ";

52. leia iQtd;

53. enquanto ( iQtd < 0 || iQtd > 100 )

54. inicio

55. escreva "\nRedigite a quantidade: ";

56. leia iQtd;

57. fim

58.

59. rTotCliente = rTotCliente + rPrecoProd[iOpcao][iTam] * iQtd;

60. fim

61. senao

62. se ( iOpcao < 0 )

63. inicio

64. multiplasOpcoes (iOpcao)

65. inicio

66. caso -1:

67. escreva "\n\n========================";

68. escreva "\nPreco a pagar: R$ ";

69. escreva rTotCliente;

70. escreva "\n========================";

71. escreva "\ntecle [enter]";

72. getch( );

73. rTotCaixa = rTotCaixa + rTotCliente;

74. iContCliente = iContCliente + 1;

75. rTotCliente = 0;

76. saia;

77.

78. caso -2:

79. se ( rTotCliente > 0 )

80. inicio

81. escreva "\n\n*** Feche primeiramente a conta do cliente ***";

82. iOpcao = 0;

83. fim

84. senao

85. inicio

86. escreva "\n\n========================";

87. escreva "\nTotal do movimento: R$ ";

88. escreva rTotCaixa;

89. escreva "\n Total de clientes: ";

90. escreva iContCliente;

91. escreva "\n Gasto por cliente: R$ ";

92. se ( iContCliente > 0 )

93. escreva rTotCaixa / iContCliente;

94. escreva "\n========================";

95.

96. fim

97. escreva "\ntecle [enter]";

98. getch( );

99. saia;

100. fim

101. fim

102. fim

103. enquanto ( iOpcao != -2 );

104.

105. fim

106. //---------------------------------------------------------------------------

Exemplo 13: rescrevendo o exemplo anterior.

Na solução anterior, permanece o problema da alteração do menu. Para resolvê-lo vamos modificar a maneira de imprimi-lo e criaremos uma matriz para armazenar os nomes dos produtos. A figura seguinte apresenta a matriz denominada cNomeProd de maneira esquemática. Note que é preciso reservar uma coluna para cada caracter, tomando por base a palavra mais longa que será armazenada. Além disso, deve-se somar um à quantidade de colunas pois a linguagem C utiliza a última posição para colocar o caracter \0 que é o delimitador de strings. Note no exemplo abaixo que para escrever uma string basta fornecer o nome da matriz seguido do primeiro índice. Por exemplo, escrevendo-se escreva cNomeProd[3] obteremos como saída Coca.

| |0 |1 |2 |3 |4 |5 |6 |7 |8 |9 |10 |

|0 |N |a |p |o |l |i |t |a |n |a |\0 |

|1 |L |o |m |b |i |n |h |o |\0 | | |

|2 |P |o |r |t |u |g |u |e |s |a |\0 |

|3 |C |o |c |a |\0 | | | | | | |

|4 |G |u |a |r |a |n |a |\0 | | | |

Figura 7: Representação esquemática da matriz de nomes de produtos.

1. //---------------------------------------------------------------------------

2. // Autor: Tacla

3. // Data : 30 julho 1999

4. // Exercício Pizzaria - pg. 16 em algoritmos.doc

5. // Reformulado para trabalhar com matriz de valores e nomes de produtos.

6. //---------------------------------------------------------------------------

7. #include "tradutor.h"

8. programa

9. inicio

10. real rTotCaixa=0, rTotCliente=0;

11. real rPrecoProd[5][2] = { { 5.00, 6.50 },

12. { 5.50, 6.50 },

13. { 5.50, 6.00 },

14. { 0.80, 1.20 },

15. { 0.70, 1.25 } };

16.

17. caracter cNomeProd[5][11] = { "Napolitana",

18. "Lombinho ",

19. "Portuguesa",

20. "Coca ",

21. "Guarana " };

22.

23. inteiro iOpcao, iTam, iQtd, iContCliente=0;

24.

25. execute

26. inicio

27. clrscr( );

28. escreva "\n Produto Medio Grande";

29. escreva "\n================================";

30.

31. para ( iOpcao = 0; iOpcao < 5; iOpcao = iOpcao + 1)

32. inicio

33. escreva "\n ";

34. escreva iOpcao;

35. escreva ". ";

36. escreva cNomeProd[iOpcao];

37. escreva " R$";

38. escreva rPrecoProd[iOpcao][0];

39. escreva "\tR$";

40. escreva rPrecoProd[iOpcao][1];

41. escreva "\n--------------------------------";

42. fim

43. escreva "\n-1. Fechar a conta do cliente";

44. escreva "\n-2. Fechar o caixa";

45. escreva "\n--------------------------------";

235. ..... o restante do programa é idêntico ao exemplo anterior ....

Exercícios:

1. Leia 5 números inteiros do teclado, coloque-os num vetor e apresente-os em ordem crescente.

2. Leia do teclado números inteiros de 1 a 7. Mostre o nome do dia da semana correspondente por extenso. Armazene os nomes dos dias numa matriz de caracteres.

3. Faça um programa que permita duas pessoas jogarem velha.

Estruturas de Dados Heterogêneas

/* Registros , Structs */

Funções

Quando temos um problema complexo para resolver geralmente utilizamos a técnica do dividir para conquistar, ou seja, dividimos o problema em subproblemas e, se preciso for, decompomos os subproblemas em problemas menores e assim por diante. Resolvendo cada um dos subproblemas e fazendo-os trabalhar de forma coordenada, alcançamos a solução para todo o problema.

Um exemplo da vida real. Você deseja fazer uma viagem para uma cidade onde nunca esteve antes e onde não há conhecidos. O problema é: como chegar na cidade, lá se instalar, visitar pontos interessantes e retornar. Olhando o problema à distância vemos que os subproblemas a serem resolvidos são:

1. Chegar na cidade (via aérea, trem, navio, carro ou ônibus ?)

2. Arranjar um lugar para ficar

3. Conhecer os pontos interessantes

4. Voltar.

Decompondo os subproblemas poderíamos chegar em:

1. Chegar na cidade (via aérea, trem, navio, carro ou ônibus ?)

1. Definir data de saída

2. Verificar meio mais barato

3. Comprar passagem

2. Arranjar um lugar para ficar

1. Conversar com outras pessoas que já foram

2. Pesquisar em guias turísticos

3. Pesquisar na Internet

4. Escolher um local

5. Fazer reserva para uma semana

3. Conhecer os pontos interessantes

1. Conversar com outras pessoas que já foram

2. Pesquisar em guias turísticos

3. Pesquisar na Internet

4. Escolher pontos mais interessantes

4. Voltar

1. Definir data de saída

2. Verificar meio mais barato

3. Comprar passagem.

Empregamos técnica similar para construir programas. Nas linguagens de programação, cada subdivisão do problema pode ser implementada através de uma função. Uma função é um bloco de código responsável pela realização de uma tarefa específica.

1 Aplicação: Conversão de temperatura

Exemplificamos a utilização desta técnica, denominada de desenvolvimento top-down que significa do genérico para o detalhe ou refinamentos sucessivos.

Exemplo 14: Celsius para Farenheit e vice-versa.

Faça uma algoritmo que converta temperaturas de graus Celsius para Farenheit e vice-versa de acordo com a escolha do usuário. A fórmula para conversão é C = 5/9 * (F - 32), Onde F é o valor em Farenheit e C será o valor em graus Celsius. O algoritmo deve ser executado pelo menos uma vez, ou seja, depois que o programa for chamado o usuário terá que fazer uma conversão. Depois da primeira conversão, perguntar ao usuário se deseja prosseguir.

Pseudo-código (top-down)

programa

faça

pedir temperatura

pedir unidade (Celsius ou Farenheit)

Se unidade for Celsius

Transformar temperatura para Farenheit

senão

Transformar temperatura para Celsius

perguntar "prosseguir ?"

enquanto usuário desejar prosseguir

fim

Note que existem dois subproblemas em aberto: transformar de Celsius para Farenheit e vice-versa. São duas tarefas que serão implementadas como funções. Identificadas as funções, definimos as entradas e as saídas da mesma, ou seja, os valores que são necessários para que ela realize sua tarefa (neste caso, a conversão de temperaturas) e o valor retornado.

A função Transformar para Farenheit. terá como entrada o valor de uma temperatura em Celsius e retornará o valor correspondente em Farenheits. Representaremos a função como uma caixa preta, onde somente interessam as entradas e as saídas. O modo como a função realiza os cálculos não interessa neste momento.

Figura 8: Função TransformarParaFarenheit (Caixa Preta)

Aplicando raciocínio similar ao da funçãoTransformar para Farenheit obtemos a seguinte visão caixa-preta da função TransformarParaCelsius.

Figura 9: Função TransformarParaCelsius (Caixa Preta)

Observe que nosso problema de conversão de temperaturas foi subdividido em dois menores: Celsius para Farenheit e Farenheit para Celsius. No entanto, é preciso que uma função principal coordene a execução destas funções ou tarefas. Em seguida, é apresentado o diagrama das funções que resolvem o problema da conversão de temperaturas.

Figura 10: Diagrama de Funções para o problema da conversão de temperaturas.

Observe que o diagrama anterior apenas fornece uma visão funcional do programa, ou seja, que tarefas ele realiza para alcançar o objetivo especificado. O diagrama não determina a ordem em que as funções são chamadas.

Implementação

Uma vez que está claro o objetivo do programa e como atacaremos o problema é hora de implementá-lo. Segue listagem do mesmo. Note como as funções são construídas, chamadas e como os valores retornados pelas mesmas são aproveitados pela função principal. Observer que ao invés de utilizarmos a palavra programa passaremos a utilizar principal para identificar a função principal do programa. A execução do programa sempre começa por esta função.

1. //-----------------------------------------------------------------------------

236. // Programa: ConvTemp.cpp

237. // Autor: Cesar Augusto Tacla

238. // Descrição: realiza a conversão de graus Celsius para Farenheit e vice-versa.

239. //-----------------------------------------------------------------------------

240.

241. #include "tradutor.h"

242.

243. // Protótipo das Funções

244. real TransformarParaCelsius ( real );

245. real TransformarParaFarenheit ( real );

246.

247. //-----------------------------------------------------------------------------

248. // Funcao: TransformarParaCelsius

249. // Descricao: Dada uma temp. em Farenheit retorna o valor correspondente em

250. // Celsius.

251. //-----------------------------------------------------------------------------

252. real TransformarParaCelsius ( real rTemp )

253. inicio

254. retorne ( 5.0 * ( rTemp - 32 ) ) / 9.0 ;

255. fim

256.

257. //-----------------------------------------------------------------------------

258. // Funcao: TransformarParaFarenheit

259. // Descricao: Dada uma temp. em Celsius retorna o valor correspondente em

260. // Farenheit.

261. //-----------------------------------------------------------------------------

262. real TransformarParaFarenheit ( real rTemp )

263. inicio

264. retorne ( 9.0 * rTemp + 160.0 ) / 5.0 ;

265. fim

266.

267. //-----------------------------------------------------------------------------

268. // Funcao: Principal

269. //-----------------------------------------------------------------------------

270. naoRetornaDado principal ( )

271. inicio

272. real rVlrTemp;

273. caracter cUnidade, cProsseguir;

274.

275. execute

276. inicio

277. escreva "\nValor da temp.? ";

278. leia rVlrTemp;

279. escreva "\nUnidade [C/F] ? ";

280. leia cUnidade;

281.

282. se ( cUnidade == 'c' ) entao

283. inicio

284. escreva "\nEm Farenheits: ";

285. escreva TransformarParaFarenheit( rVlrTemp );

286. fim

287. senao

288. inicio

289. escreva "\nEm Celsius: ";

290. escreva TransformarParaCelsius( rVlrTemp );

291. fim

292.

293. escreva "\nProsseguir [s/n] ? ";

294. leia cProsseguir;

295. fim

296. enquanto ( cProsseguir == 's' );

297. fim

2 Criação de funções

Para criar e utilizar corretamente funções, observar os seguintes pontos:

Protótipo

É necessário para que o compilador reconheça as funções que você criou. Aparece no início do programa, antes da definição de qualquer função. A sintaxe é a seguinte:

::= ();

< NomeFunção > ::= /* nome de até 32 caracteres que não inicie por símbolos especiais (*, &, %, etc.), nem por números e que não contenha espaços */

::= ( | | ,

::= |

::= | naoRetornaDado

::= inteiro |real | logico |caracter

Exemplos:

real TransformarParaFarenheit ( real );

logico MaiorQue (real, real);

logico MenorQue (inteiro iNum1, inteiro iNum2);

naoRetornaDado MostrarMenu( );

Definição da função

É a função em si. Realiza a transformação dos dados de entrada nos de saída. A sintaxe é a seguinte:

::=

inicio

fim

::= ()

< NomeFunção > ::= /* nome de até 32 caracteres que não inicie por símbolos especiais (*, &, %, etc.), nem por números e que não contenha espaços */

::= ( | | ,

::=

::= /* já definido anteriormente adicionado do comando retorne */

::= retorne ;

::= /* já definido anteriormente */

::= | naoRetornaDado

::= inteiro |real | logico |caracter

Note que a sintaxe do cabeçalho é parecida com a do protótipo. Porém, no cabeçalho não há ponto e vírgula no final e os parâmetros de entrada devem estar completamente definidos pelo tipo do dado e nome da variável (vide categoria sintática ). É importante que os tipos de dados de retorno e dos parâmetros de entrada declarados no protótipo coincidam com os do cabeçalho, caso contrário, ocorrerá erro de compilação. O comando retorne permite encerrar a função e ao mesmo tempo retornar o valor de saída que deve ser do mesmo tipo que o declarado no cabeçalho e no protótipo da função.

Exemplo:

Função que compara dois inteiros e retorna verdadeiro caso o primeiro seja menor que o segundo.

1. logico MenorQue ( inteiro iNum1, iNum2 )

2. inicio

3. se ( iNum1 < iNum2 )

4. retorne verdadeiro;

5. senao

6. retorne falso;

7. fim

Função que mostra um menu.

1. naoRetornaDado MostarMenu( )

298. inicio

299. escreva "1. Extrato\n";

300. escreva "2. Saldo\n";

301. escreva "3. Sair\n";

302. fim

Chamada de função

Uma função pode ser chamada de qualquer ponto do programa, inclusive de outras funções ou a partir dela mesma. Faça com que os argumentos passados na chamada coincidam com os parâmetros de entrada da função. Se a função espera receber um valor inteiro e você passa um caracter certamente ela não se comportará como desejado. Outro ponto importante é observar se está recebendo o valor retornado pela função numa variável adequada, ou seja, uma variável que tenha o mesmo tipo que o valor retornado pela função. É importante ressaltar que quando utilizamos uma variável como argumento de uma função estamos passando o conteúdo ou o valor atual da mesma. Este tipo de chamada é denominada chamada com passagem por conteúdo.

Exemplos:

Para chamar a função MenorQue definida anteriormente teríamos várias possibilidades. Note em que todas elas foi respeitado o tipo de dado dos parâmetros de entrada e de saída.

❑ result = MenorQue ( 5, 6); // result é do tipo lógico

❑ result = MenorQue ( iQtd, 10); // iQtd é uma variável do tipo inteiro

❑ result = MenorQue ( iQtd, iNum[i] ); // iNum é uma vetor de inteiros

❑ se ( MenorQue ( iQtd, iNum[i] ) ) entao

...

// podemos utilizar o valor retornado diretamente num outro comando.

Para chamar a função MenorQue definida anteriormente temos somente uma possibilidade. Note que quando não há argumentos de entrada deve-se abrir e fechar parênteses.

❑ MostrarMenu( );

Exercício:

1. Utilizando a técnica top-down faça um pseudo-código e o diagrama de funções para resolver o seguinte problema: calcular a diferença em dias entre duas datas fornecidas pelo usuário. O usuário poderá fazer várias vezes este cálculo sem sair do programa. O programa deve verificar se as datas fornecidas são válidas e se a primeira data é menor que a segunda. Só então ele calculará a diferença em dias entre as duas e apresentará o resultado. Obs: não é preciso detalhar o cálculo de diferença em dias e nem as verificações de datas.

3 Aplicação: Jogo da Velha

Apresenta-se nesta seção o pseudo-código, diagrama de funções e a implementação para um problema mais complexo: o jogo da velha. O jogador 1 sempre jogará com o símbolo 'X' e o 2, com 'O'. Os jogadores podem jogar sucessivamente sem sair do programa. A cada final de partida apresenta-se o resultado do jogo e pergunta-se a um dos jogadores se desejam prosseguir. O placar das partidas disputadas até o momento é mostrado no topo da tela e nunca desaparece.

Pseudo-código

Nível 1 (+ alto-nível)

fazer

limpar tabuleiro

mostrar tabuleiro

fazer

pedir jogada ao jogador 1

enquanto jogada for incorreta

pedir jogada ao jogador 1

mostrar tabuleiro

verificar resultado do jogo

se jogador 1 ganhou entao

adicionar 1 ao total de partidas ganhas por ele

mostrar vencedor

senao

se não houve empate

pedir jogada ao jogador 2

enquanto jogada for incorreta

pedir jogada ao jogador 2

mostrar tabuleiro

verificar resultado do jogo

se jogador 2 ganhou entao

adicionar 1 ao total de partidas ganhas por ele

mostrar vencedor

enquanto jogo não acabar

perguntar Prosseguir ?

enquanto usuário quiser prosseguir

Observe que os trechos em azul são similares variando apenas o jogador. Trechos de código repetidos são bons candidatos a funções. Porém, tomar cuidado para não colocar numa mesma função comandos que estejam agrupados apenas pela posição no código e não pela tarefa que desempenham. Por exemplo, apesar de todo o trecho em azul estar repetido, parece mais conveniente separá-lo em duas funções ou tarefas: uma para ler e verificar a validade de uma jogada e outra para fazer o procedimento em caso de vitória. Outras candidatas a funções são as tarefas especificas, tais como, verificar resultado do jogo, verificar se jogada foi correta, limpar tabuleiro e mostrar tabuleiro. Em seguida, apresenta-se nova versão do pseudo-código acima, considerando as funções identificadas.

Nível 1 (reescrito)

fazer

limpar tabuleiro

mostrar tabuleiro

fazer

Obter jogada válida do jogador 1

mostrar tabuleiro

Verificar resultado do jogo

Se jogo não acabou

Obter jogada válida do jogador 2

mostrar tabuleiro

Verificar resultado do jogo

enquanto jogo não acabar

caso resultado do jogo

jogador 1 venceu:

fazer procedimento vitória

jogador 2 venceu:

fazer procedimento vitóra

empate:

fazer procedimento de empate.

perguntar Prosseguir ?

enquanto usuário quiser prosseguir

Ao reescrever o pseudo-código notamos que no caso de empate o resultado não estava sendo mostrado, então, inserimos um novo trecho de código (em azul) executado ao final de cada partida. Uma modificação ainda pode ser feita: alternar as jogadas do jogador 1 e 2. Veja abaixo o pseudo-código reescrito.

Nível 1 (reescrito 2)

fazer

limpar tabuleiro

mostrar tabuleiro

jogador da vez = 2

fazer

jogador da vez = ( jogador da vez % 2 ) + 1

Obter jogada válida do jogador da vez

mostrar tabuleiro

Verificar resultado do jogo

enquanto jogo não acabar

caso resultado do jogo

jogador 1 venceu:

fazer procedimento vitória

jogador 2 venceu:

fazer procedimento vitóra

empate:

fazer procedimento de empate.

perguntar Prosseguir ?

enquanto usuário quiser prosseguir

Agora o pseudo-código está bem enxuto. Veja que neste nível, temos uma boa visão da solução do problema sem entrarmos em detalhes do tipo: o que é uma jogada válida ou como o tabuleiro será mostrado. Em seguida, detalharemos as funções identificadas.

Nível 2 (Detalhamento das funções)

limpar tabuleiro

entradas: nenhuma

saída: não retorna nada

pseudo-código:

atribuir espaços às variáveis que representam o tabuleiro

mostrar tabuleiro

entradas: inteiro, inteiro, caracter, caracter

saída: não retorna nada

pseudo-código:

mostrar símbolo do jogador 1 e do 2

mostrar placar

mostrar a matriz passada como parâmetro

Verificar resultado do jogo

descrição: verifica se o jogador que utiliza o símbolo passado como parâmetro de entrada venceu ou se o jogo empatou.

entradas: tipo caracter.

saída: inteiro. Retornar 0 em caso de empate, 1, se o jogador que utiliza o venceu e, 2, se o jogo não acabou.

pseudo-código:

Para cada linha do fazer

contar quantas vezes o aparece

Se aparece 3 vezes então

retornar 1 (jogador venceu)

Para cada coluna da matriz tabuleiro fazer

contar quantas vezes o aparece

contar células vazias.

Se aparece 3 vezes então

retornar 1 (jogador venceu)

Contar quantas vezes o aparece na diagonal principal.

Se aparece 3 vezes então

retornar 1 (jogador venceu)

Contar quantas vezes o aparece na diagonal secundária.

Se aparece 3 vezes então

retornar 1 (jogador venceu)

Se número de células vazias for zero

retornar 0, ou seja, empate.

retornar 2, jogo ainda não decidido.

Obter jogada válida

entradas: matriz 3 x 3 do tipo caracter, inteiro, caracter.

saída: não retorna nada

pseudo-código:

execute

Obter linha válida

Obter coluna válida

enquanto ( tabuleiro[linha-1][coluna-1] != ' ' )

tabuleiro[linha-1][coluna-1] =

Nível 3 (Detalhamento das funções)

Obter linha válida

entradas: nada

saída: número da linha (inteiro)

pseudo-código:

execute

pedir linha

equanto linha < 1 ou linha > 3

retornar número da linha

Obter coluna válida

entradas: nada

saída: número da coluna (inteiro)

pseudo-código:

execute

pedir coluna

equanto coluna < 1 ou coluna > 3

retornar número da coluna

Diagrama de Funções

Implementação

1. //-----------------------------------------------------------------------------

2. // Programa: Velha.cpp

3. // Autor: Cesar Augusto Tacla

4. // Descrição: permite duas pessoas jogarem velha.

5. //-----------------------------------------------------------------------------

6.

7. #include "tradutor.h"

8.

9. // Protótipo das Funções

10. naoRetornaDado MostrarTabuleiro( inteiro, inteiro );

11. inteiro VerificarResultado( );

12. naoRetornaDado ObterJogadaValida( inteiro, caracter );

13. inteiro ObterLinhaValida( );

14. inteiro ObterColunaValida( );

15.

16. // Variáveis Globais

17. caracter tab[3][3]; // tabuleiro do jogo

18.

19. //-----------------------------------------------------------------------------

20. // Funcao: ObterLinhaValida

21. // Descricao: Pede ao usuário o número de uma linha. Quando fornece

22. // um valor entre 1 e 3, retorna o numero da linha digitado.

23. //-----------------------------------------------------------------------------

24. inteiro ObterLinhaValida( )

25. inicio

26. inteiro lin;

27.

28. execute

29. inicio

30. escreva " Linha ? ";

31. leia lin;

32. fim

33. enquanto ( lin < 1 ou lin > 3 );

34.

35. retorne lin;

36. fim

37.

38. //-----------------------------------------------------------------------------

39. // Funcao: ObterColunaValida

40. // Descricao: Pede ao usuário o número de uma coluna. Quando fornece

41. // um valor entre 1 e 3, retorna o numero da coluna digitado.

42. //-----------------------------------------------------------------------------

43. inteiro ObterColunaValida( )

44. inicio

45. inteiro col;

46.

47. execute

48. inicio

49. escreva "Coluna ? ";

50. leia col;

51. fim

52. enquanto ( col < 1 ou col > 3 );

53.

54. retorne col;

55. fim

56.

57. //-----------------------------------------------------------------------------

58. // Funcao: VerificarResultado

59. // Descricao: Verifica se o jogador que utiliza o simbolo ganhou.

60. // Tambem verifica se o jogo terminou empatado ou se ainda não

61. // acabou.

62. // Retorna: 0 - empate

63. // 1 - jogador da vez ganhou

64. // 2 - jogo não encerrado

65. //-----------------------------------------------------------------------------

66. inteiro VerificarResultado( caracter simbolo )

67. inicio

68. inteiro i, j,

69. cont,

70. cont_brancos = 0;

71.

72. // conta as ocorrencias do em cada uma das linhas

73. para ( i = 0; i < 3; i = i + 1 )

74. inicio

75. cont = 0;

76. para ( j = 0; j < 3; j = j + 1 )

77. se ( tab[i][j] == simbolo )

78. cont = cont + 1;

79.

80. se ( cont == 3 )

81. retorne 1; // venceu

82. fim

83.

84. // conta as ocorrencias do em cada uma das colunas

85. para ( j = 0; j < 3; j = j + 1 )

86. inicio

87. cont = 0;

88. para ( i = 0; i < 3; i = i + 1 )

89. se ( tab[i][j] == simbolo )

90. cont = cont + 1;

91. senao

92. se ( tab[i][j] == ' ' )

93. cont_brancos = cont_brancos + 1;

94.

95. se ( cont == 3 )

96. retorne 1; // venceu

97. fim

98.

99. // verificar diagonal principal

100. cont = 0;

101. para ( i = 0; i < 3; i = i + 1 )

102. se ( tab[i][i] == simbolo )

103. cont = cont + 1;

104.

105. se ( cont == 3 )

106. retorne 1; // venceu

107.

108. // verificar diagonal secundária

109. se ( tab[0][2] == simbolo e tab[1][1] == simbolo e tab[2][0] == simbolo )

110. retorne 1; // venceu

111.

112. // verificar se deu empate

113. se ( cont_brancos == 0 )

114. retorne 0;

115.

116. retorne 2;

117. fim

118.

119. //-----------------------------------------------------------------------------

120. // Funcao: ObterJogadaValida

121. // Descricao: Pede ao usuário a linha e a coluna da sua jogada. A jogada é

122. // considerada válida se a linha e a coluna estão no intervalo

123. // [1, 3] e se não há marcação na linha e coluna escolhidas.

124. //-----------------------------------------------------------------------------

125. naoRetornaDado ObterJogadaValida( inteiro jogador, caracter simbolo)

126. inicio

127. inteiro lin, col;

128.

129. execute

130. inicio

131. escreva "\n\nJogador ";

132. escreva jogador;

133. escreva "\n";

134. lin = ObterLinhaValida( );

135. col = ObterColunaValida( );

136. fim

137. enquanto( tab[lin-1][col-1] != ' ' );

138.

139. tab[lin-1][col-1] = simbolo;

140. fim

141.

142.

143.

144. //-----------------------------------------------------------------------------

145. // Funcao: LimparTabuleiro

146. // Descricao: Preenche o tabuleiro com espaços.

147. //-----------------------------------------------------------------------------

148. naoRetornaDado LimparTabuleiro( )

149. inicio

150. inteiro i, j;

151.

152. para ( i = 0; i < 3; i = i + 1 )

153. para ( j = 0; j < 3; j = j + 1 )

154. tab[i][j] = ' ';

155. fim

156.

157. //-----------------------------------------------------------------------------

158. // Funcao: MostrarTabuleiro

159. // Descricao: Mostra o placar e o tabuleiro com marcação atual.

160. //-----------------------------------------------------------------------------

161. naoRetornaDado MostrarTabuleiro( inteiro ptos1, inteiro ptos2 )

162. inicio

163. inteiro i, j;

164.

165. limpaJanela;

166.

167. // mostra placar do jogo

168. escreva "Jogo da Velha\n";

169. escreva "-------------\n\n";

170. escreva "Jog1 ";

171. escreva ptos1;

172. escreva " X ";

173. escreva ptos2;

174. escreva " Jog2";

175. escreva "\n\n";

176.

177. // mostra indices das colunas

178. escreva " 1 2 3\n";

179.

180. // mostra tabuleiro

181. para ( i = 0; i < 3; i = i + 1 )

182. inicio

183. escreva i+1;

184. escreva " ";

185. para ( j = 0; j < 3; j = j + 1 )

186. inicio

187. escreva " ";

188. escreva tab[i][j];

189. escreva " ";

190. se ( j != 2 )

191. escreva "|";

192. fim

193. se ( i != 2 )

194. escreva "\n ---+---+---\n";

195. fim

196.

197. retorne;

198. fim

199.

200. //-----------------------------------------------------------------------------

201. // Funcao: Principal

202. //-----------------------------------------------------------------------------

203. naoRetornaDado principal ( )

204. inicio

205. caracter cProsseguir, // prosseguir: s ou n

206. simbolo[2]; // simbolos utilizados pelo jog1 e jog2

207.

208. inteiro jogador, // jogador da vez

209. iResultado, // resultado do jogo

210. ptos[2]; // pontos dos jogadores 1 e 2

211.

212. simbolo[0] = 'X'; // símbolo para o jogador 1

213. simbolo[1] = 'O'; // símbolo para o jogador 2

214. ptos[0] = 0; // jogador 1 começa com zero pontos

215. ptos[1] = 0; // jogador 2 começa com zero pontos

216.

217. execute

218. inicio

219. LimparTabuleiro( );

220. MostrarTabuleiro( ptos[0], ptos[1] );

221. jogador = 2;

222.

223. execute

224. inicio

225. jogador = ( jogador % 2 ) + 1;

226. ObterJogadaValida( jogador, simbolo[jogador-1] );

227. MostrarTabuleiro( ptos[0], ptos[1] );

228. iResultado = VerificarResultado( simbolo[jogador-1] );

229. fim

230. enquanto ( iResultado == 2 );

231.

232. multiplasOpcoes( iResultado )

233. inicio

234. caso 0:

235. escreva "\n\n * EMPATE * \n";

236. saia;

237. caso 1:

238. escreva "\n\n *** JOGADOR ";

239. escreva jogador;

240. escreva " VENCEU ***\n";

241. ptos[jogador-1] = ptos[jogador-1] + 1;

242. fim

243.

244. escreva "\nProsseguir [s/n] ? ";

245. leia cProsseguir;

246. fim

247. enquanto ( cProsseguir == 's' );

248.

249. fim

4 Escopo de Variáveis

Nesta seção estudaremos as variáveis em relação a sua visibilidade ou escopo.

Observe no exemplo do jogo da velha a variável tab que representa o tabuleiro. Ela foi declarada no início do programa, fora de qualquer função. Este tipo de variável é denominada variável global, pois pode ser acessada (ter o conteúdo modificado ou consultado) em qualquer função do programa. Ela é alocada no início do programa e somente cessa de existir quando o mesmo é encerrado. Recomenda-se utilizar o mínimo possível destas variáveis pois dificultam a compreensão do programa e reduzem sua modularidade. Variáveis globais causam dificuldades na localização de erros pois, quando apresentam um valor inesperado, devemos percorrer todas as linhas que a referenciam para encontrar o problema.

As variáveis que são declaradas dentro das funções são denominadas de variáveis locais. No jogo da velha, cProsseguir e jogador são exemplos de variáveis locais da função principal e lin é variável local de ObterLinhaVálida. Uma variável local somente pode ser acessada na função onde foi declarada sendo invisível para as demais funções. São criadas a cada chamada da função e cessam de existir assim que a função é encerrada (o conteúdo não é mantido entre diversas chamadas). As variáveis que aparecem nos cabeçalhos das funções também são variáveis locais.

5 Funções Recursivas

Uma função é dita recursiva quando chama a si mesma. Um exemplo clássico é o fatorial. Para calcular o 5! fazemos 5*4! Para calcular o fatorial de 4, fazemos 4*3! e assim por diante. Observe que para obter o fatorial de 5, chamamos a própria função fatorial para calcular o valor de 4! que, por sua vez, chama a função fatorial para calcular 3! e assim por diante. Veja o exemplo abaixo.

1. //-----------------------------------------------------------------------------

2. // Programa: Fatorial.cpp

3. // Autor: Cesar Augusto Tacla

4. // Descrição: calcula o fatorial de um número.

5. //-----------------------------------------------------------------------------

6.

7. #include "tradutor.h"

8.

9. // Protótipos das Funções

10. inteiro Fatorial( inteiro valor )

11.

12. //-----------------------------------------------------------------------------

13. // Funcao: Fatorial

14. // Descricao: retorna o fatorial de um número inteiro.

15. //-----------------------------------------------------------------------------

16. inteiro Fatorial( inteiro valor )

17. inicio

18. se ( valor > 1 )

19. retorne valor * Fatorial ( valor - 1 );

20. senao

21. retorne 1;

22. fim

23.

24. //-----------------------------------------------------------------------------

25. // Funcao: Principal

26. //-----------------------------------------------------------------------------

27. naoRetornaDado principal ( )

28. inicio

29. inteiro iVlr;

30.

31. escreva "\nFATORIAL\n";

32. escreva "\nValor ? ";

33. leia iVlr;

34. escreva "\nFatorial = ";

35. escreva Fatorial( iVlr );

36. getch( );

37. fim

Métricas de Qualidade de Programas

Funcionalidade, Coesão, Acoplamento,

Compilador Borland C++ 3.1

1 Instruções para Editar/Compilar/Executar um Programa

1. Configuração Inicial

1. ::= \\rle_server\publica\tacla\algo

2. Crie um diretório (denominado a partir de agora) para colocar seus exercícios. Por exemplo, você pode criar um diretório chamado A:\algo

3. Copie para o arquivo tradutor.h que está no .

4. Execute o programa Borland C++.

5. No menu Options ( Directories acrescente ;a:\algo no campo Include Directories.

2. Edição de um novo programa

1. File ( New para abrir uma janela limpa de edição.

2. Digite o código fonte.

3. Salve no preferencialmente com um nome de até 8 caracteres ,sem acentuação e sem símbolos especiais.

3. Abrindo um programa já digitado

1. File ( Open

2. Digite o nome do programa a ser carregado

4. Compilação de um programa

1. Compile ( Make ou tecle F9 (compilação + linkedição)

2. Veja as mensagens de erro de sintaxe (erros de compilação)

3. Corrija cada um dos erros, clicando sobre a mensagem e alterando a linha do programa com erro.

4. Salve

5. Repita o processo até que não existam mais erros.

5. Execução de um programa

1. Run ( Run ou tecle [CTRL] [F9]. Uma outra opção, é abrir uma janela DOS, posicionar no diretório onde o arquivo .exe foi criado e digitar o nome do programa. Se estiver rodando Borland C para Windows uma janela será aberta automaticamente para o programa. Caso esteja trabalhando com a versão DOS, ele trabalhará com a tela cheia e ao final da execução retornará para o Borland C. Para visualizar os resultados do programa pressione [ALT] [F5].

6. Execução Passo a Passo (Debug)

1. Para executar passo a passo use a tecla F8 (step over) e F7 (step into)

2. Para visualizar o valor de uma variável use uma das opções seguintes:

1. [ALT] [F4] Inspect: mostra o valor da variável naquele instante

2. [CTRL] [F4] Evaluate/Modify: mostra o valor da variável e permite modificar o conteúdo

3. [CTRL] [F7] Watch: mostrador de valores de variáveis. (Add: adiciona uma variável ao mostrador; Delete: retira)

Referências Bibliográficas

Este texto foi baseado nas seguintes bibliografias:

[1] Sucheuski, M. Desenvolvedor Profissional - Algoritmos, editora Lísias, 1996.

[2] Guimarães, A. M.; Lages, N. A. C.; Algoritmos e Estruturas de Dados, LTC, 1985.

[3] Achraf, O. Anotações de Aula.

-----------------------

10 em binário

rBim2

rBim1

rNota1

rNota2

importante: não confunda o símbolo de atribuição "=" com o relacional "==".

iCodigo[0]

iCodigo[2]

iCodigo[1]

cLetra[0][1]

rNota [1]

rNota [0]

cLetra[0][0]

cLetra[0][2]

cLetra[1][2]

cLetra[1][1]

cLetra[1][0]

TransformarPara

Farenheit

Temperatura

Celsius (real)

Temperatura

Farenheit(real)

TransformarPara

Celsius

Temperatura

Farenheit (real)

Temperatura

Celsius (real)

Temperatura

Farenheit(real)

Temperatura

Celsius (real)

TransformarPara

Farenheit

Temperatura

Celsius (real)

Temperatura

Farenheit (real)

TransformarPara

Celsius

linha (int)

jogador(int)

simbolo(car)

Principal

result (int)

simbolo(car)

ptos jog1 (int),

ptos jog2 (int)

simbolo jog1 (car),

símbolo jog2 (car)

principal

MostrarTabuleiro

LimparTabuleiro

VerificarResultado

ObterJogadaVálida

ObterLinhaVálida

ObterColunaVálida

coluna (int)

................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download