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

Linguagens de Programao

Caderno de Apoio Cadeira 2000/2001

por Nuno Miguel Cavalheiro Marques


14-12-2000

Universidade Aberta

-ii-

2000-12-14

ndice Geral
ndice Geral _______________________________________________________________________________ iii ndice de Figuras ____________________________________________________________________________ v Introduo_________________________________________________________________________________ vii

1.1 Objectivos da Cadeira ________________________________________________________ vii 1.2 Sobre a Necessidade deste Caderno _____________________________________________ vii
Mdulo de Estudo 1 :Diversidade das Linguagens __________________________________________________ 1

1.1 Objectivos ___________________________________________________________________ 1 1.2 Programas e Linguagens _______________________________________________________ 1


1.2.1 1.2.2 1.3.1 1.3.2 1.3.3 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 Principais conceitos _______________________________________________________________ 1 Tipologia das linguagens ___________________________________________________________ 3 Programao Imperativa ___________________________________________________________ 4 Programao Orientada por Objectos _________________________________________________ 4 Programao Funcional ____________________________________________________________ 5 FORTRAN______________________________________________________________________ COBOL ________________________________________________________________________ Outras linguagens dos anos 60: O exemplo do APL ______________________________________ Linguagens da Famlia do PASCAL __________________________________________________ C _____________________________________________________________________________ Linguagens Orientadas por Objectos __________________________________________________ 5 6 7 7 9 9

1.3 Principais Paradigmas _________________________________________________________ 4

1.4 Evoluo e Comparao das Linguagens de Programao ___________________________ 5

1.5 Exerccios __________________________________________________________________ 10


Mdulo de Estudo 2 : Introduo ao C++ ________________________________________________________ 11

2.1 Material de Estudo: __________________________________________________________ 11 2.2 Objectivos: _________________________________________________________________ 11 2.3 Exerccios __________________________________________________________________ 11
Mdulo de Estudo 3 : Elementos duma Linguagem de Programao __________________________________ 13

3.1 Objectivos __________________________________________________________________ 13 3.2 Tipos e Variveis ____________________________________________________________ 13


3.2.1 3.2.2 3.2.3 3.2.4 3.3.1 3.3.2 3.3.3 3.3.4 3.4.1 3.4.2 3.4.3 Nomes ________________________________________________________________________ Declaraes e Associaes ________________________________________________________ Ciclo de Vida de uma Varivel _____________________________________________________ Variveis Locais Estticas _________________________________________________________ R-Value e L-Value_______________________________________________________________ Reserva Dinmica de Memria _____________________________________________________ Dangling Pointers (apontadores pendentes)____________________________________________ Garbage Colection _______________________________________________________________ 13 13 16 17 17 17 18 19

3.3 O Tipo de Dados Apontador ___________________________________________________ 17

3.4 Expresses e Instrues _______________________________________________________ 19


Tratamento de Excepes _________________________________________________________ 20 Tratamento das excepes em JAVA ________________________________________________ 20 A Instruo goto ________________________________________________________________ 22

3.5 Sub-programas: Passagem de Parmetros _______________________________________ 23


Universidade Aberta -iii2000-12-14

3.5.1 3.5.2 3.5.3 3.5.4 3.6.1 3.6.2 3.6.3 3.6.4

Passagem por Valor ______________________________________________________________ Passagem por Referncia__________________________________________________________ Passagem por Valor-resultado ______________________________________________________ Passagem por Nome: Expanso de Macros em C _______________________________________ Reserva Esttica_________________________________________________________________ Reserva Dinmica de Blocos _______________________________________________________ Gesto de Memria nas Linguagens da Famlia do C ____________________________________ O Stack-frame dum Programa C ____________________________________________________

23 24 25 25 26 27 27 28

3.6 Gesto de Memria __________________________________________________________ 26

3.7 Exerccios __________________________________________________________________ 29


Mdulo de Estudo 4 : Declaraes, Definies e Classes em C++ _____________________________________ 31

4.1 Objectivos __________________________________________________________________ 31 4.2 Material de Estudo___________________________________________________________ 31 4.3 Exerccios __________________________________________________________________ 31


Mdulo de Estudo 5 : Introduo Programao em Lgica ________________________________________ 33

5.1 Objectivos __________________________________________________________________ 33 5.2 Material de Estudo___________________________________________________________ 33 5.3 Exerccios __________________________________________________________________ 33


Referncias ________________________________________________________________________________ 35

Universidade Aberta

-iv-

2000-12-14

ndice de Figuras
Figura 1 A Mquina de Von Neumann ____________________________________________________________ 2 Figura 2 : Quando a funo foo termina, a rea de memria que lhe estava reservada libertada e ptr_a fica com um dangling pointer. ____________________________________________ 19 Figura 3 : Gesto da memria num programa C/C++. ______________________________________________ 28 Figura 4 : Gesto do stack-frame numa chamada de procedimento em C/C++. ___________________________ 29

Universidade Aberta

-v-

2000-12-14

Universidade Aberta

-vi-

2000-12-14

Introduo
1.1 Objectivos da Cadeira Mais do que o estudo de uma nica linguagem de programao, a cadeira de Linguagens de Programao da Universidade Aberta vai-se centrar sobre o estudo comparado dos diversos paradigmas e caractersticas das linguagens de programao. Assim os alunos vo conhecer os diversos conceitos e tcnicas de programao associados aos principais tipos de linguagens de programao (nomeadamente linguagens imperativas, linguagens funcionais, linguagens orientadas por objectos e linguagens lgicas). Na exposio da matria apresentada, assume-se conhecimento de uma linguagem imperativa, nomeadamente o Pascal (estudada na cadeira de Programao da Universidade Aberta). O conhecimento duma linguagem funcional moderna, como por exemplo o Haskell (estudada na cadeira de Fundamentos da Computao na Universidade Aberta) tambm fortemente aconselhado. Como neste momento j deve ser claro para um estudante de informtica, a componente prtica indispensvel no estudo de qualquer linguagem de Programao. Mais do que uma viso superficial e meramente terica dos vrios paradigmas da programao pretende-se uma viso essencialmente prtica. Esta viso s possvel se em vez de se estudarem superficialmente as principais linguagens, nos centrarmos num pequeno conjunto de linguagens modernas, que incorporem todos os paradigmas em estudo. Tal ser conseguido atravs da aplicao dos conceitos tericos a duas linguagens em concreto o C++ e o Prolog. O estudo da linguagem Prolog ser apenas utilizado para ilustrar os paradigmas funcional e lgico, deixando-se o estudo detalhado desta linguagem para uma prxima cadeira. Com o C++ (uma linguagem orientada por objectos hbrida com possibilidade de suporte simultneo de mltiplos paradigmas), ser possvel ilustrar como e onde devem ser utilizados os restantes paradigmas e caractersticas em estudo.

1.2 Sobre a Necessidade deste Caderno O estudo da cadeira dever basear-se em 6 meios de estudo principais: 1. Utiliza-se este caderno para guiar o aluno pelo estudo dos dois livros adoptados, complementando-os quando necessrio. Este caderno constitudo por diversos mdulos de estudo. Em cada mdulo de estudo feita uma pequena introduo aos contedos desse mdulo, sendo referidos os objectivos didcticos do mdulo e os captulos e pginas dos livros adoptados que cobrem essa matria. Quando necessrio ser introduzida a descrio de tpicos em estudo, no cobertos pelos dois livros adoptados. Nesses casos este caderno de apoio ser a principal fonte de estudo. Finalmente complementa-se cada seco com um pequeno conjunto de exerccios de autoavaliao para o aluno. O livro: Problemas e Linguagens de Programao por Helder Coelho, LNEC, 1984. Neste livro apresentado um estudo comparativo e uma perspectiva histrica sobre as principais linguagens de programao. So abordados os principais conceitos por detrs dos paradigmas imperativo, funcional e lgico. O livro: Programao em C++, conceitos bsicos e algoritmos por Pimenta Rodrigues, Pedro Pereira e Manuela Sousa, FCA- Editora de Informtica. Servir simultaneamente para introduzir o paradigma das linguagens orientadas por objectos e abordar a principal linguagem utilizada na cadeira: o C++. Esta linguagem hbrida, servir os seguintes objectivos: 1. 2. 3. 4. 5. reforar os conceitos adquiridos na cadeira de programao com as linguagens imperativas, atravs duma breve introduo s linguagens da famlia do C; a utilizao de uma linguagem prxima do sistema operativo como o C/C++, permitir igualmente compreender a forma de implementao dos principais paradigmas das linguagens de programao; ilustrar o paradigma dos ADT e introduzir as linguagens orientadas por objectos atravs do estudo de uma linguagem real; permitir aos alunos dominarem os principais conceitos por trs duma das mais populares e poderosas linguagens de programao: o C++; o estudo da linguagem PROLOG permitir compreender as principais caractersticas associadas programao em lgica.

2.

3.

Universidade Aberta

-vii-

2000-12-14

4.

Um conjunto de exerccios de auto-avaliao, bem como outra informao complementar para a cadeira estaro brevemente disponveis, em fase experimental, via Internet na pgina da cadeira. Quando responder aos exerccios na pgina Internet, receber, automaticamente a correco dos seus exerccios bem como uma informao sobre o seu conhecimento actual do mdulo em causa. Um trabalho de desenvolvimento, com entrega facultativa. Parte do exame da cadeira incidir sobre o estudo deste trabalho. O habitual conjunto com 2 testes formativos e respectivos relatrios, a enviar em breve. "Comparative Programming Languages", 2nd Edition. Leslie B. Wilson e Robert G.Clark, Addison-Wesley, 1993. ISBN 0-201-56885-3. Este livro aborda, de uma forma comparada, os principais conceitos por trs das diversas linguagens de programao. "Programming Languages, Concepts and Constructs", Ravi Sethi, 1st Edition, Addisson-Wesley, September 1989. ISBN 0-201-10365-6, que por vezes serviu de guia em algumas das matrias expostas.

5. 6.

Outras referncias aconselhadas, so os livros:

Universidade Aberta

-viii-

2000-12-14

Mdulo de Estudo 1 :

Diversidade das Linguagens

A utilizao de uma linguagem de programao por excelncia a forma de especificar o funcionamento de um computador. Consoante os problemas a serem tratados, as melhores formas de especificao e tratamento podem ser distintas. Se incluirmos linguagens especficas e em estudo, no surpreende pois que existam, actualmente, mais de um milhar de linguagens de programao e dialectos distintos. Mais ainda, por todo o mundo comisses internacionais e grupos de investigao continuam a criar, desenvolver, melhorar ou substituir linguagens de programao diferentes. pois normal a um informtico ter contacto com um nmero elevado de linguagens de programao distintas. Para um estudante que aps um esforo inicial j domina razoavelmente uma ou duas linguagens de programao, este panorama pode parecer desanimador: dada a constante evoluo da informtica, como conseguir rapidamente dominar uma nova linguagem de programao? Qual a melhor linguagem a escolher para realizar uma determinada tarefa? Para quem verificou como linguagens de programao distintas podem ser diferentes (compare-se por exemplo o Pascal ou o Haskell), pode partida parecer uma misso impossvel tentar aprender a trabalhar com qualquer nova linguagem, que pode ainda nem existir. Este no no entanto o caso, pois embora algumas linguagens possam parecer partida muito diferentes, cedo se comeam a encontrar as semelhanas entre as diversas linguagens. Esta caracterizao ser mais fcil quando enquadrada numa perspectiva histrica de evoluo das vrias linguagens. S assim se compreendem as motivaes, funes e objectivos da criao dos vrios paradigmas relativamente s linguagens de programao e dentro destes das especificidades das vrias linguagens. Nesta seco vamos tentar comparar as diversas linguagens de programao entre si, apresentando inicialmente uma caracterizao em termos de tipo, prestando particular ateno aos vrios paradigmas da computao utilizados. Para auxiliar a compreenso da razo de ser de certas caractersticas e do porqu de certas semelhanas ser ainda necessrio efectuar o estudo da evoluo das principais linguagens de programao.

1.1

Objectivos

