Buscar

Apostila C++ Básico (2)

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você viu 3, do total de 43 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você viu 6, do total de 43 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você viu 9, do total de 43 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Prévia do material em texto

Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 1 
 
 
 
 
Linguagem de Programação
 C++ 
 
Básico
 
Linguagem de Programação C++ – Sumário 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 2 
Sumário 
 
 
Linguagens de programação – História de C ____________ 3 
Características da linguagem C ______________________ 4 
A linguagem C++ ________________________________ 5 
Fundamentos de C++ ___________________________ 6 
Dados Padrões ________________________________ 10 
Tipos definidos e estruturas de dados _________________ 11 
Modificadores de dados ___________________________ 13 
Conversões de dados ___________________________ 14 
Classes de armazenamento ______________________ 15 
Matrizes _____________________________________ 16 
Operadores _____________________________________ 17 
Controle de fluxo ________________________________ 22 
Ponteiros _____________________________________ 27 
Funções _____________________________________ 30 
Diretivas do pré-processador ______________________ 36 
Arquivos _____________________________________ 37 
Introdução ao modo gráfico ______________________ 41 
Palavras reservadas ___________________________ 43 
 
Linguagem de Programação C++ – Linguagens de Programação – História de C 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 3 
Linguagens de programação – História de C 
 
 
O computador é uma ferramenta poderosa que possui as mais variadas aplicações no mundo moderno. 
Encontramos sistemas controlados por computadores em quase todas as áreas do conhecimento humano, 
como telecomunicações, indústrias, internet, medicina, etc. Entretanto, por mais potentes e flexíveis que 
sejam os computadores, eles nada fariam sem que fossem orientados por listas de instruções detalhadas, 
interpretadas e executadas pelo processador: os programas. 
 
Tudo que é físido em um computador é chamado hardware, e tudo que ele entende são dois estados de 
tensão que chamaremos, simbolicamente, de 0 e 1 (esses valores foram adotados somente para facilitar o 
entendimento). Todos os processadores possuem a sua linguagem de máquina (ou código binário), um 
conjunto de sequências de “zeros” e “uns” que produzem determinadas ações. É possível escrever 
programas em linguagem de máquina, mas seria uma tarefa improdutiva porque para que o processador 
execute tarefas comuns é necessário escrever muito código. Com o aumento da necessidade de 
programas, criaram-se as linguagens de programação, códigos intermediários entre a linguagem humana 
e a da máquina. Assim surgiram as linguagens Assembly, ADA, PL/I, CPL, BCPL, B, C, C++, Pascal, e 
muitas outras. As linguagens de programação podem estar mais próximas da linguagem de máquina ou da 
humana. Quanto mais próxima da linguagem humana, maior o nível de uma linguagem de programação. 
A linguagens sofisticadas para ambientes visuais como Visual Basic e Delphi são de altíssimo nível por 
estarem muito longe do código binário. Os programas de computador também podem ser chamados de 
softwares. 
 
Para que o computador interprete os programas escritos em uma linguagem de programação, eles devem 
ser traduzidos em linguagem de máquina. Isso pode ser feito por compilação ou interpretação. A 
linguagem é compilada quando o programa é traduzido inteiramente para a linguagem de máquina antes 
da execução, e interpretada quando a tradução é feita linha por linha durante a execução. Linguagens 
interpretadas tendem a ser mais lentas porque a tradução durante a execução representa um trabalho extra. 
 
A linguagem C foi desenvolvida nos Laboratórios Bell por Dennis Ritchie em 1972. Sua origem está 
muito ligada ao sistema operacional UNIX, escrito inicialmente em 1969 em linguagem montadora. 
 
Para entendermos como a linguagem C surgiu, devemos retroceder para o Algol 60, projetado em 1960 
por um Comitê Internacional. Essa linguagem possuía objetivos elevados para os computadores da época 
e por isso nunca foi muito utilizada. Para trazer o Algol 60 mais próxmo da realidade, surgiu tanto em 
Londres quanto em Cambridge em 1963 a linguagem CPL, que também fracassou por ser muito difícil. 
Por isso Martim Richards criou em 1967 a linguagem BCPL, uma versão mais simples do CPL. Logo 
depois, Ken Tompson desenvolveu linguagem B, ainda mais simples que a BCPL, para reescrever o 
sofisticado sistema UNIX. Ainda havia uma problema: B e BCPL tornaram-se linguagens limitadas, úteis 
apenas para alguns tipos de problemas. 
 
Devido a esses e outros contratempos, como imcompatibilidade com alguns tipos de hardware, Dennis 
Ritchie desenvolveu a sucessora de B, chamada de C. 
 
Com a nova linguagem, um mundo rico em possibilidades foi aberto aos novos programadores de 
sistemas. C permitia o contato íntimo com a máquina enquanto possibilitava implementar instruções de 
alto nível nos mesmos programas, ou seja: uma linguagem de baixo e alto nível simultaneamente. 
Linguagem de Programação C++ – Características da Linguagem C 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 4 
Características da linguagem C 
 
 
C pode ser considerada a principal linguagem orientada para máquinas. Diversamente de linguagens 
criadas para aplicações específicas, como FORTRAN, que são orientadas para problemas, C possui 
flexibilidade suficiente para implementar soluções para os mais variados tipos de problemas nos mais 
diversos hardwares. 
 
As linguagens de alto nível permitiram que o programador se concentrasse no problema que tinha que 
resolver, deixando a manipulação da máquina para o compilador ou interpretador. Para a engenharia ou 
administração, são excelentes. No entanto, os programadores que desenvolviam sistemas ainda 
dependiam das indigestas linguagens montadoras de suas máquinas. Para essa classe, C foi a solução 
definitiva em termos de produtividade e eficiência: está distante o suficiente da máquina para 
implementar rotinas de alto nível, e próxima o suficiente para especificar detalhes necessários para o 
sistema operacional. Talvez por isso a popularidade de C seja tão grande. 
 
Dentre as vantagens de C, podemos citar: 
 
1. É uma linguagem pequena; 
2. Pode ser de alto ou baixo nível, dependendo do ponto de vista; 
3. Produz um código muito eficiente, comparável ao código Assembly; 
4. Fracamente figurada, possuindo alta flexibilidade para manipulação de dados; 
5. É estruturada, antecipando o surgimento formal desse conceito; 
6. Suporta programação modular; 
7. Possibilita interfaces com as linguagens Assembly e Pascal; 
8. Apresenta operadores para manipulação de bits; 
9. Permite notáveis implementações de aritmética de ponteiros; 
10. Contém estruturas flexíveis de dados, limitados apenas pela necessidade; 
11. Portabilidade para funcionar em máquinas e sistemas operacionais diferentes; 
 
Como nenhuma linguagem de programação é perfeita, as principais desvantagens de C são: 
 
1. Fracamente figurada, podendo produzir efeitos colaterais inesperados e bizarros; 
2. Ausência de verificação de tempo de processamento. 
 
Como surgiram muitos compiladores para a linguagem C e as variações da linguagem começaram a 
ameaçar a grande portabilidade de flexibilidade de C, em 1983 o ANSI padronizou a linguagem para que 
todos os compiladores fossem implementados segundo as mesmas regras. O ANSI manteve alguns 
conceitos que são conhecidos como “espírito de C”, como: 
 
 Confie no programador. 
 Não impeça que o programador faça o que precisa ser feito. 
 Mantenha a linguagem pequena e simples. 
Linguagem de Programação C++ – A Linguagem C++ 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 5 
A Linguagem C++ 
 
 
Em 1980, o Dr. BjarneStroustrup desenvolveu a sucessora de C, a linguagem C++, que possui a base na 
linguagem C com idéias do Algol 68 e Simula67: operadores podem ser sobrecarregados e variáveis 
podem ser declaradas em qualquer ponto dentro do bloco de instruções como no Algol 68; objetos podem 
ser criados com funções virtuais e classes derivadas como no Simula67. 
 
Quando foi necessário realizar algumas simulações orientadas a eventos, muito rigorosas e com conceitos 
inexistentes nas linguagens de programação da época como objetos e eventos, e exigindo eficiência que 
nenhuma linguagem existente era capaz de fornecer, nem mesmo C, um grupo liderado pelo Dr. 
Stroustrup começou a trabalhar na implementação de uma nova linguagem, versátil e poderosa, mas que 
deveria manter a compatibilidade com programas e bibliotecas escritos em C. Devido ao alcance absoluto 
desse objetivo, a linguagem que nascia foi considerada sucessora de C e chamada C++. 
 
Dentre as melhorias, a mais significativa é a orientação ao objeto, mudando radicalmente os conceitos 
avançados de programação estruturada orientada para procedimentos, que era o caso de C. No entanto, 
para manter o “espírito de C”, o programador ainda é responsável por muitas verificações que são 
dispensáveis em outras linguagens mais rigorosas e também mais limitadas, como tamanho de vetores e 
matrizes, endereçamento de ponteiros, etc. 
 
Para que possamos ter idéia do que foi modificado em relação à linguagem C, citamos as principais 
melhorias de C++: 
 
