Você está na página 1de 51

apêndice B

Guia de Sintaxe ANSI/ISO


Padrão C++

Sumário
B.1 Elementos da linguagem B.12 Operadores new e delete
B.2 Tipos de dados B.13 Arrays
B.3 Constantes B.14 Enumerações, estruturas e uniões
B.4 Conversão de tipos B.15 Cadeias
B.5 Declaração de variáveis B.16 Funções
B.6 Operadores B.17 Classes
B.7 Entradas e saídas básicas B.18 Herança
B.8 Sentenças B.19 Sobrecarga de operadores
B.9 Sentenças condicionais: if B.20 Modelos (templates)
B.10 Laços: sentenças repetitivas B.21 Exceções
B.11 Ponteiros B.22 Espaço de nomes (Namespaces)

1
INTRODUÇÃO
C++ é considerado um C maior e mais potente. Neste apêndice, serão mostradas as regras de
A sintaxe de C++ é uma extensão de C, na qual sintaxe do padrão clássico de C++, retiradas do
foram acrescentadas numerosas propriedades, Annotated Reference Manual (ARM), de Strous-
fundamentalmente orientadas a objetos. C ANSI1 trup e Ellis, bem como as últimas propostas in-
já adotou inúmeras características de C++, por corporadas ao novo rascunho de C++ ANSI, que
esse motivo, a emigração de C a C++ não costu- está incluído nas versões 3.0 (atual) e 4.0 (futura)
ma ser difícil. de AT&T C++.

1
  Utiliza-se indistintamente os termos ANSI C (nome em inglês) e C ANSI, tradução para o espanhol muito usada na vida profissional
e acadêmica.

2
Guia de Sintaxe ANSI/ISO Padrão C++    3

B.1 ELEMENTOS DA LINGUAGEM


Um programa em C++ é uma seqüência de caracteres que são agrupados em componentes léxicos (tokens) que
compreendem o vocabulário básico da linguagem. Esses componentes de léxico são: palavras reservadas, iden-
tificadores, constantes, constantes de cadeia, operadores e sinais de pontuação.

B.1.1 Caracteres
Os caracteres que podem ser utilizados para construir elementos da linguagem (componentes léxicos ou tokens)
são:

a b c d e f g h i j k l m n o p q r s t u v w x y z
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
0 1 2 3 4 5 6 7 8 9
+ - * / = ( ) { } [ ] < > ‘ ” ! @  / $ ^ & % - : . , ; ? \ |

caracteres espaço (branco e tabulações).

B.1.2 Comentários
C++ suporta dois tipos de comentários. As linhas de comentários ao estilo C e ANSI C, tal como:

/* Comentário estilo C */, pode ser estendido


/* até que aparece a marca de fechar */
// Este tipo de comentário termina ao final da linha
// Somente é possível uma linha de comentário

A versão /*...*/ é utilizada para comentários que excedam o comprimento de uma linha e a versão
/  /... é utilizada somente para comentários de uma linha.
Os comentários não se aninham.

B.1.3 Identificadores
Os identificadores (nomes de variáveis, constantes etc.) devem começar com uma letra do alfabeto (maiúscula
ou minúscula) ou com um caractere sublinhado e podem ter um ou mais caracteres. Os caracteres segundo e
posteriores podem ser letras, dígitos ou um sublinhado, não sendo permitidos caracteres alfanuméricos nem
espaços.

teste_prova //legal
X123 //legal
multi_palavra //legal
var25 //legal
15var //não legal

C++ é sensível a maiúsculas. As letras maiúsculas e minúsculas são consideradas diferentes.


Pagamento_mês é um identificador diferente de pagamento_mês

Para uma boa prática de programação, é aconselhável utilizar identificadores significativos que ajudam a
documentar um programa.

nome sobrenome salário preço_líquido


Idade Comprimento Altura Salário_mês
4   Programação em C++: Algoritmos, estruturas de dados e objetos

B.1.4 Palavras reservadas


As palavras reservadas ou chaves não podem ser utilizadas como identificadores por causa do seu significado
restrito em C++; nem podem ser redefinidas. A Tabela B.1 enumera as palavras reservadas de C++, segundo o
ARM.2

Tabela B.1 Palavras reservadas (Keywords) de ANSI/ISO C++

asm* default for new* sizeof* typedef


auto delete* friend* operator* static typename
bool* do goto private* struct union
break double if protected switch unsigned
case else inline* public* template* using
catch* enum int register this* virtual*
char explicit* long return throw* void
class* extern mutable* short true* volatile*
const false* namespace* signed try* while
continue float

* Estas palavras não existem em ANSI C.

Os diferentes compiladores comerciais de C++ podem incluir novas palavras reservadas. Estes são os casos
de Borland, Microsoft e Symantec.

Tabela B.2 Palavras reservadas de Borland C++

_ _asm _ _cdecl _ _cs _ _declspec _ _ds


_ _es _ _except _ _export _ _far _ _fastcall
_ _finally _ _huge _ _import _ _interrupt _ _loadds
_ _near _ _pascal _ _rtti _ _saveregs _ _seg
_ _ss _ _stdcall _ _thread _ _try _asm
_cdecl _cs _ds _es _export
_far _fastcall _huge _import _interrupt
_loadds _near _pascal _saveregs _seg
_ss _stdcall asm auto bool
break case catch cdecl char
class const const_cast continue default
delete do double dynamic_cast else
enum explicit extern false far
float for friend goto huge
if inline int interrupt long
mutable namespace near new operator
pascal private protected public register
reinterpret_cast return short signed sizeof
static static_cast struct switch template
this throw true try typedef
typeid typename union unsigned using
virtual void volatile wchar_t while
Guia de Sintaxe ANSI/ISO Padrão C++    5

Tabela B.3 Palavras reservadas de Visual C++

_asm _fastcall public signed


_except new unsigned void
_virtual_inheritance typedef using directive do
throw class default _leave
case goto _int8 struct
_finally register sizeof auto
operator using declaration volatile explicit
typeid uuid double mutable
const delete long true
if _int16 switch catch
reinterpret_cast static template flota
return wmain _based private
_uuidof dynamic-cast extern typename
d11export man naked const-cast
_int32 _multiple try inline
_inheritance
static-cast this _cdecl _inline
while bool for short
else false protected virtual
enum namespace union dllimport
-single-inheritance _try continue _int64
thread char _declspec _stdcall
break friend int xalloc

O comitê ANSI acrescentou novas palavras reservadas (Tabela B.4).

Tabela B.4 Novas palavras reservadas de ANSI C++

bool false reinterpret_cast typeid


const_cast mutable static_cast using
dynamic_cast namespace true wchar_t

B.2 TIPOS DE DADOS


Os tipos de dados em C++ são divididos em dois grandes grupos: integrais (dados inteiros) e de ponto flu­tuante
(dados reais). A Tabela B.5 mostra os diferentes tipos de dados em C++.

Tabela B.5 Tipos de dados simples em C++

char signed char unsigned char


short int long
unsigned short unsigned unsigned long
float double long double

Os tipos derivados em C++ podem ser:

• enumerações (enum)
• estruturas (struct)
• uniões (união)
• arrays
• classes (classe e struct)
• uniões e enumerações anônimas
• ponteiros
6   Programação em C++: Algoritmos, estruturas de dados e objetos

B.2.1 Verificação de tipos


A verificação ou comprovação de tipos em C++ é mais rígida (restrita) que em C.
• Usar funções declaradas. Essa ação é ilegal em C++ e é permitida em C:
int main ( )
{
//...
printf (x); //C: int printf ( );
//C++ é ilegal, já que printf não é
//permitida devolve um int
return 0;
}

• Falha ao devolver um valor de uma função. Uma função em C++ declarada com um tipo determinado de
retorno deve devolver um valor desse tipo. Em C, é permitido não seguir a regra.
• Atribuição de ponteiros void. A atribuição de um tipo void* a um ponteiro de outro tipo deve ser feita
com uma conversão explícita em C++. Em C, é realizada implicitamente.
• Início de constantes de cadeia. Em C++, devemos proporcionar um espaço para o caractere de terminação
nulo quando se inicializam constantes de cadeia. Em C, é permitida a ausência desse caractere.
int main( )
{
//...
char car[7] = “Cazorla”, //legal em C
//erro em C++
//...
return 0;
}

Uma solução para o problema que funciona tanto em C como em C++ é:


char car[8] = “Cazorla”;

B.3 CONSTANTES
C++ contém constantes para cada tipo de dado simples (integer, char etc.). As constantes podem ter três
sufixos, u, l e f, que indicam tipos unsigned, long e float, respectivamente. Assim, podem-se acrescentar
os prefixos o ou ox que representam constantes octais e hexadecimais.
456 0456 Ox456 //constantes inteiras: decimal, octal,
//hexadecimal
1231 123u1 //constantes inteiras: long, unsigned
//long
‘B’ ‘b’ ‘4’ //constantes tipo char
3.1415f 3.14159L //constantes reais de diferente posição
“cadeia de caracteres” //constantes de cadeia

As cadeias de caracteres estão entre aspas e as constantes de um só caractere estão entre apóstrofos.
“ ” //cadeia vazia, ‘\0’

Uma constante literal é um valor escrito diretamente no programa sempre que seja necessário. Por exemplo:
int minhaIdade = 25;

minhaIdade é uma variável de tipo int; 25 é uma constante literal.


Guia de Sintaxe ANSI/ISO Padrão C++    7

B.3.1 Declaração de constantes com const

Em C++, os identificadores de variáveis/constantes podem ser declarados como constantes, significando que
têm um valor de início, mas que não pode ser modificado. Essas constantes são denominadas simbólicas.
Essa declaração é efetuada com a palavra reservada const.

const double PI = 3.1416;


const char BRANCO = ‘ ’;
const double PI_EG = PI;
const double Double_PI = 2*PI;

O modificador de tipos const também se utiliza em C++ para proporcionar proteção somente de leitura
para variáveis e parâmetros de funções. As funções-membro de uma classe que não modificam os membros
dado que são acessados podem ser declarados const. Esse modificador evita também que parâmetros passados
por referência sejam modificados:

void copy (const char* fonte, char* destino);

B.3.2 Declaração de constantes com #define

C++ suporta também o método tradicional de declaração de constantes, ainda que agora esteja obsoleto. Para
declarar uma constante por esse método, devemos realizar com #define.

#define estudantePorChave 50
#define PI 3.1416
#define hex 16