Os objectivos deste mdulo so: 1. 2. 3. 4. 5. Compreender os principais conceitos por trs de uma linguagem de programao. Desenvolver a capacidade para distinguir as principais formas de classificao de linguagens. Introduzir os principais paradigmas da programao, associado-os s principais linguagens. Saber associar os diversos paradigmas de programao com as linguagens que lhe deram origem. Identificar os principais erros de estruturao e associar a sua soluo com o aparecimento de uma dada linguagem. 6. Dada uma tarefa e um conjunto de linguagens de programao, saber quais as linguagens mais apropriadas para resolver esse problema.

1.2

Programas e Linguagens

Segue-se um resumo dos temas abordados no captulo 1 do segundo livro adoptado (pginas 1 a 24 de [RodriguesPereiraSousa98]) e da seco "Programas e Linguagens" (seco 3) do 1 livro adoptado (pginas 17 a 26 de [Coelho84]). Com este resumo pretende-se auxiliar o aluno no estudo dos livros adoptados, realando os pontos principais e adicionando alguma informao, onde relevante. A leitura deste resumo no dispensa de forma alguma a leitura das referidas seces. 1.2.1 Principais conceitos

Os seguintes conceitos so muitas vezes utilizados nos livros adoptados e a sua compreenso essencial na compreenso da forma de funcionamento de um computador e na compreenso do que e de como funciona uma
Universidade Aberta -12000-12-14

linguagem de programao. Mquina de von Neumann: Abstraco do computador moderno. utilizada para ilustrar o funcionamento de um computador. constituda por uma memria capaz de guardar bytes de informao devidamente endereados; uma unidade de controle que executa instrues de controle do estado da mquina (incluindo qual o endereo da prxima instruo a ser lida da memria); uma unidade aritmtica que executa operaes sobre os dados em memria e uma unidade de entrada/sada, que interage com o exterior.

Figura 1 A Mquina de Von Neumann A programao da unidade de controlo da mquina de Von Neumann pode apenas ser efectuada com um conjunto muito limitado e simples de instrues. Uma hiptese de um conjunto de instrues base para a mquina de von Neumann poderia ser: Soma e subtraco de um endereo de memria na posio i, com o acumulador: A := A+M[i]; A:=A-M[i]; Soma e subtraco do valor endereo dado pelo endereo de memria na posio i, com o acumulador: A := A+ [M[i]]; A:=A-[M[i]]; Multiplicao e diviso do acumulador por 2: A := A*2; A:= A div 2; Mover o contedo do acumulador de e para memria: A :=M[i]; M[i] :=A; Executar as instrues situadas a partir do endereo i de memria: Goto i (PC := i) Se o valor do acumulador for maior ou igual a zero, executar as instruo situadas a partir do endereo de memria i: if( A>=0 ) goto i

Todos os programas executados num computador tm de ser codificados num conjunto de instrues similares a estas. Os programas assim codificados dizem-se em linguagem mquina ou cdigo mquina. Compilador: Um compilador um programa, capaz de ler um ficheiro (normalmente de texto) contendo um programa escrito numa dada linguagem de programao e gerar um programa em linguagem mquina que seja equivalente ao programa inicial. Para tal, o compilador deve analisar o programa lido quer sintacticamente (i.e. verificar se a sua escrita est de acordo com uma gramtica bem definida) quer semanticamente. A seco 2.3 do livro [RodriguesPereiraSousa98] (pginas 31 a 36) refere um compilador para a linguagem C++. Interpretador: Tal como o compilador, um interpretador analisa sintctica e semanticamente uma dada linguagem de programao. No entanto, em vez de converter o programa que lhe dado em linguagem mquina, o interpretador executa o programa que lhe dado, passo a passo. Assim o interpretador que controla o comportamento do programa, facilitando a interaco com o utilizador e a reescrita do programa (visto que o
Universidade Aberta -22000-12-14

programa no tem de ser recompilado sempre que o desejamos executar). Linguagens de programao: Linguagens formais utilizadas na descrio de mecanismos abstractos. Tm como objectivo descrever e comunicar um processo computacional. Podem ser utilizadas para estudar os algoritmos e para os definir de modo no ambguo.

1.2.2

Tipologia das linguagens

H diferentes formas para representar e relacionar as linguagens de programao entre si. a) Por nveis: disposio hierrquica, segundo o seu nvel e mbito. O nvel denota um ndice da facilidade do programador enunciar a soluo dos seus problemas. Linguagens de baixo nvel: O cdigo mquina e a sua representao em Assembler. Linguagens de alto nvel: algortmicas, imperativas, prescritivas, procedimentais (apoiadas sobre processos), determinsticas e quantitativas. Papel determinante do clculo numrico. Exs: FORTRAN, PASCAL e SIMULA. Linguagens de muito alto nvel: Idealmente, no algortmicas1, declarativas, no determinsticas e qualitativas. Vocacionadas para o processamento simblico (como clculo formal, manipulao de frmulas algbricas, processamento de lngua natural), conduzindo a programas mais abstractos. O programador descreve o problema em funo de relaes sobre objectos. Com uma descrio precisa o computador resolver o problema sem qualquer outra interveno. Exs: SQL, PROLOG, Haskell. Devido ao facto de ser ainda hoje uma das principais linguagens funcionais alguns autores incluem igualmente o LISP nesta famlia; isto apesar desta linguagem ser fortemente algortmica e j ter sido inclusivamente utilizada na construo de um sistema operativo.

b) Por rvores genealgicas Desenha-se a rede das linguagens de programao destacando as suas ligaes implcitas e explcitas. As principais rvores dividem-se pelos paradigmas da programao: imperativo, orientado por objectos, funcional e lgico. c) Geraes As linguagens agrupam-se de acordo com um processo de mutaes e seleces tecnolgicas. Este processo descontinuo. usual a seguinte classificao em 5 geraes: 1 Gerao: Linguagem binria, linguagens mquina e Assembly. 2 Gerao: Utilizando compiladores (i.e. baseadas em sistemas que lem o programa numa destas linguagens e o "traduzem", ou compilam, para linguagem binria): COBOL, BASIC, RPG, FORTRAN IV/V, ALGOL 58/60/68/W. 3 Gerao: Linguagens procedimentais: PL/1, PASCAL, FORTRAN 8X, APL, C, SIMULA, BLISS. 4 Gerao: Geradores de programas (i.e. produzem programas noutras linguagens). A linguagem ADA. Linguagens de interrogao (p.ex. para bases de dados):SQL, QBE. 5 Gerao: Linguagens de especficao de problemas: LISP, PROLOG.

d)

Outras Formas de Classificao

Eis outras formas de classificao referidas no texto, teis essencialmente para identificar quando e como se deve optar por uma linguagem ou por outra. Classificao por domnios de aplicao: cientficas: ALGOL, BASIC, FORTRAN comerciais: COBOL
1

- De facto muito difcil criar uma linguagem de programao no algortmica. Mesmo nas linguagens desta famlia a programao, muitas vezes, acaba por ser efectuada utilizando um estilo algortmico.
Universidade Aberta -32000-12-14

processamento de listas: LISP gerais (ou fins mltiplos): ALGOL68, PASCAL, SIMULA 67 Inteligncia Artificial: PROLOG Cincias Sociais: SPSS. Planeamento de espaos: PROLOG Programao de Sistemas: C Classificao por modos de processamento: interactiva: o programador pode efectuar alteraes ao programa enquanto este executado: o programa no compilado mas sim interpretado. O BASIC foi pioneiro neste conceito. Exs: BASIC, APL, LISP, PROLOG. Por lotes (ou programas compilados). Exs: FORTRAN, COBOL, ALGOL, PASCAL. Classificao por categorias: Se a linguagem especfica para um dado fim, ou se pelo contrario, pretende ser o mais universal possvel. Definem-se duas categorias principais: 1. Fim geral: PL/1, PASCAL, BASIC, FORTRAN, C. 2. Fim especifico: COBOL, LISP, PROLOG. Classificao por nmero de utilizadores: Sobre o nmero de utilizadores que houve/h de cada linguagem num dado momento, ou pela percentagem do cdigo existente numa dada linguagem. 1.3 Principais Paradigmas

Paradigmas (estilos de programao) diferentes so adequados para objectivos diferentes. 1.3.1 Programao Imperativa Linguagens que permitem descrever a resoluo de um problema atravs de uma srie de tarefas elementares (comandos) que o computador pode compreender e executar. A sequncia de comandos define o processo (ou procedimento) a seguir e permite a mudana de estado de variveis de atribuio. Implementada com base na mquina de von Neumann. As variveis do programa (e o nmero da instruo em execuo) descrevem o estado da computao a qualquer instante. Principais problemas: No so adequadas computao em paralelo (pois esto baseadas em execuo sequencial). Baixa produtividade na programao: Grande esforo do programador no controlo do estado do programa (valores das variveis). So exemplos clssicos o FORTRAN, COBOL, PASCAL e C. No segundo livro adoptado ([RodriguesPereiraSousa98]), na pgina 17, so identificados mais alguns paradigmas, que esto normalmente associados ao paradigma imperativo, nomeadamente o paradigma procedimental (decomposio do problema em procedimentos), o modular e a abstraco de tipos de dados. Na programao modular o programa divide-se em mdulos associados aos vrios dados que necessrio tratar. Para cada um desses mdulos constrem-se procedimentos que acedem aos dados desse mdulo, por forma a impossibilitar o acesso a esses dados pelo resto do programa (i.e. encapsulamento dos dados). A abstraco dos tipos de dados possibilita um passo para alm da simples modularidade: em vez de se terem procedimentos associados aos dados, constrem-se procedimentos associados ao tipo dos dados. Ambos estes paradigmas so fundamentais para a programao orientada por objectos. E sero estudados em profundidade nos prximos mdulos. 1.3.2 Programao Orientada por Objectos O programa organizado em funo de objectos, que contm no s as estruturas de dados (i.e. os registos do PASCAL) mas tambm as funes que sobre eles agem. A comunicao entre objectos feita atravs de mensagens (que activam as funes de um objecto). Mensagens normalizadas permitem que diferentes classes de objectos possam responder aos mesmos tipos de mensagens. Os objectos so normalmente organizados numa rede podendo os objectos mais especializados herdar as propriedades (i.e. funes e campos) dos objectos mais genricos (herana). Este paradigma est particularmente bem adaptado construo de interfaces grficas, conforme ilustrado em
Universidade Aberta -42000-12-14

[RodriguesPereiraSousa98], na pgina 19,20. So exemplos clssicos de linguagens com este paradigma o SMALLTALK e o SIMULA. O C++ e o JAVA so linguagens que utilizam o paradigma da programao orientada por objectos, embora tambm deixem ao programador a possibilidade de ignorar o paradigma da programao orientada por objectos e utilizar apenas o paradigma da programao imperativa. Por esta razo, estas linguagens so por vezes chamadas de linguagens hbridas entre linguagens imperativas e linguagens orientadas por objectos.

1.3.3 Programao Funcional Descrevem o conhecimento de um problema atravs da declarao de funes (instrues funcionais de alto nvel). As funes so aplicadas recursivamente ou por composio e tm como resultado valores. A parte algortmica e procedimental (idealmente) suprimida: modela-se apenas as formulaes matemticas da computabilidade. So exemplos clssicos o LISP ou o APL. A linguagem Haskell tambm uma linguagem funcional.

a)

Programao lgica

O problema descrito em funo de afirmaes (asseres ou factos) e de regras sobre os objectos. Procurou-se possibilitar a total supresso da parte algortmica e procedimental: cabe ao interpretador (ou compilador) encontrar os caminhos ou processos de resoluo do problema. A programao em lgica estende o paradigma funcional. Programas e dados aparecem em conjunto. A programao lgica est normalmente associada linguagem PROLOG.

1.4

Evoluo e Comparao das Linguagens de Programao