1. Estruturas passam a ser de tipo nome, não exigindo o uso da palavra reservada na declaração; 
2. Declarações de variáveis em qualquer lugar do bloco, desde que antes da utilização; 
3. Operador resolução de escopo, permitindo variáveis locais de globais de mesmo nome; 
4. Especificador const, bloqueando o valor de variáveis; 
5. Uniões anônimas, recurso que economiza tempo e memória; 
6. Conversões explícitas, que diminuem os efeitos colaterais de uma linguagem fracamente figurada; 
7. Modelagem de função, especificando no cabeçalho da função os tipos de cada argumento; 
8. Sobrecarga de função, permitindo que mais de uma função com o mesmo nome, desde que tenham 
tipo de retorno e/ou argumentos de tipos diferentes; 
9. Funções com número de argumentos indefinido; 
10. Tipo referência, facilitando o entendimento e a sintaxe; 
11. Especificador inline, deixando que o compilador decida se pode inserir o código de um função no 
código em linha, economizando o tempo de chamada e armazenamento na pilha; 
12. Operadores new e delete, melhorando a alocação dinâmida de memória; 
13. Ponteiros void e funções tipo void, aumentando o poder dos ponteiros e formalizando funções 
void; 
14. Programação orientada ao objeto; 
15. Biblioteca stream, melhorando sensivelmente as operações de I/O. 
Linguagem de Programação C++ – Fundamentos de C++ 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 6 
Fundamentos de C++ 
 
 
Os programadores frequentemente relatam a dificuldade no aprendizado da linguagem C++ (bem como 
C), provavelmente devido à sintaxe simbólica e intimidativa. Essa queixa dificilmente acontece com 
Pascal, que possui uma sintaxe didática. O fato é que C e C++ foram projetadas para programadores de 
sistemas, ou seja, pessoas que já possuem um amplo conhecimento de lógica de programação, arquitetura 
e funcionamento do hardware. Mesmo assim, nada disso impede que a primeira linguagem de um 
programador seja C ou C++. 
 
Todos os programas devem receber dados de alguma fonte de entrada; processar as informações recebidas 
por meio de instruções que podem ser divididas genericamente em: simples, condicionais, laços e 
funções; expressar os resultados da manipulação dos dados de entrada; possuir uma estrutura modular e 
nomes autodocumentados (com significado) para facilitar a manutenção e a leitura posterior feita por 
outros programadores. 
 
Um programa C++ é constituído de funções, que são blocos de código cujas instruções executam ações de 
rotina. Também existem variáveis que são locais da memória RAM onde são armazenadas informações. 
Outros itens estarão presentes em um programa C++ e serão introduzidos oportunamente na compreensão 
da linguagem. Vamos escrever nosso primeiro programa C++, que imprime uma mensagem na tela: 
 
// Primeiro programa C++ 
// Curso de Linguagem de Programação C++ PROG001.CPP - Silvio Sabino 
 
#include<iostream.h> 
 
void main(void){ 
 cout << "\nMeu primeiro programa!"; 
 return; 
} 
 
// Fim do programa 
 
Vamos analisar linha a linha o conteúdo desse programa: 
 
// Primeiro programa C++ 
// Curso de Linguagem de Programação C++ PROG001.CPP – Silvio Sabino 
 
Todo programa deve possuir comentários significativos para facilitar o acompanhamento de outros 
programadores ou para manutenção posterior, que pode ocorrer muitos anos depois da criação do 
programa. Esse comentário explica o que é o programa. 
 
#include<iostream.h> 
 
Essa instrução é uma diretiva do pré-processador que inclui o arquivo IOSTREAM.H no código do 
programa. Esse arquivo é um dos vários arquivos de cabeçalho da linguagem C++, que são bibliotecas 
com rotinas implementadas pelos programadores da linguagem. 
 
void main (void){ 
... 
} 
 
Esse bloco de código é uma função C++. O símbolo { abre o código e } fecha o mesmo. Esses símbolos 
também são utilizados para laços e estruturas de controle, que veremos mais adiante. A palavra void no 
Linguagem de Programação C++ – Fundamentos de C++ 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 7 
início da linha representa o tipo de retorno da função. Nesse caso a função não retorna nenhum valor, fato 
evidenciado pela palavra void. A palavra main é o identificador (nome) da função. Todos os programas 
C++ possuem uma única função main e a execução do programa começa sempre a partir dessa função. A 
palavra entra parênteses void representa os argumentos da função. Nesse caso, a função não tem nenhum 
argumento, o que é indicado pela mesma palavra void. Entre os delimitadores { e } do bloco, podem 
existir instruções que são chamadas corpo da função: 
 
cout << "\nMeu primeiro programa!"; 
 
Essa linha invoca a stream cout (console out) definida em IOSTREAM.H, que imprime o argumento 
“Meu primeiro programa!” na tela. Merece atenção a presença da sequência \n que significa nova linha. 
C e C++ possuem uma série de caracteres especiais que são formados por barra invertida (\) seguido de 
uma letra ou símbolo. Eis os mais comuns: 
 
\a Beep 
\n nova linha 
\t tabulação horizontal 
\v tabulação vertical 
\r retorno de carro 
\b retrocesso (backspace) 
\’ aspas simples 
\” aspas duplas 
\\ barra invertida 
\f salta uma página 
\0 nulo (NULL) 
 
return; 
 
Retorna da função para o processo anterior, no caso o sistema operacional. Essa instrução pode ser 
dispensada nesse caso sem nenhum aviso do compilador. 
 
// Fim do programa 
 
Comentário para evidenciar que o programa terminou nesse ponto. 
 
O compilador C++ ignorará espaços repetidos, tabulações ou linhas em branco em quase todos os pontos 
do programa. Portanto, o mesmo programa anterior pode ser escrito de várias formas, como por exemplo: 
 
// Primeiro programa C++ 
// Curso de Linguagem de Programação C++ PROG0011.CPP - Silvio Sabino 
#include <IOSTREAM.H> 
void main (void) {cout << "\nMeu primeiro programa!";return;}// Fim do programa 
 
Esse programa é igualmente válido. Devemos observar que na diretiva do pré-processador não podem 
haver espaços entre os símbolos < > e o nome do arquivo de cabeçalho IOSTREAM.H pode ser escrito 
em maiúsculas. Todas as instruções C++ são terminadas em ponto-e-vírgula. Outracaracterística 
marcante na sintaxe C e C++ é a diferença entre letras minúculas e maiúsculas. Em muitas linguagens, 
como Pascal, não existe nenhuma diferença, mas em C++ isso é sentido pelo compilador. 
 
Vamos agora analisar um segundo programa C++. O código apresenta declarações de variáveis e a função 
adicao, cuja tarefa é calcular o valor da soma de dois números passados como parâmetros. As explicações 
estão inseridas em forma de comentário: 
 
Linguagem de Programação C++ – Fundamentos de C++ 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 8 
// Segundo programa C++ 
// Curso de Linguagem de Programação C++ PROG002.CPP - Silvio Sabino 
 
#include<iostream.h> // incluindo iostream.h para utilizar a classe cout 
 
// função que retorna a soma de 2 números cujos valores 
// são passados como parâmetros 
int adicao (int a, int b){ 
 
 // declarando a variável que conterá o valor da soma 
 // dos dois parâmetros "a" e "b" 
 int resultado; 
 
 // atribuindo o valor da adicao de "a" e "b" à variável resultado 
 resultado = a + b; 
 
 // retornando o valor contido na variável "resultado" para 
 // o processo anterior, que nesse caso é a função main() 
 return resultado; 
 
} 
 
// função principal do programa onde é iniciada a execução 
void main(void){ 
 
 // declarando duas variáveis do tipo inteiro 
 int n , m, soma; 
 
 // atribuindo o valor 2 à variável "n" e 4 à variável "m" 
 n = 2; 
 m = 4; 
 
 // passando "n" e "m" como parâmetros para que a função soma(int, int) 
 // calcule a soma dos dois valores e retorne o resultado que é atribuído 
 // à variável soma 
 soma = adicao (n, m); 
 
 // imprimindo o valor de "soma" na tela 
 cout << soma; 
 
 // retornando o processo anterior, no caso o sistema operacional 
 return; 
 
} 
 
// Fim do programa 
 
 
O próximo programa melhora a interface com o usuário solicitando os valores das variáveis n e m para 
que a função adicao calcule a soma dos dois valores: 
 
// Terceiro programa C++ 
// Curso de Linguagem de Programação C++ PROG003.CPP - Silvio Sabino 
 
#include<iostream.h> // incluindo iostream.h para utilizar as classes cout e cin 
 
// função que retorna a soma de 2 números cujos valores 
// são passados como parâmetros 
int adicao (int a, int b){ 
 
 // declarando a variável que conterá o valor da soma 
 // dos dois parâmetros "a" e "b" 
 int resultado; 
Linguagem de Programação C++ – Fundamentos de C++ 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 9 
 
 // atribuindo o valor da adicao de "a" e "b" à variável resultado 
 resultado = a + b; 
 
 // retornando o valor contido na variável "resultado" para 
 // o processo anterior, que nesse caso é a função main() 
 return resultado; 
 
} 
 
// função principal do programa onde é iniciada a execução 
void main(void){ 
 
 // declarando duas variáveis do tipo inteiro 
 int n, m, soma; 
 
 // pedindo para o usuário o valor de "n" 
 cout << "\nDigite o 1o. no.: "; 
 cin >> n; 
 
 // pedindo para o usuário o valor de "m" 
 cout << "Digite o 2o. no.: "; 
 cin >> m; 
 
 // passando "n" e "m" como parâmetros para que a função soma(int, int) 
 // calcule a soma dos dois valores e retorne o resultado que é atribuído 
 // à variável soma 
 soma = adicao (n, m); 
 
 // imprimindo o valor de "soma" na tela 
 cout << "A soma é: " << soma; 
 
 // retornando o processo anterior, no caso o sistema operacional 
 return; 
 
} 
 
// Fim do programa 
 
 
Nos programas acima, vimos como é a sintaxe de declaração de funções e variáveis, como passar 
parâmetros para uma função e como retornar valores para o processo anterior que chamou a função. 
 
Depois disso, provavelmente será possível reconhecer um programa C++ se alguém nos apresentar um. 
Passaremos agora a detalhar os aspectos específicos da linguagem C++. 
Linguagem de Programação C++ – Tipos definidos e estruturas de dados 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 10 
Dados padrões 
 
 
Todo programa C++ deve ter pelo menos a função main( ), e podem também conter dados que podem ser 
variáveis ou constantes. 
 
Todos os dados e funções C++ são referenciados por identificadores (nomes). Os identificadores não 
podem começar com dígitos numéricos porque assim o compilador não poderia separar tais 
identificadores de constantes.Eis a descrição suscinta dos tipos de dados padronizados C++: 
 