B.4 CONVERSÃO DE TIPOS


As conversões explícitas são forçadas mediante moldes (casts). A conversão forçosa de tipos de C++ tem o
formato clássico:

(tipo) expressão

C++ modificou a notação anterior por uma notação funcional como alternativa sintática:

nome do tipo (expressão)

As seguintes notações são equivalentes:

z = float(x); //notação de moldes em C++


z = (float)x; //notação de moldes em C

B.5 DECLARAÇÃO DE VARIÁVEIS


Em ANSI C++, todas as declarações de variáveis e funções devem ser feitas no princípio do programa ou
função. Sendo necessárias declarações adicionais, o programador deve voltar ao bloco de declarações ao obje-
to e fazer os ajustes ou inserções necessários. Todas as declarações devem ser feitas antes que seja executada
qualquer sentença. Assim, a declaração típica em C++

NomeTipo NomeVariável, NomeVariável2, ...


8   Programação em C++: Algoritmos, estruturas de dados e objetos

proporciona declarações como:


int saldo, meses;
double clipper, salário;

Como em C, podemos atribuir valores às variáveis em C++:


int mês = 4, dia, ano = 1995;
double salário = 45.675;

Em C++, as declarações de variáveis podem ser situadas em qualquer parte de um programa. Essa caracte-
rística faz que o programador declare suas variáveis próximo ao lugar onde são utilizadas as sentenças de seu
programa. O seguinte programa é legal em C++, mas não é válido em C:

#include <iostream.h>
int main( )
{
int i;
for (i=0; i < 100; ++i)
cout << i << endl;

double j;
for (j = 1.7547; j < 25.4675; j+= .001)
cout << j << endl;
}

O programa anterior poderia ser reescrito, fazendo a declaração e a definição dentro do mesmo laço:

int main( )
{
for (int i=0; i<100; ++i)
cout << i << end1;

for (double j = 1.7545; j < 25.4675; j += .001)


cout << j << end1;
}

B.6 OPERADORES
C++ é uma linguagem muito rica em operadores, classificados nos seguintes grupos:

• Aritméticos.
• Relacionais e lógicos.
• Atribuição.
• Acesso a dados e tamanho.
• Manipulação de bits.
• Vários.

Como conseqüência da grande quantidade de operadores, é produzida também uma grande quantidade de
diferentes expressões.

B.6.1 Operadores aritméticos


C++ proporciona diferentes operadores que relacionam operações aritméticas.
Guia de Sintaxe ANSI/ISO Padrão C++    9

Tabela B.6 Operadores aritméticos em C++

Operador Nome Propósito Exemplo

+ Mais unitário Valor positivo de x x = + y + 5


– Negação Valor negativo de x x = - y;
+ Adição Soma x e y z = x + y;
– Subtração Subtrai y de x z = x - y;
* Multiplicação Multiplica x por y z = x * y;
/ Divisão Divide x por y z = x/y;
% Módulo Resto de x dividido por y z = x%y;
++ Incremento Incrementa x depois de usar x++
– – Decremento Decrementa x antes de usar – –x

Exemplos

-i + w; //menos unitário mais unitário


a*b/c%d //multiplicação, divisão, módulo
a+b a–b //soma e subtração binárias
a=5/2; //a recebe o valor 2, se a for considerado inteiro
a=5./2; //a recebe o valor 2.5, se a for real

Os operadores de incremento e decremento servem para incrementar e decrementar em um os valores


armazenados em uma variável.

variável++ //pós-incremento
++variável //pré-incremento
variável-- //pós-decremento
-- variável //pré-decremento
++a; equivale a a = a + 1;
--b; equivale a b = b - 1;

Os formatos pós-fixos ficam de forma diferente segundo a expressão que seja aplicada:

b = ++a; equivale a a = a+1; b = a;


b = a++; equivale a b + a; a = a+1;

int i, j, k = 5
k++; //k vale 6, mesmo efeito que ++k
--k //k vale agora 5, mesmo efeito que k--
k = 5;
i = 4*k++; //k é agora 6 e i é 20
k = 5;
j = 4 * ++k; //k é agora 6 e i é 24

B.6.2 Operadores de atribuição

O processador de atribuição (=) faz que o valor situado à direita do operador seja aplicado à variável situada à
sua esquerda. A atribuição costuma ocorrer como parte de uma expressão de atribuição e as conversões são
produzidas implicitamente.

z = b+5; //atribui (b+5) à variável z


10   Programação em C++: Algoritmos, estruturas de dados e objetos

C++ permite múltiplas atribuições em uma única sentença. Assim,

a = b+ (c=10);

equivale a:

c=10;
a=b+c;

Outros exemplos de expressões válidas e não-válidas são:

//expressões legais //expressões não legais


a=5 * (b+a); a+3 = b;
double x = y; PI = 3;
a=b=6; x++ = y;

C++ proporciona operadores de atribuição que combinam operadores de atribuições e outros diferentes, pro-
duzindo operadores como +=, /=, -=, *= e %=. C++ suporta outros tipos de operadores de atribuição para mani-
pulação de bits.

Tabela B.7 Operadores aritméticos de atribuição

Operador Formato aberto Formato curto

+= x = x + y; x + = y;
-= x = x - y; x - = y;
*= x = x * y; x * = y;
/= x = x/y; x / = y;
%= x = x%y; x % = y;

Exemplos

a + = b; equivale a a = a + b;
a * = a + b equivale a a = a * (a+b);
v + = e; equivale a v = v + e;
v % = e; equivale a v = v%e;

Expressões equivalentes
n = n+1;
n += 1;
n++;
++n;

B.6.3 Operadores lógicos e relacionais

Os operadores lógicos e relacionais são os blocos de construção básicos para construções de tomada de posição
em uma linguagem de programação. A Tabela B.8 mostra os operadores lógicos e relacionais.
Guia de Sintaxe ANSI/ISO Padrão C++    11

Tabela B.8 Operadores lógicos e relacionais

Operador Nome Exemplo

&& AND (e) lógico a && b


| | OR (ou) lógico C || d
! NOT (não) lógico !C
< Menor que i < 0
<= Menor que ou igual a i <= 0
> Maior que j > 50
>= Maior que ou igual a j >= 8.5
= = Igual a x == ‘\0’
!= Não igual a c != ‘/n’
?: Atribuição condicional k = (i < 5)? 1: i;

O operador ?: é conhecido como expressão condicional. A expressão condicional é uma abreviação da


sentença condicional if-else. A sentença if
if (condição)
variável = expressão1;
else
variável = expressão2;
é equivalente a:
variável =(condição) ? expressão1 : expressão2;

A expressão condicional comprova a condição. Se essa condição é verdadeira, é atribuída expressão1 à


variável; caso contrário, é atribuída expressão2 à variável.

Regras práticas
Os operadores lógicos e relacionais atuam sobre valores lógicos: o valor falso pode ser ou 0 ou o ponteiro nulo;
o valor verdadeiro pode ser qualquer valor diferente de zero. A tabela seguinte mostra os resultados de diferen-
tes expressões.

x > y 1, se x excede y, se não 0


x >= y 1, se x é maior que ou igual a y, se não 0
x < y 1, se x é menor que y, se não 0
x <= y 1, se x é menor que ou igual a y, se não 0
x == y 1, se x é igual a y, se não 0
x!= y 1, se x e y são distintos, se não 0
!x 1, se x é 0, se não 0
x || y 0, se ambos x e y são 0, se não 1

Avaliação em curto-circuito
C++, como C, admite reduzir o tempo das operações lógicas; a avaliação das expressões é reduzida quando
algum dos operandos recebe valores concretos.

1. Operação lógica AND (&&). Se na expressão exprl && expr2, expr1 recebe o valor zero e a opera-
ção lógica AND (e) sempre será 0, seja qual foi o valor de expr2. Conseqüentemente, expr2 não será
avaliada nunca.
2. Operação lógica OR (||). Se expr1 recebe um valor diferente de zero, a expressão expr1 || expr2
será avaliada a 1, qualquer que seja o valor de expr2; portanto, expr2 não será avaliada.
12   Programação em C++: Algoritmos, estruturas de dados e objetos

B.6.4 Operadores de manipulação de bits


C++ proporciona operadores de manipulação de bits, assim como operadores de atribuição de manipulação
de bits.

Tabela B.9 Operadores de manipulação de bits (bitwise)

Operador Significado Exemplo

& AND bit a bit x & 128


| OR bit a bit j | 64
^ XOR bit a bit j ^ 12
~ NOT bit a bit ~j
<< Deslocar para a esquerda i << 3
>> Deslocar para a direita j >> 4

Tabela B.10 Operadores de atribuição de manipulação de bits

Operador Formato aberto Formato reduzido

&= x = x & y; x &= y;


|= x = x | y; x |= y;
^= x = x ^ y; x ^= y;
<<= x = x << y; x << = y;
>>= x = x >> y; x >> = y;

Exemplos
~x Muda os bits 1 a 0 e os bits 0 a 1
x & y Operação lógica AND (e) bit a bit de x e y
x | y Operação lógica OR (ou) bit a bit de x e y
x << y x é deslocado para a esquerda (em y posições)
x >> y x é deslocado para a direita (em y posições)

B.6.5 O operador sizeof


O operador sizeof proporciona o tamanho em bytes de um tipo de dado ou variável. sizeof assume o
argumento correspondente (tipo escalar, array, record etc.). A sintaxe do operador é:

sizeof (nome_variável / tipo_de_dado)

Exemplos
int m, n[12];
sizeof(m) //proporciona 4, em máquinas de 32 bits
sizeof(n) //proporciona 48
sizeof(15) //proporciona 4
tamanho = sizeof(long) – sizeof(int);

B.6.6 Prioridade e associatividade de operadores


Quando são realizadas expressões nas quais se misturam operadores diferentes, é preciso estabelecer uma
precedência (prioridade) dos operadores e a direção (ou seqüência) de avaliação (ordem de avaliação: es-
querda-direita, direita-esquerda), denominada associatividade.
Guia de Sintaxe ANSI/ISO Padrão C++    13

A Tabela B.11 mostra a precedência e a associatividade de operadores.

Tabela B.11 Precedência e associatividade de operadores

Operador Associatividade Prioridade

::.->[ ]( ) ++ -- Esquerda-Direita 1


