You are on page 1of 105

Faculdade SATC

Técnicas de Programação I
Algoritmos

Engenharias Elétrica e Mecânica

Profº.: Giovani Martins Cascaes


giovani.cascaes@satc.edu.br

http://www.satc.edu.br/gcascaes/

versão 1.06.105

2010/2011
Acontece que é muito difícil inventar uma teoria que descreva o
universo de uma só vez. Pelo contrário, decompomos o problema
em pedaços e inventamos várias teorias parciais. Cada uma
dessas teorias parciais descreve e prevê uma determinada e
limitada classe de observações, desconsiderando os efeitos de
outras quantidades, ou representando-os por simples conjuntos de
números. É possível que este enfoque esteja inteiramente errado.
Se tudo no universo depender de tudo o mais de uma maneira
fundamental, poderia ser impossível chegar mais perto de uma
solução completa através da investigação de partes isoladas do
problema. Ainda assim, foi desta maneira que fizemos progresso
no passado.

HAWKING e MLODINOW – Uma nova história do tempo


Sumário
Listas de figuras.............................................................................................................. 5
Lista de tabelas ............................................................................................................... 6
1 Introdução .................................................................................................................... 7
1.1 Definições de algoritmos ........................................................................................ 8
1.2 Formas de representações de algoritmos ................................................................ 8
1.2.1 Descrição narrativa .......................................................................................... 9
1.2.2 Fluxogramas .................................................................................................. 10
1.2.3 Português estruturado ou pseudocódigo ........................................................ 11
2 Variáveis, expressões, funções, atribuições, entrada e saída ................................. 15
2.1 Variáveis............................................................................................................... 15
2.1.1 Tipos de variáveis.......................................................................................... 16
2.2 Exercícios propostos............................................................................................. 19
2.3 Expressões ............................................................................................................ 20
2.3.1 Expressões Aritméticas.................................................................................. 20
2.3.2 Expressões Relacionais.................................................................................. 21
2.3.3 Expressões Lógicas........................................................................................ 22
2.3.4 Prioridade de operadores ............................................................................... 24
2.4 Funções primitivas................................................................................................ 24
2.5 Atribuições............................................................................................................ 25
2.6 Saída de dados ...................................................................................................... 28
2.7 Entrada de dados................................................................................................... 31
2.8 Exercícios propostos............................................................................................. 34
3 Comandos de controle de fluxo ................................................................................ 38
3.1 Seqüência ou bloco............................................................................................... 38
3.2 Seleção.................................................................................................................. 40
3.3 Seleção entre múltiplas escolhas .......................................................................... 44
3.4 Exercícios propostos............................................................................................. 50
3.5 Estruturas de repetições ........................................................................................ 55
3.5.1 Enquanto........................................................................................................ 55
3.5.2 Faca enquanto ................................................................................................ 57
3.5.3 Para ................................................................................................................ 59
3.6 Exercícios propostos............................................................................................. 65
4 Modularização ........................................................................................................... 70
4.1 Funções................................................................................................................. 70
4.1.1 Exercícios propostos...................................................................................... 78
4.2 Funções sem retorno ............................................................................................. 80
4.2.1 Exercícios propostos...................................................................................... 83
5 Estruturas e classes.................................................................................................... 85
5.1 Estruturas .............................................................................................................. 85
5.1.1 Definindo e declarando estruturas ................................................................. 86
5.1.2 Acessando os membros de estruturas ............................................................ 88
5.1.3 Estruturas mais complexas ............................................................................ 89
5.1.4 Exercícios propostos...................................................................................... 92
5.2 Classes .................................................................................................................. 92
5.2.1 Programas desestruturados ............................................................................ 92
5.2.2 Programas estruturados.................................................................................. 92
5.2.3 Programas orientados a objetos ..................................................................... 93
5.2.4 Declarando classes......................................................................................... 94
5.2.5 Permitindo o acesso aos membros da classe ................................................. 96
5.2.6 Exercícios propostos...................................................................................... 98
6 Mini Manual do C Quietly...................................................................................... 100
Bibliografia.................................................................................................................. 105

Obs.: Os exercícios presentes nas listas em cada capítulo


desta, foram retirados ou adaptados de livros e páginas
da internet e pertencem a seus respectivos donos.
Listas de figuras

Figura 1.1 – Etapas que antecedem o desenvolvimento de programas. .................... 7


Figura 1.2 – Fluxograma cálculo do Triplo de um Número. .................................... 11
Figura 3.1 – Fluxograma para estrutura SE. ............................................................. 41
Figura 3.2 – Fluxograma para estrutura SE SENAO. .............................................. 42
Figura 3.3 – Fluxograma para estrutura ESCOLHA CASO. .................................. 48
Figura 3.4 – Fluxograma para estrutura ENQUANTO............................................ 55
Figura 3.5 – Fluxograma para estrutura FACA ENQUANTO................................ 58
Figura 3.6 – Fluxograma para estrutura PARA........................................................ 60
Figura 5.1 – Um retângulo representado no plano cartesiano. ................................ 90
Figura 5.2 – Algoritmo desestruturado. ..................................................................... 92
Figura 5.3 – Algoritmo modular.................................................................................. 93
Figura 5.4 – Algoritmo orientados a objetos. ............................................................. 93
Figura 6.1 – Iniciando o C Quietly com um novo algoritmo. ................................. 100
Figura 6.2 – Novo código-fonte em linguagem C. .................................................... 101
Figura 6.3 – Compilando um código-fonte............................................................... 102
Figura 6.4 – Término da compilação do código-fonte. ............................................ 102
Figura 6.5 – Executando o programa. ...................................................................... 103
Figura 6.6 – Saída de execução do programa. ......................................................... 103
Figura 6.7 – Inserindo novas palavras-chave........................................................... 104
Lista de tabelas

Tabela 2.1 – Exemplos de nomes de variáveis............................................................ 16


Tabela 2.2 – Operadores aritméticos .......................................................................... 20
Tabela 2.3 – Operadores relacionais........................................................................... 21
Tabela 2.4 – Operadores lógicos.................................................................................. 22
Tabela 2.5 – Conjunção................................................................................................ 22
Tabela 2.6 – Disjunção ................................................................................................. 23
Tabela 2.7 – Negação .................................................................................................... 23
Tabela 2.9 – Caracteres de conversão para função imprima ................................... 28
Tabela 2.10 – Caracteres de controle.......................................................................... 29
Tabela 2.11 – Caracteres de conversão para função leia .......................................... 31
1 Introdução

A automatização de tarefas é um aspecto marcante da sociedade moderna. O


aperfeiçoamento tecnológico alcançado, com respeito a isto, teve como elementos
fundamentais a análise e a obtenção de descrições da execução de tarefas em termos de
ações simples o suficiente, tal que pudessem ser automatizadas por uma máquina
especialmente desenvolvida para este fim, o Computador.
Em ciência da computação houve um processo de desenvolvimento simultâneo e
interativo de máquinas (hardware) e dos elementos que gerenciam a execução
automática (software) de uma dada tarefa. E essa descrição da execução de uma tarefa,
como considerada acima, é chamada Algoritmo.
Lógica de programação é a técnica de encadear pensamentos para atingir
determinado objetivo. Quando há um problema e o objetivo é solucioná-lo, é necessário
ordenar o pensamento de forma lógica durante a elaboração das ações a serem seguidas
para solucionar o problema. Sendo assim, algoritmo não é a solução do problema (fig.
1.1), mais a maneira de representar a solução do problema criada por cada indivíduo. Os
caminhos que levam a solução de um determinado problema podem ser inúmeros,
estando, assim, a cargo de cada pessoa desenvolver seu raciocínio lógico na elaboração
de soluções criativas e inovadoras.

Problema

Solução

Algoritmo

Figura 1.1 – Etapas que antecedem o desenvolvimento de programas.

O programa escrito em uma linguagem de programação não é nada mais do que


a representação, obedecendo à sintaxe e semântica da linguagem, do algoritmo que
representa a solução do problema proposta pelo programador.

7
O objetivo desse curso é a Lógica de Programação dando uma base teórica e
prática, suficientemente boa, para que, o aluno domine os algoritmos e esteja habilitado
a aprender uma linguagem de programação.

1.1 Definições de algoritmos

“O conceito central da programação é o conceito de algoritmos, isto é,


programar é basicamente construir algoritmos”.
É a descrição, de forma lógica, dos passos a serem executados no cumprimento
de determinada tarefa.
“O algoritmo pode ser usado como uma ferramenta genérica para representar a
solução de tarefas independente do desejo de automatizá-las, mas em geral está
associado ao processamento eletrônico de dados, onde representa o rascunho para
programas (Software)”.
“Serve como modelo para programas, pois sua linguagem é intermediária à
linguagem humana e às linguagens de programação, sendo então, uma boa ferramenta
na validação da lógica de tarefas a serem automatizadas”.
“Um algoritmo é uma receita para um processo computacional e consiste de uma
série de operações primitivas, interconectadas devidamente, sobre um conjunto de
objetos. Os objetos manipulados por essas receitas são as variáveis”.
É a forma pela qual se descreve soluções de problemas do mundo real, a fim de
serem implementadas utilizando os recursos do mundo computacional. Como este
possui severas limitações em relação ao mundo real, exige-se que, sejam impostas
algumas regras básicas na forma de solucionar os problemas, para que, possamos
utilizar os recursos de hardware e software disponíveis. Pois, os algoritmos, apesar de
servirem para representar a solução de qualquer problema, no caso do Processamento de
Dados, eles devem seguir as regras básicas de programação para que sejam compatíveis
com as linguagens de programação.

1.2 Formas de representações de algoritmos

Existem diversas formas de representação de algoritmos, mas não há um


consenso com relação a melhor delas. O critério usado para classificar hierarquicamente
estas formas está diretamente ligado ao nível de detalhe ou, inversamente, ao grau de
abstração oferecido.
Algumas formas de representação de algoritmos tratam os problemas apenas em
nível lógico, abstraindo-se de detalhes de implementação muitas vezes relacionados
com alguma linguagem de programação específica. Por outro lado existem formas de
representação de algoritmos que possuem uma maior riqueza de detalhes e muitas vezes
acabam por obscurecer as idéias principais do algoritmo, dificultando seu entendimento.

Dentre as formas de representação de algoritmos mais conhecidas pode-se citar:

i) Descrição Narrativa;
ii) Fluxogramas;
iii) Pseudocódigo, também conhecido como Português Estruturado.

8
1.2.1 Descrição narrativa

Nesta forma de representação os algoritmos são expressos diretamente em


linguagem natural. Como exemplo, têm-se os algoritmos a seguir:

Exemplo 1.1 – Algoritmos em linguagem natural.

Algoritmo 1 - Troca de um pneu furado

Afrouxar ligeiramente as porcas


Suspender o carro
Retirar as porcas e o pneu
Colocar o pneu reserva
Apertar as porcas
Abaixar o carro
Dar o aperto final nas porcas

Algoritmo 2 - Cálculo da média de um aluno

Obter as suas três notas de provas


Calcular a média aritmética
Se (média for maior que 7)
Aluno foi aprovado
Senão
ele foi reprovado

Algoritmo 3 - Troca de lâmpadas queimadas

Se (lâmpada estiver fora de alcance)


Pegar escada;
Pegar lâmpada;
Tirar lâmpada queimada;
Colocar lâmpada nova;

Algoritmo 4 – Realizar uma prova

Ler a prova;
Pegar a caneta;
Enquanto ((houver questão em branco) e (tempo não terminou)) faça
Se (souber a questão)
Resolvê-la;
Senão
Pular para próxima;
Entregar a prova.

9
Exercícios propostos

Exercício 1.1 – Um homem precisa atravessar um rio com um barco que possui
capacidade de carregar apenas ele mesmo e mais uma de suas três
cargas, que são: um lobo, um bode e um fardo de capim. O que o
homem deve fazer para conseguir atravessar o rio sem perder suas
cargas?

Exercício 1.2 – Construa a seqüência/solução que mova três discos de uma Torre de
Hanói, que consiste em três hastes (a-b-c), uma das quais serve de
suporte para três discos de tamanhos diferentes (1-2-3), os menores
sobre os maiores. Pode-se mover um disco de cada vez para qualquer
haste, contanto que nunca seja colocado um disco maior sobre um
menor. O objetivo é transferir os três discos para outra haste.

a b c

Exercício 1.3 – Três jesuítas e três canibais precisam atravessar um rio; para tal,
dispõem de um barco com capacidade para duas pessoas. Por medidas
de segurança não se permite que em alguma margem a quantidade de
jesuítas seja inferior à de canibais. Qual a seqüência de passos que
permitiria a travessia com segurança?

Esta representação é pouco usada na prática porque o uso da linguagem natural


muitas vezes dá oportunidade a más interpretações, ambigüidades e imprecisões. Por
exemplo, a instrução “afrouxar ligeiramente as porcas” no algoritmo da troca de pneus
está sujeita a interpretações diferentes por pessoas distintas. Uma instrução mais precisa
seria: “afrouxar a porca, girando-a 30º no sentido anti-horário”.

1.2.2 Fluxogramas

É a utilização de símbolos gráficos para representar algoritmos. Nos


fluxogramas existem símbolos padronizados para início, entrada de dados, cálculos,
saída de dados, fim, etc.

10
Exemplo 1.2 – Fluxograma para calcular o triplo de um número qualquer, fornecido
pelo usuário.

Início

Num

Triplo = Num * 3

Triplo

Fim

Figura 1.2 – Fluxograma cálculo do Triplo de um Número.

1.2.3 Português estruturado ou pseudocódigo

Esta forma de representação de algoritmos é rica em detalhes, como a definição


dos tipos das variáveis usadas no algoritmo. Por assemelhar-se bastante à forma em que
os programas são escritos, encontra muita aceitação no meio acadêmico. Na verdade,
esta representação é suficientemente geral para permitir a tradução de um algoritmo nela
representado para uma linguagem de programação específica, praticamente de maneira
direta.
Após a criação do algoritmo que representa a solução do problema, o mesmo
deverá ser testado em papel ou em uma ferramenta que interprete as ações do algoritmo,
com a finalidade de validar a solução descrita no algoritmo.
Cada ação contida nas linhas do algoritmo pode ser chamada de instrução.
Desta maneira, pode-se dizer que um algoritmo é formado por um conjunto finito de
instruções. E um programa o que é?
Um programa de computador nada mais é do que a representação do algoritmo
numa linguagem de programação, seja ela C, Pascal, Delphi, Cobol, etc. Como a
maioria das linguagens de computadores está escrita em inglês, a tarefa dos
programadores consiste em traduzir os algoritmos escritos em português para a
linguagem de programação, em inglês.

A forma geral da representação de um algoritmo na forma de pseudocódigo


adotada nesta apostila é a seguinte:

11
#incluir biblioteca
/* 1. Declaração das bibliotecas utilizadas */

#definir constantes ou macros


/* 2. Declaração de constantes, entre outras */
principal () /* 3. Função principal do algoritmo */
inicio /* 4. Início do escopo / bloco principal */

/* 5. Declaração e classificação de variáveis */

/* 6. Iniciar as variáveis */
/* 7. Solicitar a entrada de dados ao usuário */
/* 8. Entrada de dados */
/* 9. Processamento / Cálculos */
/* 10. Saída de informações */
/* 11. Retorno de erro ou Ok */

fim /* 12. Final do escopo / bloco principal */

incluir é uma palavra que indica a inclusão de bibliotecas no algoritmo;

definir consiste em uma porção opcional onde são declaradas as constantes


globais usadas no algoritmo;

principal é uma palavra que indica o início da execução de um algoritmo em


forma de pseudocódigo, com a sintaxe próxima da linguagem de programação C;

variáveis consistem em uma porção “opcional” onde são declaradas as


variáveis usadas no algoritmo;

inicio e fim são respectivamente as palavras que delimitam o início e o


término do conjunto de instruções do corpo do algoritmo e em todas as demais
estruturas composta por uma seqüência ou bloco de instruções.

Comentários /*...*/ utilizados ao longo do algoritmo, servem como


informações adicionas e que facilitam o entendimento da solução proposta. Não são
analisados pelas ferramentas de desenvolvimento de programas, como o C. O C Quietly
também ignora comentários durante o processamento.

O algoritmo do cálculo da média de um aluno, na forma de um pseudocódigo, é


apresentado a seguir (ex. 1.3).

Exemplo 1.3 – Algoritmo para calcular a média aritmética simples de duas notas.
Inicialmente será mostrado como algoritmo generalizado e em seguida,
como deverá estar ao longo desta apostila. Usando a sintaxe da
linguagem C e o C Quietly.

12
Situação 1: Visto como algoritmo presente em vários livros de estrutura de dados
e algoritmos:

Algoritmo Calculo_Media

inteiro nota1, nota2;


real media;

Inicio
Leia(nota1, nota2);

media <- (nota1 + nota2)/2;

Se (media >= 7)
Então
Escreva (‘Aprovado‘)
Senão
Escreva (‘Reprovado‘);

Fim

Situação 2: Visto como algoritmo com a sintaxe da linguagem C e podendo ser


utilizado no C Quietly:

#incluir <stdio.h>
#incluir <conio.h>

principal ()
inicio

inteiro nota1, nota2;


real media;

leia("%d",&nota1);
leia("%d",&nota2);

media = (nota1 + nota2)/2.0;

se (media >= 7.0)


inicio
imprima ("Aprovado\n");
fim
senao
inicio
imprima ("Reprovado\n");
fim

getch(); /* Aguarda uma tecla para finalizar */

retorno (0);
fim

13
Para escrever algoritmos é preciso uma linguagem clara e que não deixe margem
a ambigüidades, para isto, deve-se definir uma sintaxe e uma semântica, de forma a
permitir uma única interpretação das instruções em um algoritmo. A sintaxe aqui
proposta, tende a uma maior proximidade com a linguagem C, mas ainda assim poderá
ser “convertida” para outras linguagens como exemplo a linguagem Pascal.