char: utilizado para armazenar caractares alfanuméricos, o tipo char ocupa um byte na memória. Devido 
ao fato de C++ ser fracamente figurada, um dado char pode ser visto como número ou caractere, 
dependendo do desejo do programador na aplicação específica. Seu valor padrão pode variar de –128 a 
127. 
 
int: ocupa no modelo padrão uma palavra (nas máquinas da plataforma PC, isso corresponde a dois 
bytes) na memória e seu valor padrão pode variar entre –32768 a 32767. Pode armazenar números 
inteiros ou pode ser visto como caractere, dependendo da aplicação, mas o valor do segundo byte não é 
considerado nesse caso. 
 
float: pode armazenar valores em ponto flutuante e correspondem aos números reais. Ocupam duas 
palavras na memória e seu valor padrão pode variar entre 3,4x10
-38
 até 3,4x10
+38
. 
 
double: armazena valores em ponto flutuante de precisão dupla. Ocupam quatro palavras na memória e 
seu valor padrão pode variar entre 1,7x10
-308
 e 1,7x
+308
. 
 
enum: tipo de dado associado a um conjunto de constantes inteiras chamadas de conjunto de enumeração 
(enumeration set), que possuem valor presumido mas que podem ser especificados pelo programador. A 
sintaxe é: 
 
enum semana {domingo, segunda, terça, quarta, quinta, sexta, sábado} dias; 
 
A declaração acima cria o tipo enum semana e a variável dias, do tipo semana. A constante domingo tem 
valor 0 e as seguintes têm o valor da anterior mais um. 
 
void: tipo vazio para retorno e argumentos de funções. Seu uso é importante para ponteiros, definindo 
ponteiros genéricos. Isso será visto quando tratarmos de dados dinâmicos. 
 
Dados padrão podem ser iniciados com algum valor quando são declarados, como na declaração: 
 
int inteiro = 7; 
 
Se o programador esquecer de iniciar a variável na declaração ou fora dela, seu valor será desconhecido 
até que lhe seja atribuído algum valor. 
 
Os dados variáveis, em suma, são os que podem estar no lado esquerdo de uma instrução de atribuição, ou 
em outros termos, são lvalues. Quaisquer outras expressões não são lvalues (localizador de objeto) 
 
Pode-se conhecer o tamanho de qualquer tipo de dado C++ utilizando-se o operador sizeof que retorna o 
tamanho em bytes do operando. Por exemplo: sizeof(int) retorna 2, que é o tamanho em bytes do tipo int.
Linguagem de Programação C++ – Tipos definidos e estruturas de dados 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 11 
Tipos definidos e estruturas de dados 
 
 
 typedef 
 
Além dos dados padronizados, podem ser definidos outros tipos de dados com a palavra reservada 
typedef: 
 
typedef int inteiro; 
 
Com essa definição, poderemos declarar um dado inteiro a como int a ou inteiro. Já que inteiro foi 
definido como sendo equivalente ao tipo int. Na maioria dos casos, typedef é utilizado para conferir 
significado aos tipos criados pelo usuário e facilitar a sintaxe, nos poucos casos restantes é uma 
necessidade para que a linguagem suporte certas declarações ou passagem de argumentos para funções. 
 
 Estruturas de dados 
 
Podem ser definidos tipos de dados heterogêneos, ou estruturas dedados, formados por combinações de 
tipos válidos, padrões ou não. Existem três tipos de estruturas de dados em C++: 
 
struct: a estrutura segue o conceito de registro: dados relacionados logicamente referenciados por um 
único nome, e cada dado representa um campo. Considere um número complexo com a parte real e 
imaginária. As duas partes podem ser referenciadas por um só nome, desde que declarada uma estrutura, 
como por exemplo: 
 
struct complexo { 
 double real; 
 double imag; 
}; 
 
class: tipo de dado concebido para a criação de objetos e pode ser entendida com a uma evolução de 
struct. As funções de uma classe são conhecidas como métodos. A classe abaixo possui dados (campos 
ou instâncias) e métodos: 
 
class exemplo{ 
 int n,u; 
 float t; 
 
 public: 
 char letra; 
}; 
 
int exemplo::metodo1(void){ 
 return(0); 
} 
 
As instâncias e métodos de uma classe somente podem ser acessadas pelo programa diretamente se 
especificadas com o modificador public. No exemplo, somente letra pode ser acessada fora da classe. Em 
C++, tipos de dados struct também podem ter métodos, e suas instâncias são sempre presumidas 
públicas. Para impedir o acesso de alguma instânca pelo programa, utilizamos o modificador private. A 
palavra reservada this representa um ponteiro que aponta para o objeto atual. 
 
Quando criamos uma class, não criamos um objeto, mas apenas um tipo de dado. Quando em algum lugar 
do programa declaramos um dado do tipo de uma class definida, então criamos um objeto na memória. 
Linguagem de Programação C++ – Tipos definidos e estruturas de dados 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 12 
 
Para que o objeto seja construído na memória, existe sempre uma função especial denominada construtor 
do objeto e para dealocar o espaço reservado, o programa chama uma outra função, chamada destrutor. O 
programador pode criar seus próprios construtores de destrutores, como veremos mais adiante. 
 
union: um tipo interessante de estrutura de dados. Em uma union, todos os dados ocupam a mesma área 
de memória, sendo que a memória ocupada pela union é igual ao tamanho do maior tipo de dado. 
Consideremos a union abaixo: 
 
union teste { 
 char caractere; 
int inteiro; 
float flutuante 
 double flutuante_duplo; 
}; 
 
O maior tipo de dado é o campo flutuante_duplo, que ocupa 8 bytes. Na memória, esses campos estariam 
de forma parecida com o esquema abaixo: 
 
 
 
 
C45D:0780 C45D:0781 C45D:0782 C45D:0783 C45D:0784 C45D:0785 C45D:0786 C45D:0787 
 
Em uma união, os campos estão no mesmo endereço, portanto se um deles tiver seu valor alterado, todos 
podem sofrer a alteração. 
 
Para acessar bits em um local de memória, C e C++ possuem uma forma de acessá-los com um tipo 
especial de estrutura denominada campo de bits: 
 
struct campo{ 
 unsigned c1:1; // 1 bit 
 unsigned c2:1; // 1 bit 
 unsigned c3:4; // 4 bits 
 unsigned c4:2; // 2 bits 
}; 
 
Os campos de bits em uma estrutura pode ocupar no máximo 16 bits. A configuração na memória seria 
algo parecido com o esquema abaixo: 
 c4 c3 c2 c1 
 
Bit 8 Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 
 
Se o número total de bits ocupado pelos campos de bits da estrutura for diferente de um múltiplo de 8, os 
bits restantes até completar um múltiplo de 8 são “desperdiçados”, pois não será possível acessar os bits 
restantes porque o processador só poderá endereçar bytes e não bits. 
char 
int float 
double 
Linguagem de Programação C++ – Modificadores de dados 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 13 
Modificadores de dados 
 
 
Os tipos padrões char e int podem ter seus intervalos de valores alterados pelos modificadores signed e 
unsigned. O modificador signed (sinalizado) é o estado padrão e não é necessário expressá-lo na 
declaração. Já unsigned (sem sinal) deve ser explicitado para que o compilador saiba que o dado será 
considerado sempre positivo. Nos dados signed o bit mais significativo representa o sinal, e quando 
declaramos um dado unsigned o compilador utiliza todos os bits disponíveis para guardar a informação. 
O efeito é a alteração dos intervalos de valores: unsigned int pode variar de 0 a 65535 e unsigned char 
de 0 a 255. 
 
O modificador long dobra o tamanho em bytes ocupado pelos tipos int e double. E short pode modificar 
o tipo int, mas nenhum efeito ocorre na plataforma PC. 
 
O resumo abaixo mostra o efeito nos intervalos e no tamanho em bytes dos modificadores de sinal e 
tamanho nos tipos padrões C++: 
 
Tipo Tamanho Intervalo 
unsigned char 8 bits 0 a 255 
Char 8 bits -128 a 127 
Enum 16 bits -32768 a 32767 
unsigned int 16 bits 0 a 65535 
short int 16 bits -32768 a 32767 
Int 16 bits -32768 a 32767 
unsigned long 32 bits 0 a 4294967295 
Long 32 bits -2147483648 a 2147483647 
Float 32 bits 3,4x10
-38
 a 3,4x10
+38 
Double 64 bits 1,7 x10
-308
 a 1,7 x10
+308 
long double 80 bits 3,4 x10
4932
 a 1,1 x10
4932 
 
Os dados podem ter seus valores inalteráveis pelo programa se modificados pela palavra reservada const, 
e podem ter seu valor modificado por algum evento externo através do modificador volatile. Se um dado 
variável é declarado normalmente como: 
 
int a=0; 
 
O valor contido na variável pode ser alterado pelo programa em uma instrução de atribuição qualquer, 
mas se ele a variável for declarada com o modificador const: 
 
const int a=0; 
 
O programador não poderá alterar o valor dessa variável, entretanto um processo externo pode se ela for 
declarada como volatile, mesmo sendo especificado o modificador const: 
 
const volatile a=0; 
 
Nesse caso, o compilador não presumirá qualquer valor para a constante, que pode estar sendo atualizada 
por algum processo externo. 
Linguagem de Programação C++ – Conversões de dados 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 14 
 
Conversões de dados 
 
 
Quando escrevemos instruções que envolvem mais de um tipo de dado, eles são convertidos 
automaticamente seguindo uma ordem hierárquica para que o compilador possa executar a instrução. 
Essas operações são chamadas de modo misto. Essa necessidade de conversão existe porque tipos de 
dados diferentes são armazenados de modos diferentes na memória. Os dados originais não são alterados, 
pois é somente durante o cálculo da instrução que os tipos são alterados influenciando no resultado. 
Consideremos a instrução abaixo: 
 
float termo1=2.0, resultado; 
int termo2=3; 
resultado = termo1*termo2; 
 
