1
11
1
1
Novatec Editora
Joel Saade
C++
2
22
2
2
Copyright
2004 da Novatec Editora Ltda.
Todos os direitos reservados e protegidos pela Lei
9.610 de 19/02/1998. É proibida a reprodução desta
obra, mesmo parcial, por qualquer processo, sem prévia
autorização, por escrito, do autor e da Editora.
Editor:
R
UBENSP
RATESSegunda edição: janeiro/2006
ISBN: 85-7522-053-5
N
OVATECE
DITORAL
TDA.
Rua Luís Antônio dos Santos 110
02460-000 São Paulo SP – Brasil
Tel.: +55 11 6959-6529
Fax: +55 11 6950-8869
E-mail:
novatec@novatec.com.br
3
33
3
3
Conceitos básicos ... 5 Estrutura de um programa C++ ... 5Descobrindo a versão do compilador ... 5
Compilação e link-edição de programas ... 5
Arquivos-cabeçalho ... 5
Identificadores ... 6
Variáveis ... 6
Comentários ... 6
Tabela de seqüências de escape ... 6
Operadores ... 7 Atribuição ... 7 Aritméticos ... 7 Aritméticos de atribuição ... 7 Incremento e decremento ... 7 Relacionais ... 7 Condicional ternário ... 8 Lógicos ... 8 Bitwise ... 8 Comprimento ... 9 Conversão de tipos ... 10
Type cast (Conversão forçada de tipos) ... 10
Comandos ... 12 Bloco ... 12 Decisão ... 12 Iteração ... 13 Desvio ... 15 Pré-processador ... 16 Diretivas do pré-processador ... 16
Diretivas de pré-processamento/compilação condicional .... 17
Macros do pré-processador ... 17
Operadores do pré-processador ... 17
Asserções ... 17
Tipos de dados predefinidos ... 18
Tipos Simples ... 18
Tabela dos tipos de dados integer e character ... 19
Tipos compostos ... 20 Arrays bidimensionais ... 21 Strings ... 22 Estruturas ... 23 Uniões ... 28 Enumeração ... 28 Ponteiros ... 29
Typedef - Nome alternativo para tipos ... 37
Funções ... 38
Estrutura de uma função ... 38
Protótipo de função ... 38
Chamada a uma função ... 38
Retorno de valor e recepção de argumentos ... 39
Tipos de passagem de argumentos e referência ... 40
Funções recursivas ... 41
Argumentos const ... 42
Argumento-default ... 42
Funções inline ... 42
Passagem de argumentos à função main() ... 43
Sobrecarga de funções ... 43
Entrada e saída básicas ... 44
Leitura de caracteres via teclado ... 44
Classes de memória ... 45 Escopo ... 45 Ligação ... 45 Classe automática ... 45 Classe estática ... 46 Classe dinâmica ... 47
Tabela de classes de memória ... 47
4
44
4
4
Namespaces ... 48 Definição de namespaces ... 49 Classes e objetos ... 50Declaração de classes e criação de objetos ... 50
Métodos externos à classe ... 51
Métodos inline ... 51
Seções de uma classe ... 52
Chamadas qualificada e não qualificada a um método ... 53
Construtor de classes ... 53 Destrutor de classes ... 56 Construtor default ... 56 Construtor de cópia ... 59 Construtor explicit ... 60 Array de objetos ... 61 Métodos const ... 62 Argumentos const ... 62
Métodos const X atributo mutable ... 63
Escopo de classe ... 63
Friends ... 63
Passagem de objetos como argumentos ... 67
Sobrecarga de operadores ... 68
Retorno de objetos ... 69
Variáveis-membro static ... 70
Métodos static ... 71
Classes e alocação dinâmica de memória ... 72
Herança de classes ... 73
Herança simples ... 73
Tabela de tipos de herança ... 76
Tabela de permissões de acesso ... 76
Classes-base abstratas ... 76
Herança múltipla ... 77
Níveis de herança (Cadeia de herança) ... 79
Métodos virtuais ... 81
Destrutores virtuais ... 83
Métodos virtuais e classes-base abstratas ... 84
Templates ... 86
Template de funções ... 86
Template de classes ... 86
A classe string ... 88
Manipulação de objetos string com operadores ... 88
Manipulação de objetos string com métodos ... 89
Entrada e saída com objetos string ... 97
Exceções ... 99
Exceções e funções ... 100
Múltiplos blocos try ... 101
Captura de qualquer exceção ... 102
Exceções e classes ... 102
Entrada e saída avançadas ... 104
Streams ... 104
Saída com cout ... 104
Entrada com cin ... 108
Processamento de arquivos ... 114
Gravação de arquivos ... 114
Leitura de arquivos ... 114
Entrada e saída formatadas ... 114
Outras possibilidades de entrada/saída ... 115
Verificação de erros ... 116
Modos de abertura de arquivos ... 117
Impressão de arquivos ... 118
Arquivos binários, métodos write() e read() ... 118
RTTI (RunTime Type Information) ... 121
Componentes do RTTI ... 121
Tabela de operadores e precedências ... 122
5
55
5
5
Conceitos básicos
Estrutura de um programa C++
A estrutura é simples e é a seguinte:#include < ... > using namespace ...; tipo main() {{{{{ comandos;;;;; }}}}}
Elemento
Significado
#include Identifica os arquivos-cabeçalho utilizados no programa. using namespace Identifica os namespaces utilizados no programa. tipo Tipo do valor a ser retornado pela função main(). main() Função obrigatória. Todo programa se inicia por ela,
independentemente da sua localização no programa. { } Identifica o início/fim da função main().
Exemplo: Exibe uma frase no vídeo e salta de linha.
#include <iostream> using namespace std; int main()
{
cout << “Hello World\n”; return 0;
}
Descobrindo a versão do compilador
• No djgpp, digite gcc -v • No Linux, digite g++ -vCompilação e link-edição de programas
• No djgpp, para compilar/linkar um único programa:
gcc -c p1.cpp gxx -o p1.exe p1.o
• No djgpp, para compilar/linkar vários programas:
gcc -c p1.cpp p2.cpp gxx -o p3.exe p1.o p2.o
• No Linux, para compilar/linkar um único programa:
g++ p1.cpp -o p1
• No Linux, para compilar/linkar vários programas:
g++ p1.cpp p2.cpp -o p3
Arquivos-cabeçalho
Arquivos incluídos no programa por meio da diretiva #include. Contêm protótipos de funções, definições de macros, declarações de tipos, de estruturas, de classes e de constantes.
Formato
Significado
#include <nome> Procura um arquivo-cabeçalho no diretório-padrão de arquivos-cabeçalho.
6
66
6
6
Identificadores
São nomes dados pelo programador a variáveis, funções, classes etc. Podem conter somente caracteres alfabéticos minúsculos/ maiúsculos, numéricos e o _ (sublinhado). O primeiro caractere deve ser alfabético ou _ (sublinhado).
Variáveis
Variáveis podem ser declaradas em qualquer ponto dentro de uma função, mas sempre antes de serem utilizadas.
Exemplos:
int valor1 = 40, valor2 = 50; double raiz = sqrt(25.); float saldo (1500.);
Case sensitivity
C++ distingüe maiúsculas de minúsculas, inclusive em relação às suas palavras reservadas, que devem ser escritas em letras minúsculas. Identificadores, como ano e ANo são distintos.
Comentários
Documentam o programa, sendo ignorados pelo compilador. São escritos utilizando-se os caracteres // ou /* */.
Exemplos:
// Função para cálculo da área de um retângulo int status = 0; // Variável de controle /* Linha 1
Linha 2 */
Tabela de seqüências de escape
As seqüências de escape são constituídas pelo caractere \ seguido de outros. Permitem a utilização de caracteres que não podem ser digitados ou que têm um significado especial para C++.
\a Emite um alerta sonoro 7 07 \b Move o cursor para a esquerda 8 08 \f Salta para uma nova página 12 0C \n Salta de linha e posiciona o cursor no
seu início 10 0A \r Move o cursor para o início da linha 13 0D \t Move o cursor para a próxima posição
de tabulação horizontal 9 09 \v Move o cursor para a próxima posiçãode tabulação vertical 11 0B \” O caractere “ 34 22 \’ O caractere ‘ (apóstrofo) 39 27 \? O caractere ? 63 3F \\ O caractere \ 92 5C \0 Caractere nulo 0 00 \xxx O caractere correspondente ao valor
octal xxx
\xhhh O caractere correspondente ao valor hexadecimal hhh
Seqüência de
escape Significado
Código ASCII decimal hexa
As seqüências de escape podem ser escritas de três formas equivalentes e entre aspas ou apóstrofos.
Forma
Exemplo
Simbólica cout << “\a”; Numérica hexadecimal cout << “\x043”; Numérica octal cout << “\103”;
7
77
7
7
Operadores
Atribuição
Operador
Significado
= Atribui o valor de um elemento a outro. Exemplos:
valor1 = 99; // Atribuição simples valor2 = valor3 = valor4 = 9; // Atribuição múltipla
Aritméticos
Operador
Significado
Precedência
* Multiplicação 1
/ Divisão 1
% Resto da divisão entre inteiros 1
+ Adição 2
- Subtração 2
Aritméticos de atribuição
Operador
Significado
*= Multiplicação com atribuição.
/= Divisão com atribuição.
%= Resto da divisão entre inteiros com atribuição.
+= Adição com atribuição.
-= Subtração com atribuição.
Exemplos:
taxa *=*=*=*=*= 3; equivale à taxa = taxa * 3; total +=+=+=+=+= 20; equivale à total = total + 20;
Incremento e decremento
Operador
Significado
Forma
Precedência
variável++++++++++ Adiciona 1 de sufixo 1 variável--- Subtrai 1 de sufixo 1 ++
++ ++ ++
++variável Adiciona 1 de prefixo 2
----variável Subtrai 1 de prefixo 2
• X++ significa: use o valor atual de X e some 1 a esse valor. O mesmo vale para o operador ---.
• ++X significa: some 1 ao valor de X e então use esse novo valor. O mesmo vale para o operador ---.
Exemplos: int X = 5, Y = 0, Z = 5, W = 0; Y = X++; W = ++Z; cout << X << " " << Y << endl; // X = 6 e Y = 5 cout << Z << " " << W << endl; // Z = 6 e W = 6
Relacionais
Operador
Significado
Precedência
< Menor que 1
<= Menor que ou igual a 1
> Maior que 1
>= Maior que ou igual a 1
== Igual a 2
!= Não igual a 2
8
88
8
8
Condicional ternário
É uma forma alternativa a um comando if ... else.
exp1 ????? exp2 ::::: exp3
Se exp1 for verdadeira, o valor de toda a expressão será o valor de exp2, caso contrário, o valor de exp3.
Exemplos:
y = (6 < 2) ? 1 : 2; // y = 2
cout << (saldo < 400. ? “Pedir empréstimo” : “Bom saldo”);
Lógicos
not (
( (
( (!)))))
Nega (inverte) o valor-verdade de uma expressão. Para negar uma expressão, use parênteses; o operador not tem maior precedência que os operadores relacionais e demais operadores lógicos.
not not not not
not exp ou !!!!! exp
Exemplo:
x = not(5 > 9); // x = 1
and ( ( ( ( (&&)))))
Combina duas expressões em uma, que terá o valor true ou false.
exp1 andandandandand exp2 ou exp1 &&&&&&&&&&exp2
Exemplo:
x = 7 > 6 and 3 < 5; // x = 1
or (
( (
( (||)))))
Combina duas expressões em uma, que terá o valor true ou false.
exp1 ororororor exp2 ou exp1 ||||||||||exp2
Exemplo:
x = 7 > 8 or 3 < 5; // x = 1
Bitwise
Manipulam bits de valores inteiros.
Deslocamento de bits de um valor inteiro
valor << n Desloca n bits à esquerda. Equivale a multiplicar por 2n.
valor >> n Desloca n bits à direita. Equivale a dividir por 2n.
Exemplos:
// Deslocamento à esquerda short int item = 12;
item = item << 1; // Equivalência: item <<= 1; cout << “Depois do deslocamento: “<<item<< endl; // 24 // Deslocamento à direita
unsigned short int item = 12;
item = item >> 1; // Equivalência: item >>= 1; cout << “Depois do deslocamento: “<<item<< endl; // 6
Bitwise lógicos
Atuam sobre os bits de um valor e não sobre o valor como um todo.
~ (Negação (complemento de 1))
Converte bits 0 em 1 e vice-versa. Exemplo:
unsigned short int valor1 = 12; valor1 = ~valor1;
cout << “Depois da negação: “ <<valor1<<endl; / /
9
99
9
9
65523 | (OR inclusivo)Combina dois valores criando um novo valor. Exemplo:
unsigned short int valor1 = 51,valor2 = 89,valor3; valor3 = valor1 | valor2;
cout << “valor1 | valor2: “ << valor3 << endl; // 123
^ (XOR (OR exclusivo))
Combina dois valores criando um novo valor. Exemplo:
unsigned short int valor1 = 51,valor2 = 89,valor3; valor3 = valor1 ^ valor2;
cout << “valor1 ^ valor2: “ << valor3 << endl; // 106
& (AND)
Combina dois valores criando um novo valor. Exemplo:
unsigned short int valor1 = 51,valor2 = 89,valor3; valor3 = valor1 & valor2;
cout << “valor1 & valor2: “ << valor3 << endl; // 17
Bitwise alternativos
São operadores bitwise lógicos na forma de palavras.
Operador padrão
Operador alternativo
~ compl | bitor ^ xor & bitand |= or_eq ^= xor_eq &= and_eq
Tabela de precedência de operadores bitwise
Operador
Significado
Precedência
~ Negação (complemento de 1) 1
<< Deslocamento à esquerda 2
>> Deslocamento à direita 2
& AND 3
^ XOR (OR exclusivo) 4
| OR inclusivo 5
<<= Deslocamento à esquerda com atribuição 6 >>= Deslocamento à direita com atribuição 6
&= AND com atribuição 6
^= XOR (OR exclusivo) com atribuição 6
|= OR inclusivo com atribuição 6
Comprimento
Retorna o comprimento, em bytes, do seu operando.
sizeof( sizeof( sizeof( sizeof( sizeof(operando))))) Exemplos:
int vetor[3], matriz[2][3],valor; cout << sizeof(float); // 8 cout << sizeof(vetor); // 12 cout << sizeof(matriz); // 24 cout << sizeof(valor); // 4
10
10
10
10
10
Conversão de tipos
C++ efetua conversões de um tipo de dado em outro, automaticamente, nos seguintes casos:
• atribuição de valores; • expressões aritméticas;
• passagem de argumentos a uma função. Exemplo 1:
// Conversão automática na atribuição short int valor1 = 10;
long int valor2;
valor2 = valor1; // Converte short int em long int
Exemplo 2:
// Conversão automática em expressões aritméticas int valor1 = 10;
float valor2 = 20.;
double total = valor1 + valor2;
valor1 é convertido em float e o resultado, em double. Exemplo 3:
// Conversão automática na passagem de argumentos double somar(double,double); // Protótipo int main()
{
float valor1 = 10.,valor2 = 20.;
double total = somar(valor1,valor2); // Chamada return 0;
}
double somar(double v1,double v2) // Definição {
return v1 + v2; }
valor1 e valor2 são convertidos em double.
Type cast (Conversão forçada de tipos)
Conversão de um tipo em outro, de modo explícito. A forma inicial de type cast, vinda da linguagem C e também aceita por C++, é a seguinte:
( ((
((tipo))))) valor
C++ altera levemente essa sintaxe para:
tipo (((((valor)))))
Elemento
Significado
tipo Tipo no qual valor será convertido.
valor Constante, variável ou expressão a sofrer typecast. Exemplos:
// Type cast antes da adição. Resultado 3 int valor1, valor2;
valor1 = int(1.6) + int(2.5);
// Adição antes do type cast. Resultado 4 valor2 = int(1.6 + 2.5);
// Type cast de valor do tipo char char letra = ‘z’;
cout << “Código ASCII “ << int(letra); // 122
11
11
11
11
11
static_cast
Converte ponteiros de uma classe em ponteiros de uma outra classe, em uma cadeia de herança. Pode ser utilizado ainda para efetuar algumas conversões entre tipos relacionados, como aquelas efetuadas pelo type cast da linguagem C. A conversão é feita na compilação.
static_cast < static_cast < static_cast < static_cast <
static_cast <tipo> (> (> (> (> (valor)))))
Exemplo: int x = 10, y = 4; float q; q = x / y; cout << q << endl; // 2 q = static_cast<float>(x) / static_cast<float>(y); cout << q << endl; // 2.5
const_cast
Type cast que anula o efeito dos qualificadores const e volatile.
const_cast < const_cast < const_cast < const_cast <
const_cast <tipo> (> (> (> (valor)))))> (
• tipo deve ser igual ao tipo original. Exemplo:
...
void alter(const int *); // Protótipo da função alter() int main()
{
int valor = 55;
cout << "valor antes: " << valor endl;
alter(&valor); // Chama a função alter() cout << "valor depois: " << valor << endl; return 0;
}
void alter(const int * pt1) // Definição da função alter() { int * pt2; pt2 = const_cast<int *>(pt1); *pt2 = 999; } Resultado do programa valor antes: 55 valor depois: 999
Como o argumento int * é const, a função alter() não poderia alterá-lo, mas com o type cast, essa restrição foi anulada.
reinterpret_cast
Converte um ponteiro em qualquer outro tipo de ponteiro. Converte ainda qualquer tipo inteiro (e seus subtipos, inclusive char) em um ponteiro e vice-versa.
Exemplo:
int valor = 65; int * ptr = &valor;
cout << *reinterpret_cast<char *>(ptr); // A
12
12
12
12
12
Comandos
Bloco
Comandos escritos entre { }. Os blocos têm uma propriedade: se uma nova variável for definida dentro de um bloco, essa persistirá enquanto o bloco estiver em execução. Ao término de sua execução, a variável deixará de existir.
Exemplo:
int valor1 = 100;
{ // Início do bloco int valor2 = 200;
cout << “valor1 (no bloco) = “<<valor1<< endl; // 100 cout << “valor2 (no bloco) = “<<valor2<< endl; // 200 } // Fim do bloco
cout << “valor1 (fora do bloco) = “ << valor1 << endl; // 100 // Erro: uso de valor2 fora do bloco onde foi definida // cout << “valor2 (fora do bloco) = “ << valor2 << endl;
Decisão
if
Tomada de decisão com base no resultado de uma expressão.
if if if if if (((((exp))))) comando1;;;;; [elseelseelseelseelse
comando2;;;;;]
Elemento
Significado
exp Expressão cujo valor será determinado.
comando1 Comandos a serem executados se exp for verdadeira (ou != 0). Se implicar mais de um comando, escrevê-los entre { }. comando2 Comandos a serem executados se exp for falsa (ou == 0). Se
implicar mais de um comando, escrevê-los entre { }.
If’s encadeados
Constituem-se em uma seqüência de comandos if. Exemplo:
if (num == 1)
cout << "Um" << endl; else
if (num == 2)
cout << "Dois" << endl; else
cout << “Número inválido“ << endl;
switch
Permite a execução de comandos conforme uma expressão, em uma estrutura de decisões múltiplas.
switch ( switch ( switch ( switch ( switch (exp_inteira))))) { case casecase case
case constante1 ::::: [comando1;;;;;] case
casecase case
case constante2 ::::: [comando2;;;;;] . . .
. . .. . . . . . . . .
[default :default :default :default :default : [comandoN;;;;;]] }
13
13
13
13
13
Elemento
Significado
exp_inteira Expressão a ser comparada com cada uma das constantes. Deve resultar em um valor do tipo inteiro.
constante1... Constante ou expressão constante inteira que se espera corresponder à exp_inteira. Pode ser uma constante na forma de uma letra, pois exp_inteira pode ser do tipo char. Cada constante deve ser diferente da outra.
comando1... Comandos a serem executados caso exp_inteira coincida com a respectiva constante.
comandoN Comandos a serem executados caso exp_inteira não corresponda a nenhuma das constantes.
Exemplo:
switch (num) // Supondo num do tipo int {
case 1 : cout << "Um" << endl; break; case 2 : cout << "Dois" << endl; break;
default : cout << "Número inválido" << endl; break; }
Iteração
for
Executa comandos enquanto uma condição for verdadeira.
for for for for
for (exp1;;;;; exp2;;;;; exp3) corpo;;;;;
Elemento
Significado
exp1 Expressão que inicializa a variável de controle do loop. É executada apenas uma vez.
exp2 Geralmente uma expressão relacional que verifica a variável de controle. Se o seu resultado for verdadeiro, o loop continuará, caso contrário, terminará. Se for falso na primeira vez, o corpo não será executado.
exp3 Expressão que atualiza a variável de controle.
corpo Comandos a serem executados caso exp2 seja verdadeira. Se contiver mais de um comando, escrevê-los entre { }. Exemplo:
int k, somat = 0; // Soma os valores de 1 a 5 for (k = 1;k < 6;k++)
{
cout << “k = “ << k << " "; somat = somat + k; }
cout << endl << “Somatório: “ << somat << endl; // 15
Uma variável declarada em exp1 fica restrita ao corpo do for: Exemplo:
for (int k = 1; k < 4; k++) cout << k << endl;
// cout << k; Erro: k não pode ser usada fora do for
Pode-se omitir exp1, usando-se o caractere “;” no seu lugar: Exemplo:
int k = 1;
for (;k < 4;k++) // Omissão de exp1 cout << “k = “ << k << endl;
exp2 pode ser uma expressão que, enquanto resultar em valor diferente de 0, implicará a execução do loop, caso contrário, o término: Exemplo:
for (k = 3; k; k—= 1)
cout << “k = “ << k << endl;
14
14
14
14
14
Pode-se omitir exp3, usando-se o caractere ";" no seu lugar: Exemplo:
int k = 1;
for (;k < 4;) // Omissão de exp1 e exp3 {
cout << “k = “ << k << endl;
k++; // exp3 é escrita no corpo do loop }
O operador , (vírgula)
Permite o uso de mais de uma expressão onde uma é permitida. Exemplo:
int k, somat;
for (k = 1, somat = 0; k < 6; k++)
while
Executa comandos enquanto uma condição for verdadeira.
while while while while while (exp) corpo;;;;;
Elemento
Significado
exp Geralmente uma expressão relacional que controla o loop. Se oseuresultadoforverdadeiro,oloopcontinuará,casocontrário, terminará. Se for falso na 1ª vez, o corpo não será executado. corpo Comandos a serem executados caso exp seja verdadeira. Se
contiver mais de um comando, escrevê-los entre { }. Exemplo:
int k = 1, somat = 0; // Soma os valores de 1 a 5 while (k < 6) { cout << “k = “ << k << " "; somat = somat + k; k += 1; }
cout << endl << “Somatório: “ << somat; << endl; // 15
exp pode ser uma expressão que, enquanto resultar em valor diferente de 0, implicará a execução do loop, caso contrário, o término: Exemplo: int k = 3; while (k) { cout << “k = “ << k << endl; k -= 1; }
do while
Executa comandos enquanto uma condição for verdadeira. O corpo do loop é executado pelo menos uma vez.
do do do do do corpo;;;;; while ( while ( while ( while ( while (exp);););););
Elemento
Significado
exp Geralmente uma expressão relacional que controla o loop. Se o seu resultado for verdadeiro, o loop continuará, caso contrário, terminará.
corpo Comandos a serem executados caso exp seja verdadeira. Se contiver mais de um comando, escrevê-los entre { }.
15
15
15
15
15
Exemplo:char codigo = ‘#’,senha; do {
cout >> “Digite a senha: “; cin >> senha; } while (senha != codigo);
Loops aninhados
Loop aninhado: um loop contido em outro. No exemplo seguinte, a cada iteração do for externo há 3 iterações do for interno. Exemplo:
int j, k;
for (j = 1;j < 4;j++) // loop externo {
cout << “j = “ << j << endl;
for (k = 1;k < 4;k++) // loop interno cout << “ k = “ << k << endl;
}
Desvio
break
Salta partes de código saindo da estrutura (for, while, do while ou switch) onde se encontra.
break break break break break;
A seguir, a sintaxe do comando break com o comando while:
while (exp) {
comando1;;;;; if (condição)
break; // Encerra o loop e desvia paracomando3 comando2;;;;;
} comando3;
continue
Salta partes do código de um loop (for, while ou do while), causando um retorno à sua expressão de controle.
continue continue continue continue continue;
A seguir, a sintaxe do comando continue com o comando while:
while (exp) {
comando1;;;;; if (condição)
continue; // Retorno à expressão de teste comando2;;;;;
}
goto
Desvia para um ponto identificado, no programa.
goto gotogoto goto goto rótulo:;:;:;:;:; Exemplo: if (divisor == 0) goto fim; ... fim:
cout << “Divisão impossível” << endl;