14
2 Variáveis, expressões, funções, atribuições, entrada e saída

Desenvolver algoritmos requer o conhecimento do conceito de alguns itens


indispensáveis na representação da solução de um problema qualquer. A compreensão
ou entendimento destes conceitos e das possibilidades de utilização de cada um dos
elementos acima, permite a precisa definição de quais elementos farão parte da solução
proposta durante a elaboração da mesma.
Na seqüência, é apresentado além dos conceitos de cada um dos itens anteriores
também, as formas de sua aplicação e uso em determinadas situações.

2.1 Variáveis

Toda variável é identificada por um nome ou identificador. Assim, por


exemplo, em um algoritmo para calcular a hipotenusa de um triângulo retângulo pelo
teorema de Pitágoras (a2 = b2 + c2), os identificadores a, b e c podem representar
as posições na memória (RAM ou memória principal) que armazenam o valor da
hipotenusa e dos catetos.
O conteúdo de uma variável pode ser de vários tipos: inteiro, real, caractere e
lógico, entre outros. Trabalharemos inicialmente com estes quatro tipos no C Quietly.
No C Quietly as variáveis serão definidas na parte inicial do algoritmo da
seguinte forma:

tipo_da_variavel nome_da_variavel ;

Exemplo 2.1 - Declarações de variáveis.

inteiro a;
real x;
char letra;
char nome[40]; /* Armazena até 40 caracteres */

Os identificadores representam os nomes escolhidos para rotular as variáveis, as


constantes e as funções, obedecendo as seguintes regras:

i) O primeiro caractere deve ser uma letra;


ii) Se houver outros caracteres, estes só poderão ser letra, algarismo e o _
(sublinha);

15
iii) Os nomes das variáveis escritas com letras maiúsculas são diferentes das
letras minúsculas. Assim, nota1 é diferente de NOTA1.
iv) Palavras chaves ou reservadas de cada linguagem também não podem ser
utilizadas, facilitando a conversão do algoritmo para o código fonte da
linguagem a ser utilizada.

A seguir (tab. 2.1), alguns exemplos de nomes de variáveis permitidos, além de


alguns dos erros que poderiam ser cometidos durante a escolha do nome de um
identificador, seja ele, uma variável, uma constante ou de funções.

Tabela 2.1 – Exemplos de nomes de variáveis


Nomes Válidos Nomes Não-Válidos
valor, IDADE, nota1, Nome 4mes /* inválido */
a, X, x
main /* inválido */
fim /* inválido para o C Quietly, pois
este o traduziria para } */

Declarar uma variável consiste em reservar espaço na memória principal (RAM)


do computador. Desta forma, um endereço de memória é alocado e pode-se ter acesso a
este endereço por meio do nome da variável. Esta é uma característica das linguagens de
alto nível como a linguagem C e Pascal.
Nos algoritmos destinados a resolver um problema no computador, cada variável
corresponde a uma posição de memória, cujo conteúdo pode variar ao longo do tempo
durante a execução do algoritmo/programa. Embora a variável possa assumir diferentes
valores, ela só pode armazenar um único valor a cada instante.

2.1.1 Tipos de variáveis

Os tipos de variáveis utilizados no algoritmo (representação da solução do


problema) dependem da finalidade do mesmo, mas, podem-se definir alguns tipos de
variáveis pelo fato de serem largamente utilizados e implementados na maioria das
linguagens de programação, sendo estes:

Numéricas

São variáveis que armazenam dados numéricos e estão divididas em duas


classes. A classe das variáveis inteiras é representada pelo tipo inteiro e a classe das
variáveis fracionárias pelo tipo real.

inteiro

Os números inteiros são aqueles que não possuem casas decimais, somente a
parte inteira é considerada. Estes podem ser positivos ou negativos.
As variáveis declaradas como inteiro não poderão receber valores fracionários,
somente valores inteiros. Ex.: 15, 56, -67, 0, para declarar uma variável
numérica do tipo inteiro, utilize:

16
inteiro a;
inteiro b;

ou

inteiro a,b;

real

Os números reais são aqueles que possuem além da parte inteira do número,
também a parte fracionária deste. Podendo ser positivo ou negativo.
Uma variável declarada como sendo do tipo real tem a capacidade de armazenar
o número completo, ou seja, parte inteira e fracionária deste. Ex.: 34.97, 6.5067,
-56.0, 10.1, para declarar uma variável numérica do tipo real, utilize:

real x;
real y;

ou

real x,y;

Caracteres

Os caracteres podem armazenar letras (‘a’..‘z’; ‘A’..‘Z’), números (‘0’..’9’) ou


outros caracteres especiais (‘@’,’#’, ‘$’, ‘%’, ‘*’, ‘\’, ...). Eles podem aparecer isolados
(tipo char), ou agrupados formando palavras/frases (tipo char[]).

char

Uma variável do tipo char, pode armazenar um único caractere e o mesmo


necessita estar entre ‘‘ (apóstrofo). E quando for necessário armazenar vários
caracteres? Há um outro tipo (string) tal qual outras linguagens? Em C ANSI, não. A
linguagem C, assim como o C Quietly, utilizam um arranjo ou vetor de caracteres,
definido como char [ ]. Para definir uma variável capaz de armazenar um caractere ou
outra para vários caracteres, proceda da seguinte maneira:

char ch; /* ch pode armazenar um único


caractere */
char endereco[40]; /* endereco pode armazenar até 40
caracteres */
char disciplina[TAMANHO]; /* disciplina pode armazenar até
TAMANHO caracteres, veja definição
de TAMANHO a seguir */

Lógicos

Também conhecido como tipo booleano. Pode representar apenas dois valores:
Verdadeiro ou Falso. Pode ser utilizado em algumas linguagens de programação com

17
outras denominações, tais como Sim/Não, True/False, 1/0, Verdadeiro/Falso.

Ao utilizarmos o C Quietly, e indiretamente a linguagem C, buscaremos outro


conceito antes de continuarmos com o tipo lógico: o conceito de constante simbólica.

Constante simbólica

A declaração de constantes nos algoritmos dá ao programador a facilidade de


utilizar o nome da constante como valor substituível em qualquer parte do algoritmo,
com a vantagem de defini-la em um único local. Seu valor permanece inalterado durante
toda execução do algoritmo/programa. Para se definir constantes, deve-se declará-las de
acordo com a sintaxe:

#definir nome_da_constante valor

Exemplo 2.2 – Definindo constantes simbólicas.

#definir TAMANHO 50
#definir MAX 100

#definir VERDADEIRO 1
#definir FALSO 0

e/ou

#definir TRUE 1
#definir FALSE 0

Utilizando a instrução #definir, pode-se representar um tipo de variável


lógica tratando-a como variável do tipo inteiro.

Exemplo 2.3 - Algoritmo com o uso de constantes simbólicas.

#incluir <stdio.h>
#incluir <conio.h>

#definir MEDIA_APROVADO 7

principal ()
inicio
inteiro nota1, nota2;
real media;

leia("%d",&nota1);
leia("%d",&nota2);

media = (nota1 + nota2)/2.0;

18
se (media >= MEDIA_APROVADO)
inicio
imprima ("Voce foi Aprovado\n");
fim
senao
inicio
imprima ("Voce foi Reprovado\n");
fim

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */

retorno (0);
fim

Exemplo 2.4 - Algoritmo com o uso de Variáveis inteiras.

#incluir <stdio.h>
#incluir <conio.h>

principal ()
inicio

inteiro num, dobro;

imprima("Entre com um numero: ");


leia("%d",&num);

dobro = num * 2;

imprima("%d, e seu dobro = %d\n",num,dobro);

imprima("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */
retorno(0);
fim

2.2 Exercícios propostos

Exercício 2.1 - Quais as palavras abaixo possuem nomes válidos para identificadores?
Válido/Inválido
Salario_Real ( ) ( )
TotalEmDolares ( ) ( )
Real ( ) ( )
Nota GrauA ( ) ( )
@Home ( ) ( )
Web@Home ( ) ( )
web ( ) ( )
Salário2010 ( ) ( )
Opção_Inicial ( ) ( )
Last ( ) ( )
4Ever ( ) ( )

19
2.3 Expressões

Um algoritmo tem como característica fundamental a capacidade de processar


dados. Processar dados significa realizar operações com estes dados. O uso de
operadores permite a realização de tais operações. Por exemplo, o símbolo + é um
operador que representa a operação aritmética de adição.
Uma expressão é um arranjo de operadores e operandos. A cada expressão
válida é atribuído um valor numérico. Como exemplo têm-se, 4 + 6 que é uma
expressão cujo valor resultante é 10.
Os operandos podem ser variáveis, constantes ou valores gerados por funções.
Os operadores identificam as operações a serem efetuadas sobre os operandos. Cada tipo
de dados possui um conjunto de operadores relacionados. Os operadores classificam-se
em unários e binários, conforme tenham um ou dois operandos, respectivamente.
Na solução da grande maioria dos problemas é necessário que as variáveis
tenham seus valores consultados ou alterados e, para isto, deve-se definir um conjunto
de operações a serem utilizadas nas expressões, sendo eles:

2.3.1 Expressões Aritméticas

São aquelas cujo resultado da avaliação é do tipo numérico, seja ele inteiro ou
fracionário (real). Somente o uso de operadores aritméticos (tab. 2.2) e variáveis
numéricas é permitido em expressões aritméticas.

Tabela 2.2 – Operadores aritméticos


Símbolo Significado Matemática
+ Adição +
* Multiplicação x
- Subtração ou inversor do sinal -
/ Divisão ÷
resto Resto da divisão de inteiros

Exemplo 2.5 - Algoritmo para obter e realizar diversas operações com dois números.

#incluir <stdio.h>
#incluir <conio.h>

principal ()
inicio
inteiro a, b, r;
real r2;

imprima ("Digite o primeiro numero: ");


leia ("%d",&a);
imprima ("Digite o segundo numero: ");
leia ("%d",&b);

r = a + b;
imprima ("A soma de %d e %d = %d\n",a,b,r);

20
r2 = (real) a / b;
imprima ("A Divisao de %d e %d = %0.2f\n",a,b,r2);

r = a - b;
imprima ("A subtracao de %d e %d = %d\n",a,b,r);

r = a * b;
imprima ("A multiplic de %d e %d = %d\n",a,b,r);

r = a / b;
imprima ("A Divisao int %d e %d = %d\n",a,b,r);

r = a resto b;
imprima ("O Resto Div de %d e %d = %d\n",a,b,r);

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */

retorno (0);
fim

Obs.: A divisão de um número inteiro por outro, também inteiro, é sempre um


número inteiro; se o resultado for fracionário, este será truncado.

2.3.2 Expressões Relacionais

Os operadores relacionais (tab. 2.3) são utilizados para efetuar a comparação


entre dados de mesmo tipo, relacionando variáveis ou expressões, resultando em um
valor lógico (Verdadeiro ou Falso).

Exemplos:

A == B; A é igual a B
C != D; C é diferente de D
F >= E; F é maior ou igual a E
J < H; J é menor que H
X <= 5; X é menor ou igual a 5
3 > W; 3 é maior que o valor da variável W

Tabela 2.3 – Operadores relacionais


Operador Operação Matemática
== Igual =
!= Diferente ≠
< Menor que <
> Maior que >
<= Menor ou Igual ≤
>= Maior ou Igual ≥
Exemplo 2.6 - Algoritmo com o uso de operadores relacionais.

21
#incluir <stdio.h>
#incluir <conio.h>

principal ()
inicio

inteiro idade;

imprima("Entre com sua idade: ");


leia("%d",&idade);

se (idade >= 18)


inicio
imprima ("Voce já pode fazer sua CNH\n");
fim

imprima("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */
retorno(0);
fim

2.3.3 Expressões Lógicas

São utilizadas para avaliar expressões lógicas. Os operadores lógicos


fundamentais estão relacionados na tabela seguinte (tab. 2.4). As tabelas verdade de
cada um dos operadores lógicos são apresentadas logo a seguir.

Tabela 2.4 – Operadores lógicos


Operador Operação Matemática
&& conjunção e
|| disjunção ou
! negação nao

Tabela verdade do operador &&

Suponha que uma empresa da região esta fazendo uma entrevista com quatro
pessoas, para o preenchimento de uma vaga de programador sênior. Cada pessoa irá
responder 1 se domina a linguagem e 0 caso não seja de seu domínio.

Tabela 2.5 – Conjunção


Você conhece a Você conhece a Saída
linguagem C? linguagem Pascal?
1 1 1
1 0 0
0 1 0
0 0 0

22
Irá conseguir o trabalho o candidato que dominar ambas as linguagens exigidas
para o preenchimento da vaga. O operador && (tab. 2.5) somente considera válida a
expressão em que todas as respostas são verdadeiras.

Tabela verdade do operador ||

Suponha que a mesma empresa disponha de uma outra vaga de programador


júnior e exige que o candidato conheça pelo menos uma linguagem de computador.
Cada pessoa irá responder 1 se domina a linguagem e 0 caso não seja de seu domínio.

Tabela 2.6 – Disjunção


Você conhece a Você conhece a Saída
linguagem C++? linguagem PHP?
1 1 1
1 0 1
0 1 1
0 0 0

Irá conseguir o trabalho o candidato que dominar ao menos uma das linguagens
exigidas para o preenchimento da vaga. O operador || (tab. 2.6) considera válida a
expressão em que pelo menos uma resposta seja verdadeira.

Tabela verdade do operador !

Tabela 2.7 – Negação


Você conhece Saída
Algoritmos?
1 0
0 1

O operador ! (tab. 2.7) inverte a saída.

Exemplo 2.7 - Algoritmo com o uso de operadores lógicos e relacionais.

#incluir <stdio.h>
#incluir <conio.h>

principal ()
inicio

inteiro idade;
char sexo;

imprima("Qual o seu sexo: ");


leia("%c",&sexo);
imprima("Qual a sua idade: ");
leia("%d",&idade);

23
se (idade >= 18 && sexo == 'M')
inicio
imprima ("Voce precisa alistar-se!\n");
fim

imprima("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */
retorno(0);
fim

2.3.4 Prioridade de operadores

Durante a execução de uma expressão que envolve vários operadores, é


necessário existir certas prioridades, caso contrário pode-se obter valores que não
representam o resultado esperado. A maioria das linguagens de programação utiliza as
seguintes prioridades de operadores:

i) Efetuar operações embutidas em parênteses “mais internos”


ii) Efetuar funções
iii) Efetuar resto, multiplicação e/ou divisão
iv) Efetuar adição e/ou subtração
v) Operadores relacionais
vi) Operadores lógicos

Obs.: O programador tem plena liberdade para incluir novas variáveis,


operadores ou funções para adaptar o algoritmo as suas necessidades,
lembrando sempre, de que, estes devem ser compatíveis com a linguagem
de programação a ser utilizada.

2.4 Funções primitivas

Uma linguagem de programação oferece um conjunto de funções pré-definidas,


que são usadas com vários tipos de dados simples. As funções estão intimamente
ligadas ao conceito de função (ou fórmula) matemática, na maioria das vezes,
necessitam de dados como parâmetro (dados de entrada). Em algoritmos utilizam-se as
funções facilmente encontradas nas principais linguagens de programação. Veja (tab.
2.8) algumas dessas funções a seguir.

Tabela 2.8 – Funções Primitivas


Função Finalidade
sen (x); Seno do ângulo x
cos (x); Co-seno do ângulo x
tan (x); Tangente do ângulo x
abs (x); Valor absoluto de x
potencia (y,x); Eleva y a x
raiz (x); Raiz quadrada de x
log (x) Logaritmo Natural de x

24
Exemplo 2.8 – Usando funções pré-definidas, para determinar o valor da hipotenusa.

#incluir <stdio.h>
#incluir <conio.h>
#incluir <math.h>

principal ()
inicio

inteiro ladoA, ladoB;


real Q1, Q2, hipotenusa;

imprima ("Entre com o cateto A: ");


leia ("%d",&ladoA);
imprima ("Entre com o cateto B: ");
leia ("%d",&ladoB);

Q1 = potencia(ladoA,2);
Q2 = ladoB * ladoB;
hipotenusa = raiz(Q1 + Q2);

imprima ("CA = %d e CB = %d\n",ladoA,ladoB);


imprima ("Hipo = %0.4f\n",hipotenusa);

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */

retorno (0);
fim

Obs.: O teorema de Pitágoras foi citado anteriormente (seção 2.1).

2.5 Atribuições

Um comando de atribuição altera o conteúdo de um identificador (lado


esquerdo) pelo valor resultante da expressão (lado direito). A variável e a expressão
devem ser do mesmo tipo, exceto no caso em que a variável é do tipo real e o resultado
da expressão é do tipo inteiro, quando o valor inteiro da expressão é transformado em
real.
A operação de atribuição permite que se forneça um valor a uma certa variável.
Caso seja atribuída uma expressão à variável, será armazenado o resultado daquela
expressão. Se for atribuída uma outra variável, será armazenado o conteúdo daquela
variável. Para a operação de atribuição, utiliza-se a seguinte sintaxe:

variavel = valor ou expressão ;

Exemplo 2.9 – Atribuição de um valor a uma variável inteira.

y = 6;

25
Lê-se da seguinte forma:

A variável y recebe o valor 6 ou o valor 6 é atribuído a variável y.

O computador por sua vez:

Assume que o valor 6 deve ser armazenado (guardado, alocado) na memória,


em um local previamente reservado por meio da declaração da variável y.

Memória principal (RAM)

y
6

Exemplo 2.10 – Atribuição de um valor e de uma expressão envolvendo operandos


inteiros a uma variável do mesmo tipo.

x = 3;
z = y * x;

Lê-se da seguinte forma:

A variável z recebe o valor da multiplicação de y por x ou y multiplicado por x


é atribuído a variável z.

O computador por sua vez:

O resultado da multiplicação do conteúdo das variáveis y e x armazenados