Para executar a instrução de atribuição, o valor de termo2 é temporariamente convertido para float e o 
valor de termo2 não é alterado. A hierarquia de conversão segue a sequência: double, float, long, int, 
short. 
 
Se um float é convertido para int a parte fracionária é perdida sem arredondamento, vejamos o exemplo: 
 
float termo1=2.9, termo2=7.8; 
int resultado; 
resultado = termo1*termo2; 
 
Esse operação teria como resultado 22,62 se resultado fosse do tipo float ou double, mas como é uma 
variável do tipo int a parte fracionária é perdida e resultado receberá o valor 22 após a instrução. 
 
Em algumas instruções o resultado normal é indesejável e nesse caso os dados devem ser convertidos 
com o operador cast, que modela o tipo de dado da melhor maneira para a aplicação: 
 
float termo1=5.7, resultado; 
int termo2=3, termo3=4; 
resultado = termo1 + termo2/termo3; 
 
Depois dessa instução, o valor de resultado é 5,7. Isso é estranho, já que os dados inteiros não exerceram 
nenhuma influência. Isso ocorreu porque após a divisão termo2/termo3o resultado deveria ser 0,75 mas 
como os dois operandos são inteiros a parte fracionária é desprezada e o resultado da divisão é 0. 
 
Para corrigir esse problema, C++ possui o operador de modelamento de dados (cast). Usando o operador 
cast em um dos operandos inteiros, o resultado seria 4,275: 
 
resultado = termo1 + termo2/(float)termo3; 
 
Quando o operador cast é aplicado em termo3, a divisão passa a considerar todos os dados como float, 
conforme a hierarquia de conversão, por isso não é necessário modelar os dois operandos da operação.
Linguagem de Programação C++ – Classes de Armazenamento 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 15 
Classes de armazenamento 
 
 
Os dados em C++ podem ter seu armazenamento padrão modificado, e isso terá efeitos na visibilidade 
(escopo) da variável dentro do arquivo e dentro do programa (se o programa conter mais de um arquivo). 
Um dado declarado fora de qualquer função é um dado de escopo global, porém se ele for declarado 
dentro de um bloco de código ele terá escopo local. As declarações de dados pode ser de nível interno ou 
externo. 
 
As classes possíveis em declarações de nível interno são auto (padrão) static e register. Um dado auto 
ou static existe enquanto o programa estiver dentro do bloco onde está declarado, mas se for static a cada 
chamada à função ele retém o último valor e deve ser iniciado com algum valor, ou o compilador 
presumirá o valor zero. Se um dado é declarado com classe register o compilador tentará armazenar esse 
dado em um registrador da CPU ou otimizá-lo. Devemos ter cuidado: register é uma solicitação e não 
uma ordem, pois nem sempre será possível armazenar dado em um registrador. 
 
Em declarações de nível externo, as classes podem ser somente extern ou static: extern refere-se a um 
dado declarado em outro arquivo, e pode ser declarado apenas uma vez em um dos arquivos; dados static 
podem ser declarados em mais de um arquivo, já que static limita o escopo no arquivo onde está 
declarado. Uma função também pode ter classe de armazenamento modificada: funções static são visíveis 
apenas dentro do arquivo onde está declarada e funções extern são visíveis em todos os arquivos que 
formam o programa. Funções sem classe de armazenamento são extern por padrão Abaixo um exemplo 
de declaração de de um dado com declarações de nível externo (para rodar, abra o projeto proj01.prj no 
Turbo C++): 
 
// Ilustrando o uso de classes de armazenamento static e extern 
// Arquivo PROG004.CPP 
// Curso de Linguagem de Programação C++ PROG004.CPP - Silvio Sabino 
 
#include<iostream.h> 
 
int a=0; 
static int b; 
 
extern void modifica(void); // declaração de função para acessá-la em outro arquivo 
 
void main(void){ 
 cout << "\nO valor de a é: " << a; 
 modifica(); 
 cout << "\n\nE o de B em PROG004.CPP é: " << b; 
} 
 
 
// Ilustrando o uso de classes de armazenamento static e extern 
// Arquivo PROG005.CPP 
// Curso de Linguagem de Programação C++ PROG005.CPP - Silvio Sabino 
#include<iostream.h> 
 
extern int a; 
static int b=2; 
 
void modifica(void){ 
 a=a+1; 
 cout << "\n\nO valor de a mudou para: " << a; 
 cout << "\nE o de B em PROG005.CPP é: " << b; 
} 
Linguagem de Programação C++ – Operadores 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 16 
Matrizes 
 
 
Qualquer tipo de dado em C e C++ pode ser organizados em arranjos (array) contíguos na memória 
RAM. Esses arranjos são chamados matrizes e têm grande importância na programação. As matrizes 
podem ter uma ou mais dimensôes, e quando possuem uma dimensão podem ser denominadas de vetores. 
A declaração de uma matriz de 5 inteiros de nome matriz seria: 
 
int matriz[5]; 
 
Para uma matriz bidimensional em que cada dimensão possui 5 elementos: 
 
int matriz[5][5]; 
 
O nº de elementos de uma matriz pode ser omitido na declaração, mas se a matriz não for iniciada o seu 
tamanho será presumido como 0 pelo compilador. Para declarar uma matriz iniciando-a a sintaxe é: 
 
int matriz[]={0,1,2,3,4,5,6}; 
 
No caso de matrizes de mais de uma dimensão, somente a dimensão mais à direita pode ficar sem o nº de 
itens: 
 
int matriz[5][]={{0,1,2,3},{4,5,6,7},{8,9,10,11},{12,13,14,15},{16,17,18,19}}; 
 
No caso de matrizes de caracteres (em Pascal, o tipo string é padrão, o que não ocorre com C e C++),a 
inicialização pode ser feita como mostrada acima ou de forma mais direta: 
 
char matriz[]= "essa é uma matriz de caracteres"; 
 
No caso de mais de uma dimensão: 
 
char matriz[3][]={"primeiro item","segundo item","terceiro item";}; 
 
Nesse caso, o compilador criará todos os itens com o tamanho do maior item. 
 
Poderemos usar as matrizes com todas as possibilidades que elas oferecem quando estudarmos os 
ponteiros, um assunto de extrema importância em C e C++ que é um dos motivos da escolha delas para 
implementar sistemas operacionais. 
Linguagem de Programação C++ – Operadores 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 17 
Operadores 
 
 
C++ possui alguns operadores que não são encontrados em outras linguagens de programação, como 
operadores bit a bit, de atribuição composta, incremento e decremento e operador vírgula. Os tipos de 
operadores C++ são: 
 
 Operadores bit a bit 
 
Tratam os dados como sequências de bit individuais. São & (AND), | (OR), ^ (XOR), ~ (complemento de 
um). O programa a seguir ilustra os efeitos dos operadores bit a bit: 
 
// Ilustrando os efeitos dos operadores bit a bit 
// Curso de Linguagem de Programação C++ PROG006.CPP - Silvio Sabino 
 
#include<iostream.h> 
 
unsigned int zeros=0; 
unsigned int uns=255; 
unsigned int medio=127; 
 
void main(void){ 
 cout << "\n\n 0 em binário é 0000000000000000"; 
 cout << "\n127 em binário é 0000000001111111"; 
 cout << "\n255 em binário é 0000000011111111\n"; 
 cout << "\n0 & 255 = " << (zeros & uns) << " 0000000000000000"; 
 cout << "\n0 | 255 = " << (zeros | uns) << " 0000000011111111"; 
 cout << "\n0 ^ 255 = " << (zeros ^ uns) << " 0000000011111111"; 
 cout << "\n~0 = " << (~zeros) << " 1111111111111111"; 
 cout << "\n0 & 127 = " << (zeros & medio) << " 0000000000000000"; 
 cout << "\n0 | 127 = " << (zeros | medio) << " 0000000001111111"; 
 cout << "\n0 ^ 127 = " << (zeros ^ medio) << " 0000000001111111"; 
 cout << "\n~127 = " << (~medio) << " 1111111110000000"; 
 cout << "\n255 & 127 = " << (uns & medio) << " 0000000001111111"; 
 cout << "\n255 | 127 = " << (uns | medio) << " 0000000011111111"; 
 cout << "\n255 ^ 127 = " << (uns ^ medio) << " 0000000010000000"; 
 cout << "\n~255 = " << (~uns) << " 1111111100000000"; 
} 
 
 Deslocamento 
 
Também conhecidos como rotação de bits. Esses operadores, bem como os operadores bit a bit, são 
bastante utilizados em programação de sistemas, por manipularem diretamente os bits dos dados. O 
operador deslocamento à esquerda << move todos os bits uma posição para a esquerda, e o deslocamento 
à direita >>, move todos os bits para a direita. Nos dois casos, os bits de um extremo é perdido e o do 
outro extremo torna-se zero. O programa a seguir mostra como funcionam os operadores de deslocamento 
de bits: 
 
// Ilustrando os efeitos dos operadores bit a bit 
// Curso de Linguagem de Programação C++ PROG007.CPP - Silvio Sabino 
 
#include<iostream.h> 
 
unsigned int valor1=7; 
unsigned int valor2=64512; 
 
void main (void){ 
 
Linguagem de Programação C++ – Operadores 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 18 
 cout << "\n\n 7 em binário ‚ 0000000000000111";cout << "\n64512 em binário ‚ 1111110000000000\n"; 
 cout << "\n 7<<1 = " << (valor1<<1) << " 0000000000001110"; 
 cout << "\n 7<<2 = " << (valor1<<2) << " 0000000000011100"; 
 cout << "\n64512>>1 = " << (valor2>>1) << " 0111111000000000"; 
 cout << "\n64512>>2 = " << (valor2>>2) << " 0011111100000000"; 
 
} 
 
 Incremento e decremento 
 
Somar ou subtrair 1 de um número é tão comum em programação que C++ possui operadores especiais 
para essas ações: ++ (incremento) e – (decremento). Eles só podem ser utilizados por dados variáveis e a 
sua sintaxe pode ser observada no programa abaixo: 
 
