Você está na página 1de 108

Apontamentos de Programao em C/C++

Paulo Baltarejo e Jorge Santos

Instituto Superior de Engenharia do Porto


Departamento de Engenharia Informtica

Verso Draft Maro de 2006


Aviso de licena de utilizao: Este documento pode ser utilizado livremente para fins
no comerciais, permitido aos seus utilizadores, copiar, distribuir e exibir publicamente os
seus contedos, desde que sejam ressalvados os direitos de autor do mesmo, nomeadamente,
dever ser sempre includa esta pgina em todas as cpias.
Paulo Baltarejo e Jorge Santos, 2006

i
ii
ndice

1 Programao em C/C++ 1
1.1 Histria da linguagem C/C++ . . . . . . . . . . . . . . . . . . . . . . 1
1.2 Estrutura de um programa em C++ . . . . . . . . . . . . . . . . . . 1
1.3 Criao de um programa em C++ . . . . . . . . . . . . . . . . . . . . 3
1.4 Modelo de compilao da linguagem C++ . . . . . . . . . . . . . . . 4
1.5 Variveis, Tipos de dados e Constantes . . . . . . . . . . . . . . . . . 4
1.5.1 Variveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.5.2 Tipos de dados . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.5.3 Declarao de variveis . . . . . . . . . . . . . . . . . . . . . . 6
1.5.4 Constantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.5.4.1 Literais . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.5.4.2 Definidas . . . . . . . . . . . . . . . . . . . . . . . . 9
1.5.4.3 Declaradas . . . . . . . . . . . . . . . . . . . . . . . 10
1.6 Estruturas de controlo . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.6.1 Instrues de Sequncia . . . . . . . . . . . . . . . . . . . . . 11
1.6.1.1 Operadores aritmticos . . . . . . . . . . . . . . . . . 12
1.6.1.2 Operadores relacionais e lgicos . . . . . . . . . . . . 13
1.6.2 Exerccios Resolvidos . . . . . . . . . . . . . . . . . . . . . . . 16
1.6.2.1 Distncia euclidiana entre dois pontos . . . . . . . . 16
1.6.2.2 Determinar permetro e rea de circunferncia . . . . 17
1.6.3 Exerccios Propostos . . . . . . . . . . . . . . . . . . . . . . . 17
1.6.3.1 Calcular ndice de massa corprea (IMC) . . . . . . . 17
1.6.3.2 Converter horas, minutos e segundos . . . . . . . . . 18
1.6.3.3 Teorema de Pitgoras . . . . . . . . . . . . . . . . . 18
1.6.3.4 Converter temperaturas . . . . . . . . . . . . . . . . 18
1.6.4 Instrues de Deciso . . . . . . . . . . . . . . . . . . . . . . . 18
1.6.4.1 Deciso binria . . . . . . . . . . . . . . . . . . . . . 18
1.6.4.2 Deciso mltipla . . . . . . . . . . . . . . . . . . . . 19
1.6.5 Prioridade dos operadores . . . . . . . . . . . . . . . . . . . . 21
1.6.6 Exerccios Resolvidos . . . . . . . . . . . . . . . . . . . . . . . 22
1.6.6.1 Distncia euclidiana entre dois pontos . . . . . . . . 22
1.6.6.2 Classificar em funo da mdia . . . . . . . . . . . . 23
1.6.6.3 Determinar o mximo de 3 valores . . . . . . . . . . 23
1.6.6.4 Determinar tringulo vlido . . . . . . . . . . . . . . 24
1.6.7 Exerccios Propostos . . . . . . . . . . . . . . . . . . . . . . . 25
1.6.7.1 Classificar tringulo . . . . . . . . . . . . . . . . . . 25
1.6.7.2 Diviso . . . . . . . . . . . . . . . . . . . . . . . . . 25
1.6.7.3 Resolver equao da forma ax2 + bx + c = 0 . . . . . 25

iii
1.6.7.4 Converter entre escalas de temperaturas . . . . . . . 25
1.6.7.5 Calcular ndice de massa corprea (IMC) . . . . . . . 26
1.6.7.6 Determinar ano bissexto . . . . . . . . . . . . . . . . 26
1.6.7.7 Parque de estacionamento . . . . . . . . . . . . . . . 26
1.6.8 Instrues de Repetio . . . . . . . . . . . . . . . . . . . . . 27
1.6.8.1 Instruo do-while . . . . . . . . . . . . . . . . . . 27
1.6.8.2 Instruo while . . . . . . . . . . . . . . . . . . . . 28
1.6.8.3 Instruo for . . . . . . . . . . . . . . . . . . . . . . 28
1.6.9 Exerccios Resolvidos . . . . . . . . . . . . . . . . . . . . . . . 30
1.6.9.1 Calcular somatrio entre dois limites . . . . . . . . . 30
1.6.9.2 Calcular factorial de um nmero . . . . . . . . . . . 31
1.6.9.3 Determinar se um nmero primo . . . . . . . . . . 32
1.6.9.4 Determinar nmero e idade da pessoa mais nova de
um grupo . . . . . . . . . . . . . . . . . . . . . . . . 32
1.6.9.5 Determinar o aluno melhor classificado e a mdia das
notas de uma turma . . . . . . . . . . . . . . . . . . 33
1.6.10 Exerccios Propostos . . . . . . . . . . . . . . . . . . . . . . . 34
1.6.10.1 Diviso atravs de subtraces sucessivas . . . . . . . 34
1.6.10.2 Determinar o mximo e mnimo de uma srie . . . . 35
1.6.10.3 Determinar quantidade de nmeros primos . . . . . . 35
1.6.10.4 Determinar se um nmero perfeito . . . . . . . . . 35
1.6.10.5 Calcular potncia por multiplicaes sucessivas . . . 35
1.6.10.6 Maior nmero mpar de uma sequncia de valores . . 35
1.6.10.7 Algarismos de um nmero . . . . . . . . . . . . . . . 35
1.6.10.8 Apresentao grfica de temperaturas . . . . . . . . 35
1.6.10.9 Soma dos algarismo de um nmero . . . . . . . . . . 36
1.6.10.10 Jogo de adivinhar o nmero . . . . . . . . . . . . . . 36
1.6.10.11 Capicua de um nmero . . . . . . . . . . . . . . . . 36
1.6.10.12 Converso de base numrica . . . . . . . . . . . . . . 36
1.7 Funes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
1.7.1 mbito da variveis global e local . . . . . . . . . . . . . . . 38
1.7.2 Passagem de argumentos . . . . . . . . . . . . . . . . . . . . . 41
1.7.2.1 Passagem por valor . . . . . . . . . . . . . . . . . . . 41
1.7.2.2 Passagem por referncia . . . . . . . . . . . . . . . . 42
1.7.2.3 Valores por omisso nos argumentos . . . . . . . . . 43
1.7.3 Prottipos de funes . . . . . . . . . . . . . . . . . . . . . . . 44
1.7.4 Estrutura de um programa em C++ . . . . . . . . . . . . . . 45
1.7.5 Exerccios resolvidos . . . . . . . . . . . . . . . . . . . . . . . 46
1.7.5.1 Funo que devolve o maior algarismo de um nmero 46
1.7.5.2 Funo que indica se um nmero perfeito . . . . . . 46
1.7.6 Exerccios propostos . . . . . . . . . . . . . . . . . . . . . . . 47
1.7.6.1 Funo mdia de dois nmeros . . . . . . . . . . . . 47
1.7.6.2 Funo lei de Ohm . . . . . . . . . . . . . . . . . . . 47
1.7.6.3 Funo somatrio . . . . . . . . . . . . . . . . . . . . 48
1.7.6.4 Funes para codificar e descodificar nmeros . . . . 48
1.7.6.5 Nmeros primos . . . . . . . . . . . . . . . . . . . . 48
1.8 Vectores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
1.8.1 Definio de vectores . . . . . . . . . . . . . . . . . . . . . . . 49

iv
1.8.2 Atribuio dos valores iniciais . . . . . . . . . . . . . . . . . . 49
1.8.3 Acesso aos elementos de um vector . . . . . . . . . . . . . . . 50
1.8.4 Exerccios resolvidos . . . . . . . . . . . . . . . . . . . . . . . 51
1.8.4.1 Funes manipulando vectores . . . . . . . . . . . . . 51
1.8.5 Exerccios propostos . . . . . . . . . . . . . . . . . . . . . . . 52
1.8.5.1 Determinar desvio padro de uma srie . . . . . . . . 52
1.8.5.2 Prova de atletismo . . . . . . . . . . . . . . . . . . . 52
1.8.5.3 Suavizao . . . . . . . . . . . . . . . . . . . . . . . 53
1.9 Vectores multidimensionais . . . . . . . . . . . . . . . . . . . . . . . 53
1.9.1 Exerccios resolvidos . . . . . . . . . . . . . . . . . . . . . . . 55
1.9.1.1 Funes manipulao de matrizes . . . . . . . . . . . 55
1.9.2 Exerccios propostos . . . . . . . . . . . . . . . . . . . . . . . 58
1.9.2.1 Mximo local . . . . . . . . . . . . . . . . . . . . . . 58
1.9.2.2 Determinar se uma matriz simtrica . . . . . . . . 58
1.10 Vectores como parmetros . . . . . . . . . . . . . . . . . . . . . . . . 58
1.11 Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
1.11.1 Iniciao de strings . . . . . . . . . . . . . . . . . . . . . . . . 60
1.11.2 Funes para manipulao de strings . . . . . . . . . . . . . . 61
1.11.3 Converso de strings para outros tipos . . . . . . . . . . . . . 62
1.11.4 Exerccios resolvidos . . . . . . . . . . . . . . . . . . . . . . . 63
1.11.4.1 Programa para manipulao de strings e caracteres . 63
1.11.5 Exerccios propostos . . . . . . . . . . . . . . . . . . . . . . . 68
1.11.5.1 Funo que determine o nmero de ocorrncias . . . 68
1.11.5.2 Funo que verifique se uma string inversa de outra 68
1.11.5.3 Funo que conta as palavras de uma string . . . . . 68
1.11.5.4 Funo que formate uma string . . . . . . . . . . . . 68
1.12 Ponteiros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
1.12.1 Operador endereo & . . . . . . . . . . . . . . . . . . . . . . . 68
1.12.2 Operador de referncia * . . . . . . . . . . . . . . . . . . . . . 69
1.12.3 Ponteiros e vectores . . . . . . . . . . . . . . . . . . . . . . . . 72
1.12.4 Ponteiros para ponteiros . . . . . . . . . . . . . . . . . . . . . 72
1.12.5 Ponteiros do tipo void . . . . . . . . . . . . . . . . . . . . . . 73
1.13 Tipos de dados no nativos . . . . . . . . . . . . . . . . . . . . . . . 74
1.13.1 Estruturas de dados instruo struct . . . . . . . . . . . . 74
1.13.2 Definio de tipos instruo typedef . . . . . . . . . . . . . 79
1.13.3 Unio instruo union . . . . . . . . . . . . . . . . . . . . . 79
1.13.4 Enumeradores instruo enum . . . . . . . . . . . . . . . . . 81
1.13.5 Exerccios resolvidos . . . . . . . . . . . . . . . . . . . . . . . 83
1.13.5.1 Ponto e recta . . . . . . . . . . . . . . . . . . . . . . 83
1.13.5.2 Gesto de clientes de uma discoteca . . . . . . . . . 85
1.13.6 Exerccios propostos . . . . . . . . . . . . . . . . . . . . . . . 86
1.13.6.1 Empresa de construo civil . . . . . . . . . . . . . 86
1.13.6.2 Empresa de construo civil . . . . . . . . . . . . . 86
1.14 Programas de grandes dimenses . . . . . . . . . . . . . . . . . . . . 90
1.14.1 Diviso em mdulos . . . . . . . . . . . . . . . . . . . . . . . 91

v
vi
Lista de Figuras

1.1 Ciclo de vida de um programa em C . . . . . . . . . . . . . . . . . . 3


1.2 Modelo de compilao . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.3 Execuo de uma funo . . . . . . . . . . . . . . . . . . . . . . . . . 38
1.4 Arquitectura do modelo de memria . . . . . . . . . . . . . . . . . . 40
1.5 Execuo da pilha . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
1.6 Passagem de variveis por valor . . . . . . . . . . . . . . . . . . . . . 42
1.7 Passagem de variveis por referncia . . . . . . . . . . . . . . . . . . 43
1.8 Estrutura de um programa em C/C++ . . . . . . . . . . . . . . . . . 45
1.9 Ilustrao da lei de Ohm . . . . . . . . . . . . . . . . . . . . . . . . . 48
1.10 Representao grfica do vector vec . . . . . . . . . . . . . . . . . . . 49
1.11 Representao grfica de uma matriz . . . . . . . . . . . . . . . . . . 53
1.12 Representao de uma string . . . . . . . . . . . . . . . . . . . . . . . 60
1.13 Representao da memria do computador . . . . . . . . . . . . . . . 69
1.14 Ponteiro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
1.15 Ponteiro para ponteiro . . . . . . . . . . . . . . . . . . . . . . . . . . 73
1.16 Representao de uma unio . . . . . . . . . . . . . . . . . . . . . . . 80
1.17 Tipos de dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
1.18 Representao grfica de um mdulo . . . . . . . . . . . . . . . . . . 91
1.19 Incluso de um ficheiro . . . . . . . . . . . . . . . . . . . . . . . . . . 92
1.20 Incluso de um ficheiro (directivas de pr-processamento) . . . . . . . 93

vii
viii
Lista de Tabelas

1.1 Palavras reservadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6


1.2 Tipos de dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.3 Caracteres especiais . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.4 Exemplo operadores compostos . . . . . . . . . . . . . . . . . . . . . 12
1.5 Operadores aritmticos . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.6 Operadores aritmticos compostos . . . . . . . . . . . . . . . . . . . . 13
1.7 Operadores de incremento (modo prefixo e sufixo) . . . . . . . . . . . 14
1.8 Operadores relacionais . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.9 Exemplos de operadores relacionais . . . . . . . . . . . . . . . . . . . 14
1.10 Operadores lgicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1.11 Exemplos de operadores lgicos . . . . . . . . . . . . . . . . . . . . . 15
1.12 Tabelas de verdade: conjuno, disjuno e negao . . . . . . . . . . 15
1.13 Operadores de manipulao de bits . . . . . . . . . . . . . . . . . . . 16
1.14 Tabela de verdade dos operadores de manipulao bits . . . . . . . . 16
1.15 Relao de precedncia dos operadores . . . . . . . . . . . . . . . . . 22
1.16 ndice de massa corprea . . . . . . . . . . . . . . . . . . . . . . . . 26

ix
x
Resumo
Estes apontamentos tm como objectivo principal apoiar os alunos que pretendam
aprender programao de computadores utilizando a linguagem C++, em particular
aqueles que frequentam a disciplina de Introduo Informtica do Ano 0 leccionada
no Instituto Superior de Engenharia do Porto (ISEP).
A estrutura destes apontamentos foi definida de acordo com a abordagem de
aprender-por-exemplo, pelo que, os conceitos so apenas introduzidos de acordo
com a necessidade de explicar a resoluo de um determinado programa. De forma
a suportar esta abordagem apresentado um grande nmero de exerccios resolvidos.

Porto, Janeiro de 2006


Jorge Santos e Paulo Baltarejo

xi
xii
Captulo 1

Programao em C/C++

1.1 Histria da linguagem C/C++