na memória, será alocado na variável z.

Memória principal (RAM)

y x z
6 3 18

No comando de atribuição, a variável e valor/expressão devem ser do mesmo


tipo, exceto nos seguintes casos:

i) A variável sendo real, a expressão ou a outra variável podem ser do tipo


inteiro;
ii) A variável sendo char[], a expressão ou a outra variável podem ser do tipo
char.

26
Exemplo 2.11 – Trocando o conteúdo das variáveis a e b com auxílio de uma variável
temporária.

a = 2;
b = 3; /* Passo 1 */
temp = a;

a = b; /* Passo 2 */
b = temp; /* Passo 3 */

Memória (RAM) Memória (RAM) Memória (RAM)

a b temp a b temp a b temp


2 3 2 3 3 2 3 2 2

Passo 1 Passo 2 Passo 3

Exemplo 2.12 – Incrementando e decrementando as variáveis a e b com auxílio dos


operadores ++ e --.

a = 5;
b = 7; /* Passo 1 */

a++; /* Passo 2 */
b--; /* Passo 3 */

Memória (RAM) Memória (RAM) Memória (RAM)

a b a b a b
5 7 6 7 6 6

Passo 1 Passo 2 Passo 3

No algoritmo é preciso representar a troca de informações que ocorrerá entre o


mundo da máquina e o nosso mundo, para isso, deve-se utilizar comandos de entrada e
saída, sendo que, no algoritmo esses comandos representam apenas a entrada e a saída
da informação, independente do dispositivo utilizado (teclado, discos, impressora,
monitor, ...).

27
2.6 Saída de dados

Um comando de saída serve para que o algoritmo mostre ao usuário os


resultados desejados. A unidade de saída padrão é o monitor de vídeo, podendo ser
também a impressora ou uma memória auxiliar como o disco rígido.

imprima (“texto, conversao e controle”, variável, constante ou expressão );

Os identificadores contidos na lista, devem estar separados por vírgula.


Considerando a unidade de saída padrão, o monitor de vídeo, no algoritmo o
comando seria:

imprima ("texto");
ou
imprima ("texto %caractere",variavel);
ou
imprima ("texto %caractere",constante);
ou
imprima ("texto %caractere",expressao);

Onde %caractere pode ser substituído por qualquer um dos caracteres de


conversões apresentados (tab. 2.9) a seguir.

Tabela 2.9 – Caracteres de conversão para função imprima


Conversão Finalidade
%c Imprime o conteúdo da variável com representação ASCII
%d Imprime o conteúdo da variável com representação decimal com sinal
%u Imprime o conteúdo da variável com representação decimal sem sinal
%o Imprime o conteúdo da variável com representação octal sem sinal
%x Imprime o conteúdo da variável com representação hexadecimal sem
sinal
%f Imprime o conteúdo da variável com representação com ponto decimal
%e Imprime o conteúdo da variável com representação em notação
científica (exponencial)
%g Formato geral, escolhe a representação mais curta entre %f e %e

Além dos caracteres de conversão, também é possível utilizar-se caracteres de


controle (tab. 2.10) por meio da \ (contra barra) seguida do caractere correspondente à
ação desejada. Desta maneira, pode-se mover o cursor para a linha seguinte (\n),
separar dados usando tabulações (\t) entre eles e representar caracteres utilizados na
sintaxe do comando de saída, tal qual aspas ou a própria contra barra, utilizada em
conjunto com os caracteres de controle.

28
Tabela 2.10 – Caracteres de controle
Caractere de Controle Finalidade
\n Nova linha
\t Tabulação
\b Retrocesso
\r Retorno de carro
\f Salto de página
\a Sinal sonoro
\\ Contra barra
\’ Apóstrofo
\” Aspas
\0 O caractere NUL

Com imprima o cursor permanece na mesma linha após a execução do


comando, utilizando-se o caractere de controle (\n) move-se o cursor para a próxima
linha.

Exemplo 2.13 – Mostrando os conteúdos das variáveis a e b após sua declaração


seguida de atribuições de valores inteiros as mesmas, além de realizar e
exibir a soma entre elas.

#incluir <stdio.h>
#incluir <conio.h>

principal ()
inicio

inteiro a, b;

a = 5;
b = 10;

imprima ("A = %d e B = %d\n",a,b);


imprima ("Soma = %d\n",a + b);

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */

retorno (0);
fim

Para o caso de utilizar-se de variáveis do tipo real, os valores são mostrados na


notação exponencial, em um campo de 6 posições, a menos que uma formatação seja
especificada, veja exemplo na seqüência.

Exemplo 2.14 – Mostrando a média aritmética simples entre as variáveis A e B do


exemplo anterior.

29
#incluir <stdio.h>
#incluir <conio.h>

principal ()
inicio

inteiro a, b;
real m;

a = 5;
b = 10;

m = (a + b)/2.0;

imprima ("A = %d e B = %d\n",a,b);


imprima ("Media = %e\n",m);
imprima ("Media = %f\n",m);
imprima ("Media = %.2f\n",m);

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */

retorno (0);
fim

Memória (RAM)

a b m
5 10 7.5

Vídeo

A = 5 e B = 10
Media = 7.50000e+00
Media = 7.500000
Media = 7.50
pressione qualquer tecla...

Na formatação, se a variável for real especifica-se o total de posições ocupadas e


a quantidade de casas decimais. Se for inteira, somente total de posições.

30
2.7 Entrada de dados

Um comando de entrada serve para que o algoritmo solicite dados no momento


em que o mesmo está sendo executado. Esses dados fornecidos serão armazenados em
variáveis na memória. Em geral a unidade de entrada é o teclado, podendo também ser
uma memória auxiliar como o disco rígido.

leia (“conversao”, variavel1, variavel2, ... );

Os identificadores contidos na lista, devem estar separados por vírgula.


Considerando a unidade de entrada padrão, o teclado, no algoritmo o comando
seria:
leia ("%conversao",&variavel);
ou
leia ("%conversao %conversao",&var1, &var2, ...);

Onde %conversao deve ser substituído por um dos caracteres de controle (tab.
2.11) a seguir. Cada variável ou lista de variáveis deve vir precedida por um caractere &
(“E” comercial), que indica o fornecimento do endereço de memória representado pelo
identificador (nome da variável).

Tabela 2.11 – Caracteres de conversão para função leia


Conversão Finalidade
%c Espera-se um único caractere na entrada
%d Espera-se um inteiro decimal na entrada
%u Espera-se um inteiro decimal na entrada
%o Espera-se um inteiro octal na entrada
%x Espera-se um inteiro hexadecimal na entrada
%f Espera-se um número de ponto flutuante na entrada
%h Espera-se um inteiro curto na entrada
%s Espera-se uma cadeia de caracteres na entrada

Exemplo 2.15 – Desenvolver um algoritmo para obter as três notas de um aluno e


armazená-las na memória do computador por meio das variáveis
nota1, nota2 e nota3, estas devem ser capazes de guardar notas com
casas decimais.

#incluir <stdio.h>
#incluir <conio.h>

principal ()
inicio

real nota1, nota2, nota3;

31
leia ("%f%f%f",&nota1,&nota2,&nota3);

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */

retorno (0);
fim

No momento da execução do algoritmo com os comandos acima, o programa


mostra a tela do usuário e o cursor aparece esperando a digitação dos três valores que
devem ser separados por, pelo menos, um espaço em branco. Com uma única
(<enter>) confirmação ao final da digitação dos valores.

Vídeo

_ 3.5 7.8 8.4 <enter>

pressione qualquer tecla...

Assim, valor 3.5 será armazenado na variável nota1, o valor 7.8 em nota2
e o valor 8.4 em nota3.

No instante da solicitação de dados, podemos usar junto com o leia um comando


de saída (imprima) com a finalidade de emitir mensagens que orientem o usuário na
digitação dos dados.

Exemplo 2.16 – Algoritmo que calcula a média aritmética simples de três notas com
mensagens indicando ao usuário quais dados fornecer.

#incluir <stdio.h>
#incluir <conio.h>

principal ()
inicio

real nota1, nota2, nota3;


real media;

imprima ("Entre com a primeira nota: ");


leia ("%f",&nota1);
imprima ("Entre com a segunda nota: ");
leia ("%f",&nota2);
imprima ("Entre com a terceira nota: ");
leia ("%f",&nota3);

media = (nota1 + nota2 + nota3)/3.0;

32
imprima ("\nMedia Final = %.2f\n",media);

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */

retorno (0);
fim

A seguir, vê-se como seria a entrada das notas e a exibição da média aritmética
simples após seu cálculo pelo computador.
Inicialmente é mostrada a primeira mensagem Entre com a primeira
nota: e em seguida o programa fica aguardando até que o usuário forneça um número
(fracionário ou inteiro) correspondente à primeira nota do aluno, para então prosseguir
com a instrução seguinte. De maneira semelhante acontece também com a leitura das
demais notas.

Memória (RAM)

nota1 nota2 nota3 media


5.0 6.0 9.0 6.67

Vídeo

Entre com a primeira nota: 5.00


Entre com a segunda nota: 6.00
Entre com a terceira nota: 9.00

Media Final = 6.67


pressione qualquer tecla...

Cada valor lido pelo comando leia e armazenado na memória. Para realizar o
cálculo da média o computador acessa as posições de memória das notas e realiza a
soma das notas para então dividir o resultado pela constante 3.0. O Resultado final é
exibido logo depois. Para finalizar o programa pressione uma tecla.

Exemplo 2.17 – Algoritmo que lê a idade de uma pessoa expressa em anos, meses e
dias e exibe-a expressa apenas em dias.

#incluir <stdio.h>
#incluir <conio.h>

principal ()
inicio

33
inteiro ano, mes, dias, total;

imprima ("Quantos anos voce tem: ");


leia ("%d",&ano);
imprima ("e quantos meses: ");
leia ("%d",&mes);
imprima ("e quantos dias: ");
leia ("%d",&dias);

total = (ano * 365 + dias * 30 + dias);

imprima ("\nTotal em dias = %d\n",total);

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */

retorno (0);
fim

2.8 Exercícios propostos

Exercício 2.1 – Exemplifique o uso dos comandos de Atribuição, Entrada e Saída.

Exercício 2.2 – Qual a diferença entre os comandos imprima e leia?

Exercício 2.3 – Como podemos imprimir a mensagem “Linha inicial”, seguida de duas
linhas em branco e uma outra mensagem “Linha final”? É possível
realizar esta tarefa em um único comando? Dê exemplos.

Exercício 2.4 – Como podemos orientar o usuário na digitação dos dados?


Exemplifique.

Exercício 2.5 – Escreva os comandos necessários para ler:


i) as 3 notas de um aluno
ii) o peso e altura de uma pessoa

Exercício 2.6 – Escreva os comandos necessários para exibir:


i) o conteúdo da variável x
ii) o resultado da expressão 2+3

Exercício 2.7 – Determine os valore finais de a, b e c após a execução do trecho do


programa abaixo:
a = 0;
b = 1;
c = a + b;
a = a + 1;
b = a + b + c;

Exercício 2.8 – A ordem das atribuições é importante? a = b e c = a tem o


mesmo efeito de c = a e a = b ?

34
Exercício 2.9 – Em qual dos seguintes pares é importante a ordem dos comandos?
Supor: x ≠ y ≠ z.

a) x = y; b) x = y; c) x = z; d) z = y;
y = z; z = x; x = y; x = y;

Exercício 2.10 – Fazer um algoritmo que dadas às dimensões de um retângulo, calcule


a sua área e mostre na tela.

#incluir <stdio.h>
#incluir <conio.h>

principal ()
inicio

inteiro base, altura, area;

imprima ("Digite o valor da base do retangulo: ");


leia ("%d",&base);
imprima ("Digite o valor da altura do retangulo: ");
leia ("%d",&altura);

area = base * altura;

imprima ("Area = %d\n",area);

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */

retorno (0);
fim

Exercício 2.11 – Escreva um algoritmo que leia um número inteiro positivo e exiba o
dobro do mesmo.

Exercício 2.12 – Escreva um algoritmo para calcular e exibir o comprimento de uma


circunferência, sendo dado o valor de seu raio. (C = 2 π R)

Exercício 2.13 – Escreva um algoritmo para ler uma temperatura dada na escala
Fahrenheit e exibir o equivalente em Celsius. (C = 5 (F – 32))
9
Exercício 2.14 – Escreva um algoritmo para calcular e exibir a média ponderada de
duas notas dadas. (nota1 = peso 6 e nota2 = peso 4)

Exercício 2.15 – Escreva um algoritmo que leia duas variáveis inteiras e troque o
conteúdo entre elas.

Exercício 2.16 – Escreva um algoritmo para calcular e exibir o valor de x y, sendo


dados a base (x) e o expoente (y).

Exercício 2.17 – As raízes de uma equação quadrática da forma

35
ax2 + bx + c = 0

são reais se e somente se o discriminante dado por

b2 – 4ac

for maior ou igual a zero. Preparar um algoritmo para ler os valores


dos coeficientes a, b e c e imprimir o valor do discriminante. Mostrar
também uma mensagem se é possível encontrar as raízes reais ou não.

Exercício 2.18 - Qual o resultado das expressões aritméticas abaixo, sabendo-se que os
valores de X, Y e Z são, respectivamente, 1, 2 e 5 ?

a) Z resto Y / Y
b) X + Y + Z / 3
c) raiz( Z / Y + X * Y)
d) Z - abs (X – potencia (Y,2))

Exercício 2.19 - Escreva o resultado das seguintes funções:

a) abs (-4)
b) abs (5.2)
c) potencia (1.0,4)
d) potencia (10,2)
e) raiz (25)
f) raiz (9.0)

Exercício 2.20 - Preencha a Tabela Verdade abaixo:

a b a && b a || b !a !b
TRUE TRUE
TRUE FALSE
FALSE TRUE
FALSE FALSE

Exercício 2.21 - Escreva o resultado das seguintes comparações:


a) 1 != 1.0
b) FALSE == FALSE
c) TRUE != TRUE
d) 3 > 5.0
e) –2 <= 2
f) ‘a’ == ‘A’

Exercício 2.22 - Qual o resultado das expressões lógicas abaixo, sabendo-se que os
valores de A e B são, respectivamente, TRUE e FALSE?

a) !A && B || A && !B
b) !(!(A || B) && (A || B))

36
c) A || B && !A || !B
d) (A || B) && (!A || !B)

Exercício 2.23 - Faça um algoritmo que calcule o perímetro de um retângulo, sendo


dado o comprimento e a largura desse retângulo. P = 2 x (c + l)

Exercício 2.24 - Faça um algoritmo que leia dois valores numéricos inteiros para duas
variáveis e que troque o conteúdo dessas variáveis, visualizando o
valor das mesmas antes e depois da troca.

Exercício 2.25 - Faça um algoritmo que leia dois números reais e que calcule a soma,
produto e a média desses números.

Exercício 2.26 - Faça um algoritmo que determine o volume de uma esfera, sendo dado
o respectivo raio. (V = 4/3 x π x r3) Repare que, em C, a divisão de 4
por 3 dá um valor inteiro se não tomar medidas adequadas.

37
3 Comandos de controle de fluxo

Para representar a solução de um problema deve-se escrever o conjunto de


passos a serem seguidos, sendo que, a maioria dos problemas exige uma dinâmica na
sua solução, impondo assim que os algoritmos executem um conjunto de instruções de
acordo com as possíveis situações encontradas no problema original. Na maioria das
linguagens de programação os mecanismos utilizados para esse controle são: Seqüência,
Seleção e Repetição.

3.1 Seqüência ou bloco

Usada para executar comandos passo a passo, sabendo que todos eles serão
executados na ordem descrita, sem nenhum desvio. Uma seqüência ou bloco pode
possuir um ou vários comandos, os quais devem ser delimitados pelos identificadores de
inicio e fim.

inicio
comando1;
...
comandon;
fim

Exemplo 3.1 – Desenvolver um algoritmo para ler um número inteiro e escrever seu
sucessor e seu antecessor.

#incluir <stdio.h>
#incluir <conio.h>

principal ()
inicio

inteiro num, suc, ant;

imprima ("Entre com um numero: ");


leia ("%d",&num);

suc = num + 1;
ant = num - 1;

imprima ("Sucessor = %d\n",suc);

38
imprima ("Antecessor = %d\n",ant);

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */

retorno (0);
fim

Exemplo 3.2 – Desenvolver um algoritmo para ler dois números inteiros e escrever a
seguinte saída:

Dividendo: __
Divisor: __
Quociente: __
Resto: __

#incluir <stdio.h>
#incluir <conio.h>

principal ()
inicio

inteiro valor1, valor2, q, r;

imprima ("Entre com o dividendo: ");


leia ("%d",&valor1);
imprima ("Entre com o divisor: ");
leia ("%d",&valor2);

q = valor1 / valor2;
r = valor1 resto valor2;

imprima ("Dividendo: %d\n",valor1);


imprima ("Divisor: %d\n",valor2);
imprima ("Quociente: %d\n",q);
imprima ("Resto: %d\n",r);

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */

retorno (0);
fim

Exemplo 3.3 – Desenvolver um algoritmo para ler um ângulo em graus e escrever:


seno, co-seno, tangente, secante, co-secante e cotangente deste ângulo.

#incluir <stdio.h>
#incluir <conio.h>
#incluir <math.h>

#definir PI 3.1415926

39
principal()
inicio
real angulo, rang;
imprima ("Entre com um ângulo em graus: ");
leia ("%f",&angulo);

rang = angulo * PI / 180;

imprima ("Valor do PI:%f\n",PI);


imprima ("Seno: %f\n",sen(rang));
imprima ("Co-seno: %f\n",cos(rang));
imprima ("Tangente: %f\n",tan(rang));
imprima ("Co-secante: %f\n",(1 / sen(rang)));
imprima ("Secante: %f\n",(1 / cos(rang)));
imprima ("Cotangente: %f\n",(1 / tan(rang)));

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */

retorno (0);
fim

3.2 Seleção

Usada para tomar decisões, ou seja, desviar a execução do algoritmo de acordo


com uma condição (Expressão Lógica), podendo ser simples (fig. 3.1) ou
composta (fig. 3.2).

Veja as afirmações a seguir:

i) Todos os alunos terão bolsas de estudos integrais;


ii) Somente alunos com renda inferior ou igual a dois salários mínimos,
receberão a bolsa de estudos;
iii) Os alunos com renda superior a dois salários mínimos, portanto, sem
direito à bolsa de estudo, receberão auxílio transporte, o qual não é
concedido aos alunos que possuem a bolsa integral;
iv) Os alunos com renda inferior a um salário mínimo receberão bolsa
integral e para os alunos com renda superior a este e de não mais que
dois salários mínimos as bolsas serão de 50%. Demais alunos com renda
superior a dois salários mínimos ganham somente o auxílio transporte.

O primeiro item refere-se a uma seqüência de instruções onde nenhuma decisão


precisa ser tomada, pois todos os alunos irão receber a bolsa de estudos. Os primeiros
exemplos deste capítulo demonstram este conceito. Já na segunda afirmação, aparece
uma situação de decisão simples (fig. 3.1), onde para estar habilitado a receber a bolsa
de estudos cada aluno precisa preencher o requisito de renda mínima exigido. A seguir,
a sintaxe de uma estrutura de decisão simples. Os colchetes [...] delimitam uma
parte opcional da estrutura.

Sintaxe:

40
se (condicao)
inicio
comando ;
[ou sequencia1 ;]
fim

Fluxo
se

Figura 3.1 – Fluxograma para estrutura SE.

A terceira afirmação apresenta uma situação um pouco mais complexa, o que


exige uma estrutura de decisão composta (fig. 3.2). Levando em consideração que
somente os alunos com renda superior a dois salários mínimos receberão o auxílio
transporte se faz necessário informar que os alunos que recebem a bolsa de estudos, não
serão contemplados com este auxílio. Na seqüência a sintaxe de uma estrutura de
decisão composta. Os colchetes [...] delimitam uma parte opcional da estrutura.

Sintaxe:

se (condicao)
inicio
comando ;
[ou sequencia1 ;]
fim
senao
inicio
comando ;
[ou sequencia2 ;]
fim

Os exemplos seguintes demonstram a funcionabilidade de cada uma das versões


da estrutura de decisão.

Exemplo 3.4 – Desenvolver um algoritmo para ler um número inteiro e exibi-lo se for
positivo.

#incluir <stdio.h>

41
#incluir <conio.h>

principal ()
inicio

real n;

imprima ("Entre com um numero: ");


leia ("%f",&n);

se (n > 0.0)
inicio
imprima ("%f eh positivo!\n",n);
fim

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */

retorno (0);
fim

Fluxo
se

Figura 3.2 – Fluxograma para estrutura SE SENAO.

No exemplo (ex. 3.4) anterior, o comando imprima só será executado se a


condição (n > 0.0) for verdadeira. Caso contrário, nenhuma ação será executada.

Exemplo 3.5 – Desenvolver um algoritmo para ler um número e determinar se ele é


maior que zero ou não.

#incluir <stdio.h>
#incluir <conio.h>

principal ()

42
inicio
real n;

imprima ("Entre com um numero: ");


leia ("%f",&n);

se (n > 0.0)
inicio
imprima ("%f eh maior que zero!\n",n);
fim
senao
inicio
imprima ("%f nao eh maior que zero!\n",n);
fim

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */

retorno (0);
fim

Neste exemplo (ex. 3.5), a mensagem que será exibida dependerá do resultado
da expressão lógica (n > 0.0). Se ela for verdadeira, será executado o comando
imprima do bloco inicio e fim que se refere à palavra se. Caso contrário, será
executado o comando imprima do bloco inicio e fim que se refere à palavra
senao. Em nenhuma hipótese será executado ambos os comandos imprima.

E a quarta afirmação, como empregá-la em um algoritmo? Há uma nova


estrutura para tal? Respostas a seguir.

Há casos em que é necessária a realização de mais de dois testes, como na


afirmação ainda não discutida. Para satisfazer as condições da última afirmação, será
preciso testar se o aluno possui renda inferior a um salário mínimo para poder receber a
bolsa de estudos integral e na seqüência determinar por meio de outro teste se a renda do
aluno encontra-se situada entre um e dois salários mínimos, garantindo-lhes uma bolsa
de estudos de 50%. O fato do aluno não estar incluso no primeiro grupo não lhe garante
a indiscriminadamente a bolsa de estudos de 50%. Por fim indicar aos alunos que se
encontram fora das situações anteriores que receberão o auxílio transporte.
Para estes casos empregam-se mais de uma estrutura de decisão simples e/ou
composta, denominando-se de ses encaixados/aninhados (se senao se). O
exemplo (ex. 3.6) a seguir ilustra este conceito.

Exemplo 3.6 – Desenvolver um algoritmo para ler um número e determinar se ele é


maior, menor ou igual a zero.

#incluir <stdio.h>
#incluir <conio.h>

principal ()
inicio

43
real n;
imprima ("Entre com um numero: ");
leia ("%f",&n);

se (n > 0.0)
inicio
imprima ("%f eh maior que zero!\n",n);
fim
senao
inicio
se (n < 0.0)
inicio
imprima ("%f eh menor que zero!\n",n);
fim
senao
inicio
imprima ("%f eh igual a zero!\n",n);
fim
fim

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */

retorno (0);
fim

Pode-se observar que diversas linhas deste algoritmo terminam sem o ponto-e-
vírgula, isto porque o ponto-e-vírgula só é utilizado para separar comandos e/ou
estruturas.
Deve-se tomar cuidado quando da utilização de ses aninhados, pois a cláusula
senao é sempre relacionada ao último se. Se, dentro de algum algoritmo, necessitar-se
contornar este fato, pode-se fazê-lo com uso dos delimitadores inicio e fim. Estes
também são utilizados em seqüências ou blocos.

3.3 Seleção entre múltiplas escolhas

Utilizada quando se deseja executar um entre vários comandos (ou uma entre
várias seqüências de comandos) dependendo do resultado de uma expressão. Mais de
um comando ou vários comandos ou seqüências podem ser executados também, veja
ainda nesta seção.
A estrutura de seleção (decisão múltipla) é chamada de escolha caso e em
linguagem C apresenta-se como comando de nome switch case, e obedece a seguinte
sintaxe.

Sintaxe:

escolha (expressao)
inicio
caso <constante1> : comando ;
comando ;

44
pare;
caso <constante2> : comando ;
comando ;
pare;

caso <constante3> : comando ;


comando ;
pare;

...

[padrao : comando ;
comando ;
pare ;]

fim

O comando escolha é delimitado pelo bloco de inicio e fim. Internamente


possui uma expressao e suas opções de comparação por meio de cláusulas caso. A
expressao após o comando escolha é avaliada e comparada com cada uma das
constantes de cada cláusula caso. Cada uma das constantes deve ser bem definida. A
seqüência a ser executada logo que uma constante seja igual à expressão pode ser um ou
mais comandos. O resultado da expressao é comparado com cada constante da lista
para verificar-se a igualdade entre eles. Caso esta igualdade seja encontrada, o comando
correspondente é executado e a estrutura é finalizada ou não, dependendo da existência
de comandos pare. Caso nenhuma igualdade entre a expressao e as constantes
sejam verificadas, os comandos correspondentes à cláusula padrao serão executados.
Os colchetes [...] delimitam uma parte opcional da estrutura.
Os próximos exemplos ilustram formas de utilização do comando de seleção
entre múltiplas escolhas.

Exemplo 3.7 – Desenvolver um algoritmo para simular uma calculadora básica de


números inteiros utilizando o comando escolha caso.

#incluir <stdio.h>
#incluir <conio.h>

principal ()
inicio

char op;
inteiro x,y;
imprima ("Digite o operador: ");
leia ("%c",&op);
imprima ("Entre com os operandos: ");
leia ("%d%d",&x,&y);

escolha (op)
inicio
caso '+' : imprima ("Soma = %d\n",x + y);
pare;

45
caso '-' : imprima ("Subtracao = %d\n",x - y);
pare;
caso '*' :
caso 'x' :
caso 'X' : imprima ("Produto = %d\n",x * y);
pare;
caso '/' : imprima ("Divisao = %d\n",x / y);
pare;
padrao : imprima ("Operador invalido!\n");
pare;
fim

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */

retorno (0);
fim

Neste exemplo a mensagem que será exibida, bem como a operação executada,
dependerá do conteúdo da variável op. Se for igual a uma das constantes especificadas,
será executado o comando imprima correspondente. Se nenhuma constante for igual
ao conteúdo de op, será executado o imprima da cláusula padrao.
Pode-se também escrever o mesmo programa anterior (ex. 3.7) sem utilizar a
estrutura escolha caso, apenas utilizando se's aninhados, como demonstra a
algoritmo seguinte.

Exemplo 3.8 – Desenvolver um algoritmo para simular uma calculadora básica de


números inteiros sem utilizar o comando escolha caso.

#incluir <stdio.h>
#incluir <conio.h>

principal ()
inicio

char op;
inteiro x,y;

imprima ("Digite o operador: ");


leia ("%c",&op);
imprima ("Entre com os operandos: ");
leia ("%d%d",&x,&y);
se (op == '+')
inicio
imprima ("Soma = %d\n",x + y);
fim
senao
inicio
se (op == '-')
inicio
imprima ("Subtracao = %d\n",x - y);
fim

46
senao
inicio
se (op == '*' || op == 'x' || op == 'X')
inicio
imprima ("Produto = %d\n",x * y);
fim
senao
inicio
se (op == '/')
inicio
imprima ("Divisao = %d\n",x / y);
fim
senao
inicio
imprima ("Operador invalido!\n");
fim
fim
fim
fim

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */

retorno (0);
fim

Para compreender melhor o comando pare em todas ou algumas cláusulas


caso do comando escolha, veja a figura (fig. 3.3) a seguir.
A expressao é avaliada e o valor obtido é comparado com os valores
associados às cláusulas caso em seqüência.
Quando o valor associado a uma cláusula é igual ao valor do escolha os
respectivos comandos são executados até encontrar um pare.
Se não existir um pare na cláusula selecionada, os comandos das cláusulas
seguintes são executados em ordem até encontrar um pare ou esgotarem-se as
cláusulas do escolha.
Se nenhuma das cláusulas contém o valor de seleção a cláusula padrao, se
existir, será executada.
O exemplo (ex. 3.9) a seguir ilustra o que acontece quando não são utilizados
comandos pare em cada uma das cláusulas caso, partindo do princípio que este não
foi o desejo do programador. Mas, por que o comando escolha caso tem este
comportamento?
Há casos onde esta característica é importante para que não seja necessário
repetir comandos a serem executados por diversas cláusulas caso. Sendo assim,
agrupam-se dois ou mais casos e suas respectivas constantes e somente ao final coloca-
se o comando referente aos casos anteriores, sem esquecer, se este for o desejo, o
comando pare. No Exemplo (ex. 3.7) anterior é possível observar que para não repetir
o mesmo comando para multiplicar os valores para as constantes ‘*’ ,’x’ ,’X’ ,
optou-se por não utilizar comandos pare nestes casos.

Exemplo 3.9 – Desenvolver um algoritmo para identificar os caracteres de ‘0’ à

47
‘9’ mostrando-os na tela. Utilize o comando escolha caso.

#incluir <stdio.h>
#incluir <conio.h>

principal ()
inicio

char digito;

imprima ("Digite um caractere de 0 a 9: ");


leia ("%c",&digito);

escolha (digito)
inicio
caso '0' : imprima ("0");
caso '1' : imprima ("1");
caso '2' : imprima ("2");
caso '3' : imprima ("3");
caso '4' : imprima ("4");
caso '5' : imprima ("5");
caso '6' : imprima ("6");
caso '7' : imprima ("7");
caso '8' : imprima ("8");
caso '9' : imprima ("9");
pare;
fim

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */

retorno (0);
fim

escolha

caso :
pare;

caso :

caso :
pare;

Figura 3.3 – Fluxograma para estrutura ESCOLHA CASO.

Ao executar o algoritmo do exemplo (ex. 3.9) anterior, têm-se a tela abaixo.


Supondo que o usuário forneça o valor 4 obtêm-se a seguinte saída: 456789. Uma vez

48
que o caractere é encontrado em uma das constantes (caso) e não há comandos pare,
toda a seqüência atual é mostrada. Isto para o caso apresentado constitui-se de um erro
de lógica.

Vídeo

Digite um caractere de 0 a 9
_4 <enter>
456789
pressione qualquer tecla...

Exemplo 3.10 – Construir um algoritmo para identificar os números arábicos de 0 à 9


mostrando os números cardinais correspondes na tela. Utilize o
comando escolha caso.

#incluir <stdio.h>
#incluir <conio.h>

principal ()
inicio

inteiro num;

imprima ("Digite um numero de 0 a 9: ");


leia ("%d",&num);

escolha (num)
inicio
caso 0 : imprima ("zero");
pare;
caso 1 : imprima ("um");
pare;
caso 2 : imprima ("dois");
pare;
caso 3 : imprima ("tres");
pare;
caso 4 : imprima ("quatro");
pare;
caso 5 : imprima ("cinco");
pare;
caso 6 : imprima ("seis");
pare;
caso 7 : imprima ("sete");
pare;
caso 8 : imprima ("oito");
pare;
caso 9 : imprima ("nove");
pare;

49
fim

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */

retorno (0);
fim

Exemplo 3.11 – Construir um algoritmo para identificar qual época do ano estamos.
Utilize o comando escolha caso.

#incluir <stdio.h>
#incluir <conio.h>

principal ()
inicio

inteiro epoca;

imprima("Periodo trimestral do ano estamos: ");


leia ("%d",&epoca);

escolha (epoca)
inicio
caso 1 : imprima ("verao\n");
pare;
caso 2 : imprima ("outono\n");
pare;
caso 3 : imprima ("inverno\n");
pare;
caso 4 : imprima ("primavera\n");
pare;
padrao : imprima ("Periodo invalido!\n");
pare;
fim

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */

retorno (0);
fim

3.4 Exercícios propostos

Exercício 3.1 – Faça um algoritmo que leia um número inteiro e que determine o seu
módulo sem usar nenhuma função disponível em C para essa
finalidade.

Exercício 3.2 – Faça um algoritmo que determine se um ano introduzido pelo usuário
é ou não bissexto. Um ano é bissexto se for múltiplo de 4 sem ser de
100 ou se for múltiplo de 400.

50
Exercício 3.3 – Faça um algoritmo que calcule o salário semanal de um funcionário.
Deve ser lido o número total de horas (valor inteiro) de trabalho desse
funcionário durante a semana, o custo de uma hora normal e o custo
de uma hora extraordinária. Para calcular o salário, deve-se considerar
como horas normais as 40 primeiras e como horas extraordinárias (se
existirem) as restantes horas de trabalho.

Exercício 3.4 – Escreva um algoritmo que leia um número inteiro e determine se ele é
par ou ímpar.

Exercício 3.5 – Deseja-se calcular a conta de consumo de energia elétrica de um


consumidor. Para isto, escreva um algoritmo que leia o código do
consumidor, o preço do Kw e a quantidade de Kw consumido, e exiba
o código do consumidor e o total a pagar.

total a pagar = preco x quantidade


total a pagar minimo = R$ 13,20

Exercício 3.6 – Escreva um algoritmo para ler três números inteiros distintos e
determinar o menor deles.

Exercício 3.7 – Faça um algoritmo que, dado as três notas de um aluno, determine e
exiba a sua média final e o seu conceito, sabendo-se que:

A média final é calculada pela média aritmética simples das 3 notas;


O conceito é determinado de com base na tabela a seguir:

Média Final Conceito


≥ 8,0 A
≥ 6,0 e < 8,0 B
< 6,0 C

Exercício 3.8 – Os comandos (i) e (ii) são equivalentes? Explique sua resposta.

(i) a = b == c
(ii) se a == b
inicio
a = TRUE;
fim
senao
inicio
a = FALSE;
fim

Exercício 3.9 – Escreva um algoritmo que determine o grau de obesidade de uma


pessoa, sendo fornecido o peso e a altura da pessoa. O grau de
obesidade é determinado pelo índice da massa corpórea (Massa =

51
Peso/Altura2) seguindo a tabela abaixo:

Massa Corpórea Grau De Obesidade


< 26 Normal
≥ 26 e < 30 Obeso
≥ 30 Obeso Mórbido

Exercício 3.10 – O Criciúma Futebol Clube deseja aumentar o salário de seus


jogadores. O reajuste deve obedecer a seguinte tabela:

Salário Atual (R$) Aumento


0,00 a 1.000,00 20%
1.000,01 a 5.000,00 10%
acima de 5.000,00 0%

Escrever um algoritmo que leia o salário atual de um jogador, e exiba


o salário atual e o salário reajustado.

Exercício 3.11 – Faça um algoritmo para calcular a conta final de um hóspede de um


hotel, considerando que:

a) Serão lidos os tipos de apartamentos utilizados (A, B, C ou D), o


número de diárias utilizadas pelo hóspede e o valor do consumo
interno do hóspede;

b) O valor da diária é determinado pela seguinte tabela:

Tipo Do Apto Valor Da Diária (R$)


A 150,00
B 100,00
C 75,00
D 50,00

c) O valor total das diárias é calculado pela multiplicação do número


de diárias utilizadas pelo valor da diária;

d) O subtotal é calculado pela soma do valor total das diárias e o valor


do consumo interno;

e) O valor da taxa de serviço equivale a 10% do subtotal;

f) O total geral resulta da soma do subtotal com a taxa de serviço;

g) Escreva a conta final contendo: o tipo do apartamento, o número de