// Ilustrando os efeitos dos operadores bit a bit 
// Curso de Linguagem de Programação C++ PROG008.CPP - Silvio Sabino 
 
#include<iostream.h> 
#include<conio.h> 
 
int numero=10; 
 
void main(void){ 
 clrscr(); 
 cout << "\nnumero incrementado: " << ++numero; 
 cout << "\nnumero novamente incrementado: " << numero++; 
 cout << "\nnumero decrementado: " << --numero; 
 cout << "\nnumero novamente decrementado: " << numero--; 
} 
 
Já que numero foi iniciado com valor 10 e foi incrementado 2 vezes e depois decrementado 2 vezes, então 
a princípio a saída deve ser: 
 
numero incrementado: 11 
numero novamente incrementado: 12 
numero decrementado: 11 
numero novamente decrementado: 10 
 
Mas a saída que ele apresenta é outra. Execute o programa para verificar e veja que o resultado é 
diferente. Isso acontece porque a posição dos operadores ++ e – influi no resultado, pois altera a ordem de 
execução da instrução. Quando escrevemos: 
 
cout << "\nnumero incrementado: " << ++numero; 
 
A ordem de execução é: primeiro a variável numero é incrementada e depois a sentença é impressa por 
cout. 
 
Enquanto que na linha seguinte: 
 
cout << "\nnumero novamente incrementado: " << numero++; 
 
A ordem é: primeiro a sentença é impressa por cout e depois a variável numero é incrementada 
O mesmo ocorre com decremento. 
 
 
 
Linguagem de Programação C++ – Operadores 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 19 
 Aritméticos 
 
Os operadores para operações aritméticas em C++ são: + (adição), - (subtração), * (multiplicação), / 
(divisão) e % (módulo). O operador módulo retorna o resto de uma divisão entre dois inteiros. 
 
 Atribuição simples e compostos 
 
Diferente de outras linguagens, C++ possui um operador de atribuição ao invés de uma instrução de 
atribuição. Isso torna-se claro na instrução abaixo, que não seria possível em outras linguagens: 
 
valor1 = valor2 = valor3 = 2; 
 
Ou seja: valor3 recebe o valor 2 e a operação retorna o valor contido em valor3, que é atribuído à variável 
valor2, e a peração retorna o valor contido em valor2 e finalmente valor1 recebe 2. 
 
C++ possui ainda um conjunto de operadores de atribuição compostos que permitem que o código seja 
escrito de forma mais concisa sem perder a clareza. As instruções abaixo são equivalentes: 
 
valor = valor + 5; 
valor + = 5; 
 
Outras operações que podem utilizar esses operadores são as demais perações aritméticas, deslocamento 
de bits e bit a bit, gerando os seguintes operadores: +=, -=, *=, /=, %=, <<=, >>=, &=, ^=, |=. 
 
 Relacionais e lógicos 
 
Os operadores relacionais C++ sempre estabelecem uma relação entre os valores dos operandos. Eles 
retornam 0 se o teste for falso e 1 se for verdadeiro. Os operadores relacionais C e C++ são: == (igual, 
note que ele é diferente do operador = de atribuição), != (diferente), > (maior), < (menor), >= (maior ou 
igual), <= (menor ou igual). 
 
Os operadores lógicos C e C++ retornam resultados de acordo com a relação lógica de seus argumentos: 
&& (AND), || (OR), ! (NOT). O operador && retornará 1 quando os dois argumentos forem verdadeiros, 
|| retornará 1 quando pelo menos 1 argumento for verdadeiro e ! inverte o valor que seria retornado. O 
programa a seguir mostra os resultados de teste relacionais e lógicos de acordo com a entrada do usuário: 
 
// Ilustrando os resultados dos operadores relacionais e lógicos 
// Curso de Linguagem de Programação C++ PROG009.CPP - Silvio Sabino 
#include<iostream.h> 
 
void main(void){ 
 
 float num1, num2; 
 
 cout << "\nInforme o primeiro valor real: "; 
 cin >> num1; 
 cout << "\nInforme o segundo valor real: "; 
 cin >> num2; 
 
 cout << "\n\nResultado de "<<num1<<" == "<<num2<<" -> " <<(num1==num2); 
 cout << "\nResultado de "<<num1<<" != "<<num2<<" -> " <<(num1!=num2); 
 cout << "\nResultado de "<<num1<<" > "<<num2<<" -> " <<(num1>num2); 
 cout << "\nResultado de "<<num1<<" < "<<num2<<" -> " <<(num1<num2); 
 cout << "\nResultado de "<<num1<<" >= "<<num2<<" -> " <<(num1>=num2); 
 cout << "\nResultado de "<<num1<<" <= "<<num2<<" -> " <<(num1<=num2); 
Linguagem de Programação C++ – Operadores 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 20 
 cout << "\nResultado de "<<num1<<" && "<<num2<<" -> " <<(num1&&num2); 
 cout << "\nResultado de "<<num1<<" || "<<num2<<" -> " <<(num1||num2); 
} 
 
 Operador condicional ternário 
 
Esse operador torna o código compacto por envolver um decisão com pouco código. Sua sintaxe é: 
 
condição ? expressão_verdadeira : expressão_falsa ; 
 
A condição genérica na instrução acima é um teste, que pode envolver operadores condicionais e lógicos: 
 
// Ilustrando os resultados dos operadores relacionais e lógicos 
// Curso de Linguagem de Programação C++ PROG010.CPP - Silvio Sabino 
#include<iostream.h> 
 
int a, b, c; 
 
void main(void){ 
cout << "\n\nInforme o primeiro valor: "; 
cin >>a; 
cout << "Informe o segundo valor: "; 
cin >>b; 
cout << "Informe o terceiro valor: "; 
cin >>c; 
cout << "o "<<((a>=b && a>=c)?"1o.":(b>=c)?"2o.":"3o.")<<"no. ‚ maior"; 
} 
 
 Operador vírgula 
 
O operador vírgula permite que duas expressões coexistam na mesma linha onde normalmente somente 
uma seria premitida. Seu uso será evidenciado quando tratarmos de estruturas de controle de fluxo. 
 
 Resolução de escopo 
 
C++ permite que uma variável local possua o mesmo nome de uma global, bastando que seja utilizado o 
operador resolução de escopo ::. No trecho abaixo as há duas variáveis teste: 
 
int teste; 
... 
void funcao(int teste){ 
 ::teste=teste; 
} 
 
Dentro da função funcao, a variável global recebeu o valor da variável local por meio do operador ::. 
 
 
 
Assim como nas outras linguagens, os operadores C++ obedecem a níveis de precedência que 
determinam a ordem que o compilador avaliará os operadores. Efeitos colaterais pode surgir quando os 
operadores são colocados de forma confusa. As instruções abaixo podem causar efeitos colaterais: 
 
valor = 2; resultado = (valor = 4) + valor; 
 
Existem duas formas de avaliar a expressão: valor recebe 4 e em seguida resultado recebe 8 (4+4); ou 
valor é usado como 2 e logo depois recebe 4, e resultado recebe 6. 
Linguagem de Programação C++ – Operadores 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 21 
 
A tabela abaixo relaciona os operadores C++ por ordem de precedência, sendo que alguns ainda não 
foram descritos. Operadores da mesma categoria tem a mesma precedência: 
 
Categoria Descrição Operador 
Precedência mais alta Chamada de função () 
 Índice de matriz [] 
 Referência indireta de estruturas -> 
 Resolução de escopo :: 
 Referência direta de estrutura . 
Unários NOT ! 
 Complemento de 1 ~ 
 Sinal positivo + 
 Sinal Negativo - 
 Incremento ++ 
 Decremento -- 
 Endereço & 
 Referência indireta * 
 Modelamento (cast) (tipo) 
 Tamanho do operando sizeof 
 Alocação dinâmicanew 
 Dealocação dinâmica delete 
Multiplicativos Multiplicação * 
 Divisão / 
 Módulo % 
Acesso a membros Referência indireta membro de estrutura .* 
 Referência indireta membro de estrutura ->* 
Aditivos Adição + 
 Subtração - 
Deslocamento Deslocamento à esquerda << 
 Menor que << 
Relacionais Menor ou igual a <= 
 Maior que > 
 Menor ou igual a >= 
Igualdade Igual == 
 Diferente (não igual) != 
 AND bit a bit & 
 XOR bit a bit ^ 
 OR bit a bit | 
 AND lógico && 
 OR lógico || 
 Condicional ternário ?: 
Atribuição Atribuição = 
 Atribuições compostas *=, /=, %=, +=, -=, &=, ^=, |=, <<=, >>= 
 Vírgula , 
Linguagem de Programação C++ – Controle de fluxo 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 22 
Controle de fluxo 
 
 
Para que possamos escrever programas C++ mais elaborados, é necessário dominar as estruturas de 
controle de execução de instruções, que são, basicamente, as instruções condicionais e laços. 
 
Quase todos os programas que escrevemos até o momento seguiram sempre uma sequência definida e o 
programador não interferiu em nenhum momento para que o programa tomasse decisões. A exceção foi o 
uso do operador condicional ternário. 
 
Quando é feito o controle de fluxo em um programa, algumas instruções podem não ser executadas em 
nenhum momento dependendo dos critérios adotados para a decisão. 
 
 if 
 
Esse instrução executa condicionalmente um bloco de código. Um bloco de código com apenas uma 
instrução não precisa ser delimitado com chaves { }, mas deve ser delimitado se houver mais de uma. A 
sintaxe genérica da instrução if é: 
 
if(expressão de teste) 
 ação; 
 
Caso exista mais de uma instrução devem ser usadas as chaves: 
 
if(expressão de teste){ 
 instrução1; 
 instrução2; 
 ... 
} 
 
O programa abaixo exemplifica o uso da instrução if: 
 
 
//Ilustrando o uso da instrução if 
// Curso de Linguagem de Programação C++ PROG011.CPP - Silvio Sabino 
#include<iostream.h> 
 
