Академический Документы
Профессиональный Документы
Культура Документы
SUMÁRIO
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.
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
+ - * / = ( ) { } [ ] < > ‘ “ ! @ = / $ ^ & % - : . , ; ? \ |
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:
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
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
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
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++
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++.
• enumerações (enum)
• estruturas (struct)
• uniões (união)
• arrays
• classes (classe e struct)
• uniões e enumerações anônimas
• ponteiros
• 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;
}
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.
As cadeias de caracteres estão entre aspas e as constantes de um só caractere estão entre apóstrofos.
Uma constante literal é um valor escrito diretamente no programa sempre que seja necessário. Por exemplo:
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:
C++ modificou a notação anterior por uma notação funcional como alternativa sintática:
nome do tipo (expressão)
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.
Exemplos
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:
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
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.
a = b+ (c=10);
equivale a:
c=10;
a=b + c;
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
+= 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;
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.
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.
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)
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);
::.->[ ]( ) 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.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
cout << i;
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
}
#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;
#include <iostream.h>
int main( )
{
int i;
cin >> i;
cout << i << “\n”;
return 0
}
#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
#include <iostream.h>
int main( )
{
int i = 36;
cout << dec << i <<" " << oct << i <<" " << hex << i <<"\n";
return 0
}
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.
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;
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
{
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);
}
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++;
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;
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;
}
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;
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
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
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 é:
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
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:
A sentença continue termina a iteração que está sendo efetuada e começará de novo a seguinte iteração:
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.
char cad[80]=“Cazorla”;
int i;
return expressã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.
Uma vez declarado um ponteiro, podem ser fixados o endereço ou a posição de memória do tipo que foi
apontado.
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 * ip;
double *dp;
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.
int lista[5];
lista[3] = 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
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.
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
estabelece v como um ponteiro a um objeto que não pode ser modificado. Um exemplo pode ser:
vptr = iptr;
iptr = vptr; //Incorreto em C++, correto em C
iptr = (int *), vptr; //Correto em C++
...
}
Constantes de cadeia
Sua declaração é semelhante a
char *Cadeia = “Meu professor”;
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;
#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;
if (*ptr1 == *ptr2)
cout << “*ptr1 é igual a *ptr2 \n”;
else
cout << “*ptr1 não é igual a *ptr2\n”;
}
new NomeTipo
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;
#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
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]
int multidim[4][10][3];
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;
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
};
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;
};
alfa w;
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
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
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.
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
ImprimirValores(n,a);
ImprimirValores(n); //equivalente a ImprimirValores (n, 0.0)
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.
#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
ou
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
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
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.
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.
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.
#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
};
class( )
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.
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
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;
};
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( )
class nome {
...
friend protótipo_de_função;
...
};
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.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
};
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.
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.
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
//...
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)
o compilador avalia a expressão ativando uma das seguintes funções, dependendo de em qual esteja definida:
classe Cponto {
private:
double x, y;
public:
Cponto& operator = (const Cponto& ponto);
...
};
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
};
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
T é um parâmetro de planilha
T pode ser um tipo ou uma expressão. As planilhas instanciam-se para criar classes delas.
MinhaClasse <int> x;
MinhaClasse <Estudante> MinhaEstudante;
private:
T1 x;
T2 y;
T2 raio;
};
//...
Círculo <int, long> c;
Círculo <unsigned, float> D;
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.
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
}
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( )
{ 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.
{
const string & que_arg;
}
};
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.
nome_espaço_de_nomes::nomes_membro
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.
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
O qualificador nome deve ser um nome de espaço definido anteriormente. Podem aparecer as diretivas
using em escopos locais e globais.
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”
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.
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
#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”
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