Вы находитесь на странице: 1из 49

APÊNDICE E

Manual de Sintaxe da Linguagem C++

SUMÁRIO

E.1 Elementos da linguagem E.12 Os operadores new e delete


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

C++ é considerada um C maior e mais potente. A sintaxe de C++ é uma extensão de C, acrescentadas nume-
rosas propriedades, fundamentalmente orientadas a objetos. ANSI C já adotou várias características de C++,
mas a migração de C para C++ não é difícil.
Neste apêndice mostramos as regras de sintaxe do padrão clássico de C++ retiradas de Annotated Refe-
rence Manual (ARM), de Stroustrup e Ellis, assim como as últimas propostas incorporadas ao novo apagador
de ANSI C++, que estão incluídas nas versões 3.0 (atual) e 4.0 (futura) de AT&T C++ e conhecida como
ANSI C++1.

E.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. Estes componentes de léxico são: palavras reservadas,
identificadores, constantes, constantes de cadeia, operadores e sinais de pontuação.

1
  Em julho de 1998 foi aprovado o padrão ANSI C++. Em 1992 aprovou-se o padrão C descrito como ISOTEC 9899:1990
Programming languajes-C.


mmFundamentos de programação – Algoritmos, estruturas de dados e objetos

E.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).

E.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.

E.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 permitido 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

E.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 E.1 enumera as palavras reservadas de C++ segundo o
ARM2.

2
  Siglas do livro de Margaret Ellis e Bjarne Stroustrup no qual definem as regras de sintaxe da linguagem C++ padrão, Annotated
Reference Manual, Addison-Wesley, 1992.
Manual de sintaxe da linguagem C++mm

Tabela E.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 E.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

Tabela E.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
mmFundamentos de programação – Algoritmos, estruturas de dados e objetos

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

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

bool false reinterpret_cast typeid


const_cast mutable static_cast using
dynamic_cast namespace true wchar_t

E.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 E.5 mostra os diferentes tipos de dados em C++.

Tabela E.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

E.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. Esta 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.
Manual de sintaxe da linguagem C++mm

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”;

E.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.

E.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. Este modificador evita também que parâmetros passa-
dos por referência sejam modificados:

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


mmFundamentos de programação – Algoritmos, estruturas de dados e objetos

E.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

E.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

E.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 ob-
jeto e fazer os ajustes ou inserções necessários. Todas as declarações devem ser feitas antes que seja executa-
da qualquer sentença. Assim, a declaração típica em C++
NomeTipo NomeVariável, NomeVariável2, ...

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;
}
Manual de sintaxe da linguagem C++mm

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;
}

E.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.

E.6.1 Operadores aritméticos


C++ proporciona diferentes operadores que relacionam operações aritméticas.

Tabela E.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 é considerado inteiro
a=5./2; //a recebe o valor 2.5, se a for real
mmFundamentos de programação – Algoritmos, estruturas de dados e objetos

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

E.6.2 Operadores de atribuição

O processador de atribuição (=) faz que o valor situado à direita do operador seja aplicado à variável situada
a 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

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,
produzindo operadores como +=, /=, -=, *= e %=. C++ suporta outros tipos de operadores de atribuição para
manipulação de bits.
Manual de sintaxe da linguagem C++mm

Tabela E.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;

E.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 E.8 mostra os operadores lógicos e relacionais.

Tabela E.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;
10mmFundamentos de programação – Algoritmos, estruturas de dados e objetos

é 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
diferentes 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 ope-
raçã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.

E.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 E.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 E.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;
Manual de sintaxe da linguagem C++mm11

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)

E.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);

E.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:
esquerda-direita, direita-esquerda), denominada associatividade. A Tabela E.11 mostra a precedência e a
associatividade de operadores.

Tabela E.11 Precedência e associatividade de operadores

Operador Associatividade Prioridade

::.->[ ]( ) Esquerda-Direita 1
++ -- & (direção) (tipo) ! - + ~ Direita-Esquerda 2
sizeof (tipo) new delete *(indereçã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 vírgula) Esquerda-Direita 16
12mmFundamentos de programação – Algoritmos, estruturas de dados e objetos

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

E.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 E.12 lista os operadores que podem ser sobrecarregados.

Tabela E.12 Operadores que podem ser sobrecarregados

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

E.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).

E.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 ostre-
am construída em iostream.

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

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

Desejando-se visualizar o valor do objeto int ativado 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”;
return 0
}

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