Para alm de dar ao aluno uma perspectiva histrica da evoluo das linguagens de programao, h mais trs razes principais para efectuar este estudo: as linguagens actualmente existentes so mais facilmente explicveis se analisarmos a sua evoluo. De igual forma, a anlise dos erros feitos no passado permitir-nos- compreender melhor porque devemos evitar comete-los de novo quando construmos o nosso prprio cdigo. Por ltimo, ao apresentar a forma como estes so implementados em diversas linguagens e as vantagens que a sua incluso apresenta na escrita do cdigo, este estudo permite exercitar a comparao de vrias linguagens e motivar o estudo dos vrios paradigmas da programao, O resumo que se segue complementa a leitura das seces "Linguagens de Programao: Evoluo e Conceitos" (seco 4 e 6), "Comparao de Algumas Linguagens de Programao" (seco 5) e "Escolha da Linguagem mais Apropriada" do 1 livro adoptado (pginas 27 a 60 de [Coelho84]), complementada relativamente ao estudo das linguagens C e C++ com a seco "As Linguagens C e C++" (seco 1.5, pginas 21 e 22 do segundo livro adoptado, [RodriguesPereiraSousa98]).

1.4.1 FORTRAN Em 1954 surge o FORTRAN (iniciais de FORmula TRANslator), criado por John Backus. Foi a primeira linguagem de alto nvel. Antes do FORTRAN a programao tinha de ser feita em ASSEMBLY, uma linguagem de programao simblica, cujo nico fim era tornar legvel para um humano o cdigo de mquina. Assim enquanto a linguagem ASSEMBLY associava uma instruo simblica directamente a uma instruo mquina do processador, o FORTRAN compilava (ou traduzia) 1 expresso ou formula de base matemtica (representada por 1 instruo FORTRAN) para um conjunto de instrues mquina. Na dcada de 60 o FORTRAN, entretanto redesenhado, nomeadamente recebendo influencias do ALGOL, torna-se cada vez mais utilizado, chegando a ser considerado como uma normas para as aplicaes de clculo cientfico. No fim da dcada de 70, inicio da dcada de 80, o FORTRAN 77 apresenta-se como uma linguagem de excelncia para os clculos numricos e cientficos. Existem no entanto duas objeces principais aos programas em FORTRAN:
Universidade Aberta -52000-12-14

1. difcil escrever programas legveis. usual a aplicao de alguns truques difceis de compreender. 2. difcil estruturar os programas de forma lgica. Um dos problemas com as verses do FORTRAN anteriores ao FORTRAN 77 era a necessidade de utilizar a instruo GOTO. Esta instruo provoca um salto da linha de execuo corrente para outra seco do cdigo. Os problemas surgem porque muitas vezes necessrio associar esta instruo instruo IF, criando um salto condicional para outra seco do cdigo. Torna-se pois necessrio construir cursos de aco demasiado complicados para serem lembrados em detalhe. A instruo GOTO, utilizada desta forma, leva pois a programas ilegveis. Outro dos problemas com as primeiras verses dos programas em FORTRAN o facto das variveis serem seriamente limitadas: todas as variveis eram visveis em qualquer parte do programa. Este aspecto exige uma constante ateno do programador aos nomes das variveis e facilita a introduo de erros no cdigo difceis de detectar (devido utilizao, por erro, de uma dada varivel, num dado contexto, levar alterao do valor dessa varivel, noutro contexto um significado totalmente diferente). Finalmente, a ausncia de recursividade no FORTRAN77 levantava por vezes srias dificuldades estruturao do cdigo e representao de certos problemas. Devido a ter sido a primeira linguagem de programao de alto nvel foi desenvolvido um extenso trabalho e conjunto de bibliotecas para clculo numrico em FORTRAN. Apesar da linguagem FORTRAN no ter ficado indiferente aos desenvolvimentos das cincias da computao e da maioria das recentes verses do FORTRAN (nomeadamente o FORTRAN 9x) resolverem os problemas aqui referidos, a herana do passado, que torna o FORTRAN apetecvel, implica igualmente a ilegibilidade do cdigo: a maioria das rotinas FORTRAN foi desenvolvida em verses antigas do FORTRAN, e logo tm os problemas aqui descritos. Mesmo assim, em certos casos, a soluo mais prtica continua a passar por se recorrer utilizao do FORTRAN. 1.4.2 COBOL Encomendada pelo Departamento de Defesa dos EUA em 1959, o COBOL foi considerado como uma norma para o desenvolvimento de aplicaes comerciais, sendo uma das linguagens mais utilizadas de sempre. O COBOL uma linguagem preparada para a manipulao de grandes ficheiros, por programas que permanecem praticamente inalterados. O principal conceito introduzido por esta linguagem foi o da importncia da descrio dos dados independentemente do computador utilizado. Era assim fcil gerar os dados num computador e trat-los noutro. Os programas em COBOL podem pois ser vistos como percursores dos modernos sistemas de base de dados. O COBOL apresenta uma sintaxe muito prxima do ingls, o que facilita a leitura do programa para algum que no domine a linguagem. Sendo desenhada com vista ao tratamento de grandes volumes de dados, as possibilidades de clculo cientfico desta linguagem so muito bsicas. Assim, em aplicaes exigindo um grande nmero de clculos seria prefervel a utilizao de outra linguagem, como por exemplo o FORTRAN. Estas caractersticas ficam claras aps uma breve anlise da linguagem. Relativamente sua sintaxe um programa COBOL apresenta-se dividido em quatro divises: Identificao do nome do programa fonte (a IDENTIFICATION DIVISION). Contendo o nome do programa, o seu autor e data de criao. Caractersticas que facilitam a utilizao do programa num meio empresarial. Ambiente (a ENVIRONMENT DIVISION) especfica o tipo de computador que compilar e o tipo de computador que executar o programa fonte. Uma seco para a descrio dos dados (a DATA DIVISION), que especfica o formato dos dados a serem utilizados ou preparados pelo sistema. Procedimento do programa (a PROCEDURE DIVISION), que especfica qual o tratamento a dar aos dados.

O COBOL pode ser considerado como o precursor das modernas linguagens de bases de dados, nas quais o SQL tem vindo a ganhar relevncia. De facto, actualmente verifica-se que os primeiros sistemas COBOL tem vindo gradualmente a ser substitudos por sistemas de gesto de bases de dados em SQL. Mas nem todos os problemas so resolvidos utilizando sistemas de bases de dados. Outra das tendncias no software desenvolvido comercialmente passa pela utilizao de pacotes proprietrios adaptados para as principais tarefas da empresa. Actualmente algumas empresas especializam-se no aconselhamento e fornecimento de pacotes de software altamente configurveis, muitas vezes por recurso a uma linguagem de programao prpria.
Universidade Aberta -62000-12-14

No entanto, tal como no caso do FORTRAN, a grande popularidade que esta linguagem teve no passado, nomeadamente na rea comercial, reflecte-se em que ainda hoje exista um elevado nmero de aplicaes desenvolvidas em COBOL: muitas vezes pode ser necessrio o desenvolvimento e alterao de programas COBOL. Mais ainda, as tcnicas e mdulos de programao que se aplicam nos pacotes proprietrios dos dias de hoje, so facilmente aprendidas utilizando a programao em COBOL. LISP O LISP surge em 1959, por proposta de John McCarthy no MIT. Trata-se de uma linguagem essencialmente virada para problemas de inteligncia artificial i.e. tendo como objectivo a manipulao de expresses simblica complexas. Cria uma perspectiva totalmente nova de ver as linguagens de programao, sendo a primeira linguagem funcional. Assim, veio introduzir uma srie de conceitos novos numa linguagem de programao, muitos dos quais s nos anos 70 foram reconhecidos como imprescindveis: Dados e programas so representados de forma uniforme. Utiliza a lista como estrutura de dados unificadora. Forma prefixa dos operadores. Introduz a recurso como estrutura de controle fundamental. Utiliza garbagge collection para gesto da memria, i.e. as estruturas em memria so geridas de forma automtica, sendo as estruturas de dados no necessrias ao programa apenas removidas quando necessrio, de forma dinmica durante a execuo do programa.

Os principais elementos desta linguagem so a lista (constituda por tomos alfanumricos ou numricos, ou outras listas) e a recursividade. O LISP est includo no grupo das linguagens funcionais. O objectivo destas linguagens , idealmente, que o utilizador deixe de ser obrigado a descrever com preciso como o resultado deve ser computado, concentrando-se no que deve ser calculado: o resultado. Tanto em LISP como em PROLOG os dados e o prprio programa so representados da mesma forma, sendo fcil ao programa alterar os seus dados, ou mesmo alterar-se a si prprio. Devido a um grande conjunto de funes tanto o LISP como o PROLOG conseguem realizar rapidamente tratamentos bastante complicados. Nesta cadeira iremos dedicar um pouco mais de ateno ao estudo da linguagem PROLOG devido riqueza das suas tcnicas de programao, essenciais para compreender devidamente quer conceitos comuns programao imperativa como seja o conceito de lista, de operador e de recurso, quer conceitos introduzidos por estas linguagens, como seja o conceito de gramtica formal, anlise sintctica ou de unificao.

1.4.3 Outras linguagens dos anos 60: O exemplo do APL Com a criao da norma BNF, nos anos 60 assistiu-se a uma exploso no nmero de linguagens de programao. Uma das linguagens de programao mais original deste perodo foi o APL. A linguagem APL (A Programming Language), foi criada em 1962 por Kenneth Iverson. O objectivo do APL foi tornar a manipulao das matrizes e vectores to fcil como a de simples nmeros. Esta linguagem veio propor uma nova notao para a computao, incorporando muitos conceitos da matemtica, nomeadamente atravs da utilizao de operadores de muito alto nvel. Esta caracterstica veio permitir a escrita mais compacta dos algoritmos, e possibilitou novas formas de olhar alguns problemas. No entanto, este tambm um dos grandes problemas com o APL. Os programas ao serem escritos de forma muito compacta e de forma extremamente crptica (p.ex. tendo os programas de ser lidos da direita para a esquerda), comprometem a sua legibilidade. 1.4.4 Linguagens da Famlia do PASCAL

a) ALGOL Aps o aparecimento do FORTRAN, surge a necessidade de formalizar os conceitos por trs da sintaxe das linguagens de programao de alto nvel. Para se poder efectuar esta formalizao foi criada a notao BNF (de Backus-Naur Formalism, j estudado na cadeira de Programao da Universidade Aberta, captulo 2 de [Martins97]). Enquanto notao, o BNF veio permitir a construo de regras gramaticais com uma notao rigorosa e formal. Esta notao foi utilizada na definio da sintaxe para uma nova linguagem: o ALGOL, e veio possibilitar a realizao dos trabalhos tericos que criaram a cincia da computao.

Universidade Aberta

-7-

2000-12-14

Surgindo a primeira especficao em 1958, o ALGOL 58 foi a linguagem percursora do PASCAL e do ADA. O ALGOL 58, veio clarificar e adicionar novas caractersticas relativamente FORTRAN54. Com o ALGOL58, realaram-se os seguintes aspectos de uma linguagem de programao: Era um linguagem algortmica i.e. capaz de descrever com facilidade um algoritmo. Era (tal como o FORTRAN) uma linguagem imperativa. Criou a noo de bloco (BEGIN ... END, tal como no PASCAL) e procedimento. Criou o conceito de validao de tipos. Criou a noo de escopo lexical i.e. um dado nome (p.ex. uma varivel ou procedimento, no caso do PASCAL) s visvel em determinados blocos. Introduziu as instrues de controlo de ciclos WHILE e DO. Fez-se acompanhar por um compilador. Apesar destes aspectos, o ALGOL58, ainda no estava prximo das linguagens mais recentes: No era possvel a criao de novos tipos de dados. Necessitava de um mecanismo abstracto para os dados. Outro dos principais problemas com a linguagem ALGOL era o esforo de programao que esta linguagem impunha para a entrada e sada de dados no numricos. Foi no entanto a noo de compilador que veio a permitir a exploso de linguagens que se deu de seguida, durante a dcada de 60. Em 1966 Niklaus Wirth apresentou o ALGOL-W, que veio de seguida a dar origem ao PASCAL.

