You are on page 1of 29

Linguagens de Programao 1 - Notas de Aula

Aviso: Essas notas de aula tem por finalidade orientar o professor no encaminhamento das aulas, a fim de no deixar assuntos fora da ordem planejada. A leitura deste material no reduz a necessidade de leitura da bibliografia recomendada. ltima atualizao em 28/02/12.

1. Paradigmas de Linguagens de Programao


Existem muitas linguagens de programao, todas elas com caractersticas diferentes. Por vezes, muito diferentes. As linguagens no entanto, adotam tcnicas comuns de programao, desenvolvidas de forma independente de uma linguagem conforme a rea de Linguagens de Programao evolui. As linguagens de programao podem ser classificadas de muitas formas diferentes. Umas das formas de classificao quanto ao paradigma de programao. Mas o que um paradigma? A palavra paradigma pode significar muitas coisas. No contexto cientfico, costuma ser usada para um conjunto de teorias, padres e mtodos que juntos representam uma forma de organizar o conhecimento, ou seja, uma forma de ver o mundo [Budd91]. No contexto de linguagens de programao, podemos dizer de maneira bem simples que paradigma um estilo. Porm estamos nos referindo a estilo numa conotao forte. Para serem chamados de paradigmas de programao, estilos precisam ser suficientemente diferentes e completos para serem considerados uma forma de ver o mundo. Autores diferentes classificam as linguagens de programao de formas diferentes. Apesar disso, geralmente aceito que existem dois tipos principais de programao: (a) programao imperativa (ou procedural), de acordo com a qual os programas so construdos por meio de uma sequncia de ordens - o programador escreve um procedimento que leva soluo de um problema; (b) programao declarativa (ou descritiva), de acordo com a qual os programas so construdos simplesmente pela descrio da soluo de um problema - cabe ao compilador encontrar uma sequncia de instrues que produz a soluo declarada. Na programao declarativa, existem duas formas principais de se descrever solues: (a) atravs de funes (conceito matemtico de associao entre elementos de um conjunto domnio para um conjunto imagem) e (b) atravs de predicados (elementos sintticos que permitem expressar relaes entre elementos de conjuntos). Vale lembrar que uma funo um tipo especial de relao de associao. Assim, dadas essas duas categorias gerais distintas e o fato de que em uma delas, existem duas formas muito diferentes de descrever a soluo de um problema, o autor deste texto considera que so trs os paradigmas de programao: programao imperativa (ou procedural) - em que programas so implementaes de algoritmos (sequncia de instrues que levam soluo de um problema); programao funcional - em que programas so implementaes de funes e programao lgica - em programas so implementaes de predicados (relaes entre elementos de conjuntos diversos).

comum encontrar autores que classificam a Programao Orientada a Objetos como sendo um paradigma de programao. Essa classificao considera que o projeto de programas orientados a objetos segue conceitos de destaque suficiente para que esse estilo de programao seja classificado parte da programao imperativa. Este texto se concentra na programao imperativa, apesar de apresentar conceitos que so independentes do paradigma de programao. Alguns conceitos em particular so melhor

Notas de Aula de GCC105 - BCC e BSI - UFLA

exemplificados atravs de suas implementaes em linguagens funcionais como (LISP, ML, Haskell, etc.) e nesses casos daremos preferncia a exemplos nessas linguagens.

2. Conceitos de Linguagens de Programao


Este o capitulo principal deste texto. Aqui so descritas caractersticas das linguagens de programao de uma maneira independente da linguagem de programao. So apresentados problemas relativos ao projeto de uma linguagem de programao juntamente com formas de resolv-los. As vrias solues so comparadas para permitir que as linguagens de programao sejam entendidas de um ponto de vista mais amplo do que simplesmente como uma coleo de comandos e tipos de dados. Espera-se que as as informaes apresentadas aqui permitam que leitor que sinta ambientado em qualquer linguagem de programao que venha a usar no futuro, em funo de conhecer os conceitos que permitem a criao das vrias facilidades que so proporcionadas de formas diferentes, por linguagens diferentes.

2.1 Tipos de Dados


Algumas linguagens no tem o tipo de dado que voc precisa, pode ser necessrio implement-lo (ex.: implementar listas ou rvores usando vetores). Algol68 permitia a declarao de novos tipos, um avano significativo. Um tipo primitivo de dados aquele que no pode ser decomposto em partes mais simples [Watt, 89]. Para tal classificao, considera-se a linguagem propriamente dita (e no suas bibliotecas). Para entender melhor essa definio, necessrio explicar melhor o conceito de ser decomposto. Algumas informaes so representadas por um grupo de outras informaes (as partes mais simples). Se o programador no tem acesso a essas partes mais simples, dizemos que o tipo de dados um tipo primitivo. Como os tipos de dados ainda no foram apresentados, vamos fazer uma analogia para dar um exemplo. Suponha que uma pessoa (talvez um aborgene no interior da Austrlia) observa um carro e no percebe que ele feito de vrias peas interligadas. Para ele uma lanterna quebrada pode ser motivo para trocar o carro, j que ele entende o carro como uma s entidade. Se o programador s pode ver numa informao a informao como um todo (por causa da linguagem de programao), essa informao de um tipo primitivo. O primeiro exemplo de um tipo de dados formado por partes mais simples o ponto flutuante, visto na seo 2.1.2.

2.1.1 Inteiros
Diferentes capacidades. Com ou sem sinal. Complemento de dois X Complemento de um. Complemento de dois requer circuito simples. Complemento de um permite duas representaes para o zero.

2.1.2 Ponto Flutuante


uma representao para nmeros racionais criada com o objetivo de manter a maior quantidade de bits significativos. Os bits que representam um ponto flutuante, so usados em trs partes independentes: sinal, mantissa e expoente.
prof. Bruno Schneider 2

Notas de Aula de GCC105 - BCC e BSI - UFLA

A norma IEEE 754 estabelece 23 bits de mantissa e 8 de expoente para preciso simples; 52 bits de mantissa e 11 bits de expoente para preciso dupla.

2.1.3 Decimais
Ponto fixo, til em aplicaes comerciais. Algumas mquinas tinham hardware prprio para esse tipo e representavam nmeros como strings de bits, desperdiando um pouco de espao. Hoje em dia, costuma-se usar emulao desse tipo no software.

2.1.4 Booleanos
Um nico bit no normalmente enderevel na memria. Tipos booleanos aumentam a legibilidade da linguagem (ver exemplo na seo de expresses booleanas). Algumas linguagens permitem que o valor de qualquer tipo seja testado.

2.1.5 Caracteres
Existem vrios sistemas de representao. Alguns usam tamanhos fixos e outros usam tamanhos variveis. Considerar UNICODE como um sistema de codificao de caracteres um erro comum. O prprio livro do Sebesta, afirma que o UNICODE um conjunto de caracteres de 16 bits, o que errado. Dizer que os caracteres so representados de acordo com a tabela ASCII outro.

2.1.6 Ponteiros
Proporcionam flexibilidade para outros tipos. Essa flexibilidade tem uma relao importante com o fato de que ponteiros podem apontar para lugar nenhum (ex.: nil em Pascal, null em Java). Esse valor especial quase sempre o nmero zero. Outro elemento importante a capacidade de representar informaes de uma forma segmentada (partes da informao ficam num lugar da memria e partes ficam em outro). Uma linguagem em que os tipos so na verdade ponteiros para os respectivos tipos, permite a representao de variveis que no tem valor.

2.1.7 Strings
Quando so tipos primitivos, strings costumam vir acompanhas de diversos operadores para comparar, extrair substring, concatenar, etc. Para manter o tamanho varivel num espao esttico de memria, preciso algum tipo de controle. FORTRAN usa strings sempre cheias. C usa o terminador zero. Pascal usa o tamanho no primeiro elemento do vetor (problemas de limite para o tamanho). Strings podem ser dinmicas. Por serem elementos compostos, as operaes podem ser complicadas (atribuir, comparar, etc.). As linguagens que fornecem formas de descrever padres de strings se destacam na criao de programas que precisam manipular texto. Destas, SNOBOL (em especial a verso 4) tem importncia especial por entender os padres como tipos de primeira classe (que podem ser manipulados como qualquer outro tipo primitivo). Das linguagens mais modernas, Perl, uma das
prof. Bruno Schneider 3

Notas de Aula de GCC105 - BCC e BSI - UFLA

mais lembradas por seus recursos de casamento de padres. Os padres so geralmente descritos por expresses chamadas de expresses regulares. Com frequncia, diz-se que SNOBOL e Perl tem nfase em processamento de strings por causa dessa poderosa forma de processar texto. Exemplo: teste em Perl para ver se uma string contm uma data:
if $linha =~ (0[1-9]|[12][0-9]|3[01]) / (0[1-9]|1[012]) / ([12][0-9]{3})

A representao interna pode usar listas ou vetores (dentre outras possibilidades menos populares), trazendo para a string as vantagens e desvantagens desses tipos. Algumas linguagens permitem interpolao de strings, o que facilita a construo de strings a partir de diversos valores de tipos diferentes. Strings tem um papel importante na segurana de computadores (buffer overflow).

2.1.8 Enumerados
Amentam a legibilidade do programa. Usa constantes simblicas para os valores possveis. Temos problemas se uma mesma constante aparece em mais de um tipo.

2.1.9 Subfaixas
Facilitam a deteco de erros de faixa/limite. Aumentam a legibilidade ao tornar explcitos limites de um tipo numrico. Erros podem ser detectados em tempo de compilao. Costumam herdar as operaes do tipo pai.