++ -- & (direção) (tipo) ! - + ~ Direita-Esquerda 2
sizeof (tipo) new delete *(sem direção)
.* ->* Esquerda-Direita 3
* / % Esquerda-Direita 4
+ - Esquerda-Direita 5
<< >> Esquerda-Direita 6
< <= > >= Esquerda-Direita 7
= = != Esquerda-Direita 8
& Esquerda-Direita 9
^ Esquerda-Direita 10
| Esquerda-Direita 11
&& Esquerda -Direita 12
|| Esquerda-Direita 13
?: Direita-Esquerda 14
= += -= *= /= %= >>= <<= &= /= ^= Direita-Esquerda 15
(operador ponto) Esquerda-Direita 16

Exemplo
a * b/c + d equivale a ((a*b)/(c+d)

B.6.7 Sobrecarga de operadores


A maioria dos operadores de C++ pode ser sobrecarregada ou redefinida para trabalhar com novos tipos de
dados. A Tabela B.12 lista os operadores que podem ser sobrecarregados.

Tabela B.12 Operadores que podem ser sobrecarregados

+ - * / % ^ & |
~ ! = < > += -= *=
/= %= ^= &= |= << >> >>=
<<= == != <= >= && || ++
-- , ->* -> ( ) [ ]

B.7 ENTRADAS E SAÍDAS BÁSICAS


Ao contrário de muitas linguagens, C++ não tem facilidades incorporadas para manusear entrada ou saída.
Essas operações são realizadas mediante rotinas de bibliotecas. As classes que C++ utiliza para entrada e saída
são conhecidas como fluxos. Um fluxo é uma seqüência de caracteres, juntamente com uma coleção de rotinas,
para inserir caracteres em fluxos (a tela) e extrair caracteres de um fluxo (de teclado).

B.7.1 Saída
O fluxo cout é o fluxo de saída-padrão que corresponde a stdout em C. Esse fluxo deriva da classe ostream
construída em iostream.
14   Programação em C++: Algoritmos, estruturas de dados e objetos

Unidade
cout Tela
central entrada binária saída de caracteres

Figura B.1 Uso de fluxos para saída de caracteres.

Desejando-se visualizar o valor do objeto int chamado i, escreve-se a sentença

cout << i;

O seguinte programa visualiza na tela uma frase:

#include <iostream.h>
int main( )
{
cout << “Olá, mundo\n”;
}

As saídas em C++ podem ser conectadas em cascata, com uma facilidade de escrita maior que em C.

#include <iostream.h>
int main( )
{
int i;
i = 1099;
cout << “O valor de i é” << i << “\n”;
return 0
}

Outro programa que mostra a conexão em cascata é:

#include <iostream.h>
int main( )
{
int x = 45;
double y = 495.125;
char *c = “e multiplicada por x=”;
cout << c << y*x << “\n”;
}

B.7.2 Entrada
A entrada é manuseada pela classe istream. Existe um objeto predefinido istream chamado cin que se refere
ao dispositivo de entrada-padrão (o teclado). O operador utilizado para obter um valor do teclado é o operador
de extração >>. Por exemplo, se i era um objeto int, será escrito:

cin >> i;

que obtém um número do teclado e o armazena na variável i.

Um programa simples que lê um dado inteiro e o visualiza na tela é:

#include <iostream.h>
int main( )
Guia de Sintaxe ANSI/ISO Padrão C++    15

{
int i;
cin >> i;
cout << i << “\n”;
}

Como no caso de cout, podem ser introduzidos dados em cascata:

#include <iostream.h>
int main( )
{
char c[60];
int x,y;

cin >> c >> x >> y;


cout << c << “ ” << x << z << y << “\n”;
}

B.7.3 Manipuladores
Um método fácil de mudar a largura do fluxo e outras variáveis de formato é utilizar um operador especial
denominado manipulador. Um manipulador aceita uma referência de fluxo como um argumento e devolve uma
referência ao mesmo fluxo.
O programa seguinte mostra o uso de manipuladores especificamente para conversões de número
(dec, oct e hex):

#include <iostream.h>
int main( )
{
int i = 36;
cout << dec << i << oct << i “ ” hex << i <<“\n”;
}

A saída desse programa é:

36 44 24

Outro manipulador típico é end1, que representa o caractere de nova linha (salto de linha), e é equivalente a
‘n\’. O programa anterior pode ser escrito também assim:

#include <iostream.h>
int main( )
{
int i = 36;
cout << dec << i “ ” << oct << i <<“ ” << hex << i << end1;
}

B.8 SENTENÇAS
Um programa em C++ consta de uma seqüência de sentenças. Existem diversos tipos de sentença. O ponto-e-vírgula
é utilizado como elemento terminal de cada sentença.
16   Programação em C++: Algoritmos, estruturas de dados e objetos

B.8.1 Setenças de declaração


Utilizam-se para estabelecer a existência e, opcionalmente, os valores iniciais de objetos identificados pelo nome.

NomeTipo identificador, ...;


NomeTipo identificador = expressão, ...;
const NomeTipo identificador = expressão, ...;

Algumas sentenças válidas em C++ são:

char c1;
int p, q = 5, r = a+b; //supondo que a e b tenham sido
//declaradas e iniciadas com antecedência
const double IVA = 16.0;

B.8.2 Sentenças de expressão


As sentenças de expressões fazem que a expressão seja avaliada. Seu formato geral é:

expressão;

Exemplos
n++;
425; //legal, mas não faz nada
a+b; //legal, mas não faz nada
n = a < b || b != 0;
a += b = 3; //sentença complexa

C++ permite múltiplas atribuições em uma sentença.

m = n +(p = 5); equivale a p = 5


m = n + p;

B.8.3 Sentenças compostas


Uma sentença composta é uma série de sentenças entre chaves. As sentenças compostas têm o formato:

{
sentença
sentença
sentença
...
}

As sentenças fechadas podem ser qualquer uma: declarações, expressões, sentenças compostas etc. Um
exemplo é:

{
int i = 5;
double x = 3.14, y = -4.25;
int j = 4–i;
x = 4.5.*(x–y);
}

O corpo de uma função C++ é sempre uma sentença composta.


Guia de Sintaxe ANSI/ISO Padrão C++    17

B.9 SENTENÇAS CONDICIONAIS: if


O formato geral de uma sentença if é:

if (expressão) if (expressão) {
sentença <seqüência de sentenças>
}

Se expressão for verdadeira (diferente de zero), então são executadas sentença ou seqüência de
sentenças; caso contrário, salta-se a sentença. Depois que a sentença if foi executada, o controle passa para
a sentença seguinte.
Exemplo 1
if (a < 0)
 negativos++;

Se a variável a for negativa, incrementamos a variável negativos.


Exemplo 2
if (númeroDeDias < 0)
númeroDeDias = 0;
if (( altura – 5) < 4){
área = 3.14 * raio * raio;
volume = área * altura;
}
Exemplo 3
if (temperatura >= 45)
cout << “Estou em Sonora: Lindíssima, em agosto”;
cout << “Estou em VeraCruz” << temperatura << end1;

A frase “Estou em Sonora: Lindíssima, em agosto” se visualiza quando temperatura é maior


que ou igual a 45. A sentença seguinte sempre é executada.
A sentença if_else tem o formato seguinte:

1. if (expressão) 2. if (expressão)
sentença1; <seqüência de sentenças 1>
else else
sentença2; <seqüência de sentenças 2>

Se expressão é diferente de zero, a sentença1 é executada e sentença2 salta; se expressão for zero,
a sentença1 salta e sentença2 é executada. Uma vez que tenha sido executada a sentença if_else, o con-
trole passa para a sentença seguinte.
Exemplo 4
if (Número == 0)
cout << “Não será calculada a média”;
else
média = total / Número;
Exemplo 5
if (quantidade > 10){
desconto = 0.2;
preço = n * preço*(1 – desconto);
}
18   Programação em C++: Algoritmos, estruturas de dados e objetos

else {
desconto = 0;
preço = n * preço;
}

B.9.1 Sentenças if_else aninhadas


C++ permite aninhar sentenças if_else para criar uma sentença de alternativa múltipla:

if (expressão 1)
sentença 1; | {sentença composta}
else if (expressão 2)
sentença 2; | {sentença composta}
else if (expressão N)
sentença N; | {sentença composta}
[else
sentença N+1; | {sentença composta}]

Exemplo
if (a > 100)
if (b <= 0)
SomaP = 1;
else
SomaN = 1;
else
Número = 1;

B.9.2 Sentenças de alternativa múltipla: switch


A sentença switch oferece uma forma de realizar decisões de múltiplas alternativas. O formato de switch é:

switch (expressão)
{
case constante 1;
sentenças
break:
case constante 2;
sentenças
.
.
.
break;
case constante n:
sentenças
break;
default: //opcional
sentenças
}

A sentença switch requer uma expressão cujo valor seja inteiro. Esse valor pode ser uma constante, uma
variável, uma chamada à função ou uma expressão. O valor de constante deve ser uma constante. Ao execu-
tar a sentença, avaliamos expressão, e se seu valor coincide com uma constante, executamos as sentenças
a seguir; caso contrário, executamos as sentenças a partir de default.
Guia de Sintaxe ANSI/ISO Padrão C++    19

switch (Pontos)
{
case 10:
nota = ‘A’;
break;
case 9:
nota = ‘B’;
break;
case 7,8:
nota = ‘C’;
break;
case 5, 6:
nota = ‘D’;
break;
default:
nota = ‘F’;
}

B.10 LAÇOS: SENTENÇAS REPETITIVAS


Os laços servem para efetuar tarefas repetitivas. Em C++, existem três diferentes tipos de sentenças repetitivas:

• while.
• do.
• for.

B.10.1 Sentença while


A sentença while é um laço condicional que se repete enquanto a condição é verdadeira. O laço while nunca
pode iterar se a condição comprovada for inicialmente falsa. A sintaxe da sentença while é:

while (expressão)
sentença;
ou

while (expressão){
< seqüência de sentenças >
}

Exemplo
int n, soma = 0;
int i = 1;
while (i <= 100)
{
cout <<“Entrar”;
cin >> n;
soma += n;
i++;
}
cout <<“A média é” << double (soma)/100.0;

B.10.2 Sentença do
A sentença do atua como a sentença while. A única diferença real é que a avaliação e o teste de saída do laço
são feitos depois que o corpo do laço foi executado, e não antes. O formato é:
20   Programação em C++: Algoritmos, estruturas de dados e objetos

do
sentença
while (expressão);
sentença seguinte

Executamos sentença e, a seguir, avaliamos expressão, e se for verdadeira (diferente de zero), o con-
trole passa novamente ao princípio da sentença do, e o processo se repete até que expressão seja falso (zero)
e o controle passe para a sentença seguinte.
Exemplo
int n, soma = 0;
int i = 1;
do
{
cout <<“Entrar”;
cin >> n;
soma += n;
i++;
} while (i <=100);
cout << “A média é” << double soma)/100.0;