b) Pascal Em 1968 Niklaus Wirth, projectou o PASCAL. Esta linguagem pretendeu incorporar os melhores aspectos e facilidades das linguagens ALGOL 60 e ALGOL W. Tendo como objectivo o ensino da programao, oferece novas facilidades para estruturar dados (os tipos de dados definidos pelo utilizador) e a decomposio modular de proporcionou um novo grau de abstraco, os quais foram mais tarde desenvolvidos pelo prprio Wirth na linguagem MODULA-2, que surge na linha do PASCAL. Nas principais caractersticas do PASCAL incluem-se: A necessidade de declarao de todas as variveis no inicio do programa/sub-programa. O suporte de variveis com qualquer comprimento e tipo, definido na declarao da varivel. A elevada autonomia dos procedimentos, que podem ser escritos e testados independentemente do cdigo do programa principal.

Um dos principais problemas do PASCAL em aplicaes de clculo cientfico no entanto o reduzido nmero de funes matemticas que suporta, relativamente, por exemplo, ao FORTRAN. c) ADA

Surge no fim da dcada de 70, tendo sido escolhida pelo Departamento de Defesa dos EUA para a substituio da infinidade de linguagens que este departamento utilizava, nomeadamente do FORTRAN, COBOL e PASCAL. Assim o ADA foi desde cedo virado para problemas de grandes dimenses, complexos e exigindo a manipulao de processos concorrentes. Devido a uma grande exigncia a nvel do rigor sintctico dos seus programas, estes apresentam um baixo nmero de erros e uma elevada fiabilidade. Devido maior maturidade da Engenharia de Software na altura da sua especificao, o ADA recebeu os principais paradigmas da programao. Assim o ADA considerado por alguns autores como a primeira linguagem universal, pois incorpora: O conceito de dados abstractos. Em ADA, os programas s podem ter acesso a um conjunto seleccionado de informao de um dado mdulo. A utilizao de estruturas modulares e especificaes de interfaces para os grandes programas. Controle sobre aspectos implementacionais de baixo nvel, na mquina objecto. A manipulao de excepes (surgida na dcada de 60 na linguagem PL/1, um esforo da IBM para substituir o FORTRAN, ALGOL e COBOL).
-82000-12-14

Universidade Aberta

O suporte para concorrncia e processamento paralelo. Onde so necessrios conceitos de como a sincronizao de tarefas e de passagem de mensagens entre tarefas em execuo simultnea em um ou vrios processadores. Nas verses mais recentes (Ada95), os conceitos de herana e objecto.

Outra das caractersticas do ADA uma elevada fiabilidade do cdigo desenvolvido. Esta caracterstica deriva da elevada rigidez sintctica e semntica desta linguagem, que permite diminuir o nmero de erros de funcionamento dos programas. Esta de resto a razo porque esta uma boa linguagem para utilizar em sistemas crticos, como no caso de sistemas de controle militar ou aeroespaciais, onde um nico erro de programa pode trazer graves consequncias. Apesar destas caractersticas, o ADA (ainda?) no ganhou grande aceitao. Talvez tal se deva igualmente rigidez sintctica que exige na escrita dos seus programas: por vezes, devido a uma especificao sintctica demasiado exigente, o ADA obriga a solues menos directas para o desenvolvimento do cdigo. Neste aspecto o ADA distingue-se do C++ que de certa forma se baseia no conceito oposto: o da flexibilizao da linguagem. 1.4.5 C A linguagem C foi construda em 1972 nos Laboratrios Bell por Dennis Ritchie, com o fim de escrever o sistema de operativo UNIX. Trata-se de uma linguagem bastante pequena, apresentando apenas as caractersticas indispensveis. No C todos os aspectos no indispensveis na linguagem so passados para uma extensa biblioteca de funes, que pode ser expandida pelo programador. Tendo sido a linguagem utilizada para construo dos sistemas UNIX, o C uma linguagem com extenso acesso ao hardware, com elevada fiabilidade no tratamento das entradas e sadas do sistema. De igual forma, em sistemas UNIX, como exemplo o LINUX, todas as bibliotecas do prprio sistema operativo tm uma interface em linguagem C, podendo pois ser facilmente evocadas de dentro de um programa C. Contrariamente ao PASCAL ou ao ADA, que visam encoraja o desenvolvimento de programas fiveis atravs da imposio de uma estrutura, o C altamente flexvel (permitindo quase todas as combinaes operando/operador possveis) e produzindo cdigo extremamente eficiente. A linguagem C extremamente prtica, podendo os programas em C ser quer extremamente compactos (e cripticos), como extremamente estruturados e auto explicativos, sem que com isso se perca em eficincia. Desta forma a deciso de tornar o cdigo claro (quando trabalhando em equipa, ou em projectos largos e desenvolvendo cdigo mais complexo), quer a de tornar o cdigo compacto (quando necessria eficincia no desenvolvimento ou no cdigo) cabe ao programador. O C uma linguagem desenvolvida a pensar em programadores responsveis, sendo dever dum bom programador de C tornar o seu cdigo auto explicativo por forma a respeitar os conceitos da programao estruturada. A linguagem C uma das linguagens general-purpose mais escolhida pela generalidade dos programadores. 1.4.6 a) Linguagens Orientadas por Objectos SIMULA 67

O SIMULA67 foi desenvolvido por Dahl e Nygaard, para aplicaes no domnio da simulao. Veio introduzir o conceito de classe. Neste conceito um grupo de declaraes e procedimentos eram agrupados e tratados como uma nica entidade. Durante a execuo do programa, podiam ser criados diversos objectos de uma dada classe, cada um trabalhando sobre os seus dados. O conceito de classe ficou associado ao conceito de abstraco de dados.

b) C++ Apesar do grande sucesso da linguagem C entre a comunidade de programadores, e apesar da grande flexibilidade desta linguagem, o suporte dos paradigmas dos tipos de dados abstractos e da programao orientada por objectos de difcil implementao em C standard. Devido grande potencialidade destes paradigmas, em especial no que se refere a projectos de trabalho em equipa e reutilizao de cdigo, em 1988, tambm nos Laboratrios BELL, Bjarne Stroustrup desenvolveu o C++ como extenso ao ANSI C. Esta linguagem hbrida, nada perde relativamente ao C (pode-se programar em C, utilizando C++), mas estende o C com a possibilidade de utilizar os conceitos da programao orientada por objectos, nomeadamente os conceitos de:
Universidade Aberta -92000-12-14

classe, herana, objectos e de polimorfismo. Sendo uma das linguagens hbridas general-purpose mais completa, ela a ideal para ilustrar os principais paradigmas da programao. O C++ ser a linguagem que iremos estudar em profundidade na cadeira de linguagens de programao. Com exemplos em C++ iremos ilustrar os principais paradigmas e mtodos da programao estruturada. 1.5 Exerccios

Na pgina web da cadeira poder encontrar a lista de exerccios proposta para este mdulo de estudo.

Universidade Aberta

-10-

2000-12-14

Mdulo de Estudo 2 :

Introduo ao C++

Inicia-se neste mdulo o estudo das linguagens da famlia do C, em concreto o C++. Com este estudo pretende-se que os alunos tenham o primeiro contacto com uma das linguagens de programao mais poderosas e que est entre as linguagens que geram os programas em cdigo de mquina mais eficientes dos dias de hoje. Mantendo as caractersticas de elevada flexibilidade e proximidade ao sistema operativo do C, o C++ estende esta linguagem com um conjunto de paradigmas que em muito facilitam o desenvolvimento de software. 2.1 Material de Estudo: O estudo deste mdulo ser realizado utilizando, como material de apoio terico, os captulos 2 e 3 do 2 livro adoptado (pginas 25 a 145 do livro [RodriguesPereiraSousa98]). Chama-se a ateno para o facto de o CD-ROM que acompanha o livro conter um conjunto de acetatos que poder auxiliar o aluno no seu estudo. Como complemento ao estudo terico, os alunos devero utilizar um compilador de C++, como seja o Borland C++ ou o Visual C++ para introduzirem, executarem e analisarem (introduzindo se necessrio pequenas alteraes no cdigo), os exemplos apresentados ao longo do texto. Caso no tenha acesso a nenhum dos compiladores de C++ referidos no livro (Borland C++ ou o Visual C++), poder fazer o download (gratuito) de um compilador de C++ via Internet. Caso opte por trabalhar em ambiente Windows, na pgina Internet da Borland (www.borland.com), tem acesso aos manuais de ajuda e FAQs dos produtos desta companhia e pode aps registo no museu, fazer download quer da verso comand-line do Borland C++ 5.5, quer do Borland Turbo Debuger 5.5. Com este debuger pode executar os programas compilados em C++, passo a passo, tal como j fez na cadeira de Programao com o Turbo Pascal. Na pgina web da cadeira poder obter a ultima informao sobre a forma de instalar e utilizar este software. 2.2 Objectivos: Os objectivos deste mdulo so: Os objectivos apresentados na pgina 25 de [RodriguesPereiraSousa98]. Saber introduzir no computador os programas que escreveu, nomeadamente: Compilar o cdigo do seu programa. Depurar e analisar o cdigo do seu programa por utilizao do Debuger. Os objectivos apresentados na pgina 85 de [RodriguesPereiraSousa98]. Criar e corrigir sintctica e semanticamente novos programas, por forma a (com auxilio do computador), conseguir dos seus programas o comportamento pretendido.

2.3 Exerccios No fim do estudo do captulo 2, o aluno deve ser capaz de resolver a totalidade dos exerccios propostos nas pginas 79 a 83 de [RodriguesPereiraSousa98]. Em particular o aluno dever resolver os exerccios 1 a 7, 9, 14, 25 e 26. No fim do estudo do captulo 3, o aluno deve ser capaz de resolver a totalidade dos exerccios propostos nas pginas 142 e 143 de [RodriguesPereiraSousa98]. Em particular o aluno dever resolver os exerccios 1 a 8 e 12.

Universidade Aberta

-11-

2000-12-14

Universidade Aberta

-12-

2000-12-14

Mdulo de Estudo 3 :

Elementos duma Linguagem de Programao

Neste mdulo de estudo tentar-se- generalizar os conceitos aprendidos no mdulo anterior a qualquer linguagem de programao imperativa. De igual forma sero apresentados os principais conceitos associados gesto de nomes numa linguagem imperativa. Estes conceitos sero essenciais para o estudo da prxima seco. Apesar do 2 livro adoptado conter uma seco sobre nomes e tipos, esta apresenta-se simultaneamente muito virada para o C/C++, e pouco relacionada com a compreenso do funcionamento interno dum programa de uma dada linguagem de programao. Apenas com o estudo de conceitos mais genricos ser possvel compreender como pode um programa escrito numa dada linguagem de programao funcionar num computador segundo o paradigma da mquina de Von Neumann. Revelou-se pois indispensvel a introduo desta seco, no s para a correcta compreenso dos conceitos desta cadeira como tambm como ferramenta indispensvel correcta compreenso do conceito de apontador: um dos principais problemas na aprendizagem da linguagem C e C++. O texto desta seco foi largamente influenciado pelos dois livros da bibliografia complementar: [WilsonClark93] e [Sethi89]. 3.1 Objectivos Com este mdulo pretende-se: Compreender a importncia dos conceitos de bloco de cdigo e procedimento. Compreender os diversos conceitos associados a um nome em qualquer linguagem de programao: Valor e tipo, visibilidade e posio. Compreender o conceito de apontador e a sua relao com a memria interna do computador. Generalizar o conhecimento das principais estruturas de controlo de um programa escrito numa linguagem imperativa. Identificar e saber utilizar as diversas formas de passagem de parmetros para um procedimento em qualquer linguagem de programao. Compreender como um programa em C gere a memria do computador. 3.2 Tipos e Variveis