2.1.10 Vetores
Agregado homogneo de valores. Os valores ficam em posies consecutivas na memria. Algumas linguagens usam parnteses para os ndices, outras usam colchetes. Uso de parnteses deixa a sintaxe semelhante uma chamada de funo. Algumas linguagens permitem o uso de enumerados ou subfaixas como ndices. Algumas linguagens determinam o valor mnimo do ndice. Algumas linguagens no verificam os limites dos ndices. Alocao esttica ou dinmica.

2.1.11 Vetores associativos (hashes)


So estruturas chave-valor. Aumento da capacidade pode ser muito custoso. Podem ser implementados por rvores.

2.1.12 Registros
Agregado heterogneo. Elementos referenciados por nomes. A declarao de classes supre a necessidade dos registros.

prof. Bruno Schneider

Notas de Aula de GCC105 - BCC e BSI - UFLA

2.1.13 Unies (Registros variantes)


Podem ser um dentre vrios tipos diferentes. Trazem problemas para a verificao de tipos. Problemas podem ser mitigados usando marcas (tags) que identificam o tipo usado (ex.: Haskell).

2.1.14 Listas
uma estrutura de dados homognea e recursiva. Requer que a estrutura seja percorrida para acessar um valor. Por ser segmentada, aumenta e diminui com facilidade.

2.1.15 Conjuntos
Linguagens mais antigas podem ter limitaes severas com relao quantidade de elementos do conjunto. Fornecem apenas facilidade na implementao (ex.: verificar se uma letra uma vogal).

2.1.16 Tipo Unidade


Alguns tipos mais exticos podem aparecer no sistema de tipos de uma linguagem. O Tipo Unidade (unit type), por exemplo, um tipo que s pode representar um valor, necessitando de zero bytes de armazenamento. O tipo void em C, C++ e Java, pode funcionar como um Tipo Unidade.

2.1.17 Tipos numa linguagem


Responder quais so os tipos disponveis em uma linguagem de programao pode no ser uma tarefa to simples quanto parece. As linguagens frequentemente fornecem um conjunto bsico de tipos e a descrio desses tipos por vezes incompleta para uma implementao. Assim, os compiladores frequentemente proporcionam outros tipos alm do conjunto bsico. Tipos tambm podem ser definidos em bibliotecas de programao. Essas bibliotecas podem ser bibliotecas-padro ou bibliotecas de terceiros. Sistemas Operacionais costumam ser distribudos com bibliotecas para a linguagem C (com definio de tipos). As linguagens de alto nvel costumam se referir a tipos de um ponto de vista com alto nvel de abstrao, deixando detalhes de implementao (e consequentemente caractersticas relacionadas ao uso desses tipos) a critrio do compilador ou interpretador. Todos esses fatores influenciam a portabilidade de uma linguagem de programao.

2.2 Vinculaes
Programas lidam com informaes abstradas em variveis. O compilador/interpretador precisa ter controle da relao entre a abstrao que aparece no cdigo fonte e a entidade manipulada pelo hardware. Para isso, os vrios elementos de um programa (em especial as variveis), so associados aos seguintes atributos: nome (relacionado ao conceito de escopo), tipo, armazenamento (ou endereo - relacionado ao conceito de tempo de vida) e valor.
5

prof. Bruno Schneider

Notas de Aula de GCC105 - BCC e BSI - UFLA

Nem todos os atributos so definidos no mesmo momento. Nem todos precisam existir num momento qualquer. A associao de um atributo ao seu valor uma vinculao. As variveis aumentam a legibilidade dos programas (em relao endereos) e resolvem o problema dos endereos absolutos. Uma vinculao esttica se for se a mesma durante todo o tempo de execuo. Vinculao dinmica aquela que pode ser alterada durante a execuo. Vinculaes podem acontecer no tempo de: projeto da linguagem, implementao da linguagem, compilao, ligao, carregamento ou execuo.

2.2.1 Vinculao de Nomes


Alm das variveis, subprogramas, parmetros, instrues (pontos na sequncia de instrues de um programa), comandos e outros elementos podem receber nomes. Portanto, a vinculao de nomes no uma questo limitada s variveis. Nem toda varivel vinculada a um nome. comum que o compilador/interpretador crie variveis temporrias sem nome. comum que um programador crie variveis sem nome. Algumas linguagens limitam o tamanho permitido para os nomes. Compiladores tambm costumam impor limites. Algumas linguagens fazem distino entre maisculas e minsculas, o que geralmente considerado uma desvantagem, porm, pode incentivar o programador agregar informaes (como o tipo) ao nome da varivel. Alguns nomes so especiais numa linguagem de programao. Existem as palavras reservadas, cujo significado o mesmo em qualquer contexto e as palavras-chave, cujo significado especial em algum contexto. Muitas vezes, palavras especiais so apenas pr-definidas, podendo ser redefinidas pelo programador. Neste caso, a linguagem provavelmente exige uma biblioteca padro que includa automaticamente no programa, na qual o nome definido. Um mesmo nome pode estar associado a diferentes entidades (ex.: variveis locais com mesmo nome em dois subprogramas). Nomes diferentes podem estar associados mesma entidade. Neste caso, chamamos esses nomes de apelidos (aliases). Apelidos podem ser criados de forma implcita (ex.: registros variantes) ou explcita, como ocorre por exemplo, pelo uso de ponteiros. Para reduzir os problemas da sobreposio de nomes, algumas linguagens usam espaos de nomes (namespaces em C++, PHP e Python; packages em Perl). Para uma instruo em particular, um nome deve estar vinculado uma nica entidade. Para lidar com isso, as linguagens de programao definem regras que levam ao conceito de escopo.

2.2.2 Escopo
O escopo de uma varivel o trecho de cdigo no qual seu nome pode ser usado, ou melhor, existe um nome vinculado ela. Nos idos de 1960 era muito comum que qualquer instruo de um programa pudesse fazer uso de qualquer varivel do programa. Essa uma viso bem prxima ao conceito de varivel do ponto de
prof. Bruno Schneider 6

Notas de Aula de GCC105 - BCC e BSI - UFLA

vista do hardware: os registradores disponveis a qualquer hora. Entretanto, isso mostrou-se um problema, j que as variveis mudavam de valor e ficava difcil entender o motivo. As linguagens passaram ento a fornecer formas de declarar variveis ao longo do programa, de maneira que seu nomes seriam vlidos somente em algumas instrues. Surge ento o problema da declarao de variveis diferentes com o mesmo nome. Para que um nome esteja vinculado uma nica entidade (varivel ou subprograma), numa dada instruo, comum que as linguagens de programao determinem que uma vinculao de um nome uma entidade, invalida as vinculaes anteriores para uma determinada parte do programa. Neste caso, dizemos que uma vinculao oculta a outra, num sistema de controle que lembra uma pilha. Isto leva ao conceito informal de que "o nome que vale o da declarao mais interna". O problema com essa afirmao que o conceito de "interno" bastante flexvel. Ainda assim, nem sempre uma vinculao de nome oculta as vinculaes anteriores. Dependendo do conceito de "interno" na linguagem de programao, a nova vinculao pode simplesmente ser um erro. Os namespaces so uma forma de manter os vrios nomes disponveis. Esse sistema nos leva ao conceito de varivel local (aquela cujo nome foi declarado no prprio bloco de cdigo em questo) e varivel externa (aquela cujo nome foi declarado fora do bloco em questo). O conceito de local/externo sempre relativo algo. Uma varivel pode ser local a um bloco ao mesmo tempo que externa a outro. O conceito de varivel global deve ser evitado, visto que um conceito absoluto e frequentemente mal usado. Por exemplo: variveis cujo escopo se estende por um arquivo inteiro so frequentemente chamadas de globais, quando na verdade esto fora de escopo em outros arquivos do mesmo programa. A alterao de uma varivel externa chamada de efeito colateral. Efeitos colaterais so perigosos e devem ser evitados sempre que possvel. O conjunto de nomes que podem ser usados numa determinada instruo chamado de ambiente de referenciamento da instruo. desejvel restringir tanto quanto possvel o escopo das variveis e procedimentos, para que no haja mltiplos nomes disponveis um bloco de cdigo sem necessidade. Esse conceito frequentemente chamado de diretriz do escopo mnimo. Para minimizar o escopo das variveis, o mnimo que um programador deve fazer evitar o uso de variveis externas. Algumas linguagens (como C++) se destacam ao oferecer recursos prprios para ajudar nessa minimizao: a possibilidade de declarar variveis em qualquer posio do cdigo, atrasando o incio de seu escopo e a possibilidade de usar instrues compostas (ver 2.4.1) em qualquer lugar do cdigo, adiantando o final do escopo para algumas variveis.

Muito da filosofia por trs de uma linguagem de programao se reflete na forma como ela gerencia os nomes das variveis, operadores e subprogramas. As linguagens variam muito nesse aspecto, passando de casos extremamente simples como C++ a casos extremamente complicados como Perl.

2.2.2.1 Escopo Esttico


No escopo esttico, a estrutura textual do programa que determina o escopo (determina o conceito de "interno"). As variveis declaradas num bloco podem ser usadas em seus sub-blocos desde que no haja uma nova vinculao daquele mesmo nome.
prof. Bruno Schneider 7

Notas de Aula de GCC105 - BCC e BSI - UFLA

2.2.2.2 Escopo Dinmico