O C uma linguagem de programao imperativa (procedimental) tpica. Foi de-
senvolvida em 1970 por Dennis Ritchie para utilizao no sistema operativo Unix.
Esta linguagem particularmente apreciada pela eficincia e a mais utilizada na
escrita de software para sistemas operativos e embora menos, no desenvolvimento
de aplicaes. A sua utilizao tambm comum no ensino, apesar de no ser a
linguagem inicial para iniciados.
De acordo com Ritchie, o desenvolvimento inicial da linguagem C aconteceu nos
laboratrios da AT&T entre 1969 e 1973. O nome "C"foi escolhido porque algumas
das suas caractersticas derivavam de uma linguagem j existente chamada "B".
Em 1973, a linguagem C tornou-se suficientemente poderosa para suportar a
escrita de grande parte do kernel do Unix que tinha sido previamente escrito em
cdigo assembly.
Em 1978, Ritchie e Brian Kernighan publicaram a primeira edio do livro "The
C Programming Language"[Kernighan e Ritchie, 1988] que durante muitos anos
funcionou como a especificao informal da linguagem (K&R C). Posteriormente
a segunda verso versou sobre a especificao ANSI C. A especificao K&R C
considerado o conjunto mnimo obrigatrio que um compilador da linguagem deve
implementar.
O C++ [Stroustrup, 2000], pronunciado "c mais mais", uma linguagem de
programao genrica que suporta tanto os paradigmas da programao estruturada
(procedimental) como o orientado ao objecto. A partir de 1990, o C++ tornou-se
uma das linguagens de programao mais populares.
Bjarne Stroustrup desenvolveu o C++ (originalmente designado "C com clas-
ses") nos laboratrios da Bell em 1983, como um melhoramento da linguagem C.
Este melhoramentos incluram: adio de classes, funes virtuais, sobrecarga de
operadores, mltipla herana, templates e tratamento de excepes.
O standard do C++ foi ratificado em 1998 como ISO/IEC 14882:1998, sendo
que a verso actual, de 2003, o ISO/IEC 14882:2003.

1.2 Estrutura de um programa em C++


Como primeira abordagem linguagem C++, considere-se o programa 1.1.

1
ISEP/DEI - Jorge Santos e Paulo Baltarejo

Listing 1.1: Programa clssico - Bom dia mundo


1 // o meu p r i m e i r o programa em C++
2 #i n c l u d e <i o s t r e a m . h>
3 int main ( )
4 {
5 cout<<"Bom d i a Mundo ! " ;
6 return 0 ;
7 }

Este programa depois compilado e executado produziria o seguinte resultado:

Bom dia Mundo!

Apesar do resultado simples, o programa contm um conjunto de elementos que


merecem um anlise detalhada.

//O meu primeiro programa em C++


Isto uma linha de comentrio. Todas as linhas comeadas por duas barras
// so consideradas comentrios e no tem qualquer efeito na compilao/exe-
cuo do programa. Servem para inserir explicaes e observaes no cdigo
do programa;

#include <iostream.h>
As linhas que comeam pelo carcter cardinal (#) so directivas de pr-compilao.
Estas no so linhas de cdigo executvel mas apenas indicaes para o com-
pilador. Neste caso #include <iostream.h> indica ao prprocessador do
compilador que inclua os cabealhos existentes no ficheiro iostream.h relati-
vos a funes utilizadas na entrada e sada de dados de um programa;

int main()
Esta linha corresponde ao incio da declarao da funo main. A funo main
o ponto por onde todos os programas em C++ comeam a sua execuo.
main seguido de parntesis ((, )) porque uma funo. O contedo da
funo main que est imediatamente a seguir declarao formal, est contido
entre chavetas ({ }) conforme o exemplo;

cout < < "Bom dia Mundo!";


Esta instruo coloca no ecr a frase "Ol Mundo!". cout (console output)
um objecto normalmente associado ecr. cout est declarado no ficheiro de
cabealhos (header file) iostream.h, portanto para poder usar o cout neces-
srio incluir o ficheiro iostream.h. Notese que esta frase termina com ponto
vrgula (;). Este carcter significa o fim da instruo e tem obrigatoriamente
que ser includo depois de qualquer instruo;

return 0;
A instruo return provoca o fim da execuo da funo main e (devolve)
retorna o que est a seguir, neste caso o zero (0).

2
Apontamentos de Programao C/C++

1.3 Criao de um programa em C++


O desenvolvimento de programas em linguagem C++, tal como na maioria das
linguagens compiladas, um processo que compreende quatro fases: escrita, compi-
lao, "linking" e execuo (ver figura 1.1).
Erros de
execuo
Erros de
linking
Erros de
compilao

Escrita do
Compilao Link ing Execuo
cdigo-fonte

ficheiro ficheiro ficheiro


cdigo-fonte objecto executvel
.cpp ou .cc .obj ou .o .exe

ficheiros de
bibliotecas Dependncia
cabealhos
.lib funcional
.h
Fluxo dados

Figura 1.1: Ciclo de vida de um programa em C

Normalmente, os ambiente de desenvolvimento integrado de aplicaes (IDE1 )


incluem um conjunto de ferramentas que suportam as referidas fases do desenvolvi-
mento de um programa/aplicao.
Escrita do cdigofonte A primeira fase do processo criao/edio de
um (ou mais) ficheiro de texto contendo o cdigofonte. Isto pode ser realizado
com recurso a um editor de texto. O referido ficheiro tem que ter a extenso
".cpp" ou ".cc". O contedo do programa tem que obedecer rigorosamente
sintaxe da linguagem.
Compilao A segunda fase, a da compilao, realizada com recurso a
um compilador especfico para linguagem, neste caso o de C++. Nesta fase se
existirem erros de sintaxe, o compilador detecta-os e reportar a sua localizao
(tipicamente nmero de linha) e uma breve descrio do erro. Note-se que os
erros de lgica no so detectados nesta fase. Se o programa no tiver erros
de sintaxe o compilador produzir o cdigo executvel, isto , um programa
pronto a ser executado. Nesta fase so includos os ficheiros de cabealhos nos
quais so declaradas as funes que serem posteriormente includas no fase de
linking.
"Linking" A terceira fase, a da linking, feita com recurso a um programa
especial, designado linker que se responsabiliza por transformar os programa
objecto (independente da plataforma de hardware) numa aplicao executvel
na plataforma em hardware especfica. Nesta fase, as declaraes das funes
(cabealhos) so substitudas por cdigo executvel, propriamente dito. Caso
ocorram erros nesta fase, o processo retorna primeira fase.
Execuo A quarta e ltima fase, execuo, s poder ocorrer no caso das
fases terminarem com sucesso.
1
Do anglo-saxnico Integrated Environment Development

3
ISEP/DEI - Jorge Santos e Paulo Baltarejo

1.4 Modelo de compilao da linguagem C++


A figura 1.2 apresenta o modelo de compilao da linguagem C++.

Erros de Erros de
compilao compilao

Pr-processador Compilador Assem bler Link er

ficheiro
cdigo ficheiro
cdigo-fonte
assembly objecto
(alterado)
.obj ou .o
.cpp ou .cc

ficheiro ficheiros de
bibliotecas
cdigo-fonte cabealhos
.lib
.cpp ou .cc .h

Figura 1.2: Modelo de compilao

No modelo de compilao da linguagem C++ so quatro os intervenientes prin-


cipais: pr-processador, compilador, assembler e linker .
Prprocessador O pr-processador executa as directivas existentes no
cdigo fonte. As directivas de pr-processamento comeam pelo carcter # e
de entre as tarefas mais comuns compreendidas na prcompilao, destacam-
se:

#include Incluso de ficheiros, tipicamente ficheiros de cabealhos;


#define definio de constantes (ver seco 1.5.4.2);
Remoo de linhas de comentrios.

Compilador Alguns compiladores traduzem o cdigo fonte (texto) recebido


do prprocessamento para linguagem assembly (tambm texto). Enquanto
que outros geram directamente o cdigo objecto (instrues do processador
em cdigo binrio);
Assembler O assembler traduz cdigo em linguagem assembly (texto) para
cdigo binrio. Pode estar integrado no compilador. O cdigo gerado pelo
assembler geralmente tem a extenso ".o" (nos sistemas operativos Unix e
Linux) e ".obj" (nos sistema operativos Windows);
Linker Se o programa fonte tem referncias a elementos definidos nas bi-
bliotecas padro ou outras, o Linker o responsvel por adicionar o cdigo
desses elementos de forma a criar o ficheiro executvel. A referncia a variveis
globais externas resolvida pelo Linker .

1.5 Variveis, Tipos de dados e Constantes


O programa OlaMundo (ver listagem 1.1) apesar de estruturalmente completo, tem
apenas como funcionalidade, escrever na consola de sada, tipicamente o ecr, a frase
"Ola Mundo!".

4
Apontamentos de Programao C/C++

1.5.1 Variveis
Na escrita de programas mais sofisticados, regra geral, ser necessria: a introduo
de dados (eventualmente introduzidos pelo utilizador) e guardar informao relativa
a clculos. neste contexto que ser introduzido o conceito de varivel.
Suponha-se que pedido a uma determinada pessoa para memorizar o nmero 5
e depois o nmero 2. A seguir, -lhe pedido que adicione a quantidade 1 ao primeiro
nmero memorizado. Depois -lhe pedido o resultado da subtraco do primeiro
com o segundo. Aps a realizao correcta destas contas, a pessoa em questo diria
que o resultado seria 4. Este processo tambm pode ser executado pelo computador.
Para tal necessrio descrever este processo atravs da linguagem de programao
(ver programa da listagem 1.2).
Listing 1.2: Somar dois nmeros
1 #include<i o s t r e a m . h>
2 int main ( )
3 {

4 int a , b , r e s u l t ;
5 a =5;
6 b=2;
7 a=a +1;
8 r e s u l t=ab ;
9 cout<<" R e s u l t a d o : "<<r e s u l t <<e n d l ;
10

11 return 0 ;
12 }
Da mesma forma que esta pessoa guardou temporariamente os valores em mem-
ria o computador tambm tem capacidade para isso, para tal foi necessrio definir
algumas variveis.
Um varivel uma poro de memria que permite armazenar um determinado
valor. Cada varivel tem um identificador e o tipo de dados. O identificador permite
referir de forma nica uma varivel enquanto que tipo de dados til para a opti-
mizao do cdigo pois diferentes tipos de dados requerem quantidade distintas de
memria. Por exemplo, no cdigo do programa da listagem 1.2, os identificadores
utilizados: a, b e result so do tipo inteiro (int).
Na escolha de identificadores aquando da definio das variveis, o programador
deve obedecer a conjunto de regras para que estes sejam vlidos, a saber:

Ser uma sequncia de uma ou mais letras, dgitos e/ou carcter "underscore"(_),
iniciada obrigatoriamente por letra ou "underscore";

Os espaos no podem fazer parte de um identificador;

Embora o comprimento de um identificador no seja limitado, alguns compi-


ladores s identificam os primeiros 32 caracteres, sendo o resto ignorado;

No podem ser iguais a qualquer palavra reservada da linguagem C++. A


tabela 1.1 apresenta as palavras reservadas segundo a norma ANSI-C++.

Um outro aspecto a ter em considerao na definio de um identificador,


que a linguagem C++ sensvel capitalizao, isto , faz a distino entre letras

5
ISEP/DEI - Jorge Santos e Paulo Baltarejo

Tabela 1.1: Palavras reservadas


asm, auto, bool, break, case, catch, char, class, const,
const_cast, continue, default, delete, do, double,
dynamic_cast, else, enum, explicit, extern, false, float,
for, friend, goto, if, inline, int, long, mutable, namespace,
new, operator, private, protected, public, register,
reinterpret_cast, return, short, signed, sizeof, static,
static_cast, struct, switch, template, this, throw, true, try,
typedef, typeid, typename, union, unsigned, using, virtual,
void, volatile, wchar_t

maisculas e minsculas, por exemplo os identificadores: result,Result e RESULT


so distintos para o compilador.

1.5.2 Tipos de dados


Aquando da declarao de uma varivel, o compilador da linguagem C++ neces-
sita, por uma questo de optimizao de cdigo, de saber qual o tipo da referida
varivel de forma a reservar em memria apenas o espao estritamente necessrio.
Por exemplo, para armazenar uma letra no necessrio tanto espao como para
armazenar um nmero real.
Notese que a memria do computador esta organizada em bytes, sendo que um
byte a unidade mnima para atribuio de memria. Com um byte possvel
armazenar:

Um nmero sem sinal entre 0 e 255;

Um nmero com sinal entre -128 a 127;

Um carcter simples.

No entanto, em muitas situaes ser necessrio armazenar valores superiores


capacidade de um byte, para este efeito existem outros tipos de dados. A tabela 1.2
apresenta os tipos dados fundamentais em C++, espao necessrio (em bytes) e a
gama de valores respectivos.
Note-se que efectivamente em C++ os caracteres so armazenados como um
valor numrico, de acordo com a norma ASCII2 .

1.5.3 Declarao de variveis


A utilizao de uma varivel num programa C++ requer a sua declarao prvia.
Considere-se os exemplos constantes no excerto de cdigo da listagem 1.3.
Listing 1.3: Declarao de variveis
1 {
2 // D e c l a r a o de v a r i v e i s
3 int a ;
2
American Standard Code for Information Interchange.

6
Apontamentos de Programao C/C++

Tabela 1.2: Tipos de dados


Nome Tam. Descrio Gama de valores
char 1 Caracter ou inteiro de 8 bits c/sinal: -128 a 127 e
de comprimento s/sinal: 0 a 255
short 2 Inteiro de 16 bits de compri- c/sinal: -32768 a 32767 e
mento s/sinal: 0 a 65635
long 4 Inteiro de 32 bits de compri- c/sinal: -2147483648 a
mento 2147483647 e s/sinal: 0 a
42949967295
int ver short e long
float 4 Nmero real 3.4e38
double 8 Nmero real, virgula flutu- 1.7e308
ante, dupla preciso
long double 10 Nmero real longo, virgula 1.2e4932
flutuante, dupla preciso
bool 1 Valores lgicos - booleanos true e false
wchar_t 2 Caracter extendido, necess- Caracteres (incluindo in-
rio para a representao de ternacionais)
caracteres internacionais

4 long int s a l d o ;
5 f l o a t media ;
6 double r a i z ;
7 bool s e n t i n e l a ;
8 char t e c l a ;
9 ...
10

11 // D e c l a r a o de v a r i v e i s
12 // mais do que uma v a r i v e l por l i n h a
13 int x , y , z ;
14 f l o a t area , p e r i m e t r o ;
15 ...
16

17 // D e c l a r a o de v a r i v e i s
18 // mais do que uma v a r i v e l por l i n h a
19 // e com i n i c i a e s
20 bool ePrimo=f a l s e ;
21 int nDiv =0, produto =1;
22 long double numero =1.0 , f a c t o r i a l = 1 . 0 ;
23 char _ 1 l e t r a= a , _ 2 l e t r a= b ;
24 }
No excerto so apresentados trs blocos que pretendem ilustrar:
No primeiro bloco, a declarao de uma varivel por linha de cdigo;
No segundo bloco, mltiplas declaraes por linha;
No terceiro bloco, para alm da declarao mltipla por linha, a iniciao de
variveis.

7
ISEP/DEI - Jorge Santos e Paulo Baltarejo

Conforme se verifica no excerto, no caso de se declarar mais do que uma varivel


por instruo, estas tm estar separadas por virgula.
Quando uma varivel declarada, o seu valor indeterminado por omisso, isto ,
no se sabe qual o valor. Por vezes til iniciar uma varivel com um determinado
valor aquando da sua declarao. Para tal acrescenta-se o sinal de igual e o valor
com que se quer inicializar a varivel.
Formalmente a sintaxe subjacente declarao/iniciao de uma ou mais vari-
veis :
<tipo-de-dados> <id1>=<Valor inicial1>, <id2>=<Valor inicial2>,...;
sendo que os parntesis rectos representam o caracter opcional, neste caso, as inici-
aes de variveis so opcionais.

1.5.4 Constantes
Uma constante qualquer identificador que tem um valor fixo, portanto que no
pode ser alterada durante a execuo do programa. Num programa em C++ podem
coexitir trs tipos de constantes: literais, definidas e declaradas.

1.5.4.1 Literais
Um literal uma qualquer identificador com o valor fixo e podem ser divididos em:
nmeros inteiros, nmeros reais, caracteres e cadeias de caracteres3
Nmeros inteiros - so constantes numricas que identificam nmeros na
base decimal. Note-se que para expressar uma constante numrica no ne-
cessrio escrever aspas(") ou qualquer outro caracter especial.

1776
707
-203

Quando escrito 1776 num programa est-se a referir ao valor numrico 1776
(mil setecentos e setenta e seis).
Alm da base decimal possvel utilizar a notao octal ou hexadecimal. Para
a notao octal precede-se o numero do caracter 0 (zero) e para hexadecimal
precede-se o nmero dos caracteres 0x(zero e x).
De seguida so apresentadas vrias formas de representar o mesmo valor, neste
caso o 75 (setenta e cinco).

Valor Notao
75 decimal
0113 octal
0x4b hexadecimal

Numeros Reais
Expressam nmeros com dcimas e/ou expoente. Podem incluir um ponto
decimal, o caracter e (que expressa "10 elevado a X", onde X um valor
inteiro) ou ambos.
3
Do anglo-saxnico String.

8
Apontamentos de Programao C/C++

Notaco Valor
3.14159 3.14159
6.022e23 6.022 1023
1.6e-19 1.6 1019
1.41421356237309504 2
3.0 3.0

Estas so cinco formas vlidas de representar nmeros reais em C++. Res-


pectivamente, o valor de , o nmero de Avogadro, a carga elctrica de um
electro (extremamente pequena), raiz de dois e o numero trs expresso como
decimal;

Caracteres e strings
Tambm existem constantes no numricas, como a seguir se exemplifica:

z
p
"Ol Mundo!"
"Como ests?"

As primeiras duas expresses representam caracteres simples enquanto as ou-


tras duas representam strings (cadeia de caracteres). Para os caracteres sim-
ples usada a plica () e para as strings so usados as aspas (").
Existem caracteres especiais que no podem ser expressos sem ser no cdigo
fonte do programa, como por exemplo, nova linha (\n) ou tabulao (\t).
Todos so precedidos pela barra "\". A tabela 1.3 seguinte apresenta a lista
dos caracteres especiais.

Tabela 1.3: Caracteres especiais


Caracter Significado
\n nova linha
\r cursor para 1coluna
\t tabulao
\b backspace
\ plica simples
\" aspas simples

1.5.4.2 Definidas
Para alm dos literais existem constantes que podem ser declaradas pelo programa-
dor, podendo ser definidas atravs de uma directiva de pr-processamento #define
ou atravs da palavrachave const (ver seco 1.5.4.3).
A seguir apresenta-se a forma como definir uma constante atravs da directiva
de prprocessamento #define e cuja a sintaxe a seguinte:
#define <identificador> <expresso>

9
ISEP/DEI - Jorge Santos e Paulo Baltarejo

Como j foi referido anteriormente o prprocessador nica e simplesmente actua


sobre o cdigo (texto) e neste caso substitu todas as ocorrncias no cdigo da
constante pelo seu valor. Por esta razo estas constantes so designadas de macros.
Nota: Um erro muito frequente a colocao do ponto e virgula (;) na
declarao da macro.
O excerto de cdigo 1.4 apresenta um exemplo da utilizao de uma macro. A
utilizao de macros tem duas vantagens:

Legibilidade do cdigo por exemplo mais fcil associarmos a mnemnica


PI ao do que o valor 3.14159265;

Facilidade de manuteno do cdigo o programador evita a repetio


da declarao das constantes, tornando mais fcil alterar o seu valor, pois
basta alterar a referida definio da macro, no necessrio procurar em todo
o cdigo o valor que se pretende alterar.

Listing 1.4: Utilizao de macros


1 #include<i o s t r e a m . h>
2

3 #define PI 3.14159265
4 #define NEWLINE \n
5

6 int main ( )
7 {
8 int r a i o =3;
9 double a r e a C i r c ;
10

11 a r e a C i r c = r a i o r a i o PI ;
12 cout<<" Raio=" << r a i o << " Area=" ;
13 cout<< a r e a C i r c << NEWLINE;
14

15 r a i o =5;
16 a r e a C i r c = r a i o r a i o PI ;
17 cout<<" Raio=" << r a i o << " Area=" ;
18 cout<< a r e a C i r c << NEWLINE;
19

20 return 0 ;
21 }

1.5.4.3 Declaradas
Atravs da palavrachave const possvel declarar constantes de um determinado
tipo de dados, conforme a seguir se exemplifica:

const int width = 100;


const char tab = \t;
const minhaConstante=12440;

No caso do tipo de dados no ser declarado, no exemplo anterior este caso surge
na ltima linha, o compilador assume que do tipo inteiro.

10
Apontamentos de Programao C/C++

Operador sizeof() Este operador recebe um parmetro, que pode ser


uma varivel ou um tipo de dados e devolve o espao em memria (em bytes)
ocupado por essa varivel ou tipo de dados, conforme exemplo seguinte, no
qual a varivel a tomar o valor 1.
int a=sizeof(char);

Converso de tipos de dados (instruo cast) A converso de dados


consiste em converter dados de um tipo noutro tipo de dados. Por exemplo:

int i;
float f = 3.14;
i = (int) f;

Este cdigo converte o numero 3.14 para o inteiro 3. Outra forma de o poder
fazer seria com a seguinte instruo:
i=int(f);
Apesar do resultado desta converso resultou numa perda de informao, em
algumas situaes tal esta situao pode ser desejvel.
Nota: O que convertido o valor da varivel f no a varivel f.
Esta do tipo float e continuar a ser.

1.6 Estruturas de controlo


De acordo com o paradigma da programao estruturada qualquer programa pode
ser descrito utilizando exclusivamente as trs estruturas bsicas de controlo: ins-
trues de sequncia, instrues de deciso e instrues de repetio.

1.6.1 Instrues de Sequncia


As instrues de sequncia so instrues atmicas (simples) permitem a leitura/es-
crita de dados, bem como o clculo e atribuio de valores. Todas as instrues so
executadas pela ordem apresentada no programa.
O programa da listagem 1.5 codifica em C++ um algoritmo cujo objectivo
cambiar euros em dlares considerando a taxa de converso 1.17.
Listing 1.5: Cambiar euro para dlar
1 #include<i o s t r e a m . h>
2 const double taxa = 1 . 1 7 ;
3 int main ( )

4 {

5 double valorEuro , v a l o r D o l a r ;
6 cout<<" I n t r o d u z a o v a l o r em e u r o s=" ;
7 c i n >>v a l o r E u r o ;
8 v a l o r D o l a r=v a l o r E u r o taxa ;
9 cout<<" Valor em d o l a r = "<<v a l o r D o l a r <<e n d l ;
10

11 return 0 ;
12 }

11
ISEP/DEI - Jorge Santos e Paulo Baltarejo

cin > > valorEuro; Esta instruo fica aguardar que o utilizador digite
(via teclado) o valor em euros. O valor digitado extrado para a varivel
valorEuro atravs do operador de extraco > >. O cin (console input) um
objecto que est normalmente associado ao teclado. O operador de extraco
extra do objecto que representa o teclado na aplicao para uma varivel da
aplicao;

#include<iostream.h> A directiva de pr-processador promove a incluso


a definio dos dois objectos associados quer a entrada de dados (cin) quer
sada de dados (cout);

valorDolar=valorEuro*taxa; Esta linha de cdigo realiza duas operaes,


a operao de multiplicao valorEuro*taxa; e a operao de atribuio do
clculo varivel valorDolar;

cout < < "Valor em dolar = " < < valorDolar < < endl; Esta linha de
cdigo coloca no ecr da nossa aplicao o texto "Valor em dolar = "concate-
nado com o contedo da varivel valorDolar seguido do manipulador de sada
de dados endl que coloca o caracter \n (nova linha) e obriga o objecto cout
a escrever no ecr.

1.6.1.1 Operadores aritmticos


O operador de atribuio serve para atribuir o resultado de uma expresso a uma
varivel. Conforme exemplo seguinte:
a=5;
A linha de cdigo anterior atribu o valor 5 varivel a. A parte esquerda do
operador = conhecida como lvalue (left value) e a parte direita como rvalue
(lado direito). rvalue uma expresso (e.g., uma varivel, uma constante, uma
operao ou qualquer combinao destes elementos) enquanto que o lvalue o
nome de uma varivel;
A operao de atribuio realizada da direita para a esquerda e nunca o inverso.
De seguida so apresentados alguns exemplos (ver tabela 1.4):

Tabela 1.4: Exemplo operadores compostos


Exemplo Resultado
a=10;
b=4; O valor da varivel c ser 10
c=a;
a=10;
b=4;
O valor da varivel a ser 60 ( 4*(10+5) )
c=5;
a=b*(c + a);
b=c=a=0; O valor das variveis a, b e c ser 0

A linguagem C++ define os seguintes operadores aritmticos simples (ver tabela


1.5). Na exemplificao dos operadores considerem-se as variveis a e b com valores,
13 e 5, respectivamente.

12
Apontamentos de Programao C/C++

Tabela 1.5: Operadores aritmticos


Operador Nome Exemplo Resultado
+ soma a+b 18
- subtraco a-b 8
* multiplicao a*b 65
/ diviso a/b 2.6
% resto da diviso inteira a%b 5

O C++ fornece igualmente os seguintes operadores aritmticos compostos (ver


tabela 1.6). Na exemplificao dos operadores considerem-se as variveis a e b com
valores, 13 e 5, respectivamente.

Tabela 1.6: Operadores aritmticos compostos


Operador Nome Exemplo Significado
+= soma/atribuio a+=b a=a+b
-= subtrao/atribuio a-=b a=a-b
*= multiplicao/atribuio a*=b a=a*b
/= diviso/atribuio a/=b a=a/b
%= resto diviso inteira/atribuio a%=b a=a%b
++ incremento a++ a=a+1
decremento b b=b-1

Note-se que os operadores aritmticos compostos da linguagem de programao


C++ permitem modificar o valor de uma varivel com um operador bsico.
Os operadores incremento (++) e decremento () s podem ser usados com
variveis. Estes incrementam e decrementam o valor da varivel em uma unidade.
Portanto, (++) e () so equivalentes a +=1 e a -=1, respectivamente.
Uma caracterstica destes operadores que podem ser usado como prefixo (pr
incremento ou prdecremento) ou como sufixo (posincremento ou pos-decremento).
Para tal, o operador tem de ser escrito antes da varivel (++a) ou depois da (a++;),
prefixo e sufixo, respectivamente. Embora quando usadas em expresses simples tipo
(++a;) ou (a++;) tenham o mesmo significado. Em operaes na quais o resultado
da operao de incremento ou de decremento avaliada noutra expresso, podem
ser diferentes. No caso do operador de incremento usado como prefixo (++a;) o valor
incrementado e depois a expresso avaliada e portanto o valor incrementado
considerado na expresso. No caso operador de incremento ser usado como sufixo
(a++;), o valor da varivel incrementado aps a avaliao da expresso.
A seguir apresentam-se dois exemplos para explicitar melhor as diferenas entre
os dois modos:

1.6.1.2 Operadores relacionais e lgicos

Nesta seco so apresentados os operadores relacionais e lgicos utilizados na lin-


guagem C++, bem como exemplos da sua utilizao.

13
ISEP/DEI - Jorge Santos e Paulo Baltarejo

Tabela 1.7: Operadores de incremento (modo prefixo e sufixo)

Exemplo Resultado
b=3;
O valor final de a ser 4 e o de b tambm
a=++b;
b=3;
O valor final de a ser 3 e o de b 4
a=b++;

Operadores relacionais

A tabela 1.8 apresenta os operadores relacionais da linguagem C++. Os operadores


relacionais avaliam a comparao entre duas expresses. O resultado dessa compa-
rao um valor do tipo bool que pode ser true ou false, obviamente de acordo
com o resultado da comparao.

Tabela 1.8: Operadores relacionais


Smbolo Significado
< menor que
> maior que
menor ou igual que
maior ou igual que
== igual
!= diferente

Na tabela 1.9 apresenta-se alguns exemplos da utilizao dos operadores relaci-


onais nos quais se consideram os valores a=5; b=6; c=7;.

Tabela 1.9: Exemplos de operadores relacionais


Exemplo Resultado
(7==5) falso
(a!=b) verdade
(a<=7) verdade
((a*b)>=c) verdade

Operadores lgicos

A tabela 1.10 apresenta os operadores lgicos da linguagem C++


O resultado das operaes com os operadores lgicos tambm verdade ou falso.
O operador !, colocado esquerda da expresso, inverte o valor lgico da mesma.
Isto , se a expresso verdadeira passa a falsa e viceversa. A tabela 1.11 apresenta
alguns exemplos da utilizao dos operadores lgicos.
De seguida so apresentadas as tabelas de verdades das operaes lgicas: con-
juno, disjuno e negao (tabela 1.12).

14
Apontamentos de Programao C/C++

Tabela 1.10: Operadores lgicos


Smbolo Significado
&& conjuno
|| disjuno
! negao

Tabela 1.11: Exemplos de operadores lgicos


Exemplo Resultado
((5==5) & & (3>6)) falso
((5==5) || (3>6)) verdade
!(5==5) falso
!verdade falso

Operador ternrio
O operador ternrio ou condicional avalia uma expresso e devolve diferentes valores
de acordo com a avaliao da expresso. A sintaxe deste operador a seguinte:
<condio> ? <resultado1> : <resultado2>
Se a <condio> verdade ento o operador vai devolver o <resultado1>. Caso
contrrio devolve o <resultado2>. Por exemplo:

int x;
x=(7==5 ? 4 : 3);

A varivel x vai ficar com o valor 3, uma vez que 7 diferente de 5.

bool x;
x=(5>3 ? true : false);

Neste caso atribuda varivel x o valor verdade.

Operadores manipulao bits


Os operadores de manipulao de bits aplicam-se apenas a expresses numricas
inteiras.
O operador um operador unrio e complementa (os bits 1s passam a 0s e
viceversa) todos os bits da varivel que estiver colocada ao seu lado direito. Os
operadores de deslocamento executam os deslocamento do operando colocado sua

Tabela 1.12: Tabelas de verdade: conjuno, disjuno e negao


a b a && b a b a || b
0 0 0 0 0 0 a !a
0 1 0 0 1 1 0 1
1 0 0 1 0 1 1 0
1 1 1 1 1 1

15
ISEP/DEI - Jorge Santos e Paulo Baltarejo

Tabela 1.13: Operadores de manipulao de bits


Smbolo Significado
Complemento (not)
& Conjuno (and)
| Disjuno inclusiva (or)
Disjuno exclusiva (xor)
>> Deslocamento direita (shift)
<< Deslocamento esquerda (shift)

Tabela 1.14: Tabela de verdade dos operadores de manipulao bits


a b a & b a | b a b
1 1 1 1 0
1 0 0 1 1
0 1 0 1 1
0 0 0 1 0

esquerda, um nmero de posies indicado pelo operando da direita. Os operadores


&, | e so binrios e caracterizam-se pelas seguintes relaes (ver tabela 1.14):
No deslocamento para a esquerda (< <) as posies que ficam livres so ocupadas
com bits a 0. No deslocamento para a direita (> >) as posies livres so ocupadas
com bits em 0, se a quantidade deslocada for sem sinal( unsigned ), ou com bits bits
idnticos ao mais significativo, se as quantidades deslocadas possurem sinal. Por
exemplo, x< <2, desloca a representao binria do valor contido em x, duas posies
(bits) para a esquerda. Se x contiver o valor binrio 00000010 (2 em decimal) ento
x< <2 faz com que x passe a conter o valor 00001000 (8 em decimal).

1.6.2 Exerccios Resolvidos


Nesta seco so apresentados alguns problemas e respectivas solues com o objec-
tivo de ilustrar a utilizao de instrues sequenciais.

1.6.2.1 Distncia euclidiana entre dois pontos


O programa da listagem 1.6 permite realizar o clculo da distncia euclidiana entre
dois pontos, sendo que cada ponto definido pelas coordenadas (x,y). A distncia
pode ser calculada de acordo com a frmula 1.6.1.
p
distncia = (x2 x1 )2 + (y2 y1 )2 (1.6.1)

Listing 1.6: Distncia euclidiana entre dois pontos


1 #include<i o s t r e a m . h>
2 #include<math . h>
3

4 int main ( )
5 {
6 int x1 , y1 , x2 , y2 ;

16
Apontamentos de Programao C/C++

7 double d i s t a n c i a ;
8 cout<<" Coordenadas ponto1 ( x/y ) : " ;
9 c i n >>x1>>y1 ;
10 cout<<" Coordenadas ponto2 ( x/y ) : " ;
11 c i n >>x2>>y2 ;
12

13 d i s t a n c i a=s q r t ( pow ( ( x2x1 ) ,2)+ pow ( ( y2y1 ) , 2 ) ) ;


14

15 cout<<" D i s t a n c i a="<<d i s t a n c i a <<e n d l ;


16 return 0 ;
17 }

1.6.2.2 Determinar permetro e rea de circunferncia


O programa da listagem 1.7 permite determinar o permetro e rea de uma circun-
ferncia, a partir do valor do raio.

Listing 1.7: rea e permetro de um circunferncia


1 #include <i o s t r e a m . h>
2 #include <math . h>
3 const double p i = 3 . 1 4 1 5 ;

4 int main ( )

5 {

6 double area , p e r i m e t r o ;
7 int r a i o ;
8

9 cout<<" I n t r o d u z a o v a l o r do r a i o : " ;
10 c i n >>r a i o ;
11 a r e a=p i pow ( r a i o , 2 ) ;
12 p e r i m e t r o=2 p i r a i o ;
13 cout<<" Area : "<<area<<e n d l ;
14 cout<<" P e r i m e t r o : "<<p e r i m e t r o <<e n d l ;
15

16 return 0 ;
17 }

1.6.3 Exerccios Propostos


Nesta seco so propostos alguns problemas com vista aplicao conjugada de
instrues sequenciais.

1.6.3.1 Calcular ndice de massa corprea (IMC)


O ndice de massa corprea (IMC) de um indivduo obtido dividindo-se o seu peso
(em Kg) por sua altura (em m) ao quadrado. Assim, por exemplo, uma pessoa de
1,67m e pesando 55kg tem IMC igual a 20,14, j que:

peso 55kg
IM C = 2
= = 20, 14
altura 1, 67m 1, 67m

17
ISEP/DEI - Jorge Santos e Paulo Baltarejo

Escreva um programa que solicite ao utilizador o fornecimento do seu peso em


kg e de sua altura em m e a partir deles calcule o ndice de massa corprea do
utilizador.

1.6.3.2 Converter horas, minutos e segundos


Escreva um programa que a partir de um determinado nmero de segundos cal-
cula o nmero de horas, minutos e segundos correspondentes. Conforme o seguinte
exemplo:

8053s = 2h + 14m + 13s

1.6.3.3 Teorema de Pitgoras


Escreva um programa para determinar a hipotenusa de um tringulo rectngulo,
dados os catetos.

1.6.3.4 Converter temperaturas


Escreva um programa que a partir de uma temperatura expressa em graus Fahrenheit
(tempF), calcule a temperatura expressa em graus Celsius (tempC). A converso
pode ser realizada de acordo com a frmula 1.6.2.

9 tempC
tempF = 32 + (1.6.2)
5

1.6.4 Instrues de Deciso


As instrues de deciso, ou seleco, permitem a seleco em alternncia de um ou
outro conjunto de aces aps a avaliao lgica de uma condio.

1.6.4.1 Deciso binria


A deciso binria permite bifurcar a execuo de um programa em dois fluxos dis-
tintos, para tal utilizada instruo if. Esta instruo pode ser utilizada de duas
formas: if e if-else.
No primeiro caso, se a condio for verdadeira executado o bloco-instrues
caso contrrio nada acontece:

if (<condio>)
{
<bloco-instrues>
}

No caso do <bloco-instrues> ser constitudo por uma s instrues no


necessrio delimitar essa instruo por chavetas ({ e }).
A listagem 1.8 apresenta um programa codificado em C++, cujo objectivo
escrever no ecr que o aluno foi aprovado no caso da nota ser superior a 9.5 valores.

18
Apontamentos de Programao C/C++

Listing 1.8: Estrutura de deciso if


1 #i n c l u d e <i o s t r e a m . h>
2 int main ( )
3 {
4 double nota ;
5 cout<<" I n t r o d u z a nota : " ;
6 c i n >>nota ;
7 i f ( nota >=9.5)
8 cout<<"O a l u n o f o i aprovado " ;
9

10 return 0 ;
11 }
No segundo caso, se a condio for verdadeira executado o bloco-instrues 1
seno executado o bloco-instrues 2:

if (<condio>)
{
<bloco-instrues 1>
}
else
{
<bloco-instrues 2>
}

Considere-se o programa em C++ presente na listagem 1.9. Neste programa so


lidas as medidas dos lados de uma figura rectangular, sendo que no caso particular
de os dois lados serem iguais estamos na presena de um quadrado. Em qualquer
um dos casos apresentada a mensagem correspondente assim como o valor da rea.

Listing 1.9: Exemplo de utilizao da instruo if-else


1 #include<i o s t r e a m . h>
2 int main ( )

3 {

4 int lado1 , lado2 , a r e a ;


5 cout<<" I n t r o d u z a medidas dos l a d o s : " ;
6 c i n >>lado1 >>l a d o 2 ;
7 a r e a=l a d o 1 l a d o 2 ;
8 i f ( l a d o 1==l a d o 2 )
9 cout<<" Area do quadrado= "<<a r e a ;
10 else
11 cout<<" Area do r e c t a n g u l o= "<<a r e a ;
12

13 return 0 ;
14 }

1.6.4.2 Deciso mltipla


A instruo de de deciso mltipla um caso particular de instrues if-else
encadeadas.

19
ISEP/DEI - Jorge Santos e Paulo Baltarejo

if (<condio 1>)
{
<bloco-instrues 1>
}
else
{
if(<condio 2>)
{
<bloco-instrues 2>
}
else
{
if(<condio 3>)
{
<bloco-instrues 3>
}
else
...
}
}

Considere-se o programa da listagem 1.10 em que o objectivo determinar qual


o maior de trs nmeros.

Listing 1.10: Determinar o maior trs nmeros


1 #include<i o s t r e a m . h>
2

3 int main ( )
4 {
5 int num1 , num2 , num3 , maximo ;
6 cout<<" I n t r o d u z a numero1 , numero2 e numero3 : " ;
7 c i n >>num1>>num2>>num3 ;
8

9 i f (num1>=num2)
10 {
11 i f (num1>=num3)
12 maximo=num1 ;
13 }
14 e l s e // s e num1<num2
15 {
16 i f (num2>=num3)
17 maximo=num2 ;
18 else
19 maximo=num3 ;
20 }
21 cout<<"O numero maior e : "<<maximo ;
22

23 return 0 ;
24 }

20
Apontamentos de Programao C/C++

A instruo switch proporciona uma forma especial de tomada de decises ml-


tiplas. Ela permite examinar os diversos valores de uma expresso compatvel com
nmeros inteiros e seleccionar o resultado adequado.

switch(expresso)
{
case constante 1:<bloco-instrues 1>
break;
case constante 2:<bloco-instrues 2>
break;
....
default:<bloco-instrues N>
}

Considere uma mquina que permite apenas trs operaes, ligar, desligar e
furar. O programa da listagem 1.11 permite modelar o funcionamento da respectiva
mquina. Sendo que aquando da digitao das letras: L, D e F, so apresentados,
respectivamente, as mensagens: Ligar, Desligar e Furar. No caso da letra digitada
ser outra apresentada mensagem de erro.
Listing 1.11: Exemplo da instruo switch
1 #include<i o s t r e a m . h>
2

3 int main ( )
4 {
5 char l e t r a ;
6 cout<<" I n t r o d u z a l e t r a (L/D/F ) : " ;
7 c i n >>l e t r a ;
8 switch ( l e t r a )
9 {
10 case L :
11 cout<<" L i g a r " ;
12 break ;
13 case D :
14 cout<<" D e s l i g a r " ;
15 break ;
16 case F :
17 cout<<" Furar " ;
18 break ;
19 default :
20 cout<<" Operacao i n v a l i d a " ;
21 }
22

23 return 0 ;
24 }

1.6.5 Prioridade dos operadores


Na avaliao de expresses so complexas, com vrios operandos e operadores,
fundamental saber qual a ordem pela qual a expresso ser avaliada. A tabela

21
ISEP/DEI - Jorge Santos e Paulo Baltarejo

1.15 apresenta a relao dos principais operadores da linguagem C++. Note-se que
alguns dos operadores referidos na tabela sero posteriormente apresentados.

Tabela 1.15: Relao de precedncia dos operadores


Prior. Operador Descrio Sentido
1 (, ), [, ], ->, ., sizeof
++, - - incremento/decremento
complemento para um
! negao
2
&,* referncia/ponteiro
(tipo de dados) converso de tipos de dados
+, - sinal
3 *, /, % operadores aritmticos
4 +, - operadores aritmticos
5 < <, > > operador de deslocamento
(bit a bit)
6 <, <=, >, >= operadores relacionais
7 ==, != operadores relacionais
8 &, , | operadores de manipulao
de bits
9 &&, || operadores lgicos
10 ?, : condicional
11 =, +=, -=, *=, /=, %=, atribuio
> >=, < <=, &=, =, |=
12 , vrgula, separador

No entanto pode-se resolver algumas dvidas em relao precedncia e sequn-


cia de avaliao com a utilizao de parntesis((,)).

1.6.6 Exerccios Resolvidos


Nesta seco so apresentados alguns problemas e respectivas solues com o objec-
tivo de ilustrar a utilizao de instrues de deciso.

1.6.6.1 Distncia euclidiana entre dois pontos


O programa da listagem 1.12 permite realizar o clculo da distncia euclidiana entre
dois pontos, sendo que cada ponto definido pelas coordenadas (x,y). no clculo da
distncia pode ser utilizada a frmula 1.6.3.
p
distncia = (x2 x1 )2 + (y2 y1 )2 (1.6.3)
Caso os pontos sejam coincidentes mostra mensagem "Pontos Coincidentes".

Listing 1.12: Distncia euclidiana entre dois pontos


1 #include<i o s t r e a m . h>
2 #include<math . h>

22
Apontamentos de Programao C/C++

4 int main ( )
5 {
6 int x1 , y1 , x2 , y2 ;
7 double d i s t a n c i a ;
8 cout<<" Coordenadas ponto1 ( x/y ) : " ;
9 c i n >>x1>>y1 ;
10 cout<<" Coordenadas ponto2 ( x/y ) : " ;
11 c i n >>x2>>y2 ;
12

13 d i s t a n c i a=s q r t ( pow ( ( x2x1 ) ,2)+ pow ( ( y2y1 ) , 2 ) ) ;


14

15 i f ( ( int ) d i s t a n c i a ==0)
16 cout<<"Os p ont o s s a o c o i n c i d e n t e s "<<e n d l ;
17 else
18 cout<<" D i s t a n c i a="<<d i s t a n c i a <<e n d l ;
19 return 0 ;
20 }

1.6.6.2 Classificar em funo da mdia


O programa da listagem 1.13 permite ler as notas de um aluno s disciplinas de
Matemtica, Portugus, Ingls e Geografia e calcular a mdia. Em funo da mdia
mostra uma mensagem com o contedo "Aprovado" ou "Reprovado". Consideram-se
notas positivas as notas iguais ou superiores a 9,5.
Listing 1.13: Calcular a mdia
1 #include<i o s t r e a m . h>
2

3 int main ( )
4 {
5 int mat , por , ing , geo ;
6 double media ;
7 cout<<" I n t r o d u z a a s n o t a s ( mat/ por / i n g / geo ) : " ;
8 c i n >>mat>>por>>ing>>geo ;
9 media=(double ) ( mat+por+i n g+geo ) / 4 ;
10

11 i f ( media >=9.5)
12 cout<<" Aprovado "<<e n d l ;
13 else
14 cout<<" Reprovado "<<e n d l ;
15 return 0 ;
16 }

1.6.6.3 Determinar o mximo de 3 valores


O programa da listagem 1.14 permite determinar o maior de trs nmeros.
Listing 1.14: Mximo de trs valores
1 #include<i o s t r e a m . h>
2

3 int main ( )

23
ISEP/DEI - Jorge Santos e Paulo Baltarejo

4 {
5 int A, B, C, maximo ;
6 cout<<" I n t r o d u z a numero1 , numero2 , numero3 : " ;
7 c i n >>A>>B>>C;
8 i f (A>=B)
9 {
10 i f (A>=C)
11 maximo=A;
12 }
13 else
14 {
15 i f (B>=C)
16 maximo=B ;
17 else
18 maximo=C;
19 }
20 cout<<"O numero maior e : "<<maximo ;
21 return 0 ;
22 }
Sugesto: Baseando-se nas solues propostas escreva um programa que permita
a determinao do mximo entre 5 nmeros. Qual a soluo mais elegante?

1.6.6.4 Determinar tringulo vlido


O programa da listagem 1.15 permite ler trs pontos geomtricos e determinar se
estes formam um tringulo. Pode ser utilizada a frmula da distncia entre dois
pontos para calcular as medidas dos lados do tringulo. Note-se que um tringulo
s vlido se a medida de cada um dos seus lados menor que a soma dos lados
restantes.
Listing 1.15: Tringulo vlido
1 #include<i o s t r e a m . h>
2 #include<math . h>
3

4 int main ( )
5 {
6 int x1 , y1 , x2 , y2 , x3 , y3 ;
7 double lado1 , lado2 , l a d o 3 ;
8 cout<<" Coordenadas ponto1 ( x/y ) : " ;
9 c i n >>x1>>y1 ;
10 cout<<" Coordenadas ponto2 ( x/y ) : " ;
11 c i n >>x2>>y2 ;
12 cout<<" Coordenadas ponto3 ( x/y ) : " ;
13 c i n >>x3>>y3 ;
14

15

16 l a d o 1=s q r t ( pow ( ( x2x1 ) ,2)+ pow ( ( y2y1 ) , 2 ) ) ;


17 l a d o 2=s q r t ( pow ( ( x3x1 ) ,2)+ pow ( ( y3y1 ) , 2 ) ) ;
18 l a d o 3=s q r t ( pow ( ( x3x2 ) ,2)+ pow ( ( y3y2 ) , 2 ) ) ;
19

20 i f ( lado1 <( l a d o 2+l a d o 3 )

24
Apontamentos de Programao C/C++

21 && lado2 <( l a d o 1+l a d o 3 )


22 && lado3 <( l a d o 1+l a d o 2 ) )
23 cout<<" t r i a n g u l o v a l i d o "<<e n d l ;
24 else
25 cout<<"Os p ont o s no forman um t r i a n g u o "<<e n d l ;
26 return 0 ;
27 }

1.6.7 Exerccios Propostos


Nesta seco so propostos alguns problemas com vista aplicao de instrues de
deciso.

1.6.7.1 Classificar tringulo


Classificar um tringulo quanto aos lados, sendo que um tringulo com todos lados
iguais designado Equiltero, com todos os lados diferentes entre si designado
Escaleno e caso tenha apenas dois lados iguais entre si, designa-se Issceles.

1.6.7.2 Diviso
Escreva um programa que dados dois valores, divide o primeiro pelo segundo. Note
que no possvel fazer a diviso por zero, neste caso deve ser apresentada a men-
sagem adequada.

1.6.7.3 Resolver equao da forma ax2 + bx + c = 0


Calcular as razes de uma equao na forma ax2 + bx + c = 0. Note que os valores
a, b e c podem ser zero, podendo dar origem a equaes sem soluo ou equaes
de primeiro grau. Considere as frmulas 1.6.4 e 1.6.5 na resoluo do problema.

binmio = b2 4ac (1.6.4)



b binmio
x = (1.6.5)
2a

1.6.7.4 Converter entre escalas de temperaturas


Escrever um programa que faa converses entre as trs escalas de temperaturas,
Kelvin, Celsius e Fahrenheit, com base em trs valores de entrada: a temperatura e
escala actual e escala pretendida. Conforme o seguinte exemplo:
As entradas 38, C e K, significam que o utilizador pretende converter a tem-
peratura 38 Celsius para Kelvin. Considere as frmulas 1.6.6 e 1.6.7 na resoluo
do programa.

9 tempC
tempF = 32 + (1.6.6)
5
tempC = tempK + 273 (1.6.7)
Sugesto: Tentar a resoluo com as estruturas se-ento-seno e alternativa-
mente utilizar a estrutura de mltipla deciso.

25
ISEP/DEI - Jorge Santos e Paulo Baltarejo

1.6.7.5 Calcular ndice de massa corprea (IMC)


O ndice de massa corprea (IMC) de um indivduo obtido dividindo-se o seu peso
(em Kg) por sua altura (em m) ao quadrado. Assim, por exemplo, uma pessoa de
1,67 m e pesando 55 Kg tem IMC igual a 20,14, j que:
peso 55kg
IM C = 2
= = 20, 14
altura 1, 67m 1, 67m

IMC Interpretao
At 18,5 (inclusive) Abaixo do peso normal
De 18,5 a 25 (inclusive) Peso normal
De 25 a 30 (inclusive) Acima do peso normal
Acima de 30 Obesidade

Tabela 1.16: ndice de massa corprea

Considerando a tabela 1.16, escreva um programa que leia o peso em kg e a altura


em m de uma determinada pessoa de forma a calcular o ndice de massa corprea do
mesmo e de seguida, estabelea as comparaes necessrias entre o IMC calculado
e os valores da tabela 1.16 e escreva uma das frases, conforme for o caso:

Voc est abaixo do peso normal ;


O seu peso est na faixa de normalidade;
Voc est acima do peso normal ;
Voc precisa de perder algum peso.

1.6.7.6 Determinar ano bissexto


Um ano bissexto se divisvel por 4, excepto se, alm de ser divisvel por 4, for
tambm divisvel por 100. Ento ele s bissexto se tambm for divisvel por 400.
Escrever um programa que leia o valor de um ano e escreva se o ano ou no
bissexto.

1.6.7.7 Parque de estacionamento


Considere um parque de estacionamento que pratica os preos seguintes:

1a hora: 2 e;
2a hora: 1,5 e;
a partir da 2a hora: 1 e/hora.

O tempo de permanncia no parque contabilizado em horas e minutos. Por


exemplo, se uma viatura permanecer 2 horas e 30 minutos no parque, pagar 2 e
(1a hora) + 1,5 e (2a hora) + 0,5 e (30 minutos a 1 e/hora) = 4 e.
Elabore um programa que, lido o tempo que determinada viatura permaneceu
estacionada no parque, diga a quantia que deve ser paga.

26
Apontamentos de Programao C/C++

1.6.8 Instrues de Repetio


As instrues de repetio, ou ciclos, permitem a execuo, de forma repetitiva, de
um conjunto de instrues. Esta execuo depende do valor lgico de uma condio
que testada em cada iterao para decidir se a execuo do ciclo continua ou
termina.
A linguagem de programao C++ compreende trs estruturas distintas de con-
trolo do tipo cclico: do-while, while e for.

1.6.8.1 Instruo do-while

O ciclo do-while um ciclo condicional que executa a iterao enquanto uma con-
dio for verdadeira. Esta condio avaliada no fim. A seguir apresenta-se a
sintaxe da estrutura do-while. O controlo do ciclo processa-se da seguinte forma.
O <bloco-instrues> sempre executado pelo menos uma vez de pois avaliada
a <condio>. Caso o resultado da avaliao seja verdade o ciclo continua at que
o resultado da avaliao seja falso. Portanto quando o resultado da avaliao da
condio for falso o ciclo termina.

do
{
<bloco-instrues>
}
while (<condio>);

Considere-se o seguinte exemplo em cuja utilizao da estrutura do-while per-


mite garantir que o valor da nota introduzida est situado entre 0 e 20.
O programa da listagem 1.16 apresenta uma soluo para o problema anterior
utilizando a estrutura do-while. Neste programa o ciclo executado uma vez e
caso o valor introduzido pelo utilizador (armazenado na varivel nota) seja inferior
a 0 ou superior a 20 a ciclo continua at que o valor da nota seja vlido, isto , entre
0 e 20.

Listing 1.16: Exemplo da instruo do-while


1 #include<i o s t r e a m . h>
2

3 int main ( )
4 {
5 int nota ;
6 do
7 {
8 cout<<" I n t r o d u z i r nota e n t r e 0 20: " ;
9 c i n >>nota ;
10 }
11 while ( nota <0 | | nota >20);
12

13 return 0 ;
14 }

27
ISEP/DEI - Jorge Santos e Paulo Baltarejo

1.6.8.2 Instruo while


O ciclo while tambm um ciclo condicional que realiza a iterao enquanto uma
determinada condio for verdadeira. A condio avaliada no inicio da iterao.
Por isso, o ciclo while pode no realizar nenhuma iterao. A seguir apresentase
a sintaxe da estrutura while. O controlo do ciclo processase da seguinte forma.
A avaliao da condio feita no inicio e caso o resultado da seja verdade ento
o <bloco-instrues> executado. No caso do resultado ser falso ento o ciclo
termina.

while (<condio>)
{
<bloco-instrues>
}

Considere-se o seguinte exemplo em cuja utilizao da estrutura while permite


calcular e escrever a tabuada de um nmero. A seguir apresentase uma possvel
codificao (1.17) em C++ do problema anterior. Neste exemplo o ciclo while vai
fazer 10 iteraes, uma vez que a varivel i iniciada a 1, em cada iterao esta
incrementada em um valor e o ciclo s termina quando a varivel i for >10.

Listing 1.17: Exemplo da instruo while


1 #include<i o s t r e a m . h>
2

3 int main ( )
4 {
5 int numero , r e s u l t a d o , i ;
6 cout<<" I n t r o d u z a o numero : " ;
7 c i n >>numero ;
8 i =1;
9 while ( i <=10)
10 {
11 r e s u l t a d o=numero i ;
12 cout<<numero<<" "<<i <<" = "<<r e s u l t a d o <<e n d l ; ;
13 i ++;
14 }
15

16 return 0 ;
17 }

1.6.8.3 Instruo for


O ciclo for bastante verstil porque aceita tanto iteraes fixas como condicionais.
Esta instruo constituda por trs elementos (todos opcionais). O primeiro ele-
mento a iniciao das variveis de controlo das iteraes. A iniciao s acontece na
primeira iterao. O segundo elemento a condio de controlo das iteraes. Uma
iterao s acontece se a condio for verdadeira. A condio sempre avaliada.
O terceiro elemento usado para actualizar as variveis de controlo do ciclo. Este
elemento no executado na primeira iterao, s nas subsequentes. Um aspecto
muito importante que a avaliao acontece sempre depois dos outros elementos.

28
Apontamentos de Programao C/C++

Na primeira iterao, as variveis so iniciadas e s depois avaliada a condio.


Nas iteraes subsequentes as variveis so actualizadas e s depois feita a avalia-
o. Obviamente, a iterao s acontece se a condio for verdadeira. Embora no
seja muito frequente, pode acontecer que nenhuma iterao seja efectuada.

for(<iniciao>;<condio>;<actualizao>)
{
<bloco-instrues>
}

Considerese o seguinte exemplo em cuja utilizao da instruo for permite


calcular a soma os 100 primeiros nmeros inteiros.
Neste exemplo introduzido um conceito importante para a programao, o
conceito de acumulador. A varivel soma em cada iterao adicionada do valor da
varivel i, permitindo que no final:
soma = 1 + 2 + 3 + 4 + 5 + ... + 100 = 5050
Por outro lado, a instruo i++; faz com que a varivel i tome todos os valores
inteiros de 1 a 100.
Listing 1.18: Exemplo da instruo for
1 #include<i o s t r e a m . h>
2

3 int main ( )
4 {
5 int soma=0, i ;
6 f o r ( i =1; i <=100; i ++)
7 soma+=i ;
8 cout<<soma ;
9 return 0 ;
10 }

Instruo break
A instruo break permite sair de um ciclo mesmo que a condio ainda seja ver-
dadeira. O cdigo 1.19 apresenta um exemplo de um ciclo que interrompido pela
instruo break. O ciclo comea com a varivel n =10 e enquanto n for >0 vai exe-
cutar o bloco de instrues. De cada iterao a varivel n decrementada numa
unidade. O bloco de instrues tem uma estrutura de deciso que quando o n for
igual a 3 vai escrever uma mensagem no ecr e executar a instruo break. O que
significa que o ciclo vai terminar quando a varivel n 3, portanto maior que 0.
Listing 1.19: Exemplo da instruo break
1 #include <i o s t r e a m . h>
2

3 int main ( )
4 {
5 int n ;
6 f o r ( n=10; n>0; n)
7 {
8 c o u t << n << " , " ;

29
ISEP/DEI - Jorge Santos e Paulo Baltarejo

9 i f ( n==3)
10 {
11 c o u t << " terminou o c i c l o ! " ;
12 break ;
13 }
14 }
15 return 0 ;
16 }

Instruo continue
A instruo continue faz com que o ciclo passa para a iterao seguinte e as ins-
trues que esto a seguir no sejam executadas. A listagem seguinte apresenta um
exemplo com a instruo continue. Neste exemplo todos os nmeros 10 a 1 so
escritos no ecr com excepo do 5. Isto porque, quando n igual a 5 a instruo
continue executada e por conseguinte a linha de cdigo cout < < n < < ", ";
no executada.
Listing 1.20: Exemplo da instruo continue
1 #include <i o s t r e a m . h>
2

3 int main ( )
4 {
5 int n ;
6 f o r ( n=10; n>0; n)
7 {
8 i f ( n==5)
9 continue ;
10 c o u t << n << " , " ;
11 }
12 return 0 ;
13 }

1.6.9 Exerccios Resolvidos


Nesta seco so apresentados alguns problemas e respectivas solues com o ob-
jectivo de ilustrar a utilizao de instrues cclicas. Nas solues so exploradas
situaes com utilizao simples dos ciclos e/ou imbricados.

1.6.9.1 Calcular somatrio entre dois limites


O programa da listagem 1.21 permite calcular a somatrio dos nmeros existentes
num intervalo definido por limites inferior e superior. Note que o utilizador pode
introduzir os limites na ordem que entender, desta forma os intervalos [5-10] e [10-5]
so igualmente vlidos.
Listing 1.21: Calcular somatrio entre dois limites
1 #include<i o s t r e a m . h>
2

3 int main ( )

30
Apontamentos de Programao C/C++

4 {
5 int lim1 , lim2 , min , max , soma , i ;
6 cout<<" I n t r o d u z a numero1 : " ;
7 c i n >>l i m 1 ;
8 cout<<" I n t r o d u z a numero2 : " ;
9 c i n >>l i m 2 ;
10 i f ( lim2>l i m 1 )
11 {
12 min=l i m 1 ;
13 max=l i m 2 ;
14 }
15 else
16 {
17 min=l i m 2 ;
18 max=l i m 1 ;
19 }
20 soma=0;
21

22 f o r ( i=min ; i<=max ; i ++)


23 soma+=i ;
24

25 cout<<" Somatorio [ "<<min<<" , "<<max<<" ] : "<<soma ;


26

27 return 0 ;
28 }

1.6.9.2 Calcular factorial de um nmero


O programa da listagem 1.22 permite calcular o factorial de um nmero sabendo
que:

n=0 1
factorial(n) =
n 1 n factorial(n 1)
Exemplo: factorial(5)=5*4*3*2*1=120
Listing 1.22: Calcular factorial de um nmero
1 #include<i o s t r e a m . h>
2

3 int main ( )
4 {
5 int f a c t o r i a l , i , numero ;
6 cout<<" I n t r o d u z a numero : " ;
7 c i n >>numero ;
8 f a c t o r i a l =1;
9 f o r ( i =1; i<=numero ; i ++)
10 f a c t o r i a l = i ;
11

12 cout<<" F a c t o r i a l ( "<<numero<<" ) : "<< f a c t o r i a l ;


13

14 return 0 ;
15 }

31
ISEP/DEI - Jorge Santos e Paulo Baltarejo

1.6.9.3 Determinar se um nmero primo


Um nmero primo se for apenas divisvel por si prprio e pela unidade, por exem-
plo: 11 nmero primo (visto que apenas divisvel por 11 e por 1), enquanto que
21 no primo, pois tem os seguintes divisores: 1,3,7 e 21. O programa da listagem
1.23 permite determinar se um nmero ou no primo.

Listing 1.23: Determinar se um nmero primo


1 #include<i o s t r e a m . h>
2

3 int main ( )
4 {
5 int i , numero ;
6 bool primo=true ;
7 cout<<" I n t r o d u z a numero : " ;
8 c i n >>numero ;
9 i =2;
10 while ( primo==true && i <=(numero / 2 ) )
11 {
12 i f ( numero%i ==0)
13 primo=f a l s e ;
14 i ++;
15 }
16 i f ( ! primo )
17 cout<<"O numero "<<numero<<" nao e primo "<<e n d l ;
18 else
19 cout<<"O numero "<<numero<<" e primo "<<e n d l ;
20

21 return 0 ;
22 }

1.6.9.4 Determinar nmero e idade da pessoa mais nova de um grupo


O programa da listagem 1.24 permite ler o nmero e a idade de uma srie de pessoas.
Este programa deve terminar quando for introduzido o nmero da pessoa = 0. No
final deve ser mostrado o nmero e idade da pessoa mais nova.

Listing 1.24: Pessoa mais nova


1 #include<i o s t r e a m . h>
2

3 int main ( )
4 {
5 int numero , idade , menorNumero=0, menorIdade =0;
6 bool p r i m e i r o=true ;
7 do
8 {
9 cout<<" I n t r o d u z a numero : " ;
10 c i n >>numero ;
11 i f ( numero >0)
12 {
13 cout<<" I n t r o d u z a a i d a d e : " ;

32
Apontamentos de Programao C/C++

14 c i n >>i d a d e ;
15 i f ( ! primeiro )
16 {
17 i f ( idade <menorIdade )
18 {
19 menorNumero=numero ;
20 menorIdade=i d a d e ;
21 }
22 }
23 else
24 {
25 menorNumero=numero ;
26 menorIdade=i d a d e ;
27 p r i m e i r o=f a l s e ;
28 }
29 }
30 }
31 while ( numero ! = 0 ) ;
32

33 i f ( primeiro )
34 cout<<"Nao foram i n s e r i d o s e l e m e n t o s "<<e n d l ;
35 else
36 {
37 cout<<"O numero e i d a d e da p e s s o a mais nova : " ;
38 cout<<menorNumero<<" , "<<menorIdade<<e n d l ;
39 }
40 return 0 ;
41 }

1.6.9.5 Determinar o aluno melhor classificado e a mdia das notas de


uma turma
O programa da listagem 1.25 permite ler as notas de portugus obtidas pelos ele-
mentos de uma turma. Este programa termina quando for introduzido o numero
do aluno 0. No final deve ser mostrado o nmero do aluno melhor classificado e a
mdia de notas de turma.

Listing 1.25: Melhor aluno e mdia das notas


1 #include<i o s t r e a m . h>
2

3 int main ( )
4 {
5 int numero , nota , melhorNumero =0, melhorNota =0;
6 int somaNotas =0,numAlunos =0;
7 bool p r i m e i r o=true ;
8 double media = 0 . 0 ;
9 do{
10 cout<<" I n t r o d u z a numero : " ;
11 c i n >>numero ;
12 i f ( numero >0)
13 {

33
ISEP/DEI - Jorge Santos e Paulo Baltarejo

14 numAlunos++;
15 do
16 {
17 cout<<" I n t r o d u z a a nota : " ;
18 c i n >>nota ;
19 }
20 while ( nota <0 | | nota >20);
21

22 somaNotas+=nota ;
23

24 i f ( ! primeiro )
25 {
26 i f ( nota>melhorNota )
27 {
28 melhorNumero=numero ;
29 melhorNota=nota ;
30 }
31 }
32 else
33 {
34 melhorNumero=numero ;
35 melhorNota=nota ;
36 p r i m e i r o=f a l s e ;
37 }
38 }
39 }
40 while ( numero ! = 0 ) ;
41 i f ( numAlunos >0)
42 {
43 media=(double ) somaNotas /numAlunos ;
44 cout<<"Numero do melhor a l u n o : "<<melhorNumero<<e n d l ;
45 cout<<" Nota do melhor a l u n o : "<<melhorNota<<e n d l ;
46 cout<<" Media das n o t a s : "<<media<<e n d l ;
47 }
48 else
49 cout<<"Nao foram i n s e r i d o s n o t a s "<<e n d l ;
50

51 return 0 ;
52 }

1.6.10 Exerccios Propostos


Nesta seco so propostos alguns problemas com vista aplicao dos diferentes
tipos de instrues anteriormente introduzidas com particular nfase na instrues
cclicas.

1.6.10.1 Diviso atravs de subtraces sucessivas


O resultado da diviso inteira de um nmero inteiro por outro nmero inteiro pode
sempre ser obtido utilizandose apenas o operador de subtraco. Assim, se quiser-

34
Apontamentos de Programao C/C++

mos calcular (7/2), basta subtrair o dividendo (2) ao divisor (7), sucessivamente,
at que o resultado seja menor do que o dividendo.
O nmero de subtraces realizadas corresponde ao quociente inteiro, conforme
o exemplo seguinte:

72 = 5
52 = 3
32 = 1

Descrever um programa para o clculo da diviso de um inteiro pelo outro. Note


que se o dividendo for zero, esta uma operao matematicamente indefinida.

1.6.10.2 Determinar o mximo e mnimo de uma srie


Ler 100 valores e determinar os valores mximo e mnimo da srie.

1.6.10.3 Determinar quantidade de nmeros primos


Determinar quantos so os nmeros primos existentes entre os valores 1 e 1000
(excluindo os limites do intervalo).

1.6.10.4 Determinar se um nmero perfeito


Um nmero n perfeito se a soma dos divisores inteiros de n (excepto o prprio n)
igual ao valor de n. Por exemplo, o nmero 28 tem os seguintes divisores: 1, 2, 4,
7, 14, cuja soma exactamente 28. (Os seguintes nmeros so perfeitos: 6, 28, 496,
8128.)
Escreva um programa que verifique se um nmero perfeito.

1.6.10.5 Calcular potncia por multiplicaes sucessivas


Escrever um programa que permita calcular uma potncia do tipo baseexpoente
atravs de multiplicaes sucessivas. Por exemplo: 24 = 2 2 2 2. Considere as
diferentes situaes relacionadas com os valores da base e/ou expoente iguais a zero.

1.6.10.6 Maior nmero mpar de uma sequncia de valores


Escreva um programa que l uma sequncia de nmeros inteiros terminada pelo
nmero zero e calcule o maior mpar e a sua posio na sequncia de valores.

1.6.10.7 Algarismos de um nmero


Escreva um programa para extrair os algarismos que compem um nmero e os
visualize individualmente.

1.6.10.8 Apresentao grfica de temperaturas


Escreva um programa que leia a temperatura de N cidades portuguesas e que re-
presente a temperatura de cada uma delas com uma barra de asteriscos (*), em que
cada asterisco representa um intervalo de 2 C. De acordo com os exemplos seguintes:

35
ISEP/DEI - Jorge Santos e Paulo Baltarejo

Porto 11 *****
Lisboa 16 ********
Faro 20 **********
Chaves 8 ****

1.6.10.9 Soma dos algarismo de um nmero


Escreva um programa que calcule a soma dos algarismos que compem um nmero.
Por exemplo: 7258 = 7+2+5+8 = 22

1.6.10.10 Jogo de adivinhar o nmero


Escrever um programa para o o jogo de adivinhar um nmero. Este jogo consiste no
seguinte: o programa sorteia um nmero e o jogador deve tentar adivinhar o nmero
sorteado. Para isso o programa deve indicar se o palpite do jogador foi maior, menor
ou se acertou no nmero sorteado. Caso o jogador acerte deve visualizado no ecr
o nmero de tentativas utilizadas.

1.6.10.11 Capicua de um nmero


Escreva um programa que leia um nmero inteiro positivo e verifique se se trata de
uma capicua, isto , uma sequncia de dgitos cuja leitura a mesma nos dois sentidos
(exemplo:32523). Sugesto: Inverter a ordem dos dgitos e verificar se o nmero
obtido coincide com o original. Por exemplo, 327 invertido ((7*10)+2)*10+3=723.

1.6.10.12 Converso de base numrica


Elaborar um programa para converter um nmero escrito em binrio para o corres-
pondente na base decimal. A converso fazse de acordo com o exemplo seguinte:

10110011(2) =
= 1 27 + 0 26 + 1 25 + 1 24 + 0 23 + 0 22 + 1 21 + 1 20
= 128 + 0 + 32 + 0 + 16 + 0 + 0 + 2 + 1
= 179(10)

Note que os expoentes das potncias na frmula de converso correspondem, res-


pectivamente, posio ocupada por cada algarismo no nmero em binrio. Sendo
que o algarismo mais direita corresponde posio zero.

1.7 Funes
As funes permitem estruturar o cdigo de uma forma mais modular, aproveitando
as potencialidades da programao estruturada que a linguagem C++ oferece.
Uma funo um bloco de instrues que executado quando chamada em
alguma parte do programa. A sintaxe de uma funo a seguinte:

<tipo-de-dados> <id-da-funo>( <argumento 1>,<argumento 2>,...)


{

36
Apontamentos de Programao C/C++

<bloco-de-instrues>
}

na qual:

<tipo-de-dados> este o tipo de dados devolvido pela funo;

<id-da-funo> este o identificador pela qual a funo conhecida. As


regras para definio de um identificador so as mesmas que para as variveis;

<argumento 1>, <argumento 2>,... estes so os argumentos da funo (o


nmero de argumentos varivel, pode ser zero). Cada argumento consiste
num tipo de dados seguido do identificador pelo qual esse argumento vai ser
identificado dentro da funo (por exemplo int x). Um argumento como
uma declarao de uma varivel dentro da funo. Os argumentos permitem
passar parmetros para dentro de uma funo quando esta invocada. Os
diferentes parmetros tem que ser separados pelo operador vrgula (,);

<bloco de instrues> o corpo da funo e tem que estar sempre deli-


mitado por chavetas({}). constitudo por zero ou mais instrues.

A listagem 1.26 apresenta um exemplo de uma funo. Para examinar este cdigo
interessa lembrar que um programa em C++ comea a sua execuo pela funo
main.
Listing 1.26: Exemplo da utilizao de funes
1 #include <i o s t r e a m . h>
2

3 int soma ( int n1 , int n2 )


4 {
5 int r ;
6 r=n1+n2 ;
7

8 return r ;
9 }
10

11 int main ( )
12 {
13 int a , b , z ;
14 a =5;
15 b=3;
16 z = soma ( a , b ) ;
17 c o u t << " R e s u l t a d o : " << z ;
18

19 return 0 ;
20 }
Na funo main declarada uma varivel do tipo int com o identificador z. A
seguir chamada a funo soma. Os parmetros tem uma correspondncia clara
com os argumentos. Na funo main invocada a funo soma passandolhe dois
valores 5 e o 3 que na funo soma correspondem s variveis n1 e n2. Quando a
funo soma invocada o fluxo de execuo sai funo main e passa para a funo

37
ISEP/DEI - Jorge Santos e Paulo Baltarejo

int soma (int n1, int n2)


int main ()
{
{
int r;
int z;
r=n1+n2;
z = soma(5,3);
return r;
cout << "Resultado: " << z;
}
return 0;
}

Figura 1.3: Execuo de uma funo

soma (ver figura 1.3). Os valores so copiados para as variveis int n1 e int n2 da
funo soma .
Na funo soma definida a varivel r do tipo int qual atribudo o resultado
da operao a mais b. Neste caso como a varivel a tem o valor 5 e a varivel b tem
o valor 3 o resultado 8. Portanto a varivel r tem o valor 8. A seguinte linha
return r;
termina a funo soma e retorna o controlo do fluxo de execuo funo main,
que recomea onde foi interrompida pela chamada funo soma. Alm disso, a
instruo return retorna o valor de r. Este valor retornado pela funo soma
atribudo varivel z;
Uma funo no tem obrigatoriamente que ter argumentos e pode no retornar
nada. Para os casos em que a funo no retorna nenhum valor o tipo da funo
void, neste caso a funo tambm designada de procedimento. A seguir (1.27)
apresentase uma funo que no tem argumentos nem retorna qualquer valor.

Listing 1.27: Exemplo de uma funo void


1 #include <i o s t r e a m . h>
2

3 void imprime ( void )


4 {
5 cout<<" I s t o e uma f u n c a o ! " ;
6 }
7

8 int main ( )
9 {
10 imprime ( ) ;
11 return 0 ;
12 }
Apesar da funo imprime no receber nenhum parmetros necessrio colocar
os parntesis ((,)).

1.7.1 mbito da variveis global e local


Em relao ao mbito de uma varivel, a linguagem de programao C++ permite
dois tipos de variveis, as variveis globais e as variveis locais. Uma varivel global
definida fora de qualquer funo, inclusive da funo main. As variveis locais

38
Apontamentos de Programao C/C++

so definidas dentro de uma funo. Quando uma varivel definida como global
significa que est disponvel em qualquer parte do programa. Estar disponvel sig-
nifica que em qualquer ponto do programa possvel manipular (ler e escrever) esta
varivel. Pelo contrrio uma varivel local s est disponvel dentro da funo onde
est definida. No exemplo da listagem 1.28 definida uma varivel global do tipo
int e com o identificador a e iniciada com o valor 0.
Listing 1.28: Variveis locais e globais
1 #include <i o s t r e a m . h>
2 // v a r i a v e l g l o b a l
3 int a =0;

5 void f 1 ( int d )
6 {
7 // v a r i a v e l l o c a l
8 int x ;
9 // l e i t u r a da v a r i a v e l a
10 x=a +3;
11 // e s c r e v e r na v a r i a v e l a
12 a=d+x ;
13 }
14 int main ( )
15 {
16 // v a r i a v e l l o c a l
17 int z =5;
18 cout<<" Valor de a= "<<a<<e n d l ;
19 f1 ( z ) ;
20 cout<<" Valor de a= "<<a<<e n d l ;
21 return 0 ;
22 }
Na funo main definida uma varivel local (int z=5;).
A instruo cout< <"Valor de a= <a< <endl; imprime no ecr a seguinte frase:

Valor de a= 0

Na qual 0 refere o valor da varivel a. A varivel a no est definida na funo


main logo para que se possa aceder tem que ser uma varivel global. Na chamada
funo f1 na funo main passado o valor da varivel local z, que 5. Portanto o
parmetro d (a varivel d na funo f1) iniciado com o valor 5. Alm da varivel
int d na funo f1 definida outra varivel (x do tipo int). varivel x da funo
f1 atribudo o valor da varivel a. Esta varivel no est definida na funo f1,
mas como global pode ser acedida para leitura e tambm para escrita. O que
acontece na instruo a=d+x; que altera o valor da varivel a para 5. Assim que
a funo f1 terminar executada a instruo cout< <"Valor de a= <a< <endl;
que imprime no ecr:

Valor de a=5

Uma varivel global "vive"enquanto o programa estiver em execuo. Uma va-


rivel local "vive"enquanto a funo onde est definida estiver a ser executada.

39
ISEP/DEI - Jorge Santos e Paulo Baltarejo

Sempre que a funo for invocada as variveis locais so criadas e sempre que a fun-
o termina estas deixam de existir. Sempre que um programa executado (passa
a processo do Sistema Operativo) lhe associado uma quantidade de memria que
dividida em trs grandes partes. Uma parte para o cdigo do programa, outra
para os dados e uma outra designada de stack . A parte do cdigo do programa
onde so colocadas as instrues do programa, obviamente instrues mquina.
A parte dos dados pode ser dividida em duas reas: A rea das variveis globais e
estticas e a heap. A heap uma zona de memria reservada alocao dinmica de
memria em tempo de execuo. A stack opera segundo o principio ltimo a entrar
primeiro a sair (LIFO4 ) e serve para armazenar os argumentos e variveis passados
ao programa. E sempre que uma funo chamada criada uma stack frame. A
stack frame serve para passar argumentos para a funo, guardar o endereo do local
onde foi chamada, definir as variveis locais funo e passar o valor de retorno.
Quando a funo termina a correspondente stack frame destruda. A figura 1.4
ilustra a forma como a memria associada a um programa est dividida.

Argumentos e
Variveis de Ambiente

Stack
Stack Frame
Stack Frame
Dados

Heap
Cdigo

Variveis Globais

Instrues do programa

Figura 1.4: Arquitectura do modelo de memria

A figura 1.5 apresenta a evoluo da stack para o programa que apresentado


na listagem 1.29.
O facto de as variveis terem o mesmo nome no significa que exista alguma
relao entre elas. No existe nenhuma relao entre as variveis das diferentes
funes nem nas variveis da mesma funo em invocaes diferentes.

Listing 1.29: Exemplo de chamadas a funes


1 #include <i o s t r e a m . h>
2

3 void h ( int a )
4 {
5 int x ;
6 cout<<" Funcao h"<<e n d l ;
7 }
4
do anglo-saxnico Last In First Out

40
Apontamentos de Programao C/C++

g() h()
stack
int x int x
int a int a
f() f() f() f() f()
int x int x int x int x int x
main() main() main() main() main() main() main()
1 passo 2 passo 3 passo 4 passo 5 passo 6 passo 7 passo tempo

Figura 1.5: Execuo da pilha

9 void g ( int a )
10 {
11 int x ;
12 cout<<" Funcao g"<<e n d l ;
13 }
14

15 void f ( )
16 {
17 int x ;
18 cout<<" Funcao f "<<e n d l ;
19 g(x );
20 h(x ) ;
21 }
22

23 int main ( )
24 {
25 f ();
26 return 0 ;
27 }

1.7.2 Passagem de argumentos


Na linguagem C++ os parmetros podem ser passados para uma funo por valor
ou por referncia.

1.7.2.1 Passagem por valor

At agora em todas as funes implementadas, a passagem de parmetros utilizada


foi por valor. Isto significa que quando uma funo chamada com parmetros,
o que lhe passado o valor da varivel (ou o literal). Por exemplo a funo
soma(int n1, int n2) do programa da listagem 1.30 recebe os valores 5 e 3 e no
as variveis x e y(figura 1.6).

41
ISEP/DEI - Jorge Santos e Paulo Baltarejo

int soma( int n1 , int n2 )

int main
{ 5 3
int a,b,z;
a=5;
b=3;
z=soma( a , b );
}

Figura 1.6: Passagem de variveis por valor

Da que, qualquer alterao variveis n1 e n2 na funo soma no tem qualquer


significado nas variveis a e b na funo main.
Listing 1.30: Variveis locais e globais
1 #include <i o s t r e a m . h>
2

3 int soma ( int n1 , int n2 )


4 {
5 int r ;
6 r=n1+n2 ;
7

8 return r ;
9 }
10

11 int main ( )
12 {
13 int a , b , z ;
14 a =5;
15 b=3;
16 z = soma ( a , b ) ;
17 c o u t << " R e s u l t a d o : " << z ;
18

19 return 0 ;
20 }

1.7.2.2 Passagem por referncia


Existem situaes em que necessrio alterar o valor de uma varivel dentro de uma
funo que foi definida noutra funo. Para este caso a varivel tem que ser passada
por referncia. O programa da listagem 1.31 apresenta a funo divisaoInteira
que tem quatro argumentos, dois passados por valor (int dividendo e int divisor)
e dois por referncia (int &quociente e int &resto). A sintaxe da linguagem C++
obriga a que os argumentos passados por referncia so identificados por um & entre
o tipo de dados e o identificador da varivel.
Listing 1.31: Passagem por referncia
1 #include<i o s t r e a m . h>
2

42
Apontamentos de Programao C/C++

3 void d i v i s a o I n t e i r a ( int d i v i d e n d o , int d i v i s o r , int &q u o c i e n t e , int &r e s t o )


4 {
5 q u o c i e n t e =0;
6 while ( d i v i d e n d o>=d i v i s o r )
7 {
8 d i v i d e n d o=d i v i d e n d o d i v i s o r ;
9 q u o c i e n t e=q u o c i e n t e +1;
10 }
11 r e s t o=d i v i d e n d o ;
12 }
13

14 int main ( )
15 {
16 int D=23 , d=5, q , r ;
17

18 d i v i s a o I n t e i r a (D, d , q , r ) ;
19

20 cout<<"O quoc . da d i v . i n t e i r a . de "<<D<<" por "<<d<<" e "<<q<<e n d l ;


21 cout<<"O r e s . da d i v . i n t e i r a de "<<D<<" por "<<d<<" e "<<r<<e n d l ;
22

23 return 0 ;
24 }

Desta forma as variveis q e r definidas na funo main que dentro da funo


divisaoInteira so quociente e resto, respectivamente. Isto significa que qual-
quer alterao dentro da funo divisaoInteira nas variveis quociente ou resto
altera o valor das variveis q e r da funo main (listagem 1.7).

void divisaoInteira(int dividendo , int divisor , int &quociente , int &resto )

int main() endereo endereo


{ 23 5 de q de r
int D,d,q,r;
D=23;
d=5;
divisaoInteira( D , d , q , r )
}

Figura 1.7: Passagem de variveis por referncia

Esta uma forma de fazer uma funo retornar mais do que um valor.

1.7.2.3 Valores por omisso nos argumentos


Quando se declara uma funo pode-se especificar valores para cada um dos par-
metros. Para tal basta atribuir valores com o operador = na declarao da funo.
O programa da listagem 1.32 apresenta a funo divide, cujo o segundo argumento
tem um valor por omisso. Significa isto que a funo pode ser chamada de duas
formas, com um parmetro ou com dois. Com um serve para iniciar o argumento a,
sendo que o b est iniciado por omisso. Com dois inicia os dois argumentos.

43
ISEP/DEI - Jorge Santos e Paulo Baltarejo

Listing 1.32: Passagem por referncia


1 #include <i o s t r e a m . h>
2

3 int d i v i d e ( int a , int b=2)


4 {
5 int r ;
6 r=a/b ;
7 return r ;
8 }
9 int main ( )
10 {
11 cout<<d i v i d e (12)<< e n d l ;
12 cout<<d i v i d e (20 ,4) < < e n d l ;
13 return 0 ;
14 }
Deste modo a sada deste programa 6 e 5. A chamada divide(12) tem como
retorno o 6, resultado da operao 12/6. A chamada (20,4) tem como resultado 5
(20/4).

1.7.3 Prottipos de funes


Nos programas apresentados anteriormente as funes aparecem definidas antes da
primeira chamada a essa funo. A estrutura usada foi ento definir as funes
antes da funo main, portanto esta aparece no fim do ficheiro de cdigo. Mas
caso, as funes aparecessem depois da funo main os programas apresentados
anteriormente dariam erro de compilao. No exemplo apresentado no programa da
listagem 1.33 o compilador indicaria que no conhecia o identificador da "divide".
Isto porque no processo de compilao feita uma analise sequencial e neste caso
quando o compilador encontra o identificador "divide" no sabe o que que ele .
Listing 1.33: Erro de compilao
1 #include <i o s t r e a m . h>
2

3 int main ( )
4 {
5 int x ;
6 x=d i v i d e ( 2 0 , 5 ) ;
7 return 0 ;
8 }
9

10 int d i v i d e ( int a , int b=2)


11 {
12 int r ;
13 r=a/b ;
14 return r ;
15 }
A soluo para este problema consiste em definir os prottipos das funes antes
da sua chamada. No prottipo da funo necessrio referir qual o tipo ou tipos
de dados dos argumentos (respeitando a ordem) e qual o tipo de dados de retorno
alm do identificador da funo. A forma para definir um prottipo a seguinte:

44
Apontamentos de Programao C/C++

<tipo-de-dados> <id-da-funo> (<tipo-de-dados>,<tipo-de-dados>,...);

Listing 1.34: Prottipo de funo (exemplo)


1 #include <i o s t r e a m . h>
2 // p r o t t i p o da f u n o

3 int d i v i d e ( int , int ) ;


4

5 int main ( )
6 {
7 cout<<d i v i d e (20 ,4) < < e n d l ;
8 return 0 ;
9 }
10

11 int d i v i d e ( int a , int b )


12 {
13 int r ;
14 r=a/b ;
15 return r ;
16 }
Embora no seja necessrio colocar o identificador dos argumentos a sua utili-
zao aconselhvel. Efectivamente, em alguns casos poderseia contornar a de-
finio de prottipos, inserindo a definio das funo antes da primeira chamada,
portanto antes da funo main. No entanto, esta prtica desaconselhada, pois
ineficaz no caso de chamadas circulares entre funes.

1.7.4 Estrutura de um programa em C++


Um programa em C/C++ deve obedecer a estrutura apresentada na figura 1.8.

Directivas de pr-processador
#include
#define
Declarao de variveis globais
int pi=3.1415;

Prottipos das funes


float areaCirculo(int raio);

Programa principal
int main()
{
cout << areaCirculo(5);
return 0;
}

Implementao da funes
float areaCirculo(int raio)
{
return raio*raio*pi;
}

Figura 1.8: Estrutura de um programa em C/C++

45
ISEP/DEI - Jorge Santos e Paulo Baltarejo

No inicio do ficheiro so colocadas as directivas do prprocessador (e.g., #include,


#define). Caso se utilizem variveis globais, estas devem ser definidas logo a se-
guir directivas de pr-processador. Depois deve-se colocar o prottipo de todas
as funes implementadas. A seguir declarao dos prottipos implementada
a funo main e depois a implementao das funes anteriormente declaradas nos
prottipos.

1.7.5 Exerccios resolvidos


Nesta seco so apresentados alguns problemas e respectivas solues com o objec-
tivo de ilustrar a utilizao de funes na produo de programas modulares.

1.7.5.1 Funo que devolve o maior algarismo de um nmero


O programa da listagem 1.35 apresenta uma funo que recebe um nmero inteiro
e devolve o maior algarismo contido nesse nmero.

Listing 1.35: maior(n) que devolve o maior algarismo de um nmero


1 #include<i o s t r e a m . h>
2

3 int maior ( int n )


4 {
5 int a l g , max=n%10;
6 n/=10;
7 while ( n !=0)
8 {
9 a l g=n%10;
10 i f ( a l g >max)
11 max=a l g ;
12 n=(na l g ) / 1 0 ;
13 }
14 return max ;
15 }
16

17 int main ( )
18 {
19 int numero ;
20 cout<<" I n t r o d u z a a numero= " ;
21 c i n >>numero ;
22

23 cout<<"O maior d i g i t o de "<<numero<<" e " ;


24 cout<<maior ( numero)<<e n d l ;
25

26 return 0 ;
27 }

1.7.5.2 Funo que indica se um nmero perfeito


Um nmero n perfeito se a soma dos divisores inteiros de n (excepto o prprio n)
igual ao valor de n. Por exemplo, o nmero 28 tem os seguintes divisores: 1, 2, 4,

46
Apontamentos de Programao C/C++

7, 14, cuja soma exactamente 28. (Os seguintes nmeros so perfeitos: 6, 28, 496,
8128.)
A listagem do programa da listagem 1.36 apresenta uma funo que recebe um
nmero inteiro e devolva os valores booleanos true ou false se o nmero ou no
perfeito, respectivamente.
Listing 1.36: perfeito(N) que indica se um nmero perfeito
1 #include<i o s t r e a m . h>
2

3 bool p e r f e i t o ( int n )
4 {
5 int soma=0,x ;
6 f o r ( x=1;x<=(n / 2 ) ; x++)
7 {
8 i f ( n%x==0)
9 soma+=x ;
10 }
11 i f ( soma==n )
12 return true ;
13 return f a l s e ;
14 }
15

16 int main ( )
17 {
18 int numero ;
19 cout<<" I n t r o d u z a a numero= " ;
20 c i n >>numero ;
21

22 i f ( p e r f e i t o ( numero ) )
23 cout<<"O numero "<<numero<<" e p e r f e i t o "<<e n d l ;
24 else
25 cout<<"O numero "<<numero<<" nao e p e r f e i t o "<<e n d l ;
26

27 return 0 ;
28 }

1.7.6 Exerccios propostos


Nesta seco so propostos alguns problemas relacionados com a utilizao de pro-
cedimentos e funes na escritas de programas modulares.

1.7.6.1 Funo mdia de dois nmeros


Escreva uma funo que, dados dois nmeros reais, retorna a mdia deles arredon-
dada para um inteiro, e devolve os nmeros por ordem crescente. Faa um programa
que permita testar a funo anterior.

1.7.6.2 Funo lei de Ohm


A lei de Ohm uma relao entre a corrente (I), a tenso (V) e a resistncia (R),
de acordo com o circuito elctrico representado na figura 1.9.

47
ISEP/DEI - Jorge Santos e Paulo Baltarejo

Lei de Ohm:
V R
I = V /R

Figura 1.9: Ilustrao da lei de Ohm

a) Escreva uma funo que recebe os valores de V e R como parmetros, e calcule


a corrente I .

b) Escreva um programa que permita testar a funo anterior.

1.7.6.3 Funo somatrio


X n
2i
Calcular o somatrio
i=1
i
Sugesto: crie uma funo para determinar cada termo i da srie.

1.7.6.4 Funes para codificar e descodificar nmeros


Uma empresa pretende enviar cifrada uma sequncia de inteiros decimais de 4 dgitos
(DigDigDigDig). A cifra consiste em: substituir cada dgito Dig por (Dig+8)%10
(i.e., adiciona 8 e calcula o resto da diviso do resultado por 10); depois troca o
terceiro dgito com o primeiro e troca o quarto dgito com o segundo.

a) Escreva uma funo que receba um inteiro decimal de 4 dgitos e o devolva


cifrado.

b) Escreva uma funo que receba um inteiro cifrado e o decifre para o valor
original.

c) Escreva uma funo que apresente um menu com 2 opes, cifrar e decifrar
nmero, pea ao utilizador para escolher uma das opes, e retorne a opo
escolhida.