O seguinte exemplo visualiza os quadrados de 2 a 10:

int i = 2;
do
{
cout << i << “por” << i <<“ =” << i * i++ << end1;
}while (i < 11);

B.10.3 Sentença for


Uma sentença for executa a iteração de um laço um número determinado de vezes. for tem três componentes:
expressão1 inicializa as variáveis de controle do laço; expressão2 é a condição que determina se o laço
realiza outra iteração; a última parte do laço for é a cláusula que incrementa ou decrementa as variáveis de
controle do laço. O formato geral de for é:

for (expressão1; expressão2; expressão3)


sentença;|{<seqüência de sentenças>};

expressão1 é utilizada para inicializar a variável de controle do laço; a seguir, expressão2 é avaliada; se
for verdadeira (diferente de zero), executa-se a sentença e se avalia expressão3, e o controle passa de novo
ao princípio do laço. A iteração continua até que expressão2 seja falsa (zero) cujo momento o controle passa
para a sentença seguinte do laço.
Exemplo
1. for (int i = 0; i < n; i++) //realizam-se n iterações
sentenças

2. Soma de 100 números


int n, soma =0;
for (int i = 0; i < 100; i++)
{
cout << “Entrar”;
cin >> n;
soma += n;
}
Guia de Sintaxe ANSI/ISO Padrão C++    21

B.10.4 Sentenças break e continue


O fluxo de controle ordinário de um laço pode ser interrompido por meio das sentenças break e continue.
A sentença break produz uma saída imediata do laço for em que se encontra situada:

for (i = 0; i < 100; ++i)


{
cin >> x;
if (x < 0.0){
cout << “sair do laço” << end1;
break;
}
cout << sqrt (x) << end1;
}

A sentença break também é utilizada para sair da sentença switch.


A sentença continue termina a iteração que está sendo efetuada e começará de novo a seguinte iteração:

for (i = 0; i < 100; ++i) {


cin >> x;
if (x < 0.0)
continue;

Precaução
• Uma sentença break pode ocorrer unicamente no corpo de uma sentença for, while, do ou
switch.
• Uma sentença continue somente pode ocorrer dentro do corpo de uma sentença for, while
ou do.

B.10.5 Sentença nula


A sentença nula é representada por um ponto-e-vírgula, e não efetua nenhuma ação.

char cad[80]=“Cazorla”;
int i;

for(i=0; cad[i] !=‘\0’; i++)


;

B.10.6 Sentença return


A sentença return detém a execução da função atual e devolve o controle à função chamada. Sua sintaxe é:

return expressão;

onde o valor de expressão é devolvido como o valor da função.

B.11 PONTEIROS
Um ponteiro é uma referência indireta a um objeto de um tipo especificado. Essencialmente, um ponteiro con-
tém a posição de memória de um tipo dado.
22   Programação em C++: Algoritmos, estruturas de dados e objetos

B.11.1 Declaração de ponteiros


Os ponteiros são declarados utilizando o operador unitário. Nas sentenças seguintes, são declaradas duas va-
riáveis: n é um inteiro e p é um ponteiro a um inteiro.

int n; //n é um tipo de dado inteiro


int *p; //p é um ponteiro a um inteiro

Uma vez declarado um ponteiro, podem ser fixados o endereço ou a posição de memória do tipo que foi
apontado.

p = &n; //p se fixa ao endereço de n

Um ponteiro é declarado escrevendo-se:

   NomeTipo *NomeVariável

Uma vez declarado um ponteiro, p, o objeto que foi apontado é escrito *p e pode ser tratado como qualquer
outra variável de tipo NomeTipo.

int *p, *q, n; //dois ponteiros a int, e um int


n = -25; //n é fixado a -25
*p = 105; //*p a 105
*q = n + *p; //*q a 80

C++ trata os ponteiros a tipos diferentes como tipos diferentes:

int * ip;
double *dp;

Os ponteiros ip e dp são incompatíveis, de maneira que é um erro escrever.

dp = ip; //Erro; não se pode atribuir ponteiro a tipos


//diferentes

Podemos, entretanto, efetuar atribuições entre conteúdos, já que seria efetuada uma conversão explícita de
tipos:

*dp = *ip;

Existe um ponteiro especial (nulo) que costuma ser utilizado com freqüência em programas C++. O
ponteiro NULL tem um valor zero, que o diferencia de todos os endereços válidos. O conhecimento nos
permite comprovar se um ponteiro p é o ponteiro NULL, avaliando a expressão (p==0). Os ponteiros NULL
são utilizados somente como sinal de que aconteceu algo. Em outras palavras, se p é um ponteiro NULL, é
incorreto referenciar *p.

B.11.2 Ponteiros a arrays


Os arrays são acessados por meio dos índices:

int lista[5];
lista[3] = 5;
Guia de Sintaxe ANSI/ISO Padrão C++    23

Os arrays também podem ser acessados por meio dos ponteiros:

int lista[5]; //array de 5 elementos


int *ptr; //ponteiro a inteiro
ptr = lista; //fixa ponteiro ao primeiro elemento do array
ptr += 2; //soma 3 a ptr; ptr aponta ao 4º elemento
*ptr = 5; //estabelece o 4º elemento a 5

O nome de um array pode ser utilizado como se fosse um ponteiro ao primeiro elemento do array.

double a[10]; //p e a se referem ao mesmo array


double *p = a;

0 1 2 3 4 5 6 7 8 9

Este elemento pode ser ativado por: Este elemento pode ser ativado por:
a[0], *p ou p[0] a[6], *(p+6) ou p[6]

Se nome aponta o primeiro elemento do array, então nome+1 aponta o segundo elemento. O conteúdo do
que é armazenado nessa posição se obtém pela expressão

*(nome+1)

Ainda que as funções não possam modificar seus argumentos, se um array é utilizado como um argumen-
to de uma função, a função pode modificar o conteúdo do array.

B.11.3 Ponteiros a estruturas


Os ponteiros a estruturas são similares e funcionam igual aos ponteiros de qualquer outro tipo de dado.

struct família
{
char *marido;
char *esposa;
char *filho;
};
família mackoy; //mackoy estrutura de tipo família
família *p; //p; um ponteiro a família
p = &mackoy; //p, contém endereço de mackoy
p –> marido,“Luis Mackoy”); //iniciação
p –> esposa,“Vilma González”); //iniciação
p –> filho,“Luizinho Mackoy”); //iniciação

B.11.4 Ponteiros a objetos constantes


Quando um ponteiro é passado a um objeto grande, mas a função não modifica o objeto (por exemplo, no caso
de que somente seja desejado visualizar o conteúdo de um array), declaramos o argumento correspondente da
função como um ponteiro a um objeto constante. A declaração é:
24   Programação em C++: Algoritmos, estruturas de dados e objetos

const NomeTipo *v;

estabelece v como um ponteiro a um objeto que não pode ser modificado. Um exemplo pode ser:

void Visualizar(const ObjetoGrande *v);

B.11.5 Ponteiros a void


O tipo de dado void representa um valor nulo. Em C++, entretanto, o tipo de ponteiro void costuma ser con-
siderado como um ponteiro a qualquer tipo de dado. A idéia fundamental por trás no ponteiro void em C++ é
a de um tipo que pode ser utilizado adequadamente para acessar qualquer tipo de objeto, já que é mais ou me-
nos independente do tipo.
Um exemplo ilustrativo da diferença de comportamento em C e C++ é o segmento de programa:

int main( )
{
void *vptr;
int *iptr;

vptr = iptr;
iptr = vptr; //Incorreto em C++, correto em C
iptr = (int *), vptr; //Correto em C++
...
}

B.11.6 Ponteiros e cadeias


As cadeias em C++ são implementadas como arrays de caracteres, como constantes de cadeia e como ponteiros
a caracteres.

Constantes de cadeia
Sua declaração é semelhante a

char *Cadeia = “Meu professor”;

ou sua sentença equivale

char VarCadeia[ ] = “Meu professor”;

Desejando evitar que a cadeia seja modificada, acrescentar const à declaração

const char *VarCadeia = “Meu professor”;

Os ponteiros a cadeia são declarados:


char s[ ] ou char *s

Ponteiros a cadeias
Os ponteiros de cadeias não são cadeias. Os ponteiros localizam o primeiro elemento de uma cadeia armazenada.

char *varCadeia;
const char *Cadeiafixa;
Guia de Sintaxe ANSI/ISO Padrão C++    25

Considerações práticas
Todos os arrays em C++ são implementados mediante ponteiros:

char cadeia1[16] = “Conceito Objeto”;


char *cadeia2 = cadeia1;

As declarações seguintes são equivalentes e se referem ao caractere ‘C’:

cadeia1[0] *cadeia1 *cadeia2

B.11.7 Aritmética de ponteiros


Dado que os ponteiros são números (endereços), podem ser manipulados pelos operadores aritméticos. As
operações que são permitidas sobre ponteiros são: soma, subtração e comparação. Assim, se as sentenças se-
guintes são executadas em seqüência:

char *p; // p contém o endereço de um caractere


char a[10]; // array de dez caracteres
p = &a[0]; // p aponta o primeiro elemento do array
p++; // p aponta o segundo elemento do array
p++; // p aponta o terceiro elemento do array
p--; // p aponta o segundo elemento do array

Um exemplo de comparação de ponteiros é o seguinte programa:

#include <iostream.h>
main (void)
{
int *ptrl, *ptr2;
int a[2] = {10, 10};
ptrl =a;
cout << “ptrl é” << “ptrl << “*ptrl é” << *ptr1 << end1;
ptr2 = ptr1 + 1;
cout << “ptr2 é” << ptr2 << “*ptr2 é” << *ptr2 << end1;

//comparar dois ponteiros


if (ptr1 == ptr2)
cout << “ptr1 é igual a ptr2 \n”;

if (*ptr1 == *ptr2)
cout << ptr1 é igual a *ptr2 \n”;
else
cout << ptr1 não é igual a *ptr2\n”;
}

B.12 OPERADORES new E delete


