25
Escola Superior de Tecnologia TRANSIÇÃO PARA C C + + + + Para programadores de Pascal José Cordeiro e Joaquim Filipe © 1998

Transição do Pascal para C++

Embed Size (px)

Citation preview

Page 1: Transição do Pascal para C++

Escola Superior de Tecnologia

TRANSIÇÃO PARA CC++++ Para programadores de Pascal

José Cordeiro e Joaquim Filipe © 1998

Page 2: Transição do Pascal para C++

E S C O L A S U P E R I O R D E T E C N O L O G I A / I N S T I T U T O P O L I T É C N I C O D E S E T Ú B A L

Transição para CC++++

Para programadores de Pascal

Dezembro 1998 José Cordeiro e Joaquim Filipe Escola Superior de Tecnologia / Instituto Politécnico de Setúbal

R do Vale de Chaves, Estefanilha • 2910 Setúbal Telefone (065) 790000 • Fax (065) 721869

[email protected] [email protected]

Page 3: Transição do Pascal para C++

Índice ÍNDICEÍNDICE 33

INTRODUÇÃOINTRODUÇÃO 44

ALGUMAS DIFERENÇAS FALGUMAS DIFERENÇAS F UNDAMENTAIS ENTRE O UNDAMENTAIS ENTRE O PASCAL E O C++PASCAL E O C++ 44

ESTRUTURA DO PROGRAMESTRUTURA DO PROGRAM AA 55

Blocos 5 Comentários 5 Funções 5

TIPOS DE DADOS ELEMETIPOS DE DADOS ELEME NTARESNTARES 66

VARIÁVEISVARIÁVEIS 77

Definição 7 Inicialização 7 Variáveis globais 7 Existência e visibilidade 7

CONSTANTESCONSTANTES 88

OPERADORES E EXPRESSOPERADORES E EXPRESS ÕESÕES 99

Operadores aritméticos 9 Operadores relacionais 9 Operadores Lógicos 9 Atribuição 9 Precedências 10 Funções associadas aos tipos de dados elementares 11 Expressões 11 Conversão entre tipos de dados elementares 11 Operador de coerção (cast) 12

ENTRADA E SAÍDA ENTRADA E SAÍDA DE DADOSDE DADOS 1313

Entrada de Dados 13 Saída de Dados Simples 13 Saída de Dados Formatada 14

ESTRUTURAS DE CONTROESTRUTURAS DE CONTRO LO LO -- SELECÇÃO SELECÇÃO 1414

Instrução If 14 Instrução Switch 15

ESTRUTURAS DE CONTROESTRUTURAS DE CONTRO LO LO -- REPETIÇÃO REPETIÇÃO 1616

Instrução for 16 Instrução while 16 Instrução do-while 17

SUBPROGRAMASSUBPROGRAMAS 1717

Funções e Procedimentos 17 Transmissão de Parâmetros 17 Retorno de Valores (funções) 18 Protótipos de Funções 19

TIPOS DE DADOS AVANÇTIPOS DE DADOS AVANÇ ADOSADOS 1919

Tipo enumerativo 19 Matrizes 19 Cadeias de caracteres 20 Registos 21 Ficheiros 22 Tipos de dados definidos pelo utilizador 22

ESTRUTURAS DE DADOS ESTRUTURAS DE DADOS D INÂMICASDINÂMICAS 2323

Listas 23

Page 4: Transição do Pascal para C++

44

Introdução A linguagem C++ surge como uma extensão à linguagem C trazendo consigo dois importantes conjuntos de novidades:

1. Melhorias e acrescentos à linguagem C

2. Possibilidade de programação orientada por objectos

Este segundo conjunto de novidades não será tido em conta neste manual.

Este manual pretende ilustrar, de uma forma prática e simples, a passagem da linguagem Pascal para a linguagem C++. Neste sentido apenas se referem as características existentes na linguagem Pascal que têm correspondência na linguagem C++. Para uma transição completa seria ainda necessário analisar as características do C++ que funcionam como uma extensão ao Pascal e as novas possibilidades de programação orientada por objectos.

A transição para C++ a partir do Pascal é feita directamente não se fazendo nenhuma referência à linguagem C nem sendo necessário o conhecimento desta. Isto deve-se, principalmente, a esta forma de transição ser mais simples e preferível.

Algumas Diferenças Fundamentais entre o Pascal e o C++ Do ponto de vista da transição do Pascal para o C++ estas linguagens podem ser consideradas muito semelhantes sendo as suas diferenças principalmente de sintaxe. Para uma melhor compreensão convém, no entanto, referir algumas diferenças básicas de sintaxe e estrutura que se consideram fundamentais:

§ Enquanto em Pascal é indiferente a utilização de maiúsculas e minúsculas, em C++ existe essa distinção, sendo todas as palavras reservadas desta linguagem escritas em letras minúsculas.

§ O ponto-e-vírgula em Pascal é utilizado para separar instruções. Em C++ esse caracter é utilizado para terminar instruções.

§ Enquanto em Pascal os subprogramas podem ser de dois tipos: funções e procedimentos, em C++ apenas existem funções. Contudo, existe em C++ o tipo void (vazio), pelo que é possível obter, em C++, o mesmo efeito dos procedimentos do Pascal, utilizando funções que retornam void.

§ Os subprogramas em C++ (as funções) estão todos ao mesmo nível, não se podendo colocar uns dentro de outros como acontece em Pascal.

!!11

E M C + +

Aa Maiúsculas diferenciadas

; O Sinal ; termina instruções

f() Subprogramas só funções

f() Funções ao mesmo nível

Page 5: Transição do Pascal para C++

55

Estrutura do Programa Blocos Em Pascal, o conceito de bloco é essencial. Sintacticamente, o programa é constituído por um cabeçalho, um bloco e um ponto final. O bloco contém, por sua vez, diversas zonas incluindo, em particular, todas as funções e procedimentos utilizados pelo programa, bem como o corpo (zona de instruções) do programa principal.