No escopo dinmico, a ativao dos subprogramas que determina a escopo. As variveis do subprograma chamador so visveis na execuo do subprograma chamado, desde que no haja uma nova vinculao daquele mesmo nome. O escopo dinmico torna programas menos legveis pois o ambiente de referenciamento muda em tempo de execuo, mais lentos pois exige que a resoluo dos nomes seja feita em tempo de execuo e impossibilita a verificao de tipo, em tempo de compilao, para variveis no locais. Por outro lado, pode ser usado como forma de passagem flexvel de informaes para subprogramas. O custo dessa flexibilidade alto em funo das desvantagens j mencionadas e tambm porque funciona como um incentivo ao uso de variveis externas em oposio aos parmetros. A implementao de um compilador para uma linguagem com escopo dinmico costuma ser mais simples do que a implementao para escopo esttico. As primeiras linguagens usavam escopo dinmico, at que surgiu ALGOL que usava escopo esttico. Desde ento, quase todas as linguagens desenvolvidas usam escopo esttico, e as que j existiam (como LISP) foram modificadas ou substitudas por dialetos em que se usava escopo esttico. Das linguagens modernas e populares, podemos citar LOGO como um exemplo de linguagem com escopo dinmico e Perl, que comeou usando escopo dinmico, mas a partir da verso 5 permite que o programador escolha o tipo de escopo para cada varivel, efetivamente misturando as duas formas numa mesma linguagem.

2.2.3 Vinculao de tipos


Pode ser explcita ou implcita. Pode ser esttica ou dinmica. A vinculao dinmica de tipos implica em vinculao implcita, j que no faz sentido declarar tipos que sero vinculados somente durante uma operao de atribuio. Com a vinculao dinmica de tipos, comum que o tipo de uma varivel possa ser alterado a qualquer hora, em tempo de execuo, o que torna invivel a deteco de erros de tipo em tempo de compilao. Esse problema pode ser amenizado exigindo caracteres especiais que indicam tipos (como em Perl). Algumas linguagens tem vinculao esttica de tipos, mas fazem coero automtica (em muitos casos), gerando problemas parecidos de deteco de erros (ex.: C). A vinculao dinmica facilita a criao do compilador, que no precisa conhecer o tipo de uma varivel durante o seu uso, ela mais comum nas linguagens interpretadas, nas linguagens antigas e nas linguagens para web. Ela tem a vantagem de proporcionar um tipo de polimorfismo. Compiladores simples ainda so importantes em situaes como programas para web. A vinculao esttica proporciona maior velocidade de execuo por dois motivos: (a) no preciso gerar cdigo para sistema de tipos, pois o compilador j verificou a validade de todas as operaes e j determinou quais so as operaes usadas (ver sobrecarga de operadores) e (b) as informaes sobre os tipos permitem ao compilador fazer otimizaes no cdigo gerado.

2.2.3.1 Inferncia de Tipo


A partir de tipos de parmetros e/ou operadores, possvel inferir tipos automaticamente, permitindo a vinculao esttica sem a necessidade de declaraes. Linguagens com inferncia de tipos combinam a vinculao esttica de tipos com a implcita, proporcionando a checagem de erros de tipo em tempo de compilao com a facilidade de no
prof. Bruno Schneider 8

Notas de Aula de GCC105 - BCC e BSI - UFLA

exigir a declarao de tipos. Por outro lado, declaraes de tipo so uma forma de documentao, us-las mesmo quando no so necessrias pode melhorar a legibilidade de um programa. A inferncia de tipos nem sempre funciona, ou seja, nem sempre possvel determinar o tipo das variveis pelo seu uso, o que faz com que as linguagens que usam esse recurso ofeream formas de declarar tipos, permitindo que o programador resolva esses casos especiais.

2.2.3.2 Verificao de tipos


Deve-se verificar se os operadores (ou sub-rotinas) e seus operandos fazem sentido juntos. Os tipos devem ser compatveis1 ou deve existir alguma regra que permita que seja feita coero de tipos. Pode ser esttica (em tempo de compilao) ou dinmica (tempo de execuo). A forma dinmica exige que se mantenha informao sobre os tipos em tempo de execuo. Existe uma tendncia a se preferir que haja verificao de tipos e que ela seja feita em tempo de compilao (perda de flexibilidade para o programador). Uma linguagem que permite ao compilador/interpretador detectar qualquer erro de tipos dita uma linguagem com tipificao forte. Na prtica, sempre existe algum erro de tipo que no pode ser verificado, porm existem linguagens com tipificao notadamente mais forte do que outras. Essas linguagens so tidas como mais confiveis. Alm da vinculao dinmica de tipos, a existncia de muitas regras para coero automtica de tipos tambm reduz a capacidade de verificao de erros de tipo, levando ao que chamamos de linguagem com tipificao fraca. A linguagem C, por exemplo, apesar da vinculao esttica de tipos, considerada uma linguagem com tipificao fraca. A forma como uma linguagem lida com a verificao de tipos frequentemente chamada de o sistema de tipos (ver 2.8) da linguagem. Ela de extrema importncia pois os erros de tipos so fortes indcios de outros erros.

2.2.3.3 Compatibilidade de Tipos


Alguns tipos deveriam ser passveis de serem usados em lugar de outros sem que haja necessidade de coero. Isso pode feito de duas formas: compatibilidade de nome: duas variveis tem o mesmo tipo se esto na mesma declarao ou so declaradas com tipos de mesmo nome. compatibilidade de estrutura: duas variveis tem o mesmo tipo se tm estruturas idnticas.

A primeira forma muito restritiva e com frequncia diferencia tipos que o programador no queria diferenciar. Exige que tipos sejam declarados globalmente, podendo causar problemas com bibliotecas. A segunda forma traz problemas de indireo pois tipos podem ser formados de outros tipos e podem ser recursivos. Ela torna impossvel a diferenciao de tipos com a mesma estrutura (o que pode ser desejvel)
1 Na verso traduzida do livro texto, onde se define o que a verificao de tipos, l-se que um tipo que seja convertido automaticamente compatvel. Isso causa algum conflito com a definio da compatibilidade de tipos (ver 2.2.3.3) e provavelmente dificulta a fixao desse segundo conceito. Por isso, a definio de verificao de tipos aparece aqui ligeiramente diferente. prof. Bruno Schneider 9

Notas de Aula de GCC105 - BCC e BSI - UFLA

Na prtica as linguagens usam uma mistura dos dois tipos pois nenhum dos dois produz os resultados tidos como desejveis em alguns casos. Na orientao a objetos a compatibilidade de tipos est fortemente ligada ao conceito de herana.

2.2.4 Vinculao de Armazenamento (tempo de vida)


O tempo de vida de uma varivel o tempo durante o qual ela est vinculada uma clula de armazenamento (um endereo). Em funo do tempo de vida, uma varivel pode ser classificada como: esttica: a vinculao existe durante toda a execuo do programa e no muda; tem endereamento direto (mais rpido); no existe overhead para alocar e desalocar; permitem criar variveis sensveis histria; podem ser um desperdcio de espao se no forem usadas ao longo de toda a execuo; podem conflitar com a recursividade. stack-dinmica: a vinculao criada quando a execuo atinge a declarao da varivel e deixa de existir quando o bloco de cdigo termina sua execuo; as vinculao de tipo so estticas; funciona como uma forma de compartilhar memria entre os vrios subprogramas. heap-dinmica explcita: so criadas (sem nome) por operadores e funes de alocao de memria e so acessadas por meio de referncias; tem vinculao esttica de tipo; apresentam o overhead do acesso indireto. Ex.: objetos em Java. heap-dinmica implcita: so vinculadas ao armazenamento e ao tipo durante uma atribuio; so muito flexveis; reduzem a capacidade do compilador de encontrar erros.

O gerenciamento do heap pode ser feito por algoritmos de garbage collection. O tempo de vida de uma varivel geralmente tempo de execuo de um bloco. Vrias linguagens oferecem formas de vinculao esttica ao armazenamento, o que permite a criao de um tipo de memria em subprogramas. Nem sempre uma varivel vinculada a um armazenamento acessvel, o que desejvel, seguindo o princpio do escopo mnimo. Vinculao dinmica ao armazenamento uma propriedade que conflita com instrues tipo goto.

2.2.5 Inicializao
Inicializao a vinculao ao valor no momento da vinculao ao armazenamento. Variveis estticas em termos de armazenamento precisam ser vinculadas a um valor antes da execuo. Nesse caso, pode no ser possvel usar uma expresso para a inicializao. Nem toda linguagem oferece recursos de inicializao (ex.: Pascal).

2.3 Avaliao de expresses


Uma linguagem deveria determinar precedncia de operadores, regras para no coincidncia de tipos e para avaliao em curto-circuito.

2.3.1 Expresses aritmticas


Consistem em operadores, operandos, parnteses e funes. Operadores podem lidar com um ou
prof. Bruno Schneider 10

Notas de Aula de GCC105 - BCC e BSI - UFLA

mais operandos e podem ser sobrecarregados em algumas linguagens. Quase sempre as linguagens usam parnteses para fazer associao explcita.

2.3.1.1 Ordem de avaliao de operadores


parcialmente determinada pela precedncia dos operadores e parcialmente pela associatividade na expresso; seguindo os conceitos da matemtica. Um operador pode ter associatividade direita (ex.: x = z = 1;) ou esquerda ( esquerda mais comum). Um operador pode ser no associativo, exigindo a presena de parnteses. Quando os operadores so de mesma precedncia, a associatividade esquerda diz que o operador da esquerda Por serem aproximaes das expresses matemticas, os limites dos tipos podem tornar uma expresso no-associativa (ex.: soma com nmeros muito grades e muito pequenos). As linguagens C, C++ e Java oferecem um operador condicional ternrio (?:). Algumas ordem podem ser mais rpidas que outras, pode ser interessante deixar que o compilador escolha a ordem.

2.3.1.2 Ordem de avaliao dos operandos


A ordem de avaliao dos operandos pode influenciar o resultado (ex.: funes com efeitos colaterais). Algumas ordens de avaliao podem ser mais rpidas que outras. Algumas linguagens deixam a ordem a critrio do compilador e existem que o programador se preocupe em evitar os casos em que a ordem importante (ex.: Pascal e Ada) enquanto outras determinam uma ordem (ex.: Java).

2.3.2 Sobrecarga de Operadores