void main(void){ 
 int valor_teste; 
 cout << "\nDigite um valor inteiro: "; 
 cin >> valor_teste; 
 if(valor_teste==2){ 
 cout << "\nFoi digitado o valor 2."; 
 return; 
 } 
 cout << "\nFoi digitado um valor diferente de 2."; 
} 
 
Nesse exemplo, se o usuário digitar o valor 2, o teste valor_teste==2 retorna 1 e a instrução if direciona o 
fluxo para dentro do bloco, aparecendo a mensagem “Foi digitado o valor 2.” e o programa retorna para 
o processo anterior com a instrução return. Caso contrário o programa segue com a instrução após o 
bloco. 
 
 
 
Linguagem de Programação C++ – Controle de fluxo 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 23 
 if-else 
 
Com essa instrução o programa pode tomar duas direções baseado em um teste. A sintaxe geral seria: 
 
if(expressão de teste){ 
 instrução1; 
 instrução2; 
 ... 
} 
else{ 
 instrução1; 
 instrução2; 
 ... 
} 
 
As instruções dentro do bloco else somente serão executadas quando o teste for falso (retornar 0). 
 
 switch 
 
Quando é desejável testar uma variável em relação a vários valores, é improdutivo montarmos sequências 
de instruções if. Nesses casos é aconselhável utilizar a instrução switch. A sintaxe geral é: 
 
switch (expressão){ 
 
 case constante_1: 
 instruções; 
 break; 
 case constante_2: 
 instruções; 
 break; 
 ... 
 case constante_n: 
 instruções; 
 break; 
 
 default: instruções; 
 
} 
 
Devemos observar as peculiaridades da instrução switch. Quando o programa encontra a constante que 
corresponde ao valor da expressão, ele executa as instruções abaixo do case até que seja encontrada uma 
instrução break ou outra instrução de controle que provoque um devio na odem normal do programa. 
 
 for 
 
É uma das estruturas de laço mais potentes em muitas linguagens de programação, mas em C e C++ o 
laço for ultrapassa os limites normais de flexibilidade. Sua sintaxe geral é: 
 
for(inicialização;expressão de teste;incremento){ 
 instrução1; 
 instrução2; 
 ... 
} 
 
O laço for deve ser usado preferencialmente quando o número de iterações é conhecido. O exemplo 
abaixo mostra o uso do laço for e da instrução switch: 
 
Linguagem de Programação C++ – Controle de fluxo 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 24 
//Ilustrando o uso do laço for e da instrução switch 
// Curso de Linguagem de Programação C++ PROG012.CPP - Silvio Sabino 
#include<iostream.h> 
 
void main(void){ 
 
 // corpo do laço for, atenção às declarações 
 // de variáveis dentro da inicialização. 
 // O programa executará 5 vezes as instruções dentro do bloco 
 for(register int i = 0; i < 5;i ++){ 
 
 int valor; 
 cout << "\nDigite um valor inteiro: "; 
 cin >> valor; 
 
 // a instrução switch testará o valor de "valor" e 
 // direcionará o programa para o case certo 
 switch(valor){ 
 case 1: cout << "\n\nVocê digitou o valor 1"; 
 break; 
 case 2: cout << "\n\nVocê digitou o valor 2"; 
 break; 
 case 3: cout << "\n\nVocê digitou o valor 3"; 
 break; 
 default: cout << "\n\nVocê digitou um valor diferente de 1,2 ou 3"; 
 } 
 } 
} 
 
 while 
 
Quando não podemos prever o número de iterações necessárias é recomendado o uso do laço while: 
 
while(expressão de teste){ 
 instrução1; 
 instrução2; 
 ... 
} 
 
Vamos reescrever o exemplo anterior utilizando o laço while: 
 
// Ilustrando o uso do laço while e da instrução switch 
// Curso de Linguagem de Programação C++ PROG013.CPP - Silvio Sabino 
#include<iostream.h> 
 
void main(void){ 
 
 // iniciando a variável com um valor diferente de 0 para 
 // evitar efeito colateral no laço while 
 int valor=1; 
 
 // se o valor de "valor" for 0, o teste retorna 0 e o laço termina 
 while(valor){ 
 
 cout << "\nDigite um valor inteiro (0 para sair): "; 
 cin >> valor; 
 
 switch(valor){ 
 case 1: cout << "\nVocê digitou o valor 1"; 
 break; 
 case 2: cout << "\nVocê digitou o valor 2"; 
Linguagem de Programação C++ – Controle de fluxo 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 25 
 break; 
 case 3: cout << "\nVocê digitou o valor 3"; 
 break; 
 default: cout << "\nVocê digitou um valor diferente de 1,2 ou 3"; 
 } 
 } 
} 
 
 do-while 
 
A principal direfença entre esse instruçõ e while é que as ações dentro do bloco sempre serão executadas 
pelo menos uma vez: 
 
do{ 
 instrução1; 
 instrução2; 
 ... 
}while(expressão de teste); 
 
 break e continue 
 
Dentro de laços, a instrução break provoca a saída imediata do laço, e a instrução continue faz o 
programa saltar imediatamente para a avaliação da expressão de teste. O uso comum de break é na 
instrução switch, e continue é raramente usado. 
 
 return 
 
Provoca a saída imediata de uma função para o processo anterior. Se a mesma for de tipo diferente de 
void essa instrução deve vir acompanhada de um valor de retorno, caso contrário o compilador emitirá 
um aviso que não impede a execução do programa. Se a função for main() o programa terminará. 
 
 exit( ) e atexit( ) 
 
A função exit( ) provoca a saída imediata do programa e pede um argumento inteiro que será o código de 
erro para o sistema operacional, e atexit( ) faz com que uma função seja chamada imediatamente antes de 
terminar o programa. Essa função pede um ponteiro de função com argumento. 
 
 goto 
 
É uma instrução que desvia incondicionalmente o programa para um rótulo. Sua sintaxe geral é:goto rotulo; 
... 
rotulo: 
instrução; 
 
Seu uso é condenável por estar fora da filosofia da programação estruturada, mas foi mantido na transição 
de C para C++ porque em algumas situações seu uso é vantajoso. Exemplo genérico: 
 
... 
for(...){ 
 for(...){ 
 for(...){ 
 for(...){ 
 ... 
Linguagem de Programação C++ – Controle de fluxo 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 26 
 if(...)goto sair; 
 } 
 } 
 } 
} 
sair: 
... 
 
Nesse esquema de laços profundamente aninhados, não importam os testes dos laços externos ao for mais 
interno, porque goto desvia incondicionalmente o fluxo para o rótulo especificado. A única restrição é 
que o rótulo deve estar dentro da mesma função da instrução goto. 
 
 Laços infinitos 
 
Se a expressão de teste de um laço for vazia ou se as variáveis envolvidas não sofrerem modificação 
dentro do laço, deve existir alguma instrução para que o programa saia do laço por meio de break, 
return, goto ou pelas função exit( ), caso contrário o laço nunca terminará. 
 
Os laços infinitos podem ser usados quando o programa ou o laço termina mediante um evento produzido 
pelo usuário ou alguma entrada de valor específica. O exemplo anterior pode ser reescrito novamente 
utilizando-se um laço for(poderia ser while ou do-while, mas a expressão de teste não seria vazia) 
infinito: 
 
// Ilustrando o uso do laço infinito 
// Curso de Linguagem de Programação C++ PROG014.CPP - Silvio Sabino 
#include<iostream.h> 
 
void main(void){ 
 
 // utlizando um laço for infinito 
 // nota-se que os sinais de ponto-e-vírgula são mantidos 
 for(;;){ 
 int valor; 
 cout << "\nDigite um valor inteiro (0 para sair): "; 
 cin >> valor; 
 switch(valor){ 
 case 0: return; 
 case 1: cout << "\nVocê digitou o valor 1"; 
 break; 
 case 2: cout << "\nVocê digitou o valor 2"; 
 break; 
 case 3: cout << "\nVocê digitou o valor 3"; 
 break; 
 default: cout << "\nVocê digitou um valor diferente de 1,2 ou 3"; 
 } 
 } 
}
Linguagem de Programação C++ – Ponteiros 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 27 
Ponteiros 
 
 
Ponteiros são variáveis dinâmicas que guardam endereços de outra variáveis. A declaração de ponteiros é 
feita com o operador de referência indireta *: 
 
tipo *identificador; 
 
Onde tipo é o tipo apontado pelo ponteiro. Para atribuição, podemos utilizar o operador endereço &: 
 
tipo nome; 
tipo *apontador = &nome; 
 
O ponteiro apontador armazenará o endereço da variável nome, ou em outras palavras, apontará para ela. 
 
Ponteiros podem apontar para ponteiros, aumentando o nível de referência indireta, que é limitado apenas 
pela necessidade. Os ponteiros podem ser constantes ou variáveis. Ponteiros constantes são as matrizes ou 
ponteiros que tenham classe de armazenamento const. O nome da matriz representa o endereço do 1º 
item, ou seja, se array[50] é uma matriz, as expressões &array[0] ou array são equivalentes. Para 
declarar um ponteiro de nível(ordem) maior, basta aumentarmos o nº de operadores de referência indireta: 
 
int **p, *****p1; //p é de segunda ordem e p1 é de quinta ordem 
 
Se o operador referência indireta for utilizado em instruções durante o programa, ele permitirá o acesso à 
variável apontada pelo ponteiro. O programa a seguir mostra como isso ocorre: 
 
// Funcionamento de ponteiros 
// Curso de Linguagem de Programação C++ PROG015.CPP - Silvio Sabino 
#include<iostream.h> 
 
void main(void){ 
 
 int valor, *ponteiro = &valor; 
 cout << "\nDigite um valor inteiro: "; 
 cin >> valor; 
 cout << "\nO valor digitado foi: "<< *ponteiro; 
 *ponteiro=10; 
 cout << "\nO valor foi modificado para: " << valor; 
} 
 
 
 Aritmética 
 