#include <iostream.h>
int main( )
{
Manual de sintaxe da linguagem C++mm13

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 man( )
{
int x = 45;
double y = 495.125;
char *c = “e multiplicada por x=”;
cout << c << y*x << “\n”;
return 0
}

E.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( )
{
int i;
cin >> i;
cout << i << “\n”;
return 0
}

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 << ','<< y << "\n";
return 0
}

E.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.
14mmFundamentos de programação – Algoritmos, estruturas de dados e objetos

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";
return 0
}

A saída deste 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;
return 0
}

E.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írgu-
la é utilizado como elemento terminal de cada sentença.

E.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;

E.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;
Manual de sintaxe da linguagem C++mm15

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;

E.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.

E.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.


16mmFundamentos de programação – Algoritmos, estruturas de dados e objetos

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
controle 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);
}
else {
desconto = 0;
preço = n * preço;
}

E.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}]
Manual de sintaxe da linguagem C++mm17

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

E.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 executar
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.

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’;
}
18mmFundamentos de programação – Algoritmos, estruturas de dados e objetos

E.10 LAÇOS: SENTENÇAS REPETITVAS


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

E.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 é 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;

E.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 é:
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 contro-
le 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;
Manual de sintaxe da linguagem C++mm19

O seguinte exemplo visualiza os quadrados de 2 a 10:


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

E.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), em 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;
}

E.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.


20mmFundamentos de programação – Algoritmos, estruturas de dados e objetos

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.

E.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++)


;

E.10.6 Sentença return


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

return expressão;

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

E.11 PONTEIROS
Um ponteiro é uma referência indireta a um objeto de um tipo especificado. Essencialmente, um ponteiro
contém a posição de memória de um tipo dado.

E.11.1 Declaração de ponteiros


Os ponteiros são declarados utilizando o operador unitário. Nas sentenças seguintes, são declaradas duas
variá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


Manual de sintaxe da linguagem C++mm21

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 = new int; //p aponta para dado inteiro
q = new int; //q aponta para dado inteiro
*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.

E.11.2 Ponteiros a arrays

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

int lista[5];
lista[3] = 5;

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 += 3; //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.
22mmFundamentos de programação – Algoritmos, estruturas de dados e objetos

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 argumento
de uma função, a função pode modificar o conteúdo do array.

E.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[40];
char esposa[40];
char filho[40];
};
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
strcpy(p→marido,“Luiz”); //iniciação
strcpv(p→esposa,“Marta”); //iniciação
strcpy(p→filho,“Luizinho”); //iniciação

E.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 é:

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);


Manual de sintaxe da linguagem C++mm23

E.11.5 Ponteiros a void


O tipo de dado void representa um valor nulo. Em C++, entretanto, o tipo de ponteiro void costuma ser
considerado 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 menos independente do tipo.
Um exemplo ilustrativo da diferença de comportamento em C e C++ é o seguinte 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++
...
}

E.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;

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
24mmFundamentos de programação – Algoritmos, estruturas de dados e objetos

E.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
seguintes 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>
void 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”;
}

E.12 OS 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

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
única definição, como:
int* p = new int;
Manual de sintaxe da linguagem C++mm25

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[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

E.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.

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
26mmFundamentos de programação – Algoritmos, estruturas de dados e objetos

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

E.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 cumprimento[5] = “Olá”;


char cumprimento[ ] = “Olá”;
char cumprimento[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.

E.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


palavras 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
};

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 deste tipo (variável de enumeração).

nome var;

Considere a seguinte sentença:


enum color {Vermelho, Azul, Verde, Amarelo};
Manual de sintaxe da linguagem C++mm27

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
diferentes 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
armazenar 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’;

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;
};
28mmFundamentos de programação – Algoritmos, estruturas de dados e objetos

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 y
...
}

E.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[7] = {‘m’, ‘o’, ‘r’, ‘g’, ‘a’, ‘n’}; //não é uma cadeia
char gato[7] = {‘f’, ‘e’, ‘l’, ‘i’, ‘s’, ‘\0’}; //é uma cadeia

Leitura de uma cadeia do teclado


#include <iostream.h>
int main( )
{
char cad[80];
cout <<“Introduza uma cadeia:”; //leitura do teclado
cim >> 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>
int main( )
{
char cad[80];
cout << “Introduza uma cadeia:”;
gets(cad);
cout << “Sua cadeia é:”;
cout << cad;
return 0;
}
Manual de sintaxe da linguagem C++mm29

E.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 re-
cebe 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.

E.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( );

E.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;
}

E.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 ativamos 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);
30mmFundamentos de programação – Algoritmos, estruturas de dados e objetos