A sobrecarga, no contexto de linguagens de programao, a capacidade de fazer com que um nico identificador seja usado denotar vrias abstraes. Usar o mesmo operador para representar funes completamente diferentes prejudica a legibilidade. Erros de digitao ficam mais difceis de serem detectados. Algumas linguagens (notadamente as que permitem tipos abstratos) permitem que o programador sobrecarregue operadores. Quando bem usado, esse recurso pode aumentar a legibilidade. Se diversas bibliotecas sobrecarregarem os mesmos operadores, podem surgir conflitos.

2.3.3 Converses de tipo


Podem ser de estreitamento (inseguras) ou alargamento (o novo tipo inclui aproximaes para todos os valores do tipo original). Os nomes alargamento e estreitamento no tm relao com o espao ocupado em memria pelos tipos envolvidos. A definio dessa classificao no precisa, assim, nem sempre conveniente classificar determinada converso em uma dessas categorias. Podem ser explcitas ou implcitas. s vezes, o termo coero usado somente para as converses implcitas. O autor deste texto usa a palavra coero como sinnimo de converso. A maioria das linguagens oferece instrues para converso de tipos, que podem ser apresentadas
prof. Bruno Schneider 11

Notas de Aula de GCC105 - BCC e BSI - UFLA

como elementos sintticos da linguagem ou na forma de funes.

2.3.3.1 Coero em expresses


Se uma linguagem permite expresses aritmticas com operadores que usam operandos de tipos diferentes (expresses de modo misto), devem definir converses implcitas. Em muitas linguagens as converses implcitas de estreitamento causam a emisso de avisos por parte do compilador. No existe um consenso a respeito do que melhor: restringir a flexibilidade das expresses ou deixar a verificao de tipos sob a responsabilidade do programador. As coeres de subfaixas de inteiros para inteiros, ou de inteiros pequenos para inteiros so muito comuns. Coeres mais profundas como a converso de strings em valores numricos so mais comuns em linguagens com vinculao dinmica de tipos.

2.3.4 Operadores relacionais e expresses booleanas


Linguagens oferecem operadores relacionais para construir expresses booleanas. Operadores relacionais retornam um valor do tipo booleano (se ele for um tipo da linguagem). Operadores relacionais costumam estar disponveis para tipos numricos, strings e ordinais (enumerados e subfaixas). Expresses booleanas so aquelas que retornam um tipo booleano (o operador mais externo relacional). Um efeito interessante da falta do tipo booleano na linguagem C validade da expresso (a > b > c) que no tem o mesmo significado que se espera pela notao matemtica.

2.3.5 Avaliao em curto-circuito


Muitas vezes, para se determinar o valor de uma expresso, no preciso avaliar todos os operadores dela. Quando a avaliao de expresses feita levando em conta esses casos especiais, ela dita uma avaliao em curto-circuito. A avaliao em curto-circuito incomum para expresses aritmticas, mas comum para expresses booleanas. Na avaliao em curto-circuito, funes que mudam o estado de algo e retornam valor podem no ser chamadas, no causando qualquer mudana de estado. Por outro lado, nas avaliaes em circuito longo, operaes ilegais podem ser executadas caso o programador esperasse ver apenas uma parte da expresso processada. Algumas linguagens tem operadores especficos para os dois tipos de avaliao (ex.: and then/or eles de Ada). Usar operadores lgicos bit a bit pode prover flexibilidade (ex.: & e | no C, C++ e Java).

2.3.6 Operador de atribuio


A atribuio a instruo que realiza cpia de valores de um armazenamento para outro. uma das caractersticas bsicas da programao imperativa pois possibilita a alterao do estado de um
prof. Bruno Schneider 12

Notas de Aula de GCC105 - BCC e BSI - UFLA

processamento. Uma atribuio envolve dois elementos: uma expresso cujo valor pode ser encontrado, chamada de right value (valor direito) j que costuma aparecer do lado direito da atribuio nas vrias regras de sintaxe e uma expresso cujo armazenamento pode ser encontrado, chamada de left value (valor esquerdo). Frequentemente as linguagens tm regras sintticas que impedem elementos como constantes (literais ou no) e expresses aritmticas (variveis temporrias) de serem usadas onde se espera um left value.

2.3.6.1 Atribuio simples


a forma tradicional, em que uma varivel recebe o valor de uma expresso. O operador pode retornar algo ou no.

2.3.6.2 Alvos mltiplos


Vrias variveis recebem o valor de uma expresso. Esse efeito pode ser imitado pelos operadores que retornam referncias.

2.3.6.3 Alvos condicionais


Usando o operador ternrio ?:, C++ e Java permitem alvos condicionais.

2.3.6.4 Atribuio composta


a atribuio usando expresses em que a varivel modificada faz parte da expresso (ex.: += em C, C++ e Java).

2.3.6.5 Operador unrio de atribuio


Incrementam e decrementam, como nas linguagens C, C++ e Java.

2.3.6.6 Atribuio como funo


O operador de atribuio pode retornar valor como em C, C++ e Java. Facilitam a atribuies seguidas de teste. Permitem imitar os alvos mltiplos. Reduzem a legibilidade e, na falta do tipo booleano, reduzem a capacidade do compilador para detectar erros. Java no tem o problema das atribuies no meio de expresses (de C e C++) porque tem o tipo booleano e o uso de nmero em lugar de booleanos causa erros de tipo.

2.3.7 Atribuio de modo misto


As linguagens podem permitir atribuio do valor de um tipo uma varivel de outro tipo. Pode-se usar coero.

prof. Bruno Schneider

13

Notas de Aula de GCC105 - BCC e BSI - UFLA

2.4 Controle de fluxo


O controle de fluxo a determinao da ordem de execuo das instrues de um programa. As regras de precedncia e associatividade de operadores, vistas na seo 2.3.1, so uma forma de controle de fluxo. As linguagens tambm precisam prover formas de controlar o fluxo entre os vrios blocos de programa. O controle de fluxo to fundamental nos programas imperativos quanto a atribuio. Mecanismos de seleo de instrues permitem produzir repeties ou escolher entre vrias formas de computar um valor. Duas formas de controle (o desvio condicional/incondicional) so necessrias. Duas formas so recomendadas: o desvio condicional e a repetio com teste no incio. As linguagens proporcionam mais formas, porm no muitas, para que no fiquem complicadas demais. As instrues de controle devem ter entrada nica e sada nica. As entradas mltiplas so perigosas enquanto que as sadas mltiplas apenas reduzem a legibilidade.

2.4.1 Instrues compostas


So blocos de instrues tratados como se fossem uma nica instruo. Eliminam a necessidade de instrues delimitadas e so especialmente interessantes para as estruturas de controle de fluxo. Tambm auxiliam a manter uma lgica positiva, que destaca os casos especiais. Algumas linguagens exigem que instrues compostas apaream em determinados contextos. Quase sempre, as instrues compostas so demarcas por algum elemento sinttico (ex.: begin/end), porm algumas linguagens modernas usam a endentao para demarcao.

2.4.2 Instrues de seleo


Permitem escolher caminhos de execuo. Do ponto de vista do hardware, geralmente existem dois tipos de instruo de controle de fluxo: desvio condicional e incondicional. Esses dois elementos podem ser combinados em instrues de seleo mais abstratas. As linguagens procuram esconder o desvio incondicional do programador, oferecendo seletores.

2.4.2.1 Seleo unidirecional e bidirecional


O seletor unidirecional if (teste) instruo uma abstrao quase direta do desvio condicional do hardware. Para desincentivar o uso de desvio incondicional, as linguagens oferecem instrues compostas ou algum tipo de marcador para o final das instrues. O seletor bidirecional if (teste) then instruo else instruo o principal seletor em todas as linguagens. Geralmente o seletor unidirecional incorpora algum elemento sinttico (como o then) de forma a se tornar uma verso especial do seletor bidirecional. O teste quase sempre uma expresso booleana.

prof. Bruno Schneider

14

Notas de Aula de GCC105 - BCC e BSI - UFLA

2.4.2.2 Seletores aninhados


Quando uma instruo de seleo pode ser aninhada em outra, podemos ter ambiguidade. Essa ambiguidade pode ser resolvida por: uma regra da linguagem (ex.: Pascal/C++ - o else sempre vinculado ao if mais recente); sintaxe da linguagem (ex.: Algol60 - o if no pode ser usado como instruo de outro if, exceto se estiver numa instruo composta); endentao (nas linguagens em que a endentao determina as instrues compostas - ex.: Python).

Algumas linguagens usam sequncias de instrues (em oposio a instrues compostas) nos seletores, o que exige um marcador de final e elimina a ambiguidade.

2.4.2.3 Seleo mltipla


Alguns seletores permitem escolher dentre qualquer quantidade de instrues (ex.: case/switch). Questes de projeto: Qual o tipo da expresso de seleo? Que tipo de instrues podem ser usadas (sequncias, instrues compostas, etc.)? Somente um segmento pode ser executado? O que fazer se o valor da expresso no foi representado?

Em muitas linguagens, a seleo mltipla requer nmeros inteiros, algumas permitem qualquer tipo discreto. Nem sempre a seleo mltipla por valores discretos adequada. Vrias linguagens oferecem a possibilidade de aninhar testes nos seletores bidirecionais (elseif/elsif/elif), tornando-os seletores mltiplos que no sofrem da falta de legibilidade do aninhamento profundo de seletores bidirecionais. Esse tipo de estrutura mais genrica que a anterior (case/switch).

2.4.3 Instrues iterativas


So instrues que proporcionam repetio da execuo de um bloco (lao).

2.4.3.1 Laos controlados por contador