C++ define um método para efetuar atribuição dinâmica de memória, diferente do utilizado em C, mediante os
operadores new e delete.
O operador new substitui a função malloc tradicional em C e o operador delete substitui a função free
tradicional também em C; new atribui memória e devolve um ponteiro ao último objeto criado. Sua sintaxe é:

new NomeTipo
26   Programação em C++: Algoritmos, estruturas de dados e objetos

e um objeto de sua aplicação é:

int *ptr1;
double *ptr2;
ptr1 = new int; //memória atribuída para o objeto ptr1
ptr2 = new double //memória ampliada para o objeto ptr2
*ptr1 = 5;
*ptr2 = 6.55;

Dado que new devolve um ponteiro, podemos utilizar esse ponteiro para inicializar o ponteiro em uma úni-
ca definição, como:

int* p = new int;

Se new não pode ocupar a quantidade de memória solicitada, devolve um valor NULL. O operador delete
libera a memória atribuída mediante new.

delete ptr1;

Um pequeno programa que mostra o uso combinado de new e delete é

#include <iostream.h>
void main (void)
{
char *c;

c = new char[512];
cin >> c;
cout << c << end1;

delete c;
}

Os operadores new e delete podem ser utilizados para atribuir memória a arrays, classes e outro tipo de dados.

int * i;
i = new int[2][35]; //criar o array
//atribuir o array
...
delete i; //destruir o array

Sintaxe de new e delete

new nome_tipo new int new char[100]


new nome_tipo inicializador new int(99) new char(‘C’)
new nome_tipo new (char*)
delete expressão delete p
delete[ ] expressão delete[ ]p

B.13 ARRAYS
Um array (matriz, tabela) é uma coleção de elementos dados do mesmo tipo que se identificam por meio de
um índice. Os elementos começam com o índice 0.
Guia de Sintaxe ANSI/ISO Padrão C++    27

Declaração de arrays
Uma declaração de um array tem o seguinte formato:

nomeTipo nomeVariável[n]

Alguns exemplos de arrays unidimensionais:

int ListaNum[2]; //array de dois inteiros


char ListaNomes[10]; //array de 10 caracteres

Arrays multidimensionais são:

nometipo nomeVariável[n1] [n2] ... [nx];

O seguinte exemplo declara um array de inteiros 4 × 10 × 3:

int multidim[4][10][3];

O exemplo tabela declara um array de 2 × 3 elementos:

int tabela[2][3]; //array de inteiros de 2x3 = 6 elementos

B.13.1 Definição de arrays


Os arrays se inicializam com este formato:

int a[31] = {5, 10, 15};


char cad[5] = {‘a’, ‘b’, ‘c’, ‘d’, ‘e’};
int tabela[2][3] = {{1,2,3}{3,4,5}};

As três seguintes definições são equivalentes:

char saudação[5] = “olá”;


char saudação[ ] = “olá”;
char saudação[5] = {‘h’, ‘o’, ‘l’, ‘a’, ‘\o’};

1. Os arrays podem passar como argumentos a funções.


2. As funções não podem devolver arrays.
3. Não é permitida a atribuição entre arrays. Para atribuir um array a outro, deve ser escrito o código
para efetuar as atribuições elemento a elemento.

B.14 ENUMERAÇÕES, ESTRUTURAS E UNIÕES


Em C++, um nome de uma enumeração, estrutura ou união é um nome de um tipo. Conseqüentemente, as pa-
lavras reservadas struct, union ou enum não são necessárias quando declaramos uma variável.
O tipo de dado enumerado designa um grupo de constantes inteiras com nomes. A palavra reservada enum
é utilizada para declarar um tipo de dado enumerado ou enumeração. A sintaxe é:

enum nome
{
lista_símbolos
};
28   Programação em C++: Algoritmos, estruturas de dados e objetos

onde nome é o nome da variável declarada enumerada; lista-símbolos é uma lista de tipos enumerados, aos
quais são atribuídos valores quando se declara a variável enumerada e pode-se ter um valor de inicialização.
Podemos utilizar o nome de uma enumeração para declarar uma variável desse tipo (variável de enumeração).

nome var;

Considere a seguinte sentença:

enum color {Vermelho, Azul, Verde, Amarelo};

Uma variável de tipo enumeração de cor é:

cor tela = Vermelho; //Estilo C++

Uma estrutura é um tipo de dado composto que contém uma coleção de elementos de tipos de dados dife-
rentes combinados em uma única construção da linguagem. Cada elemento da coleção é chamado membro e pode
ser uma variável de um tipo de dado diferente. Uma estrutura representa um novo tipo de dado em C++.

A sintaxe de uma estrutura é:

struct nome
{
membros
};

Um exemplo de uma variável tipo estrutura aparecem nas sentenças seguintes:

struct quadro{
int i;
float f;
};

struct quadro nome; //Estilo C


quadro nome; //Estilo C++

Uma união é uma variável que pode armazenar objetos de tipos e tamanhos diferentes. Uma união pode ar-
mazenar tipos de dados diferentes, pode armazená-los somente um de cada vez, em oposição a uma estrutura que
armazena simultaneamente uma coleção de tipos de dados. A sintaxe de uma união é:

união nome {
membros
};

Um exemplo de estrutura é:

união alfa {
int x;
char c;
};

Uma declaração de uma variável união é:

alfa w;

A forma de acessar os membros da união é mediante o operador ponto:

u.x = 145;
u.c = ‘z’;
Guia de Sintaxe ANSI/ISO Padrão C++    29

C++ admite um tipo especial de união chamado união anônima, que declara um conjunto de membros que
compartilham o mesmo endereço de memória. A união anônima não tem atribuído um nome, portanto, acessa
diretamente os elementos da união. A sintaxe de uma união anônima é:

união {
int novoID;
int contador;
};

As variáveis da união anônima compartilham a mesma posição de memória e espaço de dados.

int main( )
{
união{
int x;
float y;
double z;
};
x = 25;
y = 245.245; //o valor em y sobrescreve o valor de x
z = 9.41415; //o valor em z sobrescreve o valor de z
...
}

B.15 CADEIAS
Uma cadeia é uma série de caracteres armazenados em bytes consecutivos de memória. Uma cadeia pode ser
armazenada em um array de caracteres (char) que termina em um caractere nulo (zero, ‘\0’).

char cão[5] = {‘m’, ‘o’, ‘r’, ‘g’, ‘a’, ‘n’}; //não é uma cadeia
char gato[5] = {‘f’, ‘e’, ‘l’, ‘i’, ‘s’, ‘\0’}; //é uma cadeia

Leitura de uma cadeia do teclado


#include <iostream.h>
main( )
{
char cad[80];

cout <<“Introduza uma cadeia:”; //leitura do teclado


cin >> cad;
cout <<“Sua cadeia é:”;
cout << cad;

return 0;
}

Essa leitura do teclado lê uma cadeia até que seja encontrado o primeiro caractere branco. Assim, quando
lemos “Serra Magna. Jaén”, em cad somente armazenamos Serra. Para resolver o problema, utilizamos
a função gets( ), que lê uma cadeia completa a partir do teclado. O programa anterior é escrito para ler toda
a cadeia introduzida:

#include <iostream.h>
#include <stdio.h>
30   Programação em C++: Algoritmos, estruturas de dados e objetos

main( )
{
char cad[80];

cout << “Introduza uma cadeia:”;


gets(cad);
cout << “Sua cadeia é:”;
cout << cad;

return 0;
}

B.16 FUNÇÕES

Uma função é uma coleção de declarações e sentenças que realizam uma única tarefa. Cada função tem quatro
componentes: 1) seu nome, 2) o tipo de valor que devolve quando termina sua tarefa, 3) a informação que recebe
ao realizar sua tarefa, 4) a sentença ou sentenças que realizam sua tarefa. Cada programa C++ tem pelo menos
uma função: a função main.

B.16.1 Declaração de funções

Em C++, devemos declarar uma função antes de utilizá-la. A declaração da função indica ao compilador o tipo de
valor que a função devolve e o número e o tipo de argumentos que recebe. A declaração em C++ é denominada
protótipo:

tipo NomeFunção (lista argumentos);

Exemplos válidos são:

double Media(double x, double y);


void Print(char* formato, ...);
extern max(const int*, int);
char LerCaracter( );

B.16.2 Definição de funções

A definição de uma função é o corpo da função, que foi declarada anteriormente.

double Média(double x, double y)


//Devolve a média de x e y
{
return (x+y)/2.0;
}
char LerCaractere( )
//Devolve um caractere de entrada-padrão
{
char c;
cin >> c;
return c;
}
Guia de Sintaxe ANSI/ISO Padrão C++    31

B.16.3 Argumentos por omissão


Os parâmetros formais de uma função podem receber valores por omissão, ou argumentos cujos valores se
inicializam na lista de argumentos formais da função.

int Potência (int n, int k=2);


Potência(256);//256 elevado ao quadrado

Os parâmetros por omissão não necessitam ser especificados quando chamamos a função. Os parâmetros
com valores por omissão devem estar ao final da lista de parâmetros:

void func1 (int i=3, int j); //ilegal


void func2 (int i, int j=0, int k=0); //correto
void func3 (int i=2, int j, int k=0); //ilegal
void ImprimirValores (int conta, double quantidade=0.0);

Chamadas à função ImprimirValores são:

ImprimirValores(n,a);
ImprimirValores(n); //equivalente a ImprimirValores (n, 0.0)

Outras declarações e chamadas à funções são:

double f1(int n, int m, int p=0); //legal


double f2(int n, int m=1, int p=0); //legal
double f3(int n=2, int m=1, int p=0); //legal
double f4(int n, int m=1, int p); //ilegal
double f5(int n=2, int m, int p=0); //ilegal

B.16.4 Funções em linhas (inline)


Se uma declaração de função é precedida pela palavra reservada inline, o compilador substitui cada chamada
da função com o código que implementa a função.

inline int Max(int a, int b)


{
if (a>b) return a;
return b;
}

main ( )
{
int x = 5, y = 4;
int z = Max(x,y);
}

Os parâmetros com valores por omissão devem entrar no final da lista de parâmetros: as funções f1, f2 e f3
são válidas, enquanto as funções f4 e f5 não são válidas.

As funções em linha (inline) evitam os tempos suplementares das chamadas múltiplas de funções. As funções
declaradas em linha devem ser simples, somente com poucas sentenças de programa; podem ser chamadas
somente um número limitado de vezes e não são recursivas.