3.2.1 Nomes Um programa pode ser visto como um conjunto de operaes sobre um conjunto de dados. Sobre os dados desse programa pode ser definido o seu tipo. O tipo dos dados define o conjunto de valores possveis desses dados e o conjunto de operaes que a eles podem ser aplicados. Assim, qualquer conjunto de dados tem um valor e um tipo. Num programa a forma usual de guardar dados utilizando variveis. As principais caractersticas de uma varivel so o seu nome, o seu valor e a referncia rea de memria interna do computador (no sentido da maquina de von Neumann atrs referida) que guarda o valor da varivel. Assim, para todas as variveis em todas as linguagens de programao, existe sempre, para qualquer varivel: nome da varivel (tambm conhecido pelo seu identificador). a sua rea de armazenamento (i.e. o endereo de memria onde o valor dessa varivel guardado). o valor armazenado.

No entanto, muitas vezes, usual a referncia a "uma varivel" denotar qualquer um destes trs aspectos, e por isso necessrio saber sempre ao que nos estamos a referir. Devido ao seu poder, a linguagem C (e a sua extenso o C++) recorre extensamente a esta distino. Sendo uma das principais dificuldades de quem comea a aprender C e C++ efectuar correctamente a distino entre estes vrios conceitos.

3.2.2

Declaraes e Associaes

Outro dos aspectos importantes a ter em conta o momento da associao do tipo e rea de armazenamento a uma
Universidade Aberta -132000-12-14

dada varivel. Quando essa associao efectuada em tempo de compilao ganhamos em eficincia (pois no necessrio executar esta operao durante a execuo do programa), por outro lado quando efectuamos essa associao em tempo de execuo do programa ganhamos em flexibilidade (pois o programa pode definir de que forma deve essa associao ser efectuada). Declarao de variveis: Nas linguagens de programao mais recentes, as variveis so introduzidas num programa atravs da sua declarao. na declarao duma varivel que se explicita qual o seu tipo e se indica ao computador a necessidade de reservar um espao em memria para conter o valor dessa varivel. As declaraes podem ser efectuadas juntamente com as instrues do programa. Blocos: O PASCAL, uma linguagem que utiliza o conceito de bloco. Em PASCAL um bloco uma sequncia de instrues entre BEGIN e END. Em PASCAL uma dada varivel pode ser associada a um bloco (sendo declarada num PROCEDURE ou FUNCTION associado a um conjunto de instrues). Em C, os blocos so declarado pelos caracteres '{' (o inicio do bloco) e '}' (o fim do bloco). O C mais genrico que o PASCAL, pois qualquer bloco pode conter no inicio a declarao de uma varivel. Scope rules (regras de visibilidade de uma varivel): variveis locais: Uma varivel local aquela que declarada dentro dum bloco de cdigo, sendo apenas visvel dentro desse bloco. variveis no locais: As variveis declaradas num bloco que contenha outro bloco dentro de si, so chamadas de no locais quando no bloco mais interno, mas continuam a ser visveis. variveis globais: Uma varivel no local, declarada no bloco mais externo (o programa) tambm chamada de varivel global.

Exemplo 1: no seguinte programa C: int a; float b; main() { /* inicio do bloco main */ int c; a=5; for(c=1;c<a; c++) { /* inicio do bloco for */ int j; int a; a=3; } /* fim do bloco for */ } /* fim do bloco main */ a e b so variveis globais, e logo conhecidas em todo o programa. c uma varivel local ao bloco main e logo no local (mas conhecida) no bloco do ciclo for. J j uma varivel apenas conhecida no interior do bloco do ciclo for. A varivel global a, foi redefinida no interior do bloco do ciclo for, assim dentro do bloco do ciclo for (i.e. entre { e } ) uma nova varivel (i.e. associada a uma nova rea de memria). Esta varivel local mantm o nome, escondendo por isso a varivel global: no interior deste bloco a varivel global a no est visvel, referindo-se todas as operaes sobre a varivel local. O ciclo continua a ser executado 5 vezes, pois embora quando se entra/sai do bloco no interior do ciclo for, a continua a ter o valor de 5. Apenas durante o ciclo a nova varivel a passa a ter o valor 3. Uma vez terminado o ciclo, a varivel retorna o seu valor original de 5. static scope (i.e. visibilidade esttica): Em linguagens como o FORTRAN, C, Pascal, Ada e Modula-2, a visibilidade de um identificador e o endereo de memria ao qual este est associado so determinados em tempo de compilao. Como consequncia os nomes so associados aos tipos em tempo de compilao.
Universidade Aberta -142000-12-14

dynamic scope: (visibilidade dinmica) A associao entre um identificador e a sua declarao (i.e. um local na memria interna do computador), depende da execuo do programa. Assim esta atribuio s pode ser efectuada em tempo de execuo. Exemplo 2: Considere o seguinte programa numa linguagem hipottica X (idntica ao C, mas com dynamic scope): int a=3; float b; int f() { /* inicio da funo a */ printf("%d\n",a); } p5() { /* inicio do bloco p5 */ int a=5; int c; f(); } /* fim do bloco p5 */ p7() { /* inicio do bloco p7 */ int a=7; int c; f(); } /* fim do bloco p7 */ main() { /* inicio do bloco main */ f(); } Este programa poder imprimir no terminal o valor 5, 7 ou 3 consoante a funo f seja chamada de dentro da funo p5, p7, ou de dentro do bloco main: numa linguagem utilizando visibilidade dinmica a declarao mais recente (durante a execuo do programa) a utilizada para definir a varivel. Assim, se f for chamada de dentro de p5, receber a varivel declarada em p5 (a declarao mais recente de a, pela ordem de execuo), se for de p7 receber a declarao de p7 e, no caso normal para o cdigo apresentado, se for chamada directamente de main, receber a declarao da varivel global. Realce-se, de novo, que isto s ser verdade no caso de uma linguagem com visibilidade dinmica, como o caso da linguagem X aqui apresentada. Assim, na linguagem C (que inspirou toda a sintaxe da linguagem hipottica, X), por exemplo, este programa imprimiria sempre o valor 3, pois no C as regras so as da visibilidade esttica (na funo f, a sempre a varivel global). Bastar tentar analisar o cdigo do ltimo exemplo, quer utilizando as regras de visibilidade esttica (i.e. considerando o ltimo exemplo como um programa em C) quer utilizando as regras de visibilidade dinmica (na linguagem hipottica X, do exemplo), para se compreender que as regras de visibilidade esttica do origem a programas muito mais fceis de compreender e de ler. Se conjugarmos a maior dificuldade de leitura de programas utilizando regras de visibilidade dinmica com a maior ineficincia do cdigo gerado pelos compiladores com visibilidade dinmica (pois no possvel efectuar validao de tipos em tempo de compilao, tornando-se pois necessrio efectuar essa validao em tempo de execuo), compreende-se que, regra geral a visibilidade dinmica no seja uma das caractersticas das linguagens modernas. H no entanto casos em que a tcnica da visibilidade dinmica apresenta vantagens, trata-se do caso dos tipos dinmicos. Tipos dinmicos: uma linguagem com tipos dinmicos aquela em que o tipo de uma varivel depende do seu valor actual. Os tipos dinmicos so muito utilizados em linguagens funcionais e linguagens lgicas. o caso de linguagens como o LISP ou o Prolog. As linguagens APL e SNOBOL4 utilizam igualmente tipos dinmicos. Como se tratam de linguagens tradicionalmente interpretadas, a sobrecarga de validao de tipos reduzida, e largamente recompensada pela flexibilidade ganha. Algumas linguagens funcionais recentes, como o ML ou o Haskell (cadeira de Fundamentos da Computao da
Universidade Aberta -152000-12-14

Universidade Aberta), apresentam um sistema de inferncia de tipos. Embora estas linguagens apresentem um sistema de tipos forte, o programador no tem de declarar todos os tipos, pois o sistema pode deduzi-los do contexto em que so utilizados. Mais vulgar a verificao de tipos que existe nas principais linguagens imperativas: statically typed (tipos estticos): Nas linguagens statically typed o compilador pode verificar se as atribuies dos tipos so correctamente efectuadas pelo programador. Assim os programas nestas linguagens tendem a ser: mais seguros (os erros de atribuio de tipos podem ser encontrados em tempo de compilao); mais eficientes (visto que as verificaes de correco dos tipos no necessitam de ser efectuadas durante a execuo do programa); e mais fceis de compreender (visto que a relao entre o tipo de uma varivel e o seu identificador podem ser efectuadas por anlise do cdigo do programa). Linguagens como o C (atravs de avisos), Pascal e Modula-2, so statically typed. strongly typed: Aquelas linguagens em que o tipo de todos os objectos pode ser predeterminado so chamadas linguagens strongly typed (com identificao de tipos forte). So exemplos de linguagens deste tipo o ADA e o ALGOL68, no entanto a maioria das linguagens no strongly typed.

3.2.3 Ciclo de Vida de uma Varivel Em C, Pascal (mais genericamente, em todas as variantes da linguagem ALGOL), apenas se reserva espao para uma varivel em memria quando a execuo do programa entra no bloco em que essa varivel declarada. De igual forma, nestas linguagens, sempre que a execuo do programa sai dum bloco, toda a memria reservada para as variveis declaradas nesse bloco deve ser libertada. Exemplo 3: no seguinte programa C: int a; float b; int p1() { int a; ... if(x!=0) p1(); } main() { /* inicio do bloco main */ int c; p1(); } /* fim do bloco main */

/* variavel a global */

/* varivel a interna a p1*/

enquanto o espao para as variveis globais a e b reservado quando o bloco principal activado (no inicio do programa), e a e b so pois variveis globais, conhecidas durante a execuo de todo o programa. J o espao para a varivel a (interna a p1) reservado sempre que o procedimento p1 entra em execuo. Note-se em concreto que se trata de um procedimento recursivo: em cada nova execuo do procedimento, criada uma nova varivel a (i.e. reservado mais um conjunto de endereos na memria interna do computador) e esse espao associado varivel criada. De igual forma sempre que termina uma execuo do procedimento p1 a varivel a associada a essa execuo libertadas. Desta forma sempre que se chama de novo o procedimento p1, podemos garantir uma das caractersticas mais importantes na estruturao deste tipo de linguagens: os valores atribudos s variveis nessa execuo da funo no interferem com valores atribudos em outras execues dessa funo. Este comportamento indispensvel para o suporte da recursividade na linguagem.

Universidade Aberta

-16-

2000-12-14

3.2.4 Variveis Locais Estticas Pode ser til preservar os valores de uma varivel interna de um procedimento entre diferentes execues. Em PASCAL, este comportamento s pode ser obtido utilizando variveis globais. Assim, para aumentar o ciclo de vida de uma varivel (por forma a ela ser lembrada entre vrias execues de um mesmo procedimento), somos tambm forados a aumentar a sua visibilidade. Apesar da varivel ser apenas relevante para um dado procedimento, todo o programa pode alterar o seu valor. O ALGOL 60, o PL/I e o C permitem a declarao das chamadas variveis locais estticas. Estas variveis tm as mesmas regras de visibilidade que as variveis locais normais, no entanto a reserva do espao para estas variveis ocorre, tal como nas variveis globais, quando o programa iniciado. Em C uma varivel pode ser declarada como varivel local esttica, precedendo a sua declarao da palavra chave static.

3.3

O Tipo de Dados Apontador

3.3.1 R-Value e L-Value Considere-se a seguinte atribuio: y := y+1 Nesta instruo o valor de y incrementado de 1. A interpretao de y varia no entanto constante o termo que consideramos. No termo da esquerda, y refere-se ao local onde o valor pode ser guardado (i.e. na varivel y). No termo da direita, y refere-se ao valor da varivel (y). Por analogia com esta expresso, usual distinguir numa varivel estes dois aspectos distintos: L-Value: Referncia ao local contendo o valor da varivel (o L vem de left, ou seja do termo da esquerda de uma atribuio). R-Value: Valor da varivel (o R vem de right, ou seja o termo da direita numa atribuio). Estes dois conceitos sero muito teis para descrever o conceito de apontador. As variveis de tipo apontador so variveis que tm como valor um endereo de memria - i.e. uma referncia a outro objecto do programa. Este tipo de dados no estava disponvel nas primeiras linguagens, tal como o ALGOL60 e o COBOL. no entanto indispensvel em qualquer linguagem modena. O tipo de dados apontador extensamente utilizado na linguagem C, nomeadamente atravs dos operadores * e &. Podemos relacionar estes operadores com as noes de l-value e r-value: 3.3.2 &<l-value> : o endereo da varivel <l-value>. *<r-value> : a varivel no endereo <r-value>.