So interessantes nos casos em que se conhece o nmero de repeties desejadas, em especial, para processamento de vetores. So parametrizados por valor inicial, valor final e passo. As linguagens variam muito a respeito dos laos controlados por contador. As questes de projeto so: o tipo da varivel de controle; o escopo da varivel de controle; o valor da varivel ao final do lao (ltima atribuio / indefinido);
15

prof. Bruno Schneider

Notas de Aula de GCC105 - BCC e BSI - UFLA

a validade de alterar os parmetros e, caso seja vlido, o efeito da alterao; a avaliao nica dos parmetros ou a cada iterao.

Algumas formas so muito flexveis e complicadas (C / Algol60) permitindo inclusive a mistura entre o controle numrico e lgico.

2.4.3.2 Laos controlados por lgica


A repetio controlada por uma expresso booleana. So mais genricos que os controlados por contador. Podem realizar o teste antes ou depois do lao.

2.4.3.3 Controle localizado pelo usurio


Para aumentar a flexibilidade dos laos, comum encontrar mecanismos de controle que podem ser colocados em qualquer instruo interna ao lao. Essas instrues so comuns para tratamento de situaes especiais, e podem aumentar a velocidade do cdigo ao custo de legibilidade. Algumas linguagens oferecem estruturas de lao sem controle (loop infinito) ou determinam que o controle opcional. As estruturas de controle envolvem sada prematura do lao (talvez de um lao mais externo) e volta prematura ao teste de controle (talvez de um lao mais externo).

2.4.3.4 Controle por estruturas de dados


Pode ser interessante fazer uma repetio para cada elemento de um conjunto ou para cada parte de uma estrutura de dados. Neste tipo de iterao, um elemento sinttico proporciona a repetio para todos os elementos de uma coleo (ex.: o comando for em Java, a partir da verso 5). A forma usada para percorrer a estrutura de dados fica abstrada. A iterao controlada por estrutura de dados costuma ser imitada usando-se iteradores num lao controlado por lgica. Neste caso a forma usada para percorrer a estrutura de dados costuma estar definida em outra parte do cdigo, proporcionando alguma abstrao desse processo. O comando for da linguagem C++ (que um lao controlado por lgica) frequentemente usado para proporcionar esse efeito, j que a linguagem no oferece iteraes controladas por estruturas de dados.

2.4.4 Desvio incondicional


O desvio incondicional, usualmente chamado de goto foi assunto de muito debate quando as bases da programao estruturada estavam sendo formadas. Eles so perigosos e eram na poca o principal fator a afetar negativamente a legibilidade dos programas. Ainda assim, sua utilidade enorme o que motivou tantos debates. Hoje em dia, a maioria das linguagens de programao ainda oferece essa instruo, porm juntamente com estruturas de controle que desincentivam ou limitam o seu uso. Linguagens que apareceram a partir da dcada de 90 como Java, j comearam a abandonar a instruo.

prof. Bruno Schneider

16

Notas de Aula de GCC105 - BCC e BSI - UFLA

Essa instruo ainda parte fundamental do conjunto de instrues de qualquer processador e usada pelos compiladores para produzir as instrues de controle de fluxo (alto nvel) das linguagens de programao em geral (seletores e laos). A tendncia que seja eliminada apenas dos cdigos de alto nvel de abstrao. O desvio incondicional funciona em conjunto com rtulos, que so identificadores (s vezes numricos) para instrues de um programa. Para reduzir os problemas relacionados com o desvio incondicional, as linguagens proporcionam formas limitadas de uso desse comando. Frequentemente as limitaes incluem desviar somente para frente e mesmo assim, somente para o comando imediatamente aps um bloco. Nessa forma, o comando no diz para onde o fluxo de instrues ser desviado, evitando abusos por parte do programador. Exemplos comuns so o break para sair de laos e o return para sair de subprogramas. Algumas linguagens procuram desincentivar at mesmo essa forma limitada de desvio. Por exemplo, em Pascal e em Python, existe uma varivel especial para definir o valor que uma funo retorna (em oposio a algo tipo return), dificultando a criao de sadas mltiplas.

2.4.5 Comandos protegidos


Uma outra forma de seleo muito diferente e incomum so os comandos protegidos, que tem a seguinte forma original: if <expresso booleana> <instruo> [] <expresso booleana> <instruo> [] ... fi A instruo executada escolhida de forma no determinstica dentre as demarcadas por expresses verdadeiras. uma construo interessante para programao concorrente.

2.5 Subprogramas
So essenciais para a abstrao de um programa, permitindo que processos completos possam ser abstrados numa entidade nica e reusados em vrios contextos. Ajudam a ressaltar a estrutura geral de um programa. desejvel permitir a compilao de subprogramas para criao de bibliotecas (tambm chamadas de pacotes).

2.5.1 Fundamentos dos subprogramas


2.5.1.1 Caractersticas gerais
Subprogramas (exceto as co-rotinas), tem as seguintes caractersticas: um nico ponto de entrada; o incio da execuo suspende a execuo da unidade chamadora; o trmino da execuo faz a execuo da unidade chamadora continuar.

prof. Bruno Schneider

17

Notas de Aula de GCC105 - BCC e BSI - UFLA

2.5.1.2 Definies bsicas


Uma definio de subprograma descreve a interface (forma para trocar informaes com o chamador) e o processo (aes). Tambm chamado de implementao. Uma chamada a subprograma a solicitao para executar o processo. Um subprograma est ativo se a sua execuo comeou mas ainda no terminou. Uma declarao de subprograma (tambm chamada de cabealho, declarao avanada ou prottipo) identifica um bloco como sendo um subprograma (geralmente por meio de uma palavra especial) de um determinado tipo (ex.: procedimento/funo), d um nome para ele e (com exceo de algumas poucas linguagens) identifica seus parmetros. Pode vir separada da definio, para fins de verificao esttica de tipos. Os parmetros, quando vistos como instncias de valores ou no ponto de vista da unidade chamadora, so chamados argumentos. Tambm podem ser chamados, respectivamente, de parmetros formais e parmetros reais. O perfil de parmetro o nmero, a ordem e os tipos dos parmetros. O protocolo de um subprograma o perfil de parmetros mais o tipo de retorno se o subprograma for uma funo. Pode ser visto como o tipo do subprograma.

2.5.1.3 Parmetros
So uma forma de fornecer os dados para o processamento de um subprograma. Deixam o subprograma mais legvel que o uso de variveis externas. O escopo reduzido ajuda a evitar erros. Eles tambm so usados para receber dados resultantes do processamento dos subprogramas. Parmetros podem ser dados ou subprogramas. A vinculao entre parmetros reais e formais por ser feita pela posio ou pelo nome. Em algumas linguagens pode-se usar a duas formas ao mesmo tempo (ex.: Ada e Python). Nem sempre obrigatrio usar todos os parmetros. Nesse caso preciso existir alguma regra a respeito daqueles no vinculados. Nem sempre preciso definir um nmero fixo de parmetros. Nesses casos, parmetros so geralmente vistos como elementos de um vetor ou lista. So geralmente variveis stack-dinmicas.

2.5.1.4 Procedimentos e Funes


Procedimentos produzem resultados alterando estados de variveis externas no programa (efeitos colaterais) j que no retornam valor. As variveis no so necessariamente visveis no programa. Por exemplo: o procedimento write do Pascal altera o estado da sada padro, por isso podemos dizer que sua execuo altera variveis externas apesar disso no ficar muito visvel no programa. Sabemos que essas variveis so externas ao write pois outros procedimentos tm acesso sada padro. Funes so modelos das funes matemticas mas que, ao contrrio delas, podem apresentar efeitos colaterais. So substitudas por um valor (ver 2.5.3.2) e geralmente usadas dentro de expresses. Podem ser entendidas como operadores.

prof. Bruno Schneider

18

Notas de Aula de GCC105 - BCC e BSI - UFLA

As funes so mais genricas que os procedimentos j que podem fazer tudo o que eles fazem e ainda retornar um valor. Apesar disso, algumas linguagens reduzem ou limitam completamente (no caso de linguagens no procedurais) a possibilidade de criao de efeitos colaterais numa funo, aproximado-as das funes matemticas e tornando-as distintas dos procedimentos. Em algumas linguagens (como C, C++ e Java) no existem procedimentos e as funes no precisam fazer parte de uma expresso.

2.5.2 Ambientes de referncia locais


Subprogramas so peas importantes do controle de escopo, indicando limites para a vinculao de nomes. Geralmente as variveis locais so stack-dinmicas. Para permitir maior velocidade, algumas linguagens ainda usam a vinculao esttica ao armazenamento, usando variveis stack-dinmicas somente nos subprogramas recursivos. Em algumas linguagens necessrio declarar explicitamente quando um programa recursivo.

2.5.3 Mtodos de passagem de parmetros


Os parmetros so uma forma boa de transmitir dados para dentro e para fora de um subprograma. Os parmetros formais podem ser usados para (a) receber dados dos parmetros reais, (b) transmitir dados para os parmetros reais ou (c) ambos. Esses trs modelos so conhecidos por (a) modo entrada, (b) modo sada ou (c) modo entrada/sada.

2.5.3.1 Passagem por valor


O valor do parmetro real usado na inicializao do parmetro formal. Esse, por sua vez, funciona como uma varivel local. Implementa o modo entrada. um mtodo seguro, mas requer tempo e armazenamento extra para a cpia. A passagem de ponteiros por valor pode ser confundida com a passagem por referncia quando o valor de uma varivel uma referncia (ex.: ponteiros). Nesse caso, a passagem por valor pode causar o mesmo efeito de uma passagem por referncia (alterao do valor do parmetro real). Na linguagem Java, em que as variveis podem ser referncias, sem que isso fique explcito para o programador, essa confuso maior. A passagem por valor deve ser preferida pelo programador nos casos em que se deseja o modo de entrada e que a quantidade de informaes passadas pequena. O livro texto usa as expresses "mudana fsica" e "transferncia fsica" na explicao desta implementao de passagem de parmetros. Esses termos no foram definidos e costumam induzir uma ideia inapropriada do processo de transferncia de valores; eles devem ser evitados.