d) Faa um programa que permita testar as funes anteriores.

1.7.6.5 Nmeros primos


Escreva um procedimento que imprima os nmeros primos existentes entre dois
nmeros. Na resoluo deste problema deve ser utilizada uma funo que determina
se um nmero primo.

1.8 Vectores
Nesta seco descrita a forma de definir e manipular vectores.

48
Apontamentos de Programao C/C++

1.8.1 Definio de vectores


Os vectores so conjuntos de elementos (variveis) do mesmo tipo de dados, colo-
cados consecutivamente na memria. Podem ser acedidos individualmente ou refe-
renciados por indexao. Isto significa que, por exemplo, para guardar vinte valores
do tipo int no necessrio declarar vinte variveis. Para tal possvel declarar
um vector com vinte posies do tipo int com um nico identificador. A seguir
apresentada a sintaxe para declarar um vector:
<tipo-de-dados> <id-do-vector> [<num-de-elem>]
na qual:

<tipo-de-dados> indica qual o tipo de dados (e.g., : int, float, char) de


cada elemento do vector;

<id-do-vector> este o identificador do vector;

<num-de-elem> entre parntesis rectos ([,]) especifica o nmero de elemen-


tos do vector. O nmero de elementos tem que ser um valor constante, isto
, no pode ser uma varivel, porque os vectores so conjuntos estticos de
memria de um determinado tamanho e o compilador tem que ser capaz de
determinar exactamente a quantidade de memria necessaria para o vector
antes de qualquer instruo ser considerada.