Em C++ não existe o conceito de bloco. O programa principal é apenas mais uma função, ainda que com um nome especial: main. Esta função é a primeira a ser executada. Todas as outras funções definem-se ao mesmo nível desta função principal.

Em Pascal todas as instruções encontram-se agrupadas dentro de uma outra forma de bloco: o bloco de instruções. Este bloco é delimitado pelas palavras begin e end.. Tal como acontece em Pascal em C++ esta forma de bloco existe utilizando-se neste caso como caracteres delimitadores as chavetas. Este tipo de bloco pode também ser utilizado sempre que se precise de colocar mais que uma instrução num local onde a sintaxe da linguagem obrigue à utilização de apenas uma instrução (Ex.: nos ciclos for) e denomina-se neste caso de instrução composta.

PascalPascal C++C++ Begin

<instrução>;

<instruções>

end

{

<instrução>;

<instruções>;

}

FIGURA 1 Bloco de instruções ou instrução composta

Comentários Os comentários colocados dentro de um programa em C++ são introduzidos de forma diferente: são começados pela sequência // e levam o compilador a ignorar tudo o que apareça a seguir dentro da mesma linha. Existe também a possibilidade de utilizar comentários muito semelhantes aos usados em Pascal em que as chavetas que delimitam os comentários (Ex.: {comentário...}) são substituídas em C++ pela sequência de símbolos /* e */ (Ex.: /*comentário...*/). No entanto, esta segunda forma de comentar é desaconselhada por ser mais difícil de gerir e poder originar erros de programação.

Funções Todas as funções em C++ necessitam de ser declaradas antes de serem utilizadas para que o compilador reconheça o seu formato, algo semelhante à utilização da declaração forward em Pascal.

Blocos de instruções definidos entre os símbolos { e }

Comentários começados pela sequência de símbolos // e válidos apenas na linha corrente

Funções com declaração obrigatória.

Page 6: Transição do Pascal para C++

66

Enquanto em Pascal as funções standard da linguagem são automaticamente reconhecidas, em C++ é necessário fornecer a sua declaração. Isto é feito habitualmente através de uma linha de código colocada no início do programa. Esta linha leva o programa de compilação a incluir no programa o texto de um ficheiro contendo a declaração das funções utilizadas (e.g. #include <iostream.h> para incluir o ficheiro iostream.h com as principais funções de entrada e saída do C++).

Na figura seguinte dá-se um exemplo de um programa completo escrito em Pascal e em C++ para permitir a comparação da estrutura do programa nas duas linguagens.

LISTAGEM 1 programa para calcular o factorial de um número.

Tipos de Dados Elementares Entre os tipos de dados básicos do Pascal iremos considerar os tipos caracter, inteiro, real e lógico.

Os tipos de dados caracter e inteiro são semelhantes nas linguagens Pascal e C++.

O tipo real aparece em C++ sub-divido em dois tipos: float e double. Estes tipos são idênticos permitindo guardar um valor real, a sua única diferença é a precisão, tendo o tipo double uma precisão dupla em relação ao tipo float. Deve-se acrescentar que é preferível usar o tipo double por questões de compatibilidade com as funções matemáticas do C++.

O tipo lógico não é suportado directamente pelo C++, em vez disso utiliza-se o valor inteiro 0 para representar o valor falso e um valor inteiro diferente de 0 (normalmente o –1 ou o 1) para representar o valor lógico verdadeiro.

..11

Tipos de dados caracter e inteiro idênticos. Tipo lógico implementado através de inteiros. Tipo real dividido em dois tipos: float e double.

Pascal C++

PROGRAM exemplo (input, output); VAR N : integer; { função factorial: } FUNCTION fact(i : integer) : integer; BEGIN if i<=1 then fact:=1 else fact:=n*fact(i-1) END; { corpo do programa principal } BEGIN Write('Escreva um número'); Read(n) Write('Factorial de n = ', fact(n)) END.

#include <iostream.h> // função factorial: int fact(int i) { if (i <= 1) return 1; else return i*fact(i-1); } // corpo da função principal main() { int n; cout << "Escreva um número "; cin >> n; cout << "Factorial de n = " << fact(n); }

Page 7: Transição do Pascal para C++

77

Na tabela 2 apresenta-se uma correspondência entre os tipos de dados elementares de ambas as linguagens:

Pascal Pascal C++C++ Char char

Integer int

Real float/double

Boolean int

TABELA 1 Correspondência entre tipos de dados elementares

Variáveis Definição As variáveis em C++ não possuem uma zona própria de definição como em Pascal podendo ser criadas em qualquer sítio do código. Como princípio devem-se definir as variáveis o mais perto possível do local em que são utilizadas.

A definição das variáveis faz-se colocando primeiro o tipo da variável e a seguir o seu nome, terminando-se com o caracter ponto-e-vírgula:

<variável> à <tipo> <nome>;

Tal como em Pascal é possível definir simultaneamente mais que uma variável do mesmo tipo desde que se separem os seus nomes por vírgulas.

Inicialização Em C++ é possível ainda inicializar uma variável na altura da sua definição. Isto é feito colocando após o nome de cada variável o sinal de igual seguido do seu valor inicial (Ex.: int valor = 10; ).

Variáveis globais As variáveis que pertencem ao programa principal em Pascal consideram-se globais e podem ser reconhecidas em qualquer parte do programa. Uma vez que em C++ as funções estão ao mesmo nível, as variáveis da função principal (main) são locais a esta não podendo ser referidas a partir de outras funções. Para que uma variável seja global em C++ esta deve ser declarada fora do corpo das funções. Deve-se, contudo, evitar o uso das variáveis globais.

Existência e visibilidade As variáveis locais em C++, tal como em Pascal, só existem e são visíveis dentro do bloco (conjunto de código delimitado por chavetas) em que estão declaradas. De notar ainda que as variáveis em C++ só são reconhecidas dentro dum bloco a partir do ponto em que foram declaradas.

YY11

Variáveis definidas em qualquer sítio do código com possíbilidade de inicialização simultânea

Variáveis globais definidas fora do corpo das funções.

Page 8: Transição do Pascal para C++

88

LISTAGEM 2 Definição de variáveis e constantes

Constantes É possível em Pascal e em C++ utilizar dois tipos de constantes: As constantes definidas pelo utilizador associadas a um identificador e os valores constantes. Na tabela 3 apresentam-se exemplos de alguns valores constantes nas duas linguagens.

PascalPascal C++C++ -3.02 -3.02

0.15E-2 0.15E-2

23 23

$FF40 0xFF40

False 0

’a’ ’a’

’algum texto’ ”algum texto”

TABELA 2 Correspondência entre valores constantes

Para definir constantes através de um identificador em Pascal utiliza-se a zona de definição de constantes referenciada pela palavra CONST. Em C++ as constantes definem-se nos mesmos locais e da mesma forma que as variáveis acrescentando-se antes do tipo a palavra reservada const. Habitualmente as constantes definem-se no inicio do programa.

LISTAGEM 3 Definição de constantes

Constantes definidas como variáveis utilizando o modificador const

Pascal C++

CONST nome = ’José’; PI = 3.14159; Diasdasemana = 7; Escudo = ’$’;

const char *nome = ”José”; const double PI = 3.14159; const int Diasdasemana = 7; const char Escudo = ’$’;

Pascal C++

PROGRAM conversão (input, output); CONST Polegadas = 2.54; VAR Comprimento : real; {variável global} Resultado : real; {variável global} BEGIN Write('Valor em polegadas: '); Read( comprimento ); Resultado := comprimento*polegadas; Write('Em centímetros = ',resultado); END.

#include <iostream.h> const double polegadas = 2.54; double comprimento; // variável global main() { cout << "Valor em polegadas: "; cin >> comprimento; double resultado; // variável local resultado = comprimento*polegadas; cout << "Em centímetros " << resultado; }

Page 9: Transição do Pascal para C++

99

Operadores e Expressões Operadores aritméticos Os operadores aritméticos aplicados aos valores reais são os mesmos em ambas as linguagens. No que diz respeito à sua aplicação a valores inteiros enquanto em Pascal se usam as palavras reservadas DIV e MOD para as operações de divisão e resto em C++ usam-se os símbolos / e %. As operações realizadas são equivalentes.

Operadores relacionais Apenas as operações de verificação de igualdade e diferença adoptam símbolos diferentes nas duas linguagens, sendo utilizado em C++ o conjunto de símbolos == para a igualdade e o conjunto != para a diferença.

Operadores Lógicos Embora as operações lógicas em ambas as linguagens sejam semelhantes os símbolos adoptados são bastante diferentes. Em C++ usam-se os símbolos && para a operação lógica ‘e’, || para a operação ‘ou’ e ! para a negação. Não existe equivalente em C++ para a operação lógica ‘ou exclusivo’ do Pascal.

Atribuição Atribuir um valor a uma variável é uma operação em C++ que devolve como resultado o valor atribuído. O símbolo adoptado é o sinal de igual =. Em Pascal a atribuição é por seu lado uma instrução única que usa o símbolo :=. É necessário tomar cuidado com o facto de que o símbolo de comparação entre dois valores em Pascal ser o mesmo que o de atribuição em C++ o que pode levar a que este seja usado erradamente numa operação de comparação como por exemplo: if(x=5) em vez de if(x==5) ). Este caso é perfeitamente válido em C++, significa que o valor 5 é atribuído à variável x devolvendo 5 como resultado da operação de atribuição. Uma vez que este valor é diferente de 0 a condição do if é verdadeira e o código do if é sempre executado.