2.5.3.2 Passagem por resultado


O parmetro funciona como uma varivel local, cujo valor copiado para o parmetro real ao final do subprograma. Implementa o modo sada. O parmetro real deve ser apropriado ao recebimento de valores, ou seja, deve estar associado a um left value. Pode causar problemas na ocorrncia de coliso entre parmetros reais (um nico parmetro real
prof. Bruno Schneider 19

Notas de Aula de GCC105 - BCC e BSI - UFLA

vinculado a dois ou mais parmetros formais). Pode causar semntica ambgua em funo do momento em que se determina o endereo de retorno. Assim como a passagem por valor, exige mais tempo e armazenamento. Os compiladores costumam usar este mtodo para retornar o valor de funo. Esse retorno um parmetro especial, no sentido de que ele no aparece junto dos outros parmetros e o parmetro real no vinculado a um nome. Isso ajuda na reduo dos problemas do mtodo.

2.5.3.3 Passagem por valor-resultado


a cpia do valor para um armazenamento separado durante chamada e durante o encerramento do subprograma. uma implementao do modo entrada/sada. Tem as desvantagens da passagem por valor e as da passagem por resultado.

2.5.3.4 Passagem por referncia


Transfere uma referncia (geralmente um endereo) ao invs do valor, de forma que o parmetro formal passa a ser um apelido (alias) do parmetro real. uma implementao do modo entrada/sada. Essa forma de passagem de parmetros tida como rpida porque uma referncia uma quantidade pequena de informao e tem sempre o mesmo tamanho, independentemente do tamanho do valor a que se refere. Entretanto, possvel que o tempo e espao necessrios para passagem de uma referncia sejam iguais ou maiores que os necessrios para a cpia de um valor. Assim, a passagem por referncia de grandes quantidades de informao mais rpida que a passagem por valor, o que torna este mtodo vantajoso mesmo em situaes nas quais o programador deseja o modo de entrada. A passagem por referncia cria efeitos colaterais e por isso deve ser evitada quando se deseja apenas o modo entrada de pouca informao. Da mesma forma que a passagem por resultado, pode causar problemas na ocorrncia de coliso de parmetros reais. Pode criar apelidos (aliases) que dificultam a leitura do cdigo (ex.: o parmetro pode ser um alias para uma varivel global). Apesar de ser bastante comum, costuma no ser oferecida por linguagens que escondem o gerenciamento de memria do programador (ex.: Java). Algumas linguagens permitem a passagem por referncia constante, na qual o parmetro formal tratado como constante, mesclando as vantagens deste mtodo com a segurana do modo de entrada (ex.: C++). Nas linguagem sem esse recurso, a passagem de uma constante por referncia no deve ser permitida pelo compilador, pois poderia permitir a alterao do valor de uma constante. Na linguagem C++ permitido dizer que o valor de retorno de uma funo passado por referncia.

2.5.3.5 Passagem por nome


A passagem por nome muito diferente das outras formas. Nela, o parmetro formal textualmente substitudo pelo parmetro real. Isso pode ser implementado de vrias formas, com semnticas diferentes. Por exemplo, se o parmetro real for uma expresso constante, pode-se usar uma implementao
prof. Bruno Schneider 20

Notas de Aula de GCC105 - BCC e BSI - UFLA

como a da passagem por valor (semntica de entrada). Se for uma varivel, pode-se usar uma implementao como a passagem por referncia (semntica de entrada/sada).

2.5.4 Parmetros que so nomes de subprogramas


Muitas vezes, desejvel passar um subprograma como argumento para outro. Isso permite um maior reaproveitamento de cdigo e ajuda a manter os vrios subprogramas pequenos. Por exemplo, um subprograma de ordenao pode receber entre seus parmetros uma funo de comparao. Assim a ordenao ser feita conforme o critrio desejado (ex.: nomes de pessoas podem ser ordenados pelo primeiro nome ou pelo sobrenome). Porm desejvel que o compilador possa verificar a quantidade de parmetros e seus tipos na chamada ao subprograma. Assim alm da informao a respeito de qual subprograma deve ser usado, desejvel se ter a informao a respeito de como ele deve ser chamado, ou seja, o protocolo do subprograma deve ser visto como seu tipo. Mais ainda, desejvel que essa informao esteja disponvel na declarao do subprograma, para permitir que ele seja compilado de forma independente do subprograma que seu parmetro. Uma questo importante o ambiente de referenciamento. O ambiente de referenciamento de uma instruo o conjunto de nomes vlidos nela. Uma instruo tem acesso s variveis locais e s externas, mas quais nomes sero considerados externos? Em outras palavras, variveis externas ao subprograma que usado como parmetro so buscadas em que ambiente? As linguagens definem respostas diferentes, listadas a seguir em ordem de popularidade: vinculao profunda: o ambiente de referenciamento aquele em que o subprograma foi declarado (a posio no texto do cdigo define a vinculao); vinculao rasa: o ambiente de referenciamento aquele em que o subprograma foi ativado (a ordem de execuo define a vinculao) - esse tipo considerado mais perigoso e vem sendo abandonado; vinculao ad hoc: o ambiente de referenciamento aquele em que o subprograma foi usado como parmetro.

2.5.5 Subprogramas sobrecarregados


Assim como os operadores, subprogramas podem ser sobrecarregados. Para tal preciso que cada verso do subprograma tenha um protocolo nico. A maioria das linguagens, entretanto, exigem que eles tenham um perfil de parmetro nico. Essa escolha est diretamente relacionada com a forma pela qual a linguagens trata expresses de modo misto. No primeiro caso, diz-se que a linguagem oferece sobrecarga dependente de contexto e no segundo caso sobrecarga independente de contexto. A possibilidade de omitir parmetros interfere com a possibilidade de sobrecarga, podendo criar ambiguidades. Entretanto essas ambiguidades podem ser detectadas pelo compilador. A sobrecarga considerada um tipo de polimorfismo (polimorfismo ad hoc). Seu uso pode levar implementao de subprogramas exatamente iguais em termos de instrues, mas que diferem em termos de tipos. Algumas pessoas acreditam que o Pascal uma linguagem que suporta a sobrecarga, visto que o compilador Free Pascal a suporta. Entretanto a linguagem no suporta sobrecarga e portanto programas desenvolvidos assim podem no compilar em outros compiladores [Veen 06] [Moore 10]
prof. Bruno Schneider 21

Notas de Aula de GCC105 - BCC e BSI - UFLA

[ISO7185].

2.5.6 Subprogramas genricos


A capacidade de encontrar erros de tipo das linguagens com vinculao esttica de tipos tem um alto custo: perda de flexibilidade. Por vezes, uma linguagem obriga o programador a escrever a mesma coisa mais de uma vez, simplesmente para satisfazer as restries do sistema de tipos. Para possibilitar a vinculao esttica de tipos e ao mesmo tempo a flexibilidade do tratamento igual para tipos diferentes, algumas linguagens permitem a parametrizao de tipos, ou seja, a definio incompleta de um tipo (especificao de um tipo genrico). Essa poderosa forma de polimorfismo (conhecida como polimorfismo paramtrico) viabiliza a definio dos chamados subprogramas genricos. Subprogramas genricos, so portanto, subprogramas em que a declarao de um ou mais tipos de parmetros foi parametrizada. Uma outra definio possvel a que subprogramas genricos so aqueles que apresentam um ou mais parmetros de tipo genrico. Exemplos de linguagens que implementam tipos genricos: Ada, C++, Haskell e Java (a partir da verso 1.5). Ada foi a primeira linguagem com uma implementao para subprogramas genricos. Nela (e em C++) A implementao de um subprograma genrico no transformada em cdigo pelo compilador e no tem efeito sobre o programa. Ela serve como um modelo (gabarito) para o compilador que usa esse modelo para gerar cdigo para todos os tipos que so usados na chamada do subprograma. De maneira mais imprecisa, pode-se dizer que o compilador gera cdigo para vrios subprogramas com o mesmo nome, um para cada tipo usado nas chamadas, tirando do programador o trabalho de sobrecarregar o subprograma. Em Ada, preciso instanciar os subprogramas de forma explcita. Em Java, o subprograma genrico gera byte-code, da mesma forma que cdigo comum2.

2.5.7 Compilao Separada e Independente


A compilao de partes de programas importante. Existem duas abordagens para permitir isso: compilao separada e compilao independente. Essas partes de programas podem ser chamadas de unidades de compilao. Na compilao separada, unidades de compilao precisam de informaes definidas em outras unidades de compilao. Essas informaes so usadas para verificao de tipos, ento em geral compreendem os protocolos de subprogramas. Na compilao independente, a compilao de uma unidade no usa informaes de outras, tornando invivel a verificao de tipos em tempo de compilao.

2.5.8 Questes de projeto referentes a funes