diárias utilizadas, o valor unitário da diária, o valor total das diárias, o
valor do consumo interno, o subtotal, o valor da taxa de serviços e o
total geral.

52
Exercício 3.12 – Deseja-se calcular o imposto de renda* de um contribuinte. Para isto,
escreva um algoritmo que:

a) Leia os seguintes dados do contribuinte: CPF, rendimento anual,


imposto retido na fonte, contribuição previdenciária, despesas
médicas, despesas com educação ao limite individual R$ 2.708,49 e
número de dependentes;

b) É deduzido o valor de R$ 1.730,40 por cada dependente;

c) Cálculo do valor total das deduções: contribuição previdenciária +


despesas médicas + dedução dos dependentes;

d) Cálculo da base de cálculo: rendimento anual – total das deduções;

e) Com base na tabela a seguir:

Base de Cálculo Alíquota Parcela a Deduzir


até 17.215,08 Isento -
De 17.215,09 até 25.800,00 7,50% 1.291,13
De 25.800,01 até 34.400,40 15,00% 3.226,13
De 34.400,41 até 42.984,00 22,50% 5.806,16
acima de 42.984,00 27,50% 7.955,36

Cálculo do imposto devido: ((base de cálculo * alíquota) - parcela a


deduzir)

f) Haverá imposto a pagar se a diferença entre o imposto devido e o


imposto retido na fonte for positiva; caso contrário, haverá imposto a
restituir;

g) Exiba todos os dados lidos e calculados.

* Regras para a declaração do IRPF - Imposto de Renda Pessoa Física


de 2010, ano-base 2009.

Exercício 3.13 – Criar um algoritmo para resolver uma equação do primeiro grau (Ax +
B = 0), onde o usuário deverá informar o valor de A e B para o sistema
calcular o resultado de “x”.

Exercício 3.14 – Observe o trecho de algoritmo abaixo, considerando L1, L2 e L3 como


variáveis lógicas.

...
se (L1)
inicio
imprima ('A')
fim

53
senao
inicio
se (L2)
inicio
se (L3)
inicio
imprima ('B')
fim
senao
inicio
imprima ('C');
imprima ('D');
fim
fim
senao
inicio
imprima ('E');
fim
fim
...
Agora, responda as seguintes questões:

a) Se forem lidos V, V e V, o que será escrito pelo algoritmo?


b) Se forem lidos F, V e V, o que será escrito pelo algoritmo?
c) Se forem lidos F, V e F, o que será escrito pelo algoritmo?
d) Que valores deveriam ser lidos para que fosse escrito apenas "E"?

54
3.5 Estruturas de repetições

Serve para efetuar um conjunto de ações repetidas vezes. Existem três tipos
básicos de repetições, sendo elas: enquanto, faca enquanto e para.

3.5.1 Enquanto

A instrução enquanto (em pseudocódigo enquanto-faça) é utilizada quando


se deseja executar várias vezes o mesmo trecho de um algoritmo ou programa, enquanto
a expressao for verdadeira.

Sintaxe:

enquanto (expressao)
inicio
comando;
[ou seqüência;]
fim

A figura (fig. 3.4) abaixo mostra a seqüência de execução da instrução


enquanto.

enquanto

F V

Figura 3.4 – Fluxograma para estrutura ENQUANTO.

O passo inicial a ser executado na instrução enquanto, é a verificação se a


expressao é verdadeira ou falsa. Sendo esta verdadeira, a ação (comando ou
seqüência de comandos) é executada e o controle do algoritmo ou programa retorna para
o topo do ciclo (loop). Novamente a expressao é testada e se ela ainda continuar
sendo verdadeira o comando ou seqüência de comandos é executado mais uma vez e, o
controle do algoritmo retorna novamente para o topo do ciclo (loop). Esse processo se
repete até que o teste da expressao seja falso. Quando isto acontece, a ação ou
comando é saltado (não executado), e o controle do algoritmo prossegue fora do
enquanto. É importante notar que a expressao só se tornará falsa se alguma ação
entre o inicio e fim dos comandos do enquanto atuar sobre alguma variável da

55
expressao, modificando seu valor. Os colchetes [...] delimitam uma parte
opcional da estrutura.
O comando enquanto analisa a expressao e enquanto o seu resultado for
verdadeiro, o comando ou a seqüência de comandos é executada. Esta estrutura é
recomendada para um número de repetições desconhecidas, podendo repetir de
nenhuma vez até n vezes.

Exemplo 3.12 – Desenvolver um algoritmo para calcular e mostrar o dobro de um


número após solicitar do usuário este número. Utilize a estrutura de
repetição enquanto. Sendo que, o algoritmo termina somente quando
o usuário fornecer o valor zero (0) como número de entrada.

#incluir <stdio.h>
#incluir <conio.h>

principal ()
inicio

inteiro num, dobro;

imprima ("Digite um numero inteiro: ");


leia ("%d",&num);

enquanto (num != 0)
inicio
dobro = num * 2;

imprima ("%d, e seu Dobro: %d\n",num,dobro);

imprima ("Digite um numero inteiro: ");


leia ("%d",&num);
fim

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */

retorno (0);
fim

Exemplo 3.13 – Algoritmo de Euclides – Ler dois números positivos m e n e encontre


seu maior divisor comum, isto é, o maior inteiro positivo que divide
tanto m como n. Garanta que m é sempre maior que n e n é diferente
de zero.

#incluir <stdio.h>
#incluir <conio.h>

principal ()
inicio

inteiro m, n, r;

56
imprima ("Entre com valor de m: ");
leia ("%d",&m);
imprima ("Entre com valor de n: ");
leia ("%d",&n);

se (m > n && n != 0)
inicio
r = m resto n; /*resto da divisão de m por n */
enquanto (r != 0)
inicio
m = n;
n = r;
r = m resto n;
fim
fim

imprima ("\nMaior divisor comum = %d\n",n);

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */

retorno (0);
fim

3.5.2 Faca enquanto

Uma outra maneira de fazer com que um conjunto de instruções seja executado
uma ou mais vezes, é utilizar a estrutura faca enquanto, conhecido também como
repita até, em pseudocódigo. Sua forma geral é mostrada a seguir.

Sintaxe:

faca
inicio
comando;
[ou seqüência;]
fim
enquanto (expressao) ;

A figura (fig. 3.5) a seguir mostra a seqüência de execução da instrução faca


enquanto.
A execução da estrutura faca enquanto ocorre da seguinte forma: quando o
fluxo de execução chega no início da estrutura (faca), o comando ou seqüência de
comandos internos à estrutura são executados. Quando o fluxo de execução chega no
enquanto, a expressao é avaliada. Se o resultado da avaliação for verdadeiro, a
execução retorna ao faca e, novamente, os comandos ou seqüência de comandos são
executados. Porém se o resultado for falso, então a execução sairá do ciclo (loop) e
passará para a primeira instrução imediatamente após o enquanto. Os colchetes
[...] delimitam uma parte opcional da estrutura.

57
faca

enquanto
V
F

Figura 3.5 – Fluxograma para estrutura FACA ENQUANTO.

É possível notar que a instrução faca enquanto é similar à instrução


enquanto, apresentada anteriormente. A única diferença é que a expressao de
controle do ciclo é testada ao final deste. Desta maneira, os comandos ou seqüência de
comandos internos ao ciclo, sempre serão executados ao menos uma vez.
A estrutura faca enquanto executa o comando ou a seqüência de comandos até
que o valor retornado pela expressao seja falso. Assim como o enquanto, esta
estrutura também é recomendada para um número de repetições desconhecidas, porém
com a diferença de repetir pelo menos uma vez até n vezes.

Exemplo 3.14 – Desenvolver um algoritmo que realize a multiplicação de dois


números inteiros positivos. Use estrutura de repetições.

#incluir <stdio.h>
#incluir <conio.h>

principal ()
inicio

inteiro m, n, r;

imprima ("Entre com valor de m: ");


leia ("%d",&m);
imprima ("Entre com valor de n: ");
leia ("%d",&n);

r = 0;

faca
inicio
r = r + m;
n = n - 1;
fim
enquanto (n != 0);

58
imprima ("\nResultado = %d\n",r);

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */

retorno (0);
fim

Exemplo 3.15 – Desenvolver um algoritmo para calcular e mostrar o dobro de um


número após solicitar do usuário este número. Utilize a estrutura de
repetição faca enquanto. Sendo que, o algoritmo termina somente
quando o usuário fornecer o valor zero (0).

#incluir <stdio.h>
#incluir <conio.h>

principal ()
inicio

inteiro num, dobro;

faca
inicio
imprima ("Digite um numero inteiro: ");
leia ("%d",&num);

dobro = num * 2;

imprima ("%d, e seu Dobro: %d\n",num,dobro);


fim
enquanto (num != 0);

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */

retorno (0);
fim

3.5.3 Para

A estrutura para (fig. 3.6) executa uma seqüência ou um bloco, de uma ou mais
declarações, um certo número de vezes. Em pseudocódigo, o comando para
corresponde à estrutura de repetição para faça.

Sintaxe:

para (inicializacoes ; condicao ; incrementos)


inicio
comando;
[ou seqüência;]
fim

59
Quando uma declaração para é encontrada durante a execução de um
programa, ocorrem os seguintes eventos:

i) A expressão inicializacao é executada. Essa expressão é, geralmente,


uma atribuição que configura uma variável para um determinado valor.
ii) A expressão condicao é executada. A condicao é, tipicamente, uma
expressão relacional de comparação.
iii) Se a condicao for falsa (zero) o comando para termina, e a execução do
programa passa para a primeira declaração após a seqüência ou bloco de
comandos do para.
iv) Se a condicao for verdadeira (diferente de zero), a seqüência ou bloco de
comandos do para é executado.
v) A expressão incrementos é executada, e a execução volta ao passo ii.

para inicializacao

teste
V
F

bloco

incremento

Figura 3.6 – Fluxograma para estrutura PARA.

Exemplo 3.16 – Desenvolver um algoritmo para imprimir na tela os números de 1 à 10.

#incluir <stdio.h>
#incluir <conio.h>

principal ()
inicio

inteiro contador;

para (contador = 1; contador <= 10; contador++)


inicio
imprima ("%d\n",contador);
fim

60
imprima ("\npressione qualquer tecla...");
getch(); /* Aguarda uma tecla para finalizar */

retorno (0);
fim

Exemplo 3.17 – Desenvolver um algoritmo que calcule e mostre a média da turma em


uma determinada avaliação. Solicite inicialmente o número de alunos
que formam a turma.

#incluir <stdio.h>
#incluir <conio.h>

principal ()
inicio

inteiro turma, i;
real nota, soma, media;

imprima ("Numeros de alunos na turma: ");


leia ("%d",&turma);

soma = 0;

para (i = 0; i < turma; i++)


inicio
imprima ("Nota do %d estudante: ",i + 1);
leia ("%f",&nota);

soma = soma + nota;


fim

media = soma/turma;

imprima ("Media da turma: %.2f\n",media);

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */

retorno (0);
fim

Variações do comando para

O comando para usa, freqüentemente, um contador que tem seu valor


incrementado (aumentado) como no exemplo (ex. 3.11) apresentado anteriormente. Mas
pode-se também fazer contagem regressiva, decrementando o contador, veja a seguir.

...

para (contador = 10; contador > 0; contador--)

61
inicio
...
fim
...

O incremento (ou decremento) pode também ser diferente de 1, como ilustra a


estrutura abaixo.

...

para (contador = 0; contador < 50; contador += 5)


inicio
... /* contador += 5 é equivalente a contador = contador + 5 */
fim
...

Se pode ainda executar múltiplas ações na instrução para, separando-as por


vírgula. Alguns exemplos a seguir.

...

para (z = 10; z <= 10 && z != 5; z++)


inicio
...
fim

para (z = 0, y = 2; z <= 5 && y < 10; z++, y += 2)


inicio
...
fim
...

Exemplo 3.18 – Criar um algoritmo que a cada número digitado pelo usuário seja
calculado o seu fatorial e exibido na tela o resultado.

#incluir <stdio.h>
#incluir <conio.h>

principal ()
inicio

inteiro n, i, fatorial;

imprima ("Entre com um numero inteiro: ");


leia ("%d",&n);

fatorial = 1;

para (i = n; i > 1; i--)


inicio
fatorial = fatorial * i;
fim

62
imprima ("Fatorial de %d e = %d\n",n,fatorial);
imprima ("\npressione qualquer tecla...");
getch(); /* Aguarda uma tecla para finalizar */
retorno (0);
fim

Para se calcular o fatorial de um número, é necessário multiplicá-lo pelos seus


predecessores até se chegar ao valor 1. Portanto, o fatorial de 5 é 5*4*3*2*1. Assim,
chega-se à conclusão de que uma estrutura para resolve o problema, visto que temos o
valor de inicialização e o ponto de parada (expresso na condição).

Exemplo 3.19 – Desenvolver um algoritmo para calcular a potência N de um número


X. Ambos serão inteiros e fornecidos pelo usuário. Imprima na tela o
seu resultado.

#incluir <stdio.h>
#incluir <conio.h>

principal ()
inicio
inteiro base, expoente, resultado, i;

imprima ("Entre com a base: ");


leia ("%d",&base);
imprima ("Entre com o expoente: ");
leia ("%d",&expoente);

resultado = base;

se (expoente == 0)
inicio
resultado = 1;
fim
senao
inicio
se (base == 0)
inicio
resultado = 0;
fim
senao
inicio
para (i = 1; i < expoente; i++)
inicio
resultado = resultado * base;
fim
fim
fim