Ativações da função ImprimirValores são:

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

Outras declarações e ativações de 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

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


Se uma declaração de função é precedida pela palavra reservada inline, o compilador substitui cada ativação
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);
}

As funções em linha (inline) evitam os tempos suplementares das ativações múltiplas de funções. As funções
declaradas em linha devem ser simples, somente com poucas sentenças de programa; podem ser ativadas
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 mdc(int v1, int v2);

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

#include <iostream.h>
int incrementar(int i);
inline int incrementar(int i)
{
i++;
return i;
}
void main (void)
{
int i = 0;
while (i < 5)
{
i = incrementar(i);
cout << “i é: ”<< end1;
}
}
Manual de sintaxe da linguagem C++mm31

E.16.5 Sobrecarga de funções


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

int max (int, int);


doublel max (double, double);

ou

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;
float j = 6.5;
soma(i);
soma(j);
}
void soma(char i)
{
cout << “Soma interior (char)” << end1;
}
void soma(float j)
{
cout << “Soma interior (float)” << end1;
}

E.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
indicar que este 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);

E.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 ativada recebe uma cópia do parâmetro, e esse parâmetro não pode ser modificado
dentro da função:
32mmFundamentos de programação – Algoritmos, estruturas de dados e objetos

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 ativação por
referência, utilizando tipos ponteiros nos parâmetros formais na declaração de protótipos. O método
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 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.

E.16.8 Passagem de arrays


Os arrays passam por referência. A direção do primeiro elemento do array passa à função; os elementos
individuais 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
}
Manual de sintaxe da linguagem C++mm33

void func(int x[ ]){


int i;
for (i = 0; i < 3; i++)
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’;
}

E.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. Esta 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 com-
pará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
normalmente 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];

|, 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 estas 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;
34mmFundamentos de programação – Algoritmos, estruturas de dados e objetos

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

E.17.1 Construtor
Um construtor é uma função membro que é ativada 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 retorno. Os construtores são como outras funções membro, ainda que não herdaram. É conveniente que os
construtores 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( ) {;} // destrutores
};

//definição dos construtores


CDesenho::CDesenho( ) {
}

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


coste = c;
nEstrelas = n;
sDiretor = dir;
}

E.17.2 Construtor por omissão


O construtor por omissão em cada classe é o construtor que não tem argumentos. C++ o invoca automati-
camente 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 é
especificado nenhum argumento. A sintaxe de um construtor por omissão é:

class( )

vetor::vetor ( ) { ... }


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

class Ponto {
public:
Manual de sintaxe da linguagem C++mm35

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

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

E.17.3 Construtor de cópia


Este construtor é criado automaticamente pelo compilador. O construtor de cópia é ativado 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 << “Ativamos o construtor de cópia.\n”;
x = p2.x;
y = p2.y;
}

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

E.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 é ativado para cada
membro do array.

Ponto figura[3];

E.17.5 Destrutores
Um destrutor é uma função membro especial que é ativada automaticamente quando desejamos apagar um
objeto da classe. O nome de um destrutor é o nome da classe, precedido pelo caractere ~ (til). Se não for de-
clarado explicitamente um destrutor, C++ cria automaticamente um vazio.

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

Um destrutor não tem parâmetros, nem inclusive void e não tem tipo de retorno. Uma classe tem so-
mente um destrutor.
36mmFundamentos de programação – Algoritmos, estruturas de dados e objetos

E.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;
};

E.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:
...
};

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( )

E.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);
//...
};
Manual de sintaxe da linguagem C++mm37

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

int Ponto::LerX( ) const


{
return x;
}

E.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úblicos.
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;
};

Função amiga
class Estudante;
class Empregado {
friend void RegistrarEstudante (Estudante &S,
Empregado &E, float taxa);
public:
Empregado (long idVal);
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;
};
38mmFundamentos de programação – Algoritmos, estruturas de dados e objetos

E.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
referimos 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
}

E.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 priva-
do (private) é acessível a outras funções membro dentro de sua própria classe. Um membro protegido
(protected) é acessível a outras funções membro dentro de sua classe e a qualquer classe derivada dela.
Os modificadores de acesso podem ser utilizados dentro de uma declaração de uma classe em qualquer
ordem e com qualquer freqüência.

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 é utilizada para declarar a classe base e evitar a herança múltipla em uma
classe derivada. A palavra virtual também é utilizada em um especificador de função membro da classe
base para ter funções polimórficas.