As vrias linguagens de programao diferem no que diz respeito a permitir efeitos colaterais em funes (por causa das vrias complicaes decorrentes - mencionadas anteriormente) e com relao aos tipos vlidos de retorno. A maioria das linguagens permite os efeitos colaterais e limita os tipos de retorno aos valores escalares (Ada uma das excees nos dois aspectos).
2 Generics Tutorial - Generics in the Java Programming Language (http://java.sun.com/j2se/1.5/pdf/genericstutorial.pdf) - pg.3. prof. Bruno Schneider 22

Notas de Aula de GCC105 - BCC e BSI - UFLA

As restries aos tipos de retorno so parcialmente justificadas pelo fato de que a troca de valores geralmente feita via passagem por resultado, causando ineficincia para grandes quantidades de informao. Uma exceo comum o tipo registro (ou tuplas) que de certo modo podem ser usados para retornar mais de um valor. Nas linguagens que permitem retornar tipos compostos, a atribuio entre esses tipos pode ser interessante para separao dos valores em variveis independentes. Ex.: (encontrado, indice) := Buscar(vetor, elemento); if (encontrado) then print(Encontrado na posio,indice); else print(No encontrado);

2.5.9 Co-rotinas
So um tipo bem diferente de subprograma. Elas se prestam uma relao de igual para igual entre unidade chamadora e chamada. Ainda assim, co-rotinas so hierarquicamente ligadas uma unidade de programa chamada unidade mestra. A unidade mestra cria uma srie de co-rotinas que se conhecem e as inicializa. Em seguida, o controle passado para uma delas que passam o controle adiante para outra co-rotina do grupo e assim sucessivamente at eventualmente todas acabam e o controle retorna unidade mestra. As co-rotinas no tem um nico ponto de entrada e mantm uma memria de suas ativaes anteriores. Os pontos em que passam o controle adiante so determinados pelo programador e cada vez que uma co-rotina ganha o controle de fluxo, ela retoma a execuo de onde parou. A invocao de uma co-rotina chamada de retomada. As co-rotinas apareceram na linguagem SIMULA que tinha o propsito de oferecer facilidade para simulao de sistemas. Um dos elementos desejados na linguagem era uma forma de proporcionar a execuo em tempo compartilhado entre unidades de programa, como se elas estivessem executando ao mesmo tempo. So geralmente implementadas na forma de laos que passam adiante o controle de fluxo a cada repetio. As co-rotinas formaram a base para a programao concorrente e so a base conceitual da multitarefa cooperativa. Dificultam a criao de mdulos independentes de programas, uma vez que o fluxo de instrues precisa ser passado voluntariamente entre as vrias co-rotinas. Um erro em uma co-rotina pode afetar todas as outras j que a execuo de qualquer co-rotina depende de retomadas a partir de suas irms. Esse mesmo problema aparece em relao aos programas na multitarefa cooperativa e foi um forte motivo para a evoluo para a multitarefa por tempo compartilhado. Exemplos de linguagens modernas que apresentam o recurso so Lua e Modula-2. So tidas como mais genricas que os subprogramas comuns.

2.6 Tipos Abstratos de Dados


A abstrao importante no s nos processos como tambm nos dados. Um tipo abstrato de dados (TAD) um encapsulamento que inclui a representao de dados (ou modelo de dados) de um nico tipo mais os subprogramas que fornecem as operaes para este tipo.
prof. Bruno Schneider 23

Notas de Aula de GCC105 - BCC e BSI - UFLA

Uma instncia de um TAD um objeto. Vrios autores consideram que precisa haver ocultao de dados para que o encapsulamento possa ser considerado um TAD. Seguiremos essa linha. Um encapsulamento um agrupamento de subprogramas e os dados que eles manipulam. Assim, um TAD caso especial de encapsulamento. Suporte aos TADs como nica forma de encapsulamento pode trazer problemas relativos a operaes entre tipos diferentes (ex.: somar ponto com vetor). Para facilitar o entendimento, podemos pensar no ponto flutuante como se fosse um TAD. De maneira no muito precisa, podemos dizer que variveis do tipo ponto flutuante so usadas para representar um tipo de informao (nmero racional); elas podem ser manipuladas com um conjunto de operaes (somar, multiplicar, etc.); o programador no precisa conhecer a sua representao interna para us-lo; no pode alterar diretamente as partes fundamentais da sua representao e no pode construir novas operaes para ele (a no ser pela composio das operaes existentes). As linguagens de programao passaram a permitir que o programador crie TADs, preferencialmente de forma que as definies do tipo e de suas operaes ficam numa unidade de compilao, enquanto que outras unidades de compilao podem declarar variveis desse tipo e usar as operaes definidas para ele. Esconder os detalhes de um tipo de dados importante para manter a independncia entre mdulos de um programa. Por exemplo: suponha que um compilador de uma determinada linguagem usa mais bits para a mantissa de um nmero de ponto flutuante do que outro compilador. Nesse caso, os programas desenvolvidos funcionam nos dois casos, e a mudana na representao de um deles no necessita mudana no cdigo que faz uso dele. Essa ideia d origem ao conceito de ocultao de dados (data hiding). A ocultao de dados uma forma de controle de acesso que limita o uso que se pode fazer de um identificador. Esse controle estende o controle proporcionado pelo escopo. Em linguagens em que a ocultao de dados mais simples, pode-se simplesmente limitar o acesso a um nome, ou seja, mesmo que o nome seja visvel pelas regras de escopo, o compilador pode no permitir que o nome seja usado. Em linguagens em que a ocultao mais sofisticada, pode-se limitar o uso do nome de uma varivel a um right-value numa expresso, ou seja, cria-se uma varivel que somente para leitura em determinados contextos. A ocultao de dados no tem como objetivo esconder dados (no sentido de impedir que o cliente saiba de usa existncia), como o nome poderia sugerir 3. Ela proporciona proteo (no sentido de impedir que o cliente possa us-los), que importante para manter a independncia entre os mdulos de um programa. Para entender o estado de um TAD num dado instante da execuo, no necessrio olhar fora do encapsulamento, j que tais instrues no poderiam alter-lo. No poderiam porque os dados do TAD esto protegidos pela ocultao. Dizemos que a ocultao de dados ajuda a manter a consistncia de um TAD, ou seja, como o estado de um TAD s pode ser alterado pelas operaes definidas no encapsulamento, fica mais fcil garantir que as vrias partes do TAD fazem sentido quando vistas como um todo. Um objeto assim dito um objeto consistente. Por exemplo, imagine que TAD que representa um vetor, que tem como caractersticas um tamanho (inteiro) e um ponteiro para um vetor dinmico interno de elementos. O tamanho usado para que seja possvel saber quantos dos elementos no vetor interno so realmente valores do vetor TAD e quantos so lixo. Se o vetor TAD tem 2 elementos mais o
3 Em alguns textos sobre ocultao, usa-se o termo visvel ou visibilidade na explicao, como em: os dados no ficam visveis. Esses termos remetem ao sentido de secreto para a palavra ocultao e por isso costumam confundir leitores. prefervel, ento, usar algo como os dados no ficam acessveis. prof. Bruno Schneider 24

Notas de Aula de GCC105 - BCC e BSI - UFLA

tamanho dele vale 3, dizemos que o vetor TAD est num estado inconsistente. Para formalizar melhor o conceito de encapsulamento, deve-se dizer que necessrio existir um elemento sinttico da linguagem agrupando os dados e os subprogramas. Declarar um tipo de dados e mais alguns subprogramas que tem a finalidade de processar esse tipo de dados, sem um elemento sinttico que engloba isso tudo no declarar um TAD. Da mesma forma, usar um elemento sinttico que existe para declarar TADs sem declarar dados e subprogramas que possam ser entendidos como um tipo de dados, no declarar um TAD.

2.6.1 Questes de projeto


Os TADs so mais bem suportados quando a linguagem permite deixar seus nomes e os protocolos de suas operaes acessveis qualquer unidade de compilao, sem tornar a estrutura interna do tipo e a implementao de suas operaes acessveis tambm. Algumas operaes genricas podem ser pr-determinadas pela linguagem. Ex.: verificao de equivalncia, atribuio. Algumas operaes genricas podem ser obrigatoriamente declaradas pelo usurio. Ex.: comportamento de iteradores, inicializao. As linguagens diferem ainda a respeito de restries para os TADs (ex.: todo TAD deve ser um tipo de ponteiro), se eles podem ser parametrizados (ex.: vetor de ...) e o controle de acesso (permitir restries ao uso desses tipos). Algumas linguagens oferecem formas de encapsular vrios tipos e suas operaes. Esse recurso mais geral que a definio de um TAD e pode ser usado com esse propsito.

2.6.2 Suporte nas linguagens


Por ser a base da orientao a objetos (OO), os TADs so suportados por qualquer linguagem que suporte o conceito da OO. A primeira linguagem a dar um passo nessa direo foi SIMULA 67, que permitia a declarao de classes. As classes eram tipos de dados declarados de tal forma que os dados e subprogramas ficavam encapsulados. No havia nenhum controle de acesso e os dados poderiam ser acessados diretamente pelos clientes da classe. Isso gera problemas de confiabilidade e tambm faz com que esse encapsulamento nem sempre seja considerado um suporte aos TADs. A linguagem Ada oferece encapsulamento na construo de unidades chamadas pacotes. Pacotes no so tipos, mas sim colees de tipos. Ada permite a separao entre declaraes e implementaes. Oferece tambm suporte ocultao de informaes, proporcionando uma forma de evitar que os clientes tenham acesso s partes internas dos TADs. Ada oferece ainda, operaes padro de atribuio e comparao de equivalncia e desigualdade, critrio do programador, que pode suprimi-las ou redefini-las. A fim de restringir o acesso s partes de um TAD para o cliente e ao mesmo tempo oferecer essa informao ao compilador, Ada usou uma palavra especial (private) para modificar declaraes, informando que elas ficam inacessveis ao cliente. A linguagem Modula-2 oferece mdulos que so muito semelhantes aos pacotes de Ada, com a restrio de que os tipos definidos em mdulos so sempre ponteiros. Dessa forma, o conhecimento da estrutura interna dos mdulos no necessria nem mesmo ao compilador e as declaraes separadas das implementaes no so necessrias.
prof. Bruno Schneider 25

Notas de Aula de GCC105 - BCC e BSI - UFLA

Em C++ a estrutura que proporciona encapsulamento a classe. Classes so tipos de dados. A ocultao de informaes funciona de maneira semelhante da Ada. Essas duas caractersticas juntas proporcionam um suporte mais direto aos TADs. Outras facilidades oferecidas so os construtores e destrutores que podem ser usados para gerenciar a inicializao, alocao e desalocao de recursos (ex.: memria no heap). O suporte de Java muito parecido como o de C++, com algumas diferenas importantes. Todos os tipos definidos pelo programador em Java devem ser classes. Todas as variveis que so TADs so alocadas no heap e acessadas por meio de referncias. Alm das classes, Java permite a definio de pacotes (encapsulamento geral) e oferece o escopo de pacote, em que partes protegidas das classes so acessveis em outras partes do pacote.

2.6.3 Tipos abstratos de dados parametrizados


Assim, como os subprogramas, tipos de dados parametrizados so de grande utilidade. Eles permitem generalizar tipos de dados, descrevendo tipos como lista de qualquer coisa. Ada, C++ e Java so exemplos de linguagens que proporcionam esse tipo de construo. Assim como nos subprogramas, elas usam o cdigo como modelo para a construo de vrios pacotes ou classes conforme os casos so instanciados.

2.7 Tratamento de erros


A execuo de programa est sujeita a vrios tipos de erros. Alguns erros acontecem ao nvel de hardware (ex.: overflow aritmtico) e outros acontecem ao nvel de software (ex.: tentar remover elemento que no existe numa coleo). Esse ltimo tipo pode ser tratado pelo compilador (quando possvel) ou pela prpria execuo do programa. As linguagens de programao devem facilitar o tratamento dessas condies de erro, facilitando a tarefa de produzir programas que lidam graciosamente com elas. Algumas linguagens determinam que seja gerado cdigo para deteco de erros em vrias situaes (ex.: valor invlido para o ndice de um vetor), mas desejvel que permitam ao programador especificar o que deve ser feito nas situaes de erro.

2.7.1 Cdigo de Erros


A forma mais primitiva para lidar com erros usar seletores que fazem uso das formas disponveis para deteco de erros. Assim, as instrues de um programa so frequentemente seguidas de instrues que desviam o fluxo de instrues caso uma situao anormal seja detectada. O uso de funes que relatam algum tipo de status da execuo comum na hora de projetar subprogramas. Programas tambm retornam esse status de tal forma que os programas que os chamaram tambm possar verificar problemas na execuo para tomar as medidas necessrias. Dessa forma, linguagens como C++ exigem que o bloco principal de um programa retorne um nmero inteiro. Por conveno, esse nmero deve ser zero para indicar um execuo sem erros, enquanto que qualquer outro nmero indica algum tipo de erro de execuo. Cada programa cria o significado dos valores que indicam erros, muitas vezes, tratando o valor como um vetor de bits em que cada bit indica a ocorrncia de um tipo de erro. O uso de funes que retornam status tem as desvantagens de (a) criar um cdigo em que a
prof. Bruno Schneider 26

Notas de Aula de GCC105 - BCC e BSI - UFLA

condies anormais ficam misturadas com a condio normal e (b) dificultar o projeto de funes que retornam o resultado de um processamento (alm do status). A segunda pode ser reduzida pela tipificao dinmica, que permite a criao de uma funo que retorna algum tipo que representa erro ou um tipo que representa o resultado do processamento. Nas bibliotecas padro da linguagem C, o valor de retorno de um subprograma geralmente usado como cdigo de erro.

2.7.2 Manipulao de Excees


Algumas linguagens oferecem construes para tratar condies anormais de execuo detectadas por hardware e software, inclusive condies incomuns (no errneas) em geral de uma mesma forma. O uso dessas construes chamado de manipulao de excees. Essas construes tem a desvantagem de adicionar uma boa dose de complexidade linguagem e consequentemente ao seu compilador. A vantagem da manipulao de excees o aumento da legibilidade e a facilidade para descrever as formas de tratar erros, o que funciona como um incentivo ao tratamento de erros.

2.7.2.1 Questes de projeto


A manipulao de excees deveria proporcionar formas de reusar cdigo para tratamento de excees (ex.: se qualquer uma dessas divises der erro faa aquilo) ao mesmo que fornece formas de ligar tratadores a casos especiais de execuo (ex.: essa diviso por zero especial e deve ser tratada de forma diferente). desejvel permitir que o tratamento de excees seja ligado e desligado tanto em tempo de execuo quanto em tempo de compilao. Outras questes de projeto da linguagem incluem: como e onde especificar os tratadores (subprogramas? trechos de cdigo?), alm de como determinar seu escopo; como vincular a ocorrncia de uma exceo execuo do tratador; como e onde retomar a execuo do programa depois do tratamento; como o usurio pode especificar excees; a existncia de tratadores padro; a criao automtica de excees para condies comuns de erro; a gerao de excees predefinidas pelo prprio programa; a possibilidade de desativar e reativar excees.

Uma forma popular de vincular a ocorrncia de uma exceo execuo do tratador conhecida como propagao de erro. Ela consiste em checar se houve erro na execuo de algum subprograma e ento repassar essa indicao para o chamador. Essa passagem que feita manualmente usando cdigos de erro feita automaticamente pela manipulao de excees.

2.8 Sistemas de tipo


A checagem de tipos , em geral, benfica. As linguagens precisam de sistemas para garantir a
prof. Bruno Schneider 27

Notas de Aula de GCC105 - BCC e BSI - UFLA

checagem, preferencialmente, em tempo de compilao. Portanto, um sistema de tipos (no contexto de linguagens de programao) o conjunto de regras que permite a classificao de expresses de acordo com um tipo. Declarar o tipo de cada varivel antes do seu uso uma forma simples de proporcionar isso, mas oferece pouca flexibilidade para o programador, limitando o reuso e a facilidade de manuteno. Para conciliar essas duas necessidades contraditrias, pode-se usar declaraes mais gerais, em que no se define um tipo por completo, mas que fornecem elementos suficientes para a checagem. O conceito de polimorfismo (tratamento de tipos diferentes de maneira uniforme) a flexibilidade desejada e difcil de conciliar com a verificao de tipos. Nas linguagens em que os tipos precisam ser completamente determinados, temos monomorfismo. Naquelas em que o tipo precisa ser parcialmente determinado (somente o suficiente para checagem de tipos nas expresses) ou em que no h sistemas de tipos, temos polimorfismo. O polimorfismo pode ento ser obtido em nveis variados, ou seja, as linguagens proporcionam mais ou menos recursos para o tratamento homogneo de tipos diferentes. Alguns dos recursos que proporcionam polimorfismo e j foram analisados so: vinculao dinmica de tipos; escopo dinmico; sobrecarga de subprogramas (e operadores); subprogramas genricos.

Nenhuma linguagem completamente monomrfica. Mesmo linguagens como Pascal possuem subprogramas polimrficos como o write, apesar de no proporcionarem esse tipo de recurso para o programador. Isso uma inconsistncia da linguagem e os projetos de linguagens mais modernas procuram oferecer ao programador um sistema de tipos consistente; com um nvel maior de polimorfismo. O polimorfismo paramtrico dos subprogramas genricos pode ser usado tambm na declarao de tipos. Essa estratgia extremamente til em tipos agregados como vetores, listas, rvores, etc. Nesse tipos, podemos variar o tipo dos valores individuais sem alterar a estrutura geral. As linguagens funcionais ML e Haskell combinam o polimorfismo paramtrico com a inferncia de tipos, proporcionando a robustez da tipificao forte com a convenincia de escrita da tipificao fraca. Entretanto, no recomendvel abusar da inferncia de tipos. Mais do que declarar tipos para o compilador, a declarao de tipos serve como uma forma de documentao do cdigo, evidenciando o significado das coisas. Alguns sistemas de tipos usam o conceito de herana para permitir restries aos parmetros de tipos. Se considerarmos que alguns tipos so casos especiais de outros, podemos agrupar tipos em conjuntos. Esses conjuntos podem ser usados como restries aos parmetros do polimorfismo paramtrico. Por exemplo: nmeros inteiros sem sinal e subfaixas podem ser considerados casos especiais (subtipos) do tipo inteiro. Algumas linguagens permitem especificar que um subprograma recebe um valor de um tipo t qualquer, desde que t pertena ao conjunto dos tipos que so nmeros inteiros. Dessa forma, parmetros reais de tipos subfaixa so vlidos para esse subprogramas mas os de tipo ponto flutuante no so. Algumas linguagens como Haskell definem subtipos em funo das operaes disponveis para eles
prof. Bruno Schneider 28

Notas de Aula de GCC105 - BCC e BSI - UFLA

(ex.: o conjunto dos tipos em que existe a comparao de equivalncia; conjuntos dos tipos para os quais existem operaes aritmticas, etc.). O programador pode ento criar um TAD com as operaes relevantes e inclu-lo em um ou mais conjuntos de tipos. Outras linguagens como Ada, fornecem formas de declarar subtipos em funo de particularidades das suas instncias. Por exemplo, suponha o tipo pessoa, como um registro que possui, entre outras coisas, o campo gnero. possvel ento declarar o tipo homem que um caso especial de pessoa, onde o gnero masculino. O termo herana usando dentro do conceito da orientao, em que, alm de vermos tipos como casos especiais de outros tipos e termos operaes comuns a vrios tipos, existe tambm a preocupao a respeito de como essas operaes alteram os valores de um tipo. A ideia bsica, entretanto a mesma.

3. Eventos
X

Referncias
[Budd 91] Budd, Timothy. An Introduction to Object-Oriented Programming. Addison-Wesly. 1991. [ISO7185] Pascal (ISO 7185:1990). [VEEN 06] http://www.few.vu.nl/~nsilvis/PPL/2006/REPORTS/pascal-vanVeen.pdf [Moore 10] http://www.standardpascal.org/standards.html

prof. Bruno Schneider

29

You might also like