Ponteiros podem ser incrementados, decrementados, adicionados ou subtraídos de constantes, e a unidade 
válida é sempre o tamanho do tipo de dado apontado: depois e incrementar um ponteiro de nome pointer 
que aponta para o tipo float com a instrução pointer++, o seu valor será o endereço sizeof(float) acima 
do anterior. E depois de pointer = pointer+3, o novo valor será 3*sizeof(float) acima do anterior. 
 
Para obter o endereço do elemento n de um ponteiro de nome array, que aponta para uma matriz, 
podemos utilizar notação de matriz ou de ponteiro se o ponteiro for variável: &array[n] ou array+n. E 
para acessar o valor desse elemento podemos escrever: array[n] ou *(array+n). Em qualquer caso, a 
notação de ponteiro executa mais rapidamente do que a de matriz. 
 
Linguagem de Programação C++ – Ponteiros 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 28 
 Modificadores de ponteiros 
 
A memória do processador 8088 é segmentada, e cada segmento tem 64 kbytes (65535 bytes). Todo 
endereçamento é feito com dois números denominados segmento e deslocamento (offset). Existem 4 
segmentos em um programa “.EXE”: código, dados, pilha e extra. Se nada for informado ao compilador, 
ele tentará sempre alocar espaço dentro do segmento de dados, mas podemos modificar ponteiros para 
que sejam armazenados em outros locais com o uso de modificadores: 
 
near: força o ponteiro a apontar somente para o deslocamento. Ocupam 2 bytes na memória; 
 
far: força o ponteiro a contar sempre o valor do segmento e do deslocamento. Além e tornar o acesso 
mais lento, ponteiros far ocupam 4 bytes; 
 
huge: semelhante ao ponteiro far, mas quando é incrementado, o segmento pode ser alterado. Isso nunca 
ocorre com um ponteiro far. 
 
Para apontar para qualquer tipo de dado, um ponteiro pode ser declarado como void * e ser moldado para 
qualquer tipo de acordo com a necessidade. Um ponteiro void simplesmente aponta para uma endereço de 
memória sem estar associado a qualquer tipo de dado. Abaixo um programa para exemplificar: 
 
// Funcionamento de ponteiros void 
// Curso de Linguagem de Programação C++ PROG016.CPP - Silvio Sabino 
#include<iostream.h> 
 
int inteiro; 
float flutuante; 
void *pointer=&inteiro; 
 
void main(void){ 
 
 *(int *)pointer = 2; 
 pointer = &flutuante; 
 *(float *)pointer = 3.0; 
 cout << "\nValor int: " << inteiro << "\nValor float: " << flutuante; 
} 
 
 Strings 
 
C++ não possui cadeias de caracteres como tipo de dado padrão. Todas as cadeias de caracteres são 
tratadas como ponteiros para o tipo char. O programador deve ter muito cuidado com strings, porque um 
acesso fora da área reservada ou alocada não será avisado pelo compilador e pode levar à catástrofe: a 
área invadida pode pertencer a outros dados, ao programa ou ao sistema operacional, no pior caso. 
 
Strings em C++ são sempre terminadas com o caractere nulo (NULL), portanto sempre devemos alocar 
espaço para um elemento além do tamanho da string. 
 
 Alocação dinâmica de memória 
 
Quando os programas tornam-se mais complexos, é comum que o programador não possa prever quanta 
memória será necessária para o programa, devendo alocar memória dinamicamente. Os operadores new e 
delete alocam e liberam memória, respectivamente. A sintaxe geral desses operadores é: 
 
tipo *ponteiro = new tipo[num_itens]; 
delete(ponteiro); 
Linguagem de Programação C++ – Ponteiros 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 29 
 
Quando o operador new é invocado pelo programa, este solicita ao sistema operacional um bloco de 
tamanho igual a núm_itens*sizeof(tipo). Se não houver memória disponível o ponteiro recebe o valor 
0(NULL). Devemos testar se a alocação foi feita com sucesso, porque se tentarmos usar um ponteiro que 
aponta para NULL ou com valor desconhecidopodemos causar uma catástrofe: os outros dados, o código 
do programa ou de outros programas pode ser corrompido e o sistema pode cair, travando a máquina. O 
programa a seguir mostra o uso dos operadores new e delete: 
 
// Operadores new e delete 
// Curso de Linguagem de Programação C++ PROG017.CPP - Silvio Sabino 
#include<iostream.h> 
 
void main(void){ 
 
 int *valor, itens; 
 cout << "\nDigite o n£mero de itens: "; 
 cin >>itens; 
 if(!(valor=new int[itens])) 
 cout << "\nMemória insuficiente!"; 
 else{ 
 cout << "\nAlocação dinâmica efetuda com suceso!"; 
 delete(valor); 
 } 
} 
 
 
 Referência 
 
É possível simplificar a notacão de ponteiros usando o tipo referência. Assim, nas chamadas de funções 
podemos utilizar os nomes das variáveis e passar o endereço para a função. O cabeçalho abaixo possui 
um argumento que é passado por referência: 
 