inline int abs(int i);


inline int min(in v1, int v2);
int mcd(int v1, int v2);
32   Programação em C++: Algoritmos, estruturas de dados e objetos

As funções em linha devem ser definidas antes de ser chamadas:


#include <iostream.h>
int incrementar(int i);

inline int incrementar(int i)


{
i++;
return;
}
main (void)
{
int i = 0;
while (i < 5)
{
i = incrementar(i);
cout << “i é: ”<< 1<<end1;
}
}

B.16.5 Sobrecarga de funções


Em C++, duas ou mais funções diferentes podem ter o mesmo nome. Essa propriedade é denominada sobrecarga.
Um exemplo é o seguinte:

int max (int, int);


doublel max (double, double);

ou também este outro:

void somar (char i);


void somar (float j);

As funções sobrecarregadas são diferentes no número e tipo de argumentos, e não no tipo que as funções
devolvem, e seus corpos são diferentes em cada uma delas.

#include <iostream.h

void soma (char);


void soma (float);
main (void)
{
int i = 65;
int i = 6.5;
soma(i);
soma(j);
}

void soma(char i)
{
cout << “Soma interior (char)” << end1;
}

void soma(float j)
{
cout << “Soma interior (float)” << end1;
}
Guia de Sintaxe ANSI/ISO Padrão C++    33

B.16.6 O modificador const


O modificador de tipos const é utilizado em C++ para proporcionar proteção somente de leitura para variáveis
e parâmetros de funções. Quando fazemos preceder um tipo de argumento com o modificador const para in-
dicar que esse argumento não pode ser mudado, o argumento ao que é aplicado não pode ser atribuído um
valor, nem mudar.

void copig (const char * fonte, char* dest);


void func_demo (const int i);

B.16.7 Passagem de parâmetros a funções


Em C++, existem três formas de passagens de parâmetros a funções:

1. Por valor. A função chamada recebe uma cópia do parâmetro, e esse parâmetro não pode ser modificado
dentro da função:

void intercâmbio (int x, int y)


{
int aux = y;
y = x;
x = aux;
}
//...
intercâmbio (i, j); //as variáveis i, j não se trocam

2. Por direção. Passa-se um ponteiro ao parâmetro. Esse método permite simular em C/C++ a chamada por
referência, utilizando tipos ponteiros nos parâmetros formais na declaração de protótipos. O método per-
mite modificar os argumentos de uma função.

void intercâmbio (int*x, int*y)


{
int aux = *y;
*y = *x;
*x = aux;
}
//...
intercâmbio (&i, &j); //i, j se trocam seus valores

3. Por referência. Pode-se passar tipos referência como argumentos de funções, o que permite modificar os
argumentos de uma função.

void intercâmbio (int &x, int &y);


{
int aux = y;
y = x;
x = aux;
}
//...
intercâmbio (i, j); //i, j trocam seus valores

Se for necessário modificar um argumento de uma função em seu interior, o argumento deve ser um tipo
referência na declaração da função.
34   Programação em C++: Algoritmos, estruturas de dados e objetos

B.16.8 Passagem de arrays


Os arrays passam por referência. A direção do primeiro elemento do array passa à função; os elementos indi-
viduais passam por valor. Os arrays podem passar indiretamente por seu valor se o array for definido como
um membro de uma estrutura.

//Passagem do array completo. Exemplo 1


#include <iostream.h>
void func(int x[ ]); //protótipo de função
void main( ){
int a[3] = {1,2,3};
func1(a); //sentenças
func1(&a[0]); //equivalentes
}

void func(int x[ ]){


int i;
for (i = 0; i < 3; i+1)
cout << i << x[i] << ‘\n’;
}

O seguinte exemplo passa um elemento de um array;


