You are on page 1of 328

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Dev-C++ Dev-C++ Dev-C++ Dev-C++ Dev-C++ Dev-C++ Dev-C++ Dev-C++ Dev-C++

Dev-C++ Dev-C++ Dev-C++ Dev-C++ Dev-C++ Dev-C++

Dev-C++ Dev-C++ Dev-C++

Dev-C++
1

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

O
Manual de C++
Usando Ambiente de Desenvolvimento Integrado Dev-C++
e wxDev-C++
Andrew Fairbairn

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Muitos programadores experientes iro dizer que a linguagem C++ a mais eloqente e
poderosa linguagem de programao, mais rpida na execuo que por exemplo, Java, uma
linguagem que ganha espao entre preferncias, mas os adeptos de C++ esto crescendo
num ritmo acelerado. Hoje muitos dos programas como os jogos World of Warcraft, Mass
Effect e The Sims entre outros foram elaborados em C++. Sitios da Web como Chrome e
Facebook em sua maior parte, foram escritos em C++.
Para as pessoas que dominam esta linguagem, oportunidades surgem constantemente.
Num condomnio at no muito luxuoso foi sugerido pela Administrao um sistema
automtico de acesso pelos veculos dos moradores onde a placa do veculo entrando seria
filmado, e constando da lista de autorizados, ganharia acesso ao estacionamento interno.
Uma aplicao perfeita para um programa elaborado em C++.
Recentemente, implementaram algumas melhorias, lanando o C++11. Isto s para
mostrar que uma linguagem pode crescer, e ser melhorada, sob norma ISO/IEC 14882:2011.
Pergunto ento, estaria pronto para comear a trilhar por um caminho que poder lhe
trazer altos ganhos, um emprego cheio de desafios e satisfao pessoal? Estando de posse
deste livro j um timo comeo. Escrevi o livro prevendo as dificuldades que eu mesmo
sentia quando comecei, s vezes to fortes que cheguei concluso que ou eu era burro, ou
o livro que tentava me ensinar faltava a sensibilidade necessria para passar de maneira
mais simples as informaes que necessitava para realmente conheer a Linguagem. O
objetivo deste livro sobretudo, passar estas informaes de forma mais simples, expor a
linguagem de vrios ngulos e de proporcionar a grande satisfao de poder dominar C++,
e finalmente ter a sensao de poder declarar, viu, no sou burro, desvendei os mistrios e
dominei C++ graas em grande parte ao Manual de C++.
Andrew Fairbairn

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Agradecimentos

Agradecimentos especiais pelo excelente trabalho elaborado para desvendar o


programa wxDevC++ vo para Sof*t e todos os colaboradores de
wxdsgn.sourceforge.net.

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


ndice

Captulo
Captulo
Captulo
Captulo
Captulo
Captulo
Captulo
Captulo
Captulo
Captulo

1 Introduo........................................................... 6
2 Os Primeiros Passos........................................... 13
3 - Acrescentando Comentrios.............................. 17
4 Programa Interativo............................................ 19
5 O Poder de Deciso............................................ 37
6 O Poder do Lao ou (Loop em ingls)................ 47
7 Todos os Poderosos Segredos de Funes....... 62
8 Reservando memria usando Matrizes.............. 99
9 A funo switch case.................................... 113
10 Os segredos de Ponteiros (Pointers)................ 126
Elaborando grficos em movimento.................129
Como usar a funo vector (Vetor)...................145
Captulo 11 Todos os segredos de Estruturas (struct)........151
Construindo uma Base de Dados..................... 153
Captulo 12 Todos os segredos de Classes...................... 159
Captulo 13 Amizade e Herana........................................... 175
Captulo 14 - Criando, abrindo e fechando arquivos............. 186
Captulo 15 Polimorfismo e Membros Virtuais.................... 206
Captulo 16 Um projeto prtico de comunicao usando a
Porta Paralela LPT1 com indicao de 8 Leds.209
Captulo 17 namespace Desmistificado............................. 211
Captulo 18 Criando e usando Listas ligadas..................... 211
Projeto: Jogo da Velha.......................................................... 222
Projeto: Controlando caracteres na janela do DOS............. 223
Projeto: Jogo da forca........................................................... 237
Captulo 19 Como construir Caixas de Dilogo e de
Pop-Ups e Drop Down...................................... 244
No devemos usar esta pgina como uma medida de contedo
porqu esto includos nestes Captulos dezenas de programas
no listados aqui, desenvolvidos para ilustrar o uso de grande
maioria das ferramentas includas no Dev-C++, que realizam
dezenas de trabalhos diferentes.

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Captulo 1 - Introduo
Para aprender qualquer idioma, necessrio que o aprendiz
domine um alfabeto primeiro. Depois o aprendiz comea a formar
palavras, seguido de frases inteiras de acordo com a sntaxe do
idioma. Entendemos que a sntaxe do idioma so as regras que
temos de seguir para que uma frase seja compreendida por um
ouvinte ou leitor. Verificamos todos os dias o fato de muitas
pessoas ignorarem a sntaxe do idioma Portugus. Mesmo assim
podemos compreender o conteudo da frase. No entanto, quando
elaboramos um programa, no caso utilizando C++, o Compilador
no dotado de inteligncia artificial, ou outro mtodo que facilite
a traduo quanto ao desvio da sntaxe. O compilador de fato
somente ir traduzir uma frase de C++ quando a sntaxe
seguida rigorosamente. De contrrio, ele nos avisa de maneira
bem sucinta. Esta a parte chata de programao, mas ir
concondar comigo, inteiramente necessrio, pois quando
escrevemos um programa queremos que ele execute uma ou mais
tarefas exatamente como planejamos. Antes de comear, teremos
de aprender a pensar como pensa um programador. Algumas
perguntas relevantes surgem, tais como, O que faz um
Compilador?, seguido por O que um Pr-Processador?, O que
Programa Fonte?, O que um Linker? Calma, muito em breve
voc estar elaborando programas em C++ que funcionam, mas
antes devemos saber as respostas destas perguntas, pois so
importantes.

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Apesar de ser inteiramente transparentes para
compilador dever efetuar os seguintes trabalhos:

ns,

um

1 Um Pr-processador processa os Macros, Instrues de


Compilao Condicionais e os arquivos tipo Include;
2 Um Compilador reune o resultado gerado pelo Prprocessador e o Cdigo Fonte (o programa) e gera o Cdigo
de Montagem de Fonte;
3 Um Assembler (Montador) reune o cdigo gerado pelo
Compilador e produz uma Listagem de Montagem incluindo
os deslocamentos. A sada do Assembler posto no Arquivo
de Cdigo Objeto;
4 Um Linker reune os Arquivos de Cdigo Objeto ou Bibliotecas
como entrada e os combina num arquivo executvel que
possui a extenso .exe;
Sei que estas respostas geram outras perguntas, mas para que o
texto mantenha uma certa leveza, melhor irmos adiante pois as
respostas viro normalmente.
O ato mais importante agora o de obter um compilador que vai
ser nosso amigo ntimo daqu e adiante.
Para sistemas operacionais que utilizam Windows 98 e adiante,
recomendo este link: Clique no link abaixo com boto direito do
mouse, Abrir hiperlink->
http://www.baixaki.com.br/download/dev-c-.htm
Para sistemas operacionais que utilizam Linux, recomendo que
instalem o programa WINE, depois faa o Download de Dev-C++
usando o link supra. Na janela, escreva sudo apt-get install wine
para instalar o WINE. Em seguida cd ~/.wine/drive_c/Dev-Cpp/.
Para executar Dev-C++ ./devcpp.exe. Ter de associar arquivos
com extenso .exe WINE, seno ter problemas para abrir o
arquivo.

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Execute o programa baixado, devcpp-4.9.9.2_setup. Este estar
presente na pasta que normalmente utiliza para downloads.

Aps execuo, aparecer a tela de Dev-C++:

Se sua verso de Windows XP, tudo bem, mas se for Windows


Vista ou 7, clique com boto direito do mouse no cone devcpp e
Propriedades,
Compatibilidade
ou
use
o
Wizard
de
compatibilidade.

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Note o fato de todo texto estar em Ingls. Podemos escolher o
idioma. Clique em Tools, depois Environment Options e Interface.

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Podemos comear. Clique em Arquivo:

Clique em Novo e Projeto:

10

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Cique em Console Application (nem todo texto est em Portugus).
D um nome ao seu projeto. Em seguida clique em Projeto C++ e
OK:
Aparece uma tela onde dever armazenar seu projeto:

Seu projeto ter o nome Projeto1, no caso.


Clique em Arquivo, Abrir projeto ou arquivo, Projeto1:

11

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Veja na janela de Compilador. Existe um cone chamado main.cpp


que faz parte do projeto. main.cpp um nome padro, a
extenso .cpp quer dizer programa fonte C++. Veja tambm que
agora temos uma janela direita, onde podemos desenvolver
nosso programa, que chamamos Programa Fonte. Temos
operacional nosso Integrated Development Environment (IDE),
Devcpp.

12

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Captulo 2 Os primeiros passos


Para comear, clique na janela de texto direita. Escreva na
primeira linha,
#include <iostream>
Esta uma declarao ao pr-processador que manda incluir uma
biblioteca chamada de iostream. Trata-se de um programa
elaborado que tem o propsito de instruir o pr-processador que
dever adicionar o cdigo que compe iostream junto ao nosso
programa fonte, antes da criao do arquivo executvel. C++ j
possui vrios destes programas que teremos de incluir
dependendo do trabalho que nosso programa efetuar, de variadas
funes. Basicamente, iostream explica como enviar caracteres
tela do visor e o que fazer com os caracteres enviados pelo
teclado por intermdio das funes cout e cin. Esta declarao
de incluso chamada de arquivo de cabealho, e todo programa
ter pelo menos um deles. Na segunda linha, escreva using
namespace std;.
#include <iostream>
using namespace std;
Note que terminamos esta linha com ponto e vrgula, que sinaliza
ao compilador que terminamos a instruo, ou que esta uma
funo, no caso namespace std, e fazem parte da sntaxe de C++.
Quase todo programa em C++ ter esta linha logo abaixo do
cabealho. using namespace std; diz ao compilador que dever
usar um grupo de funes que fazem parte da biblioteca padro
std. Logo mais saberemos o significado de using namespace
std. Por hora, completaremos nosso primeiro programa.

13

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

#include <iostream>
using namespace std;
int main ()
{
Acrescentamos uma funo chamada main. Esta funo sempre
ser a primeira a ser executada. Os parnteses (vazios neste
caso), indicam que se trata de uma funo que poder conter
parmetros. int na frente de main () indica ao compilador que a
funo poder receber apenas parmetros de tipo inteiro,
enquanto que a chaveta { indica que o corpo da funo segue.
#include <iostream>
using namespace std;
int main ()
{
cout << Oi Mundo, aqui vai meu primeiro programa em C++\n;
system(pause);
return 0;
}
Aqui, C++ usa a funo cout para visualizar todo o texto entre
aspas. Basicamente este texto enviado para cout que utiliza o
smbolo de muito menor que, ou << para mostrar a direo da
operao. A funo cout tem sua definio em iostream que
permite esta operao. Includo no texto temos \n que o
compilador entende como sendo nova linha, o mesmo efeito que o
uso da tecla Enter que move o cursor para incio da prxima
linha. Resta uma observao, C++ no aceita letras acentuadas,
que uma pena. De fato nenhum compilador que eu conheo
aceita. system(pause); uma funo que diz ao compilador
para esperar a entrada de uma tecla qualquer antes de prosseguir
com a execuo. No tivesse incluido esta instruo, no seria
possvel ver o resultado da execuo de nosso programa pois
passar to rapidamente que no veriamos nada acontecendo.
14

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Usaremos este meio de pausar antes de encerrar, muitas vezes.
Declaramos a funo main () como uma que aceita dados de tipo
inteiro, portanto devemos declarar um retorno, no caso return 0;
Isto nos diz que o programa executou corretamente.
Para concluir, a chaveta } diz ao compilador que estamos no fim
da funo main, e encerramos o programa.
Vamos ento compilar nosso primeiro programa?

Ao terminar a digitao de seu primeiro programa, selecione o tab


Arquivo, Salvar como...um nome relevante por exemplo, Oi Mundo.
Este programa agora faz parte de Projeto1, que um nome padro.
Podiamos ter chamado nosso primeiro projeto de qualquer nome.
Somente criamos um projeto para mostrar que no futuro iremos
usar um projeto, mas por enquanto no precisamos que nossos
programas faam parte de um projeto. Em todos o casos usaremos
a seqncia Arquivo, Novo, Arquivo fonte, Arquivo, Salvar
como...nome de seu programa (at antes de escrev-lo).
15

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Ter de salvar o programa, portanto aparece a tela que permite


realizar este feito. Chamei este programa de Primeiro_programa.
Verifique este fato na janela esquerda logo embaixo de Projeto1.
Aparece uma janela parecendo um quadro negro mostrando o
resultando da execuo. Use qualquer tecla para fechar a janela.
Esta janela d acesso ao DOS. De fato, executaremos a maioria
dos
programas em ambiente DOS ao longo do livro. Isto
aconteceu porque escolhemos Console Application quando
configuramos nosso novo projeto. Para quem gostaria de saber,
DOS se traduz em Disk Operating System que o Windows usa
para efetuar a maioria dos trabalhos de entrada e sada internos
no computador.
Clique na opo Log do Compilador.

16

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Aqui temos informaes de tamanho do programa executvel,


Total de Erros e uma listagem das operaes efetuadas.
Estando satisfeito com seu programa, tente acrescentar texto.
Fingir que esqueceu de colocar um ponto e vrgula aps uma
instruo seria um bom teste para ver os tipos de erros que o
compilador emite. Qualquer um poder esquecer este pequeno
detalhe, pode acreditar. Faz parte dolorosa da programao, e
depois alegria quando sanamos o problema.

Captulo 3 - Acrescentando Comentrios

Nosso primeiro programa bem simples, mas quando


desenvolvemos programas de algum porte ser uma ideia muito
boa acrescentar comentrios pois mesmo elaborado a noite
anterior, quando revisar o trabalho na manh seguinte vamos
esbarrar numa instruo que nos faz perguntar, Para qual
propsito fiz isto? Tivesse um comentrio iria saber a razo. Se
deu este n em voc, imagine outra pessoa.
Para alertar o compilador que Esta seqncia de texto um
comentrio, ele ir ignorar o texto na hora da compilao.
Fazemos isto com uso de duas barras inclinadas na mesma linha
que a instruo, ou uma barra e asterisco quando o comentrio
ocupa mais de uma linha:
(Instruo1); //Este um comentrio.
//
(Instruo2); Esta instruo no ser executada.
(Instruo3); /*Incio de comentrio em bloco.
Este comentrio faz parte do bloco.
Fim de comentrio em bloco.*/

17

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Veja o caso da instruo2. Qualquer texto direita das barras ser
ignorado pelo compilador. Este fato muito til para sanar onde
encontram-se erros no programa. Vale salientar que erros podem
ter duas orgens. Um se deve sntaxe, o outro ordenao de
instrues para realizar um trabalho corretamente. Para elaborar
programas que funcionam, necessrio prever todas as variveis
de uso. Voltando nossa ateno todas as informaes que
absorvemos at agora, seria natural achar que entendemos tudo.
A melhor maneira de fixar todos estes novos conceitos na
memria, fazer um teste de nossos conhecimentos.
Um pequeno teste Teste 1:
1) Qual a nica funo que todos os programas em C++ contm?
a) include
b) main()
c) return()
d) {
2)
a)
b)
c)
d)

Qual a funo que usamos para direcionar caracteres ao visor?


send;
using;
cout <<;
nenhum dos acima;

3)
a)
b)
c)
d)

Para indicar ao compilador o incio da funo main(), usamos?


[
>>
}
{

4) Que tipo de puntuao termina uma linha de programa?


a);
b):
c),
d).

18

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


5)
a)
b)
c)
d)

Qual o arquivo de cabealho que permite acesso cout?


Nenhum, o sistema automaticamente fornece acesso
<stringstream>
<iostream>
using namespace std;

6)
a)
b)
c)
d)

Qual dos comentrios o correto?


*/ comentrio */
/ comentrio
//* comentrio
// comentrio

7) Elabore um programa que escreve seu nome na tela. Compilou


corretamente? Executou sem rros? Se as respostas so
afirmativas, um grande parabns para voc. Seno, procure no
programa fonte se esqueceu de acrescentar ; ou {, ou } ou # ,
este ltimo antecede include <iostream>.
Respostas do Test1:
1) b; 2) c; 3) d; 4) a; 5) c; 6) d;

Captulo 4 Programa Interativo


Temos conhecimentos agora para elaborar um programa que envia
texto tela. J um grande feito. No entanto, um programa de
mo nica. Nosso desejo interagir com o programa, e podemos
realizar esta faanha passando texto e nmeros para ele. No
entanto, a entrada de texto ou nmeros ter de ser armazenado no
programa, mais precisamente na memria. Usamos como memria
as chamadas variveis. Usamos vrios tipos de variveis para este
fim, e para usar uma varivel de determinado tipo, temos de
declarar a varivel e o tipo, e inicializ-la tambm. Veja a lista de
tipos de variveis para armazenar nmeros e caracteres e seus
limites, abaixo:

19

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


short int pode ser qualquer nmero entre 32.768 e at 32.767;
signed int ou apenas int pode ser qualquer nmero entre
---2.147.483.648 e +2.147.483.647;
unsigned int pode ser qualquer nmero entre 0 e 4.294.967.295;
unsigned short pode ser qualquer nmero entre 0 e at 65.535;
long pode ser qualquer nmero entre 2.147.483.648 e at
2.147.483.647;
unsigned long
4.294.967.295;

pode

ser

qualquer

nmero

entre 0

at

float pode ser qualquer nmero inclusive de ponto flutuante


(frao) 3,4E+/-38 em notao cientfica, e equivale a 3,4 x 10+/-38;
double pode ser qualquer nmero de ponto flutuante 1,7E+/-308;
char um caractere que consta da Tabela ASCII;
string uma seqncia de caracteres e espaos;
Todas as variveis da lista menos string, C++ reconhece
automaticamente. Para usar a varivel string teremos de incluir
um arquivo de cabealho chamado <string>. Esta biblioteca
explica ao sistema como manuseiar este tipo de entrada.
Veja alguns exemplos de declaraes de variveis:
int numero;

/*Declaramas a existncia de uma varivel de tipo


inteiro chamado de numero que aceita apenas
nmeros entre --2.147.483.648 e +2.147.483.647;
*/

20

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


/*Declaramos a existncia de uma varivel
de tipo string de nome nome que aceita
uma seqncia de caracteres incluindo
espaos */
char caractere; // Declaramos uma varivel de tipo char
cout << int (caractere); // Imprimimos o cdigo ASCII da letra
string nome;

A varivel char armazena apenas um caractere. Se pretende usar


mais de um caractere, ter de usar uma matriz de tipo char. (Veja
o uso de matrizes adiante). Se declaramos e inicializamos uma
varivel de tipo char, exemplo: char letra = a; podemos anular a
varivel por intermedio da declarao: letra = \0; Neste caso
escrevemos um caractere nulo para memria onde estava
armazenado o caractere a.
Vamos logo ao nosso primeiro programa interativo. Est pronto?
Claro que est!
Nosso programa pergunta o nome e idade de uma pessoa. Em
seguida, envia estas informaes tela. Est de bom tamanho?
Execute Dev-C++. Se Projeto1 est ativado ainda, clique em
Arquivo, Salvar Projeto, Fechar Todas. Clique em Arquivo
novamente, e Novo, Arquivo Fonte. Neste caso, o programa no
far parte de um projeto. Clique novamente em Arquivo, Salvar
como, d um nome, OK.
Prepare os dedos. Tecle o seguinte programa:
#include <iostream>
#include <string>
using namespace std;
int main()
{
int idade;
string nome;
cout << "Favor digitar seu nome: ";
cin >> nome;
cout << "\nFavor digitar sua idade: ";
21

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


cin >> idade;
cout << "Seu nome e " << nome << " e voce tem " << idade <<
anos" << endl;
system("pause");
return 0;
}
Clique em Arquivo, Salvar como...nome de seu programa.
Compilar e executar seu primeiro programa interativo. Na janela
do DOS, aps digitar seu nome acione a tecla Enter no teclado, o
mesmo aps escrever sua idade. Os dados apenas sero passados
para suas respectivas variveis aps C++ receber o cdigo da
tecla Enter em cada caso.
Pressione qualquer tecla para fechar, quando cansar de admirar a
sua obra prima. Salve seu programa, Arquivo, Salvar como..., OK.
Vamos analisar o programa pois temos muitas novidades. Veja que
incluimos
o arquivo de cabealho, #include
<string>.
Declaramos duas variveis, um de tipo inteiro que aceita apenas
nmeros, que chamamos idade, a outra de tipo string que
chamamos nome. Devemos sempre usar nomes de variveis que
descrevem seu conteudo. Torna-se mais fcil entender o
programa.
Note inclusive que declaramos as variveis aps o incio de main
({). Isto significa que estas variveis somente podero ser
acessadas de dentro da funo main. Poderiamos declarar as
variveis antes de main (), e o programa funcionaria
perfeitamente. No entanto h uma distino entre declaraes de
variveis dentro de uma funo, e fora dela. H razes lgicas
para esta distino, mas entenderemos isto ao longo do livro.

22

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


A primeira funo cout << enviou para tela um pedido de dados de
entrada, e vai esperar este acontecimento atravs da funo cin
>>. O compilador sabe que trata-se de entrada de uma seqncia
de caracteres, a string, pois dissemos que a string ser salva na
varivel tipo string chamada nome. Uso da tecla Enter sinaliza o
trmino de entrada de dados. Note o identificador de muito maior
que, (>>) apontando na direo da varivel. Estou fazendo esta
discriminao de identificador para no esquecermos a sntaxe
entre cin e cout. Em cout o operador << vai para (direo das
pontas de flechas) esquerda, enquanto que cin vai para (direo
das pontas de flechas) direita, uma varivel normalmente, mas
nos dois caso poder ser outro destino. O segundo uso de cout
tem no incio do texto a seqncia \n. Colocamos este aqui e no
no fim de cout anterior porqu queremos a string nome na mesma
linha que a pergunta, s para efeito de esttica. Olhe mais de
perto, e notar que apenas texto est delimitado por aspas, mas
no o contedo das variveis. De fato o compilador sabe que deve
enviar o contedo, e no o nome das variveis. Isto poder
parecer bvio. Portanto, cuidado para no colocar aspas em torno
de nomes de variveis. Veremos que cin e cout so muito
versteis. No terceiro uso de cout usamos os operadores de
insero (<<) para escrever o texto e as variveis na mesma linha.
Acrescentando espaos aos pedaos de texto entre o contedo
das variveis evita que se juntam ao executar o programa. No final
desta linha, o uso da seqncia endl que o mesmo que \n
para todos efeitos. system uma palavra-chave, uma funo
com parmetro, no caso este parmetro pause que pausa a
execuo do programa neste ponto, mas seu uso estar restrito
programas onde precisamos ver o resultado da compilao.
Existem as funes cin.ignore() usado em conjunto com cin.get(),
ou getch() usando <conio.h> que realizam o mesmo trabalho que
system(pause), uma das funes de <iostream>. Usaremos este
ltimo por simplicidade por enquanto.

23

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Da mesma forma que enviamos dados mltiplos de sada, cada um
antecedido pelo prprio identificador (<<), podemos modificar
nosso programa interativo para obter entradas mltiplas:
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string nome;
int idade;
cout << "Favor digitar seu nome e sua idade: ";
cin >> nome >> idade;
cout << "Seu nome e " << nome << " e voce tem " << idade <<
"anos" << endl;
system("pause");
return 0;
}
No Dev-C++ clique em Arquivo, Arquivo Novo, Arquivo novamente,
Salvar como...Salvar com nome apropriado. Escreva o programa na
janela direita, e Salvar como...novamente. Clique em Executar,
Compilar e Executar ou pressione F9 no teclado. Na janela de DOS
que aparece (o quadro negro), teclamos um nome, espao e idade
seguido de Enter, como tambm podemos usar nome Enter idade
Enter. No primeiro caso o compilador reconhece a string de nome,
encerra entrada de nome, reconhece o inteiro idade e os transfere
para as respectivas variveis. Ento voc pergunta, como que o
compilador pensa que um caractere espao no faz parte da
string?
A resposta que a funo cin apenas aceita caracteres at ler o
cdigo do caractere espao. Fim da string pensa ele, mas a
verdade que uma string normalmente contm espaos entre
palavras. A sada para este dilema simples, usamos outra funo
quando temos mais de uma palavra na string.

24

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Queremos que nosso programa aceite o nome completo da pessoa.
No podemos usar a funo cin porqu este somente l a primeira
seqncia de letras.
Usamos ento a funo getline (cin, varivel tipo string, \n).
getline uma sub-funo de cin. A sub-funo usa cin como
fonte, a varivel de tipo string onde ser armazenada a string, e
um caractere que termina a string, no caso tecla
. Note que
cada argumento separado com vrgula, o ltimo argumento usa
aspas simples. Ento voc pergunta, o que uma funo? Esta
uma pergunta muito pertinente, porqu funes iro fazer parte de
muitos dos programas que iremos montar. Por hora, podemos dizer
que usaremos dois tipos de funes, um elaborado por algum
programador que no conhecemos, mas que disponibiliza o cdigo
pronto, no caso de getline, por exemplo, que o nome da funo.
Funes utilizam argumentos, normalmente contidos entre
parnteses. Para este, os argumentos so cin, uma varivel tipo
string, e a tecla Enter. Esta a sntaxe da funo getline.
Outras funes sero escritas por ns mesmos para realizar
trabalhos que particularmente necessitamos. No iremos entrar na
questo de funes ainda, pois tero um captulo nico adiante.
Veja o programa abaixo:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string nome_completo;
int idade;
cout << "Digite seu nome completo: ";
getline (cin, nome_completo, '\n');
cout << "\nDigite sua idade: ";
cin >> idade;

25

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


cout << "\nSeu nome completo e " << nome_completo << " e voce
tem " << idade << " anos. \n";
system("pause");
return 0;
}
Veja a declarao da varivel de tipo string chamada de
nome_completo. No podiamos usar nome completo porqu o
compilador consideraria o nome da varivel como sendo apenas
nome e emitiria erro, pois a sntaxe da declarao de uma
varivel tipo nome; Usando a barra de sublinhar junta as duas
palavras de modo que podemos entender, mas mantm a sntaxe.
Note que usamos duas chamadas de funes de entrada, a
primeira, getline com os argumentos, que salva a seqncia de
teclas incluindo espaos na varivel de tipo string chamada
nome_completo que termina com a tecla Enter, e a funo cin que
salva a seqncia de nmeros na varivel de tipo inteiro chamada
idade.
Poder surgir a ocasio em que temos a necessidade de juntar
duas ou mais seqncias de letras usando cin. Podemos usar o
smbolo aritmtico de somar +:
#include <iostream>
#include <string>
using namespace std;
int main()
{
int idade;
string primeiro_nome;
string sobrenome;
string nome_completo;

26

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


cout << Digite seu primeiro nome: ;
cin >> primeiro_nome;
cout << \nDigite seu sobrenome: ;
cin >> sobrenome;
nome_completo = primeiro_nome + + sobrenome;
cout << \nDigite sua idade: ;
cin >> idade;
cout << \nSeu nome completo e << nome_completo << e
voce tem << idade << anos.\n;
system(pause);
return 0;
}
Aqui temos duas novidades. Neste programa efetuamos uma
concatenao de primeiro_nome com sobrenome. Em seguida
salvamos o resultado da operao (concatenar primeiro_nome
mais um espao mais sobrenome) na varivel nome_completo.
Quando salvamos dados numa varivel, o movimento dos dados
sempre de direita para esquerda. Para explicar de forma simples,
faamos um pequeno teste:
Pense no nmero 6;
Somar 4;
Subtrair 3;
O resultado ?
Para ns fcil resolver o teste de cabea, mas vamos agora
parar para analisar a seqncia de nossos pensamentos. Primeiro,
guardamos em nossa memria o nmero 6. Depois guardamos o
nmero 4. Depois fizemos a soma do conteudo destas duas
memrias e salvamos o resultado nmero 10 em outra memria.
Neste momento temos 3 memrias guardando dados. Em seguida
guardamos o nmero 3 em outra memria e subtraimos o conteudo
desta memria do conteudo da memria onde est guardado o
nmero 10. Guardamos o resultado nmero 7 em outra memria.

27

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Escreva um programa que realiza o pequeno teste:
#include <iostream>
using namespace std;
int
{
int
int
int
int
int

main()
primeiro_numero;// Declarao das variveis
segundo_numero;
soma;
terceiro_numero;
resultado;

primeiro_numero = 6; // Inicializao da varivel com 6


segundo_numero = 4; // Inicializao da varivel com 4
soma = primeiro_numero + segundo_numero; /* O resultado da
operao aritmtica de somar guardado na varivel
soma */
terceiro_numero = 3;
resultado = soma - terceiro_numero;
cout << "O resultado = " << resultado << "\n";
system("pause");
return 0;
}
Veremos em breve que nossos programas podero resolver
qualquer operao de matemtica e nos fornecer o resultado
instantaneamente, mas antes temos de aprender como montar as
instrues de forma eficiente. A trilha longa, mas no vai ser
complicada.
Contudo, gostaria de salientar um problema que ocorre quando
usamos cin, seguida por getline(cin, nomequalquer). A funo cin
l um nmero ou caractere at a tecla \n, mas deixa \n no buffer
(memria) de entrada. Em seguida getline(cin, ) l a \n e encerra
esta operao sem ler as letras que seguem. Para que o buffer
esteja vazio e no com \n no incio, usamos a funo cin.ignore()
para remover o smbolo de nova linha. Para demostrar isto,
execute o programa abaixo:
28

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


#include <iostream>
#include <string>
using namespace std;
int main()
{
int num1, num2;
string str;
cout << "Digite dois numeros " << endl;
cin >> num1 >> num2;
cout << "A soma dos numeros = " << num1 + num2 << endl;
//cin.ignore();
cout << "Digite uma string " << endl;
getline(cin, str);
cout << "A string que digitou = " << str << endl;
return 0;
}
Nesta verso a funo cin.ignore(); no foi executada, e a ltima
cout no imprimiu a string. Agora, delete as duas barras de
comentrio para que cin.ignore() seja executada. A string
imprimida. Maravilha, no? Este um problema que assombra at
alguns programadores experimentados, mas agora que est de
posse da soluo, no acontecer com voc.
Em muitas ocasies surge a necessidade de processar uma string.
O melhor mtodo a chamada iterao onde cada caractere
separado em sequncia e ento fazemos algo com aquela letra.
Temos disponveis na biblioteca <cctype> as funes islower(),
tolower(), isupper() e toupper(). Estas funes verificam se uma
letra minscula (islower), maiscula (isupper), e converte uma
letra minscula em maiscula (toupper), ou vice versa. Veja o
programa abaixo:

29

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


#include <iostream>
#include <string>
#include <cctype>
using namespace std;
int main ()
{
string str;
cout << "Favor digitar um texto: ";
getline(cin, str);
for (string::iterator it=str.begin(); it!=str.end(); ++it)//<string>
{
if(islower(*it))//<cctype> *it aponta para o incio da string
{
*it = toupper(*it);
}
cout << *it;
}

cout << endl;


system("pause");
return 0;

Guardamos um texto na varivel tipo string de nome str. Em


seguida estabelecemos um loop for com parmetros que declaram
um iterador de string chamada de it, string::iterator it e o
inicializamos apontando para a primeira letra do texto usando a
funo str.begin(). O segundo parmetro o teste de fim da string,
it!=str.end(), e enquanto o iterador no encontra o valor nulo, \0
no final da string, incrementa o iterador ++it. A qualquer instante,
*it aponta para uma nova letra . Em seguida verificamos se a letra
minscula islower(letra), e caso verdadeiro, toupper(letra)
converte a letra em maiscula e a imprimimos.

30

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


O elemento bsico que o computador digital utiliza para realizar
todas as operaes internas e externas o chamado bit do
Ingls que significa pedacinho. Cada bit possui dois estados, ou
ligado (estado de 1), ou desligado (estado de 0). Dizemos que um
bit possui a capacidade de transmitir 2 1 ou 2 estados.
Acrescentando mais um bit, cada um com 21 estados, temos a
capacidade de transmitir 21+1, ou 22 = 4 estados com 2 bits, 00, 01,
10, 11, trs bits, 23 ou 8 estados em paralelo. A comunicao de
dados efetuada por linhas em paralelo, onde cada linha
representa um bit. Este o sistema binrio. Oito linhas podem
representar 28 nmeros, ou em valor decimal, 256 nmeros, sendo
que sempre comea com nmero 0, portanto so 255 nmeros
positivos. 8 bits formam um Byte. Cada caractere ocupa uma
memria de 1 Byte. Dois Bytes podem representar at 216 nmeros,
ou 65.535 nmeros decimais incluindo zero. Um computador
moderno possui 64 linhas em paralelo, ou 264 variaes diferentes
que traduz em 18.446.744.073.709.551.616 de nmeros decimais.
Um inteiro ocupa 4 Bytes, ou 232 possveis combinaes, uns 4
bilhes de nmeros diferentes, mas quando queremos expressar
um nmero negativo, este valor dividido em dois, a outra metade
corresponde a nmeros maiores que zero. Normalmente
programadores utilizam as variveis int e double, pois so
adequados para representar qualquer nmero que pretendemos
processar.
C++ possui meios de abreviar as operaes aritmticas usando
variveis.
Quando o desejo o de alterar o valor de uma varivel, as sntaxes
so as seguintes:

31

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


a += b o mesmo que a = a + b;/*Salvar em a o resultado da
soma dos conteudos de a e b */
a -= 3 o mesmo que a = a 3;/*Salvar em a o resultado da
subtrao de 3 do conteudo de a */
c /= b o mesmo que c = c / b;/*Salvar em c o resultado da
diviso do conteudo de c pelo conteudo de b */
a *= b o mesmo que a = a * b;/ Salvar em a o resultado da
multiplicao dos conteudos de a e b */
b = 5; a = ++b;/*Neste caso o conteudo de b incrementado com
1 antes da transferncia para a, portanto a = 6, b = 6; */
b = 5; a = b++;/*Neste caso b incrementado com 1 aps a
transferncia para a, portanto a = 5, b = 6; */
Para certificar-mos da veracidade das ltimas duas afirmaes,
podemos executar este programa:

32

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


#include <iostream>
using namespace std;
int main ()
{
int b = 5;//Declarao e inicializao de variveis
int a = 0;
a = ++b;//Incrementamos b+1 antes de enviar para a
cout << "b = 5, a = ++b " << a << " " << b << "\n";
b = 5;//Inicializamos novamente as variveis
a = 0;//pois j foram usados anteriormente
a = b++;//Incrementamos b+1 aps o envio para a
cout << "b = 5, a = b++ " << a << " " << b << "\n";
system("pause");
return 0;
}

Vimos que podemos montar um programa para somar e subtrair.


Podemos acrescentar a multiplicao e a diviso tambm, mas
agora temos de considerar que tipos de variveis podemos usar.
Vejamos o que poder acontecer:
int num1 = 5; // Declaramos e inicializamos a varivel tipo int
int num2 = 3;
int resultado = num1 / num2;/* Aqui num1 o numerador, num2 o
denominador */
Podemos declarar e inicializar uma varivel em apenas uma
operao. Tudo bem, mas veja a terceira linha de cdigo.
Declaramos a varivel resultado como tipo int, onde ser guardado
o resultado da diviso, 5 / 3. Bom, sabemos que 5 no divisivel
por 3 em termos de nmeros inteiros, e o resultado retornado ser
1, o restante ser descartado. A resposta correta de 5 dividido por
3 = 1,6667 arredondados.

33

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Veja as operaes aritmticas permitidas:
+
ADIO
SUBTRAO
* MULTIPLICAO
/
DIVISO
%
MODULO
Modulo significa o restante ou sobra. Temos duas opes para que
o resultado da diviso seja correta.
A primeira opo seria incluir o modulo na operao:
int resultado = num1 / num2; //resultado = 1
int restante = num1 % num2; //Obter o restante = 2
Tudo isto me parece muito complicado. A segunda opo muito
mais prtico.
C++ permite declarao mltipla de um tipo de varivel e neste
caso podemos faz-la:
#include <iostream>
using namespace std;
int main ()
{
double num1, num2, resultado; /*Declaramos
separado com vrgula, tipo double */

variveis

cada

num1 = 5;// Inicializamos num1 com nmero 5


num2 = 3;// Inicializamos num2 com nmero 3
resultado = num1 / num2; /*Dividir num1 por num2. O resultado da
diviso colocado em resultado*/
cout << resultado << \n; /*O conteudo de resultado vai para cout
que o envia para tela*/
system(pause);
return 0;
}// Fim de main
34

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


A pergunta : ser que declarando num1 e num2 como tipo inteiro,
resultado como tipo double, o programa funciona corretamente?
Faa este exerccio como verificao. Deu certo? No. Isto porque
C++ no permite a mistura de tipos de variveis. Quando em
dvida, declare todas as variveis envolvidas numa operao
como mesmo tipo para evitar dores de cabea. Uma razo sbia
para inicializar variveis com 0 por exemplo, porqu quando
declaramos uma varivel, ela poder conter qualquer valor.
Ento, deu para lembrar tudo? Hmmm, temos muitas coisas novas.
Em todo caso, est a um teste.
Um pequeno teste: Teste 2
1) Que tipo de varivel dever usar para salvar um nmero com
frao (2,812) por exemplo?
a) int;
b) C++ automaticamente reconhece um nmero com frao;
c) double;
d) string;
2)
a)
b)
c)
d)

Como obtemos acesso entrada de dados tipo string?


Declaramos uma varivel de tipo string;
C++ no processa este tipo de dados de entrada;
Incluimos o arquivo cabealho <string>;
Incluimos o arquivo cabealho <iostream>;

3)
a)
b)
c)
d)

Em quais destas opes inicializamos uma varivel?


int numero;
double numero_grande;
numero = 2;
int numero = 0;

4)
a)
b)
c)
d)

Qual a funo que permite entrada de uma frase?


char;
string;
getline;
iostream;
35

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


5)
a)
b)
c)
d)

Ao executar cout << 5/6; C++ imprime qual resultado?


0;
1;
0,83334;
C++ no suporta este tipo de diviso;

Respostas do Teste 2: 1) c; 2) c; 3) c,d; 4) c; 5) a;

Captulo 5 O Poder de Deciso

A capacidade de poder tomar decises eleva nossos programas


outro nvel, o mesmo que injetar uma dose grande de inteligncia
num programa. Tomamos decises todos os dias sem pensar
muito na maneira que usamos para escolher o caminho, resultado
de uma deciso. Desde o dia que nascemos, estou sentindo fome,
vou gritar em alto e bom som! A deciso de gritar ou no depende
do quanto a sensao de fome est nos incomodando. Seu chefe
aparece diante de sua mesa e pede para fazer 10 cpias de um
documento. Ns no estamos cientes disto, mas antes de tudo
mentalizamos um algoritmo que atende o pedido. Algo assim:
1)
Levar o documento at a mquina copiadora;
2)
Verificar se temos folhas suficientes para fazer as 10 cpias;
3)
Configurar a mquina para fazer 10 cpias;
4)
Inicializar a mquina;
5)
Contar as cpias para verificar se a mquina realmente
realizou o trabalho;
6)
No esquecer o original na mquina;
Todas estas aes dependem de decises que tomamos baseadas
em informaes que temos disponveis para realizar o trabalho.
Vamos abrir nossa caixa de ferramentas e ver o que temos
disponvel para este fim:
Os operadores de lgica Booleana so: !, && e || (NO, E e OU)

36

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Para no complicar muito, uma comparao Booleana sempre
rende um de dois resultados possveis, Verdadeiro ou Falso. Veja
alguns exemplos:
Se o resultado NO igual a um nmero predeterminado, a
comparao retorna Falso (retorna 0);
Se (um nmero E o resultado so iguais), a comparao retorna
Verdadeiro (retorna 1);
Se (um nmero OU um resultado so de mesmo valor), a
comparao retorna Verdadeiro;
if (!a==b && a==c)

/*Se (a NO == b E a == c) sendo verdadeira,


execute o bloco a seguir*/

if (!a==b || a==c) /*Se (a NO == b OU a == c) sendo verdadeira,


execute o bloco a seguir*/
Note que usamos o sinal de igualdade
comparamos os conteudos de duas variveis.

em

duplo

quando

Veja a tabela de operadores relacionais com exemplos, abaixo:


Operador
>
<
>=
<=
==
!=

Significado
Maior que
Menor que
Maior ou igual
Menor ou igual
Igual a
No igual a

Exemplo
3>2
3<2
3>=3
3<=2
3==3
3!=2

Retorna
Verdadeiro
Falso
Verdadeiro
Falso
Verdadeiro
Verdadeiro

Para o compilador, uma expresso avaliada retorna 1 se o


resultado da avaliao verdadeiro, e 0 no caso de falso. Para
todos os testes de comparao, usamos a declarao if para
testar uma expresso.

37

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Se temos uma declarao como if ( 1 ), o cdigo que segue esta
declarao ser executado sempre, ao passo que if ( 0 ), o
cdigo que segue esta declarao nunca ser executado.
As palavras na lingua Inglsa que correspondem s palavras em
Portugus, verdadeiro true, falso false. Surge ento o
tipo de varivel chamado bool. Usamos este tipo porqu sempre
retorna 1 ou 0.
Usamos a declarao if e else em conjunto que traduzido diz
se isso verdadeiro, execute este cdigo, seno execute aquele
cdigo.
A sntaxe da declarao if-else :
if ( expresso )
{
//Verdadeiro, execute este cdigo;
}
else
{
//Falso, execute este cdigo;
}
Nada melhor que colocar em pratica o que acabamos de aprender,
no ? Vamos ento elaborar nosso primeiro programa
inteligente.
O usurio entra com um nmero. Nosso programa ir decidir se o
nmero positivo ou negativo.

38

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


#include <iostream>
using namespace std;
int main ()
{
int numero;
cout << "Digite um numero: ";
cin >> numero;
if ( numero < 0 )
{// Chaveta de inicio do cdigo a executar se for retornado 1
cout << "\nO numero digitado e negativo.\n";
}// Chaveta de fim do cdigo
else
{// Chaveta de inicio do cdigo a executar se for retornado 0
cout << "\nO numero digitado nao e negativo.\n";
}// Chaveta de fim do cdigo
system("pause");
return 0;
}
Execute o programa. Com le podemos diferenciar entre nmeros
positivos, contando 0 como um nmero positivo, e nmeros
negativos. Note que quando digitamos um nmero negativo, este
nmero menor que 0, a comparao verdadeira, portanto
executado o cdigo entre as chavetas de incio e fim, que segue a
declarao if. Se digitarmos um nmero 0 ou positivo, a expresso
retorna 0 ou falso e o programa pula o cdigo a procura de else e
executa o cdigo que segue este.
Veremos que a declarao if-else poder ser usada quantas vezes
forem necessrios para reduzir vrias condies a uma nica
resposta.

39

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Para demostrar isto, vamos modificar nosso programa para
detectar a entrada de nmeros 0, positivos e negativos:
#include <iostream>
using namespace std;
int main ()
{
int numero;
cout << "Digite um numero: ";
cin >> numero;
if ( numero==0)//Comparamos o valor digitado com 0
{
cout << "Voce digitou o numero 0.\n";
}
else if ( numero<0 )//Estamos aqui porque valor digitado no 0
{
cout << "Voce digitou um numero negativo. \n";
}
else//Estamos aqui porque o valor s pode ser positivo
{
cout << "Voce digitou um numero positivo. \n";
}
system("pause");
return 0;
}
A declarao else-if fornece os meios de poder testar uma
segunda comparao, caso a primeira retorne falso (0).
Por
enquanto nossos programas testaram apenas uma condio cada
tentativa, mas temos as ferramentas que permitem testar duas ou
mais condies cada tentativa. Para este fim que existem os
operadores de lgica Booleana.

40

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


O operador NO (!) de C++
Analise este trecho de cdigo:
if (!0) retorna verdadeiro (1);
De mesma forma:
if (!1) retorna falso (0);
Este apenas inverte o argumento sendo testado. Se o argumento
verdadeiro, retorna falso e vice versa;
O operador E (&&) de C++
if (a==1 && b==3) Este retorna verdadeiro somente quando os dois
argumentos so verdadeiros;
Se o primeiro argumento falso, os argumentos a direita no so
testados abrindo espao para uma tcnica chamada de curtocircuito;
Um exemplo:
if (x!=0 && 2/x<0)//Sendo os dois argumentos verdadeiros
{//execute este cdigo
cout << 2/x = um numero negativo;
}
No permite a diviso (2/x) se o valor de x for zero, que geraria
erro. De outro modo teriamos de acrescentar duas declaraes if.
O operador OU (||) de C++ (Duas barras verticais)
if (a==1 || b==1) Este sempre retorna verdadeiro exceto quando os
dois argumentos so falsos;
Veja abaixo a ordem de precedncia que so avaliadas as
operaes Booleanas:

41

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


1)
2)
3)
4)

!;
==, <, >, <=, >=, !=;
&&;
||;

Veja alguns exemplos:


if (a>=2 && a<5)
Quando o valor em a maior ou igual a 2 E o valor em a
menor que 5, execute o cdigo que segue.
if (! (a>=2 && a<5))
Quando o valor em a no maior ou igual a 2 E o valor em a
no menor que 5, execute o cdigo que segue.
Abreviando F=Falso e V=Verdadeiro avalie as expresses abaixo:
if (!(V || F && V))
Como ajuda, podemos converter os argumentos em V=1 e F=0,
depois inserindo 1 ou 0 numa expresso aritmtica:
NO ((1 + 0) x 1) = NO (1 x 1 + 1 x 0) = NO (1) = 0 = Falso; Como
a prioridade dada ao operador && (igual para aritmtica),
avaliamos primeiro o resultado da multiplicao, depois, da
adio.
if (!(V || V && F))
NO ((1 + 1) x 0) = NO (0) = 1 = Verdadeiro;
if (!(V || F ) && F))
NO (0 x (1 + 0)) = NO (0) = 1 = Verdadeiro;

42

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Agora que temos alguma prtica resolvendo questes Booleanas,
podemos utiliz-la para elaborar um programa que verifica o nome
e senha de um usurio:
certo que uma Yahoo, Hotmail ou Facebook usa um programa
semelhante. A diferena que guardam a lista de nomes e senhas
em arquivos seguros que no esto ao alcance de usurios, e no
no programa que pede estes detalhes, como o nosso.
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string nome;
string senha;
cout << "Favor digitar seu nome de usuario: ";
getline(cin, nome, '\n');
cout << "\nFavor digitar sua senha: ";
getline(cin, senha, '\n');
if (nome=="The Rock" && senha=="hawaii50")
{
cout << "\nPermitir acesso: ";
}
else
{
cout << "\nNome ou senha incorreto: ";
}
system("pause");
return 0;
}
Note que C++ sensvel a letras maisculas e minsculas. A letra
T possui cdigo ASCII 1010100 binrio ou 84 decimal, enquanto
que t possui cdigo 1110100 binrio ou 116 decimal.

43

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Digitando o nome de usurio The Rock e a senha hawaii50
retorna verdadeiro, pois fizemos a comparao usando o operador
Booleano &&. Por esta razo no poder existir mais de um
usurio usando The Rock, pois tero senhas diferentes e apenas
um poderia ter acesso. Note inclusive que nosso programa no
fornece a oportunidade de repetir a operao, no caso de errar o
nome ou senha. Podemos corrigir esta falta com facilidade, mas
antes temos de aprender mais.
Neste captulo aprendemos como elaborar programas inteligentes.
Podemos ento verificar se nossa memria tambm est
funcionando:
Um pequeno teste: Teste 3
1)
a)
b)
c)
d)

Qual a funo que usamos para comparar uma condio?


main;
if;
<==;
||;

2)
a)
b)
c)
d)

Quais so as funes que usamos se temos duas condies?


if;
if else;
else if;
else;

3) Quais so as funes que usamos se temos mais de duas


condies?
a) >=;
b) if;
c) else if;
d) else;

44

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


4) Aps avaliar a expresso: if (1 && 0) sendo 1 = verdadeiro, 0 =
falso, C++ retorna:
a) 0 (falso);
b) 1 (verdadeiro);
5) Aps avaliar a expresso: if (!(1 || 0) && 1)) sendo 1 =
verdadeiro, 0 = falso, C++ retorna:
a) 1 (verdadeiro);
b) 0 (falso);
6) Qual a operao que nos permite avaliar mltiplas condies
usando apenas uma expresso?
a) Booleana;
b) if;
c) !=;
d) &&;

Respostas do Teste 3: 1) b; 2) a,d; 3) b,c,d; 4) a; 5) b; 6) a;

45

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Captulo 6 O Poder do Lao ou (Loop em ingls)
O uso de um lao no programa permite que executamos um
mesmo trecho de cdigo uma quantidade de vezes. Nossos
programas at agora foram executados apenas uma vez, mas
usando um lao podemos faz-lo repetir
a execuo
indeterminadamente. Um bom candidato nosso programa de
entrada de nome e senha. C++ disponibiliza trs funes para
estabelecer laos e so: while, do while e for. Um lao pode
conter em seu corpo, outro lao, chamado de lao aninhado. Isto
fantstico pois aumentamos o poder de processamento de dados
de nossos programas em n vezes. Vejamos como:
A funo que estabelece um lao de nome while:
Traduzido significa enquanto
A sntaxe da funo while, :
while (argumento)
{ // Incio da funo while
Enquanto argumento retorna 1, (verdadeiro), execute este cdigo;
} // Fim da funo while
Argumento retornou 0, (falso), execute este cdigo;
Apenas um GRANDE aviso quando usamos laos, sempre temos de
inserir uma condio no argumento que rompe o lao, seno ficar
preso dentro do lao eternamente!
while funciona de seguinte forma: O argumento testado, caso 1 a
rotina entre chavetas executada uma vez. Vendo a chaveta de
fechamento fim da funo while, argumento testado novamente,
e assim por diante at que se torne falso. C++ procura a chaveta
fim da funo e continua execuo a partir desta.

46

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Vamos ento modificar nosso programa de verificao de nome e
senha que jogamos na lata de lixo por ser deficiente e lhe dar nova
vida:
#include <iostream>
#include <string>
using namespace std;
int main ()
{ //Inicio de main
string nome;
string senha;
int tentativas = 0; /*Declaramos e inicializamos a varivel tipo
int chamada tentativas*/
while (tentativas < 3)//Enquanto tentativas = 0, 1 e 2 verdadeiro
{ // Incio de while
cout << "Favor digitar seu nome de usuario: ";
getline(cin, nome, '\n');
cout << "\nFavor digitar sua senha: ";
getline(cin, senha, '\n');
if (nome=="The Rock" && senha=="hawaii50")
{ //Inicio de if
cout << "\nPermitir acesso:\n";
tentativas = 0; // Foi necessrio inicializar aqui
} //Fim de if
else
{ //Inicio de else
cout << "\nNome ou senha incorreto: ";
tentativas ++;
/*Somar 1 a tentativas para que o
lao seja rompido aps 3 tentativas erradas seguidas*/
} //Fim de else
}//Fim de while
system("pause");
return 0;
}//Fim de main

47

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Verifique o fato de, se errar uma tentativa e acertar a segunda, a
varivel tentativas zerada novamente no trecho de programa que
permite acesso. Se errar trs vezes seguidas, termina o programa,
mas se nunca errar trs vezes seguidas, o programa nunca
termina.
A funo que estabelece um lao de nome do while
Traduzido significa faa enquanto.
Esta funo poder ser utilizada quando desejamos que um trecho
de programa seja executado pelo menos uma vez. Veja a sntaxe
do lao do while:
do
{
este cdigo executado enquanto o argumento retorna verdadeiro
} while (argumento);
este cdigo executado se o argumento retorna falso
Note o ponto e vrgula aps o argumento. C++ executa o trecho
entre as chavetas antes de testar o argumento. Caso o argumento
retorne verdadeiro o mesmo trecho executado novamente. Caso
o argumento retorne falso, o cdigo que segue o argumento
executado.
Veja o exemplo abaixo:

48

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


#include <iostream>
using namespace std;
int main ()
{
int numero = 3;
do
{
cout << numero << " quadrado= " << numero * numero;
}while(!(numero==3)); //Retorna falso
cout <<"\nSaimos do loop.\n ";
system("pause");
return 0;
}
Aps executar o cdigo entre do e while o argumento em
while avaliado que retorna falso, pois NO(1) = 0, o lao
rompido e C++ executa o cdigo que segue while.
Agora execute este programa:
#include <iostream>
using namespace std;
int main ()
{
int numero = 1;
do
{
cout << numero << " quadrado= " << numero * numero << "\n";
++numero;
}
while(numero<=3);//Enquanto numero menor ou igual a 3
cout <<"\nSaimos do loop.\n ";
system("pause");
return 0;
}

49

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Declaramos e inicializamos a varivel de tipo inteiro e nome
numero com digito 1. Entramos no lao do e executamos o
cdigo at while, mas antes acrescentamos 1 ao conteudo de
numero,
(++numero). O argumento de while retorna 1
(verdadeiro) pois o conteudo de numero agora 2. Repetimos a
execuo de cdigo contido pelo lao e acrescentamos o valor em
numero que agora 3. O argumento novamente avaliado e
continua verdadeiro, pois 3==3. Voltamos ao incio do lao e
executamos o cdigo, acrescentamos o valor de numero que agora
4. O argumento avaliado que agora retorna 0. C++ sai do lao e
executa o cdigo que segue.
A terceira funo que estabelece um lao, de nome for
A traduo de for no contexto ir apenas confundir, ento no a
fiz.
Veja a sntaxe da funo for:
for (inicializar varivel; avaliar condio; atualizar varivel)
{ // Inicio do lao for
Execute este bloco de cdigo;
} // Fim do lao for
A funo for contm trs argumentos normalmente, separados
por ponto e vrgula. C++ aps inicializar a varivel, avalia a
condio verdadeira ou falsa do segundo argumento, e
acrescenta, neste caso o valor da varivel para que
eventualmente torna-se falsa a avaliao.

50

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


#include <iostream>
#include <string>
using namespace std;
int main()
{
int i;
string meu_nome;
cout << "Favor digitar seu nome: ";
getline (cin, meu_nome, '\n');
for (i = 0; i < 10; i++)
{
cout << "\n" << i + 1 << "\t" << " Meu nome e: " << meu_nome;
}
system("pause");
return 0;
}
No exemplo supra inicializamos a varivel de tipo inteiro de nome
i com 0. O segundo argumento, i < 10 testado com i ==0, i
acrescentado com 1 (i++), o terceiro argumento. A chaveta {
indica o incio do cdigo a ser executado dentro do lao for.
Note o fato de nosso pedido de entrada de nome estar fora dos
limites do lao. Estivesse dentro, iriamos repetir a entrada de
nome dez vezes, que foge ao propsito de nosso programa. Analise
a sada de dados e note o uso da seqncia \t que o mesmo
que pressionar a tecla de tabulao. Isto muito til quando
desejamos imprimir uma tabela, por exemplo, para efeito de
manter ordenadas as colunas.
A maioria das pessoas comeando sentem dificuladades para
entender a operao deste lao e se voc est nesta situao, no
se preocupa, est tudo bem. O que temos de manter em mente
que C++ j sabe o que dever fazer, apenas usa os argumentos
para manter o fluxo de execuo de acordo com a sntaxe da
funo.

51

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Veja o programa que segue e se pergunta, quantas vezes ser
executado cout?
#include <iostream>
using namespace std;
int main ()
{
for (int i=0; i < 2; i++)
{ // inicio do lao for
cout << "Valor de i = " << i;
cout << "\nEste codigo esta sendo executado " << i+1 << " vezes
\n";
} // fim do lao for
system("pause");
return 0;
}
Veja o fluxograma deste programa, abaixo:

52

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Note que declaramos a varivel i de tipo inteiro junto aos


argumentos da funo for ao mesmo tempo que a inicializamos
com valor de 0. Isto perfeitamente aceitvel para C++ com
beneficio adicional que poupamos uma linha, pois ao contrrio
teriamos de declarar a varivel com linha separada antes de usla. Veja no segundo uso de cout. i + 1 no afeta o valor de i de
maneira alguma, pois C++ entende que apenas queremos que
imprima o valor de i + 1. Isto porqu inicializamos i com valor
de 0. Estamos acostumados a iniciar uma contagem a partir do
nmero 1. Veremos mais tarde que o computador inicia a
contagem desde o nmero 0 quando referimo-nos memrias.

53

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Mais sobre laos usando as declaraes break, continue e
return:
At agora rompemos um lao pela comparao de dois ou mais
argumentos. No entanto temos disposio a declarao break
que podemos usar em qualquer lugar no lao para romp-lo. Isto
quer dizer que no precisamos testar uma condio no incio ou no
fim do lao.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string nome;
while (1)// Condio sempre verdadeira
{ //Inicio do lao while
cout << "Digite seu nome, ou (sair) para sair do loop\n";
getline(cin, nome, '\n');
if (nome != "sair")// Condio torna-se falsa ao digitar sair
{ //Inicio de if
cout << "Oi " << nome << " estou no loop while\n";
} //Fim de if
else if (nome == "sair")
{ //Inicio de else if
break; //Sair do loop (lao) while
} //Fim de else if
}// fim de while
cout << "Voce digitou sair, foi executado break entao nao
estou mais no loop\n";
system("pause");
return 0;
}

54

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

A declarao continue til quando no queremos que um


determinado trecho de programa seja executado, voltando para o
inicio do lao. Veja o programa abaixo:
#include <iostream>
using namespace std;
int main()
{
double numero;
double resultado;
for (int i=1; i<10; i++)
{
cout << "Digite um numero: ";
cin >> numero;
if (numero == 0)
{
continue; //Este ser executado somente se numero==0
}
else
{
resultado = i / numero;
cout << "Resultado da divisao de " << i << " e " << numero << "
= " << resultado << "\n";
}
} //Fim do lao for
system("pause");
return 0;
}

55

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Execute o programa. Este aceita a entrada de nmeros negativos


inclusive, pois declaramos as variveis como de tipo double.
Note que a funo if avalia o caso de o nmero digitado ter sido
0. Como a diviso de qualquer nmero por 0 proibido, causando a
parada imediata do programa e gerao de erro pelo sistema, se
teclar um 0, a declarao continue executada que retorna o
fluxo de execuo ao inicio do lao e a diviso no realizada.
Note tambm que usamos a declarao else e no else if
porque temos apenas duas condies possveis. else if usada
quando temos variadas condies possveis.
Maravilha, no?
A declarao return que traduzido significa retorne utilizada
para passar parmetros para uma funo, mas possui outro efeito
importante. Ela encerra uma funo, por esta razo usada no fim
da funo. No caso do programa abaixo ela encerra main().
Veja ela funcionando neste programa:

56

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

#include <iostream>
#include <string>
using namespace std;
int main()
{
string sair;
bool chave1, chave2;
chave1 = true;
chave2 = true;
while (chave1 && chave2)
{
cout << "Estou no loop. Tecle sair para executar return..\n";
cin >> sair;
if (chave1 && chave2 && sair=="sair")
{
return 0;
}
else
{
continue;
}
} // Fim da funo while
return 0;
} // Fim da funo main
Note que usamos a declarao das variveis chave1 e chave2
como tipo bool. Este tipo opera com apenas dois estados, true
ou false, ou podamos ter inializado-as com 1, o outro estado
sendo 0. Assim podemos testar a condio da expresso Booleana
em while pois inicializamos chave1 e chave2 com valores que
correspondem a um retorno de verdadeiro dos argumentos em
while, e cout executado. Em cin fornecemos o meio de sair da
funo main ao completar o terceiro argumento em if logo em
seguida.
57

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Assim que os argumentos em if retornem verdadeiro, executado
return 0, e o fluxo de execuo pula para a chaveta fim de main.
Se digitarmos outra palavra que no a palavra sair, else
executado junto com o cdigo que a pertence, no caso continue
que direciona o fluxo de execuo para while novamente. Execute
o programa e brinque com ele. Pense no que poder acontecer se
alterar o valor de chave1 para false. Ns inicializamos os estados
de chave1 e chave2 com valores fixos, mas estes valores
poderiam ser enviados por botes ou chaves externos, como
contatos de rels por exemplo.
Surge a necessidade de reverter a ordem dos dgitos de um
nmero, por exemplo: 123. Queremos que o programa imprima 321.
Veja o programa abaixo:
#include <iostream>
using namespace std;
int main()
{
int n, reverter = 0, sobra=0;
cout << "Favor digitar um numero >= 3 digitos: ";
cin >> n;
while(n != 0)
{
sobra = n%10;
reverter = reverter*10 + sobra;
n/=10;
}
cout << "O numero revertido = " << reverter;
return 0;
}

58

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Teremos um nmero guardado na varivel n, exemplo 123 (cento e
vinte e trs). Para separar o ltimo dgito, 3, usamos o operador %
(mdulo) que retorna o restante da diviso por 10 enquanto n no
possui valor 0. Inicialmente temos guardados nas variveis:
n=123; reverter = 0; sobra=0;
sobra = 123%10 retorna 3, ento guardado em sobra temos 3.
reverter = 0*10 + sobra retorna 3, ento guardado em reverter
temos 3.
n/=10 traduzido n = n/10, ento n = 123/10 = 12. Lembra-se que
quando dividimos o valor de uma varivel declarada como de tipo
int, o restante descartado, portanto guardado em n teremos 12.
Voltamos a execuo para while. Como n = 12 o argumento
verdadeiro, e repetimos a sequncia do programa. n=12;
reverter=3; sobra=3;
sobra = 12%10 retorna em sobra o nmero 2;
reverter = 3*10 + sobra; reverter contm 30+2 = 32;
n= 12/10 = 1;
Voltamos a execuo para while, que continua verdadeiro o
argumento pois 1>0.
Temos guardados nas variveis os valores:
n=1; sobra=2; reverter=32;
sobra=1%10 = 1;
reverter = 32*10 + 1 = 320 + 1 = 321;
n=1/10 = 0;
Voltamos execuo para while que agora retorna falso pois n=0 e
saimos do lao Executamos cout que imprime o valor de reverter.
Maravilha no?
Ainda no falamos sobre laos aninhados. A razo que gostaria
de apresentar este assunto quando elaboramos um programa que
necessita do uso de dois laos aninhados.
Ento, se sente bem com laos? timo, podemos agora avaliar
nossos conhecimentos:

59

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Um pequeno test Teste 4:
1) Quais as seguintes funes que estabelecem um lao?
a) while do;
b) for;
c) do while;
d) else if;
e) while;
2) Qual a sntaxe correta da funo for?
a) for (avaliao da varivel; inicilizao da varivel; atualizao
da varivel)
b) for (inicializao da varivel. avaliao da varivel. atualizao
da varivel)
c) for (inicializao da varivel; avaliao da varivel; atualizao
da varivel)
3)
a)
b)
c)
d)
4)
a)
b)
c)
d)

Qual ser o valor final de i quando executada esta funo:


for(int i=0;i<10;i++)?
11;
10;
9;
0;
Qual a quantidade mnima garantida que um lao do while
executa?
Uma vez;
Depende do teste de condio;
Depende da entrada de dados;
Quantas vzes quiser;

60

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


5)
a)
b)
c)
d)

Quando ser executado o cdigo que segue a funo while


(num<30)?
Quando o conteudo da varivel num maior que 30;
Quando o conteudo da varivel num menor que 30;
Quando o conteudo da varivel num igual a 30;
Nunca ser executado porqu o argumento sempre retorna falso

6) Num Show de Variedades temos trs juizes que assinalam seu


voto por intermdio de um boto cada que pressionam uma vez. Se
um dos juzes achar o desempenho rum, aperta outro boto. Cada
boto envia seu ltimo estado quatro entradas separadas do
computador. Um programa recebe as informaes em bot0, de
rum, bot1, bot2 e bot3 respectivamente que correspondem
ao estado dos botes. Se nenhum juiz deu seu voto e o boto de
rum foi pressionado gera a mensagem Desempenho considerado
rum ao passo que 1 voto dever gerar a mensagem Desempenho
considerado regular, 2 votos Desempenho considerado bom e 3
votos Desempenho considerado muito bom. Escreva um
programa que realiza este trabalho. Dica: um lao while
indicado para este trabalho, com avaliao Booleana.
Respostas do Teste 4: 1) b,c,e; 2) c; 3) c; 4) a; 5) b;

61

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Captulo 7 Todos os Poderosos Segredos de Funes:
Primeiro na lista de coisas que nunca devemos fazer, o de
declarar uma funo dentro de outra funo, ok?
At o momento os programas que escrevemos residiram e foram
executados dentro da funo main. Na verdade, cada programa
que rodamos em main j o corpo da funo main. Bem dizer, o
fato de C++ fornecer os meios para executarmos um programa
inteligente e poderoso dentro da funo main j fantstico. No
entanto, agora que estamos empolgados, seria bom se
pudssemos escrever algumas funes que residiriam fora de
main. Imagine por exemplo um programa que pudesse simular uma
mini-calculadora dotada das funes bsicas de aritmtica e mais,
clculo de circunferncia de um crculo e clculo de rea
quadrada do mesmo. Em main teriamos a entrada de parmetros e
a escolha do tipo de operao que desejamos realizar. Podemos
ento chamar a funo relevante, passar para ela os parmetros e
ela por sua vez enviaria o resultado para main, para ser imprimido.
Fazendo tudo isto dentro de main tornaria nosso programa difcel
de entender, surgir a necessidade de utilizar o mesmo cdigo em
vrias partes do programa, cortar e colar, cortar e colar, afff!
Oi funes, sejam bemvindos.
Cabe ento definirmos a terminologia acerca de funes.
Precisamos fazer duas coisas importantes antes que C++ nos
permite usar uma funo, e so:
1) A declarao de uma funo: Consiste de tipo, nome e
argumentos;
2) A definio da funo: Consiste de definir a operao que a
funo realizar mais todos os componentes que a compe;
Por exemplo, uma das funes de nossa mini-calculadora seria
parecido com:

62

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


double somar (double num1, double num2)
{
return num1 + num2;
}
Vimos que precisamos declarar as variveis que usamos em cada
funo, mas h uma distino entre as variveis assim
declaradas? H sim, e so chamadas de variveis locais, e
variveis globais. Um nome de varivel declarado entre as
chavetas de uma funo:
double somar (double num1, double num2)
{
double resultado = num1 + num2;
return resultado;
}
Neste exemplo a varivel resultado declarado no corpo da funo
chamada de varivel local, porque pertence somente funo
somar. O escopo de uma varivel determina o quanto visvel, que
significa qual o pedao de cdigo que poder usar o nome da
varivel para acessar seu conteudo. As variveis declaradas
dentro de uma funo esto disponveis apenas no escopo da
funo enquanto executada. Isto quer dizer que outra funo
sendo executada em conjunto com a primeira no tem acesso s
variveis desta e vice versa. Quando uma funo chama outra as
variveis da funo chamada sero as nicas disponveis. Os
argumentos de uma funo tambm so declarados no escopo da
funo e no esto disponveis para a funo que a chamou
mesmo quando esta transmite dados.
Neste caso declaramos e definimos a funo somar como sendo
de tipo double, de nome somar e que usa dois argumentos de tipo
double de nome num1 e num2, que retorna a soma de num1 com
num2. J uma varivel global pode ser acessada por qualquer
funo. Veja o exemplo:

63

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


#include <iostream>
using namespace std;
int numero_de_chamadas_de_funcao = 0;

/*Declarao
varivel global*/

void funcao2()
{
numero_de_chamadas_de_funcao ++;
}
int main()
{
funcao2();
funcao2();
funcao2();
funcao2();
funcao2();
cout
<<
"A
funcao2
foi
chamada
numero_de_chamadas_de_funcao << " vezes\n";
system("pause");
return 0;
}

de

"

<<

Note que a funo main sempre e sem excesses a primeira


funo a ser executada.
Declaramos uma varivel que como poder ver, no pertence a
nenhuma funo, e portanto de acesso global tipo int de nome
numero_de_chamadas_de_funcao, e a inicializamos com 0. Depois
declaramos e definimos uma funo de tipo de retorno void, de
nome funcao2. void diz ao compilador que esta funo no retorna
nenhum valor. Em sua definio ela diz que usar a varivel global
numero_de_chamadas_de_funcao para receber dados. De fato esta
funo apenas soma o nmero 1 varivel numero_de
_chamadas_de_funo, cada vez que chamada.

64

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


J em main chamamos a funcao2 cinco vezes. A cada chamada
incrementado o valor na varivel. Maravilha no? Hmmm, no.
Parece muito bom, mas pense bem, uma varivel sendo acessada
por vrias funes definitivamente no aconselhvel. Melhor
ficar com as variveis locais onde outras funes so negadas
acesso. Que assim seja, sempre que possvel.
Modo padro de declarar argumentos de uma funo:
Veja o programa abaixo:
#include <iostream>
using namespace std;
int dividir (int num1, int num2=2) //Inicializamos num2 com valor 2
{
int resposta;
resposta=num1/num2;
return (resposta);
}
int main ()
{
cout << dividir (12); // Chamamos a funo dividir com valor 12
cout << endl;
cout << dividir (20,4);

system("pause");
return 0;

65

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


O compilador possui raciocnio. Note que na declarao da funo
dividir, inicializamos num2 com valor de 2. Em seguida passamos o
valor de 12 para a funo. Como passamos apenas um parmetro
para a funo, ele sabe que se trata do valor de num1 pois num2 j
possui seu valor. Na segunda chamada, passamos os valores de
num1 e de num2. Neste caso o compilador ignora o valor em num2
de 2, usando o novo valor 4 para num2. Agora, se no tivssemos
iniciado num2 e tentssemos passar apenas um parmetro, iria
confundir nosso compilador, resultando em erro.
Passando parmetros por referncia:
No programa abaixo declaramos uma funo antpost de tipo de
retorno void, (no h retorno), que possui 3 argumentos, int num,
int& anterior e int& posterior. Em main inicializamos o inteiro
numero com valor 2, mas nummenos e nummais no so
inicializadas. Na definio de antpost declaramos que o valor de
num ser subtrado por 1, o resultado guardado em anterior, e
acrescentado por 1, o resultado guardado em posterior. Usamos o
operador & para que sejam vinculadas anterior e posterior num,
sendo que o valor de num apenas passado para a funo quando
a chamamos. Resumindo, o operador de referncia & determina
qual operao na funo ser realizada.
#include <iostream>
using namespace std;
void antpost (int num, int& anterior, int& posterior)
{
anterior = num-1;
posterior = num+1;
}
int main ()
{
int numero=2, nummenos, nummais;
antpost (numero, nummenos, nummais);
cout << "Anterior=" << nummenos << ", Posterior=" << nummais;
66

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


return 0;
}
Veja o programa abaixo:
#include <iostream>
using namespace std;
int somar (int num1, int num2)
{
int resultado;
resultado = num1 + num2;
return resultado;
}
int main ()
{
int o_resultado;
o_resultado = somar (3, 4);
cout << O resultado da soma = << o_resultado << endl;
system(pause);
return 0;
}
A funo main executada. Nela declaramos uma varivel de tipo
inteiro e nome o_resultado. Nome seu identificador. Em seguida
chamamos a funo somar com dois parmetros, 3 e 4. Neste
momento main perde o contole do fluxo de execuo, que ento
passado para a funo somar. Estes nmeros so passados para a
funo somar, num1 = 3, num2 = 4. Na funo declaramos uma
varivel de nome resultado de tipo inteiro. Definimos que os
valores de num1 e num2 sero somados, e o resultado da soma
ser retornado funo que a chamou, no caso o_resultado em
main. Neste momento, o controle novamente passado a main,
junto com o resultado retornado. Para provar isto, imprimimos
o_resultado em cout.

67

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Vamos voltar nossa ateno declarao da funo somar
exposta anteriormente.
Basicamente temos duas diferenas comparado com a funo
main. A primeira o fato de a funo usar dois parmetros que so
num1 e num2. main at agora no usou parmetros, estando as
parnteses da funo vazias ( ). A segunda que retorna um valor,
( main), pelo uso da declarao return que o resultado da
soma de dois nmeros. Quando elaboramos uma funo que no
faz nada alm de por exemplo imprimir texto, podemos declarar o
tipo de retorno como void, mas lembre que uma vez declarada a
funo como void, no poder us-la para processar dados, como
a declarao de variveis, ou uso da funo if, ou uso de return.
#include <iostream>
using namespace std;
double somar (double num1, double num2) //Declarao da funo
{ //Incio da funo
return num1 + num2; //Definio da funo somar
} //Fim da funo
int main()
{
double num1, num2, resultado;
cout << "Digite dois numeros: ";
cin >> num1 >> num2;
/*Pressione
Enter
para
cada
entrada*/
resultado = somar (num1, num2); /*Chamamos a funo
somar e passamos para ela os valores em num1 e num2. Por sua
vez a funo passa para resultado o valor gerado pela operao*/
cout << "\nO resultado da soma dos dois numeros = " <<
resultado << "\n";
system("pause");
return 0;
}

68

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Declaramos uma funo chamada somar de tipo double que possui
dois argumentos separados com vrgula que obedece sntaxe da
declarao de uma funo que usa argumentos. O corpo da funo
retorna main o resultado da soma pela declarao return num1
+ num2. Vimos que todo o trabalho de somar os dois nmeros
cabe funo somar e no main.
Em main, declaramos trs variveis de tipo double pois temos
obrigao de declarar variveis de mesmo tipo usadas pela funo
somar que main ir manusear, com nomes num1 e num2, e
resultado. Declaramos as variveis aqui, porqu main no tem
acesso ao nome da varivel na funo somar. De fato no
precisavamos repetir os nomes das variveis declaradas em main.
Poderiam ter nomes como numero1 e numero2, ou argumento1 e
argumento2 ou base e altura, ou qualquer nome de varivel
relevante. cin salva os dois nmeros de entrada em num1 e num2
respectivamente. Em seguida invocamos a funo somar,
passando os dois valores para a funo. Este efetua o trabalho
devolvendo varivel resultado, o resultado da soma. Que legal,
hein? C++ faz tudo por ns. Resta main imprimir o resultado e
problema resolvido, pelo menos por enquanto pois ainda resta
acrescentar todas as outras funes que prometemos na
propaganda.
Como nosso programa j sabe somar dois nmeros, podemos
ensin-lo a subtrair dois nmeros, mas antes disto gostaria de sua
valiosa ajuda para elaborar a funo. Revendo nossa funo de
somar acho que podemos usar a mesma estrutura, s mudar o
nome e o trabalho efetuado. Enquanto isto em main, acho que
precisamos de um meio de poder escolher entre uma funo e
outra para que seja invocada a operao correta. Acho que a
funo if, else if poder resolver. Talvez voc pensou em outro
caminho? Isto muito bom, pois a programao no uma cincia
exata. O importante que seja realizado o trabalho com maior
eficincia possvel. Veremos adiante o uso da funo switch mas
por hora usaremos if.

69

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Decidimos que nossa nova funo usaria a mesma estrutura que a
de somar, com novo nome:
double subtrair (double num1, double num2)
{
return num1 num2; //Subtraimos o valor em num2, do de num1
}
Vamos acrescentar a funo e mais algumas linhas de cdigo para
torn-lo mais seguro e amigvel?
#include <iostream>
using namespace std;
double somar (double num1, double num2) //Declarao da funo
{ //Incio da funo
return num1 + num2; //Descrio da funo somar
} //Fim da funo
double subtrair (double num1, double num2)
{
return num1 - num2;
}
int main()
{
double num1, num2, resultado;
int escolha;
while (escolha != 3)
{
cout << "Digite dois numeros: \n";
cin >> num1 >> num2; /*Passaremos estes dois nmeros
para a funo escolhida*/
cout << "\n\t Operacao "; // Apresentamos um pequeno menu
cout << "\n\t 1 - Somar: "; // de escolha mltipla
cout << "\n\t 2 - Subtrair: ";
cout << "\n\t 3 - Sair: ";
70

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


cout << "\n\tEscolhe a opcao: ";
cin >> escolha;
if (escolha==1) // Caso verdadeira a avaliao execute
// Caso falsa no execute
{
resultado = somar (num1, num2); /*Chamamos a funo
somar e passamos para ela os valores em num1 e
num2. Por sua vez a funo passa para resultado o
valor gerado pela operao */
cout << "\nO resultado da soma dos dois numeros = " <<
resultado << "\n";
}
else if (escolha==2)
{
resultado = subtrair (num1, num2);
cout << "\nO resultado da subtracao dos dois numeros =
" << resultado << "\n";
}
else if (escolha !=1 || escolha !=2)
{
cout << "\nEscolha invalida, favor tentar novamente.. \n";
continue; /* Voltar execuo para incio do
lao
(executar while)*/
}
system("pause");
} // Fim de while. Estamos aqui porqu a escolha foi o nmero 3
return 0;
} // Fim de main

71

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Note que em main usamos a mesma declarao de chamada de
funo para as duas funes externas, i.e. resultado = nome da
funo (num1, num2) sendo necessrio apenas mudar o nome da
funo e operao a executar. Ao executar o programa, aps o
pedido de entrada de dois nmeros, apresentamos ao usurio um
pequeno menu mostrando as opes que este tm disponvel.
Usamos como argumento na funo while a entrada de qualquer
nmero, menos o nmero 3, que se for escolhido, torna o
argumento falso que direciona o fluxo de execuo at a chaveta
de fim de while, encerrando o programa. Ao mesmo tempo o
programa reconhece que um usurio poder surpreender, portanto
elaboramos um filtro usando uma operao Booleana que
retorna verdadeiro se o nmero escolhido no seja 1 ou 2.
Estaremos executando este filtro porqu o usurio inseriu algo
que retornou falso aos argumentos das funes if else if
anteriores. Sendo verdadeiro, a execuo passa pelo aviso da
falha e permite a redeno pela declarao continue, que
retorna o fluxo de execuo funo while.
Execute o programa e verifique seu funcionamento. Entre com os
nmeros e use cada parte do programa. Insira um nmero em
escolha, por exemplo o nmero 4. Avalie a operao correta do
filtro. Uma vez satisfeito, resta perguntar se o programa realmente
est funcionando eficientemente. Seguir o fluxo de execuo e
tente identificar as falhas. Com certeza, nosso programa possui
algumas...
A primeira que poder notar o fato de, se entrar com nmero 3,
que deveria encerrar o programa, na verdade somente far isto
depois de voltar para while aps executar todo o cdigo do corpo
desta funo.
A segunda o fato de avaliar a entrada de um nmero que no
consta da tabela apenas no fim do programa.
A terceira o fato de nossa tabela de escolha ser declarada
depois da entrada de dados.
Vamos ento corrigir estas falhas. Veremos que isto no difcel:

72

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


#include <iostream>
using namespace std;
double somar (double num1, double num2) // Declarao da funo
{ //Incio da funo
return num1 + num2; //O trabalho que a funo realiza
} //Fim da funo
double subtrair (double num1, double num2)
{
return num1 - num2;
}
int main()
{
double num1, num2, resultado;
int escolha;
while (1) //Sempre verdadeiro
{
cout << "\n\t Operacao "; /* Apresentamos um pequeno
menu*/
cout << "\n\t 1 - Somar: "; //de escolha mltipla
cout << "\n\t 2 - Subtrair: ";
cout << "\n\t 3 - Sair: ";
cout << "\n\tEscolhe a opcao: ";
cin >> escolha;
if (escolha < 1 || escolha > 3)
{
cout << "\nEscolha " << escolha << " invalida. Favor
tentar novamente.\n";
continue;
}
else if (escolha == 3)
{
break;
}
cout << "\nDigite dois numeros:\n";
73

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


cin >> num1 >> num2;
if (escolha==1)
{
resultado = somar (num1, num2); /*Chamamos a
funo somar e passamos para ela os valores em num1 e num2.
Por sua vez a funo passa para "resultado" o valor gerado pela
operao */
cout << "\nO resultado da soma dos dois numeros = "
<< resultado << "\n";
}
else if (escolha==2)
{
resultado = subtrair (num1, num2);
cout << "\nO resultado da subtracao dos dois numeros =
" << resultado << "\n";
}
system("pause");
} // Fim de while. Estamos aqui porqu a escolha foi o nmero 3
return 0;
} // Fim de main
Note que alteramos o argumento da funo while para que nosso
lao no dependa da entrada de valor da escolha, que no uma
boa ideia como j vimos. O fluxo de execuo do cdigo dentro do
lao agora depender da declarao das funes if else if,
incluindo o rompimento e conseqente sada do lao. Nosso filtro
de escolha diz que qualquer nmero menor que 1 ou maior que 3
ir executar a mensagem de aviso, e continue, que retorna o
fluxo de execuo para while. Sendo a entrada vlida, o valor
comparado com nmero 3 e se verdadeira, executa break que
direciona o fluxo de execuo para a chaveta de fim de lao, e em
seguida fim de main. Restam as escolhas nmeros 1 e 2 que so
executadas normalmente. Note tambm s para efeito de
estarmos preparados no futuro, que se entrar com um caractere
(tipo char), o programa dispara num lao sem fim. Isto acontece
porqu elaboramos filtros que administram nmeros apenas. Mais
74

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


tarde iremos falar tudo sobre estes filtros, mas por hora no
vamos divergir de nosso propsito para no perder o fio da meada.
Quando usamos um nmero particular com freqncia, e para no
termos o trabalho de escrev-lo repetidas vezes no programa,
podemos usar a diretriz define. Por exemplo, se queremos
acrescentar a habilidade de clculo da rea e da circumferncia
de um crculo usamos a abreviao da palavra grega
que significa permetro. A primeira letra pi, e seu valor
aproximado 3,141593. A sntaxe da declarao define :
#define um nome um valor;
Para nosso propsito usaremos:
#define pi 3.141593, e normalmente reside logo abaixo dos
arquivos de cabealho;
#include <iostream>
#define pi 3.141593
(, C++ estipula o uso de ponto, e no vrgula de ponto decimal,
como nos velhos tempos).
Seria bom neste momento, para aguar a sua tcnica, escrever as
funes que realizam as operaes de multiplicao e de diviso
para nossa mini-calculadora. Acrescente estes dotes tabelinha
de mltipla escolha em main, e o cdigo de chamada das funes
adicionais, no esquecendo de acrescentar os nmeros da escolha
ao filtro. Se por acaso j fez este trabalho por conta prpria, isto
fantstico, parabns. De contrrio, est tudo bem, analise o
programa que fizemos juntos. Nas funes, preciso mudar o
nome de cada e declar-las embaixo das outras duas, por
exemplo:
double multiplicar (double num1, double num2)
{
return num1 * num2;
}
double dividir (double num1, double num2)
75

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


{
return num1 / num2;
}
Na tabelinha de mltipla escolha, acho melhor alterar o valor que
encerra o programa, para zero, que como sabe o nmero 3 por
enquanto. Assim poder acrescentar outros nmeros sem ter de
alterar a ordem numrica. A funo while ter como argumento
(1). Acrescente mais duas funes else if (escolha == 3) {
resultado = multiplicar (num1, num2); cout e etc, e repetir os
passos para dividir. S para efeito de comparao, eis o programa
modificado:
#include <iostream>
using namespace std;
double somar (double num1, double num2) //Declarao da funo
{ //Incio da funo
return num1 + num2; //O trabalho que a funo realiza
} //Fim da funo
double subtrair (double num1, double num2)
{
return num1 - num2;
}
double multiplicar (double num1, double num2)
{
return num1 * num2;
}
double dividir (double num1, double num2)
{
return num1 / num2;
}
int main()
{
double num1, num2, resultado;
int escolha;
while (1)
76

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


{
cout << "\n\t Operacao: "; /* Apresentamos um pequeno

menu de escolha mltipla */


cout << "\n\t 1 - Somar: ";
cout << "\n\t 2 - Subtrair: ";
cout << "\n\t 3 - Multiplicar: ";
cout << "\n\t 4 - Dividir: ";
cout << "\n\t 0 - Sair: ";
cout << "\n\tEscolhe a opcao: ";
cin >> escolha;
if (escolha == 0)
{
break;
}
else if (escolha < 1 || escolha >4)
{
cout << "\nEscolha " << escolha << " invalida. Favor tentar
novamente.\n";
continue;
}
cout << "\nDigite dois numeros:\n";
cin >> num1 >> num2;
if (escolha==1)
{
resultado = somar (num1, num2); /*Chamamos a
funo
somar e passamos para ela os valores em num1 e num2.
Por sua vez a funo passa para "resultado" o valor gerado pela
operao */
cout << "\nO resultado da soma dos dois numeros = "
<< resultado << "\n";
}
else if (escolha==2)
{
77

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


resultado = subtrair (num1, num2);
cout << "\nO resultado da subtracao dos dois numeros =
" << resultado << "\n";
}
else if (escolha==3)
{
resultado = multiplicar (num1, num2);
cout << "\nO resultado da multiplicacao dos dois
numeros = " << resultado << "\n";
}
else if (escolha==4)
{
resultado = dividir (num1, num2);
cout << "\nO resultado da divisao dos dois
numeros = " << resultado << "\n";
}
system("pause");
} // Fim de while. Estamos aqui porqu a escolha foi o nmero 0
return 0;
} // Fim de main
Se voc salvou o programa como minicalculadora, por exemplo,
ter acesso verso executvel com extenso .exe. Para tanto,
clique no meio onde instalou Dev-Cpp, exemplo: Clicar Meu
computador, HDxxx (C:), Dev-Cpp e procure minicalculadora entre
os programas. Dev-C++ salva duas verses de seus programas, um
com extenso .cpp que o programa fonte, mais a verso
executvel com extenso .exe. Clique em minicalculadora.exe e o
programa ser executado diretamente na janela do DOS.
Para que nossa mini-calculadora calcule a rea quadrada, e a
circumferncia de um crculo precisamos de apenas uma entrada,
que o valor do raio, digamos em centmetros. Porm nosso
programa pede a entrada de dois nmeros. Ento, o que fazer?

78

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


#include <iostream>
#define pi 3.141593
using namespace std;
double somar (double num1, double num2) //Declarao da funo
{ //Incio da funo
return num1 + num2; //O trabalho que a funo realiza
} //Fim da funo
double subtrair (double num1, double num2)
{
return num1 - num2;
}
double multiplicar (double num1, double num2)
{
return num1 * num2;
}
double dividir (double num1, double num2)
{
return num1 / num2;
}
double area (double raio)
{
return pi*raio*raio;
}
double circum (double raio)
{
return 2*pi*raio;
}
int main()
{
double num1, num2, resultado, raio;
int escolha;
while (1)
{
79

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


menu */

cout << "\n\t Operacao "; /* Apresentamos um pequeno

cout << "\n\t 1 - Somar: "; // de escolha mltipla


cout << "\n\t 2 - Subtrair: ";
cout << "\n\t 3 - Multiplicar: ";
cout << "\n\t 4 - Dividir: ";
cout << "\n\t 5 - Area de circulo:";
cout << "\n\t 6 - Circumferencia:";
cout << "\n\t 0 - Encerrar: ";
cout << "\n\tEscolhe a opcao: ";
cin >> escolha;
if (escolha == 0)
{
break;
}
else if (escolha < 1 || escolha > 6)
{
cout << "\nEscolha " << escolha << " invalida. Favor tentar
novamente.\n";
continue;
}
else if (escolha >=1 && escolha <=4)
{
cout << "Digite dois numeros: \n";
cin >> num1 >> num2; /*Passaremos estes dois nmeros
para a funo escolhida*/
}
else if (escolha == 5 || escolha == 6)
{
cout << "\nDigite o raio, em cm: ";
cin >> raio;
}
if (escolha==1)
{
resultado = somar (num1, num2); /*Chamamos a funo
somar e passamos para ela os valores em num1 e num2. Por sua
vez a funo passa para "resultado" o valor gerado pela operao
*/
80

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


cout << "\nO resultado da soma dos dois numeros = " <<
resultado << "\n";
}
else if (escolha==2)
{
resultado = subtrair (num1, num2);
cout << "\nO resultado da subtracao dos dois numeros =
" << resultado << "\n";
}
else if (escolha==3)
{
resultado = multiplicar (num1, num2);
cout << "\nO resultado da multiplicacao dos dois
numeros = " << resultado << "\n";
}
else if (escolha==4)
{
resultado = dividir (num1, num2);
cout << "\nO resultado da divisao dos dois numeros
= " << resultado << "\n";
}
else if (escolha == 5)
{
resultado = area (raio);
cout << "\nA area de um circulo de " << raio << "
cm de raio = " << resultado << "cm quadrados.\n";
}
else if (escolha == 6)
{
resultado = circum (raio);
cout << "\nA circumferencia de um circulo de " <<
raio << " cm de raio = " << resultado << "cm.\n";
}
system("pause");
} // Fim de while. Estamos aqui porqu a escolha foi o nmero 0
return 0;
81

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


} // Fim de main
Dado que temos dois tipos de entradas, sendo num1 e num2, o
outro sendo raio, tinhamos que diferenciar entre os dois. Caso
contrrio o programa escreveria Digite dois numeros.. e logo em
seguida Digite o raio.... Analisando as operaes, vimos que os
nmeros entre 1 a 4 geram operaes que necessitam de dois
nmeros para realizar somar, subtrair, multiplicar e dividir. Os
nmeros restantes, 5 e 6 necessitam de apenas a medida do raio
de um crculo. Implementamos dois filtros, o primeiro:
else if (escolha >=1 && escolha <=4)
verdadeiro quando escolha 1 ou maior E 4 ou menor, i.e.
corresponde entrada de escolha entre 1 a 4, e o cdigo de
entrada de dois nmeros executado. O segundo filtro:
else if (escolha == 5 || escolha == 6)
verdadeiro quando escolha 5 OU 6, e o cdigo de entrada de
medida do raio executado. O resto do cdigo executa
normalmente.
Agora que sabemos como funciona nossa mini-calculadora
intimamente, podemos ir acrescentando funes, como por
exemplo, o clculo de porcentagem! Infelizmente temos de
prosseguir, pois temos muito caminho pela frente.
At agora, elaboramos funes normais e como poder atestar,
funcionam muito bem. No entanto temos outros tipos de funes,
que dependendo da aplicao, poderemos utilizar.
O Prottipo de uma Funo:
Quando declaramos um prottipo, colocamos esta declarao
antes da funo main. Existe uma razo muito boa para fazermos
isto. que se no declaramos o prottipo antes de main, quando
formos chamar a funo, tudo que executamos em main no
estaria disponvel para ser usado na funo pois declaramos e
definimos a funo depois de main. Ok j fizemos isto, exceto que
neste caso fechamos o prottipo com ponto e vrgula, que
significa que iremos definir a funo em outro lugar, normalmente

82

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


depois de main. Veja um bom exemplo de uso de prottipo de
funo:

#include<iostream>
using namespace std;
double soma;
//Declaramos a varivel global de tipo double
double num_impar(double num); /*Declaramos um prottipo de
funo de nome num_impar que usa um parmetro chamado n um
de mesmo tipo*/
int main()
{
double num;
double resultado;
while (1)
//Execute sempre
{
//Incio do lao while
cout<<"Digite um numero. 0 para sair: ";
cin>>num;
//O nmero digitado guardado na varivel num
if (num <= 0) //Caso seja um nmero negativo ou 0
{
return 0;
// Sair do programa
}
resultado = num_impar(num); /*Chamamos a funo num_impar
usando num como parmetro */
}

//Fim de while

cout<<"A soma dos numeros impares = "<<resultado<<"\n";


//resultado contm a soma passada pela funo
system("pause"); //Esperar tecla
return 0;
}
//Fim de main

83

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

double num_impar(double num) //A definio da funo est aqui


{
double n=num; /*Declaramos uma varivel n. O conteudo de num
depositado na varivel n */
while (n >= 0)//Subtrair 2 sucessivamente at sobrar 1 ou 0
{
//Incio do Loop while
if (n == 1)
//No caso do nmero ser mpar
{
//Incio de if
soma = soma + num;
}
//Fim de if
else if (n == -1)
//Caso o nmero digitado foi 1
{
//Incio de else if
soma = soma + 1;
}
//Fim de else if
else if (n == 0) /*Aps processamento, nmero
par */
{
//Incio de else if
soma = soma + 0; //No somar o nmero par
}
//Fim de else if
n -= 2;
//Subtrair 2 do nmero digitado
}
//Fim do Loop while
return (soma); //Retorna o resultado de soma funo main
} //Fim da funo num_impar ( )

84

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


O trabalho que este programa realiza o de subtrair 2
sucessivamente de um nmero que o usurio insere at que este
resulta em 0, no caso de um nmero par, 1 no caso de um nmero
mpar. O programa no aceita nmeros negativos, e se for o caso,
encerra. Tambm h previso de entrada do nmero 1, como 1 2
= -1. Todos os nmeros mpares so somados em seqncia e
guardados em soma aps processamento. Note que todo o
processamento dos nmeros realizado pela funo. A funo
main apenas verifica uma entrada de nmero negativo, e imprime
o resultado da soma.
Funo de tipo inline
Diferentemente dos outros tipos de funes onde uma funo
invoca outra e o fluxo de execuo passa para a funo chamada,
passando dados entre si, a funo inline literalmente
transferida para a funo que a invocou e executada dentro do
corpo da funo invocadora pelo compilador. um mtodo que
executa mais rpido e com maior eficincia que os outros dois,
mas estas vantagens ocorrem somente quando a funo inline
composta de poucas linhas de cdigo. Veja um exemplo:
#include <iostream>
using namespace std;
int funcao_inline(int); // Declaramos um prottipo de funo
int main()
{
int numero;
cout << "Digite um numero: ";
cin >> numero;
cout << "\nO resultado = " << funcao_inline(numero)<< "\n";
system("pause");
return 0;
}
inline int funcao_inline(int num)
{
85

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


return num * num;
}
Note que a funo inline muito parecida com o tipo prottipo. De
fato um prottipo declarado e na descrio dizemos que se trata
de tipo inline que o compilador ir decidir se tratar como inline ou
no, pois toda funo j tratada como inline pelo compilador,
dependendo se a funo inline ir sobrecarregar a memria do
cache, (memria de variveis) ou no.
Resumindo, o compilador decide se vai usar o tipo prottipo como
inline ou no, mesmo que a declaramos como tal.
Sobrecarregando uma funo:
Esta palavra poder passar a ideia que uma funo em algum
instante explodir, ou causar um incndio, mas na verdade
descreve apenas a instncia que usamos o mesmo nome para
identificar mais de uma funo. Por exemplo, se temos uma
funo que realiza o trabalho de clculo de rea quadrada de um
tringulo usando os argumentos de x e y (x1, y1, x2, y2, x3, y3),
enquanto outra funo calcula a rea de um tringulo usando
como argumentos (base, altura), as duas funes podero ter o
mesmo nome, como por exemplo, int calc_area_triangulo (int x1,
int y1, int x2, int y2, int x3, int y3) e a outra int calc_area_triangulo
(int base, int altura). Isto perfeitamente aceitvel, pois C++
identifica cada funo pelos argumentos, no caso. Para ns neste
momento, estes detalhes no fazem muito sentido, mas logo mais
veremos que cada nome, cada varivel e outros dados ocupam
espaos na memria, e que esta memria disponibilizada
parcamente. Isto pode ser comparado nossa conta de cheque
especial onde
temos apenas R$1.000,00 disponveis, mas as
contas somam R$1.250,00. Claro, a sada tentar reduzir os
R$250,00 a mais.

86

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Os Segredos de Laos Aninhados:
Laos de funo for so utilizados quando temos a necessidade
de processar uma predeterminada quantidade de dados, repetido
uma predeterminada quantidade de vezes. Humm, parece
complicado, mas mais simples que a explicao leva a crer. Um
uso tpico seria imprimir aquela tabelinha de multiplicao,
comeando com o nmero 1 multiplicado de 1 at 10 vezes, depois
o nmero 2 multiplicado de 1 at 10 vezes e assim por diante at o
nmero 10 multiplicado de 1 at 10 vezes. Seria possvel um mero
mortal elaborar um programa em C++ para realizar esta tarefa? Ok
mero mortal, aonde comear?
Bem, o primeiro passo ser a de saber o que est acontecendo.
Veja este pequeno programa:
#include <iostream>
using namespace std;
int main()
{
for (int i=1; i<=3; i++)
{ // Inicio do lao externo
cout << "\nO valor de i = " << i << endl;
system("pause");
for (int j=1; j<=3; j++)
{ // Inicio do lao aninhado (interno)
cout << "\nO valor de j = " << j;
cout << "\nO valor de i * j = " << i * j << endl;
system("pause");
} // Fim do lao aninhado (interno)
} // Fim do lao externo
return 0;
}

87

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


A execuo da funo for externa comea com o valor da
varivel i de tipo int inicializada com nmero 1. A segunda
funo for est dentro da primeira entre as chavetas de incio e
fim, mas estando as duas na mesma funo, no caso main,
precisamos usar nomes de variveis diferentes, portanto na
segunda funo for inicializamos a varivel j com valor de
nmero 1, depois incrementado para 2 e finalmente para 3.
Durante todo o tempo a varivel i permaneceu com valor
numrico 1. Somente depois de avaliao de j retornar falso
que o fluxo de execuo retorna primeira funo for, que
acontece quando j == 4 e o lao rompido. Esta seqncia
repetida i vezes e termina quando i == 4 e o lao rompido. Se
ordenar os resultados imprimidos, veremos o incio de nossa
tabelinha de multiplicao. i.e.
i
j
i
j
i
j
1x1=1 2x1=2 3x1=3
1x2=2 2x2=4 3x2=6
1x3=3 2x3=6 3x3=9
Veja abaixo uma variao da tabela x 10:

88

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


#include<iostream>
using namespace std;
int main()
{
cout << "A tabela de 10:" << endl;
cout << " 1x\t2x\t3x\t4x\t5x\t6x\t7x\t8x\t9x\t10x" << endl;
cout << "---------------------------------------------------------------------------" << endl;
cout << "" << endl;
for(int i = 1; i <= 10; i++)
{
cout << i << "| ";
for(int j = 1; j <= 10; j++)
{
cout << i * j << '\t';
}
cout << endl;
}
system("pause");
}
Note no segundo uso de cout em que dissemos ao C++ que dever
imprimir os nmeros de 1 e at 10 cada separado por tabulao,
enquanto que no quinto uso de cout dissemos que dever imprimir
os nmeros entre 1 e at 10 (valores de i) seguido pelo caractere
|, barra vertical. No sexto uso de cout o resultado da
multiplicao de i * j seguido por tabulao cada e no ltimo uso
de cout dissemos que depois de imprimir cada linha de resultados
em coluna, o cursor ir para prxima linha.

89

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


At o momento avaliamos a condio do segundo argumento da
funo for a partir de um valor prefixado. No entanto C++
permite que este argumento seja alterado qualquer instante. Isto
torna nossos laos dinmicos e atuantes.
Imagine que precisamos elaborar um programa que imprime todos
os nmeros primos entre 1 e at 100.
Como sabemos um nmero primo somente divisvel por 1 ou pelo
valor dele mesmo. Assim o nmero 4 no um nmero primo, pois
divisvel por 2, alm claro, por 1 e 4. A pergunta , como
podemos escrever um programa que realiza esta tarefa? Para mim,
quando um trabalho parece muito complicado, vou reduzindo este
em pedacinhos, cada pedacinho fazendo uma pequena parte do
trabalho. Acho que podemos comear com a gerao dos 100
nmeros, concorda? Ok.
for (int i=1; i<=100; i++). Pronto, j temos a seqncia de 100
nmeros.
Para cada nmero gerado, vamos ter que sucessivamente testar
se um nmero primo. Se numero = i, ento podemos reduzir a
faixa de teste entre i =1, e i = numero. Isto faz sentido? Claro, mas
vamos comear o teste com 2, pois sabemos que o nmero 1 j o
primeiro nmero primo.
for (int i=2; i < numero; i++). Neste lao, sempre que retorna uma
avaliao verdadeira, incrementa-se i, e sempre que falso, no
incrementa i. Depois de avaliado e processado o nmero 1,
numero ser sempre maior ou igual ao valor de i. Lembre-se que i
uma varivel local, portanto podemos usar o mesmo nome pois
pretendemos aninhar este segundo lao como parte de uma
funo que no a main. Ok, temos dois nmeros diferentes. E
agora, o que podemos fazer com eles? Bom, vamos analisar logo
que i=1=numero. Neste segundo lao avaliamos 2<1 que falso e
saimos deste lao, o mesmo acontecendo quando i=2=numero pois
2<2 tambm falso e i no incrementado em i++ em nenhum
dos casos.

90

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Estamos numa situao em que basta um retorno de falso ou
verdadeiro, ento podemos imprimir os nmeros 1 e 2 que
retornaram falso.
Neste interim nosso lao externo foi incrementado, para 2 e para
3. Com numero = 3 vamos testar esta condio no lao i=2; 2<3;
que retorna verdadeiro e i incrementado, depois no mesmo lao,
numero = 3; i = 3 , 3 < 3 retorna falso e samos do lao. Quando i
era 2 e numero era 3, verdadeiro, como podemos verificar se
numero primo? Uma maneira simples a de testar o mdulo dos
dois nmeros. (numero % i ==0) Esta avaliao retorna falso no
caso de ((3 % 2 == 0) = falso) porque sobra 1. Um falso retornado
significa um nmero primo, e se o teste retorna verdadeiro, no
um nmero primo pois um nmero divisvel por um de valor
menor.
Ento temos mais um pedacinho do quebra cabea:
numero % i == 0;
Claramente temos 3 funes, a main que gerar os nmeros entre
1 e 100, e que chama a funo de teste com parmetro. A funo
retorna verdadeiro ou falso, e caso verdadeiro imprime o nmero
sendo testado, caso falso, no imprime o nmero.
A segunda funo ir gerar um meio de testar o nmero gerado em
main, contra nmeros que aumentam sucessivamente at o valor
de numero. Sempre que a seqncia retornar verdadeiro, invocar a
terceira funo para testar se divisvel. Caso falso a seqncia,
a funo retorna verdadeiro main, que imprime o nmero.
A terceira funo realiza o trabalho de testar o caso de um nmero
ser divisvel por um nmero de menor valor numrico.
Veja o programa com todos os pedacinhos no lugar, abaixo:

91

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


#include <iostream>
using namespace std;
bool primo (int numero); // Declaramos os prottipos
bool divisivel (int numero, int divisor); /* das funes primo e
divisivel tipo bool */
int main ()
{
cout << "Estes sao os numeros primos entre 1 e ate 100: \n\n";
for ( int i = 1; i <= 100; i++ )
{
if ( primo( i ) ) // Invocamos a funo primo com parmetro valor i
{
cout << i << '\t'; // Imprimir o resultado com (tabulao) em colunas
}
// sempre que primo retorna verdadeiro
}
cout << endl;
system("pause");
}
//Fim de main
bool primo (int numero) // A funo primo recebe o valor de i
{
for ( int j = 2; j < numero; j++) //Lao aninhado
{ // Inicio do lao aninhado
if ( divisivel( numero, j )) /* A funo divisivel recebe os valores de
i (numero) do lao externo e de j do
lao interno chamado de divisor*/
{ //Inicio de if
return false; // Esta linha pulada sempre que divisvel retorna 0
} //Fim de if
} // Fim de for. Estamos aqui porque for retornou falso
return true; // Estamos aqui porque um nmero primo
} //Fim de primo
bool divisivel (int numero, int divisor)
{
return numero % divisor == 0;
}
92

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Passando parmetros para a linha de comando:
At o momento declaramos a funo main como uma funo vazia,
mas podemos passar parmetros ou argumentos para main. Esta
operao torna-se necessrio quando necessitamos que main
execute um programa que abre um arquivo, passando o arquivo
para main, como exemplo.
Veja o programa abaixo:
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char *argv[])
{
//main uma funo, portanto aceita parmetros
argc = 5;
argv[1] = "Meu";
argv[2] = "nome";
argv[3] = "e";
argv[4] = "Andrew";
cout << "argc = " << argc << endl;
for(int i = 0; i < argc; i++)
cout << "argv[" << i << "] = " << argv[i] << endl;
system("pause);
return 0;
}
Os argumentos de main sempre seguem este padro, onde int argc
define o nmero de argumentos e char *argv[] um apontador
para os elementos em argc, chamado de vetor. Note que arcv[0]
retornou o caminho onde o programa reside, i.e. C:\ e etc onde
voc determinou como local para armazenagem dos programas
desenvolvidos.

93

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


J sabemos para que servem nmeros binrios e hexadecimais.
Podemos elaborar um programa que converte nmeros decimais
em nmeros binrios e hexadecimais, e ainda determina o tipo de
tringulo pelas medidas dos lados, e tambm imprime o fatorial de
um nmero? Fiz o programa abaixo que realiza quase todo
trabalho, s falta acrescentar uma funo que retorna o dia da
semana:
#include<iostream>
using namespace std;
int convDecHex( int numDecimal)
{
int quociente;
int i=1,j,temp;
char numeroHexa[10];
quociente = numDecimal;
while(quociente!=0)
{
temp = quociente % 16;
//converter dec em caracteres hex
if( temp < 10)
{
temp = temp + 48;
}
else
temp = temp + 55;
numeroHexa[i++]= temp;
quociente = quociente / 16;
}
cout << "O numero equivalente hexadecimal = ";
for(j = i -1 ;j> 0;j--)
{
cout << numeroHexa[j];
}
return 0;
}

94

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


int converterDec_Binario(int numDecimal)
{
int quociente;
int numeroBin[100],i=1,j;
quociente = numDecimal;
while(quociente!=0)
{
numeroBin[i++]= quociente % 2;
quociente = quociente / 2;
}
cout << "O numero binario equivalente a " << numDecimal << " =
";
for(j=i-1; j>0; j--)
{
cout << numeroBin[j];
}
return 0;
}
int fatorial(int expoente)
{
static int fat=1;
if(expoente>0)
{
fat=fat*expoente;
fatorial (expoente-1);
}
return fat;
}
int triangulo(float a, float b, float c)
{
if(a==b && a==c)
{
return 1;
}
else if(a==b && a!=c)
{
return 2;
}
95

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


else return 3;
}
int main(){
int num, fat, expoente, escolha, tipo_triangulo;
float a, b, c;
cout << "Escolher a operaao " << endl;
cout << "\n\t1- Fatorial";
cout << "\n\t2- Converter decimal para hexadecimal";
cout << "\n\t3- Converter decimal para binario";
cout << "\n\t4- Determinar tipo triangulo";
cout << "\n\t5- Determinar dia da semana" << endl;
cin >> escolha;
switch (escolha)
{
case 1: cout << "Digite o numero a fatoriar " << endl;
cin >> num;
expoente = num;
fat = fatorial(expoente);
cout << "O numero fatoriado = " << fat << endl;
break;
case 2:
cout << "Digite o numero para converter em
hexadecimal " << endl;
cin >> num;
convDecHex(num);
break;
case 3:
cout << "Digite o numero decimal para converter em
binario " << endl;
cin >> num;
converterDec_Binario(num);
break;
case 4:
cout << "Digite os lados a, b, c do triangulo " << endl;
cin >> a >> b >> c;
tipo_triangulo = triangulo(a, b, c);
if(tipo_triangulo == 1)
96

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


{

cout << "O triangulo eh equilatero" << endl;

}
else if(tipo_triangulo == 2)
{
cout << "O triangulo eh isoceles" << endl;
}
else if(tipo_triangulo == 3)
{
cout << "O triangulo eh escaleno" << endl;
}
break;
case 5: // Acrescente a funo que retorna dia da semana
break;
}
return 0;
}
Analise cada funo do programa e usando seus conhecimentos
adquiridos at este momento, elabore meios de fazer o programa
executar enquanto no receber um comando que encerra a
execuo. Acrescente uma funo que retorna o dia da semana.
Dica (enum).
Bom, agora que aprendemos a dana do tango com as funes,
resta saber se vamos pisar no p delas durante o ensaio:

97

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Um pequeno teste, Teste 5:
1)
a)
b)
c)
d)

Qual a opo abaixo que declara um prottipo de funo?


funcao (int numero);
prototipo;
int funcao (int num1, int num2);
funcao = int i * int j;

2)
a)
b)
c)
d)

Qual a opo abaixo que define uma funo?


int funcao (int) = 2;
int funcao (int a, int b) { return a*b; }
int funcao (int a, int b);
char funcao (int);

3)
a)
b)
c)
d)

Qual a opo abaixo que invoca uma funo?


int funcao(i);
resultado = multiplicar (num1, num2);
cout << O resultado = << soma (num1 + num2);
if (mult *i = 2);

Respostas do Teste 5: 1) c; 2) b; 3) b;

98

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Captulo 8 Reservando memria usando Matrizes:
At o momento reservamos memria quando declaramos uma
varivel e tipo de dados que ela usar. Automaticamente C++
reserva a quantidade de memria necessria para guardar os
dados que pertence varivel. Imagine a situao em que temos 5
instrumentos sendo ciclados automaticamente em ambiente
trmicamente controlado. Testaremos os instrumentos ao aplicar
uma tenso e ler o resultado em degraus de temperaturas que
correspondem : -40oC, 0oC, 25oC, 55oC e 85oC. Teremos ento: 5
leituras x 5 degraus = 25 leituras. O programa ter de identificar
cada instrumento, e juntar a ele os resultados do teste de cada
degrau de temperatura. Para no ter que declarar dezenas de
variveis, podemos declarar apenas uma matriz onde podemos
guardar todos os resultados em um s lugar. Maravilha no?
Assim como a declarao de variveis, o mesmo acontece com
matrizes. A diferena que declaramos quantas memrias
compe a matriz, ou em outras palavras, quantas clulas
individuais compe a matriz. Matrizes possuem dimenses, sendo
a mais simples unidimensional, depois a bi-dimensional e at as
matrizes multi-dimensionais. Vamos ento ver como funcionam
matrizes:
A matriz unidimensional:
Para declarar uma matriz unidimensional obedecendo a sntaxe:
tipo de dados nome_da_matriz [ ];
As chavetas quadradas contero a quantidade de clulas que
compe a matriz. Resta lembrar que a primeira clula sempre
possui endereo 0.
Uma matriz unidimensional: int matriz [8]; Esta matriz possui 9
clulas dispostas em uma nica fileira que ocupam 2 Bytes de
memria cada.

99

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Podemos expandir visualmente a matriz desta forma:
matriz
0

O nome ou identificador da matriz matriz aponta para o primeiro


elemento, o elemento 0.
Neste momento nossa matriz de 8 clulas contm lixo, digo isto no
bom sentido. Vamos ento salvar em cada clula o nmero 0, a
saberemos o que contm.
#include <iostream>
using namespace std;
int main()
{
int celula = 0;
int matriz [8];
for (int i=0; i<8; i++)
{
matriz [i] = celula;
}
for (int i=0; i<8; i++)
{
cout << "A celula " << i << " da matriz contem: " << matriz [i] <<
endl;
}
system("pause");
}
No primeiro lao escrevemos o conteudo da varivel de nome
celula e de tipo inteiro desde a clula de endereo 0 e at a de
endereo 7 inclusivo. No segundo lao enviamos o conteudo de
cada clula em seqncia para cout que o imprime na tela. Em
cada caso endereamos a clula de interesse com o valor em i.

100

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Podemos inicializar uma matriz, por exemplo de tipo char:
char matriz [] = Algum texto;
char matriz [] = { A, l, g, u, m, , t, e, x, t, o, \0 };
Ao compilar as duas linhas de cdigo supra, o sistema escreve os
dois textos em memria, matriz apontando para a primeira clula
que contm A nos dois casos. A nica diferena que no
primeiro caso, o sistema acrescenta um caractere nulo \0 na
ltima clula. No segundo caso ns acrescentamos o caractere
nulo. O caractere nulo usado para definir onde terminam os
dados na matriz, mas nunca imprimido, pois serve apenas como
ponto de referncia de fim de dados.
Veja o programa abaixo:
#include <iostream>
using namespace std;
int main ()
{
char matriz [] = "Algum texto";
char outra_matriz [] = { 'A', 'l', 'g', 'u', 'm', ' ', 't', 'e', 'x', 't', 'o', '\0' };
cout << matriz << " " << outra_matriz << endl;
cout << matriz[0] << matriz[1] << endl;
system("pause");
return 0;
}
No segundo uso de cout endereamos explicitamente as primeiras
duas clulas de matriz, e imprimimos seus contedos.
Em tese uma matriz unidimensional poder conter inmeras
clulas, e podemos declarar inmeras matrizes de tipos
diferentes. Para o programa de teste de instrumentos temos que
associar temperatura com leitura cada instrumento. O mais
apropriado para esta aplicao seria uma matriz bi-dimensional:

101

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Podemos visualizar este tipo:
double teste [5] [5];
Nesta matriz bi-dimensional podemos obter as leituras de at 5
instrumentos, cada srie de leituras cinco temperaturas
diferentes.
double teste [5] [5];
Endereo lao interno

Endereo
Lao
externo

0,0

0,1

0,2

0,3

0,4

1,0

1,1

1,2

1,3

1,4

2,0

2,1

2,2

2,3

2,4

3,0

3,1

3,2

3,3

3,4

4,0

4,1

4,2

4,3

4,4

Vejamos que a leitura do instrumento nmero 1 -40C estar


guardada na matriz teste na clula de endereo 0,0, do
instrumento nmero 2 no endereo 0,1 e assim adiante,
completando a leitura de 5 instrumentos -40C. Se temos uma
leitura de 5,024 guardada na clula de endereo 2,3 podemos
ganhar acesso ao contedo desta clula:
cout << A leitura do instrumento 4 -40C = << teste [2] [3];
Note que em memria as 25 clulas estaro dispostas em linha
horizontal, com nome teste apontando para a primeira clula,
[0,0].

102

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Aps analisar a matriz bi-dimensional temos a plena intuio de
que precisaremos de dois laos aninhados para leitura dos
resultados, e mais dois laos aninhados para imprimir os
resultados guardados. Suponhamos que uma mquina externa que
possui conversores analgicos/digitais at 16 canais configurado
para que sejam guardados todos os resultados. Uma vez terminado
o teste, as leituras so enviadas em seqncia para nosso
programa, comeando com as relacionadas -40C. Iremos
simular a tal mquina inserindo os valores em torno de 5,000 numa
varivel de nome valores de tipo double. Finalmente nosso
programa ir determinar o desvio padro de todos os instrumentos
testados, e o imprimir. Olhe, se isto estimulou uma vontade
enorme de sair correndo para tomar uma cervja ao invs de
encarar este desafio, inteiramente compreensvel, mas se ficar
ir se sentir maravilhosamente bem, pois o melhor est por vir,
garanto.
Primeiramente, para quem no sabe, o desvio padro dp dado
pela equao:
dp =

(n n1)2
(nt 1)

Onde: = soma; n1 = valor da mdia de n testes; n= valor de cada teste:


nt = nmero de testes;
Uma das descries de desvio padro o clculo da probabilidade
de acontecer uma anormalidade. Para cumprir as normas de
controle
de
qualidade
um
instrumento
dever
operar
nominalmente
em
ambientes
de
grandes
variaes
de
temperatura. Neste teste iremos determinar o desvio padro de
um lote de instrumentos.

103

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Para realizar clculos de raz quadrada necessrio incluir o
arquivo cabealho <cmath>. Se sua verso de Devcpp no veio
com este arquivo, poder ser baixado pelo site: devpak.org.
Devpaks contm uma multiplicidade de arquivos de cabealho,
cada um elaborado para cumprir uma srie de trabalhos. Ver que
cmath um aliado completo quanto questes de operaes de
matemtica, citando apenas um dos arquivos que um Devpak
contm. Para se certificar que sua verso de Dev-cpp possui
cmath, execute o programa abaixo:
#include <iostream>
#include <cmath>
using namespace std;
int main ()
{
double numero;
cout << "Entre com um numero: ";
cin >> numero;
cout << "\nA raiz quadrada de " << numero << " = " << sqrt (numero)
<< endl;
system("pause");
}
Caso no possuir cmath, o compilador ir resmungar sobre esta
falha, e no realizar a compilao. Mas tudo bem, poder baixar
cmath e copi-lo para a pasta Include de devcpp.
Voltando questo dos instrumentos que esto esperando nosso
programa qual falta est emperrando a produo, temos que
pensar um pouco. Bom voc pensa, primeiro vou escrever o
programa main, que vai ter meios de guardar as 25 leituras vindo
dos instrumentos. Lembra-se que vamos fingir que a entrada
destes dados ser realizada pelo teclado, e no diretamente
atravs de uma porta de comunicao serial ou paralela como
numa situao real.

104

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Depois, main vai chamar uma funo para realizar todos os
clculos de desvio padro, a funo retorna para main o valor do
desvio padro, e o imprime. Perfeito.
Aqui est main que escrevemos aps algumas tentativas:
int main()
{
double valores [5][5];
for (int i=0; i<5; i++)
{
for (int j=0; j<5; j++)
{
cout << "Entrar com valor " << "[" << j << "]"<< "["<< i << "]" <<
": ";

cin >> valores [j][i]; // Envia para cada clula o valor teclado
}
}
cout << "\nO desvio padrao = " << calc_dp(valores);
cout << endl;
system("pause");
}
Primeiro declaramos uma matriz bi-dimensional de 5 x 5 clulas
onde vo os valores inseridos, resultados das leituras dos 5
instrumentos a 5 degraus de temperaturas. Em seguida um lao
for que usa a varivel i tipo inteiro como argumentos. Outro
lao for aninhado usa a varivel j tipo inteiro como
argumentos. Como esto aninhados na mesma funo tivemos que
chamar as variveis de nomes diferentes. Note o fato que a
avaliao das variveis correspondem quantidade de clulas
declaradas da matriz bi-dimensional. Apos inseridas as leituras na
matriz valores [j][i] de main, chamamos a funo calc_dp
usando como argumento a matriz valores. No preciso declarar
que se trata de uma matriz, C++ j sabe. O mesmo cout tambm
recebe o valor calculado pela funo, do desvio padro.

105

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Uma calculadora cientfica possui um programa especializado
para calcular desvio padro. Nossa funo ter de realizar o
mesmo trabalho passo a passo. Lembrando a equao:
dp =

(n n1)2
(n 1)

1 passo: Somar todas as leituras;


2 passo: Dividir a soma das leituras pelo nmero de leituras para
determinar a mdia das leituras;
3 passo: Subtrair de cada leitura a mdia;
4 passo: Multiplicar cada resultado do 3 passo por si;
5 passo: Somar os resultados do 4 passo;
6 passo: Dividir a soma do 5 passo pelo nmero de testes 1;
7 passo: O desvio padro a raz quadrada do valor do 6 passo;
Veja nossa funo que efetua todos estes clculos:
double calc_dp (double valores[5][5])
{
double soma = 0;
double media = 0;
double n_menos_1 = 24;
double numero_testes = 25;
double soma_n_menos_media = 0;
double desvio_padrao = 0;
double res_n_menos_media = 0;
double soma_quadrados = 0;
double quadrado [5][5];
for (int i=0; i<5; i++)
{
for (int j=0; j<5; j++)
{
soma += valores[j][i]; // Mesmo que soma=soma + valores
}
106

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


}
media = soma / numero_testes;
for (int i=0; i<5; i++)
{
for (int j=0; j<5; j++)
{
res_n_menos_media = valores [j][i] - media;
quadrado
[j][i]
=
res_n_menos_media
res_n_menos_media;
soma_quadrados += quadrado [j][i];
}
}

desvio_padrao = sqrt (soma_quadrados / n_menos_1);


return desvio_padrao;
}
Na declarao da funo temos que dizer ao compilador que
estamos usando a matriz bi-dimensional valores com tipo e
tamanho, que no caso pertence main. Lembre que em main
chamamos a funo dizendo que passariamos os dados da matriz
usando apenas o nome da matriz. Usamos laos aninhados
primeiro para obtermos o valor da mdia, depois laos aninhados
para cumprir os passos restantes. Declaramos outra matriz bidimensional chamada de quadrado para cumprir o 4 passo.
Finalmente obtivemos a raz quadrada usando sqrt (argumentos)
que cmath entende como a raz quadrada de tudo entre
parnteses e passamos para main o desvio padro com return
desvio_padrao.
Veja abaixo o programa completo:

107

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


#include <iostream>
#include <cmath>
using namespace std;
double calc_dp (double valores[5][5])
{
double soma = 0;
double media = 0;
double n_menos_1 = 24;
double numero_testes = 25;
double soma_n_menos_media = 0;
double desvio_padrao = 0;
double res_n_menos_media = 0;
double soma_quadrados = 0;
double quadrado [5][5];
for (int i=0; i<5; i++)
{
for (int j=0; j<5; j++)
{
soma += valores[j][i];
}
}
media = soma / numero_testes;
for (int i=0; i<5; i++)
{
for (int j=0; j<5; j++)
{
res_n_menos_media = valores [j][i] - media;
quadrado
[j][i]
=
res_n_menos_media
res_n_menos_media;
soma_quadrados += quadrado [j][i];
}
}
desvio_padrao = sqrt (soma_quadrados / n_menos_1);
return desvio_padrao;

108

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


}
int main()
{
double valores [5][5];
for (int i=0; i<5; i++)
{
for (int j=0; j<5; j++)
{
cout << "Entrar com valor " << "[" << j << "]"<< "["<< i << "]" <<
": ";
cin >> valores [j][i];
}
}
cout << "\nO desvio padrao = " << calc_dp(valores);
cout << endl;
system("pause");
}
E algum momento surgir a necessidade de passar uma matriz
para uma funo como parmetro. C++ no permite que passamos
um bloco de memria como um valor para uma funo, mas
podemos sim, passar seu endereo. Para tanto basta declarar o
tipo de matriz quando declaramos a funo.
Veja o exemplo abaixo:
void uma_funcao ( int argumento [])
Ao declarar uma matriz:
int minha_matriz [80];
Basta chamar a funo com a matriz como parmetro:
uma_funcao (minha_matriz);

109

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Veja o exemplo abaixo:
#include <iostream>
using namespace std;
void imprimir_matriz (char matriz[], int comprimento)
{
for (int i=0; i<comprimento; i++)
cout << matriz[i];
cout << endl;
}
int main ()
{
char matriz1 [] = { 'E', 's', 't', 'o', 'u', ' ', 'f', 'e', 'l', 'i', 'z', '\0' };
char matriz2 [] = { 'O', 'i', '\0' };
imprimir_matriz (matriz2, 2);
imprimir_matriz (matriz1, 11);
system("pause");
return 0;
}
Declaramos e definimos nossa funo chamada imprimir_matriz
com dois parmetros, o primeiro aceita qualquer matriz de tipo
char, o segundo especifica seu comprimento. A funo no tm
retorno, por isso determinamos o tipo void, pois apenas imprime o
contedo das matrizes que a enviamos. J em main, declaramos
duas matrizes de tipo char e as inicializamos. Chamamos a funo
duas vezes, com parmetros que definem o nome da matriz, e a
quantidade de dados que cada uma contm.
Surge a necessidade de se ordenar nmeros inseridos em ordem
aleatria, em ordenao crescente ou decrescente. Como fazer
isto? Bem, usamos um algoritmo de ordenao, e funciona de
seguinte forma:

110

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


#include<iostream>
#include<tchar.h>
using namespace std;
int main()
{
_tsetlocale(LC_ALL, _T("portuguese"));
int i, j, temp, num[50];
cout << "Favor digitar 50 nmeros inteiros:\n";
for(i=0;i<50;i++)
{
cin >> num[i];
}
for(i=0;i<50;i++) // O algoritmo de ordenao comea aqui
{
for(j=0;j<50;j++) // Este loop executado 50 vezes cada valor de i
{
if(num[i]<num[j])
{
temp = num[i];
num[i] = num[j];
num[j] = temp;
}
}
} // e termina aqui
cout << "O maior nmero = " << num[49] << endl;
cout << "O menor nmero = " << num[0] << endl;
cout << "A soma do maior com menor = " << num[49] + num[0];
return 0;
}

111

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


No programa supra aproveitei o ensejo para incluir uma biblioteca
<tchar.h> que permite usar texto em Portugus usado em cout <<
apenas.
A primeira linha _tsetlocale(LC_ALL, _T("portuguese"));
de main faz esta correlao. Depois usamos laos for aninhados
para realizar a ordenao dos nmeros inseridos na matriz tipo int
de nome num[50] pela funo cin>>;
O loop de varivel j executado 50 vezes para cada valor da
varivel i, o nmero de menor valor estar guardado em num[0] e o
maior valor em num[49]. Neste programa soma-se o maior com
menor e imprime o resultado.
O algoritmo de ordenao guarda os valores ordenados nas
posies da matriz em ordem crescente neste caso. Um bom
exerccio seria inverter a ordem, de crescente para decrescente.
Para tanto, acrescentar um loop for(i=49;i<0;i--) { cout<< Os
nmeros em ordem decrescente = << num[i] << endl;

112

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Captulo 9 A funo switch case
No programa que simula uma mini-calculadora, apresentamos ao
usurio uma tabelinha de opes de escolha. Reproduzimos aqui o
cdigo que produz esta tabelinha:
cout << "\n\t 1 - Somar: "; // de escolha mltipla
cout << "\n\t 2 - Subtrair: ";
cout << "\n\t 3 - Multiplicar: ";
cout << "\n\t 4 - Dividir: ";
cout << "\n\t 5 - Area de circulo:";
cout << "\n\t 6 - Circumferencia:";
cout << "\n\t 0 - Encerrar: ";
cin >> escolha;
Depois de apresentar a tabela de mltipla escolha, tivemos que
elaborar uma quantidade de filtros usando if else if at reduzir
a escolha um nmero constando da tabela, e executar o cdigo
que a escolha representa. A funo switch veio para tomar o
lugar de algumas declaraes de if else if. Vejamos como
switch funciona usando nossa tabela de mltipla escolha:
cin >> escolha;
switch (escolha)
{
case 1:
somar ();
break;
case 2:
subtrair();
break;
case 3:
multiplicar();
break;
case 4:
dividir();
break;

113

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


case 5:
area();
break;
case 6:

case 0:

circum();
break;
cout << Encerrando o programa. ;
break;

default:

cout << Erro. Favor escolher uma das opcoes: ;


break;

Maravilha, podemos usar switch-case no programa de minicalculadora, e deletar alguns if, else if. Mas espera a, e se o
usurio errar a tecla na fase de escolha, enviada a mensagem de
erro e o usurio no tem outra chance de corrigir seu erro? Calma,
estavamos chegando l. Se colocamos switch num lao, o usurio
ter chance de se redimir, a boa notcia sendo que ao executar
break o fluxo de execuo direcionado apenas at o final de
switch, e no do lao.

114

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Veja abaixo a verso da mini-calculadora usando switch:
#include <iostream>
#define pi 3.141593
using namespace std;
double somar (double num1, double num2) //Declarao da funo
{
return num1 + num2; //O trabalho que a funo realiza
} //Fim da funo
double subtrair (double num1, double num2)
{
return num1 - num2;
}
double multiplicar (double num1, double num2)
{
return num1 * num2;
}
double dividir (double num1, double num2)
{
return num1 / num2;
}
double area (double raio)
{
return pi*raio*raio;
}
double circum (double raio)
{
return 2*pi*raio;
}
int main()
{
double num1, num2, resultado, raio;
int escolha;

115

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


while (1)
{
cout << "\n\t Operacao "; // Apresentamos um menu
cout << "\n\t 1 - Somar: "; // de mltipla escolha
cout << "\n\t 2 - Subtrair: ";
cout << "\n\t 3 - Multiplicar: ";
cout << "\n\t 4 - Dividir: ";
cout << "\n\t 5 - Area de circulo:";
cout << "\n\t 6 - Circumferencia:";
cout << "\n\t 0 - Encerrar: ";
cout << "\n\tEscolhe a opcao: ";
cin >> escolha;
if (escolha == 0)
{
break; // Sair do lao while
}
else if (escolha >=1 && escolha <=4)
{
cout << "Digite dois numeros: \n";
cin >> num1 >> num2; /*Passaremos estes dois nmeros
para a funo escolhida*/
}
else if (escolha == 5 || escolha == 6)
{
cout << "\nDigite o raio, em cm: ";
cin >> raio;
}
switch (escolha)
{
case 1: resultado = somar(num1, num2);
break;
case 2: resultado = subtrair(num1, num2);
break;
case 3: resultado = multiplicar(num1, num2);
break;
116

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


case 4: resultado = dividir(num1, num2);
break;
case 5: resultado = area(raio);
break;
case 6: resultado = circum(raio);
break;
default: cout << "\nEscolha " << escolha << " invalida.
Favor tentar novamente.\n";
break;
}
if (escolha == 1)
{
cout << "O resultado da soma = " << resultado << endl;
}
else if (escolha == 2)
{
cout << "O resultado da subtracao = " << resultado <<
endl;
}
else if (escolha == 3)
{
cout << "O resultado da multiplicacao = " << resultado
<< endl;
}
else if (escolha == 4)
{
cout << "O resultado da divisao = " << resultado << endl;
}
else if (escolha == 5)
{
cout << "A area do circulo = " << resultado << " cm
quadrados " << endl;
}
else if (escolha == 6)
{
cout << "A circunferencia do circulo = " << resultado <<
" cm " << endl;
117

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


}
} // Fim de while. Estamos aqui porqu a escolha foi o nmero 0
} // Fim de main
} // Fim de while. Estamos aqui porqu a
escolha foi o nmero 0
Quando chamamos a funo em switch, esta executada j com
os valores de num1, num2 ou raio. A mesma funo retorna um
resultado, mas main no sabe qual a funo retornando o
resultado. Por esta razo mantivemos os filtros de entrada de
escolha. Vale notar que a sntaxe exige o uso de break logo aps a
chamada da funo. Isto evita que o fluxo de execuo seja
direcionado sucessivamente para as opes embaixo da opo
escolhida. Note tambm que switch delimitada com chavetas de
incio e de fim, e no caso a declarao break direciona o fluxo de
execuo apenas at a chaveta fim de switch, e no de while.
Vejamos que switch poder ser utilizado para realizar outros
trabalhos. Veja o programa abaixo:

#include <iostream>
#include <cstring>

/*Temos que incluir a biblioteca cstring para


utilizar a funo strcmp( )*/

using namespace std;


int main()
{
char seq1[20], seq2[20]; //Declaramos duas matrizes de tipo char
int resultado;
cout << "Digite a primeira sequencia: " << endl;
cin >> seq1;

118

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


cout << "Digite a segunda sequencia: " << endl;
cin >> seq2;
resultado = strcmp( seq1, seq2 );
switch( resultado )
{
case ( 1 ):
cout << "A primeira sequencia > que a segunda " << endl;
break;
case ( 0 ):
cout << "A primeira = segunda sequencia " << endl;
break;
case ( -1 ):
cout << "A primeira sequencia < que a segunda " << endl;
}
cout << "O tamanho da primeira sequencia: "<< strlen( seq1 )
<< endl;
cout << "O tamanho da segunda sequencia: " << strlen( seq2 )
<< endl;
system("pause");
}

119

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Temos algumas novidades neste programa. A primeira a incluso
do arquivo cabealho <cstring> que diz ao sistema como
processar a comparao de duas seqncias de letras, atravs da
funo strcmp(argumento1, argumento2). Aps a comparao,
este retorna 1 no caso da primeira ser maior que a segunda, 0 no
caso das duas serem iguais, e -1 caso a segunda seja maior que a
primeira. Uma destas condies foi passada para resultado que
usamos como parmetro de switch. Sabendo que strcmp passa um
destes valores para switch, usamos case para comparar os trs
valores. Outra novidade o uso da funo strlen(argumento) que
retorna o comprimento de uma seqncia de caracteres.
Pergunta..porqu no colocamos break depois da terceira opo?
Bom, a funo strcmp() retorna uma de apenas 3 alternativas e
nada mais. Podemos at usar break e at default, mas quase
impossvel que outra alternativa seja retornada.
O programa abaixo compara duas placas automotivas. Se iguais,
poder abrir um porto que permite acesso:
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char s[20];
char r[20];
cout<<"Digite a primeira placa: \n";
cin.getline(s,10);
cout<<"Digite a segunda placa: \n";
cin.getline(r,10);
if(strcmp(s,r)==0)
cout<<"As placas sao iguais. ";

120

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


else
cout<<"As placas sao diferentes. ";
system("pause");
}
Note o uso da funo cin.getline(destino, comprimento). A funo
strcmp funciona apenas com argumentos de tipo char. Este guarda
o nmero da placa, i.e. LAE 4030 numa matriz, e o compara com
uma placa j registrada. Sei que no caso entramos com a segunda
placa mas vamos fingir que j existe. A funo strcmp retorna 0 se
a comparao em if verdadeira, sendo sim quando retorna 0.

Os segredos da funo enum nome {argumentos (dados)};


Hoje em dia quase tudo que conhecemos pode ser subdividido em
pores menores. Se o assunto o automvel, sendo esta a classe
automvel precisamos especificar um fabricante, e depois um
modelo deste mesmo fabricante, e depois modelos de modelos
deste fabricante e etc. Uma semana composta de 7 dias, (fala
srio, diga algo de novo) de segunda at domingo, apesar de
domingo ser considerado muitas das vezes como o primeiro dia da
semana. (Desculpe, coloquei isto s para efeito de exemplo.) C++
possui uma funo de enumerao que podemos usar. Uma
enumerao de dias por exemplo poder comear com primeiro
elemento segunda-feira. A funo retorna o nmero 0 que substitui
segunda-feira, depois 1 que substitui tera-feira e assim por diante
at domingo. Em tese uma lista enumerada poder conter
qualquer quantidade de elementos. Mas a melhor parte que
podemos usar switch-case para identificar um elemento da lista.
Se no queremos a enumerao do primeiro elemento como sendo
a partir de 0, podemos igualar este a qualquer valor numrico.
Veja abaixo um exemplo de uso da funo enum{};

121

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


#include <iostream>
using namespace std;
enum Dias {
segunda=1,
terca,
quarta,
quinta,
sexta,
sabado,
domingo
}; // A funo termina com ponto e vrgula
int main()
{
int dia=0;
int hoje=0;
cout << "\nQue dia e hoje? (Tecle 1 a 7) segunda = 1: ";
cin >> dia;
hoje = Dias (dia);
switch (hoje)
{
case 1:
cout << "\nHoje
break;
case 2:
cout << "\nHoje
break;
case 3:
cout << "\nHoje
break;
case 4:
cout << "\nHoje
break;
case 5:
cout << "\nHoje

e segunda-feira" << endl;

e terca-feira" << endl;

e quarta-feira" << endl;

e quinta-feira" << endl;

e sexta-feira" << endl;


122

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


break;
case 6:
cout << "\nHoje e sabado" << endl;
break;
case 7:
cout << "\nHoje e domingo" << endl;
break;
default:
cout << "\nAinda esperamos este dia" << endl;
break;
}
system("pause");
}
Algumas observaes importantes quanto ao uso de enum:
Os elementos contidos entre as chavetas de incio e fim que
compe a listagem de enum podem ser texto ou nmeros ou
qualquer caracteres desde que sejam separados por vrgulas.
Contudo no temos acesso diretamente aos elementos, apenas o
valor numrico que os elementos representam na ordem que foram
colocados na lista.
No programa obtemos o nmero que corresponde ao dia. Em
seguida chamamos a funo enum com este argumento, e enum
retorna o nmero que ento usamos em switch que est em hoje.
Imprimimos o dia retornado em case, por final.
Ento, se sente comfortvel com as funes switch case e de
enumerao?

123

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


timo, vamos ao pequeno teste:
Um pequeno teste. Teste 6:
1) Qual das opes abaixo declara corretamente uma matriz?
a) matriz(5);
b) matriz(num2, num3);
c) matriz [3];
d) int matriz [5];
2)
a)
b)
c)
d)

Qual das opes abaixo declara uma matriz bi-dimensional?


matriz 9, 9;
int matriz [3][4];
int matriz [5];
matriz [3][3];

3)
a)
b)
c)
d)

A matriz double matriz [5][5] possui quantas clulas?


15;
25;
35;
10;

4)
a)
b)
c)
d)

O endereo da primeira clula de uma matriz bi-dimensional ?


1,1;
0,1;
0,0;
2,2;

5) Sendo char1 e char2 iguais, strcmp(char1, char2) retorna que


nmero?
a) 2;
b) 0;
c) 1;
d) -1;

124

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


6) enum carros {Ford, Volkswagen, Fiat, Hyundai, Honda, Peugeot};
retorna que nmero relacionado Fiat?
a) 0;
b) 1;
c) 2;
d) 3;
7) Na funo switch case declaramos um destes para impedir
que o case seguinte seja executado:
a) return;
b) break;
c) continue;
d) endl;

Respostas do Teste 6: 1) d; 2) b; 3) b; 4) c; 5) b; 6) c; 7) b;

125

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Captulo 10 Os segredos de Ponteiros (Pointers):
No captulo 4 mencionamos que quando declaramos uma varivel
e a inicializamos, C++ guarda o valor que inserimos, em memria,
e quando resgatamos o valor ao chamar a varivel, por exemplo,
cin << nome da varivel;, C++ lembra o endereo de incio da
memria onde o guardou e o copia para cin. Todo este trabalho era
invisvel para ns, mas agora vamos aprender como enderear as
memrias onde C++ guarda estes valores. Com isto, possvel que
esteja pensando, para que precisamos acessar memria? C++ j
no faz isto? Ento para que ter mais este trabalho?
Bem, estas perguntas so vlidas at certo ponto. Alm deste
ponto reside o fato que at agora nossos programas exigiram uma
quantidade fixa de memria. Uma vez em execuo no tinhamos
como solicitar mais memria, que quando voc estiver no futuro
prximo escrevendo programas de jogos, por exemplo, e quer
acrescentar mais uma nave aliengena ao jogo durante a
execuo, certamente precisar de mais memria para acomodar
a nova nave. De agora e adiante temos que pensar de modo
diferente com respeito memria. Sabemos que programas esto
sendo executados simultaneamente o tempo todo, cada um
reservando uma parte da memria, conhecido vulgarmente como
The Heap que o sistema disponibiliza para este fim. Cada
programa passa a ser o dono de uma parte do heap. Uma vez que
no precisa mais da memria alugada este tem a
responsabilidade de liberar novamente aquela memria para que
outros programas possam us-la. Quando isto no acontece, a
memria rapidamente se esgota, e comeamos a experimentar
problemas para rodar nossos programas, e o sistema comea a
emitir avisos do tipo Memria baixa, e etc.

126

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Ponteiros so de fato semelhantes a qualquer varivel que j
conhecemos. Veja a sntaxe para declarao de um ponteiro:
tipo *nome;
A nica diferena entre esta declarao e a declarao de uma
varivel comum, o uso do asterisco antes do nome. De fato
podemos declarar ponteiros e variveis na mesma linha desde que
sejam do mesmo tipo:
int numero, *ponteiro;
Ponteiros podem trabalhar com variveis, e fazem isto a maior
parte do tempo. Se apontarmos para uma varivel podemos
inclusive alterar seu conteudo:
int numero = 3;
int *p;
p = &numero;
*p = 6;
Agora a varivel de nome numero contm 6.
Nas primeiras duas linhas de cdigo declaramos duas variveis de
tipo inteiro, uma delas como ponteiro. Na terceira linha passamos
para a varivel p o endereo da memria onde est guardado o
conteudo de numero, e na quarta linha dissemos ao compilador
para escrever o nmero 6 na memria apontada pelo ponteiro *p.
Durante a compilao C++ sabe que a varivel p um ponteiro,
pois a declaramos como tal. Esta distino importante para
entendermos como funciona.
Note que o smbolo & usado sempre para especificar um
endereo de memria. Para melhor entender isto tudo, eis um
pequeno programa que exemplifica o que foi dito:

127

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


#include <iostream>
using namespace std;
int main()
{
int numero = 3;
int *p;
cout << "O conteudo de numero = " << numero;
p = & numero;
cout << "\nO endereco de numero = " << p;
*p = 6;
cout << "\nO conteudo de numero agora = " << numero << endl;
system("pause");
}
Note que o C++ retornou o endereo da memria da varivel
numero em sistema de numerao hexadecimal 0x22ff74 que
equivalente ao nmero decimal 2.293.620. Como sabemos, o
sistema de numerao decimal possui base 10, j o hexadecimal
possui base 16. Veja a comparao entre os dois sistemas:
0
0

1
1

2
2

3
3

4
4

5
5

6
6

7
7

8
8

9
9

10 11 12 13 14 15
A
B
C
D
E
F

Se dividirmos o nmero decimal 256 por 16 sucessivamente a


resposta em hexadecimal 0x100 para C++ ou 100H para ns
seres humanos. Se seu sistema retornou um endereo diferente de
memria, tudo bem. Isto vai de acordo como cada sistema
aporciona memria.
Resumindo, primeiro declaramos o ponteiro, depois obtemos um
endereo, e finalmente, escrevemos um valor para onde o ponteiro
est apontando, de grosso modo.

128

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Nesta altura seria bom frisar que se alterar qualquer valor em
memria que esteja reservado ou para o sistema ou outro
programa, receber uma mensagem como Este programa
executou operao restrita de memria e ser fechado. Ponteiros
no so inofensivos e podem causar um estrago se no forem
controlados. Uma maneira de manter ponteiros sob controle a de
declarar e inicializ-los com valor nulo:
int *p = NULL, ou *p = 0;
Agora que fomos apresentados a ponteiros, digo apresentados
mas ainda no ntimos, vamos elaborar nosso primeiro programa
de grficos, que ser a base de como mover objetos pela tela do
visor.
Para podermos desenhar objetos usando Devcpp, no usamos
ambiente DOS, e sim uma janela orientada a Windows chamada de
WinBGI, que traduzido significa Windows Borland Graphics
Interface. Mas antes precisamos seguir alguns procedimentos
para que funcione:
Como proceder para incorporar grficos em Devcpp:
1) Usar este link <graphics.h> e salvar para a pasta
include do Devcpp; Clicar com boto direito no link, e
abrir hiperlink.
2) Usar este link libbgi.a e salvar para a pasta lib do
Devcpp; Clicar com boto direito no link, e abrir
hiperlink.
3) Execute
Dev-C++
IDE
(Integrated
Development
Environment). Clique em Arquivo -> Novo -> Projeto. Na
janela Novo projeto, clique no tab WinBGIm. Em Opes
do projeto, altere o nome, exemplo, projeto de
graficos. Clique na opo WinBGIm, projeto c++ e OK.

129

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


4) Na janela de Projeto do lado esquerdo, aparecer o
projeto de graficos. Abrir clicando no +. Veja que temos
algum programa chamado de main.cpp que Devcpp
colocou nossa disposio. Clique em main.cpp com
boto direito e Remover arquivo, Salvar arquivo e Sim.
Clicar novamente em Arquivo, Novo e Adicionar nova
unidade ao projeto atual? Sim. Note que agora temos
como parte do projeto, um programa Sem ttulo1.
5) Clique no tab Projeto e Opes do projeto. Clique em
Parmetros e na janela do Linker tecle:
--lbgi
-lgdi32
-lcomdlg32
-luuid
-loleaut32
-lole32
Clique OK.
6) Na janela de programa fonte escreva este programa:
#include<iostream>
#include<conio.h>
#include<graphics.h>
using namespace std;
#define
#define
#define
#define
#define

LEFT
RIGHT
UP
DOWN
ESC

75
77
72
80
27

//
//
//
//
//

Cdigo
Cdigo
Cdigo
Cdigo
Cdigo

ASCII
ASCII
ASCII
ASCII
ASCII

da
da
da
da
da

tecla
tecla
tecla
tecla
tecla ESC

int main()
{
int driver, mode;
char tecla;
int x, y, passo, raio;

130

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


tecla = 0;
x = 100;
y = 100;
raio = 50;
passo = 5;
detectgraph(&driver, &mode);
initgraph(&driver, &mode, "");
while(tecla != ESC)
{
cleardevice();
circle(x, y, raio);
fflush(stdin);
tecla = getch();
if(tecla == LEFT) x = x - passo;
if(tecla == RIGHT) x = x + passo;
if(tecla == UP) y = y - passo;
if(tecla == DOWN) y = y + passo;
}
closegraph();
return(0);
}
Clique em Compilar e Executar. Salvar como movendoobjeto ou
outro nome apropriado. Aps a compilao e a execuo aparece
a tela do WinBGI. Nela um crculo de centro localizado 100 pixels
ao longo do eixo x (horizontal), e 100 pixels ao longo de eixo y
(vertical). O ponto de referncia o canto superior esquerdo do
quadro. (0,0) pixels. Nosso crculo possui 50 pixels de raio, e move
5 pixels cada pulso de uma das teclas direcionais. Note as
funes
detectgraph(&driver,
&mode),
e
initgraph(&driver,
&mode,), que fazem parte de <graphics.h>.

131

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Note que usamos o operador de referncia & para obtermos os
endereos de driver e mode.
Os arquivos cabealho que possuem extenso .h so antigos da
linguagem C, mas Devcpp reconhece estes arquivos, e o prprocessador executa sem problemas. Note que agora temos duas
telas, a que roda em WinBGI, e a que roda em DOS. Temos no
programa uma varivel de tipo char chamada de tecla. Esta recebe
o cdigo da tecla que foi pressionada. Definimos o cdigo de todas
as teclas que sero usadas no programa. Para usar a funo
getch() inclumos o arquivo cabealho <conio.h>. getch() deu
orgem funo cin de Devcpp. Assim aps cleardevice(), que
apaga a ltima posico do crculo, chamamos a funo circle com
trs parmetros, o primeiro em x que se refere coordenada do
centro do crculo no eixo x, o segundo em y que se refere
coordenada no eixo y, e o terceiro que se refere ao raio do
crculo. A funo fflush(stdin) limpa a memria onde estava o valor
da ltima tecla. Direcionamos o crculo com as teclas de controle
de cursor, as quatro flechas. Para cima diminuimos a coordenada
Y por 5 pixels cada pulso, o mesmo com a tecla de esquerda,
diminuimos a coordenada do eixo x por 5 pixels. A tecla direita
aumenta a coordenada do eixo x por 5 pixels, e a para baixo
aumento a coordenada do eixo y por 5 pixels, tudo isto
acontecendo num lao while que espera a tecla Esc para sair do
lao. A funo closegraph() fecha a janela que foi inicializada com
initgraph.
Este programa deve ter deixado voc com mil ideias novas, no?
Bom, vamos voltar para os ponteiros porque ainda temos muito
que falar sobre eles, especialmente relacionados memria.
C++ trata memria como uma grande quantidade de clulas
distribudas numa nica fileira. J vimos o endereo hexadecimal
de uma memria, o endereo de uma varivel. Para no ter que
escrever nmeros enormes como a que representa 22FF74H vamos
fingir que este endereo 2.000D.

132

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Cada clula de memria possui o endereo do anterior +1. Se
procuramos a clula de endereo 2.000 sabemos que esta existe
entre a clula de endereo 1.999 e 2.001, como tambm que ela
existe 100 clulas depois de 1.900, ou 1.000 clulas antes de
3.000.
O Operador de Referncia (&):
No mesmo instante que executada a declarao de uma
varivel, a quantidade de memria necessria atribuida ela
num endereo especfico, o endereo da varivel. Como imaginou,
este trabalho efetuado automaticamente pelo sistema
operacional. O endereo que localiza uma varivel em memria a
referncia da varivel. Tudo bem a? Esta ltima frase a que
importa mais. Resumindo:
Endereo em memria da varivel = & referncia da varivel;
Queremos que Pedro
escrevemos isto assim:

lembre

endereo

de

Paulo,

ento

Pedro = &Paulo;
Se Paulo mora na casa de nmero 2.000, ento Pedro lembra o
endereo 2.000. o nmero que Pedro possui neste momento.
Pedimos para Pedro que busque o que Paulo tem na casa:
Pedro = *Paulo;
Se a casa de Paulo possui conteudo 55 ento nesta altura Pedro
possui 55.

133

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Se Pedro como tambm Paulo so variveis, ento quando
pedimos que Pedro lembre o endereo de Paulo, Pedro se tornou
um ponteiro, porqu uma varivel (que possui endereo prprio)
apontando para o endereo de outra varivel. No entanto, Pedro
deixou de ser um ponteiro quando pedimos que buscasse o
conteudo do endereo de Paulo, voltando a ser uma varivel igual
a Paulo. Se o endereo de Pedro o nmero 1.000, podemos
visualizar toda a seqncia:
Pedro = &Paulo;

Endereo de outra varivel


Conteudo do endereo
Pedro
1.000
1.001
1.002

998

999

34

20

2.000

248

125

1.999
244

Paulo
2.000
55

2.001
464

2.002
128

998

999

Pedro
1.000

1.001

1.002

34

20

55

248

125

1.999
244

Paulo
2.000
55

2.001
464

2.002
128

1.998
56
Pedro = *Paulo;

1.998
56

Se existe o operador de referncia, ento tambm temos o


operador de dereferncia. Dizem que a necessidade a me da
criao!

134

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


O Operador de Dereferncia (*):
Quando pedimos que Pedro lembre o endereo de Paulo, Pedro o
guardou. Agora, entra em cena a Ana. Ela quer o endereo que
Pedro guardou para ter acesso ao conteudo do endereo de Paulo,
e Paulo coitado nem sabe disto.
Escrevemos o pedido de Ana:
Pedro = &Paulo;

998

999

Pedro
1.000

34

20

2.000

248

125

1.999
244

Paulo
2.000
55

2.001
464

2.002
128

998

999

Pedro
1.000

1.001

1.002

34

20

2.000

248

125

1.999
244

Paulo
2.000
55

2.001
464

2.002
128

2.999

Ana
3.000

3.001

1.998
56

1.001

1.002

Ana = *Pedro;

1.998
56

55
Pedro aponta para o endereo de Paulo. Ana pega o conteudo do
endereo de Paulo.

135

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Analise estas linhas de cdigo:
Paulo = 55;
Pedro = &Paulo;
Depois de executadas, todas estas linhas retornam verdadeiro:
Paulo == 55;
&Paulo == 2.000;
Pedro == 2.000;
*Pedro == 55;
Resumindo:

& usado quando queremos o endereo de...;


* usado quando queremos o valor apontado por..;

Para criar mais confuso ainda, o asterisco que usamos para


declarar um ponteiro no tem a mesma significncia que este que
acabamos de usar. O da declarao usado apenas para declarar
o ponteiro, exemplo: int *p; Tudo bem, no vai nos atrapalhar, mas
precisava salientar esta diferna.
Podemos mudar o endereo que estava em um ponteiro, e pass-lo
para outro ponteiro de modo sorrateiro, quer dizer, sem declarar
isto explicitamente. Veja o programa abaixo:

136

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


#include <iostream>
using namespace std;
int main ()
{
int num1 = 1, num2 = 2;
int * p1, * p2;
p1 = &num1;// p1 = endereo de num1
p2 = &num2;// p2 = endereo de num2
*p1 = 10;
// valor apontado por p1 = 10. num1 == 10
p1 = p2;
// p1 = p2 (o endereo de num2 copiado para p1)
*p1 = 20;
// valor apontado por p1 = 20. num2 == 20
cout << "Valor de num1 = " << num1 << endl;
cout << "Valor de num2 = " << num2 << endl;
system("pause");

}
Declaramos duas variveis de tipo inteiro e as inicializamos. Em
seguida declaramos dois ponteiros de tipo inteiro tambm, pois
temos que sempre declarar ponteiros de mesmo tipo que o tipo de
dados que iro processar. p1 est apontando para o endereo de
num1, ponteiro p2 apontando para o endereo de num2. *p1 = 10
escreve o valor 10 para a memria do endereo onde est
apontando, num1. Em seguida, passamos para p1 o endereo de
num2 (p1 = p2), e finalmente escrevemos para a memria do
endereo de num2, o valor 20. Viu? Ponteiros no so to
complicados para entender, como alguns dizem. Bom, pelo menos
at agora.

137

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Lembra de matrizes? Bom, ponteiros so bastante semelhantes.
De fato uma matriz formada utilizando o mesmo conceito que um
ponteiro. E como seria isso, voc pergunta? Bem, quando
declaramos uma matriz, exemplo: char matriz [5];, o nome matriz
aponta para o primeiro elemento da matriz, e se o conteudo de
matriz [0] A, ento cout << matriz [0] imprime a letra A. Apesar
de ser um ponteiro constante, ainda um ponteiro. Se agora
declaramos um ponteiro, char *p; em seguida p = matriz, o
ponteiro torna-se herdeiro de todos os atributos da matriz. Agora o
ponteiro poder mudar todos os valores das 5 clulas que compe
a matriz. Veja o programa abaixo:
#include <iostream>
using namespace std;
int main()
{
char matriz [5];
char *p=NULL;

for (int i=0; i<5; i++)


{
matriz [i] = char (i + 65); // Cdigo ASCII de A e at E
cout << "matriz " << i << " contem " << matriz [i] << endl;
}
p = matriz; // Endereo de matriz em p
*p = char (72); // Guardar em matriz [0] a letra H
p++; // ponteiro aponta para matriz [1]
*p = char (75); // Guardar em matriz [1] a letra K
p = &matriz [4]; // Endereo de matriz [4] em p
*p = char (76); // Guardar em matriz [4] a letra L
for (int i=0; i<5; i++)
{
cout << "matriz " << i << " contem " << matriz [i] << endl;
}
system("pause");

138

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


A tabela de cdigos ASCII:

Esta tabela pode ser decifrada quando usamos o cdigo


hexadecimal ou binrio referente s colunas e fileiras. Por
exemplo para se obter o cdigo decimal da letra A (maiusculo),
obtemos o cdigo hexadecimal, coluna 4, fileira 1, portanto 41 H.
Para converter 41H para o nmero decimal correspondente:
(160 x 1) + (161 x 4) = 1 + 64 = 65D. Podiamos ter colocado o cdigo
hexa se assim desejar: 0x41 que o compilador entenderia
perfeitamente..
matriz [i] = char (i + 0x41); De fato C++ prefere-nos a usar o cdigo
hexadecimal pois todo nmero hexa divisvel por 8, e lembre que
8 bits = 1 Byte, muito menos trabalho para o sistema.
Falamos da semelhana entre uma matriz e um ponteiro. Uma
diferena a de acrescentar memria usando um ponteiro.

139

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Ponteiros e memria dinmica:
At ento, foi reservada apenas uma quantidade fixa de memria
para nossas variveis. Surge um problema. O que fazer quando no
sabemos de antemo a quantidade de memria que nosso
programa necessitar antes da execuo? Vem para nos socorrer
a declarao dos operadores new e delete.
Veja as duas linhas de cdigo:
int *p;
p = new int [6];
Declaramos a existncia de um ponteiro de tipo inteiro. Logo em
seguida que o sistema dever reservar 6 elementos para tipo
inteiro de memria dinmica que pertencem p. Suponhamos
que o endereo de p 2.000. Podemos visualizar a memria a
partir do endereo 2.000:
p
2.000
2.001
2.002
2.003
2.004
2.005

No caso declaramos new int [6] mas podemos dizer new int [i].
Uma vez executando, podemos obter a quantidade de memoria
que necessitamos:
J a declarao do operador delete apaga o conteudo da
memria reservada e a devolve ao sistema.
Veja o programa abaixo:

140

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


#include <iostream>
#include <new> // Permite usar new para reservar memria
using namespace std;
int main ()
{
int mem, num;
int * p;
cout << "Deseja reservar memoria para quantos numeros? ";
cin >> mem;
p = new int [mem];
for (num=0; num<mem; num++)
{
cout << "\nEntre com o numero " << num + 1 << ": ";
cin >> p[num]; // Cada nmero ser guardado a partir de p[0]
}
cout << "\nVoce teclou os numeros: ";
for (num=0; num<mem; num++)
{
cout << p[num] << ", ";
delete [ ] p;
}
system("pause");
}
Incluimos o novo arquivo cabealho <new> para usar new e
delete. Logo aps a entrada da quantidade de nmeros que iremos
armazenar, o sistema aporciona memria dinmica ao ponteiro p
de acordo com o valor de mem, pois solicitamos a quantidade de
memria atravs da linha p = new int [mem];, onde sero salvas
esta quantidade de nmeros inteiros. Como um nmero inteiro
ocupa 4 bytes, a quantidade de memria dinmica reservada p
ser mem x 4 bytes.

141

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Seria racional no entrar com valor de mem com algum valor
exagerado, como 900.000 por exemplo. Seu sistema poder no
ter condies de reservar esta quantidade de memria e ir avisar
com uma mensagem tipo [Erro. No foi possvel reservar a
memria solicitada.] e termina abruptamente o programa. Mais
tarde iremos elaborar meios de transtornar este tipo de problema,
mas por hora vamos em frente.
Uso da funo Vector (Vetor):
Quando usamos a funo vector a quantidade de memria
estipulada reservada, com a diferena que no precisamos usar
delete para devolver a memria ao sistema.
#include <vector> //Precisamos incluir o programa <vector>
#include <iostream>
using namespace std;

vector <int> vector; //Declaramos vector de tipo int


size_t size = 10;//Declaramos a quantidade de memria a reservar
std::vector<int> matriz(size);
/*O vetor ser uma matriz de
tamanho size*/
int main()
{
int matriz[size];
int valor, elemento, i;
for(i=0; i<size; ++i)
{
matriz[i] = i;
}
for(i=0; i<size; ++i)
{
valor = matriz[i];

142

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


if(valor > matriz[i-1])
{
elemento = i;
valor = valor;
}
else
{
valor = valor;
elemento = i;
}
}
cout<<"\n O elemento "<<elemento<<" de valor
"<<valor;
cout<<"\n eh o maior numero ";
system("pause");
return 0;
}
Ponteiros relacionados funes:
Ponteiros permitem que uma funo aponte para o endereo de
uma varivel local que pertence outra funo, em seguida alterar
seu valor:
#include <iostream>
using namespace std;
void trocar_sem_p (int esq, int dir)
{
int temp;
temp = esq;
esq = dir;
dir = temp;
}
void trocar_com_p (int *p_esq, int *p_dir)
{
143

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


int temp;
temp = *p_esq;
*p_esq = *p_dir;
*p_dir = temp;
}
int main ()
{
int x=2, y=7;
trocar_sem_p (x,y);
cout << x << " " << y << endl;
trocar_com_p (&x, &y);
cout << x << " " << y << endl;
system("pause");
return 0;
}
A ideia a de trocar os valores entre as variveis x e y. Antes de
executar o programa, vamos tentar determinar o porqu de termos
duas funes que aparentemente realizam o mesmo trabalho. Note
que nenhuma das funes retorna algum valor. As variveis de
cada funo so variveis locais, portanto outra funo no tm
acesso elas. Agora vamos compilar e executar o programa.
Verifique o fato de a funo trocar_sem_p quando chamada passa
para main os valores que inicializamos as variveis x e y sem
nenhuma mudana, mas a segunda funo usando ponteiros
realizou a troca dos valores. Podemos visualizar as aes de cada
uma:

144

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


A funo copia os valores de x e y para esq e dir:
Memria
2

esq

dir

??
temp

A funo copia esq para temp, dir para esq e temp para dir:
2

esq
dir
temp
Os valores de x e y permanecem inalterados. Isto aconteceu
porqu fizemos apenas uma cpia na funo, pois fisicamente no
podemos alterar os valores de variveis locais a no ser atravs
de ponteiros.
Visualizamos agora a ao da segunda funo:

??
p_esq

p_dir

temp

p_esq aponta para o valor de x, p_dir para o valor de y. Com isso a


funo agora tm acesso aos valores de x e y em memria:
7

2
p_esq

p_dir

temp

Passamos o valor apontado por p_esq para temp, p_dir para p_esq
que aponta para o valor de x, e temp para p_dir, que aponta para o
valor de y.
Finalizando, chamamos a funo com endereos de x e y.

145

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Usando ponteiros que apontam para funes:
Quando queremos passar uma funo para outra funo, usamos
a funo a ser passada como argumento da outra. Na operao
temos que declarar o ponteiro como prottipo da funo com
nome da funo como argumento. Usamos o operador asterisco
antes do nome. Veja o programa abaixo:
#include <iostream>
using namespace std;
int somar (int num1, int num2)
{
return (num1+num2);
}
int subtrair (int num1, int num2)
{
return (num1-num2);
}
int operacao (int x, int y, int (*ponteiro)(int,int))
{
int chamada_de_funcao;
chamada_de_funcao = (*ponteiro)(x,y);
return (chamada_de_funcao);
}
int main ()
{
int direto,com_ponteiro;
int (*ponteiro)(int,int) = subtrair;

146

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


direto = operacao (5, 3, somar);
com_ponteiro = operacao (4, direto, ponteiro);
cout << com_ponteiro << endl;
system(pause);
return 0;
}
cout imprimiu -4. Vamos olhar mais de perto a funo main.
Declaramos duas variveis de tipo inteiro e de nomes direto e
com_ponteiro. Em seguida apontamos para a funo subtrair,
usando *ponteiro com dois parmetros de tipo int. Chamamos a
funo somar com parmetros 5 e 3. somar retorna a soma = 8 que
guardada em direto. Quando chamamos a funo operacao com
x=4, y=8, ponteiro envia os dados de x e y para subtrair que
retorna -4 que guardado em com_ponteiro. cout imprime esta
resposta. Note que no usamos desta vez a funo
system(pause); para fixar o resultado na tela. Usamos getch();
que espera a entrada de qualquer tecla. Para usar getch() tivemos
que incluir o arquivo cabealho <conio.h>.
Ento, estamos dominando ponteiros? Hmm, melhor um pequeno
teste, s para verificar.
Um pequeno teste Teste 7:
1) Qual das seguintes a declarao correta de um ponteiro?
a) ponteiro *;
b) *p;
c) int *p;
d) &p;
2) Uma varivel possui endereo 1.750. Qual resposta aponta para
este endereo?
a) int &p;
b) int p = 1.750;
c) p = & varivel;
d) *p = varivel;

147

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


3) int *p; int memoria; p = &memoria; *p = 26; Aps executar estas
linhas, a varivel memoria contm?
a) 0;
b) Poder conter qualquer valor;
c) 26;
d) 1;
4)
a)
b)
c)
d)

Qual das opes abaixo solicita memria dinmica?


int p new;
delete new int;
*int new p;
p = new int [ i ];

5)
a)
b)
c)
d)

Qual das opes abaixo deleta a memria dinmica em uso?


delete int p;
Esta ao no necessria, pois o sistema se encarrega disso;
delete [ ] p;
p = delete [ ];

6)double matriz [10]; int *p; p = matriz; *p = 44; p++; *p = 69;


Aps executar o cdigo supra, matriz [0] e matriz [1] contm:
a) 0, 10;
b) 69, 44;
c) 44, 69;
d) Os valores originais, pois no pode ser compilado, o cdigo gera
erro de converso de tipo;

Respostas do Teste 7: 1) c; 2) c; 3) c; 4) d; 5) d; 6) d;

148

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Captulo 11 Todos os segredos de Estruturas (struct):
Uma estrutura formada por todos os elementos que a compe.
Jura? Fala algo que no sei. Ok, tudo bem, no vamos explicar
como funciona uma caneta ou um carro ou um prdio. Vamos
apenas usar o conceito de uma estrutura. Vamos pensar numa
empresa que declarou falncia, prestes fechar as portas. Apesar
de tudo, os empregados acham que podem administrar a empresa
entre eles para voltar a proporcionar lucro. Juntos compram a
empresa falida e comeam a se organizar. Podemos dizer que
formaram uma cooperativa de trabalho. Nesta estrutura que
chama-se agora A Cooperativa, temos vrios departamentos,
cada um fazendo seu trabalho para manter A Cooperativa
funcionando com mxima eficincia. A Cooperativa composta
dos Departamentos de: Administrao, Contabilidade, Compras,
Vendas e Marketing, Estoque, Controle de Qualidade, Produo e
Manuteno. Todos
estes
departamentos
necessitam de
informaes geradas por departamentos individuais em tempo
real. A maneira mais eficinte de distribuir estas informaes
atravs de uma rde de computadores. Como podemos fazer para
passar A Cooperativa do papel para o computador, eis a questo.
Podemos proceder de seguinte forma:
Primeiro vamos declarar a nossa estrutura....
struct ACooperativa
Neste momento estamos criando uma estrutura de nome e tipo,
igual declarao de uma varivel.
Agora podemos incluir todas as variveis que usaremos para
mover dados entre as partes da estrutura. Todos os dados sero
salvos em uma matriz que chamamos no caso, de pessoal, que faz
parte integral da estrutura. Veja o programa abaixo:

149

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

#include <iostream>
#include <string>
#include <sstream>
using namespace std;
struct ACooperativa
{
string nome;
int id;
string cargo;
float salario;
string depto;
} pessoal [10];
void imprimir (ACooperativa pessoa);
int main ()
{
string dados;
int i;
for (i=0; i<10; i++)
{
cout << "Entre com o nome: ";
getline(cin, pessoal[i].nome);
cout << "\nEntre com a id: ";
getline(cin, dados);
stringstream(dados) >> pessoal[i].id;
cout << "\nEntre com o cargo: ";
getline(cin, pessoal[i].cargo);
cout << "\nEntre com o salario: ";
getline(cin, dados);
stringstream(dados) >> pessoal[i].salario;
cout << "\nEntre com o departamento: ";
getline(cin, pessoal[i].depto);
}

150

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

cout << "\nDados do pessoal: " << endl;


for (i=0; i<10; i++)
{
imprimir(pessoal[i]);
}
system("pause");
void imprimir (ACooperativa pessoa)
{
cout << "Nome: " << pessoa.nome << "\t";
cout << "ID: " << pessoa.id << "\t";
cout << "Cargo: " << pessoa.cargo << "\t";
cout << "Salario: " << pessoa.salario << "\t";
cout << "Depto: " << pessoa.depto << endl;
}

Note que incluimos um arquivo cabealho que no vimos antes, o


<sstream>. Este programa nos permite usar a funo
stringstream que possibilita a entrada de tipos de dados mistos,
nmeros e letras, sem classific-los como tipo int, ou float, apesar
que declaramos estes tipos de variveis, id e salario, e so
tratados como tipo string para todos os efeitos.
Agora vamos analisar detalhadamente as partes.
struct ACooperativa
{
string nome;
int id;
string cargo;
float salario;
string depto;
Declaramos um tipo de estrutura chamada de ACooperativa que
possui 5 membros, cada membro de tipo fundamental, int, float e
string.

151

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


struct ACooperativa
{
string nome;
Declarao de membros da estrutura
int id;
string cargo;
float salario;
string depto;
} pessoal [10];
Este ponto e vrgula fecha o campo de objetos
Uma vez declarada, ACooperativa se tornou um novo nome vlido
de tipo igual aos fundamentais, e daquele ponto e adiante
podemos declarar variveis deste tipo composto, como fizemos ao
declarar a matriz pessoal. A matriz pessoal um objeto da
estrutura ACooperativa, e podemos declarar quantos objetos que
se fazem necessrios. Podamos ter dividido pessoal em uma
matriz para cada departamento. No fizemos isto para manter uma
certa simplicidade. Exemplo: } admin[10], compras[10], vendas[10]
e etc.; Este campo chamado de campo de objetos, logo aps a
chaveta de fechamento da estrutura, antes do ponto e vrgula.
Uma vez declarado o objeto podemos operar diretamente nele,
utilizando o operador . , Exemplo: pessoal[i].nome, pessoal[i].id e
etc. ; O ponto virtualmente vincula a varivel matriz, desde que
seja de mesmo tipo, como pessoal[i].nome de tipo string,
pessoal[i].id de tipo inteiro. Note que pessoal[10] uma vez
executada reserva memria bastante para os 5 membros x 10
pessoas. Neste momento temos 10 pessoas trabalhando na
empresa, e teremos que preencher os dados de cada pessoa
quando executamos o programa.

152

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


void imprimir (ACooperativa pessoa);
int main ()
{
string dados;
int i;
for (i=0; i<10; i++)
{
cout << "Entre com o nome: ";
getline(cin, pessoal[i].nome);
cout << "\nEntre com a id: ";
getline(cin, dados);
stringstream(dados) >> pessoal[i].id;
cout << "\nEntre com o cargo: ";
getline(cin, pessoal[i].cargo);
cout << "\nEntre com o salario: ";
getline(cin, dados);
stringstream(dados) >> pessoal[i].salario;
cout << "\nEntre com o departamento: ";
getline(cin, pessoal[i].depto);
}
A primeira declarao a existncia de um prottipo de funo
tipo void, vinculada ACooperativa. void diz ao sistema que esta
funo ir receber e transmitir apenas texto, e no realiza
nenhuma funo de processamento de dados que envolve um
retorno. A descrio da funo imprimir(ACooperativa pessoa)
segue fora do escopo de main, como j sabemos. A funo main
neste momento faz o trabalho de coletar todos os dados das
pessoas que trabalham na empresa, estabelecendo os vnculos
com cada varivel que compe a estrutura. O sistema guarda cada
dado em pessoal na seqncia que foi digitada. Uma matriz, como
sabe no permite que sejam inseridos dados de tipos diferentes a
no ser de tipo declarado. Por esta razo usamos a funo
stringstream para guardar nmeros, no caso de tipo float, de
salario, e int de id na matriz pessoal, junto com texto, no caso
nome, cargo e depto.

153

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

cout << "\nDados do pessoal: " << endl;


for (i=0; i<10; i++)
{
imprimir(pessoal[i]);
}
system("pause");
return 0;
void imprimir (ACooperativa pessoa)
{
cout << "Nome: " << pessoa.nome << "\t";
cout << "ID: " << pessoa.id << "\t";
cout << "Cargo: " << pessoa.cargo << "\t";
cout << "Salario: " << pessoa.salario << "\t";
cout << "Depto: " << pessoa.depto << endl;
}

Para visualizar todo o conteudo de pessoal, chamamos a funo


imprimir(ACooperativa pessoa) dez vezes, uma para cada grupo de
dados. Note que o objeto matriz pessoal foi passado para a funo
void
imprimir(ACooperativa
pessoa)
pela
declarao
imprimir(pessoal[i]); Com esta declarao cada vez que chamamos
a funo imprimir, pessoa pode ser vinculado com todas as
variveis (membros) que compe a estrutura. A funo cout em
cada caso envia o conteudo de pessoal em grupos na sequncia
em que aumenta a varivel i.
Insire o programa no Devcpp IDE e o salve com nome apropriado.
Execute o programa e entre com todos os dados de pessoal da sua
nova empresa. Veja a relao imprimida, admire...Ihhh, e se eu
quiser aumentar meu salrio, vou ter que preencher tudo
novamente? Calma, vamos ver o que podemos fazer.

154

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


No programa abaixo acrescentamos o cdigo que permite efetuar
alteraes dos dados que foram copiados para nosso banco de
dados:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
struct ACooperativa
{
string nome;
int id;
string cargo;
float salario;
string depto;
} pessoal [2];

void imprimir (ACooperativa pessoa);

int main ()
{
int indice;
bool ok=1;
string dados;
int i;
for (i=0; i<2; i++)
{
cout << "Entre com o nome: ";
getline(cin, pessoal[i].nome);
cout << "\nEntre com a id: ";
getline(cin, dados);
stringstream(dados) >> pessoal[i].id;
cout << "\nEntre com o cargo: ";
getline(cin, pessoal[i].cargo);
155

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


cout << "\nEntre com o salario: ";
getline(cin, dados);
stringstream(dados) >> pessoal[i].salario;
cout << "\nEntre com o departamento: ";
getline(cin, pessoal[i].depto);
}
cout << "\nDados do pessoal: " << endl;
for (i=0; i<2; i++)
{
imprimir(pessoal[i]);
}
cout << "\nDeseja alterar a relacao? ";
if (ok)
{
cout << "\nQual nome? ";
getline(cin, dados, '\n');
for (i=0; i<2; i++)
{
if (dados == pessoal[i].nome)
{
indice = i;
}
}
cout << "Digite novo nome: ";
getline(cin, pessoal[indice].nome);
cout << "Digite nova id: ";
getline(cin, dados);
stringstream(dados) >> pessoal[indice].id;
cout << "Digite novo cargo: ";
getline(cin, pessoal[indice].cargo);
cout << "Digite novo salario: ";
getline(cin, dados);
stringstream(dados) >> pessoal[indice].salario;
cout << "Digite novo depto: ";
getline(cin, pessoal[indice].depto);
for (i=0; i<2; i++)
{
imprimir (pessoal[i]);
156

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


}
}
system("pause");
}

void imprimir (ACooperativa pessoa)


{
cout << "Nome: " << pessoa.nome << "\t";
cout << "ID: " << pessoa.id << "\t";
cout << "Cargo: " << pessoa.cargo << "\t";
cout << "Salario: " << pessoa.salario << "\t";
cout << "Depto: " << pessoa.depto << endl;
system("pause");
}

Note que a matriz pessoal agora foi reduzida para acomodar


apenas duas pessoas, para facilitar nosso trabalho. No trecho de
cdigo que efetua alteraes, foi necessrio comparar o nome
com o nome guardado na matriz para apontar a entrada
relacionada com os dados que desejamos alterar.
No momento o programa executa uma vez, pois no inserimos os
meios de execuo constante. Para isso acontecer, teremos que
desmembrar o programa em partes que preenchem a matriz, e que
alterem a matriz, em funes. J temos a funo que imprime a
matriz. Estamos no momento falando sobre estruturas, mas para
elaborar um programa completo que funcione como imaginamos,
teremos que aprender mais.

157

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Usando ponteiros em estruturas:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
struct confeit {
string bolo;
string tipo;
};
int main ()
{
confeit obolo; // Declaramos uma varivel obolo tipo confeit
confeit * pbolo; // Declaramos um ponteiro pbolo tipo confeit
pbolo = &obolo; // Apontamos para os endereos dos membros
cout << "Nome do bolo: ";
getline (cin, pbolo->bolo); // Operador de insero ->
cout << "Tipo de bolo: ";
getline (cin, pbolo->tipo);
cout << "\nVoce pediu:\n";
cout << pbolo->bolo;
cout << " (" << pbolo->tipo << ")\n";
system("pause");
return 0;
}
Usamos o operador de insero -> para passar os parmetros
para os membros de confeit.
Em seguida passamos para cout o nome e tipo de bolo apontados
pelo operador de insero.

158

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Captulo 12 Todos os segredos de Classes:
Veremos que h semelhanas entre classes e estruturas de dados.
De fato a nica diferena a de podermos inserir funes na
classe, o que no possvel com estruturas. Veja a sntaxe:
class uma_classe
{
public: membro1;
private: uma_funcao (argumento);
protected: membro3;
} nomes de objetos;
uma_classe o identificador vlido para a classe. Os nomes
reservados, public, private e protected especificam os nveis de
acesso que os membros possuem:
public:
As variveis public so visveis para todas as classes e funes;
private:
As variveis private so visveis apenas para a classe que as
pertencem;
protected:
As variveis protected so visveis apenas para a classe que as
pertencem, como tambm qualquer subclasse;
Uma vez declarada a classe, se no especificado o nvel de
acessibilidade, todos os membros so considerados como de
acesso private, que o padro.

159

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


s vezes difcel determinar o nvel de acesso variveis. Veja os
exemplos abaixo:
public: class saldo_bancario
{
public: string cliente;
public: float saldo;

public: saldo_bancario (string nome, float reais)


{
nome = cliente;
if ( reais > 0)
{
saldo = reais;
}
else
{
reais = 0;
}

Declaramos os membros cliente e saldo como de acesso public.


Com isso quaisquer objetos no sistema podero alterar o valor de
saldo, inclusive passando um saldo negativo. Vamos agora corrigir
o programa para negar acesso indiscriminado ao membro saldo:

160

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


public: class saldo_bancario
{
public: string cliente;
private: float saldo;
public: saldo_bancario (string nome, float reais)
{
nome = cliente;
if ( reais > 0)
{
saldo = reais;
}
else
{
reais = 0;
}
}

public: float buscar_saldo()


{
return saldo;
}
public: void def_saldo ( float reais )
{
if (reais > 0)
saldo = reais;
else
reais = 0;
}
}

Veja que acrescentamos dois objetos, buscar_saldo e def_saldo.


Estes ainda podem acessar o saldo, mas no podem alterar seu
valor. Para diferenciar se um objeto dever ter o poder de
modificar ou no o valor de um membro, temos que nos perguntar
se necessrio determinado objeto possuir este poder.

161

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


#include <iostream>
using namespace std;
class Quadrado
{
int base, altura;
public:
void valores (int,int);
int area ()
{
return (base*altura);
}
};
void Quadrado::valores (int x, int y)
{
base = x;
altura = y;
}
int main ()
{
Quadrado quadro;
quadro.valores (3,3);
cout << "area: " << quadro.area() << endl;
system("pause");
return 0;
}

162

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Declaramos uma classe, que tambm podemos dizer um tipo
chamado de Quadrado. Esta classe possui trs membros, um de
acesso
privado,
pois
no
declaramos
isto
portanto
automaticamente so private, de dois variveis de tipo inteiro com
nomes base e altura. Em seguida declaramos duas funes de
acesso public, (mas ainda no definimos a primeira), a funo
membro chamada de valores que possui dois parmetros. A
importncia desta funo fundamental, pois dar main acesso
s variveis base e altura. Por ltimo, a funo membro chamada
de area, que retorna o resultado da multiplicao de base com
altura. Veja na definio da funo valores, vinculada classe
quadrado pelo uso do operador de escopo ::. Na definio desta
passamos os valores de x e y para base e altura. Na funo main,
declaramos um objeto da classe quadrado chamado de quadro.
Esta relao Quadrado/quadro poder ser visto como a declarao
de uma varivel qualquer, exemplo: Se Quadrado o tipo ento
quadro o objeto do tipo. Com esta relao estabelecida o objeto
quadro ter acesso aos membros public de Quadrado pela
insero de ponto, i.e. quadro.valores (3,3) e a_area = quadro.area
();
Podemos declarar mais de um objeto da classe quadrado. Prove
isto acrescentando as seguintes linhas de cdigo em main:
Quadrado quadro2;
quadro2.valores(3,6);
Acabamos de acresentar mais um objeto varivel tipo Quadrado de
nome quadro2.
Quando usamos classes no futuro, vamos sempre declarar um
Construtor que reserva memria bastante para acomodar o ensejo,
valores de membros e outras necessidades. Da mesma forma que
criamos um Contrutor, tambm devemos declarar um Destruidor
para liberar a memria reservada pelo sistema.

163

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Construtores e Destruidores (constructor), (destructor):
constructor uma funo especial que chamada
automaticamente cada vez que criamos um novo objeto da classe
e dever possuir o mesmo nome que a classe. Nunca devemos
declarar um construtor com retorno qualquer, pois no faz parte
da sntaxe e gerar erro.
Usando nosso programa de classe Quadrado, iremos construir um
construtor. Veja a sntaxe a seguir:
#include <iostream>
using namespace std;
class Quadrado
{
int base, altura;
public:
Quadrado (int,int); // Nosso construtor
int area ()
{
return (base*altura);
}
};
Quadrado::Quadrado ( int x, int y)
{
base = x;
altura = y;
}

164

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Note que o membro valores foi substitudo pela declarao de
construtor Quadrado que possui dois parmetros de tipo inteiro.
Precisamos agora definir nosso construtor, que fazemos na linha:
Quadrado::Quadrado (int x, int y). Na descrio inicializamos as
variveis base e altura com os valores que passaremos para elas.
int main ()
{
Quadrado quadro1 (3,3);
Quadrado quadro2 (3,6);
cout << "area1: " << quadro1.area() << endl;
cout << "area2: " << quadro2.area() << endl;
system("pause");
return 0;
}
Estes argumentos sero passados na hora que criamos os objetos
quadro1 e quadro2 em main.
Veja o programa completo:
#include <iostream>
using namespace std;
class Quadrado
{
int base, altura;
public:
Quadrado (int,int); // Declaramos nosso construtor
int area ()
{
return (base*altura);
}
};

165

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Quadrado::Quadrado ( int x, int y) // Definimos nosso construtor
{
base = x;
altura = y;
}
int main ()
{
Quadrado quadro1 (3,3);
Quadrado quadro2 (3,6);
cout << "area1: " << quadro1.area() << endl;
cout << "area2: " << quadro2.area() << endl;
system("pause");
return 0;
}
O compilador reconhece um destruidor pela incluso de um til ~
em frente o nome da classe. Vamos construir um destruidor:
#include <iostream>
using namespace std;
class Quadrado
{
int *base, *altura;
public:
Quadrado (int,int); // Declaramos nosso construtor
~Quadrado(); // Declaramos nosso destruidor
int area ()
{
return ( *base * *altura);
}
};

166

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Note que declaramos as variveis membros, base e altura como
ponteiros *base e *altura. Fizemos isto porqu quando reservamos
memria dinmica estes estaro apontando para os valores de
base e altura.
Quadrado::Quadrado ( int x, int y) // Definimos nosso construtor
{
base = new int;
altura = new int;
*base = x;
*altura = y;
}
Reservamos memria dinmina para base e altura e apontamos
para estes.
Quadrado::~Quadrado ()
{
delete base;
delete altura;
}
Definimos o destruidor e liberamos a memria aporcionada base
e altura.
int main ()
{
Quadrado quadro1 (3,3);
Quadrado quadro2 (3,6);
cout << "area1: " << quadro1.area() << endl;
cout << "area2: " << quadro2.area() << endl;
system("pause");
return 0;
}

167

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Imprimimos as duas reas das variveis objeto, tipo Quadrado de
nome quadro1 e quadro2 que inicializamos com valores.
Bom, estamos a dominando classes como dominamos estruturas
e todas as outras partes expostas pelo livro. Subimos esta
montanha para ver o que existe do outro lado, e s vimos outra
montanha. Esta a parte chata da linguagem C. No entanto peo
que no desanime, pois isto faz parte da aprendizagem da
linguagem, igual s caixinhas japonesas, abre uma caixinha s
para descobrir que dentro desta existe outra, e outra. Cada uma
mais uma ferramenta que podemos usar para solucionar um
problema.
Eventualmente
teremos
todas
as
ferramentas
disponveis e poderemos dizer, agora s ter uma ideia que posso
transform-la num programa. Maravilha.
Bom, enquanto a estrutura de dados e classes esto no fogo
cozinhando, vamos divergir um pouco, e aprender como gerar
nmeros aleatrios. Nosso propsito o de gerar seis nmeros
entre 1 e at 50, e depois apostar o resultado na mega sena. Veja
como:
Gerando nmeros aleatrios:
Antes de tudo, devemos incluir trs arquivos cabealho:
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
int main()
{
unsigned int indice = (unsigned int) time (NULL);
srand (indice);

168

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


for (int i=0; i<6; i++)
{
cout << "Numero " << i+1 << " = " << rand () % 50 + 1 << endl;
system("pause");
}
return 0;
}
A funo time com parmetro nulo NULL retorna a quantidade
de segundos que se passaram desde 1 de janeiro, 1971, um
nmero em torno de 1.344.447.565, uns 42,63 anos no momento
que montei o programa. Por esta razo incluimos <ctime> no
cabealho. Este ndice usado como valor de incio da funo
srand. J que um valor sempre em andamento, a funo rand
utiliza o valor de ndice em srand para gerar nmeros aleatrios,
dentro de uma faixa estipulada aps %. Note que 50 + 1 gera
nmeros aleatrios entre 1 e at 50.
Incluimos <cstdlib> para podermos usar as funes srand e rand.
As
chances
de
repetir
um
nmero
gerado
diminuem
consideravelmente quando aumentamos a faixa. Uma repetio
poder ocorrer porqu nossa faixa gera nmeros entre 1 e at 50,
mas na verdade dois nmeros gerados 12.546, depois 12.800 para
nosso programa so diferentes, mas imprimimos apenas os dois
primeiros digitos, o nmero 12.
Se est pensando que poder utilizar a tcnica para elaborar um
jogo de cartas, estar no caminho certo, ou se no seu jogo de
explorao do universo voc ativou um portal de pulo no
hiperespao, tambm o caminho certo. Bom, vamos voltar
Terra onde iremos aprender tudo sobre typedef e Unies.

169

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Tipos de dados Definidos (typedef):
typedef utilizado quando queremos usar sinnimos de tipos
existentes:
typedef double a_media_de_todos_os_valores[12];
Declaramos
uma
matriz
tipo
double
de
a_media_de_todos_os_valores composta de 12 clulas.

nome

a_media_de_todos_os_valores m;
Declaramos m como sinnimo de a_media_de_todos_os_valores.
m ser considerada como a_media_de_todos_os_valores porqu
ambas so de mesmo tipo. Agora podemos usar m para modificar
os valores da matriz.
Todos os segredos de Unies (union):
Unies podem ser utilizados para diminuir a quantidade de
memria usada pelo programa. Isto possvel porqu todos os
elementos da unio usam a mesma memria, portanto se
alteramos o valor de um dos elementos, os valores de todos sero
alterados:
struct livros
{
char titulo [30];
char autor [30];
union moeda
{
float real;
float dollar;
} preco;
} livro;
A unio que chamamos moeda possui dois elementos, real e
dollar. Se guardamos o preo em real, no podemos obter o preo
170

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


em dollar, pois sero de mesmo valor. Para ganhar acesso s
moedas usaremos livro.preco.dollar, ou livro.preco.real. Note
inclusive que o objeto da unio, preco, no precisa ser declarado.
Chama-se este caso de unio annima e para ter acesso a real e
dollar, usamos livro.real, ou livro.dollar. Ento voc pergunta, para
que serve a unio? Boa pergunta, mas precisava saber que existe
esta opo.
Para o prximo assunto, imagine que temos um brao de rob. A
mo do brao se movimenta num espao tridimensional, como
sabe. Podemos definir a localizao de um ponto neste espao
tridimensional com as coordenadas (x, y, z) ao alcance da mo.
Usando a funo operator
aritmticas em classes:
Tabela de operadores que
+
*
/
<<
>>
<<= >>=
-%
&
!
&&
||
%=
[]
new[] delete[]

para

podem
< >
== !=
|
^
() ,

sobrecarregar

operaes

ser sobrecarregados
+= -=
*=
/=
<= >=
=
++
~ &= ^=
|=
->* -> new delete

A ideia de sobrecarregar um operador, que ento possibilita seu


uso em classes, e para sobrecarregar um operador usamos a
sntaxe:
tipo operator sinal (que consta da tabela) (parmetros);
Vamos ento criar uma classe que soma as coordenadas
tridimensionais de nosso brao de rob para que se posiciona num
ponto diferente no espao tridimensional:

171

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


#include <iostream>
using namespace std;
class robo
{
public:
int x, y, z;
robo (){};
robo (int,int,int);
robo operator+ (robo);
};
Declaramos uma classe de nome robo de acesso public. Aps a
declarao das variveis de tipo inteiro, declaramos o construtor
robo com corpo vazio, robo (){}; Foi necessrio fazer isto porqu
declaramos explicitamente outro construtor de mesmo nome, robo
(int, int, int); De fato os objetos de robo () {} sero definidos em
main, coord_anterior, coord_a_somar e coord_nova. Outro membro
da classe a funo que sobrecarrega o operador +, declarado em
seguida.
robo::robo (int a_x, int b_y, int c_z)
{
x = a_x;
y = b_y;
z = c_z;
}
Definimos o construtor robo no cdigo supra. Lembre que o
construtor tem que usar o mesmo nome que a classe.

172

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


robo robo::operator+ (robo indice)
{
robo temp;
temp.x = x + indice.x;
temp.y = y + indice.y;
temp.z = z + indice.z;
return (temp);
}
Definimos a funo que sobrecarrega o operador + ao mesmo
tempo vinculamos operator+ a classe robo usando o operador de
escopo ::. Esta funo realiza todo o trabalho de somar os
parmetros passados em main, que retorna para main o resultado
temp (x, y, z).
int main()
{
robo coord_anterior(4,2,3);
robo coord_a_somar(5,3,4);
robo coord_nova;
coord_nova = coord_anterior + coord_a_somar;
cout << "("<< coord_nova.x << "," << coord_nova.y << "," <<
coord_nova.z << ")" << endl;
system("pause");
return 0;
}
No cdigo supra estamos realizando uma operao indita, a de
somar os parmetros de dois objetos da classe, e no simples
variveis comuns, o terceiro objeto sendo coord_nova. Note que
tivemos que declarar coord_nova como tipo robo antes de poder
us-lo.

173

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Usando a palavra-chave this:
this traduzido significa este. utilizado para diferenciar entre uma
varivel membro e parmetros. Por exemplo, o cdigo:
varx(varx); onde a funo varx inicializada com o parmetro
varx.
varx::varx (varx);
this-> varx = 5;
Muito melhor seria usar nomes de variveis diferenciados:
varx (novo_varx)
Mas, vamos insistir no uso de this;
O programa abaixo exemplifica muito bem o uso de this:
#include <iostream>
using namespace std;
class uso_de_this
{
public:
int variavel; // Varivel nmero 1 de nome varivel
void var_saida (int variavel) // Varivel nmero 2 de mesmo nome
{
this -> variavel = 10; // this aponta para varivel nmero 1
cout << variavel << endl; // Imprimimos varivel nmero 2
cout << this -> variavel << endl; // Imprimimos Varivel nmero 1
}
};

174

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


int main ()
{
uso_de_this objeto;
objeto.var_saida (20); // Passamos o nmero 20 para var_saida
system("pause");
return 0;
}
Existe um consenso entre programadores que preferem chamar
variveis, de nomes diferentes. Desta forma no necessrio usar
this para identificar qual a varivel sendo processada em
determinado instante, outros gostam de us-lo. Pessoalmente
acho que chamando variveis de nomes diferenciados deixa a
impresso de um programa mais arrumado.

Captulo 13 Amizade e Herana:

Como j dissemos, membros de uma classe declarados como de


acesso private ou protected no podem ser acessados por objetos
ou membros de outra classe. Isso verdade, mas isto no se
aplica a um amigo, em ingls, friend. Para que um amigo tenha
acesso aos membros privados ou protegidos, basta declarar este
amigo como membro, usando a palavra-chave friend. Veja o
exemplo abaixo:

175

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


#include <iostream>
#define pi 3.142
using namespace std;
class circulo
{
double raio;
public:
void valor (int);
double area ()
{
return (pi * raio * raio);
}
friend circulo outro (circulo);
};
Declaramos uma classe de nome circulo que possui um membro
de acesso private, double raio, e trs de acesso public, as funes
valor, area e a que declaramos como friend, outro, que tm
acesso todos os membros de circulo, mesmo a de acesso
private, a varivel raio.
void circulo::valor (int r)
{
raio = r;
}
Em seguida definimos a funo valor fora do corpo de circulo,
dando acesso deste todos os membros pelo uso do operador de
escopo ::, com parmetro int r.

176

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


circulo outro (circulo cparam)
{
circulo circ;
circ.raio = cparam.raio * 2;
return (circ);
}
Declaramos e definimos a funo outro de tipo circulo que amigo
da classe circulo. Esta ter acesso irrestrito varivel private,
raio, e modifica o valor deste para o valor em circv.valor * 2. i.e. 3
* 2.
int main ()
{
circulo circv, circb;
circv.valor (3);
circb = outro (circv);
cout << "Area = " << circb.area() << " unid. quadradas " <<endl;
system("pause");
return 0;
}
A funo main executada primeiro, onde circb chama a funo
friend outro com parmetro numrico 3. outro retorna 3 * 2 a
main. cout chama a funo area que possui argumentos (3.142 * 6
* 6), e retorna o resultado a cout que o imprime.
Usando classes amigas:
Da mesma forma que declaramos uma funo como amigo da
classe, podemos declarar classes amigas de outras classes. Uma
vez declarada a amizade, a classe amiga ter acesso todos os
membros da outra classe. Veja um exemplo:

177

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


#include <iostream>
using namespace std;
class quadro;
class quadrado
{
int largura, altura;
public:
int area ()
{
return (largura * altura);
}
void valor (quadro x);
};
Declaramos o prottipo da classe quadro primeiro. Isto
necessrio porqu na descrio da classe quadrado usamos
quadro como parmetro da funo valor, o prottipo da funo
valor (quadro x);.
class quadro
{
private:
int lado;
public:
void val_lado (int x)
{
lado=x;
}
friend class quadrado;
};

178

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Na descrio da classe quadro, declaramos uma funo membro
de nome val_lado com parmetro int x. Em main passaremos o
valor de lado para x. Em seguida declaramos que a classe quadro
amiga da classe quadrado, portanto ter acesso aos membros da
classe quadrado.
void quadrado::valor (quadro x)
{
largura = x.lado;
altura = x.lado;
}
Tornamos visveis os membros privados da classe quadrado
usando o operador de escopo, ao declarar o parmetro de valor
como vinculado quadro. Na sua definio declaramos que os
valores de largura e altura de acesso privado em quadrado podem
ser alterados pelo valor em x, pois lado tm acesso estas
variveis.
int main ()
{
int medida;
cout << "Entre com a medida dos lados: ";
cin >> medida;
quadro quad;
quadrado qdr;
quad.val_lado(medida);
qdr.valor(quad);
cout << "\n" << qdr.area() << " unidades quadradas " << endl;
system("pause");
return 0;
}

179

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Declaramos dois objetos em main. O primeiro de tipo quadro
objeto quad que apontamos para val_lado, o outro de tipo
quadrado objeto qdr que apontamos para valor. Chamamos a
funo val_lado e passamos o valor em medida para ela. Em
seguida chamamos a funo valor que fornece acesso aos
membros em quadrado. Em cout chamamos a funo area que
retorna o produto da multiplicao dos lados. Note que os dois
lados possuem o mesmo valor.
Todos os segredos de Herana entre classes:
C++ possui capacidades especiais que permitem a herana entre
classes. Isto quer dizer que podemos criar classes derivadas de
outras classes, sendo que herdam os membros destas. Fazemos
esta operao quando os membros das classes possuem algumas
caractersticas iguais ou pelo menos semelhantes. Como exemplo,
podemos declarar uma classe de nome volume, e mais duas
classes derivadas de volume, como uma classe de nome cone,
outra de nome cilindro. Sabemos que o volume dos dois objetos
depende da altura e a medida do raio, como tambm de pi, mas
no exatamente iguais.
Entra em cena o operador : que vamos usar para derivar classes.
Se chamarmos a primeira classe de classe_base e a classe
derivada de classe_derivada, ento a sntaxe da operao
determina que:
class classe_derivada : class classe_base { protected:....public: };

180

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Veja o programa abaixo:
#include <iostream>
#define pi 3.142
#define div 0.3334
using namespace std;
class volume
{
protected:
double raio, altura;
public:
void valores (double r, double alt)
{
raio=r;
altura=alt;
}
};
class cilindro: public volume
{
public:
double vol ()
{
return (pi * altura * raio * raio);
}
};
class cone: public volume
{
public:
double vol ()
{
return (div * pi * altura * raio * raio);
}
};
181

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

int main ()
{
double r, alt;
cout << "Entra com valores de raio e altura: ";
cin >> r >> alt;
cilindro cil;
cone con;
cil.valores (r,alt);
con.valores (r,alt);
cout << "\n O volume do cilindro = " << cil.vol() << " unidades
cubicos " << endl;
cout << "\n O volume do cone = " << con.vol() << " unidades
cubicos" << endl;
system("pause");
return 0;
}
Entre com valores de raio e altura usando ponto e no vrgula se
forem fraes. i.e raio = 2.4
altura = 4.8;
Note que os objetos das classes cilindro e cone possuem membros
herdados da classe volume, as variveis raio, altura e a funo
valores. Nas declaraes de herana tornamos a classe volume
visvel com grau de acesso public para cada classe derivada.
Adicionalmente na classe volume, especificamos o grau de acesso
como sendo protected e no private. Fizemos isto porqu
necessitamos que as variveis raio e altura sejam acessveis s
classes derivadas, estes estaro visveis apenas quando estes
membros forem de acesso protected, e no private. Note que a
funo main ter acesso apenas aos membros de acesso public.
Em main declaramos dois objetos, um de cada classe sendo eles
cilindro cil, e cone con. Lembre que cil por exemplo, uma
varivel de tipo cilindro de nome cil, ento ter acesso valores
pelo uso do operador ponto, cil.valores(argumentos), onde

182

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


passamos para valores as medidas de raio e altura. Os volumes de
cada objeto so retornados cout em cada caso.
Ento, sente-se bem com todas estas tcnicas? Caso tenha
alguma dvida, que no surpreendente devido quantidade de
informaes passadas, podemos descanar durante uma reviso
mais profunda:
Um teste no to pequeno Teste 8:
1)
a)
b)
c)
d)

Qual a linha de cdigo abaixo que declara um objeto de uma


estrutura?
struct Loja ();
int preco;
} estoque [100];
No existem objetos em estruturas.

2)
a)
b)
c)
d)

Qual a linha de cdigo abaixo que declara um estrutura?


struct banco { };
int banco ();
void banco;
double banco (void);

3)

Qual o arquivo cabealho que permite entrada de dados de


tipos mistos?
<string>
<iostring>
<stdio>
<sstream>

a)
b)
c)
d)

4)
Quais os membros da estrutura abaixo?
struct corpo { string olhos, boca, orelhas; int qtd; } cabeca (),
o_corpo [52];
a) corpo
b) olhos, boca, orelhas, qtd;
c) o_corpo

183

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

5)
a)
b)
c)
d)

Assinale a maior diferna entre estruturas e classes:


No h diferna;
Podemos declarar funes como membros de estruturas.
Podemos declarar funes como membros de classes.
Podemos declarar objetos em estruturas o que no possvel
em classes.

6)

Porqu no podemos declarar variveis e funes de grau de


acesso private em classes derivadas (herana)?
A sntaxe determina isto.
Porqu no queremos que outras classes tenham acesso s
funes e variveis declaradas.
Sempre declaramos o grau de acesso como sendo protected.
Somente assim as classes derivadas tero acesso s
variveis e funes, mas estaro bloqueados para outras
funes, como main.

a)
b)
c)

7)
a)
b)
c)

Qual das linhas de cdigo define um construtor?


quadrado:quadro(int x, int y);
quadrado::quadrado(int x, int y)
quadro::quadrado();

8)
a)
b)
c)

Qual das linhas de cdigo define um destruidor?


quadrado::destruidor(int, int)
quadrado::~quadrado(int x, int y)
quadrado::~quadrado()

Respostas do Teste 8:
1) c; 2) a; 3) d; 4) b; 5) c: 6) c; 7) b; 8) c;

184

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Captulo 14 - Criando, abrindo e fechando arquivos:


Basicamente temos duas classes, e so istream e ostream. A
funo cin de fato um objeto da classe istream, e como j
imaginou, cout um objeto da classe ostream. Para C++ usamos
as classes ifstream e ofstream aliadas s funes .open() e
.close(), onde open e close traduzidos significam abrir e fechar
respectivamente. Come exemplo, veja o programa abaixo:
#include <fstream>
#include <iostream>

/*Precisamos desta biblioteca


ofstream e ifstream*/

para

usar

using namespace std;


int main()
{
string entrada_de_texto;
ofstream arquivo;
arquivo.open ("meu_arquivo");
if (arquivo.is_open())
//Devemos verificar a
//abertura correta do arquivo
{
arquivo << "Este texto vai no arquivo";
arquivo.close();//Fechar explicitamente o arquivo
}
else
//Erro na abertura do arquivo
{
cout<<"O arquivo no pode ser aberto.";
system("pause");// Esperar tecla
return 0;
//Encerramos o programa
}
ifstream arquivo1 ( "meu_arquivo" );//Abrir o arquivo para leitura
if (arquivo1.is_open())
{

185

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


getline (arquivo1, entrada_de_texto);
cout << entrada_de_texto << endl;
}
else
{
cout<<"O arquivo no pode ser aberto.";
system("pause");
return 0;
}
system("pause");
return 0; //O arquivo fechado implicitamente
}
Usamos ofstream da classe fstream para declarar um objeto de
nome arquivo para criar meu_arquivo, e o abrimos com
arquivo.open(meu_arquivo). Pode acontecer que algo impede a
abertura do arquivo, como por exemplo se j est sendo usado por
outro programa. Testamos esta condio com a funo if
(arquivo.is_open). O arquivo abriu corretamente, ento escrevemos
um texto nele. Terminada a operao, temos que fechar
explicitamente o arquivo, e fazemos isto com arquivo.close() sem
parmetro. Agora vamos reabrir o arquivo para leitura. Note uma
grande semelhana entre as duas operaes. nica diferena de
termos que usar um nome de objeto diferente, no caso arquivo1,
aliado ifstream. Usamos a funo getline com argumentos, o
primeiro que direciona a operao arquivo1 vinculado
meu_arquivo, onde o conteudo de meu_arquivo ser copiado para a
varivel de tipo string, entrada_de_texto. O texto passado para
cout que o imprime.
O programa supra usa o cdigo bsico necessrio para criar,
escrever para, e ler de arquivos. Considere agora a sntaxe de
abertura de um arquivo: open (nome do arquivo, modo);

186

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


No programa abrimos o arquivo usando apenas o nome do arquivo
como parmetro, mas haver a necessidade de declarar o modo
tambm. Modo um parmetro opcional composto de um nmero
de flags ou bandeiras que indicam a operao adicional de
abertura, e so:
ios::in
ios::out
ios::binary
ios::ate

ios::app

ios::trunc -

Uma operao de leitura de dados;


Uma operao de entrada de dados;
Aberto em modo binrio;
Este quando configurado aponta para o fim do
arquivo. Quando no for configurado aponta para o
incio do arquivo;
Quando usado acrescenta novos dados aos dados
existentes no arquivo. Usado somente em
operaes de entrada de dados;
Usado quando queremos substituir o conteudo de
um arquivo previamente aberto;

Veja o exemplo abaixo:


#include <fstream>
#include <iostream>

//Precisamos desta
//ofstream e ifstream

biblioteca

para

usar

using namespace std;


int main()
{
string entrada_de_texto;
ofstream arquivo;
arquivo.open ("meu_arquivo");
if (arquivo.is_open())
//Devemos verificar a abertura correta
//do arquivo
{
arquivo << "Este texto vai no arquivo";
arquivo.close();//Fechar explicitamente o arquivo
}
187

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


else
//Erro na abertura do arquivo
{
cout<<"O arquivo no pode ser aberto.";
system(pause);// Esperar tecla
return 0;
//Encerramos o programa
}
ifstream arquivo1 ( "meu_arquivo" );//Abrir o arquivo para leitura
if (arquivo1.is_open())
{
getline (arquivo1, entrada_de_texto);
cout << entrada_de_texto << endl;
}
else
{
cout<<"O arquivo no pode ser aberto.";
arquivo1.clear();
}
ofstream arquivo2;
arquivo2.open("meu_arquivo", ios::out | ios::app);
if (arquivo2.is_open())
{
arquivo2 << "...e este texto tambem " << endl;
arquivo2.close();
}
else
{
cout<<"O arquivo no pode ser aberto.";
arquivo2.clear();
}
ifstream arquivo3;
arquivo3.open("meu_arquivo");
if (arquivo3.is_open())
{
getline (arquivo3, entrada_de_texto);
cout << entrada_de_texto << endl;
}
188

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


else
{
cout<<"O arquivo no pode ser aberto.";
arquivo3.clear();
}

system(pause);
return 0; //O arquivo fechado implicitamente

De acordo com a sntaxe, na segunda abertura de meu_arquivo


para escrita usamos os flags ios::out e o operador | (barra
vertical) para separar este de ios::app.
Alguns programadores usam o fato de sendo a primeira operao
com arquivos a sua abertura, a funo nome.open (nome do
arquivo, modo), C++ automaticamente cria e abre um arquivo, no
caso dele no existir, com a declarao ofstream (nome de
arquivo, modo), porqu a funo .open automaticamente
executada, no caso.
C++ fornece ainda, mais quatro funes membros que podemos
usar para indicar o estado da operao de entrada e leitura de
arquivos, que retornam um valor Booleano em todos os casos:
good () bad () -

fail () -

eof () -

Retorna condio Falsa se qualquer uma das funes


abaixo retornem condio Verdadeira;
Retorna condio Verdadeira no caso de erro, por
exemplo se tentamos escrever para um arquivo
fechado;
Retorna condio Verdadeira se por exemplo tentar ler
dados de tipo char quando estamos lendo dados de tipo
inteiro;
Retorna condio Verdadeira quando lido o
sinalizador de fim de arquivo \0;
189

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Se abilitada qualquer uma destas condies, devemos usar a
funo clear () para desabilitar a condio. Note que no caso de
haver algum problema na abertura de arquivo, apenas revertemos
o estado de verdadeira das bandeiras com arquivo.clear(), onde
antes saamos do programa.
Todos os fluxos de entrada e de sada possuem pelo menos um
apontador interno. As funes de entrada/leitura como ifstream e
ofstream possuem os ponteiros internos de nome get e put
respectivamente, que apontam para o prximo elemento a ser
processado numa operao, e podem ser configurados usando as
funes-membro tellg() (get) e tellp() (put) que retornam um dado
de tipo inteiro contendo a posio onde encontra-se o ponteiro.
Temos ainda mais duas funes de nome seekg() e seekp() que
alteram o valor do ponteiro para o valor absoluto a partir do incio
do arquivo. Declaramos as funes seek com dois parmetros,
deslocamento e direo, onde direo poder ser um dos
seguintes:
ios::beg Onde o deslocamento ser a partir do incio do fluxo;
ios::end - Onde o deslocamento ser desde o fim do fluxo;
ios::cur - Sem deslocamento;
Parece muito complicado. Melhor ver um exemplo:
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
string entrada_de_texto;
int inicio, fim;
ofstream arquivo;
arquivo.open ("meu_arquivo");
if (arquivo.is_open())
190

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


{
arquivo << "Este texto vai no arquivo";
arquivo.close();
}
else
{
cout<<"O arquivo no pode ser aberto.";
arquivo.clear();
}
ifstream arquivo1 ( "meu_arquivo" );
if (arquivo1.is_open())
{
getline (arquivo1, entrada_de_texto);
cout << entrada_de_texto << endl;
}
else
{
cout<<"O arquivo no pode ser aberto.";
arquivo1.clear();
}
ofstream arquivo2;
arquivo2.open("meu_arquivo", ios::out | ios::app);
if (arquivo2.is_open())
{
arquivo2 << "...e este texto tambem " << endl;
arquivo2.close();
}
else
{
cout<<"O arquivo no pode ser aberto.";
arquivo2.clear();
}
ifstream arquivo3;
arquivo3.open("meu_arquivo");
if (arquivo3.is_open())
{
getline (arquivo3, entrada_de_texto);
cout << entrada_de_texto << endl;
191

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


}
else
{
cout<<"O arquivo no pode ser aberto.";
arquivo3.clear();
}
ifstream arquivo4 ("meu_arquivo");
if (arquivo4.good()) // Enquanto nenhum dos outros flags
{
inicio = arquivo4.tellg(); //O ponteiro aponta para o inicio.
arquivo4.seekg (0, ios::end); //Sem deslocamento, direo fim.
fim = arquivo4.tellg(); //Nova posio do ponteiro (fim).
arquivo4.close();
cout << "\nTamanho do arquivo = " << (fim - inicio) << " Bytes." <<
endl;
}
else
{
cout<<"Erro na abertura do arquivo.";
arquivo4.clear();

}
system(pause);
return 0;

Veja as ltimas linhas de cdigo. Note que no incio de main


declaramos duas variveis de tipo inteiro de nomes inicio e fim.
Usamos estes para determinar o nmero de Bytes que o arquivo
contm.
Nesta altura voc poder estar perguntando, o qu um arquivo
binrio? Um exemplo, se voc j tentou abrir um arquivo com
extenso .exe usando um processador de texto como Word, o qu
imprimido ser o cdigo binrio de cada byte convertido em
cdigo ASCII. Lembre no incio deste livro onde falamos que o
Montador converte o cdigo fonte em cdigo de montagem
192

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


produzindo cdigo objeto? Em outras palavras, o cdigo binrio
que possui uma quantidade de bytes contendo apenas nmeros,
cada byte composto de nmeros que representam instrues e
valores numricos. Quando executamos qualquer programa em
C++, estamos executando um arquivo binrio com extenso .exe.
No podemos usar os mesmos mtodos para trabalhar com
arquivos binrios, porqu no possuem espaos ou outros
caracteres que podemos usar para indicar exatamente aondo
estamos, temos apenas o incio e fim do arquivo que podemos usar
para determinar o tamanho do arquivo. Devemos evitar uma
comparao entre arquivos com extenso .exe e arquivos com
extenso .bin. So to diferentes quanto a gua para o vinho.
Estamos neste ponto referindo-nos arquivos com extenso .exe.
O que vamos fazer agora um programa que converte caracteres
de tipo char em cdigo binrio. Depois vamos criar um arquivo de
nome arq.bin e escrever nele a representao do alfabeto em
letras minsculas de cdigo binrio, mas primeiro vamos tentar
converter apenas a letra u para ver se funciona:
#include <climits>
#include <iostream>
using namespace std;
char *conv_dec_bin(char *conv, unsigned char decimal)
{
unsigned char bit;
char *binario = conv;
for ( bit = 1 << (CHAR_BIT - 1); bit; bit >>= 1 )
{
*conv++ = decimal & bit ? '1' : '0'; //Se bit 1==1 : bit 0 ==0
}
*conv = '\0';
return binario;
}

193

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


int main(void)
{
unsigned char u = 117;
char b [ CHAR_BIT * sizeof(u) + 1 ];
cout << conv_dec_bin(b,u)<< endl;
system(pause);
return(0);
}
A representao decimal da letra u o nmero 117. O que
fizemos reservar o espao em memria da matriz b o tamanho
deste nmero + 1 para que seja inserido um caractere nulo logo
aps. CHAR_BIT um Macro de <climits> que usamos para
determinar a quantidade de bits que compe este char. Chamamos
a funo conv_dec_bin com parmetros tamanho e valor de u.
Nesta funo determinamos os bits que representam o valor 117,
no caso 01110101, que retornado main. Veja a tabela de
converso do nmero binrio para valor decimal:
128
0

64
1

32
1

16
1

8
0

4
1

2
0

1
1

Somando os valores decimais da primeira fileira onde marcamos 1


binrio na segunda fileira, rende o valor decimal: i.e.
64+32+16+4+1 = 117;
Veja a tabela ASCII para determinar o valor decimal da primeira
letra. A letra a em cdigo binrio 01100001:
128
0

64
1

32
1

16
0

8
0

4
0

2
0

1
1

Portanto: 64+32+1 = 97D


Enquanto que a letra z em cdigo binrio 01111010:

194

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


128
0

64
1

32
1

16
1

8
1

4
0

2
1

1
0

Portanto: 64+32+16+8+2 = 122D


Nossa faixa de converso ser desde 97 e at 122.
Veja nosso programa que realiza toda operao, abaixo:
#include <iostream>
#include <fstream>
#include <climits>
using namespace std;
char *conv_dec_bin(char *conv, unsigned char decimal)
{
unsigned char bit;
char *binario = conv;
for ( bit = 1 << (CHAR_BIT - 1); bit; bit >>= 1 )
{
*conv++ = decimal & bit ? '1' : '0';
}
*conv = '\0';
return binario;
}
int main(void)
{
unsigned char letra;
ofstream arquivo;
arquivo.open("arq.bin", ios::binary | ios::out | ios::app);
if (arquivo.is_open())

195

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

for (letra=97; letra<123; letra++)


{
char b [ CHAR_BIT * sizeof(letra) + 1 ];
arquivo << conv_dec_bin(b,letra);
cout << "Byte = " << letra << " " << conv_dec_bin(b,letra) <<
endl;
}
arquivo.close();
}
else
{
cout << "O arquivo nao pode ser aberto.";
arquivo.clear();
}
char * bloco_memoria;
long tamanho;
ifstream arquivo1("arq.bin", ios::in | ios::binary | ios::ate);
if (arquivo1.is_open())
{
tamanho = arquivo1.tellg();
bloco_memoria = new char [tamanho];
arquivo1.seekg (0, ios::beg);
arquivo1.read (bloco_memoria, tamanho);
arquivo1.close();
cout << "Todo o conteudo de arq.bin foi enviado para memoria.";
delete[] bloco_memoria;
}
else
{
cout << "Nao foi possivel abrir o arquivo";
arquivo1.clear();
}
196

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


system(pause);
return 0;
}
Para operaes de construo de um byte de bits selecionados,
precisamos incluir o arquivo cabealho <climits> que possui uma
Macro CHAR_BIT que utiliza pelo menos 8 bits que so rodados
para esquerda e para direita dentro do byte (<< (CHAR_BIT-1) bit
>> 1) para construir os 8 bits que respresentam o cdigo binrio
do nmero constante da tabela ASCII. Primeiro abrimos o arquivo
com o flag ios::ate, que posiciona o ponteiro no fim do arquivo.
Quando executamos tamanho=arquivo1.tellg(), o tamanho do
arquivo passado para tamanho. Criamos em memria um
espao de tamanho bytes com bloco_memoria = new char
[tamanho] e apontamos para o incio do arquivo com
arquivo1.seekg(0, ios::beg);
Em seguida gravamos na memria reservada os bytes de nmero
tamanho na memria usando arquivo1.read (bloco_memoria,
tamanho), e fechamos o arquivo.
Normalmente iremos fazer algo com os bytes em memria antes
de devolv-la ao sistema com delete[], mas no momento nosso
propsito foi realizado, ento fechamos o programa.
Nosso prximo assunto diz respeito polimorfismo. Bom,
considere C++ como sendo uma lingugem de programao
orientada objetos. No objetos como uma lavadora de louas ou
coisa parecida, mas descrio de objetos seria mais apropriado.

197

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Captulo 15 Polimorfismo e Membros Virtuais:


Lembre quando falamos de classes derivadas de outras classes?
Bem, uma das principais caractersticas de classes derivadas o
fato de poder usar um ponteiro de tipo compatvel com a classe
base. No entanto, no podemos usar um ponteiro diretamente para
acessar as variveis e funes de uma classe, porqu somente
podemos apontar para as variveis que a classe herdou da classe
base. Uma sada deste bco o uso de membros virtuais, que
podemos exemplificar recorrendo ao programa de clculo de
volume:
#include <iostream>
#include <conio.h>
#define pi 3.142
#define div 0.3334 // Resultado de 1/3
using namespace std;
class volume
{
protected:
double raio, altura;
public:
void valores (double r, double alt)
{
raio=r;
altura=alt;
}
virtual double vol () // Acrescentamos esta funo virtual
{
return 0;
}
};

198

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

class cilindro: public volume


{
public:
double vol ()
{
return (pi * altura * raio * raio);
}
};
class cone: public volume
{
public:
double vol ()
{
return (div * pi * altura * raio * raio);
}
};
int main ()
{
double r, alt;
cout << "Entra com valores de raio e altura: ";
cin >> r >> alt;
cilindro cil;
cone con;
volume vol;
volume *pvol1 = &cil;
volume *pvol2 = &con;
pvol1 -> valores (r,alt);
pvol2 -> valores (r,alt);
cout << "\n O volume do cilindro = " << pvol1 -> vol() << " unidades
cubicos " << endl;
cout << "\n O volume do cone = " << pvol2 -> vol() << " unidades
cubicos" << endl;
getch();
199

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


return 0;
}
Com a declarao e definio da funo membro virtual double
vol() { return 0;} como sendo membro da classe volume, agora os
ponteiros pvol1 e pvol2 tero acesso s variveis de acesso
protected da classe volume quando apontamos estes para os
endereos de cil e con, que declaramos como tipos cilindro e cone
respectivamente. Em cout apontamos diretamente para o
resultado retornado pelas classes cilindro e cone.

Captulo 16 Projeto de Comunicao usando a Porta


LPT1 do DeskTop (PC) ou Laptop
Se conseguirmos comunicar com a porta LPT1, normalmente
reservado para operao de uma impressora mas em tempos
modernos, livre, pois as impressoras mais recentes efetuam a
comunicao PC/Impressora por porta USB, teremos acesso a
vrios bits que podemos usar como Entradas/Sadas para
programar outros dispositivos conectados a ela, como o controle
de entrada ou sada de veculos e pessoas, PIC ou iluminao ou
qualquer trabalho, basta ser criativo. Para mostrar que realmente
estamos controlando os estados de tenso nos pinos de LPT1
instalamos 8 Leds conforme as imagens abaixo.
Lista de Material:
Conector 25 pinos tipo Macho;
8 Leds de uso normal;
8 Resistores de 680 Watts;
Espaguete de encolhimento trmico;

200

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Fig. 1 Diagrama esquemtico de montagem do conector

201

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Veja o programa que realiza a comunicao com LPT1:


#include <iostream>
#include <dos.h>
using namespace std;
int main(void)
{
int portalpt1 = 0x378;
int leds = 0xff;
outport(portalpt1, leds);
cout<<"\nO valor enviado = "<<leds;
system(pause);
return 0;
}

Resta ento responder pergunta que fica nos cutucando at nos


sonhos:

Afinal, porque somos obrigados a usar namespace?

202

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Captulo 17 namespace Desmistificado


Em C++ antes de podermos usar variveis, funes e tipos
compostos, como j sabe precisamos declar-las e o ponto no
programa onde fizemos a declarao determina sua visibilidade.
Pensando em um programa como uma srie de blocos, uma
entidade declarada fora de qualquer bloco ter escopo global e
significa que o nome da entidade ser vlido em qualquer lugar do
cdigo, ao contrrio de uma entidade declarada dentro dos limites
do bloco significa que uma funo ou declarao ter escopo
apenas dentro do bloco, incluindo a sua visibilidade, e por exemplo
se a declarao de uma varivel, chamada de varivel local.
Uma varivel declarada no corpo de uma funo uma varivel
local vlida por toda extenso da funo, desde a chaveta de
incio { e at a chaveta de fechamento da funo }.
Veja um exemplo:
int somar;

// Varivel global

int uma_funcao ()
{
int numero;
// Varivel local
numero = 0;
}
int outra_funcao ()
{
somar = 1; // somar vlido pois foi declarado globalmente
numero = 2; // numero no vlido pois no visvel neste bloco
}

203

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Um nome poder representar apenas uma entidade em cada


escopo, portanto no poder representar duas entidades. No
exemplo supra tentamos usar uma varivel na funo que no foi
declarada, gerando erro.
Outro exemplo:
Int uma_funcao ()
{
int x;
x=0;
double x;/* No permitida a declarao de mais de um tipo da
mesma varivel no escopo do mesmo bloco*/
x=2.5;
}
A visibilidade de uma entidade no escopo do bloco estende at o
fim do bloco, e inclui os blocos internos. No entanto um bloco
interno poder reutilizar um nome existente no escopo do bloco
que o engloba porque neste caso o nome se refere uma entidade
diferente somente dentro do bloco interno, escondendo a entidade
nomeada, fora do bloco. Veja um exemplo:

204

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

// Escopo do bloco interno


#include <iostream>
using namespace std;
int main()
{
int x = 10; // Declarao e inicializao de x externo
int y = 20; // Declarao e inicializao de y externo
{
int x; // Declarao da varivel x interno
x = 30; // Inicializa x interno com valor 30
y = 100; // Inicializa y externo com valor 100
cout << "Bloco interno : \n";
cout << "x: " << x << '\n';
cout << "y: " << y << '\n';
}
cout << "Bloco externo : \n";
cout << "x: " << x << '\n';
cout << "y: " << y << '\n';
return 0;
}
Aps execuo:
Bloco interno:
x: 30
y: 100
Bloco externo:
x: 10
y: 100
Note que a varivel y no est escondida no bloco interno,
portanto quando acessamos y ainda acessamos y externo.

205

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

As variveis que so declaradas e declaraes que introduzem um


bloco como parmetros de funes e variveis declaradas dentro
de elos de tipo for, ou dentro da funo if so locais ao bloco que
elas introduzem.
Como j falamos, apenas uma entidade pode existir que possui um
nome particular, uma vez que blocos normalmente so
relativamente curtos e nomes possuem propsitos particulares
neles, como por exemplo, nomeando uma varivel para contagem
de eventos ou argumentos e etc. Entretanto nomes que no so
locais multiplicam as chances de haver colises de nome, o que
no acontece com nomes de variveis locais considerando que as
bibliotecas podem declarar mltiplas funes, tipos e variveis
que no so locais por natureza.
Diante de todos estes problemas chegamos ao propsito do uso de
namespace, que nos permite agrupar entidades nomeadas que
ao contrrio teriam escopo global, em escopos mais magros, o
escopo namespace, para organizar os elementos de programas em
escopos lgicos diferenciados e referenciados atravz de nomes.
Para declarar um namespace, seguimos a sntaxe:
namespace identificador;
{
entidades_nomeadas
}
Onde
identificador

qualquer
identificador
vlido
e
entidades_nomeadas um conjunto de variveis, tipos e funes
que esto incluidos dentro do escopo do namespace.

206

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Veja um exemplo:
namespace meuNamespace
{
int x, y;
}
As variveis x e y so variveis normais que foram declaradas
dentro do namespace chamado meuNamespace, mas no podem
ser acessadas de fora de meuNamespace a no ser que estejam
qualificadas pelo uso do operador de escopo :: ou seja,
meuNamespace::x e meuNamespace::y.
Para evitar que sejam gerados erros por coliso de nomes
podemos declarar um namespace como funo e depois tornando
as variveis visveis para outras funes usando o operador de
escopo:
#include <iostream>
using namespace std;
namespace valores
{
int valor()
{
return 10;
}
namespace meupi
{
const double pi=3.142;
double valor()
{
return 2*pi;
}
207

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

int main()
{
cout<<valores::valor()<<\n;
cout<<meupi::valor()<<\n;
cout<<meupi::pi<<\n;
{
Aps execuo:
10
6.2832
3.1416
Note que usamos duas funes chamadas de valor, onde definimos
a primeiro dentro do namespace valores, a outro dentro do
namespace meupi, adicionalmente note como pi acessado de
modo no qualificado de dentro de namespace meupi, como
tambm dentro de main, mas fomos obrigados a usar o operador
de escopo, meupi::pi.
At o momento implementamos a declarao using apenas com
namespace padro, i.e. using namespace std;
Esta declarao diz ao compilador que estaremos usando todas as
funes, variveis e diretrizes que fazem parte da biblioteca
padro, std, mas podemos declarar que pretendemos usar
qualquer definio de namespace.
Veja o exemplo abaixo:

208

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

A palavra chave using introduz um nome na regio declarativa


atual, como um bloco, e torna redundante a necessidade de ter
que se qualificar o nome:
#include <iostream>
using namespace std;
namespace primeiro
{
int x = 5;
int y = 10;
}
namespace segundo
{
double x = 3.142;
double y = 2.72;
}
int main () {
using primeiro::x;
using segundo::y;
cout << x << \n;
cout << y << \n;
cout << primeiro::y << \n;
cout << segundo::x << \n;
return 0;
}
Aps a execuo:
5
2.72
10
3.142
209

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Note como na funo main a varivel x sem nenhum nome de


qualificao se refere primeiro::x, enquanto a varivel y se refere
segundo::y como especificado pelas declaraes using. Note
inclusive que as variveis primeiro::y e segundo::x podem ser
acessadas, mas necessitam de nomes amplamente qualificados.
using e using namespace possuem validade apenas dentro do
mesmo bloco onde so declarados, ou no escopo global, o cdigo
inteiro. Seria possvel primeiro usar os objetos de um namespace e
depois os objetos de outro namespace ao dividir o cdigo em
blocos diferentes:
#include <iostream>
using namespace std;
namespace primeiro
{
int x = 5;
}
namespace segundo
{
double x = 3.142;
}
int main ()
{
{
using namespace primeiro;
cout << x << \n;
}
{
using namespace segundo;
cout << x << \n;
}
return 0;
210

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


}

Aps execuo:
5
3.1416

Captulo 18 Criando e usando Listas Ligadas


Muito se fala sobre listas (Linked Lists), um mtodo usado para
criar clulas no Heap de memria para guardar informaes
interligadas. Vamos ento analisar como uma lista gerada:
10
A

12

Raiz
Incio

64

NULL
Fim

Dados

Ponteiro

O primeiro passo o de criar a clula raiz em memria que no


contm informaes ou dados, mas usado como ponteiro para o
primeiro nodo. Cada nodo uma clula composta de informao e
ponteiro para o nodo seguinte, repetido n vezes at o ltimo nodo
nesta cadeia que aponta para valor nulo que significa fim da
cadeia. No caso o nodo raiz est apontando para o endereo 10.
Ento voc pergunta, Hmmm isto me cheira de matrizes, porqu
no usar matrizes? Boa pergunta. Como j foi abordado em seo
anterior uma matriz possui caractersticas ambos fisicamente e
logicamente contguos uma vez que os elementos que a compe
encontram-se localizados em memrias consecutivas. Ao
dimensionar uma matriz no possvel aumentar seu tamanho,
mesmo quando se tratar de matriz de tamanho dinmico.

211

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Caso necessitamos de inserir dados numa clula no meio da
matriz, todos os outros dados que seguem a clula tem de ser
movidos uma clula para direita, caso tenhamos memria
reservada para realizar esta operao.
J uma lista ligada pode ser aumentada dinamicamente enquanto
restar memria para tanto no Heap, e usa pedacinhos de memria
espalhadas pelo Heap para crescer. Podemos inserir nodos em
qualquer lugar da cadeia, e apenas alterar o valor do ponteiro.
Uma lista sempre comea com um nodo raiz, e o programa abaixo
faz isto.
#include <iostream>
using namespace std;
struct nodo { // Declaramos uma estrutura chamada de nodo
int x;
nodo *seguinte;
};
int main()
{
nodo *raiz;

// Este no muda, o nodo raz.


// raz aponta para a estrutura nodo
raiz = new nodo; /* necessrio reservar memria no Heap para o
nodo que acabamos de criar*/
raiz->seguinte = 0; // O nodo para qual raz aponta nulo
raiz->x = 10;
/* Usando o operador de insero -> podemos
modificar o nodo que o ponteiro est
apontando, neste caso raz */
cout << O endereo de raiz = << &raiz << endl;
return 0;
}

212

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Se pensar poder usar listas ligadas para realizar centenas de


trabalhos, como guardar os nomes de msicas de vrios cantores
ou bandas, ou todas as possibilidades de uma jogada no jogo de
domins como exemplos.
Uma das desvantagens de listas que nosso programa precisa
percorrer todos os nodos procura de um dado ou informao
naquela cadeia de nodos, e quando chegar ao nodo fim, ento
informar que a informao solicitada no foi encontrada.
Note no programa supra que declaramos uma estrutura chamada
de nodo. No programa abaixo, usamos classes e funes para
realizar todo gerenciamento de nossa lista. Esta lista ter formato
linear, sem bifurcaes ou ligaes com outras listas, que tornaria
o programa muito difcil de entender.

#include <iostream>
#include <string>
using namespace std;
class lista
{
public:
struct nodo {
int id;
string nome;
struct nodo *seguinte;
} *inicio, *fim, *ptro;
lista():inicio(NULL),fim(NULL){} //
Aqui
declaramos
construtor
~lista();
// e aqui, o destruidor

um

struct lista::nodo* procurarNome(struct lista::nodo*, string);


struct lista::nodo* procurarId(struct lista::nodo*, int);
213

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


struct lista::nodo* iniciarNodo(string, int);
void
void
void
void
void
void
void

reverter(); // Declarao de prottipos


adicionarNodo( struct lista::nodo*);
inserirNodo( struct lista::nodo*);
deletarNodo( struct lista::nodo*);
deletarLista( struct lista::nodo*);
mostrarLista( struct lista::nodo*)const ;
mostrarNodo( struct lista::nodo*) const;

};
lista::~lista() {
nodo *atual,*temp;
atual = inicio;
temp = inicio;
while(atual != NULL) {
atual = atual->seguinte;
delete temp;
temp = atual;
}
}
struct lista::nodo* lista::iniciarNodo(string s, int i) {
struct nodo *ptro = new nodo;
// Caso fim
if( ptro == NULL )
return static_cast<struct nodo *>(NULL);
// nodo nulo retornar o ponteiro para novo nodo

else {
ptro->nome = s ;
ptro->id = i;
return ptro;
}

214

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


// Acrescentar novo nodo
void lista::adicionarNodo( struct nodo *novoNodo ) {
// Caso no existir um nodo, chamar este de raiz
if( inicio == NULL ) {
inicio = novoNodo;
fim = novoNodo;
}
/* Ligar o novo nodo no fim da lista
e marcar como fim (nulo)
e ajustar o ponteiro para apontar para o nodo fim*/
fim->seguinte = novoNodo;
novoNodo->seguinte = NULL;
fim = novoNodo;
}
void lista::inserirNodo( struct nodo *novonodo ) {
struct nodo *temp, *anterior;
if( inicio == NULL ) { // No caso de lista vazia marcar como inicio
inicio = novonodo;
fim = novonodo;
inicio->seguinte = NULL; // Marcar o fim da lista como nulo
return;
}
temp = inicio; /* Comear desde o inicio da lista
enquanto nome atual < novo nome*/
while( temp->nome < novonodo->nome) { // ser inserido e ento
temp = temp->seguinte;
// v ao nodo seguinte
if( temp == NULL )
// parando no nodo fim
break;
}

215

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


// Configurar nodo anterior antes de inserir
// Devemos primeiro verificar se est inserindo antes do nodo raiz
if( temp == inicio ) {
novonodo->seguinte = inicio; //Ligar campo ao nodo raiz ajustado
// para novo nodo
inicio = novonodo;
}
else {
// No o primeiro nodo
anterior = inicio;
while( anterior->seguinte != temp ) {
anterior = anterior->seguinte;
}
anterior->seguinte = novonodo; // Inserir nodo entre anterior e
// seguinte
novonodo->seguinte = temp;
if( fim == anterior )
// Se o novo nodo inserido no fim
fim = novonodo;
// da lista ajustar fim
}
}
struct lista::nodo* lista::procurarNome(struct nodo* ptro, string
nome) {
while( nome != ptro->nome ) {
ptro = ptro->seguinte;
if( ptro == NULL )
break;
}
return ptro;
}
struct lista::nodo* lista::procurarId(struct nodo* ptro, int id) {
while( id != ptro->id ) {
ptro = ptro->seguinte;
if( ptro == NULL )
break;
}
return ptro;
216

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


}
void lista::reverter() {
// Precisamos de pelo menos 2 nodos para realizar reverso
if(inicio == NULL || inicio->seguinte == NULL) return;
// Iniciando segunda lista como "eu" e inicio agora "eu// >seguinte".
// ao passo que "inicio->seguinte est apontando para nulo
// Portanto a terceira lista agora "filha" de "eu"
nodo *parente = inicio;
nodo *eu = inicio->seguinte;
nodo *filha = eu->seguinte;
// converter inicio para fim
inicio->seguinte = NULL;
// reverter o ponteiro
eu->seguinte = inicio;

while(filha != NULL){
eu->seguinte = parente;
parente = eu;
eu = filha;
filha = filha->seguinte;
}
// Quando "eu" chegar em fim "eu" torna-se inicio
inicio = eu;
// Inicio est agora apontando para penltimo nodo
inicio->seguinte = parente;

void lista::deletarNodo( struct lista::nodo *ptro )


{
struct nodo *temp, *anterior;
temp = ptro; // O nodo a ser deletado
anterior = inicio; // Inicio da lista. Atravessar at nodo antes de
//temp
217

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


if( temp == anterior ) { // Se deletando primeiro nodo
inicio = inicio->seguinte; // mover inicio ao nodo seguinte
if( fim == temp )
// Se fim somente 1 nodo
fim = fim->seguinte;
// Ajustar fim tambem
delete temp ;
// Liberar espao
}
else {
// Caso no seja o primeiro nodo
while( anterior->seguinte != temp ) { // mover anterior ao nodo
//anterior
anterior = anterior->seguinte;
// ao nodo a ser deletado
}
anterior->seguinte = temp->seguinte;// Ligar nodo anterior ao
// nodo seguinte
if( fim == temp )
// Se nodo fim
fim = anterior;
// ento ajustar o ponteiro de fim
delete temp;
// Liberar espao
}
}
void lista::deletarLista( struct nodo *ptro )
{
struct nodo *temp;
if( inicio == NULL ) return; // Evita tentar deletar uma lista vazia
if( ptro == inicio ) { // Caso estamos deletando um lista completa
inicio = NULL;
// ento ajustar inicio
fim = NULL;
// fim para nulo
}
else {
temp = inicio;
// Caso no seja uma lista inteira ajustar
// fim e
while( temp->seguinte != ptro ) // localizar nodo anterior ligado
// ao ponteiro
temp = temp->seguinte;
fim = temp;
// Ligar ao nodo fim antes de temp
}
218

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

while( ptro != NULL ) {


temp = ptro->seguinte;
delete ptro;
ptro = temp;
}

//
//
//
//

Enquanto ainda existir nodo a deletar


gravar endereo do nodo seguinte
deletar este nodo
Apontar para nodo seguinte

void lista::mostrarNodo( struct lista::nodo *ptro ) const


{
cout << ptro->id << ": " << ptro->nome << endl;
}
void lista::mostrarLista( struct lista::nodo *ptro ) const
{
if(!ptro) cout << "Nada para mostrar" << endl;
while(ptro) {
mostrarNodo(ptro);
ptro = ptro->seguinte;
}
}
int main()
{
int id;
string nome;
lista minhaLista;
lista::nodo* ptro;
// Acrescentar nodo
ptro = minhaLista.iniciarNodo( "a1",
minhaLista.adicionarNodo(ptro);
ptro = minhaLista.iniciarNodo( "b2",
minhaLista.adicionarNodo(ptro);
ptro = minhaLista.iniciarNodo( "c3",
minhaLista.adicionarNodo(ptro);
ptro = minhaLista.iniciarNodo( "d4",
minhaLista.adicionarNodo(ptro);

1 );
2 );
3 );
4 );

219

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


ptro = minhaLista.iniciarNodo( "e5", 5 );
minhaLista.adicionarNodo(ptro);
minhaLista.mostrarLista(minhaLista.inicio);
// deletar nodo
nome = "b2";
ptro = minhaLista.procurarNome( minhaLista.inicio, nome );
if( ptro == NULL ) {
cout << "\nNome: " << nome << " nao encontrado" <<
endl;

}
else {
cout << "\nDeletando o nodo ... ";
minhaLista.mostrarNodo( ptro );
minhaLista.deletarNodo( ptro );
}
minhaLista.mostrarLista(minhaLista.inicio);
// inserir nodo
nome = "b2";
id = 2;
ptro = minhaLista.iniciarNodo( nome, id );
minhaLista.inserirNodo( ptro );
cout << "\nInserindo um nodo";
minhaLista.mostrarNodo(ptro);
minhaLista.mostrarLista(minhaLista.inicio);
// reverter lista
cout << "\nRevertendo a lista \n";
minhaLista.reverter();
minhaLista.mostrarLista(minhaLista.inicio);

// deletar lista
cout << "\nAgora vamos deletar a lista para liberar memoria
... \n";

220

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

minhaLista.deletarLista(minhaLista.inicio);
minhaLista.mostrarLista(minhaLista.inicio);
return 0;
}
A lista que criamos possui 6 nodos, comeando com a raiz que
aponta para o primeiro nodo contendo o texto a1. Este nodo possui
uma Id nmero 1 que aponta para o nodo seguinte que contm o
texto b2. Este nodo possui uma Id nmero 2 sendo assim para
todos o nodos at o nodo fim, que possui o texto e5 Id nulo, fim da
lista. Esta lista poder ser usada como modelo de listas de
qualquer tamanho guardando texto ou nmeros. O compilador se
encarrega de lembrar os endereos das identidades, os ponteiros,
igual declarao e inicializao de variveis, o nome que aponta
para um segmento de memria que contm os valores atribudos
varivel. Note que o programa insere os textos e nmeros Id na
lista dentro da funo main(), e poder ser fcilmente alterado
para receber textos e Id pelo teclado.

221

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Antes de partir para WxDev-C++, podemos usar tudo que


aprendemos at agora para elaborar um jogo, e um jogo que
desafia nossos conhecimentos seria o Jogo da Velha. Neste jogo
teremos dois jogadores humanos, e no o computador que torna o
projeto um pouco mais fcil.
Ento perguntamos, qual o primeiro passo? Bom, para jogar, temos
que apresentar um quadro de nove posies, e um meio de dizer
ao programa qual o jogador, e qual entre estas 9 posies
desejamos escrever um X ou um O.
Esta parte seria um bom comeo:
void mostrar_quadro()
{
cout << "---------------------" << endl << endl;
cout << "
|
|
" << endl;
cout << " " << quadro[0][0] << " | " << quadro[0][1] << " | " <<
quadro[0][2] << endl;
cout << "_____|_____|_____" << endl;
cout << "
|
|
" << endl;
cout << " " << quadro[1][0] << " | " << quadro[1][1] << " | " <<
quadro[1][2] << endl;
cout << "_____|_____|_____" << endl;
cout << "
|
|
" << endl;
cout << " " << quadro[2][0] << " | " << quadro[2][1] << " | " <<
quadro[2][2] << endl;
cout << "
|
|
" << endl;
}

222

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Alm de desenhar o quadro tpico do jogo da velha, alocamos cada
posio do quadro uma matriz[3][3], que chamamos
apropriadamente de quadro. Para identificar cada posio, iremos
escrever nmeros entre 1 e at 9 em sequncia. Nosso programa
ir receber um destes nmeros que corresponde posio onde
dever escrever um X ou um O.
Note
inclusive
que
usamos
uma
funo
chamada
de
mostrar_quadro, ento cada vez que chamamos esta funo
teremos um quadro com as posies ocupadas com X ou O que at
ento foram escolhidas durante o decorrer do jogo.
O prximo passo ser de escolher o jogador, que realizado
alternadamente pelo programa, at que o quadro esteja populado
com as letras X ou O, que formam uma linha de 3, coluna de 3 ou
diagonal de 3. Neste passo declaramos as funes, e as variveis
globais que iremos usar:
void mostrar_quadro();
void jogador_vez();
bool fim_de_jogo();
char vez;
bool empate = false;
char quadro[3][3] = {{'1', '2', '3'}, {'4', '5', '6'}, {'7', '8', '9'}};
Note que a matriz quadro de tipo char foi inicializada com nmeros
sequenciais de 1 a 9, e foi configurado como tipo char porqu
iremos substituir os nmeros com as letras X ou O.
Declaramos as trs funes que compe o jogo, mostrar_quadro j
conhecemos, jogador_vez responsvel pela parte operacional, a
vez dos jogadores, e onde no quadro escrever um X ou um O. Note
inclusive que declaramos estas duas funes como de tipo void,
porqu no precisamos passar dados para a funo main() que as
convoca, j que declaramos as variveis como sendo de mbito
global, portanto todas as funes tem acesso elas.

223

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


void jogador_vez()
{
int escolha;
int fileira = 0, coluna = 0;
if (vez == 'X')
{
cout << "Jogador 1, sua vez [X]: ";
}
else if (vez == 'O')
{
cout << "Jogador 2, sua vez [O]: ";
}
cin >> escolha;
switch (escolha)
{
case 1: fileira = 0; coluna = 0; break;
case 2: fileira = 0; coluna = 1; break;
case 3: fileira = 0; coluna = 2; break;
case 4: fileira = 1; coluna = 0; break;
case 5: fileira = 1; coluna = 1; break;
case 6: fileira = 1; coluna = 2; break;
case 7: fileira = 2; coluna = 0; break;
case 8: fileira = 2; coluna = 1; break;
case 9: fileira = 2; coluna = 2; break;
default:
cout << "Escolher uma posicao desocupada entre 1 e 9! Tente de
novo\n";
jogador_vez();
}
A varivel vez conter uma entre duas letras, X ou O. Usando a
tcnica de recurso, onde a funo convoca ela mesma,
verificada pela funo switch(escolha) qual a posio no quadro
que um jogador escolheu. Se foi a posio 1, as variveis fileira e
coluna contero 0,0 respectivamente. Se um nmero no
corresponde aos cases entre 1 e 9, imprime mensagem de erro, e
jogador_vez convocada novamente.
224

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


if (vez == 'X' && quadro[fileira][coluna] != 'X' &&
quadro[fileira][coluna] != 'O')
{
quadro[fileira][coluna] = 'X';
vez = 'O';
}
else if (vez == 'O' && quadro[fileira][coluna] != 'X' &&
quadro[fileira][coluna] != 'O')
{
quadro[fileira][coluna] = 'O';
vez = 'X';
}
else
{
cout << "A posicao no quadro esta ocupada! Tente de novo\n";
jogador_vez();
}
}
Em seguida verificada a existncia de um X ou O naquela
posio, e se a vez do jogador X, imprimido um X na posio
quadro[0][0], o mesmo acontecendo caso o jogador O fez a jogada,
e a vez passada para o outro jogador. Um segundo teste
realizado para determinar se a posio est ocupada, pelo
operador NO ! e se negativo, imprime o aviso com nova
convocao da funo.
O prximo passo o de verificar se temos um ganhador, ou se
temos um empate.
Para esta etapa declaramos a funo fim_de_jogo como de tipo
bool, e esta funo retornar 1, no caso de jogo ganho, ou 0 no
caso de jogo empatado. O trabalho realizado pela funo compara
o contedo de posies no quadro e caso encontrar 3 posies
sucessivas contendo a letra X ou a letra O, numa fileira, coluna ou
diagonal, retorna 1 (true). Caso no encontrar a sucesso de 3 da
mesma letra, retorna 0 (false).

225

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


bool fim_de_jogo()//verificar jogo ganho, ou empate
{
for (int i = 0; i < 3; i++)
{
if ((quadro[i][0] == quadro[i][1] && quadro[i][1] == quadro[i][2])
|| (quadro[0][i] == quadro[1][i] && quadro[1][i] == quadro[2][i]) ||
(quadro[0][0] == quadro[1][1] && quadro[1][1] == quadro[2][2]) ||
(quadro[0][2] == quadro[1][1] && quadro[1][1] == quadro[2][0]))
{
return true;
}
}
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (quadro[i][j] != 'X' && quadro[i][j] != 'O')
{
return false;
}
}
}
Resta ento juntar as partes e apresentar o programa completo.
Um bom exerccio seria o de elaborar um loop que permite jogar
outra vez sem precisar compilar aps cada jogo.
#include <iostream>
using namespace std;
void mostrar_quadro();
void jogador_vez();
bool fim_de_jogo();
int resposta = 0;
char vez;
bool empate = false;
226

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


char quadro[3][3] = {{'1', '2', '3'}, {'4', '5', '6'}, {'7', '8', '9'}};
int main()
{
cout << "Jogo da Velha\n";
cout << "Jogador 1 [X] --- Jogador 2 [O]\n";
vez = 'X';
while (!fim_de_jogo())
{
mostrar_quadro();
jogador_vez();
fim_de_jogo();
}
if (vez == 'O' && !empate)
{
mostrar_quadro();
cout << endl << endl << "Jogador 1 [X] Ganhou! Fim de
jogo!\n";
}
else if (vez == 'X' && !empate)
{
mostrar_quadro();
cout << endl << endl << "Jogador 2 [O] Ganhou! Fim de
jogo!\n";
}
else
{
mostrar_quadro();
cout << endl << endl << "Empate! Fim de jogo!\n";
}
}
void mostrar_quadro()
{
cout << "---------------------" << endl << endl;
cout << "
|
|
" << endl;
cout << " " << quadro[0][0] << " | " << quadro[0][1] << " | " <<
quadro[0][2] << endl;
227

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


cout << "_____|_____|_____" << endl;
cout << "
|
|
" << endl;
cout << " " << quadro[1][0] << " | " << quadro[1][1] << " | " <<
quadro[1][2] << endl;
cout << "_____|_____|_____" << endl;
cout << "
|
|
" << endl;
cout << " " << quadro[2][0] << " | " << quadro[2][1] << " | " <<
quadro[2][2] << endl;
cout << "
|
|
" << endl;
}
void jogador_vez()
{
int escolha;
int fileira = 0, coluna = 0;
if (vez == 'X')
{
cout << "Jogador 1, sua vez [X]: ";
}
else if (vez == 'O')
{
cout << "Jogador 2, sua vez [O]: ";
}
cin >> escolha;
switch (escolha)
{
case 1: fileira =
case 2: fileira =
case 3: fileira =
case 4: fileira =
case 5: fileira =
case 6: fileira =
case 7: fileira =
case 8: fileira =
case 9: fileira =
default:

0;
0;
0;
1;
1;
1;
2;
2;
2;

coluna
coluna
coluna
coluna
coluna
coluna
coluna
coluna
coluna

=
=
=
=
=
=
=
=
=

0;
1;
2;
0;
1;
2;
0;
1;
2;

break;
break;
break;
break;
break;
break;
break;
break;
break;

228

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


cout << "Escolher uma posicao desocupada entre 1 e 9!
Tente de novo\n";
jogador_vez();
}
if (vez == 'X' && quadro[fileira][coluna] != 'X' &&
quadro[fileira][coluna] != 'O')
{
quadro[fileira][coluna] = 'X';
vez = 'O';
}
else if (vez == 'O' && quadro[fileira][coluna] != 'X' &&
quadro[fileira][coluna] != 'O')
{
quadro[fileira][coluna] = 'O';
vez = 'X';
}
else
{
cout << "A posicao no quadro esta ocupada! Tente de novo\n";
jogador_vez();
}
}
bool fim_de_jogo()//verificar jogo ganho, ou empate
{
for (int i = 0; i < 3; i++)
{
if ((quadro[i][0] == quadro[i][1] && quadro[i][1] == quadro[i][2])
|| (quadro[0][i] == quadro[1][i] && quadro[1][i] == quadro[2][i]) ||
(quadro[0][0] == quadro[1][1] && quadro[1][1] == quadro[2][2]) ||
(quadro[0][2] == quadro[1][1] && quadro[1][1] == quadro[2][0]))
{
return true;
}
}

229

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (quadro[i][j] != 'X' && quadro[i][j] != 'O')
{
return false;
}
}
}
empate = true;
return true;
}
Enjoy!!!
Controlar caracteres usando Dev-C++ se torna mais fcil quando
inclu-mos a biblioteca <windows.h> e podemos enviar caracteres
especiais e at determinar as cores destes na janela do DOS.
Lembra do programa que criamos para movimentar um circulo na
pgina 129 usando a janela WinBGI? Bom, aqui no vamos usar
WinBGI, apenas a janela do DOS. Veja como:

230

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


/* Este programa mostra como controlar a janela do console ou
janela do DOS ao criar uma matriz contendo todas as posies de
caracteres nela, semelhante ao que fazemos em grficos
bidimensionais onde manipulamos pixels como o programa que
elaboramos usando a janela do WinBGI (pgina 129), exceto que
no podemos controlar as posies de pixels usando a janela do
DOS, apenas as posies e as cores de caracteres. Usando a
tcnica podemos posicionar uma sequncia de caracteres em
qualquer posio dentro de uma grade de dimenses previamente
declaradas. A palavra Buffer se refere memria reservada para
guardar todos os dados que usaremos, no caso uma matriz [40][30]
o tamanho de nossa grade.*/
#include <windows.h>
/* Precisamos incluir window.h para usar as funes de console.
No vamos usar a funo cout ento no precisamos incluir
iostream, como tambm um namespace*/
#define GRID_WIDTH 40
// A quantidade de caracteres no eixo x da grade
#define GRID_HEIGHT 30
// A quantidade de carcteres no eixo y da grade
#define POS_X
20
// A posio inicial do ponto x
#define POS_Y
10
// A posio inicial do ponto y
int main()
{
CHAR_INFO screenBuffer[GRID_WIDTH * GRID_HEIGHT];
/* Declaramos e inicializamos o Buffer (nossa matriz) tamanho
[40][30]*/
// Este um tipo de dados do Windows que cria um retngulo
SMALL_RECT drawRect = {POS_X, POS_Y, POS_X + (GRID_WIDTH 1), POS_Y + (GRID_HEIGHT - 1)};
COORD gridSize = {GRID_WIDTH , GRID_HEIGHT};
/* Note que diminuimos as dimenses por 1 porque a primeira
posio na matriz = 0*/
231

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


COORD zeroZero = {0, 0};
// COORD posiciona o cursor nas coordenadas ao passo que toma
HANDLE OutputH;
/* a coordenada zeroZero de referncia. HANDLE a ala onde
OutputH o fixador*/
int y;
/* Seguem maiores detalhes sobre as variveis e funes, supra:
screenBuffer - Notavelmente construimos uma mariz de
CHAR_INFO que uma estrutura que possui uma cor e tamanho
igual a um retngulo comum onde area = base*altura que
corresponde quantidade de caracteres que pretendemos
imprimir na grade cada passada do programa. J que definimos os
parmetros como sendo de 40*30 teremos na grade 1.200
carateres imprimidos, o mesmo que screenBuffer[1.200]. No
podemos usar uma matriz bidimensional porque a funo
WriteConsoleOutput() a toma como uma matriz unidimensional
apenas.
drawRect - Sendo um retngulo a funo WriteConsoleOutput
espera receber dados referentes s coordenadas das posies
iniciais do topo esquerda, da direita, e da base onde queremos
imprimir nosso Buffer. Portanto, passamos para a funo
WriteConsoleOutput() a posio de inicio e depois a largura e
altura menos 1 so acrescentadas.
gridSize - Este passa para a funo WriteConsoleOutput() o
tamanho do Buffer.
zeroZero - Este informa as coordenadas do topo esquerda de
onde pretendemos imprimir.
OutputH - Precisamos declarar este para ter acessa janela do
DOS.*/
OutputH = GetStdHandle(STD_OUTPUT_HANDLE);

232

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


/*Obter um gancho para acessar a janela.
A partir deste ponto, tratamos nosso Buffer como uma matriz
bidimensional.
Para tanto usamos dois loops aninhados, o primeiro imprime as
colunas no Buffer, o segundo imprime as fileiras no Buffer,
portanto passamos 40 asteriscos para o Buffer, depois mais 40
sucessivamente ao passo que aumentamos os valores de Y at
completar o Buffer.*/
for(y = 0; y < gridSize.Y; y++)
{
for(int x = 0; x < gridSize.X; x++)
{
/*Uma vez que no podemos usar uma matriz bidimensional, onde
matriz[x][y] temos que tratar nossa matriz unidimensional
como uma matriz bidimensional e para tanto usamos a equao
onde x + (y * largura) e funciona de seguinte forma: No inicio y = 0,
e x = 0, portanto 0 + (0 * largura) = 0. O ndice de y = 0 e x
completa 1 linha com y=0. Em seguida quando y = 1, temos 0+(1 *
largura) = largura. Se pegarmos x e somarmos a largura,
estaremos no inicio da segunda fileira, certo?
Agora que temos o ndice desejado temos que configurar o
caratere e a cor.
Para configurar o caratere temos de acessar a estrutura
CHAR_INFO onde temos duas opes: uma varivel Unicode ou
uma varivel AsciiChar, e queremos este ltimo.*/
screenBuffer[x + y * GRID_WIDTH].Char.AsciiChar = '*';
/*Para configurar a cor temos de acessar a opo Attributes, da
estrutura CHAR_INFO onde temos vrias opes como por
exemplo
FOREGROUND_GREEN,
BACKGROUND_GREEN,
FOREGROUND_RED, BACKGROUND_RED, FOREGROUND_BLUE,
BACKGROUND_BLUE.
FOREGROUND se refere cor do caractere, BACKGROUND cor
de fundo.*/

233

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


screenBuffer[x+y*GRID_WIDTH].Attributes= FOREGROUND_GREEN;
}
}
/*Terminamos a inicializao da matriz e agora resta imprimi-la na
tela. Note que ao contrrio de imprimir caratere por caratere o
programa preenche toda grade de uma vez, ento muito rpido.*/
WriteConsoleOutput(OutputH,
&drawRect);

screenBuffer,

gridSize,

zeroZero,

drawRect.Top += 5; // Deslocamos a grade 5 posies para baixo


drawRect.Left += 5; // 5 posies para direita mas temos que
drawRect.Right += 5; /* acrescentar 5 posies para direita e 5
posies para */
drawRect.Bottom += 5; /* baixo para manter o tamanho da grade.
Agora vamos imprimir uns Smileys que possuem cdigo ASCII 1 de
cor azul com fundo branco.*/
for(y = 0; y < gridSize.Y; y++)
// Preenchemos as colunas
{
for(int x = 0; x < gridSize.X; x++) // Preenchemos as fileiras
{
screenBuffer[x + y * GRID_WIDTH].Char.AsciiChar = 1;
screenBuffer[x+y*GRID_WIDTH].Attributes=FOREGROUND_BLUE|
(BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_BLUE);
}
}
/* Na verdade no existe uma cor branca pronta ento temos que
produzr-la usando as 3 cores primrias como fundo sendo elas
azul, verde e vermelho. Note que vermelho/verde rende a cor
amarela, verde/azul a cor cian, azul/vermelho a cor violeta.*/
WriteConsoleOutput(OutputH,
&drawRect);

screenBuffer,

gridSize,

zeroZero,

234

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


drawRect.Top += 5; // Repetimos os deslocamentos
drawRect.Left += 5;
drawRect.Right += 5;
drawRect.Bottom += 5;
/* Repetimos o preenchimento s que desta vez imprimimos uma
grade de coraes vermelhas.*/
for(y = 0; y < gridSize.Y; y++)
// Preenchimento das colunas
{
for(int x = 0; x < gridSize.X; x++) // Preenchimento das fileiras
{
screenBuffer[x + y * GRID_WIDTH].Char.AsciiChar = 3;
screenBuffer[x+y*GRID_WIDTH].Attributes=FOREGROUND_RED;
}
}
WriteConsoleOutput(OutputH,
&drawRect);

screenBuffer,

gridSize,

zeroZero,

// Um atraso de alguns segundos antes de o programa finalizar


Sleep(1000);
return 0;
}
Agora que aprendemos como inserir caracteres na janela do DOS,
poderemos alterar alguns parmetros, quanto ao tamanho da
grade, os deslocamentos e as cores dos caracteres.
Veja o programa completo abaixo:

235

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


#include <windows.h>
#define
#define
#define
#define

GRID_WIDTH 40
GRID_HEIGHT 30
POS_X
20
POS_Y
10

int main()
{
CHAR_INFO screenBuffer[GRID_WIDTH * GRID_HEIGHT];
SMALL_RECT drawRect = {POS_X, POS_Y, POS_X + (GRID_WIDTH 1), POS_Y + (GRID_HEIGHT - 1)};
COORD gridSize = {GRID_WIDTH , GRID_HEIGHT};
COORD zeroZero = {0, 0};
HANDLE OutputH;
int y;
OutputH = GetStdHandle(STD_OUTPUT_HANDLE);
for(y = 0; y < gridSize.Y; y++)
{
for(int x = 0; x < gridSize.X; x++)
{
screenBuffer[x + y * GRID_WIDTH].Char.AsciiChar = '*';
screenBuffer[x
+
y
*
GRID_WIDTH].Attributes
=
FOREGROUND_GREEN;
}
}
WriteConsoleOutput(OutputH,
zeroZero, &drawRect);

screenBuffer,

gridSize,

drawRect.Top += 5;
drawRect.Left += 5;
drawRect.Right += 5;
drawRect.Bottom += 5;

236

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


for(y = 0; y < gridSize.Y; y++)
{
for(int x = 0; x < gridSize.X; x++)
{
screenBuffer[x + y * GRID_WIDTH].Char.AsciiChar = 1;
screenBuffer[x
+
y
*
GRID_WIDTH].Attributes
=
FOREGROUND_BLUE
|
(BACKGROUND_RED
|
BACKGROUND_GREEN | BACKGROUND_BLUE);
}
}
WriteConsoleOutput(OutputH,
zeroZero, &drawRect);

screenBuffer,

gridSize,

drawRect.Top += 5;
drawRect.Left += 5;
drawRect.Right += 5;
drawRect.Bottom += 5;

for(y = 0; y < gridSize.Y; y++)


{
for(int x = 0; x < gridSize.X; x++)
{
screenBuffer[x + y * GRID_WIDTH].Char.AsciiChar = 3;
screenBuffer[x + y * GRID_WIDTH].Attributes =
FOREGROUND_RED;
}
}
WriteConsoleOutput(OutputH,
zeroZero, &drawRect);

screenBuffer,

gridSize,

Sleep(1000);
return 0;
}

237

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Para quem no sabe o jogo da forca consiste de apresentar uma
quantidade de sublinhas ou outro caractere que corresponde
posio de letras de uma palavra oculta, neste caso, de pases.
Neste programa no foi elaborado uma forca, mas tem-se 10
tentativas de adivinhar a sequncia de letras que correspondem
palavra oculta.
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
using namespace std;
const int MAX_TENTATIVAS=10;
int preencherLetra (char, string, string&);
int main ()
{
char letra;
int tentativas_erradas=0;
string palavra;
string palavras[] =
{
"india",
"argentina",
"colombia",
"russia",
"noruega",
"australia",
"iraque",
"namibia",
"inglaterra",
"alemanha"
};
srand(time(NULL));
int n=rand()% 10;
palavra=palavras[n];
string oculto(palavra.length(),'*');
238

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


cout << "\n\nBemvindo ao jogo da forca...Adivinhar o nome de um
Pais";
cout << "\n\nCada letra eh representado por asterisco.";
cout << "\n\nVoce deve digitar apenas uma letra cada tentativa";
cout << "\n\nVoce tem " << MAX_TENTATIVAS << " tentativas para
adivinhar.";
cout << "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
// Verificacao de tentativas
while (tentativas_erradas < MAX_TENTATIVAS)
{
cout << "\n\n" << oculto;
cout << "\n\nAdivinhe uma letra: ";
cin >> letra;
// Caso tentativa correta preencher a letra
// seno incementar tentativas erradas.
if (preencherLetra(letra, palavra, oculto)==0)
{
cout << endl << "Ooops! Letra errada" << endl;
tentativas_erradas++;
}
else
{
cout << endl << "Acertou uma letra! Isto eh divertido!" << endl;
}
// Indicar quantas tentativas restam
cout << "Voce tem " << MAX_TENTATIVAS - tentativas_erradas;
cout << " tentativas restando." << endl;
// Verificar se adivinhou
if (palavra==oculto)
{
cout << palavra << endl;
cout << "Voce acertou a palavra. Parabens!";
break;
}
}
if(tentativas_erradas == MAX_TENTATIVAS)
{
239

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


cout << "\nDesculpe voce perdeu...voce foi enforcado." << endl;
cout << "A palavra era : " << palavra << endl;
}
cin.ignore();
cin.get();
system("pause");
return 0;
}
int preencherLetra (char adivinha, string palavrasecreta, string
&adivinhapalavra)
{
int i;
int acertos=0;
int len=palavrasecreta.length();
for (i = 0; i< len; i++)
{
if (adivinha == adivinhapalavra[i])
return 0;
else if (adivinha == palavrasecreta[i])
{
adivinhapalavra[i] = adivinha;
acertos++;
}
}
return acertos;
}

240

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Captulo 18 Wx-DevC++ Todos os segredos de Caixas


de Dilogo e de Menus:
Certa vz entrei num site de foruns sobre a programao de C++ e
inocentemente fiz a pergunta Algum poderia me explicar como
desenvolver aqueles Frames e Menus bacanas que apresentam
janelinhas de entradas de dados, onde posso rolar mltiplas
escolhas e etc. por favor? Bem, pelo menos duas das trs
respostas eram de acusaes de eu querer infringir direitos
autorais, a outra de que deveria ter vergonha na cara e procurar
em outro lugar. Para voc no ter que passar pelos mesmos
caminhos espinhentos e cheios de obstculos que eu tive de
trilhar, vamos aprender nesta parte como elaborar todos estes
tipos de Menus nas prximas pginas. Porm, temos que baixar e
instalar um programa que faz todo o trabalho para ns, de nome
wxDev-C++, mas primeiramente seria melhor desinstalar a verso
atual, pois no devemos executar duas verses do mesmo
programa. Digo isto porqu este Widgets uma extenso de DevC++ montado em cima da verso 5 que estivemos usando at
agora. Depois de desinstalar o programa que estivemos usando,
baixar estes programas visualizados abaixo:

241

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

wxdevcpp_wbbased_setup utiliza a Internet para instalar todos os


programas e plug-ins que ir precisar, e pode ser baixado neste
link:
http://sourceforge.net/projects/wxdsgn/files/wxDevC%2B%2B/Version%207/wxdevcpp_webbased_setup.exe/download
J TangoImages poder ser baixado neste link:
http://sourceforge.net/projects/wxdevcppbook/files/Bonus%20Section/
Selecione Tango Icons, e TangoImages.DevPak. O Install Wizard
ir instalar as imagens na pasta de onde executa o IDE.
Aps a instalao ver que h poucas diferenas entre Devcpp
4.9.2 e wxDevcpp 7.4.2, mas a nova verso possui todas as
ferramentas para montar nossas caixas de dilogo e Menus.
Nosso primeiro projeto de uma caixa de dilogo que possui duas
janelas de texto, uma de edio de HTML (Hyper Text Markup
Language), a outra uma amostra de como o texto aparecer na
Web, uma barra de estado (Status Bar), e as ferramentas para
salvar e carregar arquivos. Caso j no tenha feito, seria bom criar
um arquivo novo onde sero armazenados seus programas, por

242

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


exemplo
em
wxdevcpp.

C:\Arquivos

de

Programas\Dev-Cpp\Programas

No wx IDE clique em arquivo, novo e projeto. Aparece o dilogo de


Novo projeto:

Escolhe wxWidgets Frame. Chamei o projeto de MeuEditorHTML, e


se certifica que o boto de rdio Projeto C++ esteja selecionado.
Clique em OK.

243

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Ser salvo o projeto com extenso .dev, salvo no arquivo


wxdevprogs, ou arquivo que voc escolheu para salvar os
programas.

A caixa de dilogo Novo wxFrame nos permite configurar a caixa


de dilogo, em Window Style: Logo adiante ser elucidado para
que servem os elementos, mas por hora, configure seu
exatamente como o exemplo supra. Clique em Create.

244

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Note que wxC++ criou vrios programas, num total de seis e so:
MeuEditorHTMLApp.cpp,
MeuEditorHTMLApp.h,
MeuEditorHTMLApp.rc,
MeuEditorHTMLFrm.cpp,
MeuEditorHTMLFrm.h,
MeuEditorHTMLFrm.wxform.
Todos esto em Project Inspector esquerda, na aba Projeto. A
idia agora preencher alguns trechos de cdigo nestes
programas. Veja Inspector das Propriedades e Componentes. Na
aba Propriedades, podem ser vistos as propriedades de wxFrame
de cor preto. As de cor azul podem ser alteradas. Na aba Eventos,
vamos configurar os eventos que causam uma mudana.
Note o quadro de cor cinza direita. Este quadro representa nosso
quadro de trabalho onde vamos desenvolver nosso projeto, que j
possui o nome e trs botes no topo direita. Vamos ento
montar nosso projeto:
Clique em MeuEditorHTMLFrm.wxform em Projeto esquerda. No
Inspector das Propriedades clique na aba Componentes.
Clique duas vezes em Menubars para abrir este arquivo.

245

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Voc tm duas opes, wxMenuBar e wxPopupMenu. Clique em


wxMenuBar e em seguida no quadro de trabalho de cor cinza, mais
ou menos na parte superior.

Foi depositado no quadro um quadradinho. Neste momento isto


mostra que temos uma barra de menu e nada mais. No se
preocupa com a localizao e outros detalhes, apenas que esteja
l.

246

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Vamos agora acrescentar uma barra de status. Na janela de
Componentes, procure o arquivo Common Controls. Abra Common
Controls e procure o componente wxStatusBar. Clique neste. Note
que o cursor possui um quadradinho branco. Clique em seguida no
quadro de trabalho, na parte inferior.

Barra de Status

Neste momento temos uma barra de menu e uma barra de status


no quadro. Vamos acrescentar uma janela divisvel, chamada de
Splitter Window. Novamente em Componentes procure a pasta
Containers, e abra. Procure o componente wxSplitterWindow.
Clique neste. Em seguida no meio do quadro de desenho. O que
temos de fazer agora expandir esta at cobrir todo o quadro
usando as oito alas pretas. so clicar num dos pontos e segurar
enquanto arrastar.

247

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Splitter Window
expandido.

Barra de Status
Como pode ver, o Splitter Window ocupa todo o espao.
Vamos agora acrescentar uma janela HTML. Na mesma pasta
procure wxHtmlWindow, clique neste e no quadro de desenho, no
Splitter Window. Neste instante o quadro diminui. No se
preocupa, isto normal.

Abra a pasta Common Controls e clique em wxMemo. Em seguida


clique no lado direito do Splitter Window. Aparece a outra janela,
chamada wxMemo.

248

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Nesta altura estar anxioso para ver seu trabalho, ento pressione
a tecla F9. wxDev compila e executa o programa, e bingo! Nossa
primeira janela de dilogo.

O que temos um editor, mas somente temos funcionais os


botes de minimizar, maximizar e encerrar. Vamos ento
acrescentar as funes de editor. Feche MeuEditorHTML.
Selecione a janela WxMemo1.

249

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

No Inspector das Propriedades, clique em Strings coerente com o


texto azul Edit Strings. Aparece um boto com trz pontos...clique
no boto. Aparece uma janela de nome String List Editor, e o texto
WxMemo1. Deletar esta linha de texto e OK.
Agora podemos preencher a barra de Menu. Para comear, clique
no quadradinho que a representa.

No Inspector das Propriedades clique em Menu Items, Edit


MenuItems. Clique no boto de trs pontos. Aparece o Menu Item
Editor. Na parte inferior clique no boto Add Item. Alguns dos
campos de Properties agora esto preenchidos. Deletar o texto em
Caption, MenuItem1 e entre com o texto &File. Pressione Enter
para entrar com novo texto. No Menu Item Editor clique o boto
Apply. Acabamos de criar um menu de arquivos, ento podemos
acrescentar alguns itens.

250

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Clique no boto Create Submenu. Substituir o texto em Caption


com &Open\tCtrl+O e pressione Enter. Clique em Apply. Na janela
de Menu Items aparece o sub menu que acabamos de criar.
Repete esta operao, esta vez inserindo em Caption o texto
&Save\tCtrl+S. Clique Apply.
Nesta altura temos que aplicar um separador de menu. Para tanto,
clique em Create Submenu. Em Properties, clique em Type: Menu
Item. Aparece um dilogo Drop-Down. Selecione a opo
Separator. Clique em Apply.

251

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Precisamos acrescentar mais um item submenu, o de encerrar, ou


exit. Clique em Create Submenu. Em Caption altere o texto para
E&xit e Apply. Clique em OK.
Pressione a tecla F9 para ver sua caixa de dilogo, e o que mudou
nela. Note que agora temos nova opo File. Clique em File.
Aparecem as funes de abrir e fechar arquivos. A terceira funo
a de encerrar, separado com uma linha de separao.
No momento Open, Save e Exit possuem apenas texto, e como
pode ver, no executam nenhuma ao. Vamos criar estas aes.
No Inspector das Propriedades clique em Componentes. Abrir o
arquivo Dialogs. Vamos acrescentar dois dilogos, e so
wxOpenFileDialog, e wxSaveFileDialog. Clique em cada um e
deposite na janela direita wxMemo na sua caixa de dilogo.

252

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Clique para selecionar um dos quadrados na janela. No Inspector


das Propriedades clique em Propriedades e Extensions. Altere o
texto azul de *.* para *.htm. Repete para o outro quadrado.
Agora temos de acrescentar o cdigo que ir fazer tudo funcionar.
O que nosso programa faz o tempo todo de esperar um evento
para entrar em ao. Vamos ento criar um evento quando
clicamos em Exit. Clique no quadrado barra de menu na janela de
texto HTML esquerda. No Inspector das Propriedades seleciona
Propriedades e Edit MenuItems. Clique no boto de trs pontos
para chamar o dilogo Menu Item Editor, que j conhecemos. Na
janela de Menu Items clique no cone + ao lado esquerdo de
&File. Isto abre para mostrar os submenus. Clique em E&xit.
Clique em Edit. Em Events: OnMenu clique no boto Create.
Aparece um dilogo Pop-Up:

Clique em Yes para salvar antes de acrescentar nova funo.


Aparece outro Pop-Up:

253

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Clique em OK para criar a nova funo. No dilogo Menu Item


Editor clique no boto Apply.

Clique no boto OK.


Agora vamos acrescentar as linhas de cdigo:
Na janela de desenvolvimento direita no wxDev-C++ ver os seis
programas criados. Clique em MeuEditorHTMLFrm.cpp.
O
programa aparece na janela.

254

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Procure o cdigo seguinte e acrescente a funo Destroy(); logo


abaixo do texto // insert your code here.

Pressione a tecla F9. Se no compilar, clique em Executar e


Resetar programa. Pressione F9 novamente.

255

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


No dilogo criado clique em File e Exit que dever encerrar o
dilogo.
Se no funcionar, verifique o cdigo embaixo de void
MeuEditorHTMLFrm::Mnuexit1010Click. Se existir outra instncia,
por exemplo MeuEditorHTMLFrm::Mnuexit1010Click0 acrescente
Destroy(); neste tambm. Por exemplo uma nova instncia seria
criada se repetimos a criao da funo mais de uma vez. No caso
executada a segunda instncia.
Agora vamos ativar a parte que controla a entrada de texto na
janela WxMemo1, da direita na sua caixa de dilogo.
No
Project
Inspector,
Projeto,
clique
em
MeuEditorHTMLFrm.wxform.
Embaixo,
no
Inspector
das
Propriedades clique em Eventos. Cada evento ser quando
acrescentamos texto na janela, portanto escolhemos OnUpdated.
Clique neste.

Clique

aqui

para

opes
Clique em <Add New Function>. Somos novamente apresentados
com o cdigo onde acrescentamos a funo Destroy(); O sistema
criou mais uma funo:

256

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Acrescente a linha:
WxHtmlWindow1->SetPage(WxMemo1->GetValue());

Agora quando escrever texto na janela de Memo1, o texto


copiado para a janela HTML.
Ainda falta ativar as opes de abrir e salvar arquivos de tipo
HTML. Faremos isto agora:
Clique em MeuEditorHTMLFrm.wxform.
Na janela de texto HTML clique no quadrado que representa a
barra de menu. No Inspector das Propriedades, Propriedades,
clique em Menu Items. Clique no boto de trs pontos. Clique em +
esquerda de &File para mostrar os submenus. Clique em
&Open\tCtrl+O. Clique no boto Edit. Em Eventos: OnMenu clique
no boto Create.

257

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Para criar a nova funo clique no boto OK.


No Menu Item Editor, clique nos botes Apply e OK.
Agora a vez do submenu &Save. Repete o mesmo procedimento
que usou para o submenu &Open.

O sistema montou o cdigo bsico para estas novas funes, mas


temos que acrescentar mais quatro linhas. Clique em
MeuEditorHTMLFrm.cpp no topo da janela de desenvolvimento de
programa. Veja os trechos abaixo:

258

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


/*
* Mnuopen1007Click
*/
void MeuEditorHTMLFrm::Mnuopen1007Click(wxCommandEvent&
event)
{
// insert your code here
Vamos colocar cdigo aqui...............
}
/*
* Mnusave1008Click
*/
void MeuEditorHTMLFrm::Mnusave1008Click(wxCommandEvent&
event)
{
// insert your code here
e aqui................................................
}
No caso de Mnuopen1007Click acrescentamos este cdigo:
if(WxOpenFileDialog1->ShowModal())
{
WxMemo1->LoadFile(WxOpenFileDialog1->GetPath());
}
No caso de Mnusave1008Click acrescentamos este cdigo:
if(WxSaveFileDialog1->ShowModal())
{
WxMemo1->SaveFile(WxSaveFileDialog1->GetPath());
}

259

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Veja o cdigo completo:

Seu primeiro projeto de caixa de dilogo foi realizado, e est


funcionando. Maravilha, no? Pressione F9 para admirar a sua obra
prima.
wxWidgets elaborou toda armao para construir nossa caixa de
dilogo. Ns apenas acrescentamos algumas linhas de cdigo que
define eventos. Chamarei as armaes de Frames se me permitir,
pois o nome utilizado pelo sistema nos programas, e dilogos
so tratados de modo diferenciados. Caixas de dilogo
normalmente so usadas para colher respostas ou apresentar
escolhas, e geralmente so de dimenses fixas e portanto
apresentadas de forma modal. J Frames so apresentadas como
janelas principais de aplicao, e podem ser compostas de menus,
barras de ferramentas e de status. Nesta parte vamos conhecer as
opes de propriedades dos dois tipos.

260

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Nosso segundo projeto:
Neste projeto vamos aprender como acrescentar
dilogos em uma aplicao, e como as utilizar.

frames

Nosso primeiro passo o de abrir um novo projeto, que vamos


chamar de MultiFrame.
Executar o IDE, wxDev-C++:
Clicar em Arquivo, Novo, Projeto.
Clicar wxWidgets Frame.
Inserir nome MultiFrame.
Criar nova pasta chamada de MultiFrame.
Salvar o projeto nesta pasta.
Clicar em Create.

261

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Vamos acrescentar novo frame e novo dilogo ao projeto. Para


isto, precisamos de um lugar onde podemos colocar o cdigo para
ativ-los.
Acrescentamos
dois
botes
no
quadro
de
trabalho/desenvolvimento, um para abrir novos frames, o outro
para abrir novos dilogos.
Caso no esteja visualizado seu quadro de desenvolvimento,
clique em MultiFrameFrm.wxform. Em seguida clique em
Componentes no Inspector das Propriedades. Abra o arquivo
Common Controls e clique em wxButton. Deposite o boto
escolhido no quadro de trabalho. Repetir para depositar o segundo
boto embaixo do primeiro.
Seu quadro dever ser parecido com este abaixo:

262

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Clique no WxButton1 para selecion-lo.


Clique em Inspector das Propriedades, Propriedades. Verifique
WxButton1:wxButton
no
Inspector.
Altere
as
seguintes
propriedades:
Largura 100, tecle Enter.
Esquerda 3, tecle Enter.
Topo 3, tecle Enter.
Label Abrir Novo &Frame, tecle Enter.
Vai ter que procurar
propriedades, pacincia.

estas

propriedades

nas

listas

de

Clique em Eventos. Clique em OnClick. Selecione <Add new


function>. Aparece o cdigo da nova funo chamada de
WxButton1Click
em
MultiFrameFrm.cpp.
Volte
para
MultiFrameFrm.wxform.

263

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Agora a vez do boto nmero 2. Clique nele para selecion-lo.
Em Propriedades altere os seguintes valores:
Esquerda 3, tecle Enter.
Topo 32, tecle Enter.
Largura 100, tecle Enter.
Label Abrir Novo &Dialog, tecle Enter.
Clique em Eventos:
Selecione OnClick <Add new function>.
A nova funo foi criada em MultiFrameFrm.cpp.
Selecione MultiFrameFrm.wxform novamente.
Clique num lugar vazio no quadro cinza-escuro. Verifique
MultiFrameFrm:wxFrame no Inspector das Propriedades.
Altere os valores de altura e largura em Propriedades:
Height 100, tecle Enter.
Width 200, tecle Enter.

Veja o resultado supra.


Vamos agora acrescentar mais um Frame.

264

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Clique em Arquivo, Novo, Novo wx Frame.
Aparece um Pop-up com a mensagem Adicionar nova unidade ao
projeto atual? Clique Sim.
Novo wxFrame: Alterar Class name NovoFrm.
Alterar File Name NovoFrm.
Alterar Title Novo Frame.
Clicar em Create.
Clique no cinza escuro de Novo Frame.
Em Propriedades, altere os valores de Height para 100 e Enter, o
de Width para 250 e Enter.
Clique em
+ Frame Style para abrir. Altere
wxFRAME_NO_TASKBAR de False para True.

valor

de

Clique em Componentes. Vamos acrescentar um boto. Clique em


wxButton e deposite este no palette de cinza escuro.
Clique no boto para selecion-lo. Clique em Propriedades. Altere
as seguintes propriedades do boto:
Esquerda 84
Topo 23
Label &FECHAR
Clique em Evento, OnClick, <Add New Function>. Aparece o cdigo
da nova funo. Procure a funo abaixo:
void NovoFrm::WxButton1Click(wxCommandEvent& event), depois
da linha // insert your code here , acrescente o texto Destroy();

265

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Acrescentamos esta funo que tm o propsito de fechar a janela
com segurana enquanto terminar a execuo de outros eventos.
Agora temos de incluir a funo que criamos como arquivo
cabealho no programa MultiFrameFrm.cpp.
Procure a linha no topo do programa //// Header Include End. Logo
embaixo desta, escreva #include "NovoFrm.h".
Isto permite que usamos a classe NovoFrm dentro da classe
MultiFrameFrm.cpp.
Tecle F9 para verificar o trabalho.
Em MultiFrameFrm.cpp procure as linhas de cdigo:
void MultiFrameFrm::WxButton1Click(wxCommandEvent &event).
Embaixo de // insert your code here
Inserir estas trs linhas:
// criar um novo frame
NovoFrm * TempFrame = new NovoFrm(this);
TempFrame->Show();
A segunda linha cria uma instncia da classe NovoFrm e a vincula
ao ponteiro de tipo NovoFrm. J a terceira linha visualiza o frame
recm-criado.

266

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Vamos agora acrescentar um novo dilogo.
Clique em Arquivo, Novo, Novo wxDialog.
Clique Sim para criar nova funo.
Altere Class Name para NovoDlg.
Altere File Name para NovoDlg.
Altere Title pare Novo Dialogo.
Clique no boto da opo No Parent para desativ-la.
Clique no boto da opo Stay On Top para ativ-la.
Clique no boto Create.
Vamos depositar dois botes no quadro cinza. Em Componentes
abra a pasta Common Controls. Clique em wxButton e deposite
este no quadro cinza. Repetir e deposite o segundo boto.
Selecione wxButton1 no quadro.
Em propriedades, ID Do Nome rolar at encontrar wxID_OK, clique
nesta opo.
Em Label escreva &OK.
Esquerda 12.
Topo 14.
Clique no wxButton2 no quadro.
Em propriedades, ID Do Nome rolar at encontrar wxID_CANCEL,
clique nesta opo.
Em Label escreva &Cancelar.
Esquerda 102.
Topo 14.
Clique numa parte vazia do quadro. Em propriedades, altere:
Height 80.
Width 200.

267

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Selecione MultiFrameFrm.cpp e acrescente estes dois arquivos de
cabealho embaixo de #include "NovoFrm.h":
#include "NovoDlg.h"
#include <wx/msgdlg.h>
Rolar o programa e acrescente:
NovoDlg TempDlg(this);
if(TempDlg.ShowModal() == wxID_OK)
{
wxMessageBox("OK");
}

O Nosso Novo Projeto HTML:


Bom, agora que aprendemos como acrescentar botes e cdigo,
podemos elaborar um projeto que realmente podemos usar. Nosso
primeiro projeto foi de elaborar um editor de HTML. Este novo
projeto vai montar um editor completo.
Chamaremos nosso projeto de MeuNovoEditorHTML.

268

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Execute o IDE.
Clique em Arquivo, Novo, Projeto.
Criar nova pasta de nome Meu Novo Editor HTML e salvar o
projeto.
Clique no boto Create.
Para dimensionar o tamanho, clique no quadro de trabalho e no
Inspector, Propriedades. Altere: Height 402, Width 553, no
esquea de entrar com os dados usando a tecla Enter.
Clique em Icon, Edit Picture. Clique no boto de trs pontos.
Aparece o Pop-up Picture Editor:

Clique o boto Load. Aparece este dilogo:

269

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Em Examinar: tecle o caminho. No meu caso, C:\Arquivos de


Programas\
Dev-Cpp\
TangoImages\16x16\internet-webbrowser16x16, e Abrir. A imagem estar no Pop-up Picture Editor
na janela Image. Clique OK para inserir a imagem internet-webbrowser16x16.png.
Tecle F9. A sua tela dever ser parecida com esta abaixo:

270

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Veja o cone que acabamos de importar que aparece ao lado do
nome no topo de nosso dilogo.
Iremos agora criar uma caixa de dilogo, chamado de caixa
sobre...(algum assunto).
Clique em Arquivo,
unidade...Sim.

Novo,

Novo

wxDialog,

Adicionar

nova

Novo wxDialog:
Class Name

CaixaSobreDlg

File Name

CaixaSobreDlg

Title

Sobre HTML

Author

Seu nome

Window
Style

Use Caption, System Menu,


No Parent, Close Button

Propriedades:
Height

281 [Enter]

Width

265 [Enter]

Vamos criar outra caixa de dilogo para inserir tabelas:


Clique em Arquivo,
unidade...Sim.

Novo,

Novo

wxDialog,

Adicionar

nova

271

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Novo wxDialog:
Class
Name

CriarTabelaDlg

File Name

CriarTabelaDlg

Title

Criar Tabela

Author

Seu nome

Window
Style

Use Caption, System Menu, No


Parent, Close Button, Minimize
Button

Propriedades:
Height

308

Width

236

Icon

Use internet-webbrowser16x16.png

Para no confundir o compilador, apesar que estes dilogos faam


parte de dois .cpp diferentes, seria bom alterar ID do Nome
ID_DIALOG2, o prximo, 3 e etc.
Vamos precisar de um lugar onde inserir imagens, e faremos isto
usando outro wxDialog:
Clique em Arquivo,
unidade...Sim.

Novo,

Novo

wxDialog,

Adicionar

nova

272

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Novo wxDialog:
Class Name

InseriImagemDlg

File Name

InserirImagemDlg

Title

Inserir Imagem

Author

Seu nome

Window Style Use Caption, System Menu,


No Parent, Close Button,
Minimize Button
Propriedades:
Height

224

Width

238

Icon

Use internet-webbrowser16x16.png

Vamos criar mais uma


hiperlinks ao documento:
Clique em Arquivo,
unidade...Sim.

caixa

Novo,

de

Novo

dilogo

wxDialog,

para acrescentar

Adicionar

nova

273

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Novo wxDialog
Class Name

InserirHiperlinkDlg

File Name

InserirHiperlinkDlg

Title

Inserir Hiperlink

Author

Seu nome

Window Style Use Caption, System Menu,


No Parent, Close Button,
Minimize Button
Propriedades
Height

154

Width

373

Icon

Usar applications-internet
16x16.png desta vez, da
pasta Tango Images

274

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Nesta altura seria bom salvar o projeto: Arquivo, Salvar Projeto


Como.....MeuNovoEditorHTML ou o nome que voc chamou o
projeto. Note que o projeto sempre possui extenso .dev.
Para as partes seguintes usaremos os controles do Graphics User
Interface, (GUI). Vamos ento elaborar esta parte antes de
acrescentar as linhas de cdigo de todas as partes que criamos.
No Project Inspector clique em MeuNovoEditorHTMLFrm.wxform.
Certifique que este que est no quadro.
Vamos criar nossa barra de ferramentas. Para isto clique em
Componentes, e abra a pasta Toolbars.
Clique no componente wxToolBar e deposite este no quadro de
desenvolvimento, (o quadro cinza). Selecione Propriedades e
Nome. Escreva o texto bfermPrincipal e [Enter].
Vamos agora popular nossa barra de ferramentas com alguns
componentes. Veja a lista abaixo:

275

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Na lista abaixo temos que importar a imagem da pasta Tango
Image selecionando Bitmap em Propriedades. O nome do cone
est na segunda coluna. Nesta coluna temos todo o texto que
devemos inserir com referncia ao componente selecionado. Para
depositar os botes na barra, selecione primeiro a barra. Clique
em Toolbars, e wxToolButton. Deposite o boto, ou Separator na
barra de ferramentas com alinhamento adequado. Vamos agora
inserir uma imagem na face do boto. Em Propriedades e Bitmap,
Load e o caminho para o arquivo Tango Images. Aps a primeira
transferncia, o caminho lembrado pelo sistema. Em
Propriedades e Name, escreva o nome i.e. btNovo sem espaos
entre palavras e [Enter]. Em Propriedades e Tooltip, o texto
indicado na listagem abaixo. Aps cada insero de Bitmap, salvar
o projeto para ter certeza que fez o update no programa.
Toolbars

wxToolButton

Propriedades,
Bitmap

document-new16x16.png

Name

btNovo

Propriedades,
Tooltip

Novo documento

Toolbars

wxToolButton

Propriedades,
Bitmap

document-open16x16.png

Name

btAbrir

Propriedades,
Tooltip

Abrir arquivo existente

Toolbars

wxToolButton

Propriedades,
Bitmap

document-save16x16.png

Nome

btSalvar

Propriedades
Tooltip

Salvar este documento

276

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Common Controls

wxSeparator

Toolbars

wxToolButton

Propriedades,
Bitmap

document-print16x16.png

Nome

btImprimir

Propriedades
Tooltip

Imprimir este documento

Toolbars

wxToolButton

Propriedades,
Bitmap

document-print-preview16x16.png

Nome

btVisImp

Propriedades,
Tooltip

Visualizar impresso

Common Controls

wxSeparator

Toolbars

wxToolButton

Propriedades,
Bitmap

edit-undo16x16.png

Nome

btDesfazer

Propriedades,
Tooltip

Desfazer

Toolbars

wxToolButton

Propriedades,
Bitmap

edit-redo16x16.png

Nome

btRefazer

Propriedades,
Tooltip

Refazer

Common Controls

wxSeparator

Toolbars
Items

wxComboBox
Titulo
Titulo
Titulo
Titulo
Titulo

1
2
3
4
5

277

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Titulo 6
Name

cmbTitulo

Texto

Titulo 1

Tooltip

Alterar Titulo

Toolbars

wxToolButton

Propriedades,
Bitmap

format-justify-left16x16.png

Nome

btAlinharEsquerda

Propriedades,
Tooltip

Alinhar a esquerda

Toolbars

wxToolButton

Propriedades,
Bitmap

format-justify-center16x16.png

Nome

btAlinharCentro

Propriedades,
Tooltip

Alinhar ao centro

Toolbars

wxToolButton

Propriedades,
Bitmap

format-justify-right16x16.png

Nome

btAlinharDireita

Propriedades,
Tooltip

Alinhar a direita

Aps todo este trabalho seu quadro dever ser parecido com o
abaixo, s que bem mais comprido. Cortei para mostrar as partes
interessantes.

278

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Vamos agora acrescentar uma
MeuNovoEditorHTMLFrm.wxform.

barra

de

status.

Selecione

V em Componentes, Common Controls e selecione wxStatusBar e


deposite no quadro. A barra automaticamente colocada na parte
inferior do quadro. Em Inspector das Propriedades, Propriedades,
selecione Nome e escreva bstInfo.
Note nesta altura que quando nos referimos Sizer, estamos
falando do programa que altera automaticamente as dimenses
dos quadros e janelas quando so preenchidos com textos ou
imagens, mas temos que manter as dimenses dos cones e o
texto constantes. Faremos isto agora.
Em Componentes abra o arquivo Sizers. Selecione wxBoxSizer e
deposite este no quadro. Note que este tomou todo o quadro. Em
Propriedades, Nome escreva szPrincipal. Logo abaixo deste,
verifique Orientation, wxHorizontal.
Vamos agora criar uma barra de ferramentas em sentido vertical
ao lado esquerdo do sizer no quadro.
No temos disponvel um Toolbar vertical, ento temos de criar a
barra e os botes usando outros meios.
Clique no quadro do sizer. Em Componentes abra a pasta
Containers e selecione wxPanel. Deposite este no sizer. Em
Propriedades clique no + de Alinhamento. Selecione wxEXPAND e
clique em TRUE. Certifique que todos os outros do grupo possuem
estado FALSE. Altere Altura para 278 e Largura para 36. Em Nome
escreva pnlLado.
Agora vamos colocar os botes nesta barra.

279

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Em Componentes abra a pasta Common Controls. Selecione
wxButton e o deposite no topo da barra vertical. Em Propriedades
clique em Altura, escreva 30, em Esquerda escreva 3, Largura
escreva 30, em Nome escreva btNegrito, em Label escreva N, em
Tooltip escreva Negrito, em Topo escreva 3, em Fonte no boto de
trs pontos selecione Arial Black, tamanho 10, OK.
Os outros botes devem ser inseridos e acertadas as seguintes
propriedades:
Common Controls

wxButton

Fonte

Times New Roman, Negrito e


Italico, size 11

Altura

30

Label

Esquerda

Nome

btItalicos

Tooltip

Italicos

Topo

33

Largura

30

Common Controls

wxButton

Fonte

Arial, Negrito, 12, Sublinhado

Altura

30

Label

Esquerda

Nome

btSublinhar

Tooltip

Sublinhar

Topo

63

Largura

30

Common Controls

wxButton

Fonte

Times New Roman, Negrito, Tam


12

280

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Altura

30

Label

Esquerda

Nome

btFonte

Tooltip

Estilo fonte

Topo

93

Largura

30

Common Controls

wxButton

Fonte

Courier, Negrito, Tamanho 15

Altura

30

Label

Esquerda

Nome

btInserirLinhaHorizontal

Tooltip

Inserir linha horizontal

Topo

123

Largura

30

Common Controls

wxButton

Fonte

Courier, Negrito, Tamanho 12

Altura

30

Label

Esquerda

Nome

btPontoAncora

Tooltip

Criar ponto ancora

Topo

153

Largura

30

Common Controls

wxButton

Fonte

Times New Roman, Negrito e


Italico, Riscado, Tamanho 12

Altura

30

Label

Esquerda

281

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Nome

btCriarHiperlink

Tooltip

Criar hiperlink

Topo

183

Largura

30

Common Controls

wxBitMapButton

Tango Images

Applications-other16x16

Altura

30

Esquerda

Nome

btInserirTabela

Tooltip

Inserir tabela

Topo

213

Largura

30

Common Controls

wxBitmapButton

Tango Image

image-x-generic16x16

Button Style

[wxBU_AUTODRAW]

Altura

30

Esquerda

Nome

btInserirImagem

Tooltip

Inserir imagem

Topo

243

Largura

30

Vamos agora acrescentar um componente bloco de anotaes


composto de duas pginas, uma de previsualizao, e de edio, a
outra pgina de apenas previsualizao.

282

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Em Project Inspector selecione MeuNovoEditorHTMLFrm.wxform.
Clique em wxBoxsizer no quadro. Em Componentes selecione a
pasta Containers. Selecione wxNotebook e deposite no
wxBoxsizer.
Em Propriedades selecione Nome e escreva edtAnota. Em +
Alinhamento selecione wxEXPAND e clique em TRUE, todas as
outras FALSE. Em Robordo escreva 0. Altere a Altura para 275,
Largura para 460. Em Fator de Alongamento, 1.
Vamos agora acrescentar as duas pginas.
Clique em edtAnota. Em Componentes selecione a pasta
Containers e wxNotebookPage. Deposite este no edtAnota. Nesta
altura seria bom frizar que para ter certeza que estamos alterando
as propriedades do elemento correto, temos que selecionar o tab,
e depois clicar na pgina que desejamos alterar. Em Propriedades
selecione Nome, escreva pnbPreVisualizarCombinado. Clique em
Label, escreva Previsualizar Combinado. Selecione edtAnota. Em
Componentes selecione outra wxNotebookPage e a deposite no
edtAnota. Clique no tab wxNotebookPage1 da pgina que acabou
de depositar. Clique na pgina que aparece. Em Nome e Label,
pnbPreVisualizar e Previsualizar respectivamente.
Bom, criamos as pginas. Agora temos que fazer a edio dos
controles.
Clique no tab Previsualizar Combinado. Clique na pgina para
selecion-la. Em Componentes seleciona a pasta Sizers. Clique em
wxBoxSizer e o deposite na pgina. Em Propriedades selecione
Name, escreva szrVisComb. Verifique Orientation wxHorizontal.
Em Componentes, Containers selecione wxSplitterWindow e o
deposite na pgina.

283

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Em Propriedades, clique em + Alinhamento e selecione wxEXPAND
e TRUE. Altere para FALSE todas as outras. Escreva Rebordo, 0.
Altere Altura e Largura para 248 e 195 respectivamente. Altere a
propriedade Nome para sptPreVisComb. Altere a propriedade
Orientation para wxVertical e o Fator de Alongamento para 1.
Em seguida v em Componentes, Containers se j no estiver l,
selecione wxHtmlWindow e o deposite no mesmo Splitter. Em
Propriedades altere Nome para htmwPreVisComb, Altura 89 e
Largura 185.
Em Componentes abra a pasta Common Controls. Selecione
wxMemo e o deposite no Splitter. Em Propriedades, altere Nome
para mmoEditorTexto. Altere Altura e Largura para 139 e 185
respectivamente. Selecione Strings, Edit Strings e na janela
deletar o texto que aparece. Deixe em branco. Clique OK.
Selecione o tab Previsualizar e clique na janela para selecion-la.
Em Componentes abra a pasta Sizers e selecione wxBoxSizer.
Deposite este na janela. Em Propriedades, Nome altere o texto
para szrPreVisualizar. Em Componentes selecione a pasta
Containers e wxHTMLWindow. Deposite este na janela do
Previsualizador.
Em
Propriedades
altere
Nome
para
htmwPreVisualizar.
Em + Alinhamento selecione wxEXPAND, TRUE, todas as outras
FALSE. Rebordo 0, e Fator de Alongamento 1. Nesta altura seria
bom salvar o projeto. Aps, tecle F9 para compilar e executar. Se
o compilador reclamar de algum boto, carregar novamente a
imagem do boto em questo, e salvar o projeto.
Vamos agora criar uma barra para o menu. Clique no quadro
szPrincipal. Em Componentes, abra a pasta Menubars e selecione
wxMenuBar. Deposite este num lugar desocupado do quadro.
Clique em Propriedades e Name. Altere o nome para mnuPrincipal.

284

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Com mnuPrincipal selecionado, clique em Menu Items. Clique no
boto de trs pontos. Abre a janela Menu Item Editor. A seguir
consta uma lista de todos os controles do menu. Vou fazer o
primeiro, e o resto por sua conta. Clique em Add Item. Type,
escolhe Menu Item. Caption escrever &Arquivo, [Enter]. ID Name e
ID Value sero criados de acordo com o padro que o sistema
gera. Clique em Apply. Para o segundo item, clique em Create
Submenu. Para inserir um Bitmap, clique em Browse e escreva o
caminho para a pasta Tango Images. Insere os controles de
acordo com a lista abaixo. Aps completar cada etapa clique no
boto Apply. Se errar, comea novamente com &Arquivo.
Properties:
Type

Escolher Menu Item

Selecione

Add Item

Caption

&Arquivo

ID Name

Aceitar o padro

ID Value

Aceitar o padro

Type

Menu Item

Selecione

Clique Submenu

Caption

&Novo\tCtrl+N

ID Name

wxID_NEW

ID Value

Aceitar o padro

Hint

Criar novo documento

Bitmap Tango Images

document-new16x16.png

Type

Escolher Menu Item

Selecione

Clique Sub Menu

Caption

&Abrir\tCtrl+A

285

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


ID Name

wxID_OPEN

ID Value

Aceitar o padro

Hint

Abrir um documento

Bitmap Tango Images

document-open16x16.png

Type

Escolher Menu Item

Selecione

Clique em Sub Menu

Caption

&Salvar\tCtrl+S

ID Name

wxID_SAVE

ID Value

Aceitar o padro

Hint

Salvar documento

Bitmap

document-save16x16.png

Type

Escolher Separator

Selecione

Clique Submenu

ID Name

Aceitar o padro

ID Value

Aceitar o padro

Type

Escolher File History

Selecione

Clique Submenu

ID Name

Aceitar padro

ID Value

Aceitar padro

Type

Escolher Separator

Selecione

Clique Submenu

ID Name

Aceitar padro

ID Value

Aceitar padro

Type

Menu Item

286

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Selecione

Clique Submenu

Caption

PageSet&up

ID Name

wxID_PAGE_SETUP

ID Value

Aceitar padro

Hint

Configurar pagina

Bitmap

document-properties16x16.png

Type

Escolher Menu Item

Selecione

Clique Submenu

Caption

PrintPre&view

ID Name

wxID_PREVIEW

ID Value

Aceitar padro

Hint

Previsualizar impressora

Bitmap

document-printpreview16x16.png

Type

Escolher Menu Item

Selecione

Clique Submenu

Caption

&Imprimir\tCtrl+I

ID Name

wxID_PRINT

ID Value

Aceitar padro

Hint

Imprimir documento

Bitmap

document-print16x16.png

Type

Escolher Separator

Selecione

Clique Submenu

ID Name

Aceitar padro

287

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


ID Value

Aceitar padro

Type

Escolher Menu Item

Selecione

Clique Submenu

Caption

E&xit

ID Name

wxID_EXIT

ID Value

Aceitar padro

Hint

Sair

Bitmap

process-stop16x16.png

Type

Escolhe Menu Item

Selecione

Clique Add Item

Caption

&Edit

ID Name

wxID_EDIT

ID Value

(Aceitar padro)

Type

Escolhe Menu Item

Selecione

Clique Submenu

Caption

&Desfazer\tCtrl+D

ID Name

wxID_UNDO

ID Value

Aceitar padro

Hint

Desfazer ltima

Bitmap

edit-undo16x16.png

Type

Escolher Menu Item

Selecione

Clique Submenu

Caption

&Refazer\tCtrl+R

ID Name

wxID_REDO

288

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


ID Value

Aceitar padro

Hint

Refazer ltima

Bitmap

edit-redo16x16.png

Type

Escolhe Separator

Selecione

Clique Submenu

ID Name

Aceite padro

ID Value

Aceite padro

Type

Escolhe Menu Item

Selecione

Clique Submenu

Caption

Cu&t\tCtrl+X

ID Name

wxID_CUT

ID Value

Aceite padro

Hint

Cortar texto selecionado

Bitmap

edit-cut16x16.png

Type

Escolhe Menu Item

Selecione

Clique Submenu

Caption

&Copiar\tCtrl+C

ID Name

wxID_COPY

ID Value

Aceitar padro

Hint

Copiar texto selecionado

Bitmap

edit-copy16x16.png

Type

Escolhe Menu Item

Selecione

Clique Submenu

Caption

&Colar\tCtrl+V

289

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


ID Name

wxID_PASTE

ID Value

Aceite padro

Hint

Colar texto

Bitmap

edit-paste16x16.png

Type

Escolhe Menu Item

Selecione

Clique Add Item

Caption

&Ajuda

ID Name

wxID_HELP

ID Value

Aceite padro

Type

Escolhe Menu Item

Selecione

Clique Submenu

Caption

&Sobre

ID Name

wxID_ABOUT

ID Value

Aceite padro

Hint

Visualizar a caixa sobre

Bitmap

dialog-information16x16.png

Clique OK para terminar.


Bom, depois disto tudo, cumprir um turno de 24 horas seria fcil
em comparao. Seria bom neste momento salvar o projeto.
Depois de um bom descano podemos acrescentar os dilogos.
Voc poder estar sentindo que depois de todo este trabalho, vai
querer compilar. OK, F9 nele, mas ver que no mudou muito.

290

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Seu MeuNovoEditorHTML compilado dever ser parecido com este
abaixo:

Selecione szPrincipal. Vamos agora acrescentar os dilogos.


Selecione Componentes e abra a pasta Dialogs. Clique em
wxOpenFileDialog e o deposite no szPrincipal. Em Propriedades,
altere Extensions para *.htm; *.html, Name para dlgAbrirPasta e
Message para Abrir Pasta.
Em Componentes, Dialogs, selecione wxSaveFileDialog e o
deposite ao lado do anterior. Em Propriedades, Extensions escreva
*.htm; *.html, em Message, Salvar Pasta e em Name,
dlgSalvarPasta.
Em Componentes, Dialogs, selecione wxFontDialog e o deposite
junto aos outros. Em Propriedades, Name escreva dlgFonte.

291

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Em Componentes, abra a pasta Components. Selecione
wxHtmlEasyPrinting e o deposite junto aos outros. Em Footer
String escreva Imprimido usando MeuNovoEditorHTML - @DATE@ pagina @PAGENUM@ - de @PAGESCNT@ - pginas. Em Header
String escreva @TITLE@, em Name, dlgImprimir, em Title, Imprimir
HTML.
Em
Componentes,
abra
a
pasta
Dialogs
e
selecione
wxMessageDialog. Deposite junto aos outros. Em Propriedades,
Caption escrever Salvar Alterao?. Em Message, O conteudo da
pasta mudou/ndeseja salv-la?. Em + Message Dialog Style,
selecione TRUE nestes trs estilos, wxICON_EXCLAMATION,
wxYES_DEFAULT e wxYES_NO. Em Name, dlgSalvarAlt.
Veja abaixo o quadro de desenvolvimento:

292

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Feito isto vamos criar nossa caixa de dilogo Sobre.
Em Project Inspector, Projeto, selecione CaixaSobreDlg.wxform.
Caso este no est incluido no topo do quadro, clique em Arquivo,
Novo, Salvar Projeto como... Na pasta do projeto ver
CaixaSobreDlg.wxform e os outros. Clique nestes duas vezes para
inclu-los. Primeiro vamos inserir uma imagem no quadro. Uma
imagem poder estar em formato bitmap ou .png. A que usei baixei
na Internet. Basta salvar a imagem de sua preferncia no arquivo
Tango Images.
Em Componentes, abra o arquivo Common Controls e selecione
wxStaticBitmap. Deposite este no quadro Sobre HTML. Em
Propriedades clique Cor de Fundo e no boto de trs pontos
escolhe Use Standard Color e White no dilogo que aparece.
Clique OK. Clique em Picture e navegue at a imagem que deseja
usar. Clique Abrir e OK para inserir a imagem no quadro.
Agora temos que dimensionar o tamanho da imagem. Em Largura
altere o valor para 249 (pixels). Em Altura, 145.
Esquerda,
4.
Selecione
Estilos
Gerais,
selecione
wxSUNKEN_BORDER e TRUE. Altere Topo para 3. Em Nome,
bmpSplash. A imagem est pronta.
Agora vamos inserir uma caixa onde mostramos detalhes sobre
este projeto.
Em Componentes abra a pasta Common Controls. Altere os
componentes e as propriedades de acordo com a lista abaixo:

293

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Common Controls

wxStaticBox

Caption

Sobre Este Editor

Altura

71

Esquerda

Nome

stbCaixaInfo

Topo

150

Largura

250

Common Controls

wxStaticText

Altura

17

Label

Autor:

Esquerda

Nome

txtAutor

Topo

167

Largura

38

Common Controls

wxStaticText

Altura

17

Label

Contato:

Esquerda

Nome

txtContato

Topo

182

Largura

50

Common Controls

wxStaticText

Altura

17

Label

Icones:

Esquerda

Nome

txtIcones

Topo

198

Largura

40

Common Controls

wxStaticText

294

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Altura

17

Label

(Inserir seu nome):

Esquerda

77

Nome

txtNome

Topo

167

Largura

30

Common Controls

wxStaticText

Altura

17

Label

(use um endereo email)

Esquerda

77

Nome

txtEmail

Topo

182

Largura

141

Common Controls

wxHyperLinkCtrl

Altura

17

Label

(URL de sua escolha)

Esquerda

77

Nome

cnthiperlink

Topo

198

Largura

89

Common Controls

wxButton

Height

28

ID Name

wxID_CLOSE

Label

Fechar

Esquerda

81

Nome

btFechar

Topo

224

Largura

90

Seu quadro dever ser parecido com este, abaixo:

295

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Agora podemos elaborar nosso dilogo de inserir hiperlink. Em


Projecto selecione HiperlinkDlg.wxform. Vamos elaborar uma
caixa onde colocaremos nossos controles:
Com
dilogo
Inserir
Hiperlink
selecionado,
clique
em
Componentes, Common Controls, wxStaticBox e o deposite no
quadro. Preenche os controles e as propriedades de acordo com
os seguintes:

296

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Propriedades:
Caption

Local do link

Altura

75

Esquerda

11

Nome

stbLocalLink

Topo

Largura

342

Common
Controls

wxStaticText

Altura

17

Label

Entre com a URL ou escolhe um da


caixa Drop Down

Esquerda

18

Nome

txtEncontreLink

Topo

25

Width

322

Common
Controls

ComboBox

Altura

21

Esquerda

19

Nome

cmbHiperLink

Texto

(Em branco)

Topo

43

Largura

322

Common
Controls

wxButton

Altura

27

ID do Nome

wxID_OK

Label

OK

Esquerda

12

297

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Nome

btOK

Topo

88

Largura

91

Common
Controls

wxButton

Altura

27

ID do Nome

wxID_CANCEL

Label

Cancelar

Esquerda

250

Nome

btCancelar

Topo

88

Largura

101

Veja nosso dilogo abaixo:

298

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


esta altura estamos quase acabando nosso projeto. Resta criar
o dilogo de tabelas e o de inserir imagens. No final vamos inserir
as linhas de cdigo que fazem tudo funcionar. Salve o projeto e
vamos em frente.
Em Project Inspector, Projeto selecione CriarTabelaDlg.wxform.
Voc poder posicionar os componentes da maneira que escolher.
Os que esto nestas tabelas servem como guia, mas se quiser
mover um componente para cima um pouco, ou para o lado sua
escolha.
Vamos inserir os componentes e determinar as propriedades de
acordo com a tabela abaixo:
Containers

wxPanel

Nome

pnlFundo

Largura

225

Altura

281

Common
Controls

wxStaticText

Altura

17

Label

Fileiras

Esquerda

Nome

txtFileiras

Topo

Largura

36

Common
Controls

wxStaticText

Height

17

Label

Espaamento

Esquerda

100

Nome

txtEsp

299

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Topo

Largura

70

Common
Controls

wxStaticText

Altura

17

Label

Colunas

Esquerda

Nome

txtCols

Topo

34

Largura

40

Common
Controls

wxStaticText

Altura

17

Label

Enchimento

Esquerda

100

Nome

txtEnchimento

Topo

32

Largura

63

Common
Controls

wxStaticText

Altura

17

Label

Borda

Esquerda

Nome

txtBorda

Topo

55

Largura

35

Common
Controls

wxStaticText

Altura

17

Label

Largura

Esquerda

100

Nome

txtLargura

300

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Topo

59

Largura

75

Common
Controls

wxSpinCtrl

Altura

22

Esquerda

41

Maximum Value

100

Minimum Value

Nome

spnFileiras

Topo

Valor

Largura

53

Common
Controls

wxSpinCtrl

Altura

22

Esquerda

166

Maximum Value

100

Minimum Value

Nome

spnEsp

Topo

Valor

Largura

55

Common
Controls

wxSpinCtrl

Altura

22

Esquerda

45

Maximum Value

100

Minimum Value

Nome

spnCols

Topo

29

Valor

Largura

53
301

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Common
Controls

wxSpinCtrl

Altura

22

Esquerda

168

Maximum Value

100

Minimum Value

Nome

spcEnchimento

Topo

29

Valor

Largura

53

Common
Controls

wxSpinCtrl

Altura

22

Esquerda

45

Maximum Value

100

Minimum Value

Nome

spnBorda

Topo

53

Valor

Largura

53

Common
Controls

wxSpinCtrl

Altura

22

Esquerda

168

Maximum Value

100

Minimum Value

Nome

spnLargura

Topo

53

Valor

Largura

55

Common
Controls

wxRadioBox

302

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Caption

Alinhar

Altura

43

Itens

Esquerda
Centro
Direita

Esquerda

Major Dimension

Nome

rdbAlinhar

Radiobox Style

wxRA_SPECIFY_ROWS

Selected Button

Topo

80

Largura

230

Common
Controls

wxRadioBox

Caption

Fundo

Altura

43

Itens

Use Cor
Use Imagem

Esquerda

Major Dimension

Nome

rdbFundo

Radiobox Style

wxRA_SPECIFY_ROWS

Selected Button

Topo

130

Largura

230

Containers

wxPanel

Altura

20

Esquerda

Nome

pnlCor

Estilos Gerais

wxSIMPLE_BORDER

Topo

174

Largura

88

303

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Common
Controls

wxEdit

Altura

19

Esquerda

98

Nome

edtFonteImagem

Texto

(Deixar em branco)

Topo

174

Largura

124

Common
Controls

wxButton

Altura

26

Label

Escolher Cor

Esquerda

Nome

btEscolherCor

Topo

201

Largura

88

Common
Controls

wxButton

Height

26

Label

Escolher Imagem

Esquerda

134

Nome

btEscolherImagem

Topo

201

Largura

88

Common
Controls

wxStaticLine

Left

Length

230

Name

stlSeparador

Orientation

wxLI_HORIZONTAL

Top

235

Common

wxButton

304

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Controls
Altura

26

ID do Nome

wxID_OK

Label

OK

Esquerda

20

Nome

btOK

Topo

248

Largura

75

Common
Controls

wxButton

Altura

26

ID do Nome

wxID_CANCEL

Label

Cancelar

Esquerda

147

Nome

btCancelar

Topo

248

Largura

75

Dialogs

wxColorDialog

Name

dlgEscolherCor

Dialogs

wxOpenFileDialog

Message

Escolhe um arquivo imagem

Name

dlgEscolherImagem

Seu Criar TabelaDlg.wxform dever ser semelhante a este abaixo:

305

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Falta elaborar o dilogo de inserir imagens. Selecione Inserir


ImagensDlg.wxform. Vamos popular nosso quadro de acordo com
os seguintes:

Common Controls

wxStaticText

Altura

17

Label

Altura

Esquerda

Nome

txtAltura

Topo

Largura

35

Common Controls

wxStaticText

Largura

17

Label

Largura

Esquerda

Nome

txtLargura

Topo

40

Largura

42

Common Controls

wxStaticText
306

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Altura

17

Label

Borda

Esquerda

Nome

txtBorda

Topo

69

Largura

35

Common Controls

wxStaticText

Altura

17

Label

Fonte Imagem

Esquerda

Nome

txtFonteImagem

Topo

97

Largura

73

Common Controls

wxStaticText

Altura

17

Label

Texto alternativo

Esquerda

Nome

txtTextoAlternativo

Topo

124

Largura

87

Common Controls

wxSpinCtrl

Altura

22

Esquerda

48

Valor Max

3000

Valor Min

Nome

spnAltura

Topo

Valor

100

Largura

63

Common Controls

wxSpinCtrl

Altura

22

307

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Esquerda

48

Valor Max

3000

Valor Min

Nome

spnLargura

Topo

37

Valor

100

Largura

63

Common Controls

wxSpinCtrl

Altura

22

Esquerda

48

Valor Max

3000

Valor Min

Nome

spnBorda

Topo

66

Valor

Largura

63

Common Controls

wxStaticBitmap

Altura

84

Esquerda

120

Nome

imgPreVisualizar

Topo

Largura

106

Common Controls

wxEdit

Altura

19

Esquerda

85

Nome

edtFonteImagem

Text

(deixar em branco)

Topo

95

Largura

140

Common Controls

wxEdit

Altura

19

308

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Esquerda

90

Nome

edtTextoAlternativo

Texto

(deixar em branco)

Topo

122

Largura

136

Common Controls

wxButton

Altura

21

Label

Navegar

Esquerda

90

Nome

btNavegar

Topo

145

Largura

60

Common Controls

wxButton

Altura

21

ID do Nome

wxID_OK

Label

OK

Esquerda

10

Nome

btOK

Topo

173

Largura

60

Common Controls

wxButton

Altura

21

ID do Nome

wxID_CANCEL

Label

Cancelar

Esquerda

162

Nome

btCancelar

Topo

173

Largura

60

Dialog

wxOpenFileDialog

Message

Selecione um arquivo imagem

Nome

dlgEscArqImagem

309

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Seu quadro dever ser parecido com este abaixo:

No momento temos todos os botes, dilogos e barras de rolagem.


Agora temos de acrescentar algumas linhas de cdigo para dizer
ao sistema exatamente como todos estes componentes devem
funcionar.
Comearemos pelos dilogos, especificamente o de inserir um
hiperlink. Nosso programa principal no tm acesso diretamente
ao dilogo, ento teremos de lhe dar acesso este:
Selecione InserirHiperlinkDlg.h. Logo depois da
CreateGUIControls (), escreva as seguintes linhas:

linha

void

public:
const wxString GetHyperlink(){return cmbHiperLink->GetValue();};
void SetHyperlinks(const wxArrayString AnchorArray){cmbHiperLink>Append(AnchorArray);};

310

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


OK, agora vamos escrever o cdigo para fazer funcionar nosso
dilogo de inserir imagens:
Selecione InserirImagemDlg.h. Logo depois da linha
CreateGUIControls () deste, acrescente o cdiga seguir:

void

public:
const int GetImageWidth(){return spnLargura->GetValue();};
const int GetImageHeight(){return spnAltura->GetValue();};
const int GetBorderWidth(){return spnBorda->GetValue();};
const wxString edtFonteImagem(){return txtFonteImagem->GetValue();};
const wxString edtTextoAlternativo(){return txtTextoAlternativo>GetValue();};
Temos um boto chamado btNavegar no dilogo de Inserir
Imagem. Selecione InserirImagemDlg.wxform, e clique no boto
supra. Com este selecionado v no Inspector das Propriedades e
clique em Events. Selecione a opo OnClick, e do drop-down
escolhe <Add New Function>. A funo automaticamente
montada. Depois da linha // insert your code here, escreva estas
linhas de cdigo:
if(WxOpenFileDialog1->ShowModal())
{
wxFileName TempFilename(dlgSelArqImagem->GetPath());
//Extrair a extenso para o arquivo
wxString TempExtensionString(TempFilename.GetExt());
wxBitmap TempBitmap;
//Use-a para decidir que tipo de arquivo utilizar
if(TempExtensionString.CmpNoCase(wxT("PNG")) == 0)
{
TempBitmap.LoadFile(dlgSelArqImagem>GetPath(),wxBITMAP_TYPE_PNG);
}
else if((TempExtensionString.CmpNoCase(wxT("JPG")) == 0) ||
(TempExtensionString.CmpNoCase(wxT("JPEG")) == 0))
{
TempBitmap.LoadFile(dlgSelArqImagem>GetPath(),wxBITMAP_TYPE_JPEG);
}

311

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


else if(TempExtensionString.CmpNoCase(wxT("GIF")) == 0)
{
TempBitmap.LoadFile(dlgSelArqImagem>GetPath(),wxBITMAP_TYPE_GIF);
}
//Preencher os valores
spnAltura->SetValue(TempBitmap.GetHeight());
spnLargura->SetValue(TempBitmap.GetWidth());
edtFonteImagem->SetValue(dlgSelArqImagem->GetPath());
//Mostrar uma pr-visualizao da imagem
imgPreVis->SetBitmap(TempBitmap);
}
Logo aps //// Header Include End, incluir esta linha:
#include <wx/filename.h>
Resta escrever o cdigo para criar a tabela. Selecione Criar
TabelaDlg.h. Embaixo da funo CreateGUIControls(), inserir o
cdigo abaixo:
public:
const int GetRows(){return spnFileiras->GetValue();};
const int GetCols(){return spnColunas->GetValue();};
const int GetBorderSize(){return spnBorda->GetValue();};
const int GetCellSpacing(){return spnEsp->GetValue();};
const int GetCellPadding(){return spnEnchimento->GetValue();};
const int GetTableWidth(){return spnLargura->GetValue();};
const wxString GetTableAlignment(){return rdbAlinhamento>GetStringSelection();};
const bool IsColourSelected(){return rdbFundo->GetSelection() ==
0?true:false;};
const bool IsImageSelected(){return rdbFundo->GetSelection() ==
1?true:false;};
const wxString GetColour(){return pnlCor>GetBackgroundColour().GetAsString(wxC2S_HTML_SYNTAX);};
const wxString GetImage(){return edtFonteImagem->GetValue();};

312

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Temos de ativar nosso boto de Escolher Cor. Selecione
CriarTabelaDlg.wxform. Clique no boto Escolher Cor. Em
Propriedades clique em Eventos, e o boto de trs pontos.
Selecione <add new funtion>. Clique no evento OnClick. Rolar o
programa at a linha // insert your code here. Embaixo desta linha
escreva este cdigo:
if(dlgEscolherCor->ShowModal() == wxID_OK)
{
//Configurar a cor de fundo do painel
pnlCor->SetBackgroundColour(dlgEscolherCor>GetColourData().GetColour());
//Mostrar a nova cor
pnlCor->Refresh();
//Configurar o boto
rdbFundo->SetSelection(0);
}
Agora selecione o boto Escolher Imagem. Em Propriedades,
Eventos, selecione <add new function> e clique no evento OnClick.
Rolar a nova funo at // insert your code here. Escreva o cdigo
abaixo:
if(dlgEscArqImagem->ShowModal() == wxID_OK)
{
edtFonteImagem->SetValue(dlgEscArqImagem->GetPath());
//Configurar o boto para usar a imagem
rdbFundo->SetSelection(1);
}
Depois de tudo isto, temos ainda o Frame principal. Seria uma boa
hora para tomar aquele ch de erva doce e relaxar.

313

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Vamos comear? Ok, ento selecione MeuNovoEditorHTMLfrm.h.
Escreva estas linhas de cdigo logo aps a funo
CreateGUIControls:
public:
void UpdateHTML();
void OpenFile();
void SaveFile();
void NewFile();
bool DoFileSaveCheck();
void WrapTextInTag(const wxString& TagType);
void InsertText(const wxString& Text);
Aps a linha ////GUI Controls Declaration End, acrescente esta
linha:
wxString MRUFile;
Selecione MeuNovoEditorHTMLFrm.cpp, e logo antes do fim deste
programa, escreva as linhas de cdigo:
void MeuNovoEditorHTMLFrm::UpdateHTML()
{
//Fazer update do texto
htmVisComb->SetPage(mmoEditorTexto->GetValue());
htmPreVis->SetPage(mmoEditorTexto->GetValue());
//Algo diferente ento marcar o texto atual
mmoEditorTexto->MarkDirty();
}
void MeuNovoEditorHTMLFrm::OpenFile()
{
// Verificar se temos um arquivo para salvar antes
if(DoFileSaveCheck())
{
//Mostre o dilogo abrir pasta
if(dlgAbrirPasta->ShowModal() != wxID_CANCEL)
{

314

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


//Se temos uma pasta, acrescente ao histrico
if(!MRUFile.IsEmpty())
{
m_fileHistory->AddFileToHistory(MRUFile);
}
//Carregar um arquivo
mmoEditorTexto->LoadFile(dlgAbrirPasta->GetPath());
//Salvar o caminho
MRUFile = dlgAbrirPasta->GetPath();
//Update previsualizador
UpdateHTML();
//Limpar editor
mmoEditorText->DiscardEdits();
}
}
}
void MeuNovoEditorHTMLFrm::SaveFile()
{
//Selecionar o arquivo a salvar
dlgSalvarArquivo->SetFilename(MRUFile);
if(dlgSalvarArquivo->ShowModal() != wxID_CANCEL)
{
//Salvar arquivo e acrescentar histrico de mais usado
mmoEditorTexto->SaveFile(dlgSalvarArquivo->GetPath());
MRUFile = dlgSalvarArquivo->GetPath();
m_fileHistory->AddFileToHistory(dlgSalvarArquivo->GetPath());
}
}
void MeuNovoEditorHTMLFrm::NewFile()
{
//Verificar se precisamos salvar o arquivo
if(DoFileSaveCheck())
{
//Limpar texto
mmoEditorTexto->Clear();
UpdateHTML();
mmoEditorTexto->DiscardEdits();
}
}

315

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


bool MeuNovoEditorHTMLFrm::DoFileSaveCheck()
{
bool RetVal = true;
//Caso tenhamos texto no salvo no editor
if(mmoEditorTexto->IsModified())
{
//Verificar se devemos salvar
if(dlgSalvarAlt->ShowModal() == wxID_YES)
{
//Configurar um nome padro para arquivo
dlgSalvarPasta->SetFilename(MRUFile);
if(dlgSalvarPasta->ShowModal() != wxID_CANCEL)
{
mmoEditorTexto->SaveFile(dlgSalvarPasta->GetPath());
MRUFile = dlgSalvarPasta->GetPath();
//Acrescente lista de pastas recm-usadas
m_fileHistory->AddFileToHistory(MRUFile);
}
else
RetVal = false;
}
}
else
{
if(!MRUFile.IsEmpty())
{
m_fileHistory->AddFileToHistory(MRUFile);
}
}
return RetVal;
}
void MeuNovoEditorHTMLFrm::WrapTextInTag(const wxString& TagType)

316

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


{
//Criar variveis para fixar posio do texto
long PosFrom = 0, PosTo = 0;
//Obter localizao do texto selecionado
mmoEditorTexto->GetSelection(&PosFrom,&PosTo);
wxString TempString;
TempString << wxT("<") << TagType << wxT(">");
TempString << mmoEditorTexto->GetStringSelection();
TempString << wxT("</") << TagType << wxT(">");
mmoEditorTexto->Replace(PosFrom,PosTo,TempString);
UpdateHTML();
}
void MeuNovoEditorHTMLFrm::InsertText(const wxString& Text)
{
//Criar variveis para fixar posio do cursor
long PosFrom = 0, PosTo = 0;
mmoEditorTexto->GetSelection(&PosFrom,&PosTo);
mmoEditorTexto->Replace(PosFrom,PosTo,Text);
UpdateHTML();
}
Agora
vamos
fazer
tudo
funcionar.
Selecione
MeuNovoEditorHTMLFrm.wxform. Logo no inicio depositamos
vrios botes na barra de ferramentas. Criaremos os dilogos para
cada um:
1)
2)
3)
4)
5)

No quadro na parte inferior, selecione a barra de


menu.
Em Propriedades selecione Edit MenuItems. Clique
em (+) de &Ajuda e clique &Sobre.
Clique no boto Edit. Clique em Create. Mude o nome
da funo para MnuSobreclick, Apply e OK.
Selecione MeuNovoEditorHTMLFrm.cpp, e role at a
linha // insert your code here.
Escreva estas linhas de cdigo:
CaixaSobreDlg TempCaixaSobreDlg(this);
TempCaixaSobreDlg.ShowModal();

317

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Temos todos os outros eventos para completar, e estes so:
&Novo;
&Salvar;
PageSet&Up;
PrintPre&View;
&Imprimir;
E&xit;
Expandir &Edit para estes:
&Desfazer;
&Refazer;
Cu&t;
&Copiar;
&Colar;
No caso de no se lembrar como realizar este procedimento
exatamente, visite as pginas de 206 e adiante, onde todos estes
detalhes foram elucidados, e de grande ajuda.
Em todos os casos vamos criar as funes, chamando-as de
Mnu<funo>Click. Depois em MeuNovoEditorHTMLFrm.cpp s
rolar o programa at encontrar a nova funo criada, e aps a
linha // insert your code here, escrever o cdigo de acordo com a
tabela abaixo:

318

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

Novo nome da funo

Acrescentar na funo o cdigo

MnuNovoClick

NewFile();

MnuAbrirClick

OpenFile();

MnuSalvarClick

SaveFile();

MnuPageSetupClick

dlgImprimir->PageSetup();

MnuVisImpClick

dlgImprimir>PreviewText(mmoEditorTexto>GetValue());

MnuImprimirClick

dlgImprimir>PrintText(mmoEditorTexto>GetValue());

MnuExitClick

Close();

MnuDesfazerClick

mmoEditorTexto->Undo();
UpdateHTML();

MnuRefazerClick

mmoEditorTexto->Redo();
UpdateHTML();

MnuCortarClick

mmoEditorTexto->Cut();
UpdateHTML();

MnuCopiarClick

mmoEditorTexto->Copy();

MnuColarClick

mmoEditorTexto->Paste();
UpdateHTML();

319

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Feito tudo isto, precisamos mostrar ao programa onde encontrar
os cdigos. Selecione MeuNovoEditorHTMLFrm.cpp e logo aps a
linha //// Header Include End, acrescente estas linhas:
#include "InserirHiperlinkDlg.h"
#include "InserirImagemDlg.h"
#include "CriarTabelaDlg.h"
#include "CaixaSobreDlg.h"
Agora criaremos os eventos para cada boto na barra de
ferramentas.
Selecione
MeuNovoEditorHTMLFrm.wxform.
Comeando com o boto que chamamos btNovo, clique nele. Em
seguida clique em Eventos. Clique <Add new function>. O cdigo
novo aparece. Aps a linha // Add your code here escreva o mesmo
cdigo que usou para definir o dilogo, i.e. NewFile();
Repetir esta operao para os outros seis botes, acrescentando
o cdigo referente a cada boto de acordo com a tabela supra.
Para a janela de rodagem, que contm os Ttulos de 1 a 6, ao invs
de OnClick, selecione OnUpdated. Aps a linha // Insert your code
here escreva:
WrapTextInTag(wxString() << wxT("T") << (cmbTitulo->GetCurrentSelection()
+ 1));
Para as opes de alinhamento, os ltimos a direita na barra de
ferramentas, depois de selecionar cada elemento, Eventos, e criar
nova funo, i.e. btAlinharEsquerdaClick, btAlinharCentroClick e
btAlinharDireitaClick, inserir os respectivos cdigos em cada
funo criada:

320

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


btAlinharEsquerdaClick:
InsertText(wxT(" ALIGN=\"left\""));
btAlinharCentroClick:
InsertText(wxT(" ALIGN=\"center\""));
btAlinharDireitaClick:
InsertText(wxT(" ALIGN=\"right\""));
Para encerrar vamos dar vida aos botes na barra vertical,
esquerda no quadro comeando com btNegrito.
Selecione MeuNovoEditorHTMLFrm.wxform. Clique no boto
btNegrito. Clique em Eventos, OnClick, <Add New Function> em
todos os casos, e escreva o cdigo na funo criada aps // insert
your code here
btNegritoClick:
WrapTextInTag(wxT("N"));
btItalicosClick:
WrapTextInTag(wxT("I"));
btSublinharClick:
WrapTextInTag(wxT(S));

321

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


btFonteClick:
if(dlgFonte->ShowModal())
{
wxFontData FontData = dlgFonte->GetFontData();
wxFont Font = FontData.GetChosenFont();
long PosFrom = 0, PosTo = 0;
mmoEditorTexto->GetSelection(&PosFrom,&PosTo);
wxString TempString;
TempString = wxT("<FONT COLOR=\"");
TempString <<
FontData.GetColour().GetAsString(wxC2S_HTML_SYNTAX);
TempString << wxT("\"") << wxT(" FACE=\"");
TempString << Font.GetFaceName() << wxT("\"");
TempString << wxT(" POINT-SIZE=\"");
TempString << Font.GetPointSize() << wxT("\">");
TempString += mmoEditorTexto->GetStringSelection();
TempString += wxT("</FONT>");
mmoEditorTexto->Replace(PosFrom,PosTo,TempString);
UpdateHTML();
}
btInserirLinhaHorizontalClick:
InsertText(wxT("<HR>"));
btPontoAncoraClick:
long PosFrom = 0, PosTo = 0;
mmoEditorTexto->GetSelection(&PosFrom,&PosTo);
wxString TempString , TempAnchorString;
TempAnchorString << wxGetTextFromUser(wxT("Tecle o nome do ponto
ancora"),wxT("Criador de ponto ancora"));
TempString << wxT("<A NAME=\"") << TempAnchorString << wxT("\">");
TempString << mmoEditorTexto->GetStringSelection() << wxT("</A>");
mmoEditorTexto->Replace(PosFrom,PosTo,TempString);
UpdateHTML();
TempAnchorString.Prepend(wxT("#"));
AnchorArray.Add(TempAnchorString);

322

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Selecione MeuNovoEditorHTMLFrm.h.
abaixo da linha MRUFile:

Escreva

cdigo

logo

wxArrayString AnchorArray;
btInserirHiperlinkClick:
InserirHiperlinkDlg TempInserirHiperlinkDlg(this);
TempInserirHiperlinkDlg.SetHyperlinks(AnchorArray);
if(TempInserirHiperlinkDlg.ShowModal() == wxID_OK)
{
long PosFrom = 0, PosTo = 0;
mmoEditorTexto->GetSelection(&PosFrom,&PosTo);
wxString TempString;
TempString << wxT("<A HREF=\"");
TempString << TempInserirHiperlinkDlg.GetHyperlink();
TempString << wxT("\">");
TempString << mmoEditorTexto->GetStringSelection();
TempString << wxT("</A>");
mmoEditorTexto->Replace(PosFrom,PosTo,TempString);
UpdateHTML();
}
btInserirTabelaClick:
CriarTabelaDlg TempCreateTableDialog(this);
if(TempCreateTableDialog.ShowModal() == wxID_OK)
{
long PosFrom = 0, PosTo = 0;
mmoEditorTexto->GetSelection(&PosFrom,&PosTo);
wxString TempString;
TempString << wxT("<TABLE ALIGN=\"");
TempString << TempCreateTableDialog.GetTableAlignment();
if(TempCreateTableDialog.IsImageSelected())
{
TempString << wxT("\" BACKGROUND=\"");
TempString << TempCreateTableDialog.GetImage();
}

323

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


else if(TempCreateTableDialog.IsColourSelected())
{
TempString << wxT("\" BGCOLOR=\"");
TempString << TempCreateTableDialog.GetColour();
}
TempString << wxT("\" BORDER=\"");
TempString << TempCreateTableDialog.GetBorderSize();
TempString << wxT("\" CELLPADDING=\"");
TempString << TempCreateTableDialog.GetCellPadding();
TempString << wxT("\" CELLSPACING=\"");
TempString << TempCreateTableDialog.GetCellSpacing();
TempString << wxT("\" WIDTH=\"");
TempString << TempCreateTableDialog.GetCellSpacing();
TempString << wxT("\">\n");
for(int i = TempCreateTableDialog.GetRows();i>=0;i--)
{
TempString << wxT("<TR>\n");
for(int j = TempCreateTableDialog.GetCols();j>=0;j--)
{
TempString << wxT("<TD>\n");
TempString << wxT("</TD>\n");
}
TempString << wxT("</TR>\n");
}
TempString += wxT("</TABLE>\n");
mmoEditorTexto->Replace(PosFrom,PosTo,TempString);
UpdateHTML();
}
btInserirImagemClick:
InserirImagemDlg TempInsertImageDialog(this);
if(TempInsertImageDialog.ShowModal() == wxID_OK)
{
wxString TempString = wxT("<IMG");
TempString << wxT(" BORDER=\"");
TempString << TempInsertImageDialog.GetBorderWidth();
TempString << wxT("\" HEIGHT=\"");
TempString << TempInsertImageDialog.GetImageHeight();
TempString << wxT("\" WIDTH=\"");
TempString << TempInsertImageDialog.GetImageWidth();
TempString << wxT("\" SRC=\"");
TempString << TempInsertImageDialog.GetImageSource();
TempString << wxT("\" TITLE=\"");
TempString << TempInsertImageDialog.GetAlternativeText();

324

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


TempString << wxT("\">");
mmoEditorTexto->WriteText(TempString);
UpdateHTML();
}
Faremos uma alterao no arquivo CaixaSobreDlg.cpp. Aps a
linha ////GUI Items Creation End, escreva o cdigo abaixo:
hypIconsFrom>SetURL(wxT("http://tango.freedesktop.org/Tango_Desktop_Project"));
No
quadro
MeuNovoEditorHTMLFrm.wxform,
selecione
Previsualizar Combinado, e clique na janela direita,
mmoEditorTexto. Em Eventos clique OnUpdated e <Add new
function>. Na funo criada, aps //insert your code here escreva:
UpdateHTML();
Na pgina 271 definimos a funo UpdateHTML. Temos que
modificar o cdigo desta funo.
Substituir o cdigo com este abaixo:
//Verificar se os controles GUI foram criados antes de continuar
if(SetupComplete)
{
htmPreVisComb->SetPage(mmoEditorTexto->GetValue());
htmPreVisualizador->SetPage(mmoEditorTexto->GetValue());
mmoEditorTexto->MarkDirty();
}
Agora temos que escrever a funo SetupComplete. Selecione
MeuNovoEditorHTMLFrm.h, e aps ////GUI Controls Declaration End
acrescente este cdigo:
bool SetupComplete;
O IDE criou uma funo dentro de MeuNovoEditorHTMLFrm.cpp:
MeuNovoEditorHTMLFrm::CreateGUIControls()

325

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


Altere a funo para:
SetupComplete = false;
CreateGUIControls();
SetupComplete = true;
Precisamos criar outro evento para nosso mmoEditorTexto. Clique
Eventos, OnEnter, <Add New Function>. Escreva aps //insert your
code here :
mmoEditorTexto->WriteText(wxT("<BR>"));
Em MeuNovoEditorHTMLFrm.wxform, procure a linha contendo a
funo:
void MeuNovoEditorHTMLFrm::OnClose(wxCloseEvent& event)
{
Destroy();
}
Delete a funo Destroy();, e a substitui pelas seguintes linhas de
cdigo:
m_fileConfig->SetPath(wxT("/RecentFiles"));
m_fileHistory->Save(*m_fileConfig);
m_fileConfig->SetPath(wxT(".."));
if(event.CanVeto())
{
if(mmoEditorTexto->IsModified())
{
if(dlgSalvarAlt->ShowModal() == wxID_YES)
{
dlgSalvarPasta->SetFilename(MRUFile);
if(dlgSalvarPasta->ShowModal() != wxID_CANCEL)
{
mmoEditorTexto->SaveFile(dlgSalvarPasta->GetPath());
Destroy();
}
}
else
Destroy();

326

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn


}
else
Destroy();
}
else
Destroy();
Precisamos elaborar manualmente um manejador de evento agora,
pois no temos o cdigo pronto para este. Selecione
MeuNovoEditorHTMLFrm.h e logo antes do fim da funo };,
acrescente este cdigo:
void OnMRUFile(wxCommandEvent & event);
Selecione MeuNovoEditorHTMLFrm.cpp e logo antes do fim desta,
acrescente o cdigo abaixo:
void MeuNovoEditorHTMLFrm::OnMRUFile(wxCommandEvent & event)
{
if(DoFileSaveCheck())
{
MRUFile = m_fileHistory->GetHistoryFile(event.GetId() - wxID_FILE1);
mmoEditorTexto->LoadFile(MRUFile)
UpdateHTML();
mmoEditorTexto->DiscardEdits();
}
}
Ainda em MeuNovoEditorHTMLFrm.cpp, aps a linha ////Manual Code
Start escreva este cdigo:
EVT_MENU_RANGE(wxID_FILE1,wxID_FILE9,
MeuNovoEditorHTMLFrm::OnMRUFile)
Pronto, o projeto est terminado. Temos os conhecimentos para
elaborar qualquer caixas de dilogo ou menus. Isto realmente
fantstico. Caso no compilar, faa tudo novamente at que
consiga uma compilao 100%. A prtica faz a perfeio, e como
j experimentou com certza, qualquer pequeno erro poder
emperrar um projeto inteiro.

327

O Manual Dev-C++ e wxDev-C++ de Andrew Fairbairn

328