imprima ("Base %d elevado ao expoente %d e =


%d\n",base,expoente,resultado);
imprima ("\npressione qualquer tecla...");
getch(); /* Aguarda uma tecla para finalizar */

63
retorno (0);
fim

O cálculo da exponenciação se dá como xn de modo que para se obter o


resultado final deve-se multiplicar X por ele mesmo N vezes. Então, conhecendo o valor
de inicialização (1) e o valor final da condição será dado pelo usuário. A estrutura para
é a mais indicada.
Montar a expressão é fácil, mas em algoritmo é necessário mostrar todos os
passos para a máquina (computador), pois você o está ensinando a fazer algo. Então,
deve prever todas as situações possíveis. Por isso, testa-se a entrada do expoente 0 e da
base 0.

Comparando para e enquanto


Seja a estrutura para:

para (inicializacao ; condicao ; incremento)


inicio
comando;
[ou seqüência;]
fim

O trecho do código acima poderia ser substituído pelo trecho abaixo com a
seguinte construção:

inicializacao;

enquanto (condicao)
inicio
comando;
[ou seqüência;]
incremento;
fim

Exemplo 3.20 – Desenvolver um algoritmo para imprimir na tela os números de 1 a 10


usando a estrutura de repetição para e em seguida com enquanto.

#incluir <stdio.h>
#incluir <conio.h>

principal ()
inicio

inteiro contador;

para (contador = 1; contador <= 10; contador++)


inicio
imprima ("%d\n",contador);
fim

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */

64
retorno (0);
fim

A solução a seguir, usando enquanto, é equivalente ao exemplo acima com a


estrutura para.

#incluir <stdio.h>
#incluir <conio.h>

principal ()
inicio

inteiro contador;
contador = 1;

enquanto (contador <= 10)


inicio
imprima ("%d\n",contador);
contador++;
fim

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */

retorno (0);
fim

3.6 Exercícios propostos

Exercício 3.15 – Faça um algoritmo que calcule todos os divisores de um número.


Exemplo do algoritmo ao ser executado:

Entre com um numero: _24 <enter>


Os divisores de 24 são 1 2 3 4 6 8 12 24

Exercício 3.16 – Faça um algoritmo para ver se um número é primo ou não (um
número só é primo se apenas for divisível por 1 e por si próprio).
Exemplo do algoritmo ao ser executado:

Entre com um numero: _4


4 não é primo

Exercício 3.17 – Desenvolver um algoritmo que calcule a área de um círculo, de modo


a que o programa funcione ininterruptamente até o usuário digitar o
valor zero para o raio. Nessa altura, o algoritmo deve dizer que a área
é zero e terminar com um "Até logo". Exemplo do algoritmo ao ser
executado:

Digite o raio: 3

65
A area é 28.27
Digite o raio: 2.5
A area é 19.63
Digite o raio: -2
Esse raio é inválido
Digite o raio: 1
A area é 3.14
Digite o raio: 0
A area é 0.00
Ate logo.

Exercício 3.18 – Alguns países medem temperaturas em graus Celsius e outros em


graus Fahrenheit. Faça um algoritmo que escreve na tela uma tabela de
conversão de graus Celcius para Fahrenheit. A tabela deve apresentar
os graus Celcius de 0 à 40 com intervalos de 2 em 2. Exemplo do
algoritmo ao ser executado:

Celcius Fahrenheit
0.0 32.0
2.0 35.6
4.0 39.2
6.0 42.8
... ...
40.0 104.0

Exercício 3.19 – Faça um algoritmo que escreva a tabuada de um determinado número.


Exemplo do algoritmo ao ser executado:

Digite um numero: _9

9 x 1 = 9
9 x 2 = 18
9 x 3 = 27
9 x 4 = 36
9 x 5 = 45
9 x 6 = 54
9 x 7 = 63
9 x 8 = 72
9 x 9 = 81
9 x 10 = 90

Exercício 3.20 – Escreva um algoritmo que leia dois números e exiba o maior deles.

Exercício 3.21 – Escreva um algoritmo que leia dois números e exiba-os em ordem
crescente.

Exercício 3.22 – Faça um algoritmo que mostre todos os números inteiros pares de 2 à
100.

Exercício 3.23 – Faça um algoritmo para gerar e exibir os números inteiros de 20 até
10, decrescendo de 1 em 1.

66
Exercício 3.24 – Faça um algoritmo que leia um número N, some todos os números
inteiros de 1 à N, e mostre o resultado obtido.

Exercício 3.25 – Escreva um algoritmo que calcule o fatorial de um número inteiro


lido, sabendo-se que: N! = 1 x 2 x 3 x ... x N-1 x N e
que 0! = 1.

Exercício 3.26 – Faça um algoritmo que leia 3 números inteiros (N, X, Y) e mostre
todos os números múltiplos de N entre X e Y.

Exercício 3.27 – Faça um algoritmo que leia dois valores inteiros (X e Y) e mostre
todos os números primos entre X e Y.

Exercício 3.28 – Faça um algoritmo que, para um número indeterminado de pessoas:


Leia a idade de cada pessoa, sendo que a leitura da idade 0 (zero)
indica o fim dos dados (flag) e não deve ser considerada;

calcule e escreva o número de pessoas;


calcule e escreva a idade média do grupo;
calcule e escreva a menor e a maior idade;

Exercício 3.29 – Faça um algoritmo que leia a altura de um grupo de 20 pessoas,


calcule e exiba:
a maior altura do grupo;
a altura média;
o número de pessoas com altura superior à 2
metros.

Exercício 3.30 – Em um frigorífico existem 90 bois. Cada boi traz preso em seu
pescoço um cartão contendo seu número de identificação e seu peso.
Faça um algoritmo que escreva o número e o peso do boi mais gordo e
do boi mais magro (supondo que não haja empates).

Exercício 3.31 – Foi feita uma pesquisa de audiência de canal de TV em várias casas de
uma certa cidade, num determinado dia. Para cada casa visitada é
fornecido o número do canal (5, 7, 10 ou 12) e o número de pessoas
que estavam assistindo o canal naquela casa. Fazer um algoritmo que:
Leia um número indeterminado de dados, sendo que o flag
corresponde ao canal igual a 0 (zero);

calcule e escreva a porcentagem de audiência de


cada emissora.

Exercício 3.32 – O cardápio de uma casa de lanches, especializada em sanduíches, é


dado abaixo. Escreva um algoritmo que leia o código e a quantidade
de cada item comprado por um freguês, calcule e exiba o total a pagar.
Obs: A leitura do código "X" indica o fim dos itens.

Código Produto Preço (R$)

67
H Hamburger 3,50
C Cheeseburger 3,00
Q QueijoQuente 2,40

Exercício 3.33 – O Criciúma Futebol Clube deseja aumentar o salário de seus 22


jogadores. O reajuste deve obedecer a seguinte tabela:

Salário Atual (R$) Aumento


0,00 a 1.000,00 20%
1.000,01 a 5.000,00 10%
acima de 5.000,00 0%

Escrever um algoritmo que:

Leia o salário atual de cada jogador;


Exiba o salário atual e o salário reajustado de
cada jogador;
Exiba o total da folha de salários do clube,
antes do reajuste.
Exiba o total da folha de salários do clube,
após o reajuste.
Exiba o percentual de reajuste sobre o total da
folha de salários.

Exercício 3.34 – Uma certa firma fez uma pesquisa de mercado para saber se as pessoas
gostaram ou não de um novo produto lançado no mercado. Para isto,
forneceu o sexo do entrevistado (M-masculino ou F-feminino) e sua
resposta (S-sim ou N-não). Sabendo-se que foram entrevistadas 2.000
pessoas, fazer um algoritmo que calcule e escreva:

número de pessoas que responderam sim (S);


número de pessoas que responderam não (N);
a porcentagem de pessoas do sexo feminino (F);
a porcentagem de pessoas do sexo masculino (M);

Exercício 3.35 – Escreva um algoritmo que leia o número de andares de um prédio e, a


seguir, para cada andar do prédio, leia o número de pessoas que
entraram e saíram do elevador. Considere que o elevador está vazio e
está subindo, os dados se referem a apenas uma subida do elevador e
que o número de pessoas dentro do elevador será sempre maior ou
igual a zero. Se o número de pessoas, após a entrada e saída, for maior
que 15, deve ser mostrada a mensagem "Excesso de passageiros.
Devem sair X", sendo X o número de pessoas que devem sair do
elevador, de modo que seja obedecido o limite de 15 passageiros.
Após a entrada e saída no último andar, o programa deve mostrar
quantas pessoas permaneceram no elevador para descer.

Exercício 3.36 – Faça um algoritmo que leia vários códigos do jogador (1 ou 2) que
ganhou o ponto em uma partida de pingue-pongue, e responda quem
ganha a partida. A partida chega ao final se um dos jogadores chega a

68
21 pontos e a diferença de pontos entre os jogadores é maior ou igual a
dois. Caso contrário, ganha aquele que, com mais de 21 pontos,
consiga colocar uma vantagem de dois pontos sobre o adversário.

69
4 Modularização

A modularização consiste em um método para facilitar a construção de grandes


programas, por meio de sua divisão em pequenas etapas, que são: módulos, rotinas, sub-
rotinas ou subprogramas. Permitindo o reaproveitamento de código, uma vez que se
pode utilizar um módulo quantas vezes for necessário, eliminando assim a necessidade
de reescrever o mesmo código em situações repetitivas.

4.1 Funções

Uma função é um bloco de código precedido de um cabeçalho que contém o tipo


de retorno, o nome da função e sua lista de parâmetros. Com esta, pode-se fazer
referência ao bloco de código de qualquer ponto do algoritmo por meio do seu nome e
passando os seus parâmetros. O nome da função é nada mais além do que um
identificador único desta função que a diferencia de todos os demais identificadores,
como: variáveis, constantes e até de outras funções. A forma genérica de se construir
uma função é apresentada a seguir.

Sintaxe:

tipo_de_retorno nome_da_funcao ([lista_de_parâmetros])


inicio

/* Declaração das variáveis locais */

Comandos;

retorno (expressao);

fim

Referência, chamada ou invocação da função na seção de comandos do


algoritmo:

variavel = nome_da_funcao (variaveis) ;

O tipo de retorno da função corresponde aos tipos de variáveis utilizados até


este momento, tais como: inteiro, real, caractere, etc, presentes na maioria das
linguagens de programação. É possível também que uma função não devolva ou retorne

70
nenhum valor, sendo considerada de retorno vazio. Em algumas linguagens de
programação, tal como a linguagem Pascal este método é implementado na forma de
procedimentos.
O nome da função é dado pelo programador e precisa seguir as mesmas regras
utilizadas para nomear as variáveis e as constantes.
Na lista de parâmetros encontram-se as variáveis que devem ser passadas a
função no momento de sua chamada ou invocação. Esta lista apresenta-se da seguinte
maneira.

tipo variavel1, tipo variavel2, ..., tipo variavelN

As variáveis passadas as funções são associadas aos parâmetros da função de


acordo com a ordem das variáveis e da lista de parâmetros. Os [ ] na sintaxe do
cabeçalho da função indicam que a lista de parâmetros é opcional, permitindo assim a
criação de funções que não recebem variáveis de entrada via lista de parâmetros. Esta
deverá ainda assim conter a palavra vazio indicando a intenção da não existência de
parâmetros.
Os comandos da função, bem como as declarações de variáveis locais a função,
são delimitados pelos marcadores de inicio e fim. Todos os comandos apresentados
até o presente momento poderão ser utilizados nas funções. É neste local que é realizada
a tarefa para qual função foi projetada.
Desde modo tem um algoritmo, com a existência de uma função, a seguinte
aparência.

#incluir biblioteca
/* Declaração das bibliotecas utilizadas */

#definir constante ou macro


/* Declaração de constantes, entre outras */

tipo_de_retorno nome_da_funcao ([lista_de_parametros])


inicio

/* Declaração das variáveis locais */

Comandos;

retorno (expressao);

fim

...

principal( ) /* Função principal do algoritmo */


inicio /* Inicio do escopo / bloco principal */

/* Declaração de variáveis locais */


/* Comandos */

/* chamadas ou invocações de funções */

71
variavel = nome_da_funcao (variaveis) ;

/* Retorno de erro ou Ok */

fim /* Final do escopo / bloco principal */

A declaração de variáveis locais da função permanece idêntica às declarações no


algoritmo principal. Assim, podem ser definidas variáveis do tipo: inteiro, real ou
caractere – para citar apenas três, da mesma forma que no algoritmo. A diferença está no
acesso, uma vez que, as variáveis definidas internamente na função são de uso exclusivo
da mesma. Sendo assim, nenhuma outra função poderá ter acesso a estas variáveis, nem
mesmo o algoritmo principal.

Exemplo 4.1 - Criar um algoritmo com uma função capaz de calcular o quadrado de um
número.

#incluir <stdio.h>
#incluir <conio.h>

inteiro quadrado (inteiro n)


inicio
retorno (n * n);
fim

principal ()
inicio

inteiro num,q;

imprima ("Entre com um numero: ");


leia ("%d",&num);

q = quadrado (num);

imprima ("\nQuadrado do numero %d e = %d",num,q);

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */
retorno (0);
fim

Exemplo 4.2 - Tomando o exemplo anterior (ex. 4.1), crie um algoritmo que utilize uma
outra função para calcular o cubo de um número.

#incluir <stdio.h>
#incluir <conio.h>

inteiro cubo (inteiro x)


inicio
retorno (x * x * x);
fim

72
principal ()
inicio

inteiro num,c;

imprima ("Entre com um numero: ");


leia ("%d",&num);

c = cubo (num);

imprima ("\nCubo do numero %d e = %d",num,c);

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */
retorno (0);
fim

Exemplo 4.3 - Tomando os exemplos anteriores (ex. 4.1 e 4.2), crie um algoritmo que
utilize duas funções para calcular o cubo de um número. Se possível
também calcule o quadrado no mesmo algoritmo.

#incluir <stdio.h>
#incluir <conio.h>

inteiro cubo (inteiro x)


inicio
retorno (quadrado(x) * x);
fim

inteiro quadrado (inteiro n)


inicio
retorno (n * n);
fim

principal ()
inicio
inteiro num,r;

imprima ("Entre com um numero: ");


leia ("%d",&num);

r = quadrado (num);
imprima ("\nQuadrado do numero %d e = %d",num,r);

r = cubo (num);
imprima ("\nCubo do numero %d e = %d\n",num,r);

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */
retorno (0);
fim

73
O comando retorno presente em cada função é a maneira que a função tem para
devolver um valor ao algoritmo ou a outra função que a tenha invocado. O comando
returno aparece nas funções da seguinte forma.

retorno(valor_de_retorno);

ou

retorno();

Suponha que uma função está sendo executada. Quando se chega a uma
declaração retorno a função é encerrada imediatamente e, se o valor de retorno é
informado, a função devolve este valor. É importante lembrar que o valor de retorno
fornecido tem que ser compatível com o tipo de retorno declarado para a função. Assim
como a variável ou a expressão onde a função está inserida deve ser capaz de armazenar
ou utilizar corretamente o valor recebido da função.
Uma função pode ter mais de uma declaração retorno. Uma vez que a função
é terminada quando o algoritmo chega à primeira declaração retorno, podem-se ter
várias declarações de retorno em uma mesma função sem no entanto comprometer
seu funcionamento lógico.
A seguir outro exemplo de uso do comando retorno.

Exemplo 4.4 - Criar um algoritmo que utilize uma função para determinar se um
número fornecido pelo usuário é par ou ímpar.

#incluir <stdio.h>
#incluir <conio.h>

inteiro ePar (inteiro n)


inicio

se (n resto 2) /* verifica se e divisivel por 2 */


inicio
retorno (0); /* 0 se NAO for divisível */
fim
senao
inicio
retorno (1); /* 1 se for divisível */
fim
fim

principal ()
inicio
inteiro num;

imprima ("Entre com um numero: ");


leia ("%d",&num);

se (ePar(num))
inicio

74
imprima ("\nNumero %d e Par",num);
fim
senao
inicio
imprima ("\nNumero %d e Impar",num);
fim
imprima ("\npressione qualquer tecla...");
getch(); /* Aguarda uma tecla para finalizar */
retorno (0);
fim

É importante notar que, como as funções retornam valores, podemos aproveitá-


los para fazer atribuições, ou mesmo para que estes valores participem de expressões.
No exemplo anterior (ex. 4.4) vê-se o uso de mais de um comando retorno em uma
função.

Exercício 4.1 -Escreva a função eDivisivel (inteiro a, inteiro b),


tenha o exemplo anterior (ex. 4.4) como modelo. A função deverá
retornar 1 (um) se o resto da divisão de a por b for zero. Caso contrário,
a função deverá retornar 0 (zero).

Exemplo 4.5 - Este algoritmo que executa as 4 operações aritméticas (adição, subtração,
divisão e multiplicação). Por questões de legibilidade do código, o
algoritmo foi subdivido em quatro funções. Estas funções retornam o
valor calculado para a função principal no algoritmo.

#incluir <stdio.h>
#incluir <conio.h>

inteiro Soma (inteiro a, inteiro b)


inicio
retorno (a + b);
fim

inteiro Subtracao (inteiro a, inteiro b)


inicio
retorno (a - b);
fim

inteiro Multi (inteiro a, inteiro b)


inicio
retorno (a * b);
fim

real Divide (inteiro a, inteiro b)


inicio
retorno (a / b);
fim

principal ()
inicio

75
inteiro vlr1, vlr2, opcao;
real resultado;

faca
inicio
resultado = 0;
imprima ("Entre com um valor: ");
leia ("%d",&vlr1);
imprima ("Entre com outro valor: ");
leia ("%d",&vlr2);

imprima ("1 - Soma\n2 - Subtracao\n");


imprima ("3 - Multiplica\n4 - Divide\n");
imprima ("5 - Sair\n");
leia ("%d",&opcao);

escolha (opcao)
inicio
caso 1 : resultado = Soma(vlr1, vlr2);
pare;
caso 2 : resultado = Subtracao(vlr1, vlr2);
pare;
caso 3 : resultado = Multi(vlr1, vlr2);
pare;
caso 4 : se (vlr2 != 0)
inicio
resultado = Divide(vlr1, vlr2);
fim
senao
inicio
imprima ("Divisao por zero!\n");
fim
pare;
caso 5 : imprima ("Até logo\n");
pare;
padrao : imprima ("Opcao invalida!\n");
pare;
fim
imprima ("\nResultado = %.2f\n", resultado);
fim
enquanto (opcao != 5);

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */
retorno (0);
fim

Exemplo 4.6 - Criar um algoritmo que utilize funções para calcular a seguinte
seqüência. S(x,n) = x/1! + x2/2! + x3/3! + ... +
xn/n!

#incluir <stdio.h>

76
#incluir <conio.h>

inteiro fat (inteiro n)


inicio
inteiro k, f = 1;

para (k = 1; k <= n; k++)


inicio
f = f * k;
fim

retorno (f);

fim

real pot (real base, inteiro expo)


inicio
inteiro j;
real p = 1.0;

se (expo == 1)
inicio
retorno (base);
fim

para (j = 1; j <= expo; j++)


inicio
p = p * base;
fim

retorno (p);
fim

real serie (real x, inteiro n)


inicio

inteiro i;
real s = 0.0;

para (i = 1; i <= n; i++)


inicio
s = s + pot(x,i) / fat(i);
fim

retorno (s);
fim

principal ()
inicio
real x;
inteiro termos;

imprima ("Entre com o numero de termos: ");

77
leia ("%d",&termos);
imprima ("Entre com o valor de x: ");
leia ("%f",&x);

imprima ("\nSerie = %f", serie(x,termos));

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */
retorno (0);
fim

4.1.1 Exercícios propostos

Exercício 4.2 – Faça um algoritmo que leia um número inteiro e crie uma função que
devolva o seu módulo sem usar nenhuma função disponível em C para
essa finalidade.

Exercício 4.3 – Faça um algoritmo que possua uma função que determine se um ano
introduzido pelo usuário é ou não bissexto. Um ano é bissexto se for
múltiplo de 4 sem ser de 100 ou se for múltiplo de 400. A função deve
retornar 1 se o ano é bissexto e 0 (zero) caso contrário.

Exercício 4.4 - Criar um algoritmo com uma função que verifica se um número
fornecido pelo usuário é ímpar.

Exercício 4.5 - Desenvolver um algoritmo com uma função que calcule a Hipotenusa
de um triângulo retângulo a partir da leitura de seus Catetos na parte
principal do algoritmo. Estes serão passados a função por meio de
parâmetros.

Exercício 4.6 - Faça um algoritmo com uma função que devolverá 1 se o número
passado por parâmetro for primo e 0 (zero) se não for.

Exercício 4.7 – Faça um algoritmo com uma função que calcule o salário semanal de
um funcionário. Deve ser lido o número total de horas (valor inteiro)
de trabalho desse funcionário durante a semana, o custo de uma hora
normal e o custo de uma hora extraordinária. Para calcular o salário,
deve-se considerar como horas normais as 40 primeiras e como horas
extraordinárias (se existirem) as restantes horas de trabalho.

Exercício 4.8 – Deseja-se calcular a conta de consumo de energia elétrica de um


consumidor. Para isto, escreva um algoritmo que leia o código do
consumidor, o preço do Kw e a quantidade de Kw consumido, e exiba
o código do consumidor e o total a pagar. Calcule este último usando
uma função. Mostre os dados a seguir no algoritmo principal.

total a pagar = preco x quantidade


total a pagar minimo = R$ 13,20

78
Exercício 4.9 – Escreva um algoritmo para ler três números inteiros distintos e com
uma função para determinar o menor deles.

Exercício 4.10 – Faça um algoritmo que, dado as três notas de um aluno, determine e
exiba a sua média final (uma função) e o seu conceito (outra função),
sabendo-se que: a média final é calculada pela média aritmética das 3
notas; o conceito é determinado de com base na tabela abaixo:

Média Final Conceito


≥ 8,0 A
≥ 6,0 e < 8,0 B
< 6,0 C

Exercício 4.11 - Desenvolver um algoritmo que leia dois valores e chame uma sub-
rotina (função) que receba estas duas variáveis e troque o seu
conteúdo, ou seja, esta rotina é chamada passando duas variáveis A e
B por exemplo, e após a execução da rotina A conterá o valor de B e B
conterá o valor de A. Lembre-se de utilizar a passagem de parâmetros
por referência.

Exercício 4.12 - Crie uma função fatorial, como dado em aula anterior. Testar essa
função fazendo um algoritmo que calcule o fatorial de um número
fornecido pelo usuário.

Exercício 4.13 - Utilizando a função criada no exemplo anterior (ex. 4.4) faça um
programa que irá solicitar números inteiros ao usuário até que este
introduza um número negativo. Para cada valor introduzido, o
programa deve indicar se o número é par ou ímpar.

Exercício 4.14 - Faça uma função que devolva números aleatórios inteiros. A função
deverá receber um parâmetro n que indique a gama de valores
pretendidos e, a cada vez que for chamada, devolva um número
aleatório inteiro no intervalo [0 .. n-1].

Por exemplo, se a função for chamada com o parâmetro 6, deverá devolver um número
aleatório compreendido entre 0 e 5 (inclusive).

Exercício 4.15 - Utilizar a função que acabastes de criar no exercício anterior para
fazer um programa que simule atirar uma moeda ao ar 1000 vezes. O
programa deve contar quantas vezes saíram "cara" e quantas vezes
saíram "coroa".

Exercício 4.16 - Faça um algoritmo que gere 1000 números reais aleatórios no
intervalo [0,1]. O programa deve contar quantos números caem no
intervalo [0.0, 0.5], quantos caem no intervalo [0.5, 0.8] e
quantos caem no intervalo [0.8, 1.0].

Obs.: Para os exercícios 4.14, 4.15 e 4.16 ver as dicas a seguir.

79
Dicas para gerar números aleatórios:

A linguagem C tem as funções randomize ( ), rand ( ), random ( ) e srand ( )


para gerar números inteiros pseudo-aleatórios. Estas funções geram os ditos números a
partir de algoritmos mais ou menos elaborados e cuja implementação varia ligeiramente
de compilador para compilador. A função rand ( ) gera números aleatórios do tipo
inteiro pertencentes ao intervalo [0 .. 32767], veja a constante RAND_MAX.

Para gerar números aleatórios a pedido (por exemplo, apenas dentro de um


determinado intervalo, ou números reais em vez de inteiros) temos que trabalhar com
estes elementos, fornecendo-lhes os parâmetros adequados.

As funções randomize ( ), rand ( ), random ( ) e srand ( ) estão definidas na


biblioteca <stdlib.h> e alguns parâmetros dependem da biblioteca <time.h>.

4.2 Funções sem retorno

Uma função sem retorno é um bloco de código precedido de um cabeçalho que


contém a palavra vazio, o nome da função e sua lista de parâmetros. Desta forma,
pode-se fazer referência ao bloco de código de qualquer ponto do algoritmo por meio do
seu nome e passando os seus parâmetros. Em relação ao nome da função, sua lista de
parâmetros e variáveis locais, todos estão sujeitos às mesmas regras aplicadas às
funções com retorno.
Uma função sem retorno distingui-se de outra função com retorno por não
devolver valor algum ao algoritmo principal ou ao outro módulo que tenha invocado sua
chamada.

Sintaxe:

vazio nome_da_funcao ([lista_de_parametros])


inicio

/* Declaração das variáveis locais */

Comandos;

fim

Referência, chamada ou invocação da função na seção de comandos do


algoritmo:

nome_da_funcao (variaveis) ;

O nome da função sem retorno é dado pelo programador e precisa seguir as


mesmas regras utilizadas para nomear as variáveis e as constantes.
Na lista de parâmetros encontram-se as variáveis que devem ser passadas a
função no momento de sua chamada ou invocação. Esta lista apresenta-se da seguinte
maneira.

80
tipo variavel1, tipo variavel2, ... , tipo variavelN

As variáveis passadas as funções sem retorno são associadas aos parâmetros da


função de acordo com a ordem das variáveis e da lista de parâmetros. Os [ ] na sintaxe
do cabeçalho da função sem retorno indicam que a lista de parâmetros é opcional,
permitindo assim a criação de funções que não recebem variáveis de entrada via lista de
parâmetros. Esta deverá ainda assim conter a palavra vazio indicando a intenção da
não existência de parâmetros.
Os comandos da função sem retorno, bem como as declarações de variáveis
locais a função, são delimitados pelos marcadores de inicio e fim. Todos os
comandos apresentados até o presente momento poderão ser utilizados nas funções sem
retorno. É neste local que é realizada a tarefa para qual função foi projetada.
Desde modo tem um algoritmo, com a existência de uma função sem retorno, a
seguinte aparência.

#incluir biblioteca
/* Declaração das bibliotecas utilizadas */

#definir constante ou macro


/* Declaração de constantes, entre outras */

vazio nome_da_funcao ([lista_de_parâmetros])


inicio

/* Declaração das variáveis locais */

Comandos;
fim

...

principal( ) /* Função principal do algoritmo */


inicio /* Inicio do escopo / bloco principal */

/* Declaração de variáveis locais */


/* Comandos */

/* chamadas ou invocações de funções */

nome_da_funcao (variaveis) ;

/* Retorno de erro ou Ok */

fim /* Final do escopo / bloco principal */

Em uma função sem retorno não é necessário utilizar o comando retorno no


interior da mesma.

Exemplo 4.7 - Faça um algoritmo que possua uma função para mostrar mensagem
“Aprendendo a programar com VAZIO” na tela.

81
#incluir <stdio.h>
#incluir <conio.h>

vazio mensagem (vazio)


inicio
imprima ("Aprendendo a programar com VAZIO\n");
fim

principal ()
inicio
mensagem();

imprima ("\npressione qualquer tecla...");


getch(); /* Aguarda uma tecla para finalizar */
retorno (0);
fim

Exemplo 4.8 - Algoritmo com saudações e cálculo do quadrado de um número.

#incluir <stdio.h>
#incluir <conio.h>

inteiro quadrado (inteiro x)


inicio
retorno (x * x);
fim

vazio saudacao (vazio)


inicio
imprima ("\nOla!\n");
fim

vazio despedida (vazio)


inicio
imprima ("\nFim do Algoritmo.\n");
fim

principal ()
inicio
inteiro num, r;

saudacao ();

imprima ("Digite um numero inteiro: ");


leia ("%d", &num);
r = quadrado (num);
imprima ("Quadrado de %d eh %d.\n", num, r);

despedida ();

imprima ("\npressione qualquer tecla...");

82
getch(); /* Aguarda uma tecla para finalizar */
retorno (0);
fim

Vê-se acima uma função sem retorno e sem parâmetros. Para que uma função
retorne algo, deve-se usar a comando retorno, bem como especificar o seu tipo de
retorno. Para funções sem retorno, basta declarar a função como tendo tipo de retorno
vazio.
Deve-se lembrar que a função principal( ) é uma função e como tal deve-
se tratá-la. O C Quietly e por conseqüência o compilador C assume que a função
principal( ) deve retornar um valor inteiro. Isto dá ao sistema operacional um
valor de retorno da função principal( ). Deve-se lembrar da seguinte convenção:
se o algoritmo retornar 0 (zero), significa que ele terminou normalmente, e, se o
algoritmo retornar um valor diferente de zero, significa que o algoritmo teve um término
anormal. Há ainda a possibilidade de a função principal( ) não devolver nada ao
SO (Sistema Operacional) se este for o seu desejo, veja como proceder a seguir.

vazio principal(vazio)
inicio

/* Comandos */

fim

ou

principal(vazio)
inicio

/* Comandos */

retorno (0);
fim

A segunda forma é válida porque, as funções em linguagem C têm, por padrão, o


tipo de retorno inteiro. Isto pode não ser compatível com alguns compiladores C,
sendo assim, tenha por hábito explicitar o valor de retorno sempre.

4.2.1 Exercícios propostos

Exercício 4.17 - Criar uma função sem parâmetros que exiba na tela um menu com as
seguintes opções: Incluir, Remover, Alterar e Sair. Cada opção deve
estar em uma linha separada.

Exercício 4.18 - Criar uma função sem parâmetros que desenhe uma moldura na tela
do microcomputador. Faça no algoritmo principal uma chamada a esta
função, desenhando a moldura e após escrevendo "Hello World"
da tela. Para desenhar a moldura use os caracteres especiais da tabela
ASCII estendida.

83
Exemplos:
Pressione a tecla ALT e ao mesmo tempo um dos seguintes números
no teclado numérico - ALT + 200, ALT + 201, ALT + 205, ALT +
186, ALT + 187, ALT + 188.

Exercício 4.19 - Tendo como dados de entrada a altura e o sexo (M ou F) de uma


pessoa, construa um algoritmo que possua uma função sem retorno
para calcular e mostrar seu peso ideal, utilizando as seguintes
fórmulas:

Para Homens: ( 72.7 * altura ) - 58


Para Mulheres: ( 62.1 * altura) - 44.7

Exercício 4.20 - Altere o algoritmo anterior de maneira que quando o usuário apertar
uma tecla (tecla = getch()), seja escrito "Bye-Bye World”
na tela. O programa deve terminar automaticamente após um atraso
(sleep ou delay) de 5 segundos.

84
5 Estruturas e classes

A seguir, apresentam-se os conceitos de estruturas de armazenamento e o uso de


classes para definição e criação de objetos, ou seja, novos tipos para a linguagem de
programação.

5.1 Estruturas

Por meio de estruturas, as linguagens C/C++ oferecem um mecanismo uniforme


para a definição de unidades de informações organizadas em grupos ou campos. A
forma geral de definição de uma estrutura em algoritmo e no C Quietly é a seguinte:
Sintaxe:

estrutura nome
inicio

/* declaracao de componentes */
...

fim [variavel1, varariavel2, ..., variavelN] ;

A palavra chave estrutura inicia a definição da estrutura. O nome é


opcional, porém deve estar presente caso se deseje referenciar esta estrutura em algum
momento posterior. Da mesma forma, a lista de variáveis declaradas variavel1,
varariavel2, ..., variavelN também não precisa estar presente, a não ser
que o nome não esteja presente. Quando o nome está presente, as variáveis com essa
mesma estrutura podem ser definidas posteriormente, como na declaração a seguir,

estrutura nome_da_estrutura nome_da_variavel;

que define nome_da_variavel como sendo uma variável do tipo estrutura


nome_da_estrutura.

Uma estrutura é uma coleção de um ou mais variáveis agrupadas sob um


mesmo nome o que facilita a manipulação destes dados. As variáveis na estrutura,
diferentes dos vetores, podem conter diferentes tipos de variáveis. Uma estrutura pode
conter quaisquer tipos de dados da linguagem C, como inteiros, fracionários, caracteres,
vetores e outras estruturas. Cada variável na estrutura é chamada de membro da
estrutura.

85
5.1.1 Definindo e declarando estruturas

Formas geométricas necessitam de coordenadas que as delimitam. Um ponto no


espaço é representado pelas coordenada x e y. O valor de x representa a posição
horizontal e o valor de y a posição vertical. Assim quadrados, retângulos e outras formas
geométricas precisam de coordenadas para serem representados. Pode-se definir uma
estrutura chamada coord (coordenada) que contém ambos os valores de x e y. Como
apresentado (ex. 5.1) a seguir:

Exemplo 5.1 – Criando as estruturas para sua utilização no algoritmo.

#incluir <stdio.h>
#incluir <conio.h>

principal ( )
inicio

/* definição da estrutura */

estrutura coord
inicio
inteiro x;
inteiro y;
fim ;

imprima ("\npressione qualquer tecla...");


getch (); /* Aguarda uma tecla para finalizar */

retorno (0);
fim

A palavra reservada estrutura, a qual identifica o início da definição da


estrutura, deve ser seguida pelo nome da estrutura (o qual segue as mesmas regras de
nomes de outras variáveis em linguagem C). Entre as palavras inicio e fim está à
lista de variáveis membros da estrutura. Ë necessário dar um tipo e um nome para cada
variável membro.
O exemplo anterior (ex. 5.1) define a estrutura chamada coord que contém
duas variáveis inteiras, x e y. Isto, no entanto, não cria nenhuma instância da estrutura
coord. A estrutura está apenas definida e ainda não foram declaradas variáveis para
esta estrutura. Existem duas formas de se declarar variáveis para as estruturas. A
primeira, segue a definição da estrutura com uma lista de uma ou mais nomes de
variáveis, como mostrado (ex. 5.2) logo a seguir.

Exemplo 5.2 – Criando as estruturas e definindo as variáveis para sua utilização no


algoritmo.

#incluir <stdio.h>
#incluir <conio.h>

86
principal()
inicio

/* definição da estrutura e declaração de variáveis */

estrutura coord
inicio
inteiro x;
inteiro y;
fim primeira, segunda;

imprima ("\npressione qualquer tecla...");


getch (); /* Aguarda uma tecla para finalizar */
retorno (0);
fim

O exemplo (ex. 5.2) define a estrutura chamada coord e declara duas


estruturas, primeira e segunda , do tipo coord. primeira e segunda são cada
uma, uma instância do tipo coord. primeira contém dois membros inteiros
chamados, x e y, assim como segunda.
Este método de declaração de estruturas combina a declaração com a definição.
O segundo método consiste em declarar as variáveis de estruturas em uma localização
diferente no código fonte da definição. O exemplo (ex. 5.3) a seguir também declara
duas instâncias do tipo coord.

Exemplo 5.3 – Criando as estruturas e definindo as variáveis para sua utilização no


algoritmo, segundo método.

#incluir <stdio.h>
#incluir <conio.h>

principal()
inicio

/* definição da estrutura */

estrutura coord
inicio
inteiro x;
inteiro y;
fim ;

/* declaração das variáveis da estrutura */

estrutura coord primeira, segunda ;

imprima ("\npressione qualquer tecla...");


getch (); /* Aguarda uma tecla para finalizar */
retorno (0);
fim

87
5.1.2 Acessando os membros de estruturas

Cada membro da estrutura pode ser utilizado como outras variáveis do mesmo
tipo. Os membros da estrutura são acessados através do operador (.), também chamado
de operador ponto, entre o nome da variável da estrutura e o nome de cada membro.
Para atribuir a variável primeira as coordenadas x = 2 e y = 3, deve-se escrever o
código a seguir.

primeira.x = 2;
primeira.y = 3;

Logo a seguir, vê-se como mostrar o conteúdo armazenado na variável segunda.

imprima ("%d,%d",primeira.x, primeira.y);

Uma vantagem de utilizarem-se estruturas ao invés de variáveis declaradas


separadamente está em poder copiar informações entre estruturas em uma única
operação como mostrado a seguir.

segunda = primeira;

é equivalente a

segunda.x = primeira.x;
segunda.y = primeira.y;

Quando o algoritmo utiliza complexas estruturas com muitos membros, esta


notação pode economizar um bom tempo. Outra vantagem é a possibilidade de tratar
diferentes tipos de variáveis em um grupo único, como os dados de uma pessoa.

Exemplo 5.4 – Criando as estruturas data e hora e definindo as variáveis para sua
utilização no algoritmo.

#incluir <stdio.h>
#incluir <conio.h>

principal()
inicio

/* definição da estrutura e declaração da variável */

estrutura data
inicio
inteiro mes;
inteiro dia;
inteiro ano;
fim data_atual ;

/* definição da estrutura, declaração da variável


com inicialização */

88
estrutura hora
inicio
inteiro h;
inteiro min;
inteiro seg;
fim hora_do_nascimento = { 22, 20, 0 } ;

imprima ("\npressione qualquer tecla...");


getch (); /* Aguarda uma tecla para finalizar */
retorno (0);
fim

5.1.3 Estruturas mais complexas

São estruturas que contém outras estruturas como membros e estruturas que
contém vetores como membros. Assim, além dos tipos primitivos uma estrutura pode
conter outras estruturas, como demonstra o próximo exemplo (ex. 5.5). O exemplo
anterior (ex. 5.3) foi estendido para ilustrar está uma estrutura complexa.
Imagine que você deseje representar um retângulo. Um retângulo pode ser
representado pelas duas coordenadas diagonais dos cantos opostos. Têm-se até este
momento uma forma de representar um ponto por meio de duas coordenadas (x,y). O
exemplo (ex. 5.5) a seguir define a estrutura para representar estruturas de retângulos. A
estrutura de coordenadas de ponto também se faz presente neste exemplo, uma vez que
sua definição é imprescindível.

Exemplo 5.5 – Criando as estruturas mais complexas e definindo as variáveis para sua
utilização no algoritmo.

#incluir <stdio.h>
#incluir <conio.h>

principal( )
inicio

/* definição das estruturas */

estrutura coord
inicio
inteiro x;
inteiro y;
fim ;

estrutura retangulo
inicio
estrutura coord infEsquerdo;
estrutura coord supDireito;
fim ;

/* declaração da variável da estrutura */

89
estrutura retangulo caixa ;

imprima ("\npressione qualquer tecla...");


getch (); /* Aguarda uma tecla para finalizar */
retorno (0);
fim

Figura 5.1 – Um retângulo representado no plano cartesiano1.

O algoritmo (ex. 5.5) anterior define a estrutura do tipo retangulo que


contém duas estruturas do tipo coord. Estas duas estruturas coord são chamadas de
infEsquerdo e supDireito. A declaração da estrutura aparece no algoritmo logo
após sua definição e é chamada de caixa.
Para combinar a definição com a declaração como realizado com a estrutura
coord, siga o modelo seguinte.

estrutura retangulo
inicio
estrutura coord infEsquerdo;
estrutura coord supDireito;
fim caixa ;

Para se ter acesso à localização dos dados (membros do tipo inteiro), é


necessário aplicar o operador (.) duas vezes. Assim,

caixa.infEsquerdo.x

refere-se ao membro x do membro infEsquerdo (canto inferior esquerdo) do tipo


estrutura retangulo chamada caixa.
Para definir um retângulo com coordenadas (5,10) e (50, 30), escreve-se:

caixa.infEsquerdo.x = 5;
caixa.infEsquerdo.y = 10;
caixa.supDireito.x = 50;
caixa.supDireito.y = 30

A figura anterior (fig. 5.1) mostra a relação entre a estrutura retangulo, as


duas coordenadas, que neste caso são (0,0) e um ponto P qualquer maior que este que a
estrutura retangulo contém e as duas variáveis inteiras que a estrutura coord
possui.
A seguir um exemplo (ex. 5.6) de um algoritmo para realizar o cálculo da área de
1
Considere um plano e duas retas perpendiculares, sendo uma delas horizontal e a outra vertical.
A horizontal será denominada Eixo das Abscissas (eixo OX) e a Vertical será denominada Eixo das
Ordenadas (eixo OY). Os pares ordenados de pontos do plano são indicados na forma P = (x,y) onde x
será a abscissa do ponto P e y a ordenada do ponto P.

90
um retângulo a partir da solicitação de coordenadas ao usuário.

Exemplo 5.6 – Desenvolver um algoritmo que solicite ao usuário a entrada de duas


coordenadas referentes aos cantos inferior esquerdo e superior direto
da diagonal de um retângulo. Calcular e mostrar a área total do
retângulo formado pelas coordenadas obtidas.

#incluir <stdio.h>
#incluir <conio.h>

principal()
inicio
inteiro compto, largura;
real area;

estrutura coord
inicio
inteiro x;
inteiro y;
fim ;

estrutura retangulo
inicio
estrutura coord infEsquerdo;
estrutura coord supDireito;
fim ;

estrutura retangulo caixa ;

imprima ("Entre com a coordenada x inf esq:");


leia ("%d",&caixa.infEsquerdo.x);

imprima ("Entre com a coordenada y inf esq:");


leia ("%d",&caixa.infEsquerdo.y);
imprima ("Entre com a coordenada x sup dir:");
leia ("%d",&caixa.supDireito.x);

imprima ("Entre com a coordenada y sup dir:");


leia ("%d",&caixa. supDireito.y);

compto = caixa.supDireito.x - caixa.infEsquerdo.x;


largura = caixa.supDireito.y - caixa.infEsquerdo.y;

area = compto * largura;

imprima ("\nArea = %.2f",area);

imprima ("\npressione qualquer tecla...");


getch (); /* Aguarda uma tecla para finalizar */
retorno (0);
fim

91
5.1.4 Exercícios propostos

Exercício 5.1 – Faça um algoritmo que calcule a hipotenusa entre dois pontos a partir
das coordenadas da diagonal de triângulo retângulo.

Exercício 5.2 – Faça um algoritmo que calcule a área de triângulo retângulo a partir
das coordenadas da diagonal de dois pontos.

5.2 Classes

Um algoritmo que utiliza classes apresenta características de programas


orientados a objetos, foco das próximas seções. Antes porém, veja alguns conceitos de
programação que antecedem a programação orientada a objetos. Estes conceitos ainda
são utilizados freqüentemente, uma vez que todas essas formas de programação são
técnicas e podem ser utilizadas livremente, dependendo da necessidade de representação
da solução do problema a enfrentar.

5.2.1 Programas desestruturados

Normalmente, as pessoas iniciam a criação de pequenos algoritmos ou


programas que consiste de um único programa principal. O algoritmo principal contém
a seqüência de comandos e estruturas de decisões e repetições, além dos dados que de
acesso global ou seja, quaisquer partes do algoritmo podem modificar o conteúdo das
variáveis.
Esta técnica apresenta desvantagens, uma vez que grandes algoritmos/programas
acabam necessitando de cópias de seqüências ou de estruturas em várias partes do
algoritmo, além de o algoritmo principal ter acesso aos dados globais como mostra a
figura (fig. 5.2) a seguir. Uma forma de minimizar este fato é utilizando chamada de
módulos e seu retorno.

Algoritmo
principal(){
dados
}

Figura 5.2 – Algoritmo desestruturado.

5.2.2 Programas estruturados

Com algoritmos estruturados é possível combinar retorno de resultados em um


único lugar, a saída da função. Para chamar a função basta invocar seu nome e passar a
sua lista de parâmetros, caso exista. Após a seqüência de execução da função o fluxo
retorna para a instrução seguinte de onde foi chamada a função.

92
Uma vez que o código de uma função e os seus parâmetros foram testados e
estando estes livres de erros, eles estarão corretos para cada invocação da função. Agora
o algoritmo consiste de uma seqüência (fig. 5.3) de chamadas às funções e que facilita a
reutilização do código inclusive em outros algoritmos e a localização e identificação de
erros em cada módulo em separado. Cada módulo pode possuir seus próprios dados,
também.

Algoritmo
principal () {
dados
}

funçao1 funçao2 funçaoN

Figura 5.3 – Algoritmo modular.

5.2.3 Programas orientados a objetos

Algoritmo

Obejto1 Obejto3
dados1 dados3

Obejto2
dados2

Figura 5.4 – Algoritmo orientados a objetos.

A definição de classes bem como a criação de instâncias de objetos (fig. 5.4)


difere um pouco da definição de dados em programas estruturados.
Criar a solução de um problema usando o conceito de abstração, ou seja, usando
classes pode se tornar uma tarefa simples ou não dependendo da complexidade da
solução a representar. Trate o problema com sendo um objeto do mundo real, levante
suas características (dados) e suas ações (métodos).

93
5.2.4 Declarando classes

No C Quietly com a opção do compilador C/C++ (marcada) é possível à


definição e declaração de classes. Uma instância de uma classe é chamada de objeto.
Para definir uma nova classe utiliza-se a palavra reservada classe seguida de um
nome (mesmas regras para nomes de variáveis e constantes simbólicas). inicio e fim
delimitam os dados (atributos) e funções (métodos) da classe. publico, privado e
protegido caracterizam o tipo de acesso externo aos atributos e métodos da
classe.Sintaxe a seguir.

classe nome_da_classe
inicio
/* declarações de variáveis e métodos privados */;

publico:
/* declarações de variáveis e métodos publicos */;

fim

Uma classe se parece com uma estrutura em termos de atributos ou dados, assim
como uma estrutura é construída para agrupar algumas variáveis em um mesmo local de
fácil acesso, também as classes permitem a abstração de dados, por meio de variáveis de
diversos tipos.
Em um programa que utiliza uma interface controladora de um motor elétrico
provavelmente definiria-se uma classe chamada motor. Os atributos desta classe
seriam: temperatura, velocidade, tensão_aplicada. Estes provavelmente
seriam representados na classe por tipos como real ou inteiro. As funções membro
ou métodos desta classe seriam funções para alterar a velocidade, ler a temperatura, etc.
Outro programa de contas a pagar e contas a receber definiria-se a classe
conta_bancaria. Os atributos seriam: saldo, limite_de_saque,
taxa_de_juros, etc, representados como variáveis do tipo real. Dentre as funções
membros desta classe estariam às funções para: efetuar saques, depósitos e computar
juros. Estes são alguns exemplos de abstrações de situações encontradas no mundo real
por meio da definição classes para representá-los.
Objetos são instâncias de uma classe. Quando um objeto é criado ele precisa ser
inicializado, ou seja, para uma única classe. A classe Estudante de graduação
pode ter vários objetos em um mesmo algoritmo. Estudante de graduação João,
Matrícula 567418, Curso Engenharia Mecânica; Estudante de graduação
Márcia, Matrícula 982349, Curso Engenharia Elétrica... A classe representa
somente o molde para a criação dos objetos, estes sim contém a informação.

Exemplo 5.7 – Definir a classe Ponto e sua interface (não há necessidade de


implementá-la neste instante). Declare ainda dois objetos para esta
classe.

#incluir <iostream.h>

classe Ponto
inicio

94
inteiro x, y;

publico:
vazio setaX (inteiro vx);
vazio setaY (inteiro vy);
inteiro obtemX ( );
inteiro obtemY ( );
fim;

principal ( )
inicio

Ponto p1, p2;

retorno (0);
fim

As funções complementam e compõem a interface da classe. A terminologia


usada para designá-las é bastante variada: funções membro, métodos, etc. Quando uma
função membro é chamada, se diz que o objeto está recebendo uma mensagem (para
executar uma ação).
A sintaxe para declaração de funções membro dentro de uma classe é a mesma
sintaxe de declaração de funções comuns, exceto pelo :: precedido do nome da classe:

tipo_de_retorno nome_classe :: nome_funcao ([parâmetros])


inicio

/* Declaração das variáveis locais */

Comandos;

retorno (expressao);

fim

Exemplo 5.8 – Definir a classe Ponto e sua interface. Declare ainda dois objetos para
esta classe.

#incluir <iostream.h>
#incluir <conio.h>

classe Ponto
inicio
inteiro x, y;

publico:
vazio setaX (inteiro vx);
vazio setaY (inteiro vy);
inteiro obtemX ( ) inicio retorno (x); fim
inteiro obtemY ( ) inicio retorno (y); fim
fim;

95
vazio Ponto::setaX (inteiro vx)
inicio
x = vx;
fim
vazio Ponto::setaY (inteiro vy)
inicio
y = vy;
fim

principal ()
inicio

Ponto p1, p2;

retorno (0);
fim

A diferença é que como a função membro está definida na classe, ela ganha
acesso direto aos dados membros ou atributos, sem precisar usar o "ponto", exemplo:

um_objeto.dadomembro

As funções setaX e setaY foram definidas fora da classe, já as funções


obtemX e obtemY são definidas inline, ou seja, dentro da própria definição da classe,
uma vez que seu código não prejudica a clareza da definição da classe.

5.2.5 Permitindo o acesso aos membros da classe

privado e publico qualificam os dados membro e funções membro de uma


classe quanto ao tipo de acesso (onde eles são visíveis), isto é chamado de
encapsulamento. Suponha que você instanciou (criou) um objeto do tipo ponto em seu
algoritmo:

Ponto p; /* instanciacao */

Segundo o uso de qualquer uma das definições da classe Ponto dada


anteriormente não se pode escrever no algoritmo:

p.x = 2; /* Erro! */

mas da forma seguinteestá correto,

p.setaX (2); /* Correto! */

Aplicando encapsulamento a classe Ponto definida anteriormente.

Exemplo 5.9 – Definir a classe Ponto e sua interface. Declare ainda dois objetos para
esta classe. Represente as coordenadas de um retângulo.

96
#incluir <iostream.h>
#incluir <conio.h>

classe Ponto
inicio
privado:
inteiro x;
inteiro y;

publico:
vazio setaX (inteiro vx) inicio x = vx; fim;
vazio setaY (inteiro vy) inicio y = vy; fim;
vazio coordXY (inteiro vx, inteiro vy);
inteiro obtemX( ) inicio retorno (x); fim
inteiro obtemY( ) inicio retorno (y); fim
vazio mostraXY ( );
fim;

vazio Ponto::coordXY (inteiro vx, inteiro vy)


inicio
x = vx;
y = vy;
fim

vazio Ponto::mostraXY ( )
inicio
csaida << "X = " << x <<" , Y: " << y << "\n";
fim

principal ()
inicio

Ponto p1, p2; /* instanciação */

p1.setaX(2);
p1.setaY(3);

p2.coordXY (10,12);

p1.mostraXY();
p2.mostraXY();

getch();
retorno(0);
fim

Exemplo 5.10 – Definir a classe Ponto e sua interface. Declare ainda dois objetos para
esta classe. Represente as coordenadas de um retângulo e calcule sua
área.

#incluir <iostream.h>
#incluir <conio.h>

97
classe Ponto
inicio
privado:
inteiro x;
inteiro y;
publico:
Ponto (inteiro vx, inteiro vy); /* construtor */
inteiro obtemX( ) inicio retorno (x); fim
inteiro obtemY( ) inicio retorno (y); fim
vazio mostraXY ( );

privado:
vazio setaX (inteiro vx) inicio x = vx; fim
vazio setaY (inteiro vy) inicio y = vy; fim
fim;

Ponto::Ponto (inteiro vx, inteiro vy)


inicio
setaX (vx);
setaY (vy);
fim

vazio Ponto::mostraXY ( )
inicio
csaida <<"X = "<< obtemX()<<",Y: "<<obtemY()<<"\n";
fim

principal()
inicio
inteiro area, comprimento, largura;

/* instanciação usando construtor */


Ponto p1(1,1), p2(10,10);
p1.mostraXY();
p2.mostraXY();

comprimento = p2.obtemX( ) – p1.obtemX( );


largura = p2.obtemY( ) – p1.obtemY( );

area = comprimento * largura;

csaida <<"\nArea = " << area;

getch();
retorno(0);
fim

5.2.6 Exercícios propostos

Exercício 5.3 – Definir a classe Ponto e sua interface. Declare ainda dois objetos para

98
esta classe. Represente as coordenadas de um retângulo e a medida da
diagonal do mesmo a partir da origem (0,0).

Exercício 5.4 – Definir a classe Ponto e sua interface. Declare ainda dois objetos para
esta classe. Represente as coordenadas de um retângulo e a medida da
diagonal do mesmo.

Exercício 5.5 – Uma representação para números racionais (numerador, denominador)


que possua as operações aritméticas básicas.

Exercício 5.6 – Uma representação para ângulos na forma (Graus, Minutos,


Segundos). Também com as operações relacionadas, bem como as
operações para converter para radianos, entre outras.

99
6 Mini Manual do C Quietly

O C Quietly (CQ) é uma ferramenta livre (Freeware) para ajudar os iniciantes no


mundo da programação em algoritmo e linguagem C. Sua proposta é permitir a
desenvolvimento de pseudocódigo e automaticamente, traduzi-lo para a linguagem C.
Utilizando esta ferramenta, os alunos podem representar suas soluções de problemas em
uma linguagem muito próxima da língua natural na forma de algoritmos, não
necessitando inicialmente o domínio dos comandos da linguagem C.
A seguir (fig 6.1) é apresentada à tela inicial do CQ, com seu modelo de
algoritmo padrão. Ele acaba poupando ao programador algum tempo de digitação
oferecendo este recurso inicial. O código fonte (fig. 6.2) equivalente em c é apresentado
logo a seguir. Na seqüência, outras partes da ferramenta serão exploradas.

Figura 6.1 – Iniciando o C Quietly com um novo algoritmo.

100
Figura 6.2 – Novo código-fonte em linguagem C.

Um novo algoritmo poderá ser introduzido no editor do CQ de três formas. A


primeira, digitando-se os comandos (pseudocódigo) que representem a solução
previamente proposta de determinado problema. A segunda, compreende na abertura de
algoritmos exemplos ou anteriormente digitados para alterações, trazendo um ganho no
tempo de digitação. A outra, consiste na importação de código fonte já escrito em
linguagem C, do qual o CQ “extrai” o pseudocódigo dos comandos em C (ainda não
disponível na versão 1.1.2t).
Após o término do algoritmo, ou a qualquer momento durante a digitação do
algoritmo, é possível compilá-lo (fig. 6.3) a fim de verificar a existência ou não de erros
de digitação ou sintaxe da linguagem C. Enquanto persistirem os erros, mensagens
indicando cada um dos erros e o local destes, serão exibidos na janela abaixo do editor
do CQ sob o título: Mensagem. Não havendo erros, o que impede o funcionamento do
algoritmo/programa, a execução do algoritmo (fig. 6.6) ocorre.
O exemplo utilizado neste manual é o cálculo da média aritmética simples entre
três notas. O Algoritmo (fig. 6.3) é traduzido para o código-fonte em linguagem C,
compilado (fig. 6.4) e executado (fig. 6.5). Uma vez inseridos os valores, por parte do
usuário, a média é exibida (fig. 6.6). Terminado a execução (fig. 6.6) o programador têm
novamente ao seu dispor o editor do CQ.

101
Figura 6.3 – Compilando um código-fonte.

Figura 6.4 – Término da compilação do código-fonte.

102
Figura 6.5 – Executando o programa.

Figura 6.6 – Saída de execução do programa.

103
Figura 6.7 – Inserindo novas palavras-chave.

Totalmente flexível, o CQ permite ao programador criar sua própria lista de


palavras-chave (fig. 6.7). Cadastrando seus respectivos significados na linguagem C.
Dessa maneira os iniciantes não vão ter grandes problemas em migrar do sistema de
pseudocódigo para a linguagem C, excluindo totalmente a necessidade de se utilizar
papel.

104
Bibliografia

HOLZNER, Steven, GROUP, The Peter Norton Computing . Programando em


C++: um guia prático para programação profissional. Tradução de Sylvio
Carlos Montenegro Branco. Rio de Janeiro: Campus, 1993.

HUBBARD, John R. Teoria e problemas de programação em C++ / John R.


Hubbard; Trad. Edson Furmankigwicz. – 2. ed. – Porto Alegre : Bookman, 2003.

JAMSA, Kris. Programando em C++ - A bíblia / Kris Jamsa e Lars Klander.


Tradução: e revisão Técnica: Jeremias René D. Pereira dos Santos – São Paulo :
Makron Books, 1999.

KERNIGHAN, Brian W., RITCHIE, Dennis M. Ritchie. C a linguagem de


programação: Padrão ANSI. Tradução Daniel Viera. Rio de Janeiro: Campus,
1989.

LOPES, Anita, GARCIA, Guto. Introdução à programação. Rio de Janeiro:


Campus, 2002.

MANZANO, José Augusto N. G., OLIVEIRA, Jayr Figueiredo de. Estudo


Dirigido de Algoritmos. São Paulo: Érica, 1997.

PEREIRA, Sílvio do Lago. Estruturas de dados fundamentais: conceitos e


aplicações / Sílvio do Lago Pereira. – São Paulo : Érica, 1996.

TREMBLAY, Jaen-Paul, BUNT Richard B.. Ciência dos Computadores: Uma


Abordagem Algorítmica. Tradução Moacir Souza Prado; São Paulo: McGraw
Hill do Brasil, 1993.

105

You might also like