Reserva Dinmica de Memria

Normalmente a memria para uma varivel no programa reservada na entrada num bloco. Esta reserva efectuada de forma automtica pelo cdigo compilado. O tipo apontador o nico que permite efectuar esta reserva de memria directamente do cdigo do programa (como veremos frente existe uma zona de memria especial para esta reserva: o Heap). No PASCAL, Ada ou Java isto feito utilizando a instruo new: apontador = new integer; Esta instruo reserva espao em memria para uma varivel do tipo inteiro, colocando o endereo do espao reservado na varivel apontador. Em C a instruo equivalente, seria: apontador = (int *) malloc(sizeof(int)); Podemos inclusivamente ter 2 apontadores para o mesmo endereo de memria. Se fizermos (utilizaremos a sintaxe do C, por clareza):
Universidade Aberta -172000-12-14

outro = apontador; tanto outro como apontador apontam para a mesma rea de memria. Assim colocando um valor no R-Value de apontador: *apontador = 3; tanto *outro como *apontador contm o mesmo valor.

3.3.3

Dangling Pointers (apontadores pendentes)

Um dos problemas com os apontadores o chamado caso dos apontadores pendentes: apontadores que apontam para endereos de memria no reservada. Nos antigos sistema operativo da famlia DOS, por exemplo, a utilizao de um ponteiro no inicializado como no cdigo que se segue poderia bloquear totalmente o computador. main() { int *ptr; /* errado */ /* ptr criado mas no est definido, aponta pois para qualquer local da memria. */ /* erro: coloca 5 algures na memria: pode mesmo destruir o cdigo do programa */

*ptr=5; }

De facto, neste caso, o apontador para inteiro ptr recebe um valor, que ser colocado algures na memria (pois o valor de ptr no inicializado, e pode por isso referir qualquer posio na memria). No DOS, um apontador no inicializado poderia refernciar um endereo da memria da mquina contendo o cdigo do prprio sistema operativo. Nesse caso seria provvel que o computador ficasse bloqueado e fosse necessrio fazer um reboot mquina. J em sistemas operativos com memria protegida, como por exemplo o sistema UNIX, o erro poderia ser menos grave (quando o sistema operativo detecta um acesso a uma rea de memria protegida, i.e. que no pertence rea reservada para a execuo do programa, este termina o programa com uma mensagem de erro apropriada, normalmente 'Segmentation fault.'). Tal j no aconteceria caso o apontador, por acaso, receba um valor sobre o strack ou heap. Nesse caso outra varivel, ou posio da memria reservada, pode ser alterado. Este o caso noutra situao onde se gera um dangling pointer: int *ptr_a; foo() { int a; ptr_a=&a; } Neste caso, ilustrado na figura 2 ptr_a recebe um apontador para uma varivel local. Como acabamos de ver, nas linguagens modernas, as variveis locais apenas existem dentro do cdigo do bloco que as contm (neste caso a funo foo). Assim sendo, ptr_a recebe um valor que apenas est reservado enquanto a funo foo executada. Se se colocar um valor em *ptr_a fora desta funo provvel que se esteja a aceder ao valor de uma varivel local qualquer no cdigo (conforme veremos na seco 3.6, o espao de reserva para as variveis locais normalmente o mesmo e est em constante reutilizao).

Universidade Aberta

-18-

2000-12-14

Figura 2 : Quando a funo foo termina, a rea de memria que lhe estava reservada libertada e ptr_a fica com um dangling pointer. 3.3.4 Garbage Colection

A reserva dinmica de memria tm outro problema. Imagine-se o seguinte caso: reserva-se memria dinmica para uma dada informao, colocando-se esse endereo na varivel apontador. Se, posteriormente, colocarmos outro endereo na varivel apontador (e no tivssemos entretanto copiado a referncia a esse espao para mais nenhuma varivel) , o espao reservado inicialmente deixaria de estar refernciado e no poderia voltar a ser utilizado pelo sistema. Se o programa, como normalmente acontece, funcionar em ciclo, ao fim de algum tempo, a memria para reserva dinmica (o Heap) estar esgotada! pois necessrio limpar os endereos no refernciados regularmente. A esse processo chama-se Garbage Colection (recolha do lixo). Depende da linguagem a forma de resolver este problema. Linguagens como o PASCAL ou o C, deixam a garbadge colection responsabilidade do programador, atravs, respectivamente das instrues dispose e free. A utilizao destas instrues requer no entanto cuidado especial pois se se libertar espao reservado ainda refernciado est-se a criar um potencial dangling pointer. A linguagem JAVA, por exemplo, utiliza um outro processo: enquanto o programa executa, existe um processo que continuamente verifica a rea de memria dinmica efectuando a garbage colection de forma automtica: o garbage collector. Existem vrias formas possveis de efectuar a garbage colection, na linguagem JAVA, por exemplo ([CampioneWalrath98]) utilizou-se uma derivao da tcnica mark-sweep collector (recolha por marcao e varrimento). Trata-se dumas das tcnicas mais simples de garbage collection. Na sua forma original esta tcnica funciona da seguinte forma: 1. Fase de marcao: Marcam-se todas as clulas que podem ser alcanadas atravs de apontadores. Uma boa analogia apresentada em [Sethi89]: imagine-se que se espalha tinta atravs dos apontadores, para todas as clulas de memria em utilizao. A tinta espalha-se, de clula em clula at marcar todas as clulas em uso. 2. Fase de varrimento: Percorrer a memria toda, procurando clulas no marcadas. Sempre que uma clula no marcada encontrada, esta retornada para o espao livre do sistema. Embora seja computacionalmente pesada, esta tcnica liberta o programador da preocupao com a gesto da memria e torna assim o processo de programao mais simples e menos susceptvel de erros com dangling pointers. Esta tcnica normalmente utilizada em linguagens funcionais ou lgicas como o LISP ou o PROLOG. 3.4 Expresses e Instrues Os principais componentes de uma linguagem imperativa so as declaraes -que acabamos de estudar- as expresses e as instrues. O estudo das expresses e das instrues base comum maioria das linguagens modernas, incluindo o C++. Iremos pois focar o seu estudo no caso do C++. As expresses do C (e logo tambm do
Universidade Aberta -192000-12-14

C++) incluem o conjunto de expresses tpico de qualquer linguagem imperativa : A noo de prioridade dos operadores. Expresses matemticas. Expresses lgicas. Expresses mistas. Overloading de operadores (este ltimo caso apenas presente no C++). Os diversos tipos de instrues das diversas linguagens imperativas so tambm comuns ao C: Instrues e operadores de atribuio, mltiplos ou simples. Instrues compostas (a noo de bloco). Instrues de seleco (if e case). Instrues iterativas (do while, do repeat e for).

O seu estudo foi efectuado, no caso do C, no mdulo 2. Existe no entanto uma caracterstica do C++ que no pode ser directamente implementada no C: o tratamento de excepes. Na prxima seco vamos estudar o seu funcionamento na linguagem JAVA e a forma como este mecanismo utilizado no C++.

3.4.1 Tratamento de Excepes Durante a execuo de um programa podem ocorrer eventos anormais, que tornam a continuao normal do programa no desejvel ou mesmo impossvel. o caso frequente de erros como os devidos a: erros de hardware (erros no disco), operaes matemticas invalidas num dado domnio (divises por zero, raiz quadrada de um nmero negativo ou nmero demasiado elevado para um dado tipo de dados - overflow), erros na entrada do utilizador ou um endereo invlido de um vector. A maioria das linguagens de programao, deixa o tratamento destes acontecimentos totalmente responsabilidade do programador. Compete ao programador tratar estes erros como e quando acha necessrio. Este tipo de abordagem pode facilmente conduzir a programas complexos e pode facilmente obscurecer a estrutura interna do programa. Outra abordagem a de possibilitar o tratamento de excepes como parte da linguagem. A primeira linguagem a fazer isto, foi como vimos, o PL/I. Mais recentemente linguagens como o Ada, C++ e o JAVA incluram o tratamento de excepes de uma forma robusta. Quando um evento excepcional (como os que enumeramos acima) ocorre, diz-se que se levantou uma excepo. Nesse caso, a execuo normal do programa interrompida e o controle transferido para uma parte especial do programa conhecida pelo exception handler (tratador de excepes). Normalmente, existem diferentes rotinas para tratamento das diferentes excepes. Um programa que trata as diferentes excepes que se podem levantar diz-se resistente falha (fault-tolerant).

3.4.2 Tratamento das excepes em JAVA Aps ter ocorrido uma excepo o sistema de execuo do JAVA inicia uma busca do cdigo para tratamento desse erro. Essa busca iniciada no mtodo (o equivalente a um procedimento quando trabalhando com objectos) onde ocorreu a excepo e, caso no haja ai qualquer cdigo para tratamento da excepo, continua-se a busca, sucessivamente, no mtodo que chamou o mtodo actual. Desta forma, em JAVA, a excepo sobe como uma bolha por toda a pilha de mtodos. Apenas no caso de no ser encontrada nenhuma rotina para tratamento da excepo, que o programa termina (com uma mensagem de erro associada ao tipo de excepo detectada). Imagine-se pois que pretendiamos implementar a seguinte funo (extrada de [CampioneWalrath98]): lerFicheiro { abrirFicheiro(f); tamanho=obterTamanhoFicheiro(f); ptr=reservarMemoria(tamanho);
Universidade Aberta -202000-12-14

lerParaMemria(ptr, tamanho, f); fecharFicheiro(f); } primeira vista, embora o cdigo parea relativamente simples, ignora todos os potenciais erros deste programa: que acontece se o ficheiro no pode ser aberto? que acontece se no for possvel determinar o tamanho do ficheiro. que acontece se o comprimento do ficheiro no puder ser determinado? que acontece nos casos em que a leitura falha? que acontece quando o ficheiro no pode ser fechado? Para respondermos a todas estas questes seria necessria a implementao de muito mais cdigo. O programa acabaria por ficar em qualquer coisa como: int lerFicheiro { int codigoErro=0; int tamanho; f=abrirFicheiro(s); if(ficheiroAberto(f)) { tamanho=tamanhoFicheiro(f); if(tamanhoFicheiroOK(tamanho)) { ptr=reservarMemoria(tamanho); if(reservaMemoriaOK(ptr)) { lerParaMemria(ptr, tamanho, f); if(not(lerParaMemriaOK())) { codigoErro=-1; } } else { codigoErro=-2; } } else { codigoErro=-3; } fecharFicheiro(f); if(not(ficheiroFechado(f)) && codigoErro==0) { codigoErro=-4; } else { codigoErro=codigoErro + -4; } } else { codigoErro=-8; } return codigoErro; } O que no s complexo e com uma srie de questes subtis, como tambm torna o cdigo original totalmente ilegvel! Este exemplo ilustra bem os problemas de que as linguagens sem capacidade de deteco de excepes sofrem. No entanto se nesta funo utilizassemos as tcnicas de controle de erros teriamos uma soluo similar ao seguinte cdigo: lerFicheiro { try { abrirFicheiro(f);

Universidade Aberta

-21-

2000-12-14

tamanho=obterTamanhoFicheiro(f); ptr=reservarMemoria(tamanho); lerParaMemria(ptr, tamanho, f); fecharFicheiro(f); } catch (abrirFicheiroFalhou) { ... ; } catch (fecharFicheiroFalhou) { ...; } catch (obterTamanhoFicheiroFalhou) { ...; } catch (reservaMemriaFalhou) { ...; } catch (lerParaMemriaFalhou) { ...; } }