Por exemplo um vector para armazenar vinte nmeros inteiros (do tipo de dados
int) pode ser definido da seguinte forma:
int vec[20];
A figura 1.10 representa graficamente um vector com 20 elementos. Onde cada
rectngulo representa um elemento do vector, que neste caso so elementos do tipo
int. Os elementos esto numerados de 0 a 19, uma vez que o primeiro elemento de
um vector sempre a posio 0, independentemente do nmeros de elementos do
vector.

ndice 0 1 2 3 4 ... 19

Valor 12 8 9 17 15 ... 11

Figura 1.10: Representao grfica do vector vec

1.8.2 Atribuio dos valores iniciais


Quando se declara um vector possvel, como acontece com qualquer outra vari-
vel, iniciar os seus elementos. Para tal deve-se colocar os elementos separados por
virgulas (,) dentro de chavetas ({}). Como por exemplo:
int vec[5]={1,3,2,55,67};
O nmero de elementos deve ser igual ao nmero de posies do vector. No
entanto, possvel no definir o nmero de elementos do vector, sendo o nmero
de posies definido em funo dos elementos que esto dentro das chavetas. A

49
ISEP/DEI - Jorge Santos e Paulo Baltarejo

definio apresentada a seguir equivalente definio anterior. Ambos os vectores