int funcao(char *a, int &ref){... 
 
Quando o programa chamar essa função, a variável referência ref equivalerá ao argumento passado para a 
função, porque terão o mesmo endereço. O uso do tipo referência C++ é indispensável quando não podem 
ser utilizados ponteiros e tampouco é possível o uso de variáveis comuns. Em C, a única forma de alterar 
o valor do parâmetro original era por meio de ponteiros. 
 
 Membros de ponteiros de estruturas 
 
Para referenciarmos membros de ponteiros que apontam para estruturas de dados, a referência indireta é 
realizada com os operadores -> e ->*. Por exemplo: seja *pont um ponteiro para uma struct casa, que 
possui uma instância denominada sala que e um ponteiro do tipo comodo. 
 
struct casa *pont = new casa; 
pont->casa = new comodo; 
pont->*casa = 20; 
 
A instância casa é referenciada pelo operador-> porque a estrutura externa (pont) é um ponteiro, e o 
conteúdo apontado por casa é acessado com o operador ->*. 
Linguagem de Programação C++ – Funções 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 30 
Funções 
 
 
Conforme o conceitos da programação estruturada, todas as ações que são usadas rotineiramente devem 
ser modularizadas para economizar tempo e facilitar o entendimento. Cada módulo ou sub-rotina em C++ 
é um função, como também foi explicado no início. A sintaxe geral de uma função C++ é: 
 
tipo_de_retorno identificador(tipo_1 argum_1, tipo_2 argum_2, ..., tipo_n argum_n){ 
 instrução1; 
 instrução2; 
 ... 
} 
 
O tipo de retorno é o tipo da função, ou seja, se ela retorna um tipo int dizemos que ela é do tipo int. Para 
retornar um valor, basta que uma expressão constante ou variável seja argumento de return. 
 
 Argumentos 
 
Uma função pode ter um n° de argumentos limitado apenas pela necessidade e capacidade da máquina. 
Quando um argumento é passado para uma função, ele pode ser passado de duas formas: 
 
Passagem por valor: quando passamos o valor dos dados. Os valores das variáveis originais da função 
chamadora não são alterados porque apenas uma cópia de seus valores é armazenada na pilha para serem 
utilizadas na função chamada. Funções chamadas por valor só podem retornar um valor; 
 
Passagem por referência: nesse caso, são utilizados tipos referência e os dados originais podem ser 
alterados pela função. Por isso podemos dizer que funções chamadas por referência podem retornar mais 
de um valor (o normal com return e os outros que foram modificados). Em qualquer caso, a chamada por 
referência é mais rápida, consumindo menos espaço na pilha e menos instruções. 
 
Em C++ os argumentos podem possuir um valor padrão, definido no cabeçalho da função: 
 
int minha_funcao(int a, char n, double d=0.0, int c=0){ 
 instrução1; 
 instrução2; 
 ... 
} 
 
Argumentos com valores padrões só podem ser os últimos da função. Portanto o cabeçalho: 
 
int minha_funcao(int a, char n, double d=0.0, int c... 
 
É inválido porque após um argumento iniciado com valor padrão segiu-se um argumento normal. 
 
A função main() pode aceitar dois argumentos: 
 
void main(int argc, char argv[]){...} 
 
O argumento argc é o n° de argumentos na linha de comando e argv[] é uma matriz de ponteiros para 
char contendo os argumentos da linha de comando (o primeiro é o nome completo do programa). 
 
Podem existir funções com nº variável de argumentos utilizando as elipses (...): 
 
void funcao(int arg1, int arg2, ...){...} 
Linguagem de Programação C++ – Funções 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 31 
 
 Ponteiros de função 
 
Em alguns casos, para que o código torne-se funcional, é aconselhável referenciar uma função 
indiretamente por um ponteiro. Apontar para uma função é conter o endereço do início do seu código, 
representado pelo nome da função. O programa abaixo mostra como funciona a sintaxe de um ponteiro de 
função: 
 
// Ponteiros de função 
// Curso de Linguagem de Programação C++ PROG018.CPP - Silvio Sabino 
#include<iostream.h> 
 
// declarando um ponteiro que aponta para uma função do tipo void 
// sem nenhum argumento 
void (*ponteiro)(void); 
 
void funcao_1(void){ 
 cout << "\nExecutando a função 1!"; 
 return; 
} 
 
void funcao_2(void){ 
 cout << "\nExecutando a função 2!"; 
 return; 
} 
 
void main(void){ 
 
 int resposta; 
 do{ 
 cout << "\nVocê deseja executar qual função (1 ou 2)?"; 
 cin >>resposta; 
 }while(resposta!=1&&resposta!=2); 
 
 ponteiro = resposta==1?funcao_1:funcao_2; 
 ponteiro(); 
 return; 
} 
 
 
O uso de ponteiros de função é uma das portas para a programação avançada orientada por eventos, onde 
estruturas de dados genéricas são criadas e os objetos são diferenciados pelas funções apontadas. 
 
 Modificadores de acesso 
 
C++ pode interagir com as linguagens Pascal e Assembly. Para que uma função possa ser utilizada por 
um programa escrito em Pascal, ela deve ser modificada com a palavra reservada pascal. Assim a ordem 
de empilhamento dos argumentos seguirá o padrão da linguagem Pascal: do primeiro para o último (em 
C++ é o inverso). Diversamente, para garantir que a ordem de empilhamento dos argumento siga o padrão 
C++ deve-se utilizar cdecl. 
 
Assim como os dados referenciados por ponteiros, as funções também podem estar localizadas em 
segmentos de código diferentes. Com o uso dos modificadores near e far o compilador pode forçar uma 
chamada somente utilizando deslocamento (near) ou segmento e deslocamento (far). Chamadas distantes 
(far) tornam todo o processo mais lento. 
 
Linguagem de Programação C++ – Funções 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 32 
 inline 
 
Algumas vezes é vantajogo expandir em linha uma função pequena. Isso acontece porque existe um 
código mínimo para chamar a função envolvendo pilha, argumentos e endereçamento que pode ser de 
tamanho ou tempo de execução maior do que a colocação do código da função diretamente no local. Para 
que o programador possa sugerir a expansão em linha, usamos a palavra reservada inline. A limitação é 
que não podem haver laços na função “candidata” para a expansão. 
 
 Recursividade 
 
Muitos problemas possuem solução recursiva ou recorrente, ou seja, a solução chama a si própria até que 
uma condição básica seja satisfeita e ela começa a retornar. O fatorial de um número é um exemplo 
clássico de aplicação de recursividade. Observe a função fatorial recursiva: 
 
long fatorial(int n){ 
 return(n<2?1:n*fatorial(n-1)); 
} 
 
Sem dúvida, a recursividade torna o código claro. No exemplo do fatorial, a função chamará a si mesma 
até que o argumento n seja menor do que 2. Nesse ponto ela começa a retornar as chamadas acumuladas 
na pilhaaté a primeira. Para comparação, abaixo segue uma função de forma iterativa para o mesmo fim: 
 
long fatorial(int n){ 
 long resultado=1; 
 if(n>1)for(register int i=n;i<2;i--)resultado=resultado*i; 
 return(resultado); 
} 
 
 Sobrecarga 
 
C++ permite que mais de uma função possua o mesmo nome, desde que sejam de tipos diferentes ou 
tenham argumentos diferentes. Isso ajuda o programador porque só haverá um nome para a mesma tarefa, 
que poderá aceitar diferentes tipos de argumentos. Destrutores não podem ser sobrecarregados. O 
programa abaixo calcula o cubo de um número e aceita um argumento int ou float: 
 
// Ilustrando a sobrecarga de função 
// Curso de Linguagem de Programação C++ PROG019.CPP - Silvio Sabino 
 
#include<iostream.h> 
 
int cubo(int n){ 
 return (n*n*n); 
} 
 
float cubo(float n){ 
 return (n*n*n); 
} 
 
void main(void){ 
 int inteiro; 
 float real; 
 
 cout << "\nDigite um valor inteiro: "; 
 cin >>inteiro; 
 cout << "\nDigite um valor real: "; 
 cin >>real; 
 
Linguagem de Programação C++ – Funções 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 33 
 cout << "\nO cubo do valor inteiro ‚: " << cubo(inteiro); 
 cout << "\nO cubo do valor real ‚ : " << cubo(real); 
 return; 
} 
 
Com exceção de ., .*, ::, ?:, os operadores em C++ são sobrecarregáveis para desempenhar funções 
diferentes das originais. Uma sobrecarga que já conhecemos é a dos operadores de deslocamente de bits 
<< e >> que são utilizados com os fluxos de entrada e saída cin e cout, que correspondem a stdin e stdout 
em C. A sobrecarga de operador é realizada pela palavra reservada operator, cuja sintaxe é: 
 
operator <símbolo> (argumentos) { 
 instruções 
} 
 
Operadores sobrecarregados podem ser membros de uma class: 
 
nome_da_classe::operator <símbolo> (argumentos){ 
 instruções 
} 
 
A definição da sobrecarga deve ter parâmetros de um tipo de class ou deve ser membro de uma class e a 
precedência do operador não sofre alteração. O programa abaixo sobrecarrega o operador + para somar as 
partes real e imaginária de dois números complexos e para concatenar duas strings. Atenção nos detalhes. 
 
// Sobrecarga de operador e outras aplicações 
// Curso de Linguagem de Programação C++ PROG020.CPP - Silvio Sabino 
 
#include<string.h> 
#include<iostream.h> 
 
// criando uma struct para representar números complexos 
struct complex{ 
 
 double real; // parte real 
 double imag; // parte imaginária 
 
 // construtor para a classe complex com argumento padrão 
 complex(double real, double imag=0){ 
 this->real=real; 
 this->imag=imag; 
 } 
 
 // construtor sobrecarregado sem argumentos 
 complex(void){ 
 real=0; 
 imag=0; 
 } 
}; 
 
// criando a classe string para ser utilizada como parâmetro 
// de operator 
class string { 
 
 // ponteiro para char manipulado pelo objeto 
 // nenhuma outra parte do programa pode acessar diretamente 
 // o conteúdo desse ponteiro 
 char *str; 
 
 //comprimento máximo permitido 
 int n; 
Linguagem de Programação C++ – Funções 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 34 
 
 // tornando públicas as funções do objeto para que o programa 
 // possa invocá-las 
 public: 
 
 // atribuindo uma cadeia à str 
 // note como o argumento str é diferenciado do ponteiro str que 
 // faz parte do objeto usando-se o ponteiro this, pois as instâncias 
 // não são variáveis globais e por isso :: não funciona nesse caso 
 int setstr(char *str){ 
 if(!this->str||n<strlen(str))return(1); 
 strcpy(this->str,str); 
 return(0); 
 } 
 
 //obtendo o conteúdo de str 
// o uso do ponteiro temp evita que o processo externo 
 // obtenha o endereço de str, podendo obter apenas o 
 // conteúdo apontado por ele 
 char *getstr(void){ 
 char *temp=new char[strlen(str)+1]; 
 return(strcpy(temp,str)); 
 } 
 
 // sobrecarregando + para concatenar strings; 
 char *string::operator+(string &str1){ 
 char *temp=new char[strlen(str)+1]; 
 strcpy(temp,str); 
 return(strcat(temp,str1.getstr())); 
 } 
 
 // construtor da classe, que aloca memória 
 // de acordo com o número de itens informado 
 // pelo processo anterior 
 string(int itens=0){ 
 n=itens; 
 str=n?new char[n]:NULL; 
 } 
 
 // liberando o espaço alocado para o ponteiro str 
 // e destruindo o objeto 
 ~string(void){ if(str)delete(str); } 
}; 
 
// sobrecarregando o mesmo operador para somar as partes real 
// e imaginária de dois números complexos 
complex operator+(complex n1, complex n2){ 
 return(complex(n1.real+n2.real,n1.imag+n2.imag)); 
} 
 
// programa principal 
void main(void){ 
 
 // declarando objetos de classe string 
 string string1(11),string2(11),string3(22); 
 
 // declarando estruturas do tipo complex 
 complex c1(5,8), c2(2.4), c3; 
 
 string1.setstr("string1"); 
 string2.setstr(" + string2"); 
 
 // utilizando a sobrecarga do operador + para concatenar as strings 
Linguagem de Programação C++ – Funções 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 35 
 string3.setstr(string1+string2); 
 
 c3=c1+c2; 
 cout << "\nresultado com *char : " << string3.getstr(); 
 cout << "\nresultado com complex: " << c3.real << " " << c3.imag; 
} 
 
 Protótipos 
 
Normalmente, uma função apenas poderá invocar outra se esta estiver escrita acima daquela: 
 
int acima(void){ ... } 
... 
int abaixo(void){ ... } 
 
No fragmento acima, a função abaixo pode chamar acima, mas não o contrário. Para que isso seja 
possível, deve ser declarado um protótipo da função abaixo antes do código de acima. 
 
int abaixo(void); 
 
 Modelos 
 
Muitas vezes uma função pode executar o mesmo trabalho com tipos de dados diferentes, sem que isso 
altere as instruções que fariam parte da função. Funções desse tipo devem ser modeladas. Para construir 
um modelo, usamos as palavras reservadas template e class: 
 
template <class tipo> nome_da_funcao(argumentos){ ... } 
 
A modelo do programa seguinte aloca espaço na memória para n elementos de qualquer tipo de dado 
conforme o argumento: 
 
// Ilustrando o uso de modelos de função e ponteiros de 2a ordem 
// Curso de Linguagem de Programação C++ PROG021.CPP - Silvio Sabino 
#include<iostream.h> 
 
// Implementando o modelo de função que aloca memória e retorna NULL 
// se não existir espaço disponível 
 
template <class tipo> tipo* aloca(tipo **ponteiro, int n){ 
 return(*ponteiro=new tipo[n]); 
} 
 
void main(void){ 
 float *flutuante=NULL; 
 int n; 
 cout << "\nEscolha o número de elementos: "; 
 cin >>n; 
 cout << (aloca(&flutuante,n)?"Alocação executada":"Espaço insuficiente!"); 
 if(flutuante)delete(flutuante); 
 return; 
} 
 
O programa apresenta um detalhe interessante além do uso do modelo de função: para que o ponteiro 
flutuante seja alterado pela função modelada aloca, é passado o seu endereço, ou seja, um ponteiro de 
ponteiro (ponteiro de 2
a
 ordem), exemplificando o seu uso. 
Linguagem de Programação C++ – Diretivas do pré-processador 
Silvio Sabino de Souza Junior – sabino@cefetjunior.com.br 36 
Diretivas do pré-processador 
 
 
Em alguns casos, deve-se compilar condicionalmente um trecho de código, incluir um arquivo ou trocar 
um texto por outro segundo definições prévias. Para tal, C++ possui várias diretivas para modificar a 
compilação. As diretivas com suas sintaxes genéricas são: 
 
#define <id1>[(id2,id3...)] <sentença>: define uma macro, que pode ser simplesmente uma expressão

Outros materiais