Qualquer mtodo (o equivalente a um procedimento quando trabalhando com objectos) JAVA pode levantar excepes ou erros, predefinidos ou definidos pelo utilizador, veja-se um exemplo com o mtodo pop (que retira um elemento de uma pilha): public Object pop() throws EmptyStackException { Object obj; if (size == 0) throw new EmptyStackException(); obj = objectAt(size - 1); setObjectAt(size - 1, null); size--; return obj; } Este mtodo levanta a excepo EmptyStackException com a instruo throw, sempre que se tenta retirar um elemento de uma pilha vazia (a instruo new limita-se a criar o objecto EmptyStackException, pois em JAVA as excepes so tambm objectos). Em JAVA as excepes devem ser declaradas (o throws EmptyStackException aps o cabealho do mtodo). Apesar de poderem ser utilizadas para outros fins, importante manter a utilizao de excepes para o tratamento de situaes anormais ou de erro. De facto apenas em casos anormais ou de erro a utilizao de excepes aumenta a clareza do cdigo. Em situaes normais, a utilizao das instrues condicionais if e case a que maior clareza trs ao cdigo. Exerccio: Utilize as instrues throw e catch do C++ (consulte a ajuda on-line do C++) para implementar a funo LerFicheiro em C++, com tratamento de excepes.

3.4.3 A Instruo goto A utilizao da instruo goto normalmente desencorajada desde a carta de Dijkstra para a conceituada revista Communications of ACM de titulo "Goto Statement Considered Harmful" (1968). A instruo goto extremamente flexvel, tendo sido extensamente utilizada nas primeiras verses da linguagem COBOL e FORTRAN. A utilizao excessiva de instruo goto, nomeadamente quando ligada a saltos condicionais (i.e. utilizando a instruo goto em conjuno com a instruo if) d origem a cdigo pouco legvel, onde os erros so difceis de localizar e corrigir. Felizmente a utilizao das instrues de ciclo (for e do, conjugada com as instrues break e continue) e de subprogramas torna a sua utilizao praticamente desnecessria. Na linguagem Modula-2, por exemplo, esta instruo j foi mesmo excluda.

Universidade Aberta

-22-

2000-12-14

3.5 Sub-programas: Passagem de Parmetros Operacionalmente os mtodos de passagem de parmetros podem ser divididos em: 1. passar informao para um subprograma. 2. receber informao de um subprograma. 3. passar informao que pode ser actualizada antes de ser retornada. A linguagem Ada d directamente conta destes 3 casos, respectivamente, com os argumentos do tipo:in, out e inout. No entanto a maioria das linguagens no apresenta, directamente, estruturas que dem conta de todos estes modos. Estes trs modos podem ser implementados de diversas formas. Se pensarmos em termos de l-values e rvalues, para uma chamada de subprograma P(a), podemos implementar: Uma chamada por valor (call by value). Neste caso passamos o r-value de a. Uma chamada por referncia (call-by-reference). Passamos o l-value de a. Uma chamada por nome (call-by-name). Onde passamos o nome da varivel (neste caso texto a) para dentro do subprograma. Chamada por valor-resultado: chamada por valor, sendo o l-value da varivel actualizado apenas no fim da execuo do subprograma. semanticamente equivalente passagem por referncia.

Operacionalmente podemos relacionar estes trs modos com os modos operacionais anteriores. Utilizando a notao sintctica do Ada: IN: Passagem por valor. OUT: Passagem por resultado. IN-OUT: passagem por valor-resultado, passagem por referncia e passagem por nome.

O C utiliza apenas a passagem por valor. No entanto devido elevada flexibilidade desta linguagem possvel implementar igualmente a passagem por referncia. Devido existncia do pr-processador esta linguagem suporta tambm a passagem por nome. J no PASCAL e Modula-2, possvel utilizar tanto a passagem por valor (o caso por defeito), como a passagem por referncia (quando se adiciona a directiva var antes do nome do procedimento). De seguida utilizaremos o exemplo da funo swap para tentar ilustrar de forma clara as diferenas entre os vrios mtodos de passagem de parmetros.

3.5.1

Passagem por Valor

A passagem por valor sem duvida a forma mais usual de passar parmetros para uma funo. Com a passagem por valor, os argumentos da funo so copiados para variveis locais funo. Pode-se mesmo pensar nesta variveis como variveis locais funo, criadas com o mesmo nome dos parmetros da funo e para as quais copiado o valor do parmetro. Este processo impede assim a alterao dos valores dos seus argumentos pela prpria funo. Imaginemos agora que pretendemos implementar a funo swap que troca o contedo dos seus dois argumentos. Numa primeira abordagem, poder-se-ia pensar no seguinte programa C:

void swap_errado(int x, int y) { /* Mal implementado */ int z; z = x; x=y; y=z; } No entanto, este cdigo no funciona! De facto, como j foi referido, o C apresenta passagem por valor dos seus parmetros: os valores dos seus argumentos so copiados para novas variveis. Assim sendo, apenas as variveis locais funo tm os valores trocados, mas esta troca perde-se quando o procedimento termina e estas variveis so destrudas. Os argumentos de swap_errado mantm o seu valor. Talvez seja mais claro se considerarmos o que acontece aps a chamada de swap_errado(a,b): /*Criao das variveis x, y e z */
Universidade Aberta -232000-12-14

x = a; y = b; z = x; x = y; y =z; /*Destruio de x, y e z */

3.5.2

Passagem por Referncia

A passagem por referncia pode ser feita em PASCAL (ou no Modula-2), utilizando a palavra reservada var. Apenas com a passagem por referncia se torna possvel a implementao da funo swap, eis a implementao desta funo em PASCAL: procedure swap(var x : integer; var y : integer); var z : integer; begin z:=x; x:=y; y:=z end; Para analisarmos o comportamento desta funo, imagine-se um vector a, em que a[2]=99 a[99]=5 e i=2. Considerese que swap chamada com os seguintes argumentos: swap(i, a[i]) O que acontece neste caso? Recordemos que na passagem por referncia so os l-values das variveis que so passados como argumentos. Assim, swap dever efectuar os seguintes passos: /*Criao das variveis x, y e z */ x = l-value de i; y = l-value de a[i]; z = x; x = y; y =z; /*Destruio de x, y e z */ Desta vez, como so utilizados os l-value dos argumentos, estes so de facto alterados: x=y, equivalente a i=a[i], ou seja i recebe 99 (i.e. o valor de a[2]). y=z, equivalente a a[2]=i, ou seja a[2] recebe 2 (i.e. o valor inicial de i). Note-se que y recebe o valor de a[i] antes de ser efectuada qualquer alterao aos valores das variveis! S assim possvel efectuar a cpia correcta dos valores. De facto, a passagem por referncia reduz-se a uma passagem por valor, utilizando apontadores para os argumentos a passar. esta a razo porque o C no necessita de passagem por referncia. De facto a funo swap pode ser directamente implementada em C, utilizando apontadores: void swap(int *px, int *py) { int z; z = *px; *px = *py; *py = z; } As principais vantagens desta abordagem a de estar mais prxima da implementao em termos de linguagem mquina e a de no necessitar de nenhuma estrutura sintctica para o tratamento da passagem por referncia. A principal desvantagem o facto de os parmetros da funo, quando passados por referncia, terem que ser desrefernciados, assim em vez da chamada swap(i, a[i]) do Pascal, em C para qualquer passagem por referncia, ser necessrio escrever: swap(&i, &(a[i])); (ou alternativamente swap(&i, a+i ) )

Apesar da mais crptico, este cdigo acaba por ser mais fiel ao que de facto se passa ao nvel da mquina. So os lvalue e no os r-value que so passados como parmetros.
Universidade Aberta -242000-12-14

3.5.3 Passagem por Valor-resultado Usualmente, trata-se de uma abordagem equivalente passagem por referncia. Tal como na passagem por valor, o argumento tambm copiado para variveis locais ao subprograma (fase copy in). No entanto o valor de retorno pode no se perde, pois ele de novo copiado para as variveis argumento (fase copy out): /*Criao das variveis x, y e z */ x = a; y = b; z = x; x = y; y =z; /* Concluso do subprograma */ a=x; b=y; /* Destruio de x, y e z */ Em rigor, na maioria das linguagens, h casos em que este processo pode dar valores diferentes, considere-se o programa em pseudo-cdigo Pascal: program ... procedure foo(inout x:integer, inout y : integer); begin i := y end; begin i:=2; A[i]:=99; foo(i, A[i]); end. Neste caso, i, seria reescrito 2 vezes: a primeira dentro do procedimento foo, ficando i com o valor 99, e a ltima, mais indirecta, na sada do procedimento, voltando i ao valor 2. Na linguagem Ada, o compilador considera este tipo de construes ilegal, podendo o compilador optar por utilizar a passagem por referncia ou por valor-resultado, pois ambas so semanticamente equivalentes. 3.5.4 Passagem por Nome: Expanso de Macros em C Num programa C igualmente possvel uma outra forma de passagem de argumentos. De facto, antes de ser compilado, qualquer programa C pr-processado por um processador de macros, destinado a suportar extenses linguagem, substituio de constantes e incluso de ficheiros. Em C, todos os comandos do pr-processador so iniciados pelo caracter #. Uma das funes deste pr-processador a de efectuar a substituio literal de todas as macros pelo cdigo que lhes est associado. A vantagem deste tipo de substituio a sua elevadssima eficincia: de facto o cdigo do programa alterado em tempo de compilao, no sendo chamada qualquer funo em tempo de execuo. O mecanismo da passagem de parmetros para uma macro no entanto extremamente condicionado. Imagine-se que tentvamos implementar o procedimento swap utilizando uma macro: #define SEMI_SWAP(x,y,z) z=x; x=y; y=z; \ \ \

Que funciona na maioria dos casos (o terceiro parmetro dever receber uma varivel que ser utilizada com auxiliar). No entanto, se tentssemos utilizar esta macro para a troca de valores entre i e a[i], anteriormente apresentada, os resultados seriam totalmente diferentes. Substituindo os valores na chamada SEMI_SWAP(i,a[i], aux), vemos porqu (relembre-se que, inicialmente i=2 e a[2]=99):
Universidade Aberta -252000-12-14

aux = i; /* aux=2 */ i=a[i]; /* i=99 */ a[i]=aux; /* a[i] agora a[99] e no a[2] como pretendido */

Isto , o segundo parmetro, a[i], apresenta um naming confict com o primeiro parmetro, i. Ao alterarmos i, perdemos o l-value de a[i]! Devido a este tipo de problemas, a maioria das linguagens no possibilita a passagem por nome. O ALGOL60, tentou ser uma excepo a esta regra. Para tal enunciou um principio que generaliza o problema atrs descrito: Conflito de nomes: Um conflito de nomes ocorre durante a substituio do texto T em S se um nome no local em T alterado sobre o escopo da associao em S. Para resoluo deste tipo de conflitos o ALGOL60, sempre que detectasse qualquer varivel em conflito com este principio, recorria substituio do nome dessa varivel em todos os locais do cdigo que pudessem ser problemticos. No entanto, devido complexidade de implementao de tal tarefa e maior clareza da passagem por nome/referncia, a passagem por nome deixou de ser til e j no utilizada na maioria das linguagens de programao dos dias de hoje. O pr-processador de macros do C, das poucas excepes a esta regra. Na prtica, no C optou-se por ignorar o problema dos conflitos de nome: um programa implementado em C, utilizando a macro SEMI_SWAP, com a chamada apresentada, produzir de facto o resultado (inesperado) aqui apresentado. da responsabilidade do programador utilizar as macros por forma a evitar este tipo de conflitos. Na prtica, as macros do C apenas foram introduzidas devido s necessidades de eficincia e flexibilidade de alguns programas escritos em C. As macros com argumentos do C apenas devem ser utilizadas, tendo os devidos cuidados, em cdigo em que a sobrecarga da chamada de um procedimento seja de facto grande.

3.6 Gesto de Memria Normalmente, as linguagens de programao modernas so implementadas reservando uma rea de memria para os dados do programa. Existem duas estratgias principais para reserva desta memria: a esttica e a dos blocos dinmicos.