LISTAGEM 4 Comparação versus atribuição

Operadores semelhantes aos do Pascal utilizando por vezes símbolos diferentes

Atribuição é uma operação em C++ que devolve o valor que foi atribuído

Pascal C++

VAR N:Integer; BEGIN { Atribuição de um valor a uma variável } N := 10; { Comparação de dois valores } IF N = 10 THEN Write( ’Os valores são iguais’ ); END.

{ int n; // Atribuição de um valor a uma variável n = 10; // Comparação de dois valores if ( n == 10 ) cout << “Os valores são iguais”; }

Page 10: Transição do Pascal para C++

1010

A tabela seguinte sumariza as equivalência de operadores:

PascalPascal C++C++ + +

- -

* *

/ e DIV /

MOD %

< <

<= <=

> >

>= >=

= ==

<> !=

not !

and &&

or ||

TABELA 3 Correspondência de operadores.

Precedências As regras de precedência entre operadores são diferentes em Pascal e C++. Sempre que surjam dúvidas devem-se utilizar os parênteses. A tabela 4 apresenta um resumo das regras de precedência numa e noutra linguagem.

PascalPascal C++C++ not !

* / div mod and * / %

+ - or + -

< <= > >= <> = < <= > >=

== !=

&&

||

=

TABELA 4 Precedência de operadores.

øø11

Precedências com regras diferentes

Page 11: Transição do Pascal para C++

1111

Funções associadas aos tipos de dados elementares Existe um conjunto de funções pré-definidas no Pascal associadas aos tipos básicos. Na tabela 5 apresentam-se as funções do Pascal que se aplicam aos tipos básicos e produzem resultados do mesmo tipo. Note-se que em C++ é necessário fornecer a declaração das funções antes de serem usadas. Isto é conseguido incluindo o ficheiro de extensão .h onde se encontra a declaração (Ex.: para a função fabs deve-se colocar no ficheiro uma linha com #include <math.h> para fornecer a declaração da função).

PascalPascal C++C++ Tipo base Função Função Declaração em :

Abs abs stdlib.h ou math.h

inteiro Sqr

Abs fabs stdlib.h ou math.h

Sqr

Sqrt sqrt math.h

Sin sin math.h

Cos cos math.h

Arctan atan math.h

Ln log math.h

Real

Exp exp math.h

Pred Caracter

Succ

TABELA 5 Correspondência de funções aplicadas aos tipos básicos.

Expressões Enquanto em Pascal as operações e as expressões podem ser de qualquer um dos tipos elementares mencionados, em C++ as expressões só podem ser do tipo inteiro ou do tipo real (float ou double). Isto significa na prática que todas as expressões lógicas e do tipo caracter são efectuadas a partir do tipo inteiro.

Os caracteres em expressões envolvendo este tipo são convertidos para o seu valor em código ASCII, sendo este o valor usado nas expressões. O valor lógico também é utilizado como um inteiro, sendo 0 para o valor falso e qualquer outro valor (diferente de zero) para o valor lógico verdadeiro.

Conversão entre tipos de dados elementares Existem alguns casos em que é possível misturar diferentes tipos de dados numa expressão. Por exemplo quando se utilizam operadores relacionais, embora o tipo de dados dos operandos tenha de ser idêntico o resultado é

Funções básicas associadas aos tipos de dados elementares com equivalentes em C++

Expressões definidas com base apenas nos tipos reais e inteiro

Page 12: Transição do Pascal para C++

1212

sempre do tipo lógico. Em Pascal é também possível misturar o tipo inteiro com o tipo real numa expressão através da conversão automática do inteiro num real obtendo-se como resultado um valor real. Outra forma de se misturar tipos de dados diferentes é utilizar funções que operam sobre um dado tipo de dados e produzem como resultado um tipo diferente.

Na tabela seguinte apresentam-se as funções que, em Pascal, operam sobre um tipo de dados e produzem um tipo diferente como resultado. Estas funções permitem obter a conversão entre tipos de dados. Em C++ existe correspondência para apenas uma destas funções. Nesta linguagem a conversão normal de tipos é realizada duma forma automática pelo compilador ou utilizando um operador especial o operador de coerção.

PascalPascal C++C++ Função Conversão Função Declaração em :

Trunc Real à Inteiro Floor (*) math.h

Round Real à Inteiro

Ord Caracter à Inteiro

Chr Inteiro à Caracter

Odd Inteiro à Lógico

TABELA 6 Correspondência de funções aplicadas aos tipos básicos. usadas na conversão de tipos.

* Esta função devolve um valor do tipo double que possui parte decimal nula

Operador de coerção (cast) É possível, de uma maneira geral, utilizar tipos diferentes em operações em C++. Se for necessário o compilador converte automaticamente um dos tipos (por exemplo uma operação envolvendo inteiros e reais (float ou double) os inteiros são convertidos em reais antes da operação). Quando a conversão resultar em perca de informação ou for duvidosa o compilador gera uma mensagem de aviso. Para eliminar a mensagem, e de uma certa forma informar o compilador que a conversão é válida e pretendida, o programador deve realizar uma operação de coerção sobre o tipo que pretende converter.

A operação de coerção permite a conversão explicita entre tipos de dados diferentes. Esta operação obtem-se colocando o tipo, para o qual se quer converter um valor ou expressão, seguido entre parênteses do valor ou expressão a converter. (Ex.: 2 + 4 * int(2.3) à produz o resultado inteiro 10). Esta forma de coerção possui uma notação funcional, ou seja como se fosse uma função: o nome da função é dado pelo tipo de dados e o valor entre parênteses é o argumento. Existe, no entanto uma outra notação para a coerção, herdada da linguagem C, que consiste em colocar o tipo para o qual se quer converter entre parênteses antes do valor. (Ex.: 2 + 4 * (int) 2.3 ).

Conversão de tipos utiliza o operador de coerção (cast)

>>11

Page 13: Transição do Pascal para C++

1313

LISTAGEM 5 Conversão de tipos e operação de coerção

Entrada e Saída de Dados A entrada e saída de dados mais comum utiliza respectivamente o teclado e o monitor. Os ficheiros serão abordados mais à frente.

Entrada de Dados As instruções read e readln do Pascal são substituídas, em C++, por uma única instrução: cin, que se comporta como o read.

Enquanto a lista de parâmetros de read é apresentada entre parênteses encontrando-se os parâmetros separados por vírgulas, a instrução cin encontra-se separada dos parâmetros pelo operador de extracção >> utilizando-se o mesmo operador para separar os parâmetros entre si.

Saída de Dados Simples As instruções write e writeln, do Pascal, são substituídas, em C++, por uma única instrução: cout, que é equivalente ao write.

Tal como acontece com a instrução de entrada de dados, cin, também o cout utiliza um operador , neste caso o operador de inserção << para separar os parâmetros do comando e para separar os parâmetros entre si. Podem ainda ser utilizados caracteres especiais como o tab(\t) e o newline(\n).

LISTAGEM 6 Instruções de entrada e saída de dados

Entrada de dados feita através do operador de extracção e da variável cin

Saída de dados feita através do operador de inserção e da variável cout

Pascal C++

program exemplo(input,output); var a : integer; b : real; c : char; begin read(a, b, c); writeln('Valores lidos: ', a, b, c); end.

main() { int a; float b; char c; cin >> a >> b >> c; cout << "Valores lidos: " << a << b << c; }

Pascal C++

VAR Ch:Character; I:Integer; Val:Real; BEGIN Ch := ’a’; I := ord(Ch); Writeln( ’Ascii de: ’, ch, ’ é ’, I ); Writeln( ’Ascii: ’, i, ’ é ’, chr(I) ); Val := 3.124; Write( ’Real: ’, val ); Writeln(’ para inteiro: ’, trunc(val) ); END.

{ char ch; int i; ch = ’a’; i = int( ch ); // i=ch; era suficiente por // conversão automática cout << ”Ascii de: ” << ch << ” é: ” << i; cout << endl; cout << ”Ascii: ” << i << ” é: ” << char(i); cout << endl; val = 3.124; cout << ”Real: ” << val; cout << ” para inteiro: ” << int(val); // ou então int(floor(val)) cout << endl; }

Page 14: Transição do Pascal para C++

1414

Saída de Dados Formatada Em Pascal é possível definir na instrução write o número mínimo de caracteres com que um parâmetro deve aparecer escrito. Isto é conseguido colocando a seguir ao parâmetro um sinal de dois pontos seguido de um valor inteiro com o número de caracteres de escrita. Para o caso de números reais é ainda possível definir o número de casas decimais juntando mais um sinal de dois pontos e o total de casa decimais (Ex.: escrita de um real com 6 caracteres e duas casas decimais à Write( valor:6:2 );). Em C++ o mesmo efeito é conseguido através de manipuladores que se incluem antes dos parâmetros a serem escritos.

O manipulador setw permite definir em C++ o número mínimo de caracteres de escrita e o manipulador setprecision o número de casas decimais. Estes manipuladores possuem uma sintaxe semelhante às funções levando um argumento com o valor numérico (ver exemplo na listagem 7). Existe ainda o manipulador endl que se utiliza para mudar de linha.

LISTAGEM 7 Saída de dados formatada

NOTA

Quando se utilizam manipuladores em C++ deve-se incluir o ficheiro iomanip.h no início do programa, ou seja acrescentar a linha: #include <iomanip.h>.

Estruturas de Controlo - Selecção Em Pascal existem duas instruções de selecção: if e case. As instruções correspondentes em C++ são: if e switch.

Instrução If A instrução if do C++ requer que a condição lógica esteja entre parênteses, isto deve-se ao facto de não ser utilizada a palavra then que funciona como marcador do fim da condição em Pascal.

Formatação da saída de dados utiliza manipuladores

Instrução if com condição lógica entre parênteses e sem then

Pascal C++

VAR N:Integer; R: Real; BEGIN N := -10; R := 23.126 Write( ‘Valor inteiro – ‘, N:5 ); Writeln; Writeln ( ‘Valor real – ‘, R:8:2 ); Writeln(‘FIM’:5, ‘------‘) END. { OUTPUT: } { Valor inteiro - -10 } { Valor real - 23.12 } { Fim------ }

{ int n; double r; n = -10; r = 23.126; cout << “Valor inteiro - “ << setw(5) << n; cout << endl; cout << “Valor real – “ << setw(8) << setprecision(2) << r << endl; cout << setw(5) << “Fim” << “------“ << endl; } // OUTPUT: // Valor inteiro - -10 // Valor real - 23.12 // Fim------

Page 15: Transição do Pascal para C++

1515

A sintaxe é a seguinte:

<instrução if> à if ( <condição> ) <instrução1>;

[ else <instrução2>; ]

LISTAGEM 8 Instrução if

Instrução Switch A instrução case do Pascal possui como equivalente em C++ a instrução switch. O argumento desta instrução em C++ deve ser fornecido entre parênteses, e deve ser de um tipo inteiro ou compatível (tipos caracter ou enumerativo). Também as diferentes possibilidades de selecção são precedidas em C++ pela palavra reservada case podendo apenas existir um valor de cada hipótese. Ainda outra diferença é que se for necessário fornecer mais que uma instrução em C++ não é necessário colocar as chavetas para as agrupar. A sintaxe é então a seguinte:

<Inst. switch> à switch (<expressão>)

{ case <const> : <instrução>; }

LISTAGEM 9 Instrução switch

Instrução switch substitui case do Pascal

Pascal C++

if x=y then a:=1 else a:=2;

if (x==y) a=1; else a=2;

Pascal C++

case mes of 1,3,5,7,8,10,12: ultimodia := 31; 4,6,9,11: ultimodia := 30; 2: if ano mod 4 = 0 then ultimodia := 29 else ultimodia := 28; otherwise: ultimodia := 0 end;

switch( mes ) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: ultimodia = 31; break; case 4: case 6: case 9: case 11: ultimodia = 30; break; case 2: if ( ano%4 == 0 ) ultimodia = 29; else ultimodia = 28; break; default: ultimodia = 0; break; }

Page 16: Transição do Pascal para C++

1616

NOTA

Para a correspondência directa entre a instrução case do Pascal e a instrução switch do C++ deve-se acrescentar uma instrução break no final de cada case do C++.

Estruturas de Controlo - Repetição As três instruções de repetição do Pascal são: for, while e repeat. Em C++ as instruções correspondentes são: for, while e do.

Instrução for A instrução for do C++ é muito mais poderosa e versátil que a do Pascal.. Esta instrução possui entre parênteses uma lista de outras três instruções fornecidas pelo programador. A primeira destas instruções é corrida apenas uma vez quando se entra no for e é utilizada normalmente para iniciar uma variável de controlo. A segunda instrução fornece um valor lógico e é corrida sempre que se inicia a passagem no ciclo, se o valor lógico for falso o ciclo já não é executado passando-se à instrução seguinte. A terceira e última instrução é corrida sempre que se termina uma passagem pelo ciclo e utiliza-se normalmente para alterar o valor da variável de controlo. A sintaxe da instrução for é a seguinte:

<Inst. for> à for(<instr1>;<instr2>;<instr3>)

<instrução>;

LISTAGEM 10 Instrução for

Instrução while A instrução while é idêntica em C++ e Pascal, necessitando apenas em C++ que a condição esteja entre parênteses não sendo então utilizada a palavra do. A sintaxe é então a seguinte:

<Inst. while> à while (<condição>) <instrução>;

Instrução for com formato e funcionalidade diferentes em C++

Instrução while com a condição entre parênteses e sem do

Pascal C++

for i:=0 to 10 do begin j:=2*i+1; writeln('impar: ´, j) end;

for (i=0; i<=10; i=i+1) { j=2*i+1 cout << "impar: " << j << endl; }

Page 17: Transição do Pascal para C++

1717

LISTAGEM 11 Instrução while

Instrução do-while A instrução correspondente ao repeat-until do Pascal é a instrução do-while do C++. Esta instrução funciona de uma forma ligeiramente diferente, enquanto em Pascal o ciclo termina quando uma determinada condição é verdadeira em C++ o ciclo termina quando a condição é falsa, continuando enquanto essa condição for verdadeira. A condição aparece em C++ entre parênteses. A sintaxe desta instrução é:

<Inst.do> à do {<instrução>;} while (<expressão>);

LISTAGEM 12 Instrução do-while

Subprogramas Funções e Procedimentos Conforme foi referido na secção inicial, o Pascal difere do C++ num aspecto fundamental: enquanto o Pascal dispõe de dois tipos de subprogramas (funções e procedimentos) o C++ apenas tem um tipo: as funções. Para emular os procedimentos, em C++, pode recorrer-se a funções que retornam o tipo void, uma vez que este tipo significa vazio é o mesmo que retornar vazio ou seja não retornar nada.

Transmissão de Parâmetros Tanto em Pascal como em C++ é possível passar parâmetros por valor e por referência.

Instrução do-while sustitui repeat-until do Pascal

Pascal C++

repeat write(Em que numero pensei?'); read(n); if n = numero then writeln('Acertou!!') else if n < numero then writeln('Baixo...') else writeln('Alto...') until n=numero;

do { cout << "Em que numero pense?"; cin >> n; if (n==numero) cout << "Acertou!!" << endl; else if (n < numero) cout << "Baixo..." << endl; else cout << "Alto..." << endl; } while (n!=numero);

Pascal C++

Fact := 1; N := 5; Termo := N; While termo > 1 do Begin Fact := fact * termo; Termo := termo – 1; End Writeln(‘Factorial de ‘, N, ‘ = ‘, fact);

fact = 1; n = 5; termo = n; while (termo > 1) { fact = fact * termo; termo = termo – 1; } cout << “Factorial de “ << n << “ = “ << fact << endl;

Page 18: Transição do Pascal para C++

1818

Para o Pascal a diferenciação do método de transmissão de cada parâmetro é efectuada na definição da função (indicação ou não da palavra reservada var) e não na sua invocação. Em C++ passa-se o mesmo utilizando-se na lista de parâmetros da função o operador & antes do nome de cada variável a passar por referência.

De notar ainda que em C++ é obrigatório indicar nos parâmetros de uma função o tipo antes de todas as variáveis, não se podendo referir um tipo para um grupo de variáveis separadas por vírgula.

LISTAGEM 13 Passagem de parâmetros para funções.

Retorno de Valores (funções) O tipo do valor que é retornado por uma função em C++ aparece como primeiro elemento antes do nome da função, ao contrário do Pascal em que este aparece a seguir ao símbolo : após a lista de parâmetros da função.

O retorno de um valor, em Pascal, efectua-se por atribuição do mesmo a uma pseudo variável com o mesmo nome que a função. Em C++ a devolução de um valor efectua-se através da instrução return <expressão>, a qual também termina imediatamente a execução da função devolvendo o resultado de <expressão>.

LISTAGEM 14 Retorno de funções

Parâmetros com passagem por referência são obtidos colocando & antes do nome da variável

Retorno de funções feita a partir da instrução return que termina também a função

Pascal C++

PROGRAAM transmiteRef (input, output); VAR a, b : real; PROCEDURE troca (var x, y : real); VAR aux : real; BEGIN Aux := x; x := y y := aux END; BEGIN Write(‘Escreva dois reais:’); Readln(a, b); Writeln(a, b, ‘-- Após troca: ‘); Troca(a, b); Write(a, b) END.

#include <iostream.h> void troca(double &x, double &y) { double aux; aux = x; x = y; y = aux; } main() { double a, b; cout << "Escreva dois reais: "; cin >> a >> b; cout << a << b << " -- Após troca:\n"; troca(a, b); cout << a << b; }

Pascal C++

function fact (i : integer) : integer; begin if i<=1 then fact:=1 else fact:=i*fact(i-1) end;

int fact (int i) { if (i<=1) return 1; else return i*fact(i-1); }

Page 19: Transição do Pascal para C++

1919

Protótipos de Funções Um protótipo de uma função é uma declaração que, para além do nome da função, especifica os tipos de dados dos parâmetros e do resultado devolvido. É terminado pelo ponto-e-vírgula. O compilador de C++ utiliza o protótipo para verificar a validade sintáctica das invocações da função. Esta declaração é análoga à declaração forward, do Pascal.

O protótipo das função deve aparecer antes da chamada da função. Normalmente, é boa prática colocar os protótipos das funções num ficheiro separado com o mesmo nome do ficheiro fonte mas com a extensão .h, o qual é inserido no início do ficheiro fonte utilizando a directiva #include.

Por exemplo, se se definirem 10 funções, para além da função main, no ficheiro prog.c, deve construir-se um ficheiro designado prog.h, cujo conteúdo deverá ser uma lista dos 10 cabeçalhos (headers) das funções definidas em prog.c, terminados por ponto-e-vírgula (;).

Tipos de Dados Avançados O Pascal é uma linguagem com uma tipificação muito rica possuindo uma grande quantidade de tipos de dados. Embora o C++ apresente grande parte dos tipos do Pascal alguns deles não têm correspondência em C++ como é o caso dos tipos sub-domínio e conjunto (set).

Tipo enumerativo O tipo enumerativo encontra-se entre os tipos que existem igualmente em C++, possuindo no entanto uma sintaxe diferente nesta linguagem:

<tipo enum> à enum <nome> {<ident1>, <ident2>, …};

Matrizes As matrizes (arrays) permitem armazenar sequências de elementos, todos do mesmo tipo, identificados por um ou mais números de ordem (índices). Uma importante diferença na definição e utilização de matrizes é que em C++ o índice é sempre um inteiro cujo valor inicial é obrigatoriamente zero.

Quando se declara uma matriz em C++ fornece-se o número total de elementos existentes, digamos n. De notar que este número nunca aparece como índice da matriz uma vez que começando no valor 0 os seus índices variam entre 0 e n-1, sendo n o total de elementos da matriz.

Uma característica muito importante do C++ é que a escrita e leitura de matrizes não é testada pela linguagem, pelo que é possível escrever ou ler de um índice que não exista. Quando isto acontece na operação de escrita pode ser desastroso uma vez que se estará a escrever na memória numa zona onde poderá estar o código ou dados do programa corrompendo-os.

Nas listagens 15 e 16 apresentam-se exemplos com matrizes unidimensionais e bidimensionais.

,,11

Matrizes apenas com índices inteiros que começam obrigatoriamente no valor zero

Page 20: Transição do Pascal para C++

2020

LISTAGEM 15 Média de uma matriz de valores reais

LISTAGEM 16 Utilização de matrizes bidimensionais

Cadeias de caracteres Tal como acontece em Pascal as matrizes de caracteres ou cadeias de caracteres (strings) possuem um tratamento especial. Este tipo de matrizes unidimensionais serve para guardar um pedaço de texto.

Em C++ pode-se armazenar numa matriz de caracteres um pedaço de texto de qualquer dimensão que não exceda o tamanho da matriz. Para que seja possível determinar o fim do texto por convenção acrescenta-se um caracter especial - o caracter ’\0’ (com o código ASCII 0), no fim do texto. Todas as funções que trabalham com cadeias de caracteres em C++ adoptam esta convenção. Assim sendo, uma matriz de caracteres deverá ter espaço para o texto incluindo o caracter de terminação.

As funções de leitura e escrita de dados tratam as cadeias de caracteres como se fossem compostas por um único valor de um tipo especial. Assim é possível escrever ou ler uma cadeia de caracteres fornecendo apenas o seu identificador.

Outro aspecto importante das cadeias de caracteres em C++ é que sobre elas não existem operações definidas. Assim todas as operações com cadeias de caracteres passam pelo uso de funções. Na tabela seguinte fornece-se uma pequena lista de funções que permitem efectuar as operações existentes em Pascal sobre cadeias de caracteres do C++.

Strings definidas como matrizes de caracteres e terminadas com o caracter ASCII de valor zero

Pascal C++

program exemplo(input,output); var mat:array[0..9, 0..4] of real; x : real; begin mat[2, 3]:=2.4325; x:= mat[2, 3]*3.14; mat[4, 0]:=x*mat[2, 3]; write("Elem.4,0 = ", mat[4, 0]) end. ;

main() { double mat[10][5]; double x; mat[2][3] =2.4325; x= mat[2][3]*3.14; mat[4][0] =x*mat[2][3]; cout << "Elem.4,0 = " << mat[4][0]; }

Pascal C++

program media10valores(input,output); var mat:array[1..10] of real; x : real; I : integer; Begin x := 0.0; writeln(‘Introduza 10 valores reais: ‘); for i:=1 to 10 do begin write( I, ’º valor: ’); read( mat[I] ); x := x + mat[I]; end; writeln("Média = ", x / 10.0 ) end.

main() { double mat[10]; double x = 0.0; cout << “Introduza 10 valores reais:\n“); for( i=0; i<9; i=i+1 ) { cout << i+1 << ”º valor: ”; cin >> mat[i]; x = x + mat[i]; } cout << "Média = " << x / 10.0 << endl; }

Pascal C++

program media10valores(input,output); var mat:array[1..10] of real; x : real; I : integer; Begin x := 0.0; writeln(‘Introduza 10 valores reais: ‘); for i:=1 to 10 do begin write( I, ’º valor: ’); read( mat[I] ); x := x + mat[I]; end; writeln("Média = ", x / 10.0 ) end.

main() { double mat[10]; double x = 0.0; cout << "Introduza 10 valores reais:\n"); for( i=0; i<9; i=I+1 ) { cout << i+1 << "º valor: "; cin >> mat[i]; x = x + mat[i]; } cout << "Média = " << x / 10.0 << endl; }

Page 21: Transição do Pascal para C++

2121

C++C++ operação função Declaração em :

Comparação strcmp String.h

Junção strcat String.h

Cópia strcpy String.h

Dimensão strlen String.h

TABELA 7 Operações com cadeias de caracteres em C++.

LISTAGEM 17 Exemplo de operações com cadeias de caracteres

Registos Os registos são estruturas de dados que permitem agrupar elementos de diversos tipos, referenciados através de identificadores. O Equivalente aos registos em Pascal são as estruturas de C++ cuja sintaxe é a seguinte:

<tipo estrutura> à struct <nome> {

<variável1>;

<variável2>;

...

};

LISTAGEM 18 Utilização de registos ou estruturas

Estruturas equivalentes ao tipo registo do Pascal

Pascal C++

program exemplo(input,output); var pt1 : record x : real; y : real end; begin pt1.x:=2.4325; pt1.y:=3.14; pt1.x:=pt1.x*4.5; write("Ponto= ", pt1.x, pt1.y) end.

main() { struct ( float x; float y; ) pt1; pt1.x=2.4325; pt1.y=3.14; pt1.x=pt1.x*4.5; cout << "Ponto= " << pt1.x << pt1.y; }

C++

main() { char string[100]; char *string1 = "Inicio do texto"; char string2[20]; cout << "Dimensão da string1: " << strlen(string1); // Obter o numero de caracteres strcpy( string2, "e fim do texto"); // Copiar para string2 o texto do segundo parâmetro strcpy( string, string1 ); // Copiar para string o texto de string1 strcat( string, string2 ); // Juntar a string o texto de string2 cout << "Texto final: " << string; }

Page 22: Transição do Pascal para C++

2222

Ficheiros Os ficheiros permitem armazenar informação sobre a forma de uma sequência de elementos todos do mesmo tipo. Os dados são guardados de forma permanente, em dispositivos de memória não volátil, como por exemplo os discos rígidos. Ainda que seja possível manipular ficheiros de elementos de qualquer tipo, o tipo de ficheiros mais comum é o de caracteres (texto em formato ASCII). Em C++ não existe o tipo ficheiro, sendo utilizado um conjunto de tipos especiais definidos pelo utilizador que são pré-definidos na linguagem: Em particular os tipos ifstream para leitura de dados e ofstream para escrita de dados.

LISTAGEM 19 Utilização de ficheiros

Nota:

A manipulação de ficheiros não está abrangida pelo Pascal standard, pelo que as instruções acima referidas podem ter ligeiras alterações sintácticas em diferentes sistemas operativos.

Tipos de dados definidos pelo utilizador Também em C++ é possível definir novos tipos de dados com base nos existentes.

Os novos tipos de dados em C++ não possuem uma zona de definição própria como em Pascal, sendo declarados nos mesmos locais que as variáveis. Normalmente os novos tipos são declarados num ficheiro separado conjuntamente com a declaração de funções e variáveis externas. Este ficheiro é depois incluído no programa usando a directiva #include. Alternativamente os novos tipos são declarados no início do programa.

A sintaxe da definição de tipos em C++ é a seguinte:

<Def de tipo> à typedef <tipo existente> <nome>;

Ficheiros implementados pelos tipos ifstream e ofstream

Definição de tipos efectuada em qualquer lugar do código utilizando a palavra chave typedef

Pascal C++

program exemplo(input,output); var fich1, fich2 : file of char; a : integer; b : real; c : char; begin assign(fich1, "out.txt"); assign(fich2, "in.txt"); rewrite(fich1); reset(fich2); read(fich2, a, b, c); write(fich1, a, b, c); close(fich2); close(fich1) end.

main() { ofstream fich1; // para escrita ifstream fich2; // para leitura int a; float b; char c; fich1.open("out.txt"); fich2.open("in.txt"); fich2 >> a >> b >> c; fich1 << a << b << c; fich2.close(); fich1.close(); }

Page 23: Transição do Pascal para C++

2323

PascalPascal C++C++ array[ ] of <tipo> <tipo> [ ]

Record struct

File ofstream ou ifstream

( val1, val2, ...) enum { val1, val2, ...)

p^ *p

TABELA 8 Resumo dos tipos de dados avançados.

Estruturas de Dados Dinâmicas Tanto o Pascal como o C++ proporcionam a possibilidade de definir e utilizar estruturas de dados cuja topologia e número de elementos varia ao longo da execução do programa. Por esse motivo, estas estruturas de dados são designadas como estruturas de dados dinâmicas.

O elemento essencial para a construção de estruturas de dados deste género é um tipo de dados elementar, designado ponteiro (pointer). As variáveis deste tipo contêm valores especiais: endereços de posições de memória. Desta forma, a informação não se encontra no valor da variável mas sim no valor da posição de memória guardada na variável, conforme se ilustra na figura 1.

FIGURA 1: Exemplo de uma referência indirecta por meio de um ponteiro

Dada a variável do tipo pointer, é possível obter o valor por ela indicado de forma indirecta, através do acesso à chamada variável referenciada pelo ponteiro. A identificação da variável referenciada é obtida, em Pascal, acrescentando no fim do nome do ponteiro um acento circunflexo (^), enquanto em C++ é necessário acrescentar um asterisco (*) no início.

É preciso muito cuidado ao trabalhar com este tipo de dados uma vez que através deles é possível escrever em qualquer sitio da memória incluindo sobre o próprio programa ou sobre os seus dados.

Listas Uma lista é uma estrutura de dados dinâmica, semelhante a um vector (array unidimensional) com a diferença de o número dos seus elementos poder aumentar ou diminuir durante a execução do programa, consoante as necessidades.

ÆÆ11

66

1214843

P1 (pointer)

3.14159

*P1 (C++) / P1^ (Pascal) (nº real, na posição de mem. 1214843)

Page 24: Transição do Pascal para C++

2424

Esta possibilidade oferece duas vantagens importantes:

1. Se o número de elementos previsto inicialmente for ultrapassado o programa não terminará abruptamente com uma mensagem de erro.

2. O sobredimensionamento dos arrays é evitado, com a consequente optimização da gestão da memória disponível.

Tem a desvantagem de o processamento de listas ser geralmente mais lento do que o de arrays.

Os procedimentos de manipulação de ponteiros, utilizados em Pascal, têm correspondentes em C++ conforme é indicado na tabela 9.

PascalPascal C++C++ new new

dispose delete

nil NULL

TABELA 9 Entidades utilizadas na manipulação de ponteiros.

Seguidamente apresentam-se um programa em C++ e outro em Pascal que preenchem uma lista de 5 elementos com números inteiros, lidos do teclado, e ecoam os valores lidos no ecrã (admitindo que eram lidos os valores 4, 1, 8, 4 e 7).

A estrutura de dados criada é a que se mostra na figura 2:

FIGURA2: Estrutura de dados criada pelos programas abaixo descritos

Na página seguinte estão escritos dois programas, um em Pascal e o outro em C++, que constroem a estrutura de dados acima referida.

Dados dinâmicos utilizam os operadores new e delete para reservar e libertar espaço na memória

qq11

4 1 8 4 7 NULL (C++) NIL (Pascal)

Page 25: Transição do Pascal para C++

2525

LISTAGEM 20 Implementação de listas ligadas

Pascal C++

program lista (input,output); type lista = ^elem; elem = record num : integer; prox : lista end; var lis, lis1 : lista; j : integer; begin new(lis); lis1:=lis; for j:=1 to 4 do begin readln(lis^.num); new(lis^.prox); lis:=lis^.prox end readln(lis^.num); lis^.prox:=nil; { eco ...} while lis1<>nil do begin writeln(lis1^.num); lis1:=lis1^.prox end end.

#include<iostream.h> #include<stdlib.h> typedef struct elem *lista; struct elem{ int num; lista prox; }; main() { lista lis, lis1; int j; lis = new elem; lis1 = lis; for(j=1;j<=4;j++) { cin >> lis->num; lis->prox = new elem; lis = lis->prox; } cin >> lis->num; lis->prox = NULL; // eco... while (lis1 != NULL) { cout << lis1->num << endl; lis1 = lis1->prox; } }