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

notas-de-aula- Schneider

Disciplina:Linguagens de Programação I260 materiais733 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 “paradigma”?

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:

• 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);

• programação funcional - em que programas são implementações de funções e

• 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 “ser decomposto”.
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 é “um conjunto de caracteres de 16 bits”, 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 “apontar para lugar nenhum” (ex.: nil em Pascal, null em Java). Esse
valor especial é quase sempre o número