classe D : public virtual B1, public virtual B2 {


...
};
class Estudante : public virtual Pessoa {
//...
class Empregado : public virtual Pessoa {
//...
Manual de sintaxe da linguagem C++mm39

E.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
...

Uma vez declarada e definida a classe, podem ser escritas expressões como:
Ponto p, q, r;
//...
r = p * q; //multiplicação
//...
r = p += q; //atribuição encadeada e aritmética
//...

E.19.1 Funções operador unitário


@operando @ é o operador

O compilador avalia a expressão ativando uma das seguintes funções, dependendo de qual está definida:
tipo_retorno tipo::operator@( )
tipo_retorno operator@ (tipo)

A forma da expressão que utiliza um operador unitário, depende do operador utilizado:


operando@

E.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
40mmFundamentos de programação – Algoritmos, estruturas de dados e objetos

o compilador avalia a expressão ativando uma das seguintes funções, dependendo de em qual 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.

E.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);
...
};

E.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
};

E.20 PLANILHAS (templates)

A palavra reservada template é utilizada para implementar tipos parametrizados ou planilhas. C++
reconhece dois tipos de planilhas: planilhas de classes e planilhas de funções.

Sintaxe
template < argumentos_planilha > //planilha de classe
declaração_de_classe

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


definição_função

< argumentos_planilha > é class arg_nome


Manual de sintaxe da linguagem C++mm41

E.20.1 Planilhas de funções


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

template <class T>


tipo_retorno nome_função(T parâmetro)

T é um parâmetro de planilha

template <class T>


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

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

template <class T>


void Intercâmbio(T& x, T& y)
{
T aux;
aux = x;
x = y;
y = aux;
}
int m, n;
Estudante S1;
Estudante S2;
//...
Intercâmbio(m, n); //ativação com inteiros
Intercâmbio(S1, S2); //ativação com estudantes

E.20.2 Planilhas de classes


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

template <class T>


class MinhaClasse {
//...
};

T pode ser um tipo ou uma expressão. As planilhas instanciam-se para criar classes delas.

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

Uma planilha pode ter múltiplos parâmetros:

template <class T1, class T2>


class Círculo {
//...
42mmFundamentos de programação – Algoritmos, estruturas de dados e objetos

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; }
...
};

Pode-se instanciar essa planilha da forma seguinte:


pilha<int> elementos(30); //pilha de inteiros
pilha <CCad> cadeias(20); //pilha de objetos CCad

E.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 irá terminar o programa. Um pro-
grama lança ou dispara (throws) uma exceção no ponto em que é detectado o erro. Quando acontece isso,
um programa C++ busca automaticamente o manipulador de exceções, que responde à exceção de alguma
forma apropriada. Esta resposta é denominada “capturar uma exceção” (catching). Se não podemos encontrar
um manipulador de exceções, o programa será terminado.

E.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;
Manual de sintaxe da linguagem C++mm43

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 (parâmetro){
lista_de_sentenças
}
catch (parâmetro){
lista_de_sentenças
}

E.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.

catch (const char* mensagem)


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

E.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 ativação da função;
se a lista for vazia, o compilador pode supor que nenhuma sentença throw será executada pela função, dire-
ta 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 {
//...
}
catch (A)
{
44mmFundamentos de programação – Algoritmos, estruturas de dados e objetos

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, ativa a função unexpected. Na maioria
das implementações, unexpected ativa a função terminate que ativa 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 arqui-
vo except ou except.h.

E.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, over-flow_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( )
Manual de sintaxe da linguagem C++mm45

{
const string & que_arg;
}
};

E.21.5 Resumo da sintaxe de exceções


• throw valor;
• try {
sentenças
{
catch (tipo_exceção){
sentenças
}
• try {
sentenças
}
catch (dec_argumento1) {
sentenças
}
catch (dec_argumento2) {
sentenças
}
...

E.22 ESPAÇO DE NOMES (namespace)


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
46mmFundamentos de programação – Algoritmos, estruturas de dados e objetos

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.

E.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 inde-
pendentes da definição original do espaço de nomes.

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];
}
...

E.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 compi-
lador define imprimir( ) como uma função global.

E.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.
Manual de sintaxe da linguagem C++mm47

E.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.

E.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;

E.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
pseudô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;
48mmFundamentos de programação – Algoritmos, estruturas de dados e objetos

};
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:

// 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
pendente for zero.

E.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;
}
Manual de sintaxe da linguagem C++mm49

E.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
(geometria).

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

Aplicação. Utilizar o espaço de nomes Geometria para calcular pendentes das variáveis Ponto.

#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

Вам также может понравиться