3.6.1 Reserva Esttica Foi um processo utilizado na linguagem FORTRAN. Neste mtodo a memria para os dados reservada de forma esttica para cada elemento. Este processo permite determinar em tempo de compilao quais os endereos de memria efectivos para cada varivel. Infelizmente, e apesar da sua simplicidade este modelo no suficiente para as necessidades das linguagens modernas: o tamanho de todos os objectos tem de ser conhecido em tempo de compilao e nenhuma varivel pode ocorrer mais de uma vez, como no caso de uma funo recursiva, p.ex., que efectue o clculo dos nmeros de Fibonacci quando o argumento um nmero positivo e que retorne 1 quando o argumento um nmero negativo:

int Fib(int n) { if(n<0) return 1; if(n<=2) return 1; return Fib(n-1)+Fib(n-2) } Neste caso se a reserva de memria fosse esttica, o programa limitar-se-ia a decrementar n no primeiro termo da srie, sendo o valor utilizado no segundo termo influenciado pelas chamadas no primeiro termo, a seguinte sequncia de chamadas sucessivas da funo Fib, com o valor de n descriminado, ilustra o que se passaria, primeiro utilizando memria dinmica e depois memria esttica:

Universidade Aberta

-26-

2000-12-14

Memria dinmica:

Fib(4) n=4
Fib(4-1) n=3 Fib(3-1) n=2 =1

=3

=2
Fib(3-2) n=1 =1

Fib(4-2) n=2

=1

Memria esttica:

Fib(4) n=4
Fib(4-1) n=3 Fib(3-1) n=2 =1 Fib(2-2) =1

=1

=2

Fib(0-2) n=-2

=-1

n=0

Consideremos ento o caso de memria esttica: quando se chama a funo Fib, o valor de n actualizado. No primeiro termo da expresso n vai recebendo valores sucessivamente menores. S quando n menor ou igual a 2 que a funo retorna. No entanto no agora possvel recuperar o valor anterior de n=3, para o utilizar no segundo termo! Assim o ltimo valor de que o computador se lembra, n=2, utilizado.

3.6.2 Reserva Dinmica de Blocos Tal como na gesto esttica, o bloco principal do programa tem as suas variveis reservadas no inicio da execuo do programa. No entanto a associao das variveis dum subprograma (p.ex. funo ou procedimento) a um endereo de memria s ocorre quando se entra nesse subprograma. Este tipo de associao normalmente designada por stack storage management. De seguida vamos ilustrar como se processa a gesto dinmica de memria num programa C. Numa linguagem com gesto dinmica de memria uma varivel declarada num dado bloco de cdigo local execuo desse bloco de cdigo. Assim o compilador utiliza normalmente uma pilha (ou stack) para armazenar as variveis locais ao bloco de cdigo em execuo. Os dados necessrios para activar um subprograma so guardados num registo chamado activation record ou frame. Estas frames so guardadas numa pilha: o sack frame, criado no topo do stack quando o controle entra no bloco de cdigo. Quando o controle do programa sai de dentro desse bloco de cdigo, j no h necessidade de utilizar essa varivel, e o activation record removido do topo do stack frame, podendo os l-value das variveis locais desse mdulo serem reutilizados e atribudos a outras variveis locais desse ou doutro bloco. 3.6.3 Gesto de Memria nas Linguagens da Famlia do C

Universidade Aberta

-27-

2000-12-14

O que se segue foi extrado de [Sethi86]. Esta seco serve para exemplificar como os conceitos de que acabamos de falar so implementados na linguagem C (e por consequncia em C++). Note-se que o esquema de gesto de memria no C um pouco mais simples que em linguagens como por exemplo o Pascal onde os procedimentos podem estar aninhados (nested) uns nos outros. A figura abaixo ilustra como um programa C (com vrios blocos) organiza e gere a memria de um computador.

Figura 3 : Gesto da memria num programa C/C++. Existe um registo do processador, chamado de program counter que mantm o controle da instruo que est correntemente a ser executada pelo computador. O cdigo de um programa C, que no pode ser alterado durante a execuo do programa, representado pela caixa "cdigo" na esquerda da figura. Os dados globais so guardados em memria reservada estaticamente (representada no canto superior direito da figura pela caixa "Dados Globais Estticos"). Por sua vez os dados locais so guardados no stack frame (caixa imediatamente abaixo), que como vimos aumenta e diminui de tamanho consoante necessrio. De igual forma, no outro extremo da memria existe uma rea chamada de heap para armazenar os dados reservados pelos procedimentos calloc e malloc, utilizados na reserva dinmica de memria. Refira-se que, durante a execuo do programa, a memria livre para o programa pode esgotar-se tanto quando se reserva memria dinamicamente (p.ex., por no se chamar a instruo free), como por se declararem demasiadas variveis locais (ou vectores demasiado grandes). Como deve ser neste momento obvio, a reserva de demasiado espao para variveis locais pode exigir demasiada memria, especialmente em procedimentos recursivos. Estes problemas de memria eram particularmente incmodos nas primeiras verses do Borland C, pois (para aumentar a eficincia do acesso a memria, utilizando apenas 16 Bit para os L-Value) este programa limitava o espao de memria dinmica apenas a 64k no modo normal. Apesar deste valor poder ser multiplicado para 640k com a configurao adequada do compilador, tal era ainda insuficiente para a maioria das aplicaes mais exigentes.

3.6.4 O Stack-frame dum Programa C Para completar a descrio da gesto de memria dinmica no C resta apenas explicar como o compilador de C organiza o activation-record para cada chamada de uma funo C. Esta forma de organizao da memria faz parte da definio da linguagem C e contribuiu definitivamente para que, na mesma plataforma, se possam juntar procedimentos escritos nas mais diversas linguagens. Num ambiente Unix, por exemplo, todas as principais linguagens da actualidade ou suportam a chamada de uma funo escrita e compilada em C ou podem ter os seus subprogramas chamados de dentro de um programa em C. Considere a seguinte figura:

Universidade Aberta

-28-

2000-12-14

Figura 4 : Gesto do stack-frame numa chamada de procedimento em C/C++. As seguintes aces ocorrem quando uma funo ou procedimento C chamado: 1. Atendendo a que o C utiliza (sempre) passagem de parmetros por valor, o programa principal ou a funo chamante (i.e. o programa ou subprograma que chama a funo corrente), avalia os parmetros de chamada, e coloca os resultados (por ordem inversa) no inicio do Stack. 2. A funo chamante coloca de seguida no stack a informao necessria para restaurar a sua execuo (quadrado estado do programa), uma vez que a funo chamada termine (inclui o endereo do program counter para onde a funo chamada deve retornar a execuo). 3. A funo chamada reserva espao para as suas variveis locais. ainda reservado mais algum espao na rea de trabalho, para algumas variveis de trabalho, de que o cdigo compilado necessita (p.ex. para guardar clculos intermdios na avaliao de expresses complexas). 4. O cdigo da funo chamada ento executado. Note-se que a funo chamada pode funcionar tambm como funo chamante de outras funes (ou dela prpria no caso de uma funo recursiva). Nesse caso o stack frame utilizado para guardar os parmetros e activao das novas chamadas (quadrado parmetros de chamada). Compete funo chamante remover esses parametros quando a funo chamada retornou. Assim, aps o retorno funo corrente, o stack frame volta a ter o tamanho inicial. 5. O controle retorna funo chamante. Um valor de retorno (se existir) colocado no local apropriado da funo chamante e a informao sobre o estado do programa retirada do stack para restaurar os registos do processador para o estado de partida antes da chamada. O controle retorna ao endereo do program counter, que tinha sido previamente guardado. 3.7 Exerccios

Na pgina web da cadeira poder encontrar a lista de exerccios propostos para este mdulo de estudo.

Universidade Aberta

-29-

2000-12-14

Universidade Aberta

-30-

2000-12-14

Mdulo de Estudo 4 :

Declaraes, Definies e Classes em C++

Enquanto na seco anterior estudamos a forma e mecanismos de implementao das linguagens de programao em geral. Neste mdulo de estudo prope-se a concretizao dos conceitos apresentados numa linguagem concreta: o C++. Um particular detalhe ser dado aos paradigmas de Abstract Data Types e Object Oriented Programming que sero introduzidos no captulo 5 de [RodriguesPereiraSousa98]. 4.1 Objectivos Os objectivos deste mdulo de estudo so apresentados nas pginas 145 e 235 de [RodriguesPereiraSousa98]. 4.2 Material de Estudo O material de estudo terico composto pelos captulos 4 e 5 (pginas 145 a 338) de [RodriguesPereiraSousa98]. Relembra-se que o CD-ROM que acompanha o livro contm um conjunto de acetatos que o podero auxiliar no seu estudo. Como complemento ao estudo terico, os alunos devero utilizar o compilador de C++ para introduzirem, executarem e analisarem (introduzindo se necessrio pequenas alteraes no cdigo), os exemplos apresentados ao longo do texto. 4.3 Exerccios No fim do estudo do captulo 4, o aluno deve ser capaz de resolver a totalidade dos exerccios propostos nas pginas 228 a 234 de [RodriguesPereiraSousa98]. Em particular o aluno dever resolver os exerccios 1 a 7, 12 e 14. No fim do estudo do captulo 5, o aluno deve ser capaz de resolver a totalidade dos exerccios propostos nas pginas 335 a 338 de [RodriguesPereiraSousa98]. Em particular o aluno dever resolver os exerccios 1, 2, 7 e 11. Por fim crie uma funo main() que permita o teste dos novos mtodos criados.

Universidade Aberta

-31-

2000-12-14

Universidade Aberta

-32-

2000-12-14

Mdulo de Estudo 5 :

Introduo Programao em Lgica

No ltimo mdulo de estudo da cadeira iremos abordar o estudo da principal linguagem para a programao em lgica: o PROLOG. 5.1 Objectivos Os principais objectivos deste mdulo so: Compreender programas escritos em estilo declarativo em PROLOG. Compreender a semntica procedimental e o conceito de unificao. Compreender que num programa PROLOG dados e cdigo so equivalentes. Podendo mesmo um programa PROLOG controlar-se a si prprio, gerindo a sua base de dados, atravs de meta-regras. Saber quando um programa PROLOG simples tem mltiplas solues. Saber ler e escrever regras bsicas para interrogar uma base de dados PROLOG escrita em estilo declarativo. Saber ler e analisar programas escritos em PROLOG. Adicionar regras bsicas a programas PROLOG escritos em estilo declarativo. Introduzir algumas Queries num interpretador PROLOG. 5.2 Material de Estudo O material de estudo composto pela seco 5 da II parte do 1 livro adoptado (pginas 93 a 106). Como complemento ao estudo terico, os alunos devero utilizar um interpretador PROLOG, fornecido na pgina web da cadeira, para introduzirem executarem e analisarem (introduzindo se necessrio pequenas alteraes no cdigo), os exemplos apresentados no texto e outros exemplos apresentados na pgina web da cadeira. 5.3 Exerccios Na pgina web da cadeira poder encontrar a lista de exerccios propostos para este mdulo de estudo.

Universidade Aberta

-33-

2000-12-14

Universidade Aberta

-34-

2000-12-14

Referncias
Coelho84 Problemas e Linguagens de Programao por Helder Coelho, LNEC, 1984.

RodriguesPereiraSousa98 Programao em C++, conceitos bsicos e algoritmos por Pimenta Rodrigues, Pedro Pereira e Manuela Sousa, FCA- Editora de Informtica. 1998. ISBN 972-722-038-X. WilsonClark93 Comparative Programming Languages, 2nd Edition. Leslie B. Wilson e Robert G.Clark, Addison-Wesley, 1993. ISBN 0-201-56885-3. Sethi89 Programming Languages, Concepts and Constructs, Ravi Sethi, 1st Edition, AddissonWesley, September 1989. ISBN 0-201-10365-6. Martins97 Introduo Programao usando o PASCAL, J. Pavo Martins, Mc-Graw Hill, 1994. ISBN: 972-9241-79-7. The Java Tutorial Second Edition, Mary Campione e Kathy Walrath, AddissonCampioneWalrath98 Wesley, Maro 1998. ISBN 0201310074. http://java.sun.com/docs/books/tutorial.

Universidade Aberta

-35-

2000-12-14