tem 5 posies.
int vec[]={1,3,2,55,67};

1.8.3 Acesso aos elementos de um vector


Em qualquer ponto do programa no qual um vector esteja definido possvel aceder
a qualquer elemento do vector, quer para leitura quer para escrita como se fosse uma
varivel comum. A sintaxe a utilizar a seguinte:
<identificador-do-vector> [ndice]
Por exemplo a seguinte instruo permite armazenar o valor 75 na terceira po-
sio do vector vec.
vec[2]=75;
enquanto a seguinte instruo permite atribuir o valor do terceiro elemento do vec
a uma varivel a do tipo int.
a=vec[2];
Portanto, para todos os propsitos a expresso vec[2] como uma qualquer
varivel do tipo int.
Um aspecto muito importante em C++ est relacionado com a dimenso dos
vectores. Quando se define um vector indicase a sua dimenso, ou seja o nmero
de elementos do vector. Sendo que, a primeira posio do vector tem o ndice 0,
o que faz com que a ltima seja o numero de elementos menos 1. No caso de ser
referenciada uma posio para alm da dimenso do vector o compilador de C++
no indicar nenhum erro de compilao. Apenas em tempo de execuo o erro ser
detectado, atravs da ocorrncia de resultados inesperados ou mesmo "crash"do
programa. Cabe ao programador, controlar a dimenso do vector.
Nos vectores, os parntesis rectos ([,]) so utilizados com dois propsitos que
importa distinguir. Primeiro, so usados na definio de vectores para se colocar a
dimenso do vector. Segundo, so usados para referenciar os elementos do vector.
Na listagem do programa da listagem 1.37 apresentada as duas formas de utilizao
dos parntesis rectos ([,]).

Listing 1.37: Exemplo da utilizao dos parntesis rectos[] nos vectores


1 #include<i o s t r e a m . h>
2 #define MAX 5
3

4 int main ( )
5 {
6 int vec [MAX] = { 2 3 , 4 5 , 3 2 , 7 8 , 9 8 } , i , soma=0;
7 f o r ( i =0; i <MAX; i ++)
8 soma+=vec [ i ] ;
9 cout<<" Somatorio : "<<soma<<e n d l ;
10

11 return 0 ;
12 }

50
Apontamentos de Programao C/C++

1.8.4 Exerccios resolvidos


1.8.4.1 Funes manipulando vectores
Faa um programa que inclua:

a) Uma funo que faa a leitura de 10 valores (inteiros), guardandoos num


vector;

b) Uma funo que retorne a diferena entre o maior e o menor valor do vector;

c) Uma funo que devolva o nmero de valores pares e mpares do vector;

O procedimento apresentado na listagem 1.38 permite realizar a leitura do vector.


Notese que tanto o prprio vector como a respectiva dimenso so passados para
o procedimento como argumentos.
Listing 1.38: Leitura (vectores)
1 void l e i t u r a ( int vec [ ] , int dim )
2 {
3 int i ;
4 f o r ( i =0; i <dim ; i ++)
5 {
6 c o u t <<" vec [ " << i << " ] : " ;
7 c i n >> vec [ i ] ;
8 }
9 }
A funo presente na listagem 1.39 permite contabilizar a quantidade de nmeros
pares existentes no vector. A funo recebe prprio vector e a respectiva dimenso
como parmetros e retorna a quantidade de pares.
Listing 1.39: Conta o nmero de nmeros pares
1 int c o n t a P a r e s ( int vec [ ] , int dim )
2 {
3 int i , npar =0;
4

5 f o r ( i =0; i <dim ; i ++)


6 {
7 i f ( vec [ i ]%2==0)
8 npar++;
9 }
10 return npar ;
11 }
A funo apresentada na listagem 1.40, recebe o prprio vector e a respectiva
dimenso como parmetros e retorna a diferena entre os valores mximo e mnimo
existentes no vector.
Listing 1.40: Determina a maior diferena entre os elementos de um vector
1 int m a i o r D i f e r e n c a ( int vec [ ] , int dim )
2 {
3 int i , maximo , minimo ;
4 maximo=minimo=vec [ 0 ] ;

51
ISEP/DEI - Jorge Santos e Paulo Baltarejo

5 f o r ( i =1; i <dim ; i ++)


6 {
7 i f ( vec [ i ]>maximo )
8 maximo=vec [ i ] ;
9 else
10 i f ( vec [ i ]<minimo )
11 minimo=vec [ i ] ;
12 }
13 return ( maximominimo ) ;
14 }
No seguinte extracto (listagem 1.41) definido o vector e evocadas as funes e
procedimento anteriormente definidos.

Listing 1.41: Funo main e prottipos das funes


1 #include<i o s t r e a m . h>
2 #define MAX 10
3

4 void l e i t u r a ( int vec [ ] , int dim ) ;


5 int c o n t a P a r e s ( int vec [ ] , int dim ) ;
6 int m a i o r D i f e r e n c a ( int vec [ ] , int dim ) ;
7

8 int main ( )
9 {
10 int v e c t o r [MAX] ;
11

12 l e i t u r a ( v e c t o r ,MAX) ;
13 cout<<c o n t a P a r e s ( v e c t o r ,MAX)<<e n d l ;
14 cout<<m a i o r D i f e r e n c a ( v e c t o r ,MAX)<<e n d l ;
15

16 return 0 ;
17 }

1.8.5 Exerccios propostos


1.8.5.1 Determinar desvio padro de uma srie
Escreva um programa modular que permita determinar o desvio padro de um srie
de nmeros de acordo com a formula 1.8.1. Considere a definio de funes e
procedimento para os diversos subproblemas.
v
u n
uX
u (xi media)
u
t i=1
desvioPadrao = (1.8.1)
n1

1.8.5.2 Prova de atletismo


Faa a leitura das pontuaes que 5 juzes de uma determinada prova atriburam a
um atleta (valores compreendidos entre 0 e 9 inclusive). Determine e apresente com
formato adequado, os seguintes valores:

52
Apontamentos de Programao C/C++

mdia obtida pelo atleta;

a pior e a melhor pontuao;

a percentagem de pontuaes iguais ou superiores a 8 valores;

supondo que a 1 nota foi atribuda pelo juiz n1 e assim sucessivamente


determine os nmeros dos juzes que atriburam a melhor nota do atleta.

1.8.5.3 Suavizao
Em qualquer experincia existe um certo erro associado aos valores obtidos. Uma
tcnica conhecida como suavizao pode ser utilizada para reduzir o efeito desse erro
na anlise dos resultados. Escreva ento um programa que permita ler os dados para
um vector de N reais e implemente uma funo que produza uma suavizao sobre
esses dados. A suavizao consiste em substituir o valor actual de uma posio
pela mdia do valor da posio anterior, da posterior e dele prprio. Assumindo
que o identificador do vector v, ento v[i]=(v[i-1]+v[i]+v[i+1])/3, (excepto o
primeiro e o ltimo). O primeiro elemento do vector suavizado com base na mdia
entre os dois primeiros valores e o ltimo elemento suavizado com base na mdia
entre os dois ltimos.

1.9 Vectores multidimensionais


Um vector multidimensional pode ser descrito como um vector de vectores. Por
exemplo, um vector bidimensional (matriz) pode ser visto como uma tabela bidi-
mensional em que todos os elementos so do mesmo tipo dados. A figura 1.11 faz a
representao grfica de uma matriz.

0 1 2 ... 799

0 4 56 11 ... 6

1 12 8 1 ... 5

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

639 5 83 9 ... 4

Figura 1.11: Representao grfica de uma matriz

A varivel mat representa um vector bidimensional de 3 linhas e 5 colunas. A


forma de o definir em C++ :
int mat[3][5];
A instruo mat[1][3] referencia o elemento da segunda linha e da quarta co-
luna.
Importa relembrar que os indices comeam sempre em 0. Os vectores multi
dimensionais no esto limitados a duas dimenses. Podem ter as dimenses que o

53
ISEP/DEI - Jorge Santos e Paulo Baltarejo

programador achar necessrio. O exemplo seguinte define um vector de trs dimen-


ses.
int multiVec[100][200][50];
H contudo um aspecto a ter em considerao na definio de vectores multi
dimensionais, a memria necessria na definio destes. Pois o nmero de ele-
mentos que o vector multiVec aloca obtido pela multiplicao das dimenses
e no pela soma, como erroneamente se poderia pensar. Portanto, este vector aloca
100*200*50=1000000 elementos. Sendo que a memria necessria para armazenar
1000000 elementos do tipo int cerca de 4Mbytes (1000000*4bytes).
Notese que os vectores multidimensionais no so mais do que uma abstraco,
uma vez que possvel obter os mesmos resultados com um vector simples. Por
exemplo:
int mat[3][5]; equivalente a int mat[15]; (3*5=15)
A nica diferena consiste no facto do compilador guardar a profundidade de
cada dimenso imaginria. A seguir apresenta-se duas listagens de programas, na
quais, numa usado um vector multidimensional (listagem 1.42) e na outra um
vector simples (listagem 1.43). Apesar de aparentemente guardarem a informao
em estruturas de dados diferentes, na prtica so idnticos.

Listing 1.42: Vector multidimensional


1 #define COLUNAS 5
2 #define LINHAS 3
3

4 int main ( )
5 {
6 int mat [ LINHAS ] [ COLUNAS ] ;
7 int n ,m;
8 f o r ( n=0;n<LINHAS ; n++)
9 f o r (m=0;m<COLUNAS;m++)
10 {
11 mat [ n ] [m]=( n+1)(m+1);
12 }
13 return 0 ;
14 }

Listing 1.43: Vector pseudo-multidimensional


1 #define COLUNAS 5
2 #define LINHAS 3
3

4 int main ( )
5 {
6 int mat [ LINHAS COLUNAS ] ;
7 int n ,m;
8 f o r ( n=0;n<LINHAS ; n++)
9 f o r (m=0;m<COLUNAS;m++)
10 {
11 mat [ n COLUNAS + m]=( n+1)(m+1);
12 }
13 return 0 ;
14 }

54
Apontamentos de Programao C/C++

boa prtica de programao utilizar macros para especificar a dimenso de


um vectores tanto uni como multi-dimensionais. A utilizao de macros permite
diminuir o esforo de programao quando se pretende alterar as suas dimenses.
Isto porque basta alterar as macros e desta forma altera as dimenses dos vectores
assim como do cdigo usado para manipular estes vectores. Por exemplo para alterar
o numero de linhas de 3 para 4 bastava alterar a macro de
#define LINHAS 3
para
#define LINHAS 4

1.9.1 Exerccios resolvidos


1.9.1.1 Funes manipulao de matrizes
Escreva um programa que defina uma matriz quadrada de dimenso mxima 4 e
implemente as seguintes funes:

1. Uma funo que faa a leitura dos elementos da matriz, guardando os valores
em memria RAM. O prottipo deve ser void leitura( int matriz[][MAX_C] );

2. Uma funo que devolva a mdia da diagonal principal, com o seguinte prot-
tipo (float mediaDiagonal( int matriz[][MAX_C] )) ;

3. Uma funo que devolva um vector com os elementos cujo valor seja superior
mdia da diagonal principal, com o seguinte prottipo
(int superiorMedia( int matriz[][MAX_C], int vector[] ));

4. Uma funo que devolva uma matriz com o nmero de ocorrncias de cada
elemento, com o seguinte prottipo
(int ocorrencias( int matriz[][MAX_C], int matriz_ocorr[][2])).

Listing 1.44: Matrizes


1 #include<i o s t r e a m . h>
2 #include<s t d l i b . h>
3

4 #define MAX 50
5 #define MAX_L 4

6 #define MAX_C 4

8 int menu ( ) ;
9 void l e i t u r a ( int m a t r i z [ ] [MAX_C] ) ;
10 f l o a t mediaDiagonal ( int m a t r i z [ ] [MAX_C] ) ;
11 int s u p e r i o r M e d i a ( int m a t r i z [ ] [MAX_C] , int v e c t o r [ ] ) ;
12 int o c o r r e n c i a s ( int m a t r i z [ ] [MAX_C] , int m a t r i z _ o c o r r [ ] [ 2 ] ) ;
13 void i n c _ o c o r r ( int v a l o r , int m[ ] [ 2 ] , int n ) ;
14

15 int main ( )
16 {
17 int m a t r i z [MAX_L] [MAX_C] ;
18 int v e c t o r [MAX_LMAX_C] ;
19 int m a t r i z _ o c o r r [MAX_LMAX_C] [ 2 ] ;

55
ISEP/DEI - Jorge Santos e Paulo Baltarejo

20 int n_elem ;
21 int i , op ;
22 do{
23 op=menu ( ) ;
24 switch ( op )
25 {
26 case 1 :
27 c o u t << " I n t r o d u z a v a l o r e s para a m a t r i z " ;
28 cout<< MAX_L << "x" << MAX_C<< e n d l ;
29 l e i t u r a ( matriz ) ;
30 break ;
31 case 2 :
32 c o u t << "Media da d i a g o n a l : " ;
33 c o u t << mediaDiagonal ( m a t r i z ) << e n d l ;
34 break ;
35 case 3 :
36 c o u t << " Elementos que s a o s u p e r i o r e s a media da d i a g o n a l : " ;
37 n_elem = s u p e r i o r M e d i a ( matriz , v e c t o r ) ;
38 fo r ( i =0; i <n_elem ; i++ )
39 c o u t << v e c t o r [ i ] << " " ;
40 c o u t << e n d l ;
41

42 break ;
43 case 4 :
44 c o u t << " O c o r r e n c i a s : " << e n d l ;
45 n_elem = o c o r r e n c i a s ( matriz , m a t r i z _ o c o r r ) ;
46 fo r ( i =0; i <n_elem ; i++ )
47 {
48 c o u t << m a t r i z _ o c o r r [ i ] [ 0 ] << " : " ;
49 cout<< m a t r i z _ o c o r r [ i ] [ 1 ] << " o c o r r e n c i a ( s ) " << e n d l ;
50 }
51 break ;
52 }
53 } while ( op ! = 0 ) ;
54 return 0 ;
55 }
56

