notas-de-aula- Schneider
29 pág.

notas-de-aula- Schneider


DisciplinaProgramação I21.721 materiais248.451 seguidores
Pré-visualização11 páginas
Linguagens de Programação 1 - Notas de Aula
Aviso: Essas notas de aula tem por finalidade orientar o professor no encaminhamento das aulas, a fim 
de não deixar assuntos fora da ordem planejada. A leitura deste material não reduz a necessidade de 
leitura da bibliografia recomendada. Última atualização em 28/02/12.
1. Paradigmas de Linguagens de Programação
Existem muitas linguagens de programação, todas elas com características diferentes. Por vezes, 
muito diferentes. As linguagens no entanto, adotam técnicas comuns de programação, 
desenvolvidas de forma independente de uma linguagem conforme a área de Linguagens de 
Programação evolui.
As linguagens de programação podem ser classificadas de muitas formas diferentes. Umas das 
formas de classificação é quanto ao paradigma de programação. Mas o que é um \u201cparadigma\u201d?
A palavra paradigma pode significar muitas coisas. No contexto científico, costuma ser usada para 
um conjunto de teorias, padrões e métodos que juntos representam uma forma de organizar o 
conhecimento, ou seja, uma forma de ver o mundo [Budd91]. No contexto de linguagens de 
programação, podemos dizer de maneira bem simples que paradigma é um estilo. Porém estamos 
nos referindo a estilo numa conotação forte. Para serem chamados de paradigmas de programação, 
estilos precisam ser suficientemente diferentes e completos para serem considerados uma forma de 
ver o mundo.
Autores diferentes classificam as linguagens de programação de formas diferentes. Apesar disso, é 
geralmente aceito que existem dois tipos principais de programação: (a) programação imperativa 
(ou procedural), de acordo com a qual os programas são construídos por meio de uma sequência de 
ordens - o programador escreve um procedimento que leva à solução de um problema; (b) 
programação declarativa (ou descritiva), de acordo com a qual os programas são construídos 
simplesmente pela descrição da solução de um problema - cabe ao compilador encontrar uma 
sequência de instruções que produz a solução declarada.
Na programação declarativa, existem duas formas principais de se descrever soluções: (a) através de 
funções (conceito matemático de associação entre elementos de um conjunto domínio para um 
conjunto imagem) e (b) através de predicados (elementos sintáticos que permitem expressar 
relações entre elementos de conjuntos). Vale lembrar que uma função é um tipo especial de relação 
de associação.
Assim, dadas essas duas categorias gerais distintas e o fato de que em uma delas, existem duas 
formas muito diferentes de descrever a solução de um problema, o autor deste texto considera que 
são três os paradigmas de programação:
\u2022 programação imperativa (ou procedural) - em que programas são implementações de 
algoritmos (sequência de instruções que levam à solução de um problema);
\u2022 programação funcional - em que programas são implementações de funções e
\u2022 programação lógica - em programas são implementações de predicados (relações entre 
elementos de conjuntos diversos).
É comum encontrar autores que classificam a Programação Orientada a Objetos como sendo um 
paradigma de programação. Essa classificação considera que o projeto de programas orientados a 
objetos segue conceitos de destaque suficiente para que esse estilo de programação seja classificado 
à parte da programação imperativa.
Este texto se concentra na programação imperativa, apesar de apresentar conceitos que são 
independentes do paradigma de programação. Alguns conceitos em particular são melhor 
Notas de Aula de GCC105 - BCC e BSI - UFLA
exemplificados através de suas implementações em linguagens funcionais como (LISP, ML, 
Haskell, etc.) e nesses casos daremos preferência a exemplos nessas linguagens.
2. Conceitos de Linguagens de Programação
Este é o capitulo principal deste texto. Aqui são descritas características das linguagens de 
programação de uma maneira independente da linguagem de programação. São apresentados 
problemas relativos ao projeto de uma linguagem de programação juntamente com formas de 
resolvê-los. As várias soluções são comparadas para permitir que as linguagens de programação 
sejam entendidas de um ponto de vista mais amplo do que simplesmente como uma coleção de 
comandos e tipos de dados.
Espera-se que as as informações apresentadas aqui permitam que leitor que sinta ambientado em 
qualquer linguagem de programação que venha a usar no futuro, em função de conhecer os 
conceitos que permitem a criação das várias facilidades que são proporcionadas de formas 
diferentes, por linguagens diferentes.
2.1 Tipos de Dados
Algumas linguagens não tem o tipo de dado que você precisa, pode ser necessário implementá-lo 
(ex.: implementar listas ou árvores usando vetores).
Algol68 permitia a declaração de novos tipos, um avanço significativo.
Um tipo primitivo de dados é aquele que não pode ser decomposto em partes mais simples [Watt, 
89]. Para tal classificação, considera-se a linguagem propriamente dita (e não suas bibliotecas). Para 
entender melhor essa definição, é necessário explicar melhor o conceito de \u201cser decomposto\u201d. 
Algumas informações são representadas por um grupo de outras informações (as partes mais 
simples). Se o programador não tem acesso a essas partes mais simples, dizemos que o tipo de 
dados é um tipo primitivo.
Como os tipos de dados ainda não foram apresentados, vamos fazer uma analogia para dar um 
exemplo. Suponha que uma pessoa (talvez um aborígene no interior da Austrália) observa um carro 
e não percebe que ele é feito de várias peças 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 informação a informação como um todo (por causa da linguagem de programação), 
essa informação é de um tipo primitivo.
O primeiro exemplo de um tipo de dados formado por partes mais simples é o ponto flutuante, visto 
na seção 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 representações 
para o zero.
2.1.2 Ponto Flutuante
É uma representação para números racionais criada com o objetivo de manter a maior quantidade de 
bits significativos. Os bits que representam um ponto flutuante, são usados em três 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 precisão simples; 52 bits de 
mantissa e 11 bits de expoente para precisão dupla.
2.1.3 Decimais
Ponto fixo, útil em aplicações comerciais. Algumas máquinas tinham hardware próprio para esse 
tipo e representavam números como strings de bits, desperdiçando um pouco de espaço. Hoje em 
dia, costuma-se usar emulação desse tipo no software.
2.1.4 Booleanos
Um único bit não é normalmente endereçável na memória.
Tipos booleanos aumentam a legibilidade da linguagem (ver exemplo na seção de expressões 
booleanas).
Algumas linguagens permitem que o valor de qualquer tipo seja testado.
2.1.5 Caracteres
Existem vários sistemas de representação. Alguns usam tamanhos fixos e outros usam tamanhos 
variáveis.
Considerar UNICODE como um sistema de codificação de caracteres é um erro comum. O próprio 
livro do Sebesta, afirma que o UNICODE é \u201cum conjunto de caracteres de 16 bits\u201d, o que é errado. 
Dizer que os caracteres são representados de acordo com a tabela ASCII é outro.
2.1.6 Ponteiros
Proporcionam flexibilidade para outros tipos. Essa flexibilidade tem uma relação importante com o 
fato de que ponteiros podem \u201capontar para lugar nenhum\u201d (ex.: nil em Pascal, null em Java). Esse 
valor especial é quase sempre o número