#include <iostream.h>
{
const int N=3;
void func2(int x);
void main( ) {
int a[N] = {1,2,3};
func2(a[2]);
}
void func2(int x) {
cout << x << ‘\n’;
}

B.17 CLASSES
Uma classe é um tipo definido pelo usuário que contém um estado (dados) e um comportamento (funções que
manuseiam os dados). Uma classe é como uma estrutura (struct) em C com a diferença que contém funções
incorporadas. Além disso, uma classe pode ter alguns membros que sejam privados e os que não podem ser
acessados do exterior da classe. Essa propriedade é chamada encapsulamento e é um meio útil para ocultar
detalhes que não são vistos pelo resto do programa.
As classes são diferentes dos objetos que definem a classe como um tipo. As classes em C++ são compa-
ráveis com os tipos primitivos, como int, char e double e um nome de classe pode aparecer em qualquer
texto que puder fazer int, char e double. Um objeto, ao contrário, é como um inteiro individual, um carac-
tere ou um ponto flutuante. Um objeto tem um estado particular, enquanto uma classe é uma descrição geral do
código e dos dados e não contém informação. Cada classe pode ter muitos objetos. Um objeto é conhecido nor-
malmente como uma instância ou um exemplar.

Sintaxe
Podemos declarar uma classe em C++ utilizando class, struct ou union:
class | struct | union nome[declarações_classe_base]
{
declarações
} [definições_de_objeto];
Guia de Sintaxe ANSI/ISO Padrão C++    35

|, indica que uma das três palavras reservadas deve ser utilizada no princípio da declaração.
[ ], o conteúdo de seu interior é opcional.

Cada uma das três palavras reservadas, class, struct e union, cria uma classe com essas diferenças:

• O nível de acesso a membros por omissão é privado caso se utilize class. O nível de acesso a membros
é público se utilizamos union ou struct.
• As palavras reservadas struct e class criam um tipo semelhante a uma estrutura em C. Uma union
cria um tipo em que todos os membros dados começam no mesmo endereço na memória.

classe CCad{
private:
char *pDados;
int nComprimento;
public:
CCad( ); //Construtor
-CCad( ); //Destruidor
char *obter(void) {return pDados;}
int obtercomprimento(void) {return nComprimento;}
char * copy(char * s);
char * cat(char * s);
}

B.17.1 Construtor

Um construtor é uma função-membro que é chamada automaticamente quando criamos um objeto; seu nome é
o mesmo que o nome da classe. Quando criamos objetos dinamicamente, utilizamos new e delete, em vez de
malloc e free. Os construtores não têm tipo de retorno (nem, inclusive, void). A própria classe é o tipo de retor-
no. Os construtores são como outras funções membro, ainda que não herdaram. É conveniente que os constru-
tores sejam declarados como públicos para que o resto do programa tenha acesso a eles.

class CDesenho {
private:
long coste;
int nEstrelas;
CCad sDiretor;
public:
//Construtores
CDesenho( );
CDesenho(long c, int n, CCad dir);
~CDesenho( ){delete[];} // destruidores
};

//definição dos construtores


CDesenho::CDesenho( ) {
}

CDesenho::CDesenho(long c, int n, CCad dir){


coste = c;
nEstrelas = n;
sDiretor = dir;
}
36   Programação em C++: Algoritmos, estruturas de dados e objetos

B.17.2 Construtor por omissão


O construtor por omissão em cada classe é o construtor que não tem argumentos. C++ o invoca automatica-
mente nas seguintes situações: quando se define um objeto da classe sem argumentos, quando um array de
objetos é declarado com membros não inicializados, ou quando o operador new é utilizado, mas não é espe-
cificado nenhum argumento. A sintaxe de um construtor por omissão é:

class( )

vetor::vetor ( ) { ... }


vetor::vetor(int i = 0) { ... }

class Ponto {
public:
Ponto( )
{
x = 0;
y = 0;
}
private:
int x;
int y;
};

C++ cria automaticamente um construtor por omissão quando não existe outro construtor.

B.17.3 Construtor de cópia


Esse construtor é criado automaticamente pelo compilador. O construtor de cópia é chamado automaticamente
quando se passa um objeto por valor; constrói-se uma cópia local do objeto. O formato é:
tipo:: tipo (const tipo& x)

Ponto::Ponto (const Ponto &p2)


{
cerr << “Chama-se o construtor de cópia.\n”;
x = p2.x;
y = p2.y;
return *this;
}

O parâmetro p2 não pode ser modificado pela função.

B.17.4 Arrays de objetos de classes


Um array de objetos de classes é útil quando requer instâncias múltiplas da mesma classe. Assim, por exemplo,
se definimos um array de objetos Ponto chamado figura, o construtor por omissão Ponto é chamado para
cada membro do array.

Ponto figura[3];

B.17.5 Destruidores
Um destruidor é uma função-membro especial que é chamada automaticamente quando desejamos apagar um
objeto da classe. O nome de um destruidor é o nome da classe, precedido pelo caractere ~ (til). Se não for de-
clarado explicitamente um destruidor, C++ cria automaticamente um vazio.
Guia de Sintaxe ANSI/ISO Padrão C++    37

class Ponto{
public:
~Ponto( )
{
cout << “Destruidor Ponto chamado \n”;
}
//...
};

Um destruidor não tem parâmetros nem, inclusive, void e não tem tipo de retorno. Uma classe pode ter
somente um destruidor.

B.17.6 Classes compostas


Quando uma classe contém membros dado que são por si mesmos objetos de outras classes, é denominada
classe composta.

class DadosAcadêmicos { // ...};

class Direção { // ...};

class Estudante {
public:
Estudante( )
{
LerId (0);
LerNotaMédia(0.0);
}
void LerId(long);
void LerNotaMédia(float);
private:
long id;
DadosAcadêmicos da;
Direção dir;
float NotaMédia;
};

B.17.7 Funções-membro
As funções-membro são funções declaradas dentro de uma classe. Conseqüentemente, elas têm acesso a mem-
bros public, private e protected dessa classe. Se são definidas dentro da classe, são tratadas como funções
inline e tratadas também como sobrecarregadas.

class vetor {
public:
vetor(int n = 50); //construtor por default
vetor (const vetor& v); //construtor de cópia
vetor(const int a[ ], int n);
...
int teo( ) const { return(size-1); } //função-membro em linha
private:
...
};
38   Programação em C++: Algoritmos, estruturas de dados e objetos

As funções-membro são invocadas normalmente mediante o uso de operadores ponto (.) ou ->.

vetor a(50) ,b;


vetor* ptr_v = &b;
int teo15 = a.teo( );
teo15 = ptr_v -> teo( )

B.17.8 Funções-membro constante

Uma função-membro constante é aquela que garante que não será modificado o estado do objeto da classe.

class Ponto {
public:
Ponto (int xval, int yval);

int LerX( ) const;

void Fixarx (int xval);


//...
};

A palavra reservada const deve aparecer também na implementação da função

int Ponto::LerX( ) const


{
return x;
}

B.17.9 Funções classes amigas (friend)

Uma amiga (friend) de uma classe tem acesso a todos os membros dessa classe. Se uma função F, amiga
de uma classe C, utiliza um objeto da classe C, é como se todos os membros de C fossem declarados públi-
cos. O tipo mais comum de amigo de uma classe é uma função. As classes também podem ser amigas de
outras classes.
Para declarar uma função como amiga de uma classe, é preciso incluir um protótipo da função interior da
declaração da classe, precedida da palavra reservada friend.

class nome {
...
friend protótipo_de_função;
...
};

para declarar uma classe como amiga, utilizamos a seguinte sintaxe:

class nome {
...
friend class nome_classe;
};
Guia de Sintaxe ANSI/ISO Padrão C++    39

Função amiga
class Estudante;

class Funcionário {
public:
Funcionário (long idVal);
friend void RegistrarEstudante (Estudante &S,
Funcionário &E, float taxa);
private:
long id; // número de matrícula
float PagoTaxa;
};

Classe amiga
class classe_1 {
friend class classe_2;
//...
};
class classe_2 {
friend class classe_3;
};

B.17.10 O ponteiro this


Dentro de uma função-membro, a palavra reservada this é o nome de um ponteiro implícito ao objeto atual.
Quando desejamos utilizar o ponteiro oculto no código da função-membro, utilizamos a palavra reservada this.
Na maioria das vezes, o uso de this é desnecessário, já que C++ supõe o uso de this sempre que nos referi-
mos a membros dado.
Cponto::fixar(double novox, double novoy) {
x = novox; //x significa o mesmo que this-> x
y = novoy; //y significa o mesmo que this-> y
}

B.18 HERANÇA
Uma herança é uma relação é-um entre duas classes, na qual uma nova classe deriva de outra classe –
denominada classe-base. A nova classe é denominada classe derivada. A relação é-um se manifesta como
“um estudante de doutorado é-um estudante que está escrevendo uma tese”.
Sintaxe
class nome_classe_derivada: (public|protected|private) classe_base {
declarações
};
classe_base é o nome da classe da qual é derivada a classe atual – derivada – e os especificadores
de acesso podem ser public, protected ou private. Um membro public é acessível por meio de seu
escopo; os membros de classe_base são herdados sem modificação em seu estado. Um membro privado
(private) é acessível a outras funções-membro dentro de sua própria classe. Um membro protegido (pro-
tected) é acessível a outras funções-membro dentro de sua classe e a qualquer classe derivada dela. Os modifi-
cadores de acesso podem ser utilizados dentro de uma declaração de uma classe em qualquer ordem e com qual-
quer freqüência.
40   Programação em C++: Algoritmos, estruturas de dados e objetos

class D : public A {
...
};

A herança múltipla permite que uma classe seja derivada de mais de uma classe-base. No exemplo seguin-
te, D é a classe derivada e B1, B2 e B3 são classes-base.

class D : public B1, public B2, private B3 {


...
};

A palavra reservada virtual é um especificador de função que proporciona um mecanismo para selecionar
em tempo de execução a função-membro apropriada da classe-base e de classes derivadas

classe D : public virtual B1, public virtual B2 {


...
};
class Estudante : public virtual Pessoa {
//...
class Funcionário : public virtual Pessoa {
//...

B.19 SOBRECARGA DE OPERADORES


A sobrecarga de operadores refere-se à técnica que permite dar um novo significado aos operadores-padrão,
tais como =, <<, ... De outra forma, podem ser definidas funções operador para suas classes.

Uma função operador é uma função cujo nome consta da palavra reservada operador seguida por um
operador binário ou unitário com o formato:

operator operador
// Sobrecarga de operadores aritméticos e
// de atribuição

class Ponto
}
//...
public:
//...
Ponto operator * (const Ponto& p);
Ponto operator / (const Ponto& p);
Ponto operator += (const Ponto& p);
//...
};
//implementação de função-membro sobrecarregada
//pl * p2
inline Ponto Ponto::operator * (const Ponto& p)
{
return Ponto (x * p.x, y * p.y, z * p.z);
}
//p1 / p2
...
Guia de Sintaxe ANSI/ISO Padrão C++    41

Uma vez declarada e definida a classe, pode-se escrever expressões como:

Ponto p, q, r;
//...
r = p * q; //multiplicação
//...
r = p += q; //atribuição encadeada e aritmética
//...

B.19.1 Funções operador unitário


@operando @ é o operador

O compilador avalia a expressão chamando uma das seguintes funções, dependendo de qual está definida:

tipo_retorno tipo::operator@( )
tipo_retorno operator@ (tipo)

Dependendo do próprio operador, a expressão que utiliza um operador unitário pode ser da forma

operando@

B.19.2 Funções operador binário


Pode ser escrita uma função operador binário para um operador (tal como +, -, *, ”) que C++ aceite como um
operador binário.

operando1@ operando2 @ é o operador

o compilador avalia a expressão chamando uma das seguintes funções, dependendo de onde esteja definida:

tipo_retorno tipo1::operator@ (tipo2)


tipo_retorno tipo2::operator@ (tipo1, tipo2)
tipo1 e tipo2 são os tipos de operando1 e operando2, respectivamente.

B.19.3 Funções operador de atribuição

A declaração dessa função é:

class & class::operator = (const classe &)

Um exemplo que ilustra uma função operador de atribuição é:

classe Cponto {
private:
double x, y;
public:
Cponto& operator = (const Cponto& ponto);
...
};
42   Programação em C++: Algoritmos, estruturas de dados e objetos

B.19.4 Operadores de incremento e decremento


Os operadores incremento (+ +) e decremento (– –) seguem a maioria das regras dos operadores unitários, mas
também podem ser prefixados e pós-fixados. Os seguintes exemplos ilustram as versões pré e pós-fixadas do
operador de incremento (+ +).

class Cponto {
private:
double x, y;
public:
Cponto& operator++( ); //prefixado
Cponto operator++(int); //pós-fixado
};

class P {
public:
void operator++(int); //pós-fixado
void operator--(int); //pós-fixado
};

B.20 MODELOS (templates)


A palavra reservada template é utilizada para implementar tipos parametrizados ou modelos. C++ reconhe-
ce dois tipos de modelos: modelos de classes e modelos de funções.

Sintaxe
template < argumentos_modelo > //modelo de classe
declaração_de_classe

template < argumentos_modelo > //declaração de função


definição_função

< argumentos_modelo > é class arg_nome

B.20.1 Modelos de funções


Um modelo de função deve ter pelo menos um tipo de parâmetro, mas pode ter mais. Seu formato é:

template <classT>
tipo_retorno nome_função(T parâmetro)

T é um parâmetro de modelo

template <class T>


void Apresentar (const T &valor)
{
cout << valor;
}

Uma função modelo pode ter parâmetros adicionais:

template <class T>


void Intercâmbio(T& x, T& y)
Guia de Sintaxe ANSI/ISO Padrão C++    43

{
T aux;
aux = x;
x = y;
y = aux;
}

int m, n;
Estudante S1;
Estudante S2;
//...
Intercâmbio(m, n); //chamada com inteiros
Intercâmbio(S1, S2); //chamada com estudantes

B.20.2 Modelos de classes


Os modelos de classes oferecem a possibilidade de gerar novas classes. Os tipos mais comuns de modelos são
classes contenedoras, como arrays, listas e conjuntos. Cada modelo pode trabalhar com uma variedade de tipos
de dados. O formato básico para definir um modelo de classe é:

template <class T>


class MinhaClasse {
//...
};

T pode ser um tipo ou uma expressão. Os modelos instanciam-se para criar classes deles.

MinhaClasse <int> x;
MinhaClasse <Estudante> MinhaEstudante;

Um modelo pode ter múltiplos parâmetros:

template <class T1, class T2>


class Círculo {
//...
private:
T1 x;
T2 y;
T2 raio;
};
//...
Círculo <int, long> c;
Círculo <unsigned, float> D;

Um exemplo clássico é uma pilha de dados:

template <class T>


class pilha {
T *pilhap;
int comprimento;
int índice;
public:
T tirar(void) {return pillhap[--índice];}
void colocar(T item){pilhap[índice++] = item; }
...
};
44   Programação em C++: Algoritmos, estruturas de dados e objetos

Pode-se instanciar esse modelo da seguinte forma:

pilha<int> elementos(30); //pilha de inteiros


pilha<CCad> cadeias(20); //pilha de objetos CCad

B.21 EXCEÇÕES
O manuseio ou manipulação de exceções é o mecanismo para detectar e manipular exceções. Um manipulador
de exceções é um bloco de código que processa condições de erros específicas. Uma exceção é, quase sempre,
um erro em tempo de execução, tal como “falta de memória”, “falha ao abrir um arquivo”, “erros do intervalo
de subíndice” ou “divisão por zero”.
Em C++, quando geramos uma exceção, o erro não pode ser ignorado ou terminará o programa. Um programa
lança ou dispara (throws) uma exceção no ponto em que é detectado o erro. Quando acontece isso, um pro-
grama C++ busca automaticamente o manipulador de exceções, que responde à exceção de alguma forma
apropriada. Essa resposta é denominada “capturar uma exceção” (catching). Se não podemos encontrar um
manipulador de exceções, o programa será terminado.

B.21.1 Lançamento de exceções


Podem ocorrer muitos tipos diferentes de exceções, de modo que, quando lançamos uma exceção, uma expressão
throw exceção (ou somente throw) identifica o tipo de exceção. A sintaxe adota dois formatos:

throw
throw expressão
//lançamento de uma exceção, criando um subíndice
//está fora do intervalo
const unsigned LongArray = 500;
unsigned i;
.
.
.
if (i > = LongArray) //é o subíndice válido
throw ErroIntervalo;

A palavra reservada try, juntamente com as sentenças que seguem entre chaves, é chamada bloco try. Deve
ser seguido imediatamente por um ou mais manipuladores de exceções. Cada manipulador de exceções começa
com a palavra reservada catch seguida por um bloco que contém sentenças.

try {
lista_de_sentenças
}
catch (lista_de_parâmetros){
lista_de_sentenças
}
catch (lista_de_parâmetros){
lista_de_sentenças
}

B.21.2 Manipulador de exceções


Um bloco catch é conhecido também como manipulador de exceções e parece uma declaração de função de
um argumento sem um tipo de retorno.
Guia de Sintaxe ANSI/ISO Padrão C++    45

catch (const char* mensagem)


{
cerr << mensagem << end1;
exit(1);
}

B.21.3 Especificação de exceções

Sintaticamente, uma especificação de exceções é parte de uma declaração de funções e tem o formato:

cabeçalhofunção throw (lista de tipos)

A lista de tipos são os tipos que podem ter uma sentença throw expressão dentro da chamada da função;
se a lista for vazia, o compilador pode supor que nenhuma sentença throw será executada pela função, direta
ou indiretamente.

void demo( ) throw(int, transbordamento);


void nãodemo(int i) throw( );

Assim, uma declaração de função:

void Demo( ) throw (A, B)


{
//...
}

será tratada da seguinte forma:

void Demo( )
{ try {
//...
chamada a Demo( )
}
catch (A)
throw;
}
catch (B)
}
//...
}
catch (...)
{
//unexpected
}

Se uma função não está especificada com uma declaração throw, pode lançar qualquer exceção. A declaração
throw( ) indica que uma função não lança nenhuma exceção.
Se uma função lança uma exceção que não está em sua declaração, chama a função unexpected. Na maioria
das implementações, unexpected chama a função terminate que chama abort. A função set_unexpected
permite definir o manejo de exceções não previstas. Todas essas declarações de funções se encontram no arquivo
except ou except.h.
46   Programação em C++: Algoritmos, estruturas de dados e objetos

B.21.4 Exceções na biblioteca-padrão


As exceções da biblioteca-padrão são derivadas da classe base exception. Duas das classes derivadas são
logic_erro e runtime_erro. Os erros de tipo lógico incluem bad_cast, out_of_range e bad_typeid,
e os erros de tempo de execução incluem range_error, overflow_error e bad_alloc.

class logic_error: public exception


{
public:
logic_error/c)
{
const string & que_arg; //...
}
};