57 int menu ( )
58 {
59 int op ;
60 char b u f f e r [MAX] ;
61 do{
62 cout<<"Menu\n" ;
63 cout<<"1 Ler m a t r i z \n" ;
64 cout<<"2 Media da d i a g o n a l p r i n c i p a l \n" ;
65 cout<<"3 Elementos s u p e r i o r e s a media \n" ;
66 cout<<"4 Numero de o c o r r e n c i a s \n" ;
67 cout<<"0 S a i r \n" ;
68 cout<<"\ n D i g i t e a opcao : " ;
69 c i n . g e t l i n e ( b u f f e r ,MAX) ;
70 op=a t o i ( b u f f e r ) ;

56
Apontamentos de Programao C/C++

71 } while ( op<0 | | op >4);


72 return op ;
73 }
74

75 void l e i t u r a ( int mat [ ] [MAX_C] )


76 {
77 int i , j ;
78 char b u f f e r [MAX] ;
79 f o r ( i =0; i <MAX_L; i++ )
80 f o r ( j =0; j <MAX_C; j++ )
81 {
82 c o u t << " mat [ " << i << " , " << j << " ] : " ;
83 c i n . g e t l i n e ( b u f f e r ,MAX) ;
84 mat [ i ] [ j ]= a t o i ( b u f f e r ) ;
85 }
86 }
87

88 f l o a t mediaDiagonal ( int mat [ ] [MAX_C] )


89 {
90 int i , soma=0;
91

92 f o r ( i =0; i <MAX_L; i++ )


93 soma += mat [ i ] [ i ] ;
94

95 return ( f l o a t ) soma / MAX_L;


96 }
97

98 int s u p e r i o r M e d i a ( int mat [ ] [MAX_C] , int vec [ ] )


99 {
100 int i , j , n=0;
101 f l o a t media ;
102

103 media = mediaDiagonal ( mat ) ;


104

105 f o r ( i =0; i <MAX_L; i++ )


106 f o r ( j =0; j <MAX_C; j++ )
107 i f ( mat [ i ] [ j ] > media )
108 vec [ n++] = mat [ i ] [ j ] ;
109

110 return n ;
111 }
112

113 int o c o r r e n c i a s ( int mat [ ] [MAX_C] , int mat1 [ ] [ 2 ] )


114 {
115 int i , j , n=0;
116

117 f o r ( i =0; i <MAX_L; i++ )


118 f o r ( j =0; j <MAX_C; j++ )
119 i n c _ o c o r r ( mat [ i ] [ j ] , mat1 , &n ) ;
120

121 return n ;

57
ISEP/DEI - Jorge Santos e Paulo Baltarejo

122 }
123

124 void i n c _ o c o r r ( int v a l o r , int m[ ] [ 2 ] , int n )


125 {
126 int i =0;
127 bool i n c = f a l s e ;
128

129 do
130 {
131 i f ( m[ i ] [ 0 ] == v a l o r )
132 {
133 m[ i ] [ 1 ] + + ;
134 i n c = true ;
135 }
136 i ++;
137 }
138 while ( ! i n c && i <n ) ;
139

140 i f ( ! inc )
141 {
142 m[ n ] [ 0 ] = v a l o r ;
143 m[ ( n ) + + ] [ 1 ] = 1 ;
144 }
145 }

1.9.2 Exerccios propostos


1.9.2.1 Mximo local
Um elemento de uma matriz considerado um mximo local se for superior a todos
os seus vizinhos. Escreva um programa que dada uma matriz fornea todos os
mximos locais e as respectivas posies, considerando que os elementos da periferia
da matriz no podem ser mximos locais.

1.9.2.2 Determinar se uma matriz simtrica


Escreva um programa que dada uma matriz quadrada de dimenso n determine se
ela ou no simtrica. Uma matriz A dizse simtrica se aij = aji com 1 i, j n
.

1.10 Vectores como parmetros


A programao modular que possvel atravs da utilizao de funes obriga em
que em certos casos necessrio passar vectores (uni e multidimensionais) para as
funes como parmetro. Na linguagem C++ no possvel passar por valor um
vector, isto , um vector sempre passado por referncia (atravs do seu endereo).
Para passar um vector por parmetro a nica coisa que necessrio fazer colocar
na declarao da funo especificar que a funo tem um argumento que um vector.
Por exemplo a seguir apresenta-se o prottipo de uma funo que recebe um vector
por parmetro.

58
Apontamentos de Programao C/C++

void funcao(int v[])


Neste exemplo os elementos do vector so do tipo int e vector dentro da funo
identificado pelo identificador v. Alm do tipo e do identificador necessrio colocar
os parntesis rectos ([]), sendo que opcional colocar a dimenso, isto no caso de
ser um vector unidimensional.
O exemplo presente na listagem 1.45 ilustra a vantagem da utilizao da passa-
gem de vectores a uma funo. A funo void printvector (int v[], int len)
imprime no ecr os len elementos do vector v. Importa realar que a mesma funo
usada para imprimir o contedo do vector vector1 e do vector2. Na chamada
funo printvector na funo main no especificado a dimenso do vector, basta
colocar o nome do vector.

Listing 1.45: Vector como argumento de funes


1 #include <i o s t r e a m . h>
2

3 void p r i n t v e c t o r ( int v [ ] , int l e n )


4 {
5 f o r ( int n=0; n<l e n ; n++)
6 c o u t << v [ n ] << " " ;
7 c o u t << "\n" ;
8 }
9

10 int main ( )
11 {
12 int v e c t o r 1 [ ] = {5 , 10 , 15};
13 int v e c t o r 2 [ ] = {2 , 4 , 6 , 8 , 10};
14 printvector ( vector1 ,3);
15 printvector ( vector2 ,5);
16 return 0 ;
17 }

Quando se pretende passar vectores multidimensionais como parmetro a uma


funo obrigatrio especificar o numero de elementos de cada dimenso com ex-
cepo da primeira. A seguir apresenta o formato:
<tipo-de-dados> <id-do-vec> [][dim][dim][dim]...
Por exemplo, se se pretende que uma funo receba um vector tridimensional
obrigatrio especificar pelo menos a 2 e 3 dimenso.
void funcao(int m[][3][4])
Isto obrigatrio porque o compilador precisa de ser capaz de determinar o
nmero de elementos das 2 e 3 dimenses.

1.11 Strings
As strings so vectores de elementos do tipo char e permitem representar palavras,
frases e textos. De seguida apresentase a definio de uma string com capacidade
para 20 caracteres.
char str[20];
Est convencionado que uma string terminada pelo carcter \0, assim, na
prtica a string acima definida tem capacidade para 19 caracteres + 1. Portanto no

59
ISEP/DEI - Jorge Santos e Paulo Baltarejo

dimensionamento de um strings necessrio ter em ateno que preciso uma posi-


o para o caracter \0. Por exemplo, caso se pretendesse definir uma string para
armazenar a matricula de uma viatura e partindo do principio que uma matrcula
composta por 6 caracteres alfanumricos (4 dgitos + 2 letras) essa string teria de
ter tamanho 7.
char matricula[7];
Em C++ existe uma biblioteca que contm um conjunto de funes que per-
mitem manipular as strings. A maioria destas funes partem do princpio que na
ltima posio "vlida"est o caracter especial que o null ou \0. A figura 1.12
apresenta a representao de uma string iniciada.

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

str B o m d i' a m u n d o \0

Figura 1.12: Representao de uma string

Para poder usar estas funes necessrio fazer o incluso do ficheiro de cabe-
alho (string.h).

1.11.1 Iniciao de strings


Tal como os vectores de dados numricos as strings tambm podem ser iniciadas
aquando da sua definio. A seguir apresenta-se duas formas para iniciar uma string
na declarao

char str[]={B,o,m, ,d,i,a, ,m,u,n,d,o,\0};


char str[]="Bom dia mundo";

O compilador alm de as iniciar tambm define o seu tamanho. No caso da


primeira definio necessrio colocar o caracter \0, explicitamente. No segundo
caso o compilador acrescenta o esse caracter string.
Da mesma forma que os vectores de dados numricos as strings tambm podem
ser manipuladas por indexao.

str[0]=B;
str[1]=o;

Outro mtodo para atribuir dados a uma strings atravs do objecto cin, no-
meadamente do mtodo getline cujo prottipo :
cin.getline (char buffer[], int length, char delimiter = \n);
na qual

buffer este o endereo da string;

length este designa o nmero mximo de caracteres que a string pode conter;

delimiter o caracter delimitador usado para determinar o fim da cadeia


de caracteres inserida pelo utilizador, que por omisso o o caracter nova linha
(\n).

60
Apontamentos de Programao C/C++

1.11.2 Funes para manipulao de strings


A biblioteca cstring define um conjunto de funes para manipulao de strings.
Todas estas funes esperam que strings estejam terminadas com o carcter \0.
A seguir apresenta-se algumas das funes de biblioteca cstring assim como uma
breve descrio.
char *strcat(char *string1, const char *string2); Concatena o contedo
de string2 a string1, que deve ter espao suficiente para isso. Retorna string1.
char *strchr(const char *string, int c); Procura a primeira ocorrncia de
c (0-255) no vector de caracteres apontado por string. Retorna um ponteiro para
a primeira ocorrncia, ou NULL se no existir.
int strcmp(const char *string1, const char *string2); Compara as duas
cadeias string1 e string2. Retorna: <0 se string1 for menor do que string2; =0
se string1 for igual a string2; e >0 se string1 for maior do que string2.
char *strcpy(char *string1, const char *string2); Copia o contedo de
string2 para string1, que deve ter espao suficiente para isso. Retorna string1.
size_t strcspn(const char *string1, const char *string2); Retorna o n-
dice do primeiro carcter de string1 que pertence ao conjunto de caracteres definido
em string2. Se no existir nenhum retorna o comprimento de string1.
size_t strlen(const char *string); Retorna o comprimento de string.
char *strncat(char *string1, const char *string2, size_t count); Idn-
tica a strcat(), mas concatenando no mximo count caracteres.
int strncmp(const char *string1, const char *string2, size_t count);
Idntica a strncmp(), mas comparando no mximo count caracteres.
char *strncpy(char *string1, const char *string2, size_t count); Idn-
tica a strcpy(), mas copiando no mximo count caracteres.
char *strnset(char *string, int c, size_t count); Idntica a strset(),
mas iniciando no mximo count caracteres.
char *strrchr(const char *string, int c); Procura a ltima ocorrncia de
c (0-255) no vector de caracteres apontado por string. Retorna um ponteiro para
a ltima ocorrncia, ou NULL se no existir.
char *strnset(char *string, int c); Inicia todos os caracteres de string
com o valor c (0-255). O caracter terminador (\0) no afectado.
char *strtok(char *string1, char *string2); permite decompor a string1
em vrios vectores de caracteres. A decomposio baseia-se no principio de que
a string1 formada por uma sequncia de palavras separadas por um padro
(constitudo por um ou mais caracteres) referenciado por string2. Caso no exista
o padro referenciado por string2 a funo strtok retorna NULL.
O exemplo 1.46 apresenta algumas funes de manipulao de strings.
Listing 1.46: Exemplo da utilizao de funes da biblioteca cstring
1 #include<i o s t r e a m . h>
2 #include<s t r i n g . h>
3

4 #define SIZE 50
5

6 int main ( )

61
ISEP/DEI - Jorge Santos e Paulo Baltarejo

7 {
8 char s t r i n g 1 [ SIZE]="Bom d i a mundo ! " ;
9 char s t r i n g 2 [ SIZE ] ;
10 int n ;
11

12 strcpy ( string2 , string1 ) ;


13

14 i f ( strcmp ( s t r i n g 2 , s t r i n g 1 )==0)
15 cout<<"As s t r i n g s s a o i g u a i s "<<e n d l ;
16

17 n=s t r l e n ( s t r i n g 1 ) ;
18 cout<<"A s t r i n g 1 tem"<<n<<" c a r a c t e r e s "<<e n d l ;
19

20 return 0 ;
21 }

1.11.3 Converso de strings para outros tipos


Dado que uma string pode conter representaes de outros tipo de dados, como
nmeros, em algumas situaes pode ser til transformar uma string num dado
numrico. Por exemplo, uma string qualquer pode conter o seguinte nmero "1977",
mas em termos de codificao esta no mais nem menos do que uma sequncia de
5 caracteres, portanto, no sendo possvel realizar operaes aritmticas. Para tal
necessrio, converter esta string num tipo de dado numrico, como por exemplo:
int, long, float. Na biblioteca cstdlib ( necessrio a incluso do ficheiro de
cabealho stdlib.h) esto definidas trs funes que permitem fazer essa converso.
As funes so:
int atoi (const char *string ); converte a string num int.
long atol (const char *string ); converte a string num long.
double atof (const char *string ); converte a string num double.
A seguir apresenta-se um exemplo da utilizao destas funes
Listing 1.47: Exemplo da utilizao de funes da biblioteca cstring
1 #include<i o s t r e a m . h>
2 #include<s t d l i b . h>
3

4 #define SIZE 50
5

6 int main ( )
7 {
8 char b u f f e r [ SIZE ] ;
9 int i ;
10 long l ;
11 double d ;
12

13 cout<<" D i g i t e um numero i n t e i r o : "<<e n d l ;


14 c i n . g e t l i n e ( b u f f e r , SIZE ) ;
15 i=a t o i ( b u f f e r ) ;
16

17 cout<<" D i g i t e um numero i n t e i r o ( l o n g ) : "<<e n d l ;

62
Apontamentos de Programao C/C++

18 c i n . g e t l i n e ( b u f f e r , SIZE ) ;
19 l=a t o l ( b u f f e r ) ;
20

21 cout<<" D i g i t e um numero f r a c c i o n a r i o : "<<e n d l ;


22 c i n . g e t l i n e ( b u f f e r , SIZE ) ;
23 d=a t o f ( b u f f e r ) ;
24

25 cout<<"Os v a l o r e s i n s e r i d o s foram : "<<i <<" ( i n t ) : " ;


26 cout<<l <<" ( l o n g ) : "<<d<<" ( d o u b l e ) "<<e n d l ;
27

28 return 0 ;
29 }

1.11.4 Exerccios resolvidos


1.11.4.1 Programa para manipulao de strings e caracteres
Desenvolva um programa que implemente as seguintes funes:

1. Uma funo que recebe uma string e retorne o seu comprimento. O prottipo
da funo dever ser int mystrlen(char *s);

2. Uma funo que copie o contedo de uma string para a outra. Portanto a
funo recebe duas strings, uma designada de origem e a outra de destino.
O objectivo copiar o contedo da de origem para a de destino. Note que
as strings podem ter tamanhos diferentes. Da que, a funo recebe as duas
strings e um nmero com o comprimento da string de destino (comp_strDest).
O objectivo da funo que copiar da string de origem para a string de
destino no mximo comp_strDest 1 caracteres. A funo deve retornar o
nmero de caracteres efectivamente copiados. O prottipo da funo dever ser
int mystrncpy(char *strDest, char *strSource, int comp_strDest);

3. Uma funo que receba duas strings e retorne: 1 se as strings forem iguais; e 0
se forem diferentes. O prottipo da funo dever ser int str1Igualstr2(char *s1, char *s

4. Uma funo que receba um carcter e caso seja maisculo retorne o correspon-
dente minsculo. O prottipo da funo dever ser char mytolower(char s);

5. Uma funo que receba um carcter e caso seja minsculo retorne o correspon-
dente maisculo. O prottipo da funo dever ser char mytoupper(char s);

6. Uma funo que elimine todos os espaos esquerda do primeiro carcter(diferente


de espao). O prottipo da funo dever ser void mylefttrim(char *s);

7. Uma funo que elimine todos os espaos direita do ltimo carcter (diferente
de espao). O prottipo da funo dever ser void myrighttrim(char *s);

8. Uma funo que elimine todos os espaos mltiplos entre as palavras ou letras.
O prottipo da funo dever ser void removemultiplespace(char *s).

63
ISEP/DEI - Jorge Santos e Paulo Baltarejo

Listing 1.48: Exemplo de manipulao de strings[]

1 #include<i o s t r e a m . h>
2 #include<s t d l i b . h>
3 #include<s t d i o . h>

4 #define MAX 50

6 int menu ( ) ;
7 int m y s t r l e n ( char s ) ;
8 int mystrncpy ( char s t r D e s t , char s t r S o u r c e , int comp_strDest ) ;
9 int s t r 1 I g u a l s t r 2 ( char s t r 1 , char s t r 2 ) ;
10 char mytolower ( char s ) ;
11 char mytoupper ( char s ) ;
12 void m y l e f t t r i m ( char s ) ;
13 void m y r i g h t t r i m ( char s ) ;
14 void r e m o v e m u l t i p l e s p a c e ( char s ) ;
15

16 int main ( )
17 {
18 int op , n ;
19 char s t r 1 [MAX] , s t r 2 [MAX] , c ;
20 do{
21 op=menu ( ) ;
22 switch ( op ) {
23 case 1 : cout<<"\ n D i g i t e a s t r i n g : " ;
24 c i n . g e t l i n e ( s t r 1 ,MAX) ;
25 n=m y s t r l e n ( s t r 1 ) ;
26 cout<<"A s t r i n g tem "<<n<<" c a r a c t e r e s "<<e n d l ;
27 break ;
28 case 2 :
29 cout<<"\ n D i g i t e a s t r i n g : " ;
30 c i n . g e t l i n e ( s t r 1 ,MAX) ;
31 n=mystrncpy ( s t r 2 , s t r 1 , MAX) ;
32 cout<<" Copiou "<<n<<" c a r a c t e r e s "<<e n d l ;
33 cout<<s t r 2 <<e n d l ;
34 break ;
35 case 3 :
36 cout<<"\ n D i g i t e a s t r i n g 1 : " ;
37 c i n . g e t l i n e ( s t r 1 ,MAX) ;
38 cout<<"\ n D i g i t e a s t r i n g 2 : " ;
39 c i n . g e t l i n e ( s t r 2 ,MAX) ;
40 n=s t r 1 I g u a l s t r 2 ( s t r 2 , s t r 1 ) ;
41 i f ( n==1)
42 cout<<"As s t r i n g s s a o i g u a i s "<<e n d l ;
43 else
44 cout<<"As s t r i n g s s a o d i f e r e n t e s "<<e n d l ;
45

46 break ;
47 case 4 :
48 cout<<"\ n D i g i t e o c a r a c t e r : "<<e n d l ;
49 c=g e t c h a r ( ) ;
50 cout<<mytoupper ( c)<<e n d l ;

64
Apontamentos de Programao C/C++

51 break ;
52 case 5 :
53 cout<<"\ n D i g i t e o c a r a c t e r : "<<e n d l ;
54 c=g e t c h a r ( ) ;
55 cout<<mytolower ( c)<<e n d l ;
56 break ;
57 case 6 :
58 cout<<"\ n D i g i t e a s t r i n g : " ;
59 c i n . g e t l i n e ( s t r 1 ,MAX) ;
60 mylefttrim ( str1 ) ;
61 cout<<s t r 1 <<e n d l ;
62 break ;
63 case 7 :
64 cout<<"\ n D i g i t e a s t r i n g : " ;
65 c i n . g e t l i n e ( s t r 1 ,MAX) ;
66 myrighttrim ( s t r 1 ) ;
67 cout<<s t r 1 <<e n d l ;
68 break ;
69 case 8 :
70 cout<<"\ n D i g i t e a s t r i n g : " ;
71 c i n . g e t l i n e ( s t r 1 ,MAX) ;
72 removemultiplespace ( str1 ) ;
73 cout<<s t r 1 <<e n d l ;
74 break ;
75 }
76 } while ( op ! = 0 ) ;
77 return 0 ;
78 }
79

80 int menu ( )
81 {
82 int op ;
83 char b u f f e r [MAX] ;
84 do{
85 cout<<"Menu\n" ;
86 cout<<"1 Determinar o comprimento de uma s t r i n g \n" ;
87 cout<<"2 Copiar uma s t r i n g \n" ;
88 cout<<"3 V e r i f i c a r s e duas s t r i n g s s a o i g u a i s \n" ;
89 cout<<"4 C o n v e r t e r um c a r a c t e r m i n u s c u l o em m a i u s c u l o \n" ;
90 cout<<"5 C o n v e r t e r um c a r a c t e r m a i u s c u l o em m in u s c u l o \n" ;
91 cout<<"6 E l i m i n a r o s e s p a c o s a e s q u e r d a \n" ;
92 cout<<"7 E l i m i n a r o s e s p a c o s a d i r e i t a \n" ;
93 cout<<"8 Remover m u l t i p l o s e s p a c o s \n" ;
94 cout<<"0 S a i r \n" ;
95 cout<<"\ n D i g i t e a opcao : " ;
96 c i n . g e t l i n e ( b u f f e r ,MAX) ;
97 op=a t o i ( b u f f e r ) ;
98 } while ( op<0 | | op >8);
99 return op ;
100 }
101

65
ISEP/DEI - Jorge Santos e Paulo Baltarejo

102 int m y s t r l e n ( char s )


103 {
104 int i =0;
105 i f ( s !=NULL)
106 {
107 while ( s [ i ] ! = \0 )
108 i ++;
109 }
110 return i ;
111 }
112

113 int mystrncpy ( char s t r D e s t , char s t r S o u r c e , int comp_strDest )


114 {
115 int x , i ;
116 x=m y s t r l e n ( s t r S o u r c e ) ;
117 f o r ( i =0; i <comp_strDest 1 && i <x ; i ++)
118 s t r D e s t [ i ]= s t r S o u r c e [ i ] ;
119 s t r D e s t [ i ]= \0 ;
120 return i ;
121 }
122

123 int s t r 1 I g u a l s t r 2 ( char s1 , char s 2 )


124 {
125 int i , x , y ;
126 x=m y s t r l e n ( s 1 ) ;
127 y=m y s t r l e n ( s 2 ) ;
128 i f ( x!=y )
129 return 0 ;
130 f o r ( i =0; i <x ; i ++)
131 i f ( s1 [ i ]!= s2 [ i ] )
132 return 0 ;
133 return 1 ;
134 }
135

136 char mytolower ( char s )


137 {
138 i f ( s>=A && s<= Z )
139 s+= a A ;
140 return s ;
141 }
142

143 char mytoupper ( char s )


144 {
145 i f ( s>= a && s<= z )
146 s= a A ;
147 return s ;
148 }
149

150 void m y l e f t t r i m ( char s )


151 {
152 int i , x ;

66
Apontamentos de Programao C/C++

153 i f ( s !=NULL)
154 {
155 while ( s [0]== )
156 {
157 x=m y s t r l e n ( s ) ;
158 f or ( i =1; i <x ; i ++)
159 s [ i 1]= s [ i ] ;
160 }
161 }
162 }
163

164 void m y r i g h t t r i m ( char s )


165 {
166 int i ;
167 i=m y s t r l e n ( s ) ;
168 i f ( i >0)
169 {
170 while ( s [ i 1]== && i >0)
171 {
172 s[ i ]= \0 ;
173 }
174 }
175 }
176

177 void r e m o v e m u l t i p l e s p a c e ( char s )


178 {
179 int i , j , x ;
180

181 i =0;
182 while ( s [ i ]== ) i ++;
183

184 j=m y s t r l e n ( s ) 1;
185 while ( s [ j ]== ) j ;
186

187 while ( i <j )


188 {
189 i f ( s [ i ]== && s [ i +1]== )
190 {
191 f or ( x=i ; x<m y s t r l e n ( s ) ; x++)
192 s [ x]= s [ x + 1 ] ;
193 j ;
194 }
195 else
196 i ++;
197 }
198 }

67
ISEP/DEI - Jorge Santos e Paulo Baltarejo

1.11.5 Exerccios propostos


1.11.5.1 Funo que determine o nmero de ocorrncias
Escreva uma funo que receba duas strings e retorne o nmero de ocorrncias de
uma na outra. Por exemplo, a string "DEIDE DEDEI DEEI"tem duas ocorrncias
da string "DEI".

1.11.5.2 Funo que verifique se uma string inversa de outra


Escreva uma funo que recebe duas strings e verifica se uma inversa de outra.
Caso seja deve retornar 1 e 0 caso no seja. Note que uma strings vazia no tem
inversa.

1.11.5.3 Funo que conta as palavras de uma string


Escreva uma funo que recebe uma string e retorne o nmero de palavras. Entendendo-
se por palavra cadeias de caracteres terminadas pelo carcter espao. As palavras
tm que ter mais do que um carcter.

1.11.5.4 Funo que formate uma string


Escreva uma funo que receba uma string e a formate da seguinte forma:

1. As palavras comeam sempre com letras maiscula e o resto com letra mins-
cula;

2. As palavras tm que ter mais do que um carcter;

3. As letras (caracteres isolados em letra minscula).

1.12 Ponteiros
As variveis na linguagem C++ so definidas atravs de um identificador e do tipo
de dados. No entanto, estas esto armazenadas algures na memria. A memria
uma lista de bytes, na qual cada um tem endereo nico. Assim, as variveis podem
tambm ser referenciadas atravs do endereo de memria onde esto armazenadas.
A memria de um computador com 512 MBytes (512*1024*1024=536870912 bytes)
ilustrada na figura 1.13. Todos os bytes so endereveis (o endereo est escrito
em notao hexadecimal).

1.12.1 Operador endereo &


Sempre que se declara uma varivel, ela armazenada num local concreto da mem-
ria, sendo que o local definido pelo sistema operativo em tempo de execuo. Uma
vez atribudo o local de armazenamento, por vezes necessrio aceder directamente
a esse local. Isto pode ser feito colocando o & antes do identificador da varivel. A
listagem 1.49 apresenta um programa que permite mostrar no ecr o endereo de
memria onde a varivel est declarada.

68
Apontamentos de Programao C/C++

Endereo Byte

0x00000000

0x00000001

0x00000002

0x00000003

0x1FFFFFFF

Figura 1.13: Representao da memria do computador

Listing 1.49: Endereo de uma varivel


1 #include<i o s t r e a m . h>
2

3 int main ( )
4 {
5 int i ;
6

7 cout<<&i <<e n d l ;
8

9 return 0 ;
10 }

A colocao do & antes do identificador da varivel significa o "endereo de".


No caso do exemplo da listagem 1.49 a instruo cout< <&i< <endl; imprime no
ecr o endereo da varivel i.

1.12.2 Operador de referncia *


Os ponteiros so variveis para que armazenam endereos. A forma de definir va-
riveis do tipo ponteiro a seguinte:
<tipo-de-dados> * <identificador>;
A nica diferena em relao forma de definir variveis a colocao do caracter
* entre o tipo-de-dados e o identificador.

<tipo-de-dados> um qualquer tipo de dados vlido;

<identificador> tem o mesmo significado que o identificador de uma


varivel de um qualquer tipo de dados estudado at agora.

A seguir apresentase a definio de duas variveis do tipo ponteiro.

int *pi;
char *pc;

69
ISEP/DEI - Jorge Santos e Paulo Baltarejo

Uma varivel do tipo ponteiro tem sempre o mesmo tamanho (em nmero de
bytes) quer aponte para uma varivel do tipo int ou para uma do tipo char. No
entanto, na definio necessrio definir qual o tipo de dados que o ponteiro vai
apontar. Isto porque, como j foi referido, os tipos de dados no ocupam todos o
mesmo nmero de bytes. Da que, o compilador precisa de saber qual o tipo de
dados que o ponteiro aponta, porque quando faz uma escrita ou uma leitura atravs
do ponteiro tem que saber em quantos bytes vai escrever ou ler. A listagem 1.50
ilustra a definio, atribuio e o acesso (leitura e escrita) a uma varivel do tipo
int atravs de um ponteiro.

Listing 1.50: Exemplo da utilizao de ponteiros


1 #include<i o s t r e a m . h>
2

3 int main ( )
4 {
5 int pi , i =100;
6 // a t r i b u i o do e n d e r e o
7 // da v a r i v e l i ao p o n t e i r o
8 p i=&i ;
9 // a c e d e r ao v a l o r da
10 // v a r i v e l i a t r a v s do p o n t e i r o
11 cout <<pi<<e n d l ;
12 // a l t e r a r o v a l o r da
13 // v a r i v e l i a t r a v s do p o n t e i r o
14 p i =200;
15 // a c e d e r ao v a l o r da
16 // v a r i v e l i a t r a v s do p o n t e i r o
17 cout <<pi<<e n d l ;
18

19 return 0 ;
20 }
Como j foi referido a definio de um ponteiro fazse com a utilizao do caracter
* entre o tipo de dados e o identificador. No entanto, para aceder ao contedo da
varivel apontado pelo ponteiro tambm usado o caracter* antes do identificador.
No exemplo, da listagem 1.50 a instruo pi=&i; atribu ao ponteiro pi o endereo
da varivel i. A instruo cout< <*pi< <endl; vai imprimir no ecr o valor da
varivel i o valor do apontado pelo ponteiro pi. O significado do caracter* neste
caso significa o valor apontado por. A figura 1.14 ilustra o resultado da atribuio
de uma endereo de uma varivel a uma ponteiro.

num
Identificador Endereo Contedo 15
*pnum
num 0x0FF10101 15
&num
pnum 0x0FFAACC4 0x0FF10101 0x0FF10101 pnum

Figura 1.14: Ponteiro

Como se pode ver o valor da varivel pnum o endereo da varivel num. Portanto

70
Apontamentos de Programao C/C++

atravs do ponteiro pi ((valor apontado por pnum) *pnum) possvel aceder ao valor
da varivel num.
Sendo um ponteiro uma varivel, que armazena endereos de variveis, o seu
valor pode ser alterado. Isto , possvel atribuir o endereo de uma varivel a
um ponteiro e depois alterar esse valor com o endereo de outra varivel. Uma boa
prtica de programao colocar o valor de uma ponteiro a NULL quando no est
apontar para nenhuma varivel.
Listing 1.51: Exemplo da utilizao de ponteiros
1 #include<i o s t r e a m . h>
2

3 int main ( )
4 {
5 int p1=NULL, p2=NULL;
6 int v1 =100 , v2 =200;
7 // os p o n t e i r o s apontam t o d o s para a mesma v a r i v e l
8 p1=p2=&v1 ;
9 // a l t e r a r o v a l o r v a r i v e l v1 a t r a v s dos p o n t e i r o s
10 p1+=100;
11 p2+=100;
12 cout<<v1<<e n d l ;
13 // a l t e r a r o p o n t e i r o p2 que p a s s a
14 // a p o n t a r para a v a r i a v e l v2
15 p2=&v2 ;
16 cout <<p2<<e n d l ;
17 // a t r i b u i v a r i v e l v2 o v a l o r do
18 // a p o n t a d o r por p1 ( o v a l o r da v a r i v l v1 )
19 v2=p1 ;
20 cout<<v2<<e n d l ;
21 // a l t e r a o v a l o r v a r i v e l v1
22 // ( o p o n t e i r o p1 aponta para a v a r i v a e l v1 )
23 v1+=50;
24 cout <<p1<<e n d l ;
25

26 return 0 ;
27 }
As variveis v1 e v2 so iniciados com o valor 100 e 200 respectivamente. A
instruo p1=p2=&v1; faz com que os dois ponteiros apontem para a varivel v1. O
valor desta varivel alterado atravs dos dois ponteiros nas instrues *p1+=100; e
*p2+=100; pelo que o valor da varivel v1 passa a ser de 300. A instruo p2=&v2;
altera o ponteiro p2, que deixa de apontar para a varivel v1 e passa a apontar
para a varivel v2. A instruo v2=*p1; altera o valor da varivel v2 com o valor
da varivel v1 (uma vez que o ponteiro p1 aponta para a varivel v1). O valor da
varivel v1 alterado com a instruo v1+=50;. Assim, a sada deste programa a
seguinte:
300
200
300
350
Press any key to continue

71
ISEP/DEI - Jorge Santos e Paulo Baltarejo

Note-se que o valor das variveis pode ser alterado atravs dos ponteiros ou
atravs das prprias variveis.

1.12.3 Ponteiros e vectores


Um identificador de um vector equivalente a um ponteiro para a primeira posio
desse vector. Por exemplo, a seguir apresentase a declarao de um vector e de um
ponteiro;

int vec[10];
int *p;

a seguinte instruo valida


p=vec;
esta instruo faz com que o ponteiro p e vec sejam equivalentes, e tem as mesmas
propriedades. A nica diferena est relacionada com o facto de poder ser atribudo
outro valor ao ponteiro p enquanto que ao ponteiro vec no. Portanto, p uma va-
rivel do tipo ponteiro enquanto que vec uma varivel do tipo ponteiro constante.
Da que a seguinte instruo invlida:
vec=p;.
A seguir apresentase um exemplo que mostra a utilizao de ponteiro para
aceder aos elementos de um vector.
Listing 1.52: Exemplo da utilizao de ponteiros
1 #include<i o s t r e a m . h>
2

3 int main ( )
4 {
5 int p=NULL;
6 int vec [ 1 0 ] = { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 } ;
7 p=vec ;
8 f o r ( int i =0; i <10; i ++)
9 cout<<p [ i ]<< e n d l ;
10 return 0 ;
11 }

1.12.4 Ponteiros para ponteiros


A linguagem C++ permite a utilizao de ponteiros para ponteiros no qual o l-
timo aponta para uma varivel. Para tal basta acrescentar um asterisco por cada
referncia. Por exemplo:
Listing 1.53: Exemplo da utilizao de ponteiros
1 #include<i o s t r e a m . h>
2

3 int main ( )
4 {
5 int pp=NULL, p=NULL, a =10;
6

7 p=&a ;

72
Apontamentos de Programao C/C++

8 pp=&p ;
9

10 cout<<" e n d e r e c o de a : "<<&a<<e n d l ;
11 cout<<" e n d e r e c o de p : "<<&p<<e n d l ;
12 cout<<" e n d e r e c o de pp : "<<&pp<<e n d l ;
13

14 cout<<"O v a l o r da v a r i a v e l a : "<<a<<e n d l ;
15 cout<<"O v a l o r da v a r i a v e l p : "<<p<<e n d l ;
16 cout<<"O v a l o r da v a r i a v e l pp : "<<pp<<e n d l ;
17

18 cout<<"O v a l o r da v a r i a v e l a : "<<a<<e n d l ;
19 cout<<"O v a l o r apontado por p : "<<p<<e n d l ;
20 cout<<"O v a l o r apontado p e l o apontado por pp : "<<pp<<e n d l ;
21

22 return 0 ;
23 }
A sada do programa anterior poderia ser a seguinte.

endereco de a: 0x0012FF74
endereco de p: 0x0012FF78
endereco de pp:0x0012FF7C
O valor da variavel a: 10
O valor da variavel p:0x0012FF74
O valor da variavel pp: 0x0012FF78
O valor da variavel a: 10
O valor apontado por p: 10
O valor apontado pelo apontado por pp: 10

Press any key to continue

Como se pode ver, o valor do ponteiro pp o endereo do ponteiro p que por sua
vez tem o endereo da varivel a. A figura 1.15 apresenta graficamente a interaco
entre as variveis presentes no programa da listagem 1.53.

a
*p 10
**pp
&a
0x0012FF74 p
*pp

&p
0x0012FF78 pp

Figura 1.15: Ponteiro para ponteiro

1.12.5 Ponteiros do tipo void


Os ponteiros de tipo void so um tipo especial de ponteiros que permite que um
ponteiro possa apontar para variveis de qualquer tipo. O nico problema que

73
ISEP/DEI - Jorge Santos e Paulo Baltarejo

para se aceder ao valor da varivel apontado por este tipo de ponteiros necessrio
fazer a converso do tipo de dados (cast). Este tipo de ponteiro muito interessante
para o desenvolvimento de funes genricas, que podem receber vrios tipos de
dados diferentes. O exemplo 1.54 mostra a utilizao dos ponteiros de tipo void.

Listing 1.54: Exemplo da utilizao de ponteiros do tipo void


1 #include <i o s t r e a m . h>
2 #define TPCHAR 1
3 #define TPINT 2
4 #define TPFLOAT 3
5

6 void i n c r e m e n t o ( void ap , int t i p o )


7 {
8 switch ( t i p o )
9 {
10 case TPCHAR : ( ( ( char ) ap ))++; break ;
11 case TPINT : ( ( ( long ) ap ))++; break ;
12 case TPFLOAT : ( ( ( f l o a t ) ap ))++; break ;
13 }
14 }
15 int main ( )
16 {
17 char a = a ;
18 int b = 9 ;
19 float c = 7 . 5 ;
20

21 i n c r e m e n t o (&a ,TPCHAR) ;
22 i n c r e m e n t o (&b , TPINT ) ;
23 i n c r e m e n t o (&c ,TPFLOAT) ;
24

25 c o u t << a << " , " << b << " , " << c<<e n d l ;
26

27 return 0 ;
28 }
A sada deste programa a seguinte:

b, 10, 8.5
Press any key to continue

1.13 Tipos de dados no nativos


Nesta seco apresentada a forma de definir novos tipos de dados na linguagem
C++.

1.13.1 Estruturas de dados instruo struct


Uma estrutura de dados um conjunto de dados de variveis de diversos tipos de
dados agrupados sob um nico identificador. A seguir apresentase a forma de
definir uma estrutura:

74
Apontamentos de Programao C/C++

struct <identificador-da-estrutura>
{
<tipo-de-dados> <identificador 1>;
<tipo-de-dados> <identificador 2>;
...
<tipo-de-dados> <identificador N>;
}<identificador-da-variavel>;

na qual

<identificador-da-estrutura> o nome pelo qual este conjunto de va-


riveis identificado;

<tipo-de-dados> <identificador ...>; consiste na declarao de uma


varivel dentro da estrutura (opcional).

Na prtica a instruo struct permite definir um novo tipo de dados. A partir


do momento que definido possvel usar da mesma forma que os tipos de dados pri-
mitivos tais como o int, char, long e outros. <identificador-da-variavel> op-
cional e consiste em definir uma varivel do tipo <identificador-da-estrutura>.
A seguir apresentase a declarao de uma estrutura:

struct produtos
{
char nome[30];
float preco;
};

A instruo anterior consiste na definio de um novo tipo de dados. De seguida


apresentada a declarao de variveis do tipo produtos:
produtos lapis, caneta, borracha;
Como foi referido anteriormente tambm possvel definir variveis do tipo da
estrutura no momento da sua definio, conforme o exemplo seguinte.

struct produtos
{
char nome[30];
float preco;
}lapis, caneta, borracha;

A definio das estruturas pode ser realizada em qualquer parte do cdigo, dentro
ou fora das funes. Sendo que, quando definida dentro de uma funo este tipo
de dados s conhecido dentro dessa funo.
Aps a definio do novo tipo de dados para aceder aos diferentes campos que o
compe utiliza-se operador . (ponto). Por exemplo, a instruo lapis.preco=0.5;
permite atribuir o valor 0.5 ao campo preco da varivel lapis. Para realizar a
leitura /atribuio o processo semelhante:

float x=lapis.preco;
cin>>lapis.preco;

75
ISEP/DEI - Jorge Santos e Paulo Baltarejo

Tal como para os outro tipo de dados tambm possvel definir ponteiros para
estruturas. As regras so as mesmas que para qualquer outro tipo de dados. De
seguida apresentada a forma de definir de um ponteiro para uma estrutura.
<identificador-da-estrutura> * <identificador>;
O acesso aos elementos constituintes da estrutura feita atravs do operador >.
Conforme o exemplo (1.55) apresentado de seguida.
Listing 1.55: Exemplo da utilizao de ponteiros para estruturas
1 #include <i o s t r e a m . h>
2 #include < s t d l i b . h>
3

4 struct f i l m e s _ t {
5 char t i t u l o [ 5 0 ] ;
6 int ano ;
7 };
8

9 int main ( )
10 {
11 char b u f f e r [ 5 0 ] ;
12 filmes_t afilme ;
13 filmes_t pfilme ;
14

15 // a t r i b u i r ao p o n t e i r o o e n d e r e o da v a r i a v e l a f i l m e
16 pfilme = & afilme ;
17

18 c o u t << " D i g i t e o t i t u l o : " ;


19 // armazenar o t i t u l o na v a r i a v e l a t r a v e s do p o n t e i r o
20 c i n . g e t l i n e ( p f i l m e >t i t u l o , 5 0 ) ;
21

22 c o u t << " D i g i t e o ano : " ;


23 cin . getline ( buffer , 5 0 ) ;
24 // armazenar o ano na v a r i a v e l a t r a v e s do p o n t e i r o
25 p f i l m e >ano = a t o i ( b u f f e r ) ;
26

27 // l e r os dados armazenados na
28 // v a r i a v e l a t r a v e s do p o n t e i r o
29 c o u t << p f i l m e >t i t u l o ;
30 c o u t << " ( " << p f i l m e >ano << " ) \ n" ;
31

32 return 0 ;
33 }
O operador > exclusivamente utilizado para aceder aos elementos das estrutu-
ras atravs de ponteiros. No entanto, tambm possvel a utilizao do operador .
para aceder aos elementos de um ponteiro para uma estrutura. A seguir apresentase
diferentes formas de aceder aos elementos de uma estrutura atravs de um ponteiro.
filmes_t afilme;
filmes_t * pfilme;
pfilme=&afilme;
A instruo seguinte permite aceder ao elemento titulo da estrutura apontado
pelo ponteiro pfilme.

76
Apontamentos de Programao C/C++

pfilme->titulo;
A instruo seguinte equivalente anterior.
(*pfilme).titulo;
A definio de estruturas dentro de estruturas muito til e comum. O programa
da listagem 1.56 contm duas estruturas: data_t e filmes_t, notese que um dos
elementos da estrutura filmes_t ele prprio uma estrutura (data_estreia.
Listing 1.56: Estruturas dentro de estruturas
1 #include <i o s t r e a m . h>
2 #include < s t d l i b . h>
3

4 struct data_t
5 {
6 int dia , mes , ano ;
7 };
8

9 struct f i l m e s _ t
10 {
11 char t i t u l o [ 5 0 ] ;
12 data_t d a t a _ e s t r e i a ;
13 };
14

15 int main ( )
16 {
17 char b u f f e r [ 5 0 ] ;
18 filmes_t afilme ;
19

20 c o u t << " D i g i t e o t i t u l o : ";


21 cin . getline ( afilme . titulo ,50);
22 c o u t << " D i g i t e a data de e s t r e i a ( d i a /mes/ ano ) : " ;
23 cin . getline ( buffer , 5 0 ) ;
24 afilme . data_estreia . dia = atoi ( buffer );
25 cin . getline ( buffer , 5 0 ) ;
26 a f i l m e . d a t a _ e s t r e i a . mes = atoi ( buffer );
27 cin . getline ( buffer , 5 0 ) ;
28 a f i l m e . d a t a _ e s t r e i a . ano = atoi ( buffer );
29

30 c o u t << a f i l m e . t i t u l o ;
31 c o u t << " ( " << a f i l m e . d a t a _ e s t r e i a . dia<<" : "
32 c o u t <<a f i l m e . d a t a _ e s t r e i a . mes<<" : " ;
33 cout<<a f i l m e . d a t a _ e s t r e i a . ano<<" ) \ n" ;
34

35 return 0 ;
36 }
Da mesma forma que possvel definir vectores de tipos de dados primitivos, tam-
bm possvel definir vectores, tanto unidimensionais como multidimensionais, de
estruturas. Assim como, os elementos de uma estrutura tambm pode ser vectores.
O programa da listagem 1.57 mostra como definir estruturas nas quais alguns dos
seus elementos so tambm estruturas e vectores de estruturas. O objectivo deste
exemplo mostrar a forma de aceder/utilizar os elementos de uma estrutura deste
tipo.

77
ISEP/DEI - Jorge Santos e Paulo Baltarejo

Listing 1.57: Vectores de estruturas

1 #include <i o s t r e a m . h>


2

3 #define STR_LEN 50
4 #define NUM_DISC 30
5 #define NUM_ALUNOS 100
6

7 struct data_t
8 {
9 int dia , mes , ano ;
10 };
11

12 struct d i s c i p l i n a _ t
13 {
14 char d i s c i p l i n a [STR_LEN]
15 int c l a s s i f i c a c a o ;
16 };
17

18 struct aluno_t
19 {
20 char nome [STR_LEN ] ;
21 char morada [STR_LEN 2 ] ;
22 data_t data_nasc ;
23 d i s c i p l i n a _ t d i s c i p l i n a s [NUM_DISC ] ;
24 };
25

26 void l i s t a r A l u n o s ( aluno_t a l [ ] ) ;
27

28 int main ( )
29 {
30 aluno_t a l u n o s [NUM_ALUNOS] ;
31

32 listarAlunos ( alunos ) ;
33

34 return 0 ;
35 }
36

37 void l i s t a r A l u n o s ( aluno_t a l [ ] )
38 {
39 f o r ( int i =0; i <NUM_ALUNOS; i ++)
40 {
41 cout<<"Nome : "<<a l [ i ] . nome<<e n d l ;
42 cout<<"Morada : "<<a l [ i ] . morada<<e n d l ;
43 cout<<"Data de na sci me nt o : "<<a l [ i ] . data_nasc . dia<<" : " ;
44 cout<<<<a l [ i ] . data_nasc . mes<<" : " ;
45 cout<<<<a l [ i ] . data_nasc . ano<<e n d l ;
46 f o r ( int j =0; j <NUM_DISC; j ++)
47 {
48 cout<<"\ t D i s c i p l i n a : "<<a l [ i ] . d i s c i p l i n a s [ j ] . d i s c i p l i n a <<e n d l ;
49 cout<<"\ t D i s c i p l i n a : "<<a l [ i ] . d i s c i p l i n a s [ j ] . c l a s s i f i c a c a o <<e n d l ;
50 }

78
Apontamentos de Programao C/C++

51 }
52 }

1.13.2 Definio de tipos instruo typedef


A linguagem C++ permite a definio de tipos de dados no nativos atravs da
instruo typedef. A forma para o fazer a seguinte:
typedef <tipo-de-dados-existente> <novo-tipo-dados>;
no qual
<tipo-de-dados-existente> um tipo de dados j definido, por exemplo
um tipo de dados primitivos ou uma tipo de dados composto (estrutura);

<novo-tipo-dados> a designao do novo tipo de dados.


A seguir apresenta-se vrios exemplos da definio de novos tipos de dados.

typedef char CARACTER;


typedef int INTEIRO;
typedef float REAL;
typedef char STRING [50];

A partir destas definies possvel usar os novos tipos da mesma forma que se
podem todos os outros. No extracto de cdigo seguinte so definidoas variveis com
base nos tipos anteriores.

CARACTER a, b,c=A;
INTEIRO x=5;
REAL f=4.9;
STRING str="Bom dia mundo!!";

1.13.3 Unio instruo union


Uma unio5 permite fazer a definio de um tipo de dados de forma disjunta, isto
significa que em termos prticos uma varivel deste tipo pode ser de qualquer dos
subtipos utilizados na definio. A sintaxe de uma unio muito semelhante com
a definio de uma estrutura:

union <identificador-da-unio>
{
<tipo-de-dados> <identificador 1>;
<tipo-de-dados> <identificador 2>;
...
<tipo-de-dados> <identificador N>;
}<identificador-da-variavel>;

na qual

<identificador-da-unio> a designao do novo tipo de dados;


5
do anglo-saxnico union.

79
ISEP/DEI - Jorge Santos e Paulo Baltarejo

<identificador-da-variavel> define uma varivel do novo tipo de dados


(opcional).
Uma das grandes diferenas entre uma estrutura e uma unio, consiste no ta-
manho (nmero de bytes) que cada uma ocupa. O tamanho de uma estrutura cor-
responde ao somatrio dos tamanhos dos seus elementos e consequentemente numa
estrutura pode armazenara dados de todos os seus elementos em simultneo. No
caso das unies, o tamanho de uma unio corresponde ao tamanho do elemento que
ocupa o maior nmero de bytes. Por exemplo, a seguinte unio mtipos_t ocupa 8
bytes, uma vez que o tamanho de um char 1 byte, de um int so 4 bytes e de um
float so 8 bytes.
union mtipos_t
{
char c;
int i;
float f;
};
A figura 1.16 apresenta graficamente a unio mtipos_t. Como se pode ver, uma
unio, de cada vez, s pode armazenar informao de um dos seus tipos, uma vez
que o mesmo espao usado para todos eles. Nesta representao assume-se que os
tipos de dados char, int e float ocupam um, dois e quatro bytes, respectivamente.

mtipos_t byte byte byte byte

c
i
f

Figura 1.16: Representao de uma unio

Para aceder aos elementos de uma unio usado o operador . (ponto). Por
exemplo, a seguir apresentase a forma de definir uma unio e de aceder aos seus
elementos.
mtipos_t un;
un.c=a;
cout<<un.c;
un.i=1000;
cout<<un.1;
Importa referir, que sendo utilizado o mesmo espao para armazenar a infor-
mao dos diferentes elementos, a modificao num dos elementos afecta a infor-
mao dos outros. Na linguagem C++ tambm existe a possibilidade de definir
unies annimas, isto , se se definir uma unio dentro de uma estrutura sem
identificador-da-varivel possivel aceder aos elementos da unio sem refe-
renciar o identificador-da-variavel (que de facto no existe). A seguir apre-
sentada a definio de duas estruturas, uma com uma outra unio simples e uma
annima. A unio simples:

80
Apontamentos de Programao C/C++

struct livro
{
char titulo[50];
char autor[50];
union{
float dolar;
int iene;
}preco;
};

A unio annima:

struct livro
{
char titulo[50];
char autor[50];
union
{
float dolar;
int iene;
};
};

Considerese que existe uma varivel do tipo livro definida com o identificador
meu_livro. O acesso ao elemento dolar da unio simples fazse da seguinte forma:
meu_livro.preco.dolar
enquanto que no caso, da unio annima faz-se da seguinte forma:
meu_livro.dolar
O elemento dolar acedido com se fosse um elemento da estrutura e no da
unio. Notese que independentemente de serem ou no annima, as unies ocupam
o mesmo espao.

1.13.4 Enumeradores instruo enum


Os enumeradores servem para criar tipos de dados definidos custa de uma lista
ordenada de valores possveis. A forma de definir um enumerador a seguinte:

enum <id-do-enumerador>
{
<valor 1>,
<valor 2>,
...
<valor N>
}<id-da-variavel>;

Por exemplo, a instruo seguinte define um novo tipo de dados chamado cor_t,
para armazenar as cores.
enum cor_t{preto, branco, azul,vermelho, verde, amarelo};
Nos elementos do enumerador cor_t no existe nenhuma referncia a qualquer
tipo de dados. Portanto, os enumeradores permitem definir novos tipos de dados

81
ISEP/DEI - Jorge Santos e Paulo Baltarejo

sem referenciar qualquer outro tipo de dados j existente. No entanto, uma qualquer
varivel do tipo cor_t s pode assumir os valores escritos entre {}. De facto os
enumeradores so compilados como inteiros, em que se nada for referido o primeiro
elemento assume o valor 0 e o seguinte 1 e assim por diante. No entanto, podese
definir qual o valor inicial. Por exemplo, a instruo seguinte cria o tipo de dados
mes_t em que o primeiro elemento assume o valor 1.
mes_t {jan=1,fev,mar,abr,mai,jun,jul,ago,set,out,nov,dez};
O exemplo 1.58 mostra a utilizao dos tipos de dados definidos atravs de enum,
struct e union.

Listing 1.58: Exemplo da utilizao de tipos de dados definidos


1 #include <i o s t r e a m . h>
2

3 #define PI 3.1415
4

5 enum t i p o _ f i g u r a _ t {RECTANGULO, CIRCULO} ;


6

7 struct rectangu lo_dimensoes_t


8 {
9 double comprimento ;
10 double l a r g u r a ;
11 };
12 struct c i r c u l o _ d i m e n s o e s _ t
13 {
14 double r a i o ;
15 };
16 struct f i g u r a _ t
17 {
18 tipo_figura_t tag ;
19 union
20 {
21 rectan gulo_dime nsoes _t r e c t a n g u l o ;
22 circulo_dimensoes_t c i r c u l o ;
23 } dimen soes ;
24 };
25 double a r e a ( f i g u r a _ t f i g )
26 {
27 switch ( f i g >t a g )
28 {
29 case RECTANGULO:
30 {
31 double c = f i g >dimenso es . r e c t a n g u l o . comprimento ;
32 double l = f i g >dimenso es . r e c t a n g u l o . l a r g u r a ;
33 return c l ;
34 }
35 case CIRCULO:
36 {
37 double r = f i g >dimenso es . c i r c u l o . r a i o ;
38 return PI ( r r ) ;
39 }
40

82
Apontamentos de Programao C/C++

41 default : return 1.0; / t a g i n v a l i d a /


42 }
43 }
44 int main ( )
45 {
46 figura_t f i g ;
47

48 f i g . t a g=RECTANGULO;
49 f i g . dimensoes . r e c t a n g u l o . comprimento = 3 . 0 ;
50 f i g . dimensoes . r e c t a n g u l o . l a r g u r a = 2 . 0 ;
51

52 cout<<a r e a (& f i g )<<e n d l ;


53

54 return 0 ;
55 }
A figura 1.17 apresenta um resumo dos principais tipos de dados em C++.

vectores
ficheiros
struct
compostos
union

enumerados enum

char
Tipos de int
simples nmericos
dados float
double

lgicos bool

ponteiros
void

Figura 1.17: Tipos de dados

1.13.5 Exerccios resolvidos


1.13.5.1 Ponto e recta
Sabendo que um ponto constitudo por trs coordenadas e uma recta pode ser
definida por dois pontos. Desenvolva um programa que implemente as seguintes
estruturas e funes.

1. Defina as estruturas ponto e recta;

2. Desenvolva uma funo que permita definir um ponto. A funo dever ter o
seguinte prottipo: void inserirPonto(Ponto &p);

3. Desenvolva uma funo que mostre o valor das coordenadas de um ponto. A


funo dever ter o seguinte prottipo: void imprimirPonto(Ponto p);

83
ISEP/DEI - Jorge Santos e Paulo Baltarejo

4. Desenvolva uma funo que permita alterar valor das coordenadas de um


ponto. A funo dever ter o seguinte prottipo: void alterarPonto(Ponto *p);

5. Desenvolva uma funo que permita definir uma recta. A funo dever ter o
seguinte prottipo: void inserirRecta(Recta *r);

6. Desenvolva a funo que mostre o valor das coordenadas dos pontos de uma
recta. A funo dever ter o seguinte prottipo: void inserirRecta(Recta &r);

7. Desenvolva a funo que calcule o comprimento de uma recta. A funo dever


ter o seguinte prottipo: double comprimentoRecta(Recta r);

Listing 1.59: Exercicio de manipulao de estruturas


1 #include <i o s t r e a m . h>
2 #include <math . h>
3

4 struct Ponto
5 {
6 double x ;
7 double y ;
8 double z ;
9 };
10 struct Recta
11 {
12 Ponto p1 ;
13 Ponto p2 ;
14 };
15

16 void i n s e r i r P o n t o ( Ponto &p ) ;


17 void imprimirPonto ( Ponto p ) ;
18 void a l t e r a r P o n t o ( Ponto p )
19 void i n s e r i r R e c t a ( Recta &r ) ;
20 void i m p r i m i r R e c t a ( Recta &r ) ;
21 double comprimentoRecta ( Recta r ) ;
22

23 int main ( )
24 {
25 Ponto p ;
26 Recta r ;
27 inserirPonto (p ) ;
28 imprimirPonto ( p ) ;
29 a l t e r a r P o n t o (&p ) ;
30 imprimirPonto ( p ) ;
31 inserirRecta ( r );
32 imprimirRecta ( r ) ;
33 cout<<" comprimento da r e c t a : "<<comprimentoRecta ( r)<<e n d l ;
34 return 0 ;
35 }
36

37 void i n s e r i r P o n t o ( Ponto &p )


38 {

84
Apontamentos de Programao C/C++

39 cout<<" Coordenadas ( x , y , z ) do ponto="<<e n d l ;


40 c i n >>p . x>>p . y>>p . z ;
41 }
42

43 void imprimirPonto ( Ponto p )


44 {
45 cout<<p . x<<" : "<<p . y<<" : "<<p . z<<e n d l ;
46 }
47

48 void a l t e r a r P o n t o ( Ponto p )
49 {
50 cout<<" Novas c o o r d e n a d a s ( x , y , z ) do ponto="<<e n d l ;
51 c i n >>p>x>>p>y>>p>z ;
52 }
53

54 void i n s e r i r R e c t a ( Recta &r )


55 {
56 cout<<" Ponto 1"<<e n d l ;
57 i n s e r i r P o n t o ( r . p1 ) ;
58 cout<<" Ponto 2"<<e n d l ;
59 i n s e r i r P o n t o ( r . p2 ) ;
60 }
61

62 void i m p r i m i r R e c t a ( Recta &r )


63 {
64 cout<<" Ponto 1"<<e n d l ;
65 imprimirPonto ( r . p1 ) ;
66 cout<<" Ponto 2"<<e n d l ;
67 imprimirPonto ( r . p2 ) ;
68 }
69

70 double comprimentoRecta ( Recta r )


71 {
72 return s q r t (
73 pow ( r . p1 . xr . p2 . x ,2)+
74 pow ( r . p1 . yr . p2 . y ,2)+
75 pow ( r . p1 . zr . p2 . z , 2 ) ) ;
76 }

1.13.5.2 Gesto de clientes de uma discoteca

Pretendese um programa para a gesto de clientes de uma discoteca. A cada


cliente dado, entrada, um carto com um nmero. Os cartes esto previamente
numerados e existe uma lista de produtos (cdigo do produto, descrio e preo)
tambm previamente definida. De cada vez que o cliente consome algum produto
registado no carto o cdigo do produto assim como a quantidade. necessrio
verificar se o cdigo do produto introduzido valido. Se o cliente exceder os 10
consumos ter que liquidar a conta e pedir novo carto. Quando um cliente sai, o
programa dever calcular o preo a pagar pelo cliente e registar esse carto como
pago (dever apresentar a relao dos consumos com totais parciais e totais).

85
ISEP/DEI - Jorge Santos e Paulo Baltarejo

1. Defina as estruturas necessrias para a resoluo do problema;


2. Crie uma funo que numere os cartes a partir de um nmero dado pelo
utilizador, supondo que sero necessrios, no mximo 600;
3. Crie uma funo que inicie a lista de produtos, supondo que existem 10 pro-
dutos;
4. Crie uma funo para registar a entrada dos clientes;
5. Crie uma funo para inserir consumos;
6. Crie uma funo para calcular a despesa de um cliente;
7. Crie uma funo para indicar o nmero de clientes na discoteca;
8. Crie uma funo que permita listar os produtos.

1.13.6 Exerccios propostos


1.13.6.1 Empresa de construo civil
Uma empresa de construo civil pretende uma aplicao informtica de gesto de
recursos humanos. A empresa no prev ultrapassar os 100 funcionrios. Os dados
dos funcionrios so os seguintes: o nmero, o nome, a categoria, o vencimento e a
data de entrada dos funcionrios da empresa
1. Defina as estruturas de dados;
2. Escreva uma funo para ler os dados de um funcionrio;
3. Escreva uma funo para listar os dados de um funcionrio;
4. Escreva uma funo para ler os dados dos n funcionrios da empresa;
5. Escreva uma funo para listar os dados dos n funcionrios da empresa.

1.13.6.2 Empresa de construo civil


Dado nmero elevado de alunos inscritos na disciplina de Introduo Programao
foi pedido ao programador que desenvolvesse uma aplicao para gerir a disciplina.
Por motivos ainda desconhecidos o programador em causa foi raptado. Partindo do
que j est (1.60) desenvolvido termine a aplicao . Pressupostos a considerar na
elaborao do programa:
1. Os alunos so identificados pelo nmero;
2. Um aluno s pode estar inscrito a uma turma;
3. No podem existir turmas com o mesmo nmero;
4. A avaliao consiste em duas componentes, componente Frequncia e a Prova
escrita. As notas da Frequncia e da Prova escrita tem um peso de 50% cada
na nota final. A nota da frequncia determinada em funo das classificaes
dos 4 Minitestes (cada com um peso de 10%) e de um trabalho (peso de 60%).
Alm disso e pela ordem que se apresenta, os alunos que:

86
Apontamentos de Programao C/C++

(a) Faltem a mais de 30% das aulas efectivamente dadas so classificados


com "NF"e reprovam;
(b) Os alunos com nota inferior a 8 valores na nota da Frequncia ou da
Prova Escrita so classificados com "NC"e reprovam;
(c) Os alunos com nota superior ou igual a 9.5 so classificados como apro-
vados outros como reprovados.

O valor de qualquer classificao est compreendido entre 0 e 20 valores. Desenvolva:


Relativamente as turmas:

1. Uma funo que permita inserir uma turma. Preferencialmente insero


ordenada;
2. Uma funo que liste todas as turmas.Listar s a informao referente
turma (nmero, professor, aulas dadas e numero de alunos);
3. Uma funo que liste uma dada turma. Informao da turma assim como
dos alunos;
4. Uma funo que permita inserir as aulas efectivamente dadas aquela
turma.

Relativamente aos alunos:

1. Uma funo que permita inserir um aluno. Preferencialmente insero


ordenada;
2. Uma funo que mostre os dados de um aluno (nmero, nome, faltas,
minitestes, trabalho e exame);
3. Uma funo que permita inserir as faltas e as classificaes;
4. Uma funo que elimine um aluno;
5. Uma funo que calcule a classificao final de um aluno.

Listing 1.60: Base para o programa


1 #include <i o s t r e a m >
2 #include <iomanip>
3 #include <c t y p e . h>
4 #include <time . h>
5

6 using namespace s t d ;
7

8 #define NOME_TAM 40
9 #define NUM_TURMA_TAM 4
10 #define NUM_ALUNOS 20
11 #define NUM_MINI_TESTES 4
12 #define NUM_TURMAS 10
13 #define IGNORE 10
14

15 struct FREQ
16 {
17 // p o s i c a o 0 para o 1 MT, p o s i c a o 1 para o 2MT . . .

87
ISEP/DEI - Jorge Santos e Paulo Baltarejo

18 int m i n i t e s t e [NUM_MINI_TESTES ] ;
19 int t r a b a l h o ;
20 };
21

22 struct ALUNO
23 {
24 long numero ;
25 char nome [NOME_TAM] ;
26 FREQ f r e q u e n c i a ;
27 int exame ;
28 int f a l t a s ;
29 };
30

31 struct TURMA
32 {
33 char numero [NUM_TURMA_TAM] ;
34 char p r o f e s s o r [NOME_TAM] ;
35 int num_alunos ;
36 ALUNO a l u n o s [NUM_ALUNOS] ;
37 int aulas_dadas ;
38 };
39

40 int menuAlunos ( ) ;
41 int menuTurmas ( )
42 int menu ( ) ;
43 void manutencaoAlunos (TURMA t [ ] , int &n ) ;
44 void manutencaoTurma (TURMA t [ ] , int &n ) ;
45

46 void main ( )
47 {
48 TURMA turmas [NUM_TURMAS] ;
49 int num_turmas=0;
50 int opcao ;
51 do
52 {
53 opcao=menu ( ) ;
54 switch ( opcao )
55 {
56 case 1 : manutencaoTurma ( turmas , num_turmas ) ;
57 break ;
58 case 2 : manutencaoAlunos ( turmas , num_turmas ) ;
59 break ;
60 }
61 } while ( opcao ) ;
62 }
63

64 int menuAlunos ( )
65 {
66 int opcao ;
67 do
68 {

88
Apontamentos de Programao C/C++

69 cout<<"\n\nALUNOS"<<e n d l ;
70 cout<<" 1 I n s e r i r Aluno \n" ;
71 cout<<" 2 L i s t a r Aluno \n" ;
72 cout<<" 3 I n s e r i r F a l t a s C l a s s i f i c a c o e s \n" ;
73 cout<<" 4 E l i m i n a r Aluno \n" ;
74 cout<<" 5 C a l c u l a r C l a s s i f i c a c a o \n" ;
75 cout<<" 0 V o l t a r \n" ;
76 cout<<" Opcao > " ;
77 c i n >>opcao ;
78 } while ( opcao <0 | | opcao >5);
79 c i n . i g n o r e (IGNORE, \n ) ;
80 return opcao ;
81 }
82

83 int menuTurmas ( )
84 {
85 int opcao ;
86 do
87 {
88 cout<<"\n\nTURMAS"<<e n d l ;
89 cout<<" 1 I n s e r i r Turma\n" ;
90 cout<<" 2 L i s t a r Turmas ( Todas ) \ n" ;
91 cout<<" 3 L i s t a r Turma (Uma) \ n" ;
92 cout<<" 4 I n s e r i r Aulas Dadas\n" ;
93 cout<<" 0 V o l t a r \n" ;
94 cout<<" Opcao > " ;
95 c i n >>opcao ;
96 } while ( opcao <0 | | opcao >4);
97 c i n . i g n o r e (IGNORE, \n ) ;
98 return opcao ;
99 }
100

101 int menu ( )


102 {
103 int opcao ;
104 do
105 {
106 cout<<"\n\nALGORITMIA E PROGRAMACAO"<<e n d l ;
107 cout<<" 1 Turmas \n" ;
108 cout<<" 2 Alunos \n" ;
109 cout<<" 0 S a i r \n" ;
110 cout<<" Opcao > " ;
111 c i n >>opcao ;
112 } while ( opcao <0 | | opcao >2);
113 c i n . i g n o r e (IGNORE, \n ) ;
114 return opcao ;
115 }
116

117 void manutencaoAlunos (TURMA t [ ] , int &n )


118 {
119 int opcao ;

89
ISEP/DEI - Jorge Santos e Paulo Baltarejo

120 do
121 {
122 opcao=menuAlunos ( ) ;
123 switch ( opcao )
124 {
125 case 1 :
126 break ;
127 case 2 :
128 break ;
129 case 3 :
130 break ;
131 case 4 :
132 break ;
133 case 5 :
134 break ;
135 }
136 } while ( opcao ) ;
137 }
138

139 void manutencaoTurma (TURMA t [ ] , int &n )


140 {
141 int opcao ;
142 do
143 {
144 opcao=menuTurmas ( ) ;
145 switch ( opcao )
146 {
147 case 1 :
148 break ;
149 case 2 :
150 break ;
151 case 3 :
152 break ;
153 case 4 :
154 break ;
155 }
156 } while ( opcao ) ;
157 }

1.14 Programas de grandes dimenses


Nos exemplos apresentados at esta parte, o cdigo de cada programa est escrito
num s ficheiro com a extenso ".cpp". No entanto, quando os programas so de
grandes dimenses, uma boa prtica dividilos em ficheiros de menor dimenso.
Esta, diviso traz enormes vantagens: embora a no entanto obriga a alguns cuida-
dos. Como vantagem, pode-se referir a manuteno do programa, isto , mais
fcil analisar uma ficheiro com 100 linhas de cdigo do que com 10000. Por outro,
lado podese agrupar o cdigo que de alguma forma esteja relacionado nos mesmos
ficheiros, levando, portanto, criao de mdulos. A criao de mdulos permite a
reutilizao desses mdulos noutros programas. Como desvantagem, podese referir

90
Apontamentos de Programao C/C++

a necessidade de gerir as referncias a variveis externas, a incluso recursiva de m-


dulos entre outros. Esta separao em mdulos obriga a que a compilao de cada
mdulo. Por um lado, pode ser considerado uma desvantagem porque necessrio
compilar todos os mdulos separadamente, por outro lado, pode ser considerado
uma vantagem, uma que compilado, s necessrio voltar a compilar caso o mdulo
tenha sido alterado.

1.14.1 Diviso em mdulos


Um mdulo, geralmente, consiste em dois ficheiros: um ficheiro de cabealhos com
a extenso ".h" e outro com a implementao (cdigo) com a extenso ".cpp" ou
"cc". Por uma questo de simplicidade, geralmente os nomes dos dois ficheiros so
iguais, variando apenas a extenso. Um aspecto a ter em considerao, que
necessrio fazer o incluso do ficheiro de cabealhos no ficheiro de cdigo (ver figura
1.18).

vectores.h vectores.cpp
#include<iostream.h>
#define MAX 50 #includevectores.h
void lerVector(int v[],int n);
int maiorItemVecint v[],int n); void lerVector(int v[],int n)
... {
for(int i=0;i<n;i++){
cin>>v[i];
}
}

int maiorItemVec(int v[],int n)


{
...

Figura 1.18: Representao grfica de um mdulo

Quando um programa dividido em mdulos, por vezes existe a necessidade


de num determinado mdulo invocar funes ou aceder a variveis definidas nou-
tros mdulos. Este problema resolvido atravs da directiva de prprocessador
#include. No entanto, este mecanismo de incluso de ficheiros pode originar erros
de linker uma vez que pode acontecer que um ficheiro de cabealho seja includo
noutro mais do que uma vez. Na figura 1.19 ilustrado este problema. O ficheiro
appMain.cpp faz a incluso de dois ficheiros (vectores.h e matrizes.h) sendo que
por sua vez cada um deles faz a incluso do ficheiro defs.h. Ora, o prprocessador
ir incluir no ficheiro appMain.cpp duas vezes o contedo do ficheiro defs.h), o que
dar origem a um erro de linker .
A resoluo deste problema pode ser feita atravs da directiva de prprocessador
#if (incluso condicional). O #if avalia uma expresso inteira e executa uma aco
baseada no resultado (interpretado como true ou false). Esta directiva sempre
terminada com a palavra #endif. Entre #if e #endif podero estar as directivas
#else e #elif. Outras formas da directiva #if so:
[ifdef <identificador>] verifica se o identificador est definido com uma directiva
define.

91
ISEP/DEI - Jorge Santos e Paulo Baltarejo

defs.h
#define MAX 50
#define SIZE 100
struct ponto
{
float x,y,z;
};
...

vectores.h
matrizes.h
#include defs.h #include defs.h
void lerVector(int v[],int n); void lerMatriz(int v[],int n);
int maiorItemVec(int v[],int n); int maiorItemMatriz(int v[],int n);
.. ..

appMain.cpp
#include vectores.h
#include matrizes.h
int main()
{
...

Figura 1.19: Incluso de um ficheiro

[ifndef <identificador>] verifica se o identificador no est definido com uma di-


rectiva define.
Por exemplo, a seguir define-se uma constante que contenha o nmero de bits
de um inteiro que possa ser compilado correctamente em MS-DOS no compilador
"Turbo C"no Unix.

#ifdef TURBOC
#define INT_SIZE 16
#else
#define INT_SIZE 32
#endif

Portanto, para resolver o erro do linker necessrio alterar os ficheiros de


cabealho defs.h, vectores.h e matrizes.h. A figura 1.20 apresenta uma soluo.
A desvantagem da necessidade da compilao separada dos mdulos, facilmente
supervel atravs de "makefiles"ou com a utilizao de uma Ambiente Integrado de
Desenvolvimento.

92
Apontamentos de Programao C/C++

defs.h
#ifndef DEF_H
#define DEF_H

#define MAX 50
#define SIZE 100
struct ponto{
float x,y,z;
};

#endif

vectores.h matrizes.h
#ifndef VECTORES_H #ifndef MATRIZES_H
#define VECTORES_H #define MATRIZES_H

#include defs.h #include defs.h


void lerVector(int v[],int n); void lerMatriz(int v[],int n);
int maiorItemVec(int v[],int n); int maiorItemMatriz(int v[],int n);
.. ..
#endif #endif

appMain.cpp
#include vectores.h
#include matrizes.h
int main()
{
...
}

Figura 1.20: Incluso de um ficheiro (directivas de pr-processamento)

93
ISEP/DEI - Jorge Santos e Paulo Baltarejo

94
Bibliografia

[CCT, 2001] CCT. C Programming - Foundation Level, Training Manual & Exer-
cises. Cheltenham Computer Training, Gloucester/UK, 2001.
[CPP, ]

[Kernighan e Ritchie, 1988] Brian W. Kernighan e Dennis M. Ritchie. The C Pro-


gramming Language, Second Edition. Prentice Hall, Inc., 1988.
[Mosich, 1988] D. Mosich. Advanced Turbo C Programmers Guide. Wiley, John &
Sons, 1988.
[Sampaio e Sampaio, 1998] Isabel Sampaio e Alberto Sampaio. Fundamental da
Programao em C. FCA- Editora Informtica, 1998.
[Stroustrup, 2000] Bjarne Stroustrup. The C++ Programming Language. Addison-
Wesley Pub Co, 3rd edition edition, February 2000.

95

Você também pode gostar