,
SUMARIO
IX
X Treinamento em Linguagem C++
Capítulo 2 Operadores . ... ... ... .. .. ... ... .... .. ... .. ... .. .... . ........ . 34
Operador de atribuição: = . ..... . .. . .. . ........ . ...... . .. . ............ . .. . . 34
Operadores aritméticos: + - * I % . .. . .. .. .. . . .. .. . .. . ... . .. . . .. .. . .. . .. .. .. 35
Precedência .. . .. . .. . .. .. . .. .. . .. . .. . .. .. . .. .. . .. . ... . .. . . .. .. . .. . ...... 36
O operador menos unário: - ............................................... 37
Lendo com cin e o operador de extração >> . . .. .. . .. . .. .. .. . . .. .. . .. . .. . ... 37
Múltiplas entradas com cin . .. .. .. . .. .. .... . . .. .. . .. .. .. . .. . . .. .. . .. .. .. 38
O programa que adivinha a soma de cinco números ............... . . . .... 39
Sumário XT
Capítulo 3 Laços .. ... ... .. .... .. ... ... . .... .. ........ ... .. .......... .. .. 63
O laço for . . ............ . ........ ... .... . .. . .. . .. .. . o o •• • ••••• • •• •• • o • •• •• 63
Sintaxe do laço for ... . . ........... . . o • •••• o ••• •• o • o ••••••••••••••••••• o 64
Variáveis declaradas na instrução for .................................... 66
Flexibilidade do laço for . .. . . .. .. . .. .. .. . . .. ..... .. . .. .. . . .. ..... . .. .. .. 67
O operador vírgula ....... o ••••• o •••••••••• 67 o •••• • •• o ••••••••••••••••••••
Capítulo 4 Comandos de Decisão .. ... .. ... ... ... .. ... .. ... ... ... .. .... .. 87
O comando if . .. .. . ..... .. . .. .. . ......... . . .. ..... . ... . .. . . .. ..... . ... . .. 87
Sintaxe do comando if ........ .. . . .. . ......... . .. ..... .. . ..... . .. . ... . .. 88
O programa que conta zeros .. . .. . .. ... ....... . .. . ............ . .. . .. ... . 88
Implementando um algoritmo . .. .. . .... .. .. . . .. .. . ...... .... . .. .. . .. .. .. 89
O comando if-else ................................................. . ...... 90
Sintaxe do comando if-else ............................................. 91
O programa que conta zeros modificados ...... . .. . ............ . .. . ...... 92
Um tabuleiro de xadrez .. . .. . .. .. . .. .. . .. . .. . ...... . .. .. .... .. .. . . . .. .. . 92
O jogo de cara ou coroa ................................................. 94
Desenhando linhas ................ ... ............. . .............. .. .... 96
Comandos if aninhados ...... . .................. .. ..................... 97
Usando operadores lógicos ............................................. 101
Os comandos break e continue .. . .. . ..... . ..... . ..... .. .. . .. .. . . .. . .. . .. . 102
O comando continue .. .. .... . .. . ...... . ..... .... ..... . ........ .. .. . .. . 104
O comando goto . . .. .. .. . .. . .. . .. . ... . .. . .. . ........ . .. . .. .. . .. . .. .. . .. . 105
O comando switch ............... . ............ " ......................... 106
Sintaxe do comando switch ............ . . ... . ................. . .. .. .. . . 106
O programa DIASEMAN.CPP .... ...... . .............. . ............ . .. . 107
O programa CALC.CPP modificado .. .. . .. . .. .. . .. . .. .. . .. . . .. . .. . .. .. . 109
Casos sem break em comandos switch .. . .. . .. . .. .. . .. . . .. . .. . ...... . .. . 110
Revisão . .. . .. .. . .. . .. . .. .. . .. .. . .. . .. . ... . .. . .. . .. . ... . .. . .. . .. . .. . .. . . . 111
Exercícios . . ...... o • o •• o • ••••••••• o • o o ••••••• o • o o • o • o •••••••• o • o •• o • o o o o • 112
Capítulo 7 Estruturas . .. ......... .. .... ... ... .... .. . .... ... .. ... ... .. .. . 237
Criando novos tipos de dados com struct . .................. . .. . .. . ...... . . 238
Definindo a estru tura ... . . ..... . .. . ... . . .. ..... . ... . . .. .. . .. .. . . .. .. .. . .. 239
Declarando uma variável do tipo definido ... . .. . . .. . . ..... . .... ........... 240
Acessando os membros da estrutura .. .. .. . .. . ..... . .. . .. . .. .. .... .. .. . .. . 241
Combinando declarações ........ ......... ............. ................... 241
Inicializando estruturas .................. ....... . ........ . ...... . ...... . . 242
Atribuições entre estruturas ....... . ...... . ........ . .. .... ............ . .. . 243
Operações entre estruturas . ..... . .. . . .. .. . .. . .. .. . .. . .. .. . .. . .... .. . .. .. . 243
Estruturas aninhadas .... . .. . .. . .. . ... . .. . .. . ........ . .. . .. . .. . ...... . .. . 244
Inicializando estruturas aninhadas . . ... . .. . .. . .. . .. . ... . .. . .... . .. .. .. . .. . 245
Passando estruturas para funções ............ ..... ....... .... ........ . .... 246
Passando estruturas para funções por referência .... .. .. . .. . .. . .. . ..... . .. . 248
Funções que retornam uma estrutura . . .. .. . .. .... . .. .. . .. .. . .. .... .. . .. .. . 249
Ma trizes de estruturas 9 t I • t I t t I ' t I I t ' • ' I • t I t • I t t I I t t I I t r ' t ' t t I I ' I t I I I I I I t 251
XVI Treinamento em Linguagem C++
Apêndice - Tabela ASCII ... .. ........ . ...... ... ........ ... ..... . . . ..... 292
,
PREFACIO
XVII
Página em branco
,.,
UMA VISAO GERAL
CLASSES E OBJETOS
XIX
XX Treinamento em Linguagem C++
ENCAPSULAR E ESCONDER
HERANÇA
CLASSE BASE
~
características
A B
CLASSES DERIVADAS
Da mesma forma que você pode criar uma biblioteca de funções úteis
a diversos programas, pode formar uma biblioteca de classes que poderão vir
a ser o núcleo de muitos programas.
O uso de uma biblioteca de classes oferece uma grande vantagem sobre
o uso de uma biblioteca de funções: o programador pode criar classes derivadas
de classes-base de biblioteca. Isto significa que, sem alterar a classe-base, é
possível adicionar a ela características diferentes que a tornarão capaz de
executar exatamente o que desejarmos.
Uma classe que é derivada de uma classe-base pode, por sua vez, ser
a classe-base de outra classe.
O uso de classes derivadas aumenta a eficiência da programação pela
não-necessidade da criação de códigos repetitivos. A uma função de biblioteca
não podemos adicionar outras implementações a não ser que ela seja reescrita
ou que tenhamos seu código-fonte para alterá-la e recompilá-la.
A facilidade com que classes existentes podem ser reutilizadas sem
serem alteradas é um dos maiores benefícios oferecidos por linguagens orien-
tadas ao objeto.
POLIMORFISMO ESOBRECARGA
,
CE UM SUBCONJUNTO DE C+ +
,
A ESTRUTURA BASICA DE UM PROGRAMA EM C+ +
{
i nstrução_ l i
i nstrução_2 i
instrução_n i
1
2 Treinamento em Li11guagem C++ Cap. 1
O PRIMEIRO PROGRAMA
void ma in ()
(
cout << 11
Prime ir o Programa 11
;
Este programa compõe-se de uma única função chamada main. O nome de uma
função pode ser qualquer um, com exceção de main, reservado para a função
que inicia a execução do programa.
Em todo programa C++, deve existir uma única função chamada main.
A função main marca o ponto de partida do programa. Se um programa for
constituído de uma única função, esta será main. O programa termina quando
for encerrada a execução da função main.
O TIPO void
A função main particular de nosso programa é do tipo void. O tipo void indica
que a função não tem valor de retorno, ou seja, não retoma nada. Os tipos de
funções serão abordados em detalhes no capítulo de funções.
Cap. 1 Conceitos básicos 3
CHAVES
Toda função C++ deve começar com uma chave de abertura de bloco I e deve
terminar com uma chave de fechamento de bloco }. As chaves delimitam o corpo
da função.
ESPAÇOS EM BRANCO
v o i d main() {
cout <<
"Primeiro Programa "
•
'
}
INSTRUÇOES DE PROGRAMA
,
O PRE-PROCESSADOR C+ +
A DIRETIVA #include
,.,
ARQUIVOS DE INCLUSAO
O ARQUIVO iostream.h
Note que o objeto cout não imprime numa nova linha automaticamente.
A impressão é colocada na posição atual do cursor. Se desejar, você deve inserir
um caractere de nova linha explicitamente.
O caractere de nova linha não pode ser inserido diretamente pelo teclado.
Por que não usar a tecla [ENTER]?
Porque, se você pressionar a tecla [ENTER] em alguma posição na frase
que deve ser impressa, o processador de textos que edita o seu programa-fonte
abandonará a linha atual e passará para uma nova linha, deixando a linha
anterior inacabada, e o objeto cout não o tomará como parte da impressão.
,
CODIGOS ESPECIAIS
Além da tecla [ENTER], vários outros caracteres não podem ser digitados do
teclado para dentro do nosso programa. Esses caracteres que não podem ser
obtidos diretamente do teclado são codificados em C++ por meio da combinação
do sinal \ (barra invertida) com outros caracteres.
A tabela a seguir mostra esses códigos.
Vamos alterar o nosso exemplo para que a frase seja impressa numa nova linha
toda vez que o programa for executado. Para isso, é necessário inserir um código
de nova linha no início da frase a ser impressa. Códigos especiais podem ser
colocados em qualquer lugar dentro de uma cadeia de caracteres.
#include <ios tream . h>
ma in (}
{
,
CONSTANTES NUMERICAS
Uma constante tem valor fixo e inalterável. Números constantes em C++ podem
ser escritos nas seguintes bases numéricas:
,
VARlAVEIS
int numl;
num1=44;
c o ut << '' \nO prime iro nóme ro é '' << numl ;
in t num2;
num2 =88;
cout << " \nO segundo nómero é " << num2 ;
DECLARAÇÕES DE VARIÁVEIS
As instruções
int numl;
int num2;
12 Treinamento em Linguagem C++ Cap. 1
C++ não funciona se você não declarar suas variáveis. As variáveis podem ser
declaradas em qualquer lugar do programa.
,
TIPOS DE VARIAVEIS
,
INICIALIZANDO VARIAVEIS
int evento - 5;
char corrida - 'C';
f l oat tempo - 27. 25 ;
A saída será:
O tempo vitorioso na eliminatoria C
da competição 5 foi 27 . 25 .
Este programa utiliza os três tipos de variáveis mais comuns: int, char
e float.
3 bytes 1 byte
+ 0.12345 5
Observe que uma variável do tipo long int ocupa o mesmo espaço que
uma variável do tipo float, mas são tipos diferentes, já que a forma de
armazenamento é distinta. Lembre-se: um tipo de variável define um tamanho
e uma forma de armazenamento.
16 Treinamento em Linguagem C++ Cap. 1
unsigned j=65000 i
.
int i = ] i
A saída será:
Var unsigned - 65 000
Var int - - 536
é feita por um processo de duas etapas. No momento, você não precisa entender
como é feita essa conversão. No segundo volume deste livro, voltaremos a este
assunto.
Essa explicação vale também para o bit de ordem superior de outros
tipos de variáveis. Por exemplo, o tipo unsigned char tem um tamanho de um
byte e pode armazenar números entre O e 255, enquanto o tipo char armazena
números entre -128 a 127.
,
NOMES DE VARIAVEIS
PALAVRAS-CHAVE DE C++
- cs - loadds switch
default long template
do - near this
double near typedef
.
_ds new umon
else operator unsigned
enum _pascal virtual
- es pascal void
_export private volatile
extern protected while
Cap. 1 Conceitos básicos 19
..
MANIPULADORES DE TAMANHO DE CAMPOS NA IMPRESSAO
,
TAMANHO DE CAMPOS COM NUMEROS INTEIROS
Eis a saída:
Lap is 45
Borracha 2345
Canetas 420
Ca d e r nos 8
Fi t as 13 050
cout << 1\n l << "Ca dernos H<< setw (12) << cad ;
c out << \n << "Fitas
I I 11 << s e tw(12) << fit ;
}
Eis a saída:
Lap i s 45
Bo rracha 2345
Canetas 420
Cadernos 8
Fitas 1 305 0
Eis a saída:
Lap i s ... .. ..... 45
Borracha ........ 234 5
Canetas ......... 4 20
Ca dernos ........... 8
Fitas ....... 13050
}
22 Treinamento em Linguagem C++ Cap. 1
Eis a saída:
Lapis 4 . 88
Borracha 234 . 54
Canetas 42 . 04
Cadernos 8 . 00
Fitas 13 . 05
Eis a saída:
OBJETO CO DIGO
Lapis WQR
Borracha ASO
Canetas KPX
Cadernos FJI
Fitas TYE
,
MANIPULADORES DE BASES NUMERICAS
int n =65 ;
cout << ' \n ' << ''Hexadecimal '' << hex << n ;
cout << , \n , << "Oc tal " << oct << n ;
cout << ' \n ' << "Decimal " << dec << n ;
}
Eis a saída:
Hexadecima l 4 1
Oc tal 101
Decimal 65
,
IMPRIMINDO CARACTERES GRAFICOS
Como você provavelmente sabe, todo caractere (letra, dígito, caractere de pontua-
ção etc.) é representado no computador por um número. O código ASCII dispõe
de números de Oa 127 (decimal) abrangendo letras, dígitos de O a 9, caracteres de
pontuação e caracteres de controle como salto de linha, tabulação etc.
24 Treinamento em Linguagem C++ Cap. 1
)
Cap. 1 Conceitos básicos 25
A saída será:
Carro
Cami nhão
A saída será:
26 Treinamento em Linguagem C++ Cap. 1
C9 CD BB
fF
--
C8 CD BC
""
REVISA O
1. Todo programa em C++ deve ter uma função chamada main(), que é a
primeira função a ser executada. O programa termina sua execução quando
é encontrada a chave que fecha o corpo da função main().
2. O pré-processador é uma linguagem para o compilador C++. Suas instru-
ções são chamadas diretivas.
3. A diretiva #include causa a inclusão de outro arquivo em nosso programa-
fonte.
4. Arquivos de inclusão são textos escritos em caracteres ASCII normais.
S. O arquivo iostream.h contém as definições básicas de impressão em vídeo
e leitura de teclado.
Cap. 1 Conceitos básicos 27
13. O tipo de uma variável define seu tamanho de memória em bytes e a forma
como um valor deve ser armazenado e recuperado.
14. Os cinco tipos básicos de variáveis em C++ são: char, int, float, double e
void.
15. Os modificadores de tipo são utilizados para alterar o tamanho de um tipo
de variável ou para alterar a interpretação do seu bit mais significativo.
16. Os três modificadores de tipo em C++ são: long, short e unsigned.
,
EXERCICIOS
2. Qual será a impressão obtida por cada uma das seguintes instruções?
Assuma que elas fazem parte de um programa completo.
a) cout << "\n\tBom Dia ! Shirley.";
cout << ' \n ' << ' \t ' << '\''' <<
" Prime i r o progr ama";
cou t << ' \ " ' ;
}
Cap. 1 Conceitos básicos 29
b) 2130
c) -123
d) 33.28
e) Ox42
f) 0101
g) 2.0e30
h) '\xdc'
i) '\"'
j) '\ \'
k) 'F'
1) o
m) '\0'
n) "F"
o) -4567.89
e) int
f) A123
g) x**x
h)- -A
i) y-2
j) OOFIM
k) \meu
1) *y2
10. Quais das seguintes instruções são corretas?
a) int a;
b) float b;
c) double float c;
d) unsigned char d;
e) unsigned e;
f) long float f;
g) long g;
11. O tipo float ocupa o mesmo espaço que ___ variáveis do tipo char.
Cap. 1 Conceitos básicos 31
12. Verdadeiro ou Falso: tipos de variáveis long podem conceber números não
maiores que o dobro da maior variável do tipo int.
13. Qual o trecho de programa que inicializa a variável x?
a) int Xi x=5i
b) int x=5 i
c) int x,y=5i
d) X=Y i
c) linkeditor;
d) programa.
a) cout
Programa " i
d) cout
<<
21. Reescreva o programa que desenha uma moldura na tela para que ele
desenhe uma moldura similar, mas com quatro caracteres de largura e
quatro caracteres de altura. Use o caractere 11, de código BA hexa, para
complementar a moldura.
Cap. 1 Conceitos básicos 33
22. Escreva um programa que contenha uma única instrução e imprima na tela:
um
dois
tres
OPERADORES
C++ é uma linguagem rica em operadores, em torno de 50. Alguns são mais
usados que outros, como é o caso do operador de atribuição e dos operadores
aritméticos que executam operações aritméticas .
...
OPERADOR DE ATRIBUIÇAO: =
tem o valor 7.
Talvez não seja tão simples você compreender que
X = 3
34
Cap. 2 Operadores 35
tem o valor 3. Uma expressão de atribuição tem o valor atribuído. Por esse
motivo, podemos escrever
e y terá valor 3.
Em C++, expressões desse tipo são chamadas de atribuições múltiplas.
,
OPERADORES ARITMETICOS: + - *I %
C++ oferece cinco operadores aritméticos binários (que operam sobre dois
operandos) e um operador aritmético unário (que opera sobre um operando).
São eles:
Binários
+ Soma
Subtração
* Multiplicação
I Divisão
% Módulo
Unário
Menos unário
Estes operadores representam as operações aritméticas básicas de soma,
subtração, divisão, multiplicação e módulo.
O operador módulo opera somente com operandos inteiros e dá como
resultado o resto da divisão do inteiro à sua esquerda pelo inteiro à sua direita.
36 Treinamento em Linguagem C++ Cap. 2
Por exemplo,
17%5
"
PRECEDENCIA
na expressão
n = z + y * x;
,
O OPERADOR MENOS UNARIO: -
,..,
LENDO COM cin E O OPERADOR DE EXTRAÇAO > >
O objeto cin (pronuncia-se "C in") manipula toda entrada do teclado por meio
do operador de extração >> que conecta a entrada de dados à variável que a
conterá. As definições necessárias ao uso de cin e >> estão no arquivo "ios-
tream.h". Veja um exemplo:
#include <iostream . h>
void ma in ()
{
cout << '' \nDigite a sua idade em anos : " ;
int anos;
cout << '' \nA sua idade em dias é: " << (anos * 365);
}
38 Treinamento em Linguagem C++ Cap. 2
O objeto cin faz com que o programa aguarde que você digite a sua
idade e pressione a tecla [ENTER] para finalizar a entrada.
O operador >> toma o valor do objeto "streams" à sua esquerda e o
coloca na variável à sua direita.
,
MULTIPLAS ENTRADAS COM cin
Eis a saída:
C: \>MEDIA
Dig it e as notas das 4 provas : 5.5 7 . 5 3 .0 6.0
MÉDIA : 5 . 5
,
O PROGRAMA QUE ADIVINHA A SOMA DE CINCO NUMERO$
r = 19998 + x ;
cout << " \ nO resul tado da soma é : " << r ;
cout < < " \nDigit e o segundo núme r o : ";
c l' n >> x;
cout << '' \nO me u número é : '' << 9999 - x ;
cout << '' \nDigite o quarto número : '';
.
c ~ n >> x ;
cout << '' \nO meu número é : '' < < 9999 - x ;
}
O meu n úmero é : 77 66
,
MANIPULADORES DE BASES NUMERICAS: dec hex oct
O QUALIFICADOR const
A p alavra-ch ave const assegu ra que a variável associad a não será alter ada em
todo o programa. Esse q ualifícador é indicado para declarar valores constantes.
Veja um exemplo de seu uso:
#include <iostream. h>
void ma in ()
{
•
double ralo ;
...
CONVERSOES DE TIPOS E OOPERADOR DE MOLDE
ch = getche() ;
Eis a saída:
Press i one uma tec l a X
A tecla sucessora ASCII é Y
,
COMENTAR/OS
11 Iníc io do pr ograma
void ma in ()
{
char ch ; !* declaração de variável * /
cout << " \nPressione uma t e cla ";
cout << " \nA t e cla sucessora ASCII é " << char(ch+l) ;
)
44 Treinamento em Linguagem C++ Cap. 2
SINTAXE
Comentários são delimitados por I* e *I, podem ser escritos em várias linhas,
numa única linha ou na mesma linha de uma instrução C++. Asteriscos dentro
de comentários podem ser colocados livremente. Por exemplo:
!* ** * *********** ** ******** * ** * ********* ************ * *
* Este p rograma mostra o u so da fu nção ge t che( ) , *
* do operador de molde e o uso das duas formas *
* de escrever comentários em C+ +. *
**************************** * *********************** /
é equivalente a
++x ; 1/ adici ona 1 a x
que é equivalente a
X++ ; 11 adiciona 1 a x
cout << ''\ nN= '' << n << '' X= " << x;
A saída será
N=6 X=6
A saída será
N=6 X=S
é equivalente a
-- x ;
que é equivalente a
x-- ;
PRECEDÊNCIA
é equivalente a
x = a * (b++) ;
é completamente correta.
Você pode ser iludido ao tentar imprimir urna mesma variável diversas
vezes usando o operador de incremento ou decremento. Por exemplo:
n = 5;
cout << n << ' \ t '
<< ( n+l } << ' \t '
<< (n++} ;
n - i* (i+l) +( ++i ) ;
n = 24
int i= 3 , n;
n = 16
n - i* (i+l) +( i ++);
n - 15
Cap. 2 Operadores 49
n = 15
int i=3~ n;
6 5 4
, ,.
OPERADORES ARITMETICOS DE ATRIBUIÇAO: += --- * = I= %=
Exemplos:
• • •
l += 2 i equivale a l -- l + 2;
X *-- y+l ; equivale a X - X * (y+ 1 ) i
t I= 2 . 5 i equivale a t - t I 2.5;
p %= 5 ; equivale a p - p % 5;
d - - 3; equivale a d -- d - 3;
media I = 4 .0;
'
cou t << " \nMEDI A: " << me d i a ;
}
>=maior ou igual
< menor
== igual
! = diferente
Nos próximos capítulos, falaremos sobre laços e comandos de decisão.
Estas construções requerem que o programa pergunte sobre relações entre
variáveis ou expressões. Operadores relacionais são o vocabulário que o pro-
grama usa para fazer essas perguntas.
Em C++, não existe um tipo de variável chamado "booleana", isto é,
que assuma um valor verdadeiro ou falso. O valor zero (O) é falso; qualquer
valor diferente de zero é verdadeiro e é representado pelo inteiro um (1). Assim,
em C++ toda expressão ou variável têm um valor verdadeiro ou falso.
#inc l ude <i os t r e a m.h>
v oid ma in ()
{
int verdadei r o ,fa lso ;
A saída será
Verdadeiro 1
Falso IJJ
J\
PRECEDENCIA
A saída será
(jJ
1
Cap. 2 Operadores 53
,
OPERADORES LOGICOS: && II I
•
Alguns exemplos:
(di a==7 && mes==6 } // verdadeiro se dia for 7 e mes for 6
(op== 'S' I I op== 's') //verdadeiro se op f or Sou s
( !masculino ) / /verdadeiro s e masculino for 0
Outros exemplos:
! 5 // Lê-se '' não verdadeiro '' ou 0 .
1 II 2
X && y
a < b I I a ==c
a >= 5 && x <= 6*y
54 Treinamento em Linguagem C++ Cap. 2
!x
I , . I
. J
! (a +3 )
,
O OPERADOR CONDICIONAL TERNARIO: '·••
O operador condicional possui uma construção um pouco estranha. E' o único
operador C++ que opera sobre três expressões. Sua sintaxe geral possui a
seguinte construção:
e xp l .
? e xp2 .. e xp3
a variável que contém o maior valor numérico entre a e b será atribuída a max.
Outro exemplo:
abs = (x > 0 ) ? x : - x ; // abs é o v a l or abso l uto d e x
A instrução
cout << ( (x%2)? "Impar" : " Par ");
imprime "Impar " se x for um número ímpar, caso contrário imprimirá "Par".
Cap. 2 Operadores 55
I\
OPERADOR TIPOS
- Menos unário
+ Incremento prefixado ou pós-fixado
-- Decremento prefixado ou pó-fixado
I
• Lógico NÃO
* Multiplicação arihnética
I Divisão aritmética
% Módulo aritmético
+ Mais aritmético
- Menos aritmético
< Menor relaciona}
<= Menor ou igual relaciona!
> Maior relacional
>= Maior ou igual relaciona!
--
-- Igual relaciona}
,_
.- Diferente relaciona!
&& E lógico
II OU lógico
..
?· Condicional
-- Atribuição
*-- Aritmético de atribuição (vezes)
I= Aritmético de atribuição (divide)
0
/o= Aritmético de atribuição (módulo)
+= Aritmético de atribuição (soma)
-- Aritmético de atribuição (menos)
56 Treinamento em Linguagem C++ Cap. 2
~ , ,
OPERADORES: AVALIAÇAO LOGICA OU NUMERICA
,.,
REVISA O
,
EXERCICIOS
c) %;
d) <;
e) <<.
2. Uma expressão:
a) geralmente avalia um valor numérico;
b) sempre ocorre fora de qualquer função;
c) deve ser parte de uma instrução;
58 Treinamento em Linguagem C++ Cap. 2
b) y -- (5+ 1) / 2*3;
•
c) 1 - j = (2+3)/4 ;
d) a -- 3+2 *(b=7 /2 );
e) c -- S+l fll%4/2;
b) X + ++y
a) a += b+c;
b) b *= c - d + 2;
c) d !\--
o- a + a + a;
d) d -= c -= b - = a;
e) a += b+ = c+ = 7;
Cap. 2 Operadores 59
b) a > b
c) a =< b
d) a > = b
e) -a - b
f) -a -- -- b
g) - a --
-- b
h) a -_,. b
i) - 8 5 . 2 > = (X * 45 . 3 + 32 . 34 )
j) a + b + c -x * -y
k) I a I + I b I ! = 16 + I w I
b) ! ( 1 > 2)
c) 3 --
-- 2
d) ! ( -5 )
e) I '
J
I
,_
.- I '
J
I
f) I '
J
I
., -_ I '
J
I
+ 2
g) I '
J
I
., -_ I '
J
I
--
-- I '
J
I
60 Treinamento em Linguagem C++ Cap. 2
X - 22345 ;
y - float (x) ;
c o ut << y ;
d) X y
e) X .1 -- y
• •
f) l + J + k -2 * -k
g) ! (n-j )
h) ! n - j
i) ! x*! x
j) i&&j &&k
k) illj-3&& 0
m) i<j I l 2>= k
Cap. 2 Operadores 61
n) l• --2
--
I
I
I )•
I
--4
--
I
I
I
I
k--5
--
o) i =2 1 I j ==4 11 k==5
a) ! (i==j)
b) !(i+ 1 < j - 2)
c) .
I ( ~
• < j && n < m)
d) .I ( ~
• < 1 11 j < 2 && n < 3)
16. Escreva uma expressão lógica que resulte 1 se o ano for bissexto e O se o
ano não for bissexto.
Um ano é bissexto se for divisível por 4, mas não por 100. Um ano também
é bissexto se for divisível por 400.
17. Faça um programa que solicite ao usuário o ano e imprima "Ano Bissexto"
ou "Ano Não-Bissexto" conforme o valor da expressão do exercício 15.
Utilize o operador condicional.
18. Escreva um programa que solicite ao usuário a altura e o raio de um cilindro
circular e imprima o volume do cilindro. O volume de um cilindro circular
é calculado por meio da seguinte fórmula:
Vol = 3 . 14159 2 * r aio * raio * altura
19. Num cercado, há vários patos e coelhos. Escreva um programa que solicite
ao usuário o total de cabeças e o total de pés e determine quantos patos e
quantos coelhos encontram-se nesse cercado.
62 Treinamento em Linguagem C++ Cap. 2
20. Dois amigos jogam na loteria toda semana. Escreva um programa que
solicite com quanto cada um entrou em dinheiro e o valor do prêmio que
deve ser rateado em partes diretamente proporcionais às quantias com que
cada um entrou. O programa deve imprimir quanto receberá cada um se
eles ganharem.
21. A importância de 780.000,00 será dividida entre os três primeiros colocados
de um concurso, em partes diretamente proporcionais aos pontos consegui-
dos por eles. Construa um programa que solicite o número de pontos dos
três primeiros colocados e imprima a importância que caberá a cada um.
22. Sabendo que o latão é obtido fundindo-se sete partes de cobre com três
partes de zinco, faça um programa que solicite quantos quilos de latão ele
quer produzir e imprima quantos quilos de cobre e de zinco são necessários.
23. Uma firma contrata um encanador a 20.000,00 por dia. Crie um programa
que solicite o número de dias trabalhados pelo encanador e imprima a
quantia líquida que deverá ser paga, sabendo-se que são descontados 8%
para imposto de renda.
24. (Difícil) Faça um programa que solicite um caractere do teclado por meio
da função getch(); se for uma letra minúscula imprima-a em maiúsculo,
caso contrário imprima o próprio caractere. Use uma expressão condicional.
Capítulo 3
LAÇOS
Laços são comandos da linguagem C++ úteis sempre que uma ou mais instru-
ções devam ser repetidas enquanto uma certa condição estiver sendo satisfeita.
Em C++ existem três estruturas de laços:
for
while
do - while
O LAÇO for
O laço for é geralmente usado quando queremos repetir algo um número fixo
de vezes. Isto significa que utilizamos um laço for quando sabemos de antemão
o número de vezes a repetir.
O exemplo seguinte imprime uma linha de 20 '*' utilizando um laço for
na sua forma mais simples.
// f ordemo.cpp
#include <iostream . h>
void ma in()
{
63
64 Treinamento em Linguagem C++ Cap. 3
int i;
f o r ( i =0 ; i < 2 0 ; i++)
cout << ' * ';
}
Ponto-e-vírgula
void ma in ()
{
int i;
.
for(i=1 • J. <= 1Q) • Í++)
' '
•
cout << '\n' << setw{3 ) << l << setw{5) << (i*6) ;
}
Eis a saída:
1 6
2 12
3 18
4 24
5 30
6 36
7 42
8 48
9 54
1lll 60
void ma i n ()
{
66 Treinamento em Linguagem C++ Cap. 3
int i;
for(i =10 . I
•
l >= 1 . i -- )
I
Eis a saída:
10 6(/J
9 54
8 48
7 42
6 36
5 3(/)
4 24
3 18
2 12
1 6
Nos exemplos anteriores, utilizamos o laço for na sua forma mais simples. Isto
é, a primeira expressão para inicializar a variável, a segunda para expressar um
limite e a terceira para incrementar ou decrementar a variável.
Entretanto, elas não estão restritas apenas a estas formas. Exemplos de
outras possibilidades são mostrados a seguir.
,
O OPERADOR VIRGULA
Qualquer uma das expressões de um laço for pode conter várias instruções
separadas por vírgulas. A vírgula, neste caso, é um operador C++ que significa
"faça isto e depois isto". Um par de expressões separadas por vírgula é avaliado
da esquerd a para a direita.
11 Mostra o u s o do ope rador v í rgula no l aço for
11 Imprime os n úmeros de 0 a 98 de 2 e m 2
#inc l ude <iostream . h >
void ma in ()
{
.
f or (int i=0 , in t j =0 ; (i+j ) < 100 ; 1++ , j ++ )
c o u t << (i + j ) < < " " ;
}
USANDO CARACTERES
Qualquer uma das três expressões de um laço for pode ser omitida, embora os
pontos-e-vírgulas devam permanecer. Se a expressão de inicialização ou a de
incremento forem omitidas, serão simplesmente desconsideradas. Se a condição
de teste não estiver presente, será considerada permanentemente verdadeira.
11 Codifica a e ntrada
#include <iostream . h>
#include <conio . h>
vo i d ma i n()
{
char c h;
e ch teria um valor de O ou 1.
UM LAÇO INFINITO
Um laço infinito é aquele que é executado sempre, sem parar. Um laço infinito
sempre tem a expressão de teste verdadeira; um modo de parar sua execução
é desligando o computador.
f or ( ; ; } cout << '' Laço Infini t o '';
Outro exemplo:
f o r( int i= 0 ; i < = 100(/J •
I i - i+l )
.
I
, M
Se um laço for deve executar várias instruções a cada iteração, elas devem estar
entre chaves.
Sintaxe:
70 Treinamento em Linguagem C++ Cap. 3
fl oat soma = 0 . 0;
const int max = 10 ;
int i= S ;
{ I I Inicio do bloco
int i =15(/J ;
cout << i ; 11 Imprime 15(/J
} I I Fim do bloco
,
VISIBILIDADE DE VARIAVEIS DE BLOCO
Quando um laço for faz parte do corpo de outro laço for, dizemos que o laço
interno está aninhado.
Para mostrar esta estrutura, preparamos um programa que imprime a
tabuada do 2 ao 9.
11 Tabuada . cpp
11 I mprime a tabuada do 2 ao 9
# i nc l ude <ios t ream. h>
#include <i omani p . h>
v o i d ma in ()
{
for ( in t k= (lJ ; k< =l ,. k++ )
{
void ma in ()
{
getch() ;
}
Cnp. 3 Laços 75
Eis a saída:
C : \>NATAL
1\
/ <> \
/<<>>\
/<<<>>> \
/<<>>\
!<<<>>>\
!<<<<>>>>\
! <<<<< >>>>>\
!<<<<>>>> \
! <<<<<>>>>>\
/ <<<<<<>>>>>> \
/ <<<<<<<>>>>>>> \
!<<<<<<>>>>>>\
! <<<<<<<>>>>>>>\
! <<<<<<<<>>>>>>>>\
/<< <<<<<<<>>>>>>>>>\
FELIZ NATAL
E UM PROS PERO 199 4!
Observe que a variável j não existe fora do bloco onde ela foi declarada.
Assim, é necessário declará-la novamente em outros blocos que desejam utilizá-la.
76 Treinamento em Linguagem C++ Cap. 3
O LAÇO while
int cont=0;
Expressão de Incremento;
•
. '
l ++; // I ncremento
}
}
78 Treinamento em Linguagem C++ Cap. 3
i É CORRETO ! !
Voce acertou em 7 tentativas
Quer jogar no v a mente? (s/n) : n
Na instrução
char a d iv = rand( ) % 2 6 + ' a';
utilizamos uma nova função de biblioteca C++, a função rand (), que necessita
da inclusão do arquivo stdlib.h. Esta função retoma um inteiro aleatório entre
O e 32767.
A expressão "rand()% 26" resulta o resto da divisão do valor de rand()
por 26, que é um número entre O e 25. A este número é somado o caractere 'a'
para gerar uma letra minúscula aleatória.
OLAÇO do-while
do
{
i nstrução;
i ns t rução;
do
{
cout << " \n\ nDigite uma letra entre 'a' e 'z' : \n ";
char r esp;
whil e((resp=getch()) ! =adiv)
{
cout << r esp;
cout << '' é incorre t o. Te nte novamente\n'';
tentativas++ ;
}
,
cout << '\ n ' << resp << '' E CORRETO !!'';
cout << " \nVoce acertou e m " << tentativas
<< '' t e ntativas '';
cout << '' \ nQuer jogar novamente? ( s/n ) : '';
'"'
REVISA O
,
EXERCICIOS
c) chave de fechamento;
d) ponto-e-vírgula.
7. As três expressões que compõem a expressão do laço for são separadas por
-------------------- ·
8. Múltiplas expressões de incremento na expressão do laço for são separadas
por _________________
84 Treinamento em Linguagem C++ Cap. 3
)
cout << '' I IIIIII\n'';
}
Uma das tarefas fundamentais de qualquer programa é decidir o que deve ser
executado a seguir. Os comandos de decisão permitem determinar qual é a ação
a ser tomada com base no resultado de uma expressão condicional. Isto significa
que podemos selecionar entre ações alternativas dependendo de critérios de-
senvolvidos no decorrer da execução do programa.
C++ oferece três comandos de decisão:
i f
if - else
switch
O COMANDO if
87
88 Treinamento em Linguagem C++ Cap. 4
•
c1n >> a nos ;
if( anos< 30 )
cout << " \nVocê é muito jovem !";
SINTAXE DO COMANDO il
!/ CONTAZ.cpp
#inc l ude <i ostream.h>
#include <conio . h>
void ma in ()
{
char ch;
int cont= 0 ;
Cap. 4 Comandos de decisão 89
cout << " \nVocê d i gitou " << con t << " zeros ";
IMPLEMENTANDO UM ALGORITMO
Por exemplo:
32 = 1 + 3 + 5
62 = 1 + 3 + 5 + 7 + 9 + 11
82 = 1 + 3 + 5 + 7 + 9 + 11 + 13 + 15
90 Treinamento em Linguagem C++ Cap. 4
for(int i =l ; n > 0; n -- )
{
.
soma += 1 ;
i += 2 ·
'
}
O COMANDO il-else
instrução ;
instrução ;
}
I! CONTAZ . CPP
#include <i ostream . h>
#incl ude <conio .h>
void ma in ()
(
char ch ;
int cont=0 ;
UM TABULEIRO DE XADREZ
Veja a listagem:
!! XADREZ . CPP
#incl ude <iostream . h>
voi d ma i n ()
{
f or(int col=l;co1<=8;col++)
if( (lin+col)%2==0) // é número par ?
cout << '' \xDB \ xDB '';
else
cout << " ,
li •
C: \>XADREZ
94 Treinamento em Linguagem C++ Cap. 4
O laço for externo (da variávellin) move o cursor uma linha para baixo
a cada iteração até que lin seja 9. O laço interno (da variável col) move o cursor
na horizontal uma coluna por vez (cada coluna tem a largura de 2 caracteres)
até que seja 9. O comando if-else imprime ora quadrado cheio, ora quadrado
branco.
if( (rand()%2}==resp)
Cap. 4 Comandos de decisão 95
ganho++ ;
if (resp == 0)
cout << "Cara, você ganhou. \n" ;
else
cout < < "Coroa , v oce ganhou . \n ";
~
}
else
{
perda++;
if(resp==l)
cout << "Cara , você p e r deu . \ n n ;
else
cout << "Coroa , você perdeu . \n ";
)
}
Relatório Final :
Número de jogos que você ganhou : 5
Número de JOgos que você perdeu : 3
DESENHANDO LINHAS
O próximo exemplo utiliza caracteres gráficos para desenhar uma linha na tela.
A estrutura deste programa é semelhante à do programa XADREZ.CPP.
11 DI AGONAL . CPP
#include <iostream . h>
vo id ma in ()
{
f or( i nt lin= l; l in < 25 ; lin+ +)
fo r (int co l= l; col < 25; col ++)
i f(lin ==col)
cout << ' \xDB ';
else
cout << ' \ xB0';
cout << ' \n ' ;
}
}
Cap. 4 Comandos de decisão 97
Eis a saída:
COMANDOS il ANINHADOS
if ( X > y )
if ( y! =0 )
a = x/y ;
e ls e
a=y;
e l se
a =y ;
e lse
a =y ;
cout << 1
\ x DB 1
;
e l se
if ( col == 25 - lin )
cout < < 1
\ xDB 1
;
el s e
cout << I \ xB0 1 ;
}
}
Eis a saída:
100 Treinamento em Linguagem C++ Cap. 4
i f ( op == '+' )
cou t << nl + n2 ;
else
if( op == '- ' )
cout << nl - n2 ;
e lse
if ( op == * 1 1
)
vo id ma in ()
{
if( op --
-- ' + ' ) cout << nl + n2;
else if ( op ' -' ) cout << nl - n2 ;
else if ( op ' *' ) cout << nl * n2 ;
else if( op 'I ' ) cout << nl I n2 ;
}
int dia,mes;
else
caut << ' \ x B0 I;
caut << \n ' ;
I
}
}
11 CALC.CPP
#include <iostream.h>
void ma in ()
{
float nl ,n2;
char op ;
i f (n1==0.QJ) break ;
if ( op -- I +I )
cout << nl + n2 ;
e ls e if ( op I - I )
cout << nl - n2 ;
else if ( op -- I * I ) cout << nl * n2 ;
else if ( op I I I )
cout << nl I n2 ;
}
}
char ch ;
incr 1 =2 ;
cout << '' \n= , >ou< a " << adiv << " ? '';
}
cout << " \nO número é " << adiv ;
cout << " \ nCOMO SOU ESPERTO ! ! ! ! ";
}
O COMANDO continue
O comando continue força a próxima iteração do laço e pula o código que estiver
abaixo. Nos laços while e do-while, um comando continue faz com que o
controle do programa avalie imediatamente a expressão de teste e depois
continue o processo do laço. No laço for, é executada a expressão de incremento
e, em seguida, o teste.
O exemplo seguinte imprime os caracteres digitados no teclado que são
diferentes de dígitos.
//El i mina i mpressão de dígito s
#include <iostream . h>
#include <conio .h>
vo id ma in ()
{
char ch ;
while ((ch=getch()} ! ='X ' )
Cap. 4 Comandos de decisão 105
O COMANDO goto
goto erro ;
else
r = n/x;
• • • • •
. . . .. .
e rro :
c out << ''\ nERRO : d i v i são por zero '';
O COMANDO switch
-------- 1dois-pontos 1
Cap. 4 Comandos de decisão 107
i nstrução;
instrução ; Icorpo do terceiro caso
break ;
default : Idois-pontos
i nstrução;
ins t rução ; Icorpo do caso default
) Isem ponto-e-vírgula
Você não poderá usar uma variável nem uma expressão lógica como
rótulo de um caso. Pode haver nenhuma, uma ou mais instruções seguindo cada
caso. Estas instruções não necessitam estar entre chaves.
O corpo de um switch deve estar entre chaves.
Se o rótulo de um caso for igual ao valor da expressão do switch, a
execução começa nele. Se nenhum caso for satisfeito e existir um caso default,
a execução começará nele. Um caso default é opcional.
Não pode haver casos com rótulos iguais.
O PROGRAMA DIASEMAN.CPP
do
{
f !!< -
o -
7 '·
switch(f)
{
case (/):
cout << ''\ nDomingo'';
break;
case 1 :
cout << ''\nSegunda-feira ";
break;
case 2:
cout << " \nTerça - fe i ra'' ;
break;
case 3 :
cout << " \nQuarta-feira " ;
break;
case 4 :
cout << "\nQuinta -f eira " ;
break;
case 5 :
cout << ''\ nSexta - feira '';
break;
Cap. 4 Comandos de decisão 109
case 6 :
cout << '' \nSábado '';
}
} whi le ( getch (} != ESC) ;
}
switch(op)
{
case + I I :
cout << nl + n2; break ;
case I
•
- I •
cout << nl - n2; break ;
case * •I I •
cout << nl * n2; break;
case I I I :
cout << nl I n2 · break;
I
switch(op)
{
case ' + ' •
• cout << nl + n2 ; break ;
case ' - ' cout << nl n2 ; break ;
case 'X' •
•
...
REVISA O
,
EXERCICIOS
9. Um comando continue:
a) continua o programa após uma pausa;
b) desvia para o próximo caso de um switch;
c) permite a repetição contínua de um laço;
d) provoca a próxima iteração de um laço.
10. Verdadeiro ou Falso: A instrução goto é o método mais primitivo de
interromper o fluxo de um programa e é desaconselhada em programação
moderna.
11. Converta o fragmento seguinte para que utilize um laço for.
int i = 0;
l oop : cout << {i + +);
goto l oop ;
por
{ch > = ' 0' && ch <=' 9 ') ? continu e: cout << c h ;
b) i f ( i = 8)
cout << i << (i+2 ) << ( i+3) ;
default :
cout << "Certamente está quente!";
break;
}
18. Escreva um programa que encontre o menor inteiro positivo n que satisfaça
as seguintes condições:
n I 3 = x inteiros e resto 2
n I 5 - y inte i ros e resto 3
n I 7 - z inteiros e resto 4
117
118 Treinamento em Linguagem C++ Cap. 5
..
CHAMANDO UMA FUNÇAO
Um programa pode conter uma ou mais funções, das quais uma delas deve ser
main(). A execução do programa sempre começa emmain() e, quando o controle
do programa encontra uma instrução que inclui o nome de uma função, a função
é chamada.
Chamar uma função é o meio pelo qual solicitamos que o programa
desvie o controle e passe para à função, execute suas instruções e depois volte
à instrução seguinte à da chamada a função.
Você já escreveu programas que chamam funções. Como exemplo,
considere o seguinte programa:
#include <ios tream . h>
#include <conio . h>
vo id ma in ()
{
,..
FUNÇOES SIMPLES
void ma in ()
{
int c, f ;
I I c e l siu s ()
11 Definição da função
i nt c;
c = (fahr - 32) * 5 /9 ;
ret urn c ;
)
, ~
O PROTOT/PO DE FUNÇOES
Da mesma forma que com relação a uma variável, não podemos também usar
uma função sem antes declará-la.
A declaração de uma função é chamada protótipo e é uma instrução,
geralmente colocada no início do programa, que estabelece o tipo da função e
os argumentos que ela recebe.
,
PROTOTIPO EXTERNO ELOCAL
/I cels ius ()
11 Def i nição da função
int c;
c = (fahr - 32) * 5/9;
return c;
}
122 Treinamento em Linguagem C++ Cap. 5
T N
11 celsius()
11 Def i nição da função
i nt c el sius( int fa hr )
{
int c ;
c = ( fahr - 32) * 5/9 ;
r e turn c ;
}
void ma i n ( )
{
i nt c, f ;
cout << 11
\nCelsius = 11
<< c;
}
..
TIPOS DE FUNÇOES
O tipo de uma função é definido pelo tipo de valor que ela retoma por meio
do comando return.
Uma função é dita do tipo int quando retoma um valor do tipo int.
Os tipos de funções C++ são os mesmos tipos de variáveis, exceto
quando a função não retoma nada. Neste caso, ela é do tipo void.
O tipo de uma função é determinado pelo valor que ela retoma via comando return
e não pelo tipo de argumentos que ela recebe.
O COMANDO return
)
124 Treinamento em Linguagem C++ Cap. 5
Este valor pode, então, ser atribuído a uma variável, como no nosso
exemplo, ou fazer parte de alguma expressão.
Várias instruções return podem fazer parte de uma função, mas somen-
te uma será executada.
-
LIMITAÇOES DO COMANDO return
Enquanto vários valores podem ser passados para uma função, não é permitido
o retorno de mais de um valor por meio do comando return.
O comando retum pode retomar somente um único valor para a função que chama.
- -
DEF/NIÇAO DA FUNÇAO
O código C++ que descreve o que a função faz é chamado definição da função.
Sua forma geral é a seguinte:
t i p o nome (declaração dos parâmetros)
{
i n s t ruçõe s;
}
Cap. 5 Funções 125
A ~
PARAMETROS DA FUNÇAO
int C i
c = ( fahr - 32 } * 5/9 i
re t urn C i
Variáveis que não fazem parte dos parâmetros de uma função não
podem ser declaradas em seu cabeçalho.
A função celsius() necessita de uma variável auxiliar c que foi declarada
após a abertura da chave. Esta variável é criada toda vez que a função inicia
sua execução e destruída quando a função termina, sendo visível somente para
as instruções do corpo da função.
A variável c de main() é outra variável e não tem nada a ver com a
variável c de celsius().
126 Treinamento em Linguagem C++ Cnp. 5
No nosso exemplo, a função cria uma nova variável para receber o valor
passado. Sua declaração indica que o valor enviado será armazenado na variável
fahr criada quando a função inicia a sua execução e destruída quando a função
termina.
Receber parâmetros desta forma, em que a função cria novas cópias dos
parâmetros transmitidos, chama-se Passagem por Valor.
O próximo exemplo mostra uma função que recebe um número inteiro
como argumento e retoma o seu valor absoluto. O valor absoluto de um número
é o próprio número quando o sinal é ignorado. Por exemplo, o valor absoluto
de 5 é 5 e de -5 é também 5.
#include <iostream. h>
i nt a b s ( i n t n) ; l i Protótipo
v oid ma in ()
{
cout << abs(0 ) << ' \t ' << abs ( -3) << ' \ t ' << abs(10) ;
}
I I a b s ()
11 Calcula o valor a bsoluto de um número
int abs( i nt n)
{
ret urn ( n > 0 } ? n : -n;
}
A função main() pode tanto enviar uma constante para abs() como uma
variável. O mesmo ocorre com a função celsius().
Cap. 5 Funções 127
Uma função que não retoma nada é batizada como de tipo void. Como exemplo,
escreveremos uma função que desenha uma linha com um certo número de
asteriscos.
11 LINHA. CPP
#include <iostream . h>
voi d l i nha(int n) ;
void ma in ()
{
II linha()
11 Desenh a uma l i nha na tela
void linha (int n)
{
f or( i nt i=!ll ; i <n ; i ++) cout << I *I •
'
}
Eis a saída:
** ** ** ***** ** * ** ** ** *
* FELIZ ANI VERSARIO *
** ** *** ******* ** ** ** *
128 Treinamento em Linguagem C++ Cap. 5
.. .. ..
FUNÇOES QUE NAO RECEBEM NADA ENAO RETORNAM NADA
void ma in ()
{
cout << '' \nDigite um dígito entre 0 e 9 '';
do i sbeep() ;
}
}
/I doisbeep ()
11 toca o alto-falante duas vezes
void doisbeep(void)
{
cout << ' \x07 ';
,
PASSANDO VARIOS ARGUMENTOS
I I r e tangul o ( )
11 Desenh a um retângu lo na te l a
vo i d re t angulo( int lar gura , int a l tura)
{
largura /=2 ;
altura /=4 ;
for (int j =l ; j<= al tura ; ]++)
{
130 Treinamento em Linguagem C++ Cap. 5
cout << I \n I ;
}
}
Cozinha
Banhei ro
Qua r t o
, ~
Você pode escrever quantas funções quiser num programa, e qualquer função
pode chamar qualquer outra.
Em C++, não é permitido definir uma função dentro de outra função.
As funções são módulos independentes.
Cap. 5 Funções 131
void linha(int n) ;
vo i d espacos(int n);
void ma in ()
{
I I linha ()
11 Desenha uma linha na tela
void l i nha ( int n )
{
for(int i=0 ; l<n ; i++) cout << I * f •
'
}
11 espacos()
1/ Imprime espacos em branco
vo id espacos( int n)
{
132 Treinamento em Linguagem C++ Cnp. 5
Eis a saída:
********** * **********
* FEL I Z ANIVERSARIO *
******** * *** ** ** *****
....
CHAMADAS
....
A FUNÇOES USADAS COMO ARGUMENTO DE OUTRAS
FUNÇOES
Você já sabe que a chamada a uma função pode ser utilizada numa expressão
da mesma forma que utilizamos valores numéricos. Podemos também utilizar
a chamada a uma função como argumento para outra função.
O próximo exemplo calcula a soma dos quadrados de dois números
fornecidos pelo usuário. Eis a listagem:
//MULTFUNC . CPP
void ma in ()
{
fl oat a , b ;
cout << '' \nDigite do i s nómeros '';
cin >> a >> b ;
cout << " \nA soma dos quadrados é " << somasqr(a , b) ;
}
Cap. 5 Funções 133
float s q r(float z)
(
r eturn z*z ;
)
r eturn m+n ;
)
n = 5;
cou t << nl i
134 Treinamento em Linguagem C++ Cnp. 5
nl - 8;
cout << n ;
imprimem 5 e 8.
O operador unário &, quando usado na criação de referências, faz parte
do tipo:
int& é um tipo de dado
int& nl ; // ERRADO
int& nl = n ; // CERTO
void ma in ()
{
fl oat p r eco , val_ r e a j ;
do
{
c o ut << '' \n\ n insira o p reco atua l : '' i
•
Cln >> pre coi
r e aj ust a 2 0(prec o , val_reaj ) i
cout << " Preço novo - " << preco
<< " \ nAumento - " << va l_reaj i
} while( preco ! = 0 . 0) i
}
//re ajusta20()
// Reajusta o preco em 20%
void reajusta20(float& p , floa t& r )
{
r -- p * 0.2 i
p -- p * 1. 2 i
}
indica que p e r são outros nomes para as variáveis passadas como argumento
pela função que chama. Em outras palavras, quando usamos p e r, estamos
realmente usando preco e val_reaj de main().
Referências não existem em linguagem C e não há um meio de criar
outro nome para uma mesma variável.
,
ORDENANDO UMA LISTA DE NUMERO$
O próximo exemplo cria uma função que troca o conteúdo de duas variáveis.
Utilizaremos a função troca() para ordenar uma lista de três números.
//ORDENA.CPP
//Ordena u ma l i st a d e t rês núme r o s
#include <iostream . h>
void ma in ()
{
float nl , n2,n3 ;
I /troca ( )
//Pe rmuta o valor d e duas variáve is
void t r oca(floa t & n , f l oat& m)
{
f l oat temp=n ;
n - m;
m = t emp;
}
Eis a saída:
Di g i t e três números : 50 13 28
nl - 13
n2 - 28
n3 - 50
J\
REFERENCIAS CONSTANTES
muitos dados como argumentos. Se forem passados por valor, a função criará
uma cópia das variáveis da função que chama; por serem mu itos dados, o
programa pode não rodar. Veja o exemplo:
//REFCONST . CPP
//Mo stra o uso de r efer ência constant e
#include <i ostream.h>
vo i d ma i n ()
{
dou ble nl , n2 i
I I imprime ()
//Imprime o quadrado dos argumentos
vo i d imprime(const doubl e& n , const double& m}
{
O uso de referências poderá ser bastante confuso para alguém que leia o
programa. Sem que seja lido o protótipo da função, é impossível saber se a
função recebe uma referência da variável ou um simp les valor. Assim, não
sabemos se a variável passad a como argumento é alterada ou não. As referências
devem ser utilizadas com cuidado.
Cap. 5 Funções 139
...
VALORES DEFAULT PARA OS ARGUMENTOS DE UMA FUNÇAO
O protótipo de uma função pode incluir valores para um, alguns ou todos os
parâmetros. Se forem omitidos os argumentos correspondentes na chamada à
função, os valores default serão automaticamente usados. Se os argumentos
correspondentes forem enviados, estes serão respeitados.
Como exemplo, vamos alterar a função linha() para que ela receba dois
argumentos: o caractere para o desenho da linha e o número de caracteres a
desenhar. A função imprime uma linha de 20 asteriscos por default.
//LI NHAl.CPP
//Mos tra o uso de valores de f aul t pa ra argumentos
#include <i ost ream . h>
void ma i n ()
{
I I linha()
11 De senha uma l i nha na tela
void linh a ( int n , char ch)
{
for(i nt i=0 ; i<n ; i++) cout << ch;
}
Eis a saída:
*********** ** *******
******** ******************** ******
---------------------------------------------
140 Treinamento em Linguagem C++ Cap. 5
,..
SOBRECARGA DE FUNÇOES
//CUBO.CPP
//Mostra o uso de sobreca rga de f unções
#include <iostream . h>
int cubo ( i nt n) i
doubl e cubo(doubl e n) i
void ma in ()
{
cout << cubo(876 ) << ' \n ' i
int cubo( i nt n)
{
return n*n*n i
)
re t urn n*n*n i
}
void l i nha(int n) i
void l i nha(char ch) i
void l inha(vo i d) i
void l i nha (int n, char ch) i
v o i d ma in ()
{
void l i nha(int n)
{
for(int i=0i i <n i i+ +) cout << I * I •
'
}
void linha(char c h)
{
for (i nt i=0 ; i <20 ; i++) cout << ch ;
}
Cap. 5 Funções 143
void linha ()
(
for ( int i =0 i i<2 0 i i+ + ) cout << I * ,
I •
vo id l i nh a(int n, char ch )
{
f or( i nt i =0 i i <n i i ++) cout << ch;
)
FUNÇÕES inline
vo id ma in ()
{
144 Treinamento em Linguagem C++ Cnp. 5
...
FUNÇOES RECURSIVAS
Uma função é dita recursiva se é definida em termos dela mesma. Isto é, uma
função é recursiva quando dentro dela está presente uma instrução de chamada
a ela própria.
Como exemplo, vamos escrever uma função que calcula o fatorial de
um numero.
'
//FATORIAL . CPP
//Mostra o uso de funções r ecursivas
#incl ude <i ostream . h>
void ma i n ()
{
i nt n ;
while(l)
{
cout << '' \nDi g ite um nómero : ";
c1n >> n;
if( n < 0 ) br e ak ; //Te rmina se No . negativo
cout << '' \nFatoria l = '' << f atorial(n);
}
}
// fat orial ()
//Cal cula o fatori al de um nómero. Recursiva
long fatorial ( int n }
{
return( (n== 0) ? long( l ) : l ong(n) * f atorial (n - 1)) ;
}
146 Treinamento em Linguagem C++ Cnp. 5
A' primeira vista, não é fácil entender o funcionamento de uma função recursiva.
Para facilitar o entendimento, vamos imaginar que uma chamada
recursiva é a chamada a outra função que tenha o mesmo código da função
original.
Por exemplo, a seqüência de chamadas à função fatorial(), se o seu
argumento inicial for 3, poderia ser a seguinte:
long fatoria l( i nt n)
{
return( (n==0)? l ong(l) : 3 * f1 ( 2)) ; //chama outra função
}
l ong f1 ( int n)
{
l ong f2 (int n)
{
r e turn( (n==0) ? l ong( l) : 1 * f3(Ql)) ; // chama outra função
}
long f3 ( int n)
{
re tur n( 1) ;
}
v oid inverte(void) ;
void ma in ()
{
148 Treinamento em Ling uagem C++ Cnp. 5
cout<<' \ n ';
inve rte() ;
)
// i n v e rte()
// Inverte uma frase usando recursão
v oid invert e( )
{
char ch ;
if ((ch=getche () ) != ' \r ' ) i nverte() ;
cout << ch ;
}
Neste jogo temos três hastes, que chamaremos de haste Origem, haste Destino
e haste Temporária, e um número qualquer de discos de tamanhos diferentes
posicionados inicialmente na haste Origem. Os discos são dispostos em ordem
de tamanho, de forma que o maior disco fica embaixo, em seguida o segundo
maior e assim por diante.
O objetivo do jogo é movimentar um a um os discos da haste Origem
para a haste Destino utilizando a haste Temporária como auxiliar. Nenhum
disco pode ser colocado sobre um disco menor.
Cap. 5 Funções 149
if (n==1 }
cout << " \nMova o disco 1 da haste " << Orig
<< '' para a haste " << Dest ;
else
{
mover(n-1,0rig ,Dest,Temp) ;
cout << " \nMova o disco " << n << " da haste "
<< Orig << '' para a haste '' << Dest ;
mover(n-l,Temp , Orig,Dest) ;
}
}
Eis a saída:
Mova o disco 1 da haste O para a haste D
Mova o disco 2 da haste O para a haste T
Mova o disco 1 da hast e D para a haste T
Mova o disco 3 da haste O para a haste D
Mova o disco 1 da haste T para a haste O
Mova o disco 2 da haste T p ara a haste D
Mova o disco 1 da ha ste O para a haste D
CLASSES DE ARMAZENAMENTO
static (estáticas)
register (em registradores)
A CLASSE auto
int n ;
• •
é equivalente a
void ma in ()
{
auto int n ;
. . .
}
A CLASSE extern
void f unc(void ) ;
vo id ma in ()
{
void f u nc ()
{
i= 25 ; ] =48 ;
}
Cap. 5 Funções 153
Eis a saída:
(/) 234
25 48
O OPERADOR DE ESCOPO: ::
void ma i n ()
{
vo id ma in ()
(
int i =5 I j =l !ll ; //Variáveis automá ti cas
Co u t << :: l.• << I\ t I << ; ; j <<
I \nI //ext ernas
;
A PALAVRA-CHAVE extern
A p alavra extern não é usada para criar variáveis da classe extern e sim para
informar ao compilador que a variável em questão foi criada em outro programa
compilado separadamente e que será linkeditado junto a este para formar o
programa fina l.
void ma in ()
{
Além de passar parâmetros por referência para uma função, uma referência a
uma variável externa pode ser usada como valor retornado de uma função.
//Mostra retorno por referência
# include <i os t ream . h>
Cap. 5 Funções 155
i nt x; //Variáv e l externa
int& initx(void ) ;// Protó tipo da funç ão
vo i d ma i n ( )
{
c o ut << x;
)
i nt& i n i t x ()
{
return x;
)
Para entender a utilidade desta técnica, você deve aprender mais sobre
C++. Mais adiante, serão mostrados exemplos práticos.
A CLASSE static
void ma i n ()
{
s o ma() i
soma () i
soma( ) i
}
void s o ma ()
{
static i nt ki
c o ut << " \ nk = " << ( k+ +) i
}
A saída será:
k - 0
k - 1
k - 2
Nós já usamos a função de biblioteca C++ rand() que gera números aleatórios.
Agora desenvolveremos a nossa própria função, visto que ela não é implemen-
tada em todos os sistemas.
O esquema começa com um número chamado "semente" usado para
produzir um novo número que se tornará a nova semente. A nova semente é
usada para produzir uma nova semente e assim por diante. Desta forma, a
função deve lembrar-se da semente usada na última chamada e para isto
variáveis static se adaptam p erfeitamente. O método é baseado em congruência
linear, que não explicaremos aqui.
Cap. 5 Funções 157
//TESTRAND . CPP
//Mostra o uso de variáveis static
v oid ma in ()
{
I / rand()
//Gera números al eatórios
unsigned rand ()
{
vo id ma in ()
{
int s;
cout << '' \nDi gite a sua semente : '';
.
c~n >> s ;
inits (s) ;
for (int i=@ ; i < 5 ; i+ + )
cou t << ' \n ' << rand() ;
)
Cap. 5 Funções 159
//rand ()
//Gera números aleatórios
uns i g n e d rand ()
{
semente = (se me nt e*2 5173 + 13 849}%65536 ; //Fórmula mágica
return semente;
}
// inits(}
// I ni cializa a semente
void in its (int n)
{
semente=n ;
}
39022
61087
2019 6
4500 5
3882
23832
20241
63678
35119
49332
160 Treinamento em Linguagem C++ Cap. 5
Toda função C++ é da classe extern, ou seja, toda função C++ é visível a todas
as outras.
Uma função, além de externa, pode ser também estática. Especificar
uma função usando static permite que a função seja acessível somente às
funções do mesmo programa-fonte definidas abaixo dela, ao contrário das
outras que podem ser acessadas por outros arquivos compilados em módulos
separados.
A CLASSE register
void ma i n ()
{
int if j i
r eg is te r int mf n i
long t i
t=time (0) i
f or ( j=0 i j<50 00i ] ++ )
f or (i=0 i i <500 0 ii ++)
.
f
t=time(0) i
for(m= 0 i m< 5000im++ )
f o r(n =0 ; n<5 000; n ++ )
•
f
~ ,
OBSERVAÇOES TECNICAS
enquanto variáveis static ou extern não podem. O motivo é que elas são criadas
em tempo de compilação e não há como executar uma função nesse momento.
v o id ma in ()
{
,
O PRE-PROCESSADOR
A DIRETIVA #define
A diretiva #define, na sua forma mais simples, é usada para definir constantes
simbólicas com nomes apropriados. Veja o exemplo:
#include <i ostream. h >
#defi ne PI 3 . 14
void ma in ()
{
fl oat r aio ;
164 Treinamento em Linguagem C++ Cnp. 5
x = PI * PI ; //Quadrado de PI
• • •
Cap. 5 Funções 165
. . .
X = 3 . 14 * 3. 14 ; //Quadrado d e PI
• • •
i f ( zebra}
ERRO;
MACROS
void ma in ()
{
int nl , n2 ;
n 1=14 16 ;
n2=nl/2 ;
O programa imprime:
1416
708
As chamadas às macros são substituídas, em nossos programas, por
suas definições. Assim, toda ocorrência de PRN(n) do exemplo será trocada por
cout << n << '\n' de tal forma que no lugar de n é usado o argumento da
chamada à macro. Após o pré-processamento, o nosso programa será o seguinte:
// PRNMACRO . CPP
//Mo stra o uso de macros
void ma in ()
{
int n l,n2;
n1=1416;
n 2=nl /2 ;
não funcionará, porque o espaço entre PRN e (n) é interpretado como fim do
identificador.
"
O USO DE PARENTESES EM MACROS
. .. . .
z = 10 * SOMA(3 ,4);
#define PROD(x,y) (x * y}
• • • •
• • • •
z = PROD(2 + 3, 4 ) ;
A instrução pré-processada é
z = (2 + 3 * 4);
Uma macro pode ser definida usando outra macro. Verifique o exemplo:
//Mostra o uso de macros que chamam outras macros
#define PI 3.1416
#define SQ(x) ( (x} * (x)}
#defi ne AREA(x} ( (4 } * (PI} * SQ (x}}
void ma in (}
{
float ra1 o ;
.
• .
c 1n >> ra1o ;
Cap. 5 Funções 169
cout << " \nA área da esfera é " << AREA ( raio);
)
,
MACROS EM VARIAS LINHAS
Diretivas com um texto grande podem ser escritas em mais de uma linha se a
barra invertida (\) for colocada no final da linha, antes de prosseguir para a
próxima linha. Veja o exemplo:
#d e fin e MAI USC(ch} ( (ch} >= 'a' && (ch) < = 'z' ) ? \
( (ch) - 'a' + 'A' ) : (ch)
Se uma função for escrita para calcular a soma de dois números, será
necessário respeitar o tipo de seus argumentos ou escrever uma farm1ia de
funções sobrepostas.
Por outro lado, a falta de avaliação dos argumentos pode provocar
resultados inesperados. Verifique os dois exemplos seguintes: o primeiro im-
plementa uma macro e o segundo, uma função inline.
//Mostra probl e mas com macro s
170 Treinamento em Linguagem C++ Cap. 5
#define MAIUSC(ch } ( (c h l>= ' a ' && (ch} <= ' z ' } ? \
( (c h} - ' a ' + ' A ' ) .• ( c h)
void ma in ()
{
char cp ;
c o u t << cp ;
}
return (ch>= ' a ' && ch <= ' z ' }? (ch- ' a ' + ' A' } : ch ;
}
void ma in ()
{
char cp ;
cout << cp ;
)
Cap. 5 Funções 171
void ma in ()
{
int nl - 1 , n2 - 2 , n;
n=MIN(n1++ , n2++) ;
cout << 11
\nnl= 11
<< nl << 11
n2 =" <<n2 <<" n="<<n;
}
//FUNCAO inline
#inc lude <iostream . h>
void ma in ()
{
int nl - 1 , n2 - 2,n;
n=min(nl++,n2++) ;
cout << 11
\nnl= 11
<< nl << 11
n2= "<<n2 << " n="<<n ;
}
172 Treinamento em Linguagem C++ Cnp. 5
A DIRETIVA #undef
....
#undef ENORME //Cancela a definição de ENORME
. . . ..
....
#undef SOMA //Cancela a macro SOMA
Observe que, para remover uma macro, somente o nome da macro deve
constar na diretiva #undef. Não deve ser incluída a lista de argumentos.
A DIRETIVA #include
Além do uso dos sinais de< e>, a diretiva #include aceita uma segunda
sintaxe:
#include '' iostream . h ''
ARQUIVOS DE INCLUSAO
O texto acima pode ser gravado com o nome areas.h e todo programa
que fizer uso destas macros deve simplesmente conter a diretiva:
#include ''areas . h ''
prog ram
b eg in
write( " Isto é linguagem C++?? " ) ;
end
COMPILAÇAO CONDICIONAL
Cada diretiva #if deve terminar pela diretiva #endif. Entre #if e #endif pode
ser colocado qualquer número de #elif, mas só se permite uma única diretiva
#else. A diretiva #else é opcional e, se estiver presente, deve ser a última anterior
a #endif. Observe o exemplo:
#de fin e DEBUG 1
• • • •
....
#if DEBUG == 1
cout << '' \nERRO - '' << e rro 1 ;
#elif DEBUG == 2
cou t << " \nERRO - " << err o2 ;
#el s e
cout << " \nERRO não doc umentado";
#end i f
Outro exemplo:
#i f CORES > 5
#d ef ine SOMBRA 1
# i f COR_ FUNDO == 1
# i nclude ''corfundo .h''
#e l se
#include '' sernfundo .h''
#e ndif
#else
#define SOMBRA 0
#if CGA == 1
#include "cga . h "
#else
#includ e ''mono . h ''
#endif
#endif
176 Treinamento em Linguagem C++ Cnp. 5
Para testar constantes definidas com #define que não tenham valor
nenhum, podemos utilizar #ifdef e #ifndef. Por exemplo:
#define VERSAO_DEMO
. ...
. .. . .
#ifdef VERSAO_DEMO
#define NUM_REC 20
#else
#de fi ne NUM_REC MAXINT
#e nd if
O OPERADOR delined
A DIRETIVA #error
..
REVISA O
6. O tipo de uma função é definido pelo valor retornado por meio do comando
return.
7. O comando return encerra a execução da função e pode retornar somente
um único valor para a função que chama.
8. O mecanismo por meio do qual uma função recebe argumentos em variáveis
criadas em seu cabeçalho para armazenar uma cópia dos valores passados
é chamado "Passagem por Valor".
9. O operador de referência{&) é usado junto ao nome de um tipo para criar
uma referência a uma variável. Uma referência não é uma cópia da variável
a quem se refere. É a mesma variável sob diferentes nomes.
10. "Passagem por referência" é o nome dado à passagem de argumentos para
funções que os declaram como referência às variáveis originais. Esta forma
de passar argumentos permite às funções alterar as variáveis enviadas pela
função que chama.
11. Argumentos recebidos em referências constantes são utilizados para eco-
. ' .
normzar memona.
12. O protótipo de funções pode incluir valores "default'' para argumentos de
funções. Estes valores são usados quando os argumentos correspondentes,
na instrução de chamada, são omitidos.
13. Uma família de funções com o mesmo nome e lista de argumentos diferentes
em número e/ ou tipo é chamada "SOBRECARGA DE FUNÇÕES".
14. O código de uma função inline é inserido em todo lugar onde ela é
chamada.
15. Uma função inline deve ser escrita antes de qualquer função que a chama.
16. Funções inline poupam tempo de execução, mas não memória.
17. Uma função é dita recursiva se, em seu corpo, estiver presente uma
instrução de chamada a ela própria.
18. A classe de armazenamento de uma variável informa visibilidade, tempo
de vida, lugar da memória onde será alocada e seu valor inicial.
19. Em C++, há quatro classes de armazenamento: auto, extern, static e register.
A classe auto é a default".
'I
Cap. 5 Funções 179
,
EXERCICIOS
c) x = sorte () ;
c) float;
d) Não é possível identificar o tipo da função somente com estas informações.
12. A instrução
int& x = y;
a) poupam memória;
b) poupam tempo de execução;
a) poupam memória;
b) poupam tempo de execução;
c) aumentam a legibilidade do programa;
d) usam mais memória.
b)refi () = y;
c) refi (y);
d) refi () = 1 4 16;
34. Escreva uma macro que tenha o valor 1 se o seu argumento for um número
ímpar, e o valor O se for par.
35. Escreva uma macro que encontre o maior entre seus três argumentos.
36. Escreva uma macro que tenha valor 1 se o seu argumento for um caractere
entre 'O' e '9', e O se não for.
37. Escreva uma macro que converta um dígito ASCII entre 'O' e '9' a um valor
numérico entre O e 9.
38. Escreva funções inline correspondentes às quatro macros dos exercícios
anteriores.
39. Um número primo é qualquer inteiro positivo divisível apenas por si
próprio e por 1. Escreva uma função que receba um inteiro positivo e, se
este número for primo, retorne 1, caso contrário retorne O.
40. A famosa conjetura de Goldbach diz que todo inteiro par maior que 2 é a
soma de dois números primos. Testes extensivos foram feitos sem contudo
ser encontrado um contra-exemplo. Escreva um programa mostrando que
a afirmação é verdadeira para todo número par entre 700 e 1100. O
programa deve imprimir cada número e os seus correspondentes primos.
Use a função do exercício anterior.
41. Escreva uma função que receba como argumento o ano e retorne 1 se for
um ano bissexto e O se não for um ano bissexto. Um ano é bissexto se for
divisível por 4, mas não por 100. Um ano também é bissexto se for divisível
por 400.
42. Escreva uma função que receba dia, mês e ano e calcule o dia da semana.
Esta função retoma O se for domingo, 1 se for segunda-feira etc. Consulte
o programa DIASEMAN.CPP no capítulo anterior.
43. Escreva um programa que solicite ao usuário um ano e imprima o calendá-
rio desse ano. Utilize as funções dos dois exercícios anteriores.
Cap. 5 Funções 187
44. Escreva uma função que desenhe um retângulo de 5 linhas por 20 colunas
usando os caracteres '+', '-' e ' I '. O número de linhas, o de colunas e os
caracteres do desenho são argumentos "default" da função. Quando a
função é chamada sem nenhum argumento, desenha o seguinte retângulo:
+--------------------------- +
+---------------------------+
45. Escreva uma função que receba um número float como argumento e
retorne, em outros dois argumentos passados por referência, a parte inteira
e a parte decimal desse número.
46. Escreva uma função que ordene o valor de três argumentos do tipo char.
Por exemplo, se ch1, ch2 e ch3 são variáveis do tipo char com valores 'B',
'A' e ' C' respectivamente, após a chamada à função as variáveis conterão
'A', 'B' e 'C' respectivamente. Utilize a passagem dos argumentos por
referência.
47. Escreva uma família de funções sobrecarregadas para ler uma variável de
qualquer dos tipos: char, int, float ou double. Utilize a passagem dos
argumentos por referência.
48. Escreva uma função recursiva chamada potencia() que aceite dois argu-
mentos inteiros positivos i e j. A função retoma o i elevado à potência j. Por
exemplo: potencia(2,3) é igual a 8. Use a seguinte definição:
Um número i elevado à potência j é igual a i elevado à potência j-1 vezes i.
49. Escreva uma função recursiva que receba como argumento o número do
termo de uma seqüência de Fibonacci e retorne o seu valor. Por exemplo:
se o argumento for 7, a função retorna 13. Use a seguinte definição:
Os dois primeiros termos da seqüência têm valor. Cada um dos próximos
termos vale a soma dos dois anteriores.
50. Escreva uma função recursiva de nome soma() que receba um número
inteiro positivo n como argumento e retorne a soma dos n primeiros números
inteiros. Por exemplo, se a função receber n=5, deve retornar 15, pois
15 = 1 + 2 + 3 + 4 + 5
Capítulo 6
MATRIZES
188
Cap. 6 Matrizes 189
aloca memória para armazenar cinco variáveis do tipo int e anuncia que notas
é uma matriz de cinco elementos.
Vamos reescrever o programa anterior usando uma matriz:
//NOTAS.CPP
//Cal c ula a média das notas de cinco alunos usando matriz
#include <iostream . h>
void ma in ()
{
i nt notas[S ] , media=0 ;
f or ( i n t i =0 ; i <S; i ++)
{
cout << '' Digite a nota do aluno '' <<(i+l}<< '': '';
c1n >> notas[ i];
media += no t as [i ] ;
}
...
DECLARAÇAO DA MATRIZ
informa que a matriz notas é formada por cinco elementos do tipo int. Por
definição, uma matriz é composta por elementos de um único tipo.
O valor que dimensiona a matriz na sua declaração deve ser uma
constante inteira. Assim, não podemos dimensionar uma matriz por meio de
uma variável.
Cap. 6 Matrizes 191
O fato de uma matriz ser composta por uma série de elementos de um dado
tipo permite a escolha de qualquer tipo de variável para a matriz. Suponhamos
que você queira que as notas dos seus alunos fiquem no intervalo de O a 10 e
que não seja desprezada a parte fracionária. A solução seria usar uma matriz
de elementos do tipo float.
//NOTAS.C PP
//Ca l c u l a a médi a da s notas de a l unos usando ma t riz floa t
#include <i ostream.h>
192 Treinamento em Linguagem C++ Cap. 6
#include <iomanip.h>
void ma in ()
{
cout << ''Di gite a not a do a l uno '' <<(i +l )<< ": '';
cin >> notas[i ];
media += notas[i];
}
cout << " \n\nHédia das notas : " << (media / TAMANHO) ;
}
mais alunos, somente uma linha do programa deve ser alterada. Por exemplo,
para calcular a média das notas de 30 alunos, devemos alterar somente a
instrução de declaração da constante:
const TAMANH0=30 ;
,
UM NUMERO DESCONHECIDO DE ELEMENTOS
void ma in ()
{
const TAMANH0=50 ;
int i =0 ;
do
{
cout << '' Di gite a nota do a l uno '' <<(i +l) << '': '';
c1n >> notas[i ];
} while (notas[i++] > = 0) ;
•
1-- ;
194 Treinamento em Linguagem C++ Cap. 6
.
for ( i nt j = 0 ; j < l ; j++}
media += notas [ j] ;
O laço for foi substituído pelo laço d o-while. Este laço repete a
solicitação da nota ao usuário, armazenando-a na matriz n otas[], até que seja
fornecido um valor menor que zero.
Quando o último item for digitado, a variável i terá alcançado um valor
acima do total de itens. Isto é verdadeiro, pois é contado o número negativo de
finalização da entrada. Assim, devemos subtrair 1 do valor contido em i para
encontrar o número correto de itens.
CHECANDO LIMITES
C++ não avisa a você quando o limite de uma matriz foi excedido.
cout << '' Digit e a nota do aluno '' <<(i+l)<< '': ''i
cin >> notas[i ] i
} while (nota s [ i+ + l > = @) i
INICIALIZANDO MATRIZES
//DIAS.CPP
//Imprime o núme r o de d ias do ano até a data e s pecif i cada
#include <iostream . h>
void ma i n ()
{
i nt d i a , mes , a no ;
cout << " \ nDi gite a data no f ormato DD/ MM/AAAA: ";
{
char ch ;
c i n >> dia >> ch >> me s >> c h >> ano;
}
i nt total=dia ;
f o r( i n t i =0 ; i < mes - 1 ; i ++ }
t ota l+ =dmes[ i] ;
cout << "Tota l de dias tran scorr i dos : " << total ;
}
..
MATRIZES DE MAIS DE UMA DIMENSAO
os elementos são de tipos simples. Diremos que uma matriz é de duas dimensões
quando seus elementos forem matrizes de uma dimensão.
Na verdade, em C++, o termo duas dimensões não faz sentido, pois
todas as matrizes são armazenadas na memória de forma linear. Usaremos este
termo para indicar matrizes em que os elementos são outras matrizes.
Com dois pares de colchetes obtemos uma matriz de duas dimensões
e com cada par de colchetes adicionais obtemos matrizes com uma dimensão a
o
mais.
Para ilustrar este conceito, apresentaremos um programa que usa uma
matriz de duas dimensões para criar uma grade do jogo-da-velha.
Inicialmente, a matriz é preenchida com pontos. Depois, o programa
forma um ciclo por meio de um laço while onde a matriz é impressa, verifica-se
se algum jogador já ganhou ou se houve empate, solicita-se ao jogador que
digite um par de coordenadas e finalmente atribui-se o caractere 'o' ou 'x' ao
elemento da matriz correspondente às coordenadas entradas.
Executando este programa, você verá como trabalha um sistema de
coordenadas de duas dimensões. Digite pares de números como ( O O ), ( 1 2),
(2 2) etc. A coordenada horizontal, ou seja, o número da linha, é fornecida
primeiro. Não esqueça que os índices começam em zero.
I /VELHA. CPP
//J ogo-da-velha . Mostra matri z de duas dimensões
#include <ios tream.h>
void ma in ()
{
unsigned char v [3 ) [3 ); // Ma t riz de duas dimensões
f or ( l in = 0 i l in < 3 i lin+ + }
f o r(col = 0 ; col < 3; col++ }
v(lin) (col)= ' . 'i
wh i l e (TRUE)
{
c out << "\n \ n ";
f or (lin= 0i l in < 3 i l i n ++)
{
for(col= 0i col < 3 ; col+ +)
cou t << v ( l in ) [ c o l ) << I I •
I
if (x== 9)
{
cout << ''\n\aEmpatou !!! '';
break;
}
i f (v ( lin] [col ) --
-- I
. I ) //Casa l i vre ?
{
if(x%2)
v [lin) [col ) =X ;
else
v [ 1 in ) [co 1) =0 ;
X++ ;
}
}
• • •
• •
• •
o . .
•
• • •
o
• X •
Coorde nadas : 1 2
o . .
X O
• •
Coorde nadas : 0 2
O . X
X O
• • •
Coordenadas : 2 1
O . X
X O
o .
Coordenadas : 2 0
202 Treinamento em Linguagem C++ Cnp. 6
O X
X O
X O .
...
INICIALIZANDO MATRIZES DE DUAS DIMENSOES
v oid ma in ()
{
const char PT= ' . ' i
vvhile (TRUE)
{
'
cout << ' \ n'i
)
. .
I /Verifica se pr1me1ro jogador ganhou
i f ( (v[0] [0 ]= =0 && v[0 ] [ l ] ==0 && v[0 ] [2 ] = =0 ) li
(v [ 1][0 ] = =0 && v [ 1] [ 1 ] ==0 && v[ 1] [2 ] = =0) li
(v [2 ] [0 ] ==0 && v [2) [ 1) ==O && v ( 2 1 ( 2 1= =0) I I
(v [ 0) [0 ] ==0 && v [ 1) [ 0 ) ==0 && v[2) (0]==0) l i
(v (0 ][1] = =0 && v(1 ) [1 ) ==0 && v(2 ) [1 ) ==0) l i
(v ( 0] (2 ) = =0 && v [ 1] [ 2 ] ==0 && v(2 ) [2 ] = =0 ) li
(v [([) ] [0 ] ==0 && v [ 1] [ 1] ==0 && v[ 2] [2 ] ==0) l i
(v [0 ](2 ] ==0 && v(1] [ 1] ==0 && v(2 ] [0 ] ==0))
{
i f (x== 9)
{
cou t << ''\ n\aEmpatou !! !'' ;
break ;
}
A matriz v[J tem três elementos: v[O], v[l] e v[2]. Cada elemento de v[]
é, por sua vez, uma matriz de três elementos do tipo char. Assim, v[O], v[l] e
v[2] são nomes de matrizes de elementos do tipo char.
Para inicializar uma matriz, devemos colocar a lista de elementos em
ordem, entre chaves e separados por vírgulas, exatamente como fizemos ao
inicializar uma matriz de uma dimensão:
uns igned char v[3 ] [3]=
{ {PT, PT , PT} {PT , PT , PT}
I I {PT , PT , PT } };
v[0 ] • I
v[l ] ----------------~
v[2J ----------------------------~
Cap. 6 Matrizes 205
..
INICIALIZANDO MATRIZES DE TRES DIMENSOES
"
Uma matriz de três dimensões é uma matriz em que cada elemento é uma matriz
de duas dimensões. Observe o fragmento de programa a seguir que inicializa
uma matriz de três dimensões:
i nt tresd[3] [2 ][ 4] =
{
{1,2 , 3 ,4},
{5, 6 ,7,8}
}
{7 , 9 , 3 , 2},
{4 , 6 , 8,3 }
}
{
{7 , 2 , 6 , 3},
{0 , 1 , 9 ,4}
}
} ;
Então:
tre sd [2) [1 ) [ 0 ] 0
,.,
MATRIZES COMO ARGUMENTOS DE FUNÇOES
void ma in ()
{
i nt not as [MAXI ] i
ci n >> not as [ i] i
i nt m=0 ;
return ( m/tamanho) ;
)
A primeira parte deste programa lê a lista das notas enquanto não for
digitada uma nota negativa. O único elemento novo deste programa é a
instrução:
i n t m = med i a(notas , i) ;
ela é uma chamada à função media() que retoma a média das notas armazena-
das na matriz.
A parte crítica a ser considerada aqui é como foi passada a matriz para
a função: usamos unicamente o nome da matriz.
Para referenciar um elemento da matriz, já sabemos que a sintaxe é
notas[i]; mas o que representa o nome da matriz sem colchetes?
Passando o nome de uma matriz para uma função, não é criada uma nova cópia
da matriz. A passagem é por referência.
vo id ma in ()
Cap. 6 Matrizes 209
const MAXI=20 i
int tab[MAXI ] i
o rdena ( tab , i) i
18
25
33
46
58
73
A ORDENAÇAO BOLHA
"' "'
MATRIZES DE DUAS DIMENSOES COMO ARGUMENTO DE FUNÇOES
Para ilustrar o uso de uma matriz de duas dimen sões passada como argumento
para uma função, escreveremos um programa para avaliar a eficiência de
funcionários de uma loja quanto ao número de peças vendidas por cada um em
três meses.
O primeiro índice da matriz indica o número de funcionários da loja e
o segundo, o número de meses a serem considerados.
//HI STOGR . CPP
// I mpr ime um h ist ogra ma hor izon t a l
//Mos t ra ma triz de d uas dimensõe s como argume nto de função
con s t MES=3 ;
void ma i n ()
{
c o nst FUNC = 5;
int p e c as[FUNC] [MES] ;
int temp= 0;
for( i =0 ; i <nfunc; i+ +)
(
int temp= 0;
OI
cout << setw(2) << (i+ l) << ''
<< setw (S) << temp << ": 11 ;
STRINGS
STRINGS CONSTANTES
Sempre que o compilador encontra qualquer coisa entre aspas duplas, ele
reconhece que se trata de uma string constante.
Ao longo deste livro, já mostramos vários exemplos de strings cons-
tantes. Veja mais um exemplo:
cou t << '' Saudações !'';
1 449
1 450 s
1 451 a
1 452 u
1 4 53 d
1 45 4 a
1 455 ç
1456 ô
1 457 e
1 45 8 s
1 459
146 0 \0
1 4 61
216 Treinamento em Linguagem C++ Cnp. 6
Observe que o caractere '\0', também chamado NULL, tem o valor zero
decimal, e não o caractere '0', que tem valor 48 decimal.
A terminação '\0' é importante, pois é a única maneira que as funções
possuem para poder reconhecer onde é o fim da string.
,
STRINGS VARIAVEIS
void ma in ()
{
c har nome [80 ];
A instrução
.
Cln >> nome ;
void ma in ()
(
char nome[8([) ];
A FUNÇÃO gets(}
void ma in ()
(
char nome[8([) ];
INICIALIZANDO STRINGS
Qualquer matriz pode ser inicializada, inclusive strings que são matrizes do
tipo char.
Podemos substituir a inicialização padrão:
char nome [ J = { A
I I I In I I I a I I I \(/)I } ;
por
char nome [ J = "Ana ";
// STR4.CPP
//Mostra o uso de strings ini cializadas
#i nc l ude <ios t ream . h>
#include <Stdio . h>
vo id ma in ()
{
char salute[ ]=" Saudações , '' ;
char nome[8(/J );
,
ARITMETICA COM ENDEREÇOS
void ma in ()
{
char salute[ ] = '' Saudações , ";
char nome[80 ];
gets (nome) ;
~ ~
A FUNÇÃO strlen()
void ma in ()
{
uns i g ne d char nome [ 80) ;
i n t l e n=strlen( no me) ;
atribui o valor 5 à variável len se o nome "André" for inserido. Observe que
strlen() não conta o caractere NULL.
A FUNÇÃO strcat()
void maio ()
{
char salute[] = ''Saudações , '' ;
char no me[80 ];
Cap. 6 Matrizes 223
strcat(salute , nome);
A FUNÇAO strcmp()
Suponhamos que você queira comparar uma cadeia de caracteres, digitada pelo
usuário, com alguma string interna no programa e decida escrever o seguinte
programa:
//ERRADO.CPP
#include <i ostream. h>
#include <stdio . h>
#include <string .h>
void ma in ()
{
char r esposta [ )= "BRANCO " ;
char r esp[4(/)) ;
void ma in ()
{
void ma in (}
{
cout << \ n << s trcmp ( "A"
I I "A" } ;
I
Eis a saída:
Q)
-1
1
2
1 15
226 Treinamento em Linguagem C++ Cap. 6
A FUNÇÃO strcpy(}
vo id ma in ()
{
Estas funções são semelhantes às que acabamos de analisar. A diferença é que elas
trabalham com um número fixo de caracteres. Todas recebem um terceiro argu-
mento indicando o número de caracteres a processar. Por exemplo, a função
stmcat() concatena n caracteres da segunda cadeia na primeira; stmcmpO compara n
caracteres das cadeias; e stmcpyO copia n caracteres da segunda cadeia para a primeira.
void ma i n(}
{
c har diasema na [ 7] [14]= { "Domi ng o '',
"Segunda - f eir a",
"Te rç a -f eira " ,
"Quarta -f eira " ,
"Quinta-f eira ",
"Sex ta - fe ira " ,
"Sá bado "
);
228 Treinamento em Linguagem C++ Cap. 6
do
{
...
REVISA O
,
EXERCICIOS
in t matriz [ 3 ] [ 3 ] = { { 1 1 2 3 }
I I
{4 1 5 1 6} ,
{7 ,8,9 } };
a) zeros;
b) valores indeterminados;
23. Uma string é terminada pelo caractere ___ , que é chamado _____ .
24. A função ______ é projetada especificamente para ler uma string do
teclado.
25. Se você tem declarado uma string como:
char nome[10 ] ;
b) gets (str) ;
c) getch () ;
ESTRUTURAS
237
238 Treinamento em Linguagem C++ Cnp. 7
void ma in ()
{
}
Cap. 7 Estruturas 239
DEFININDO A ESTRUTURA
struct aluno
{
int nmat;
Ponto-e-vírgula aqui
{ //Aces so l oca l
int nmat ; //Número da matrícula
float nota [3) ; //Notas
float media ; //Média
} i
,
DECLARANDO UMA VARIAVEL DO TIPO DEFINIDO
A instrução
aluno ana ;
declara uma variável de nome ana, do tipo aluno. Esta declaração reserva
espaço de memória suficiente para armazenar todos os membros da estrutura:
2 bytes para nmat, 12 bytes para a matriz nota e 4 bytes para media.
Os membros de uma variável estrutura são armazenados em seqüência
contínua de memória.
Cnp. 7 Estruturas 241
Uma vez criada a variável estrutura, seus membros podem ser acessados por
meio do operador ponto.
A instrução
ana . nmat = 45 6 ;
....
COMBINANDO DECLARAÇOES
int nmat ;
float nota [3 ] ;
float media ;
} ana , jose~joao ; //Dec laração de diversas variáveis
INICIALIZANDO ESTRUTURAS
int d ia;
char me s [1 0 ] ;
i nt ano;
} i
..
ATRIBUIÇOES ENTRE ESTRUTURAS
Uma variável estrutura pode ser atribuída a outra variável do mesmo tipo por
meio de uma atribuição simples:
d a t a andre;
and r e = a niversario ;
.
OPERAÇOES ENTRE ESTRUTURAS
i nt pec as ;
float preco ;
};
vend a A= { 2~ , 11@ .~ },
B = { 3 , 16 . 5 } , Tot al ;
244 Treinamento em Linguagem C++ Cnp. 7
Operações simples como a soma não estão definidas para tipos criados
com a palavra struct. A soma deve ser efetuada membro a membro:
Total . p ecas - A. p ecas + B. pecas ;
Total . preco - A. p reco + B.preco ;
ESTRUTURAS ANINHADAS
Exatamente como podemos ter matrizes em que cada elemento é outra matriz,
podemos definir estruhtras com membros que sejam outras estruturas.
// STRNI NHO . CPP
//Mostra estruturas aninhadas
#include <i ostream. h>
struct data
{
int d i a;
char mes [ 10 J ;
int ano ;
} i
struct venda
{
int pecas ;
float preco ;
da ta d iavenda ;
} i
Cap. 7 Estruturas 245
vo id ma in ()
(
venda A = ( 20 , 110.0, {7 , Novembro ", l993} };
11
Eis a saída:
Peç as : 20
Preço : 110
Data : 7 de Novembro de 1993
...
PASSANDO ESTRUTURAS PARA FUNÇOES
struct venda
{
int pecas;
float preco ;
};
void main(}
{
venda A,B;
.
c 1n A. pecas ;
>>
cout << " Insira o preco : " . I
.
c1n >> A. preco;
•
c 1n >> B. pecas ;
cout << " Insira o preco : " . I
•
c1n >> B.preco;
Cap. 7 Estruturas 247
vo id listavenda(venda C, venda D)
{
Eis a saída:
Venda A
-------
-------
Insira o número de pecas : 58
Insira o prece : 1234 . 5
Venda B
-------
Entre o número de pecas : 350
Entre o preco : 45678 . 9
Venda total
-----------
Tota l de pecas: 408
Prece tota l : 46913 . 398437
,.., 1\
struct venda
{
i nt pecas;
float preco;
} i
void ma in ()
{
venda A, B;
.
FUNÇOES QUE RETORNAM UMA ESTRUTURA
Suponhamos que você queira usar uma chamada a uma função para obter os
dados sobre as vendas. C++ permite que as funções retornem uma estrutura
completa para outra função.
// STRUCVND. CPP
//Mo stra uma função que retorna uma estrutura
#i nc l ude <ios t ream . h>
struct ve nda
{
int pecas;
fl oat prece ;
) ;
venda novavenda(void};
void ma i n ()
(
venda A, B;
A=novavenda{) i
B=novavenda() ;
listavenda( A, B} ; //Estruturas como argume nto
}
v e nda novavenda(}
{
venda X;
----------
cout << " \nNova Venda\n-- --- -----\n ''·,
cout << "Ins ira o numero
' de p ecas : " '.
•
Cl O >> X.pecas;
cout << "Insira o preco : " '.
.
C lO >> X. preco ;
MATRIZES DE ESTRUTURAS
Certamente, uma lista de peças e preços é composta por várias vendas (provavel-
mente mais de duas). Cada venda é descrita por uma variável do tipo venda. Para
tratar de várias vendas, é perfeitamente correto pensar numa matriz de estruturas.
O programa seguinte, além de realizar o nosso objetivo principal de
criar uma matriz de estruturas, onde cada elemento da matriz representa uma
venda, proporcionará uma simples interface com o u suário constituída da
escolha entre duas opções assinaladas pelas letras 'E' e 'L'.
Se o usuário pressionar 'E', o programa permitirá a entrada das
informações de uma venda. Se o usuário pressionar 'L', o programa listará todas
as vendas e imprimirá os totais.
Vamos ainda aumentar as informações de cada venda acrescentando a
data de venda.
Usaremos duas novas funções de biblioteca C++, atoi() e atof(). A
primeira recebe uma string como argumento e a converte num número inteiro
correspondente à cadeia recebida. Por exemplo, se enviarmos "1234" ela retoma
o número inteiro 1234. A segunda faz a mesma coisa, mas com variáveis float.
//STRMAT . CPP
//Mostra mat rizes de estruturas
#include <iostream . h>
#inc l ude <iomanip.h>
#incl ude <stdlib. h > //Pa ra atoi (), atof {) e ex i t {)
#include <conio . h> //Para getch ()
#include <stdio . h> //Para gets ()
struct data
{
int dia ;
char mes(l(/)) ;
int ano ;
} i
struct venda
{
252 Treinamento em Linguagem C++ Cap. 7
data diavenda;
int pecas;
float preco ;
);
venda vendas[50 ];
venda Tota1 ={{0 ,"'',0 } ,0, 0 . 0} ;
i nt n=QJ;
void ma in ()
{
const TRUE=l ;
con st char ESC=2 7;
char ch;
whil e (TRUE)
{
cout << "\nDigite E para adicionar uma venda ";
cout << "\n L para l i star as vendas'';
cout << " \n ESC para t e rminar\n";
ch=getch () ;
switch(ch)
{
case ' E ': novavenda( ) ;break;
case 'L' : listavenda() ;break ;
case ESC: exit( 0) ;
default : cout << "\nOpcao invalida!!";
}
}
Cap. 7 Estruturas 253
vo id nova venda ()
{
char temp[8QJ ];
cout << "Dia : 11
gets(temp) ;
;
v e ndas[n] . pecas=atoi(temp );
cout <<"Preço: ";get s(t emp) ;
vendas [ n] . pre co=ato f(temp );
Tota l.pecas += vendas [n] .pecas;
Total . preco += vendas[n++ l . preco ;
)
void listavenda()
{
if(!n )
{
cout << ''\nLista vazia .'';
return;
)
cout << setprecision (2) ;
f or (int i=0; i<n ; i+ +)
{
cout << ''\n'' << setw(2 ) << vendas [i ] . diavenda.dia
<< de
11
<< setw( lflJ) << vendas [i ] .diavenda . me s
11
<< de
11
<< setw(4) << vendas[i ] .diavenda.ano;
11
132 2 . 13e+03
Decidimos utilizar duas novas funções da biblioteca C++ para que voce as A
conheça.
A função atoi(), com protótipo no arquivo stdlib.h, recebe o endereço
de uma string como argumento e o converte a um valor inteiro. Caso a string
não contenha um número válido, ela retornará zero. Espaços em branco iniciais
são ignorados.
A função atof(), com protótipo no arquivo stdlib.h, recebe o endereço
de uma string como argumento e o converte a um valor double. Caso a string
não contenha um número válido, ela retornará zero. Espaços em branco iniciais
são ignorados.
Cnp. 7 Estruturas 257
..
A FUNÇAO exit(J
ESTRUTURAS ECLASSES
void ma in()
{
mes ml,m2 ;
ml - Abr ;
m2 - Jun ;
"'
UNIOES
.
un1on num
{
c har str[2@] ;
int i ;
float f ;
} x ; //Cria variável
tipo=strtipo;
strcpy(x . str,n};
}
void initnum(float n}
{
tipo=floattipo;
x . f =n ;
}
void in i tnum(int n)
{
Cnp. 7 Estruturas 261
tipo=int tipo ;
.
x . ~=n ;
)
void printfunc(void );
vo id ma in ()
{
float y =34 . 56;
int z = 345 ;
initnum(z) ;
printfunc() ;
i n i tnum (y} ;
printfunc();
)
void printfunc()
{
switch (tipo)
{
cas e str tipo :
cout << \nStr -
11
<< x.str;
11
break ;
case inttipo :
•
cout << " \ nint - << x.~;
11
break ;
case float tip o:
cout << setprecision (2} ;
cout << \ nFloa t = " << x . f ;
11
break ;
}
}
262 Treinamento em Linguagem C++ Cap. 7
O OPERADOR sizeof
Uma variável de um tipo union tem o tamanho do maior membro. Para verificar
isto, usaremos um novo operador C++: sizeof.
O operador sizeof opera sobre o nome de um tipo de dado ou sobre o
nome de uma variável e resulta o seu tamanho em bytes. Veja um exemplo:
//S I ZEOF . CPP
//Mo stra o uso do ope rador s i z e o f
#inc l ude <io s t r e am.h>
un~on
. num
{
char str[2(fJ] ;
int i;
flo at f ;
} x; //Cria v ariável
void ma in ()
{
cout << s iz eo f(num ) << ' \n ';
cout << si z eo f(x);
}
Eis a saída:
2(/J
2(/J
Cap. 7 Estruturas 263
A expressão
siz e o f (num )
é equivalente a
sizeof( x )
~ "
UNIOES ANONIMAS
Uniões anônimas são uniões definidas sem a especificação do nome do tipo. Eis
um exemplo:
//UNION . CPP
//Mo stra o uso de u n iões anôn imas
#inc l ude <i o s tream . h>
#inc l ude <string.h>
#inc l ude < i o ma n ip.h>
v oid i nitnum(float n)
{
264 Treinamento em Linguagem C++ Cap. 7
tipo=floattipo;
f =n ;
)
void initnum(int n)
{
tipo=inttipo;
.
l. =n ;
}
void pr intfunc(void );
void ma in ()
{
float y =34 . 56 ;
int z = 345 ;
i n i tnum ( "VVB-TREINAMENTO" ) ;
printfunc();
initnum(z) ;
printfunc();
in i tnum (y) ;
p r intfunc();
void pr intfunc()
{
switch(tipo)
{
case strtipo :
cout << \nSt r =
11 11
<< str;
break;
case inttipo:
Cnp. 7 Estruturas 265
•
cout << " \ nint -11
<< l i
break ;
case floattip o :
cout << setprecision (2} ;
cout << ''\nFloat = " << f;
break ;
}
}
Uma união anônima não define um novo tipo de dado e sim declara
uma variável. Se esta variável for externa, deve obrigatoriamente ser também
estática.
A variável é acessada diretamente por meio dos nomes dos membros.
O operador ponto não é usado.
Quando criamos uma união anônima, devemos garantir que não haverá
conflito entre o nome dos membros e os nomes de variáveis de mesmo escopo.
.
unlOn num
{
char ch ;
int i ;
fl oat f ;
266 Treinamento em Linguagem C++ Cnp. 7
vo id ma in ()
(
num X i
cout << " \ nEnde r eço de c h -- " << unsign ed( &x. ch ) i
" \ nEnder eço . --
cout << de l " < < unsigned( &x. i ) i
cout << " \ nEnde r e ço de f - " < < unsigned( &x . f ) i
cou t << " \ nEndere ço de r ~
-- " << unsigned( &x. f ) i
Eis a saída:
Ende r eço de ch
.
- 65522
Endereço de l - 65522
Endereço de f - 65522
Endereço de f - 65522
Endereço de X -- 65522
..
UNIOES DE ESTRUTURAS
Uma união pode ter membros de qualquer tipo, inclusive estruturas ou outras
uniões. Uma união também pode ser membro de uma estrutura.
Veja um exemplo:
//UNISTRUC . CPP
//Mostra união de e struturas
#include <iostream.h>
vo id ma in ()
{
struct doisint
{
int nl;
int n2 ;
};
union intf l o
{
doisint x ;
float f;
}unex ;
cout << 11
\nunex . x . nl -
11
<< unex . x . nl ;
cout << 11
\nunex.x.n2 -
11
<< unex .x. n2;
une x . f = 345 . 22 ;
cout << 11
\nunex . f =" << unex . f ;
)
A saída será:
s iz eof(intflo ) - 4
unex . x . nl = 734
unex . x.n2 = 333
unex . f - 345 . 22 1])(/)QJl
A ROM BIOS
A maior parte das rotinas da ROM BIOS destina-se a imprimir em tela, escolher
o modo de vídeo, controlar o tamanho do cursor, ler e imprimir caracteres,
colocar um ponto em tela gráfica etc.
São fornecidas também funções para outros periféricos: manipulação
de discos, portas seriais, joysticks, teclado, impressoras etc.
Não exploraremos todas as rotinas da ROM BIOS. Para a completa
explanação de todas as rotinas, consulte o manual IBM Technica1 Reference ou
livros relacionados ao assunto.
1 byte 1 byte
Registrador AX
1 byte 1 byte
Registrador BX
1 byte 1 byte
Registrador CX
1 byte 1 byte
Registrador DX
1 byte 1 byte
Registrador AH Registrador AL
1 byte 1 byte
Registrador BH Registrador BL
1 byte 1 byte
Registrador CH Registrador CL
1 byte 1 byte
Registrador DH
D D Registrador DL
A idéia de usar urna mesma variável acessada corno dois tipos diferen-
tes parece familiar; ela é similar à nossa descrição de union.
De fato, union é o mecanismo usado para a comunicação com registra-
dores. Mas, antes de mostrarmos um exemplo, vamos explorar outro conceito.
NÚMERO DE INTERRUPÇÕES
As funções da ROM BIOS são acessadas por meio de um número que define
um grupo de funções chamadas interrupções. Cada grupo tem um número de
interrupção diferente. Por exemplo, todas as funções de tela usam a interrupção
Ox10, e todas as que fazem transações com discos usam a de número Ox13.
Portanto, para chamar urna função da ROM, precisamos primeiro conhecer seu
número de interrupção.
272 Treinamento em Linguagem C++ Cnp. 7
unsigned int di ;
un s i g ned int cflag ;
unsigned int f l ags;
};
Cnp. 7 Estruturas 273
s t ruc t BYTEREGS
(
unsigned char al ;
uns i gned c h ar ah ;
unsigned c h ar bl;
unsigned c h ar bh;
un s i g ne d char cl ;
unsigned c h ar c h;
unsigned c h ar dl ;
un s i g ned char dh;
} i
un l• on REGS
(
struct WORDREGS x;
struct BYTEREGS h ;
} i
,
DESCOBRINDO O TAMANHO DA MEMORIA PRINCIPAL
O nosso primeiro exemplo mostra o uso de uma função da ROM que retoma o
tamanho da memória principal instalada no seu computador.
Os dados requeridos por esta função estão no quadro a seguir:
//TAMMEM.CPP
//Imprime o tamanho da memór i a principal
#include <iostream . h>
#include <dos . h> // Para int86 () e REGS
vo id ma in ()
{
const MEM - 0xl2;
REGS regs;
cout << " \nTamanho da memór ia: " << reg s.x.ax;
)
LIMPANDO A TELA
Qualquer uma das duas pode ser chamada para limpar a tela toda ou
somente uma janela da tela.
Os dados requeridos por estas funções estão nos quadros a seguir:
CL = Coluna de início
DH = Linha de fim
DL = Coluna de fim
Registradores de saída: Nenhum
No nosso exemplo, usaremos a função Ox07 para escrever uma função
que limpa a tela toda e posiciona o cursor no canto esquerdo.
#include <dos . h>
cons t VI DEO = 0x l0 ;
void cls ()
{
REGS regs ;
regs . h . bh - 7. '
regs . h . ch -- 0;
regs . h . cl -- 0;
r egs . h . dh -- 24;
regs . h . dl -- 79;
const VIDEO = 0x 1 0;
278 Treinamento em Linguagem C++ Cap. 7
REGS regs ;
r e gs.h . ah - 0x01 ;
regs . h . ch - l inhai ;
r egs . h . cl - linhaf ;
int86(VIDEO ,& r egs , &r egs) ;
}
vo id ma i n ()
{
i nt li, lf;
while ( 1 )
{
if (l i < 0) brea k ;
s e l ecur( l i, l f ) ;
}