Professional Documents
Culture Documents
Transição Do C para C++
Transição Do C para C++
Superior de
Tecnologia
Para programadores de C
INTRODUÇÃO 3
ALTERAÇÕES À LINGUAGEM C 3
ESTRUTURA DO PROGRAMA 3
Ficheiros Fonte 4
Comentários 4
Constantes 4
Variáveis 4
FUNÇÕES 10
Funções inline 10
Redefinição de Funções 11
Argumentos Pré-definidos 12
Operador new 14
Operador delete 14
TÓPICOS VARIADOS 16
FICHEIROS 16
MODELOS (TEMPLATES) 20
REDEFINIÇÃO DE OPERADORES 22
Introdução
A linguagem C++ surge como uma extensão à linguagem C trazendo
!
consigo dois importantes conjuntos de novidades:
1
Informalmente diz-se que o primeiro conjunto leva àquilo a que se chama
um C melhorado (“a better C”) e é representado pelo primeiro símbolo + do
nome da linguagem. O segundo símbolo + vem das novas capacidades de
programação orientada por objectos.
Alterações à Linguagem C
Apesar da linguagem C++ ser uma extensão da linguagem C existem,
contudo, algumas alterações.
Estrutura do Programa
1
Embora os programas em C++ apresentem uma estrutura semelhante à dos
programas em C, a utilização de algumas das novas características leva-os a
apresentarem um aspecto diferente. Assim, as entradas e saídas de dados que
utilizavam anteriormente as funções printf e scanf passam a utilizar as
novas “operações” >> e << com um formato bastante diferente e que será
descrito na próxima secção.
3
Ficheiros Fonte
Extensão cpp para Uma actualização a ter em consideração é o nome dos ficheiros fonte. Uma
os ficheiros fonte
vez que a linguagem C++ é uma nova linguagem os seus ficheiros fonte irão
ter uma extensão diferente: habitualmente .cpp (C plus plus ou seja C++) ou
.C ( letra maiúscula) em alguns compiladores para Unix, em contraste com a
extensão .c dos programas em C.
Comentários
Em C++ além de se poderem usar os comentários no estilo do C (ou seja
'/*' para iniciar o comentário e '*/' para terminar o comentário), é
acrescentado um novo tipo de comentário: o comentário de uma linha.
Comentários O comentário de uma linha é iniciado pela sequência de símbolos '//', e leva
começados pelos símbolos
// e válidos apenas na linha
o compilador a ignorar qualquer caracter que se encontre a seguir a esses
corrente símbolos dentro da mesma linha. Esta forma de comentar é preferível por
ser mais fácil de gerir e originar menos erros.
Constantes
Definição de As constantes em C++ devem ser definidas a partir do modificador const,
constantes a partir do ou seja, serem definidas como variáveis acrescentando-se antes do tipo a
modificador const
palavra const. Convém recordar que sempre que se defina uma constante
desta forma deve-se obrigatoriamente inicializar a mesma.
Variáveis
Em C as variáveis apenas podiam ser declaradas a seguir ao inicio de um
bloco (após o caracter '{' ).
Declaração de Em C++ é agora possível declarar uma variável em qualquer linha de código.
variáveis em qualquer Recomenda-se, no entanto, que as variáveis sejam declaradas o mais próximo
linha de código
possível do local onde são utilizadas. Esta recomendação não se aplica se
forem usadas em vários conjuntos de instruções distintos dentro de um
mesmo bloco, pelo que neste caso será preferível a sua declaração no início
do bloco.
4
C C++
#include <stdio.h> #include <iostream.h>
. . . . . .
. . . . . .
} }
} }
Saída de dados As operações básicas de escrita no ecrã e de leitura do teclado irão ser
feita através do operador de
inserção << usado em
protagonizadas pelas novas “operações” << e >> em vez dos antigos e
conjunto com a “variável” confusos printf e scanf.
cout
Da mesma forma o valor real 15.5 pode ser escrito através de:
5
:
De uma maneira geral o operando do lado direito pode ser um inteiro, um
real (double ou float) ou qualquer outro dos tipos básicos. Também os
tipos char* e void* são reconhecidos, sendo interpretados como,
respectivamente, uma cadeia de caracteres e um endereço de memória e
escritos no ecrã de acordo. Exemplo:
Entrada de dados De uma forma análoga, a leitura de valores a partir do teclado, é efectuada
feita através do operador de
extracção >> usado em
usando cin e o operador >> (operador de extracção). Os valores lidos são
conjunto com a “variável” colocados na variável fornecida como segundo operando da operação de
cin
extracção, cin é o primeiro operando. Como exemplo da leitura de dois
valores, um do tipo double e um inteiro (int) temos:
double dval;
int ival;
7
A leitura para uma variável do tipo char* ou char[] equivale a ler uma
palavra para o endereço de memória respectivo. Apenas uma palavra é lida,
terminando a operação de leitura quando se encontrar um espaço branco. É
de referir que também a leitura de valores, incluindo do tipo char, não
recebe os espaços em branco.
6
NOTA
C C++
#include <stdio.h> #include <iostream.h>
Resultado: Resultado:
Olá mundo
Introduza um número: 12 Olá mundo
O número introduzido foi: 12 Introduza um número: 12
Introduza uma palavra: carro O número introduzido foi: 12
A palavra introduzida foi: carro
Introduza uma palavra: carro
A palavra introduzida foi: carro
LISTAGEM 2 Instruções de entrada e saída de dados
Existem ainda outras formas de escrita e leitura de valores, entre elas será
importante referir as funções de leitura get e getline e de escrita put.
7
3. Leitura de texto – com três argumentos em que o primeiro é a
cadeia de caracteres que vai receber o texto, o segundo é o
número de caracteres possíveis de armazenar na referida cadeia
de caracteres e o terceiro, que se pode omitir, é o caracter que
indica o fim da leitura que é por omissão o caracter ’\n’.
C C++
#include <stdio.h> #include <iostream.h>
printf("Ler uma linha de texto: "); cout << "Ler uma linha de texto: ";
printf( "\nTexto: %s\n", str ); cout << endl << "Texto: "<< str << endl;
printf("Ler uma linha de texto: "); cout << "Ler uma linha de texto: ";
/* Forma 3: // Forma 3:
fgets(char *, int, FILE *) */ // cin.get(char *, int, char='\n')
fgets(str, 129, stdin); cin.get(str, 129);
printf( "\nTexto: %s\n", str ); cout << endl << "Texto: "<< str << endl;
} }
8
Saída de Dados Formatada
Em C era possível efectuar uma saída de dados formatada utilizando a
instrução printf. Entre as funcionalidades oferecidas tinham-se o número
mínimo de caracteres na escrita de um valor, o número de casas decimais de
um valor real, a apresentação do sinal ou não para valores numéricos
positivos, etc. Em C++ utilizando cout existem igualmente várias
possibilidades de formatação da saída de dados.
Manipuladores
Nome Argumento Descrição
¿
oct --- Passa a mostrar os valores inteiros na notação octal
NOTA
9
C C++
#include <stdio.h> #include <iostream.h>
#include <iomanip.h>
RESULTADO: RESULTADO:
3298.23 3298.23
Teste Teste
Hello there ----
Hello there ----
Funções
No capítulo das funções em C++ foram introduzidas novidades muito
importantes, entre elas estão a possibilidade de definir várias funções com o
mesmo nome, a possibilidade de os argumentos poderem ser passados por
referência e de estes poderem também possuir valores pré-definidos.
Funções inline
Funções inline A novidade mais simples no que diz respeito às funções é o novo
permitem a colocação
directa do código da função
modificador inline. Este modificador colocado na declaração da função antes
nos locais em que esta é do tipo de retorno leva a que o compilador em vez de colocar um salto para o
chamada código da função, nos locais em que esta for chamada, coloque directamente
o código da função.
10
Redefinição de Funções
Funções com o Uma das novidades mais importantes do C++ diz respeito à redefinição de
mesmo nome são funções. Em C++ é possível definir várias funções com o mesmo nome.
possíveis e distinguem-se
pelo número e/ou tipo dos Uma vez que as funções redefinidas irão ter o mesmo nome a distinção entre
seus parâmetros
elas é feita pelos argumentos com que são chamadas. Os argumentos podem
ser diferenciados pelo número e/ou pelo seu tipo.
O tipo de retorno não permite diferenciar duas funções com o mesmo nome
e o mesmo tipo e número de argumentos.
C C++
#include <stdio.h> #include <iostream.h>
NOTA
11
No exemplo da listagem 5 mostra-se como três funções com objectivos
semelhantes (escrever uma linha de caracteres no ecrã), que em C
necessitavam de ter identificadores diferentes, podem ser definidas em C++
com um nome apenas.
Argumentos Pré-definidos
Omissão de É possível omitir alguns argumentos na chamada de uma função desde que
argumentos na na declaração ou na definição da função (e em apenas um dos sítios) apareça
chamada de uma função
através da atribuição de
o valor que o argumento irá ter se for omitido.
valores pré-definidos aos
parâmetros na declaração ou O valor por omissão é fornecido juntando um sinal de igual seguido desse
na definição da função
valor a seguir ao nome do argumento.
NOTA
#include <iostream.h>
void main(void)
{
charline();
cout << " Aluno Nota" << endl;
charline('-',25);
cout << " Joao Martins 14 " << endl
<< " Pedro Oliveira 9 " << endl
<< " Jose Silva 11 " << endl;
charline('=');
}
12
Passagem por Para indicar um argumento por referência utiliza-se o símbolo &
referência de imediatamente antes do nome do parâmetro.
parâmetros é possível
usando o operador & antes
do nome do argumento no As variáveis passadas por referência irão reflectir as alterações ao seu valor
cabeçalho da função feitas no interior da função.
C C++
#include <stdio.h> #include <iostream.h>
#include <math.h> #include <math.h>
printf("Int i -> %d\n" , iabs(i) ); cout << "Int i ->" << abs(i) << endl;
printf("Double d -> %lf\n", fabs(d) ); cout << "Double d ->" << abs(d) << endl;
printf("Complex c -> %lf\n", cabs(c) ); cout << "Complex c ->" << abs(c) << endl;
printf("Long l -> %ld\n", labs(l) ); cout << "Long l ->" << abs(l) << endl;
} }
É preciso tomar cuidado com esta forma de retornar, uma vez que a variável
retornada tem que ter existência fora da função que a retornou, o que
impossibilita o retorno de variáveis locais.
13
Estruturas de Dados Dinâmicas
Em C++ a reserva e a libertação de memória deixam de utilizar
respectivamente as funções do C malloc (ou equivalente) e free,
passando a usar os novos operadores new e delete.
Operador new
Reserva de O operador new é utilizado em C++ em substituição de malloc. Uma
memória utiliza o novo vantagem na utilização deste operador é o facto de não ser necessário utilizar
operador new em vez da
função malloc
a operação de cast para converter o ponteiro retornado num ponteiro
compatível com a variável de afectação.
ou
Operador delete
Libertação de O operador delete é utilizado em C++ com o objectivo de libertar a
memória reservada memória previamente alocada por new.
utiliza o novo operador
delete em vez da função
free Uma nota importante na utilização deste operador é que se torna possível
libertar memória a partir dum ponteiro que possua o valor NULL, esta acção
que seria desastrosa em C na função free, não irá surtir qualquer efeito em
C++.
Forma de utilização:
delete <ponteiro>;
ou
delete [ ] <ponteiro>;
14
C C++
#include <stdio.h> #include <iostream.h>
#include <string.h> #include <iomanip.h>
#include <string.h>
typedef struct telefone{
char *nome; struct TELEFONE{
long *telefone; char *nome;
}TELEFONE; long *telefone;
};
#define max_numeros 100 const max_numeros = 100;
15
Tópicos variados
Notação Funcional do Operador de Coerção (cast)
Operação de cast A operação de coerção (cast) que permite a conversão entre tipos diferentes,
utiliza os parênteses para os
valores e não para o tipo
possui uma nova notação em C++. Enquanto em C esta operação
obtinha-se colocando o tipo, para o qual se pretendia converter, entre
parênteses antes do valor a converter (Ex. Conversão de double para int
à (int)32.3), agora em C++ deve-se fazer colocando entre parênteses
o valor e não o tipo (Ex. double para int à int(32.3) ). Esta
notação tem uma sintaxe semelhante à das funções cujo nome é dado pelo
tipo da conversão e o argumento pelo valor a converter.
Ficheiros
O tratamento de ficheiros em C++ é feito principalmente com base em
1
variáveis dos novos tipos ifstream (para ficheiros de leitura), ofstream
(para ficheiros de escrita) e fstream (para escrita e leitura). Os ficheiros de
texto possuem também uma abordagem diferente da dos ficheiros binários.
As operações básicas com ficheiros mantêm-se inalteradas em C++. Assim é
possível abrir e fechar ficheiros, efectuar operações de leitura e escrita e gerir
o ponteiro de escrita e leitura dentro dos ficheiros.
Em primeiro lugar a abertura de ficheiros é feita declarando uma variável do
tipo ifstream para operações de leitura ou do tipo ofstream para
operações de escrita. O nome do ficheiro pode ser fornecido entre
parênteses directamente na declaração da variável ou através de uma função
open que é chamada associada à variável referida. Por exemplo, para abrir o
ficheiro “teste.txt” para escrita poderia-se escrever:
ofstream fich( "teste.txt" );
ou alternativamente:
ofstream fich;
fich.open("teste.txt");
16
Os ficheiros de Quando se trabalha com ficheiros de texto utiliza-se a mesma forma de
texto utilizam os escrita e leitura que quando se trabalha com o ecrã e o teclado. Por exemplo
operadores >> e <<
associados a variáveis dos
para escrever a linha “Hoje é Sábado dia 10” poderia-se fazer:
tipos ifstream e
ofstream para leitura e
fich << ”Hoje é Sábado dia ” << 10 << endl;
escrita de dados
Neste caso apenas a “variável” cout é substituída pela variável que
representa o ficheiro.
As funções get, getline e put referidas na secção de escrita e leitura
de dados também podem ser utilizadas.
Em relação à utilização de ficheiros binários, estes requerem uma abertura
efectuada de forma diferente. A função de abertura de ficheiro descrita
anteriormente, utiliza na realidade a nova funcionalidade da linguagem C++
que possibilita os argumentos por omissão. De facto, a função referida
aplicada a variáveis do tipo ofstream possui os seguintes argumentos:
open(char*,int=ios::out,int=filebuf::openprot);
O primeiro argumento leva o nome do ficheiro a abrir e o segundo o modo
•
de abertura, que no caso referido é por omissão o modo para escrita no
ficheiro. Assim sendo, para abrir ficheiros no modo binário, era necessário
referir este modo na abertura do ficheiro.
ou então,
ifstream fich;
fich.open("teste.dat", ios::in | ios::binary );
17
Os modos de abertura encontram-se resumidos na tabela 2.
in Para leitura
out Para escrita
ate Posiciona-se no fim do ficheiro após a abertura (at end)
App Para adicionar dados (append)
Trunc Inicia o ficheiro a zero (limpa-o se existir)
nocreate Falha a abertura se o ficheiro existir
noreplace Falha a abertura se o ficheiro não existir
binary Abre em modo binário
ž
seek get) contada a partir do início do ficheiro. Esta função possui uma
segunda forma com dois argumentos em que o primeiro é a posição relativa
e o segundo o local de inicio na determinação da posição efectiva. O local de
inicio pode ser dado por ios::beg – princípio do ficheiro, ios::cur –
posição corrente ou ios::end - fim do ficheiro). A função seekp possui
igualmente as mesmas possibilidades em relação ao ponteiro de escrita (seekp
significa seek put).
Por outro lado as funções tellg e tellp permitem obter respectivamente
as posições actuais dos ponteiros de leitura e de escrita nos ficheiros.
Existem ainda um conjunto de funções de teste associadas à utilização de
ficheiros, que são usadas em conjunto com as variáveis que representam os
ficheiros e que se encontram descritas na tabela 3.
18
Funções de teste em ficheiros
nome argumento descrição
C C++
#include <stdio.h> #include <fstream.h>
#include <conio.h> #include <conio.h>
19
Modelos (templates)
Funções padrão Em C++ é possível criar funções padrão (templates), que servem de modelo
permitem definir modelos
para a criação de funções
para a criação de funções. Nestas funções um ou mais dos tipos de dados
que possuem o mesmo dos argumentos e do valor de retorno não são fornecidos directamente no
código aplicado a cabeçalho da função. Esta característica permite que se criem funções com o
argumentos de tipos
diferentes código idêntico, que possuem implementações diferentes motivadas pelos
tipos de dados dos argumentos.
A título de exemplo admita-se uma função max que devolve o maior dos
valores que eram passados como argumentos. Se esses valores se referissem a
inteiros, a função poderia ser:
int max(int x, int y)
{
if( x > y )
return x;
return y;
};
Se, por outro lado estivéssemos a lidar com valores reais, então teríamos:
/
Embora o tipo dos argumentos tenha sido alterado, o código da função
permaneceu idêntico. As funções padrão permitem que os tipos envolvidos
no protótipo da função funcionem como variáveis. Segundo este princípio a
função max iria ter então a seguinte definição:
20
Como regra sempre que o compilador encontra uma chamada a uma função
segue os seguintes passos para resolver essa chamada:
Ä
Na definição de funções padrão utiliza-se uma linha inicial com a lista de tipos
diferentes que poderão constar da lista de argumentos. Esta lista aparece a
seguir à palavra template e entre os símbolos < e >. Os nomes dos tipos
deverão ser precedidos da palavra reservada class. Sintaxe usada:
char *max(char *str1, char *str2) cout << "valor char maximo: "<< max(z1,z2) << endl;
{ // é criada a função char max(char, char)
if(strcmp(str1,str2)>0)
return str1; char *str1="Texto um", *str2 = "Texto dois";
return str2;
} cout << "valor texto maximo: "
<< max(str1,str2) << endl;
// é utilizada a função char *max(char*, char*)
}
21
Redefinição de operadores
A redefinição das Regra geral todos os operadores do C++ estão preparados para trabalhar
operações associadas com os tipos de dados pré-definidos na linguagem. Por exemplo, o operador
aos operadores é efectuada
fornecendo a função:
soma (+) funciona com os tipos inteiro, caracter ou mesmo ponteiro. Mas se
operator <símbolo do o programador definir um tipo novo, por exemplo a partir de uma estrutura,
operador> (. . .)
o compilador não consegue realizar a operação e gera uma mensagem de
erro.
struct COMPLEXO{
double real;
double imag;
};
C3 = c2 + c1;
ø
A redefinição da operação passa assim pela criação de uma função especial
que irá ser chamada quando a operação e o tipo dos operandos
corresponderem à função criada. Esta função especial é caracterizada por
possuir como nome a palavra reservada operator seguida do símbolo do
operador e como argumentos variáveis do mesmo tipo dos operandos.
Retomando o exemplo anterior teríamos o seguinte código para a redefinição
da operação de soma:
return aux;
}
22
Operadores não redefiniveis
?:
.
::
.*
Os operadores >> Uma redefinição de operadores muito útil é a redefinição do operador <<
e << redefinidos para para a operação de escrita através de cout e do operador >> para a
istream e ostream
permitem a leitura e escrita
operação de leitura através de cin.
de tipos de dados definidos
pelo utilizador nas operações Na realidade cout funciona como uma variável de um tipo pré-definido na
de entrada e saída de dados
linguagem: o tipo ostream. A operação de escrita no ecrã resulta então da
redefinição que é feita do operador << para que ele funcione com este tipo
da forma conhecida. É possível, no entanto, redefinir esta operação para o
segundo operando de um novo tipo definido pelo utilizador. Por exemplo
para a escrita de um COMPLEXO utilizando cout poderia-se redefinir a
operação anterior da seguinte forma:
return os;
}
q
forma análoga, redefinir o operador >>. Note-se que neste caso cin
funciona como uma variável do tipo istream. Teríamos então:
return is;
}
23
Na listagem 11 dá-se um exemplo completo de um programa envolvendo a
redefinição dos operadores.
#include <iostream.h>
void main()
struct COMPLEXO{ {
double real; COMPLEXO c1 = {2.0,3.0},
double imag; c2={3.2,-1.3},
}; c3;
return is;
}
24