Exemplo de exceção lógica


Os erros lógicos informam um problema que é detectável antes que um programa seja executado

class domain_error : public logic_error


{
public:
domain_error( )
{

const string & que_arg


}
};

Exemplo de exceção de tempo de execução


Os erros em tempo de execução ocorrem durante a execução do programa.

class range_error : public runtime-error


{
public:
range_error( )
{
const string & que_arg;
}
};

B.21.5 Resumo da sintaxe de exceções


• throw valor;
• try {
sentenças
{
catch (tipo_exceção){
sentenças
}
• try {
sentenças
}
Guia de Sintaxe ANSI/ISO Padrão C++    47

catch (dec_argumento1) {
sentenças
}
catch (dec_argumento2) {
sentenças
}
...
throw;

B.22 ESPAÇO DE NOMES (Namespaces)


Um espaço de nomes (namespace) é um mecanismo para expressar agrupamentos lógicos, ou seja, se algumas
declarações podem ser agrupadas logicamente de acordo com algum critério, podemos colocá-las em um espaço
de nomes comum que expressem esse fato. A palavra reservada namespace define um espaço de nomes.

namespace nome {
corpo_espaço_de_nomes
}

Esse formato cria um espaço de nomes com o qualificador nome. Dentro dos caracteres chave ({ }),
corpo_espaço_de_nomes pode incluir variáveis, definições de funções e protótipos, estruturas, classes,
enumerações (enum), definições de tipos (typedef) ou outras definições de espaços de nomes. Observe que
um espaço de nomes não termina com um ponto-e-vírgula. As definições de espaço de nomes aparecem em
arquivos de cabeçalho e em módulo independentes com definições de funções.

Exemplo
namespace Vermelho {
int j;
void imprimir(int i)
{cout << “Vermelho::imprimir( ) ” << i << end1;}
}

namespace Azul {
int j;
void imprimir(int);
}
void sub1( ) {...} //pode acessar o espaço de nomes
//Azul e Vermelho
void sub( ) {...} //pode acessar o espaço de nomes
//Azul e Vermelho

Os espaços de nomes Vermelho e Azul têm dois membros com o mesmo nome: inteiro j e função
imprimir( ) (normalmente, essas definições não poderiam conviver em um espaço global, mas um espaço
de nomes elimina esse problema). Um espaço de nomes pode incluir definições de funções e protótipos de
funções. As definições de funções de sub1( ) e sub2( ) têm acesso a todos os membros do espaço de nomes
Vermelho e Azul.

B.22.1 Extensões

Os espaços de nomes se estendem, ou seja, podem ser acrescentadas declarações posteriores a espaços de nomes
definidos anteriormente. As extensões do espaço de nomes podem aparecer também em arquivos independen-
tes da definição original do espaço de nomes.
48   Programação em C++: Algoritmos, estruturas de dados e objetos

namespace Azul{ //definição original de espaço de nomes


int j;
void imprimir (int);
}

namespace Azul{ //extensão do espaço de nomes


char car;
char bufer[20];
}
...

B.22.2 Acesso aos membros de um espaço de nomes

O operador de resolução de escopo proporciona acesso a membros de um espaço de nomes.

nome_espaço_de_nomes::nomes_membro

nome_espaço_de_nomes é um qualificador de espaço de nomes definido anteriormente e nome_membro


deve estar declarado dentro de nome_espaço_de_nomes.

void Azul::imprimir(int k){


cout << “Azul::imprimir( ) = ” << k << end1;
}

O operador de resolução de escopo associa imprimir( ) ao espaço de nomes Azul; sem ele, o compilador
define imprimir( ) como uma função global.

B.22.3 Espaço de nomes sem nome

É muito útil envolver um conjunto de declarações em um espaço de nomes simplesmente para proteção diante
da possibilidade de conflitos de nomes. O formato é:

namespace {
corpo_nome_de_espaço
}

Todos os membros definidos em corpo_nome_de_espaço estão em um espaço de nomes sem nome que
se garante ser único para cada unidade de tradução.

B.22.4 Diretivas using

No acesso aos membros de espaço de nomes, pode-se ter dificuldades, especialmente com qualificadores de espa-
ço de nomes longos e espaços de nomes aninhados. As diretivas using proporcionam acesso a todos os membros
do espaço de nomes sem um qualificador de espaço de nomes e o operador de escopo. O formato é:

using namespace nome;

O qualificador nome deve ser um nome de espaço definido anteriormente. Podem aparecer as diretivas
using em escopos locais e globais.
Guia de Sintaxe ANSI/ISO Padrão C++    49

B.22.5 Declarações using


As diretivas using tornam todos os membros do espaço de nomes acessíveis sem qualificação. Ao contrário, as
declarações using qualificam somente membros individuais de espaço de nomes. O formato é:

using nome_espaço_de_nomes::nome-membro;

namespace Preto{ //define espaço de nomes Preto


int j;
void imprimir(int);
char car;
}
namespace Branco{
int j;
void imprimir(int);
double vision;
}

using Branco::vision;

B.22.6 Pseudônimo de espaço de nomes


Os pseudônimos de espaço de nomes criam nomes sinônimos de espaço de nomes. Podemos utilizar pseu-
dônimos quando um espaço de nomes tem um nome longo. O formato é:

namespace nome_pseudônimo = nome_de_espaço;

Exemplo
namespace Universidade_Pontifícia_deSalamanca_emMadri{
//...
}
Universidade_Pontifícia_deSalamanca_emMadri::String c3 =
“Fundação”;
Universidade_Pontifícia_deSalamanca_emMadri::String c4 =
“Pablo VI”;

O código anterior é pouco prático em código real; um pseudônimo curto resolve o inconveniente.

// uso de pseudônimo para abreviaturas


namespace UPSAM = Universidade_Pontifícia_deSalamanca_emMadri;

UPSAM::String c3 = “Fundação”;
UPSAM::String c4 = “Pablo VI”;

namespace Geometria{
struct Ponto {
double x, y;
};
double pendente (Ponto, Ponto);
}

O espaço de nomes inclui um tipo Ponto e uma função pendente. A implementação do arquivo
geometria.c:
50   Programação em C++: Algoritmos, estruturas de dados e objetos

// geometria.c
#include “geometria.h”

namespace Geometria { // extensão de espaço de nome


Ponto origem = {0, 0};
}
double Geometria::pendente (Ponto p1, Ponto p2){
double dy = p2.y – p1.y;
double dx = p2.x – p1.x;
if (dx = = 0)
throw “pendente( ) : pendente não definida”;
return dy / dx;
}

Uma extensão do espaço de nomes acrescentou um membro origem a Geometria. A função pendente( )
calcula a pendente dos pontos p1 e p2 e levanta uma exceção de cadeia de caracteres se o denominador da pen-
dente for zero.

B.22.7 Espaço de nomes aninhados

Os espaços de nomes são ilegais no interior de funções, mas podem aparecer em outras definições de espaço
de nomes.

namespace Exterior {
int i, j;
namespace Interior {
const int Máx = 20;
char car;
char bufer[Máx];
void imprimir( );
}
}

O acesso aos membros de um espaço de nomes aninhados é resolvido com o operador de resolução de
escopo (::)

void Exterior::Interior::imprimir( ) {
for (int i = 0; i < Máx; i++) //i é local ao laço for
cout << bufer[i] << ’’;
cout << end1;
}

B.22.8 Um programa completo com espaço de nomes


O arquivo de cabeçalho geometria.h define um espaço de nomes para uma biblioteca de geometria (geo­
metria).

#inifndf GEOMETRIAH
#define GEOMETRIAH
// arquivo geometria.h

Aplicação. Utilizar o espaço de nomes Geometria para calcular pendentes das variáveis Ponto.
Guia de Sintaxe ANSI/ISO Padrão C++    51

#include <iostream.h>
#include “geometria.h”

namespace Geo = Geometria; //pseudônimo

using Geo::Ponto;
using Geo::pendente;
namespace {
Ponto origem = {10, 10};
}
int main( )
{
try {
Ponto a = {3, 5}
Ponto b = {6, 10};
cout << “A linha ab tem a pendente”
<< pendente (a,b) << end1;
cout << “A linha origem_a tem a pendente”
<< pendente (origem, a)
<< end1;
}
catch (char *msg) {
cout << msg << end1;
return 1;
}
return 0;
}
#endif

Ao executar o programa, obteremos:

A linha ab tem a pendente 1.66667


A linha origem_a tem a pendente 0.714286

Você também pode gostar