PARADIGMAS DE LINGUAGEM DE PROGRAMAÇÃO
2 PARADIGMA IMPERATIVO
2.1 CONCEITO
As linguagens que pertencem ao paradigma imperativo tomam por base a
perspectiva da máquina. Ou seja, no modo como o computador executa programas
em linguagem de máquina.
Por esta razão é o paradigma mais antigo e difundido pelo mundo. Existe
uma infinidade de linguagens de programação do paradigma imperativo. Como a
construção de programas desse paradigma segue o modo de execução da
linguagem de máquina, o processo de tradução do programa é mais simples que os
demais paradigmas.
Outra característica importante das linguagens imperativas é que a oferta
dos seus recursos está presa à arquitetura do computador utilizada, o que explica
as diversas diferenças entre a linguagem C para arquiteturas CISC e para RISC. Em
outras palavras, uma linguagem de programação é construída a partir de uma
determinada arquitetura base.
A arquitetura mais utilizada é a Máquina de Von Neumann, cuja estrutura
está ilustrada na Figura 2.1.
R1
R2
.
.
.
Memória
(Instruções e dados)
Rn
Resultados
das operações
CPU
Unidade
lógica e
aritmética
Instruções
e dados
Unidade
de
controle
Figura 2-1 - Máquina de Von Neumann
WILIAM HIROSHI HISATUGU
E/S
PARADIGMAS DE LINGUAGEM DE PROGRAMAÇÃO
Como as linguagens de programação imperativas imitam as ações da
máquina, fazendo operações básicas entre a memória e a CPU. Uma unidade de
execução de um programa é composta por:
Obter endereços de memória para armazenar os resultados e buscar os
operandos;
Obter os dados a serem utilizados na operação;
Realizar a operação com os operandos;
Armazenar o resultado no devido endereço.
Os dados são manipulados através de endereços de memória denominados
variáveis e através de operações de atribuições de valores à essas variáveis e de
iterações (repetição de passos elementares). A Figura 2.2 ilustra um exemplo de
uma unidade de execução desse modelo.
EXEMPLO
a = b+c;
Obter os endereços de a, b e c;
Obter os valores dos endereços de c e c;
Realizar a operação b+c;
Armazenar o valor da operação no endereço de a;
Figura 2-2 - Exemplo de uma Unidade de Execução
Como forma de criar uma maior aproximação entre o desenvolvedor
humano e o computador, foi criado o conceito de função. Uma função é a
representação de um bloco de código de linguagem de máquina que executa uma
determinada tarefa. Muitas funções assemelham-se à expressões em linguagens
naturais como, por exemplo : for (i = 0;i<10;i++) ou clrscr (clear screen = tela limpa).
Esta aproximação se reflete em uma maior eficiência dos programas.
2.2 TIPOS DE DADOS
“Tipos de dados podem ser entendidos como métodos (sig: meio, forma) para
interpretar o conteúdo da memória do computador“
Os tipos de dados definem os valores que uma determinada posição da
memória (variável pode assumir). As linguagens de programação possuem os
tipos primitivos que podem ser utilizados tanto na sua forma natural, ou na
construção de outros tipos de dados chamados por estruturados (Matrizes e
Registros). Os tipos de dados foram construídos para:
WILIAM HIROSHI HISATUGU
PARADIGMAS DE LINGUAGEM DE PROGRAMAÇÃO
Associar um nome (de tipo) a um domínio, uma representação interna e a
um conjunto pré-determinado de operações;
Permitir a verificação estática de tipos
Uso em expressões, e/s e atribuição;
Definição de equivalência de tipos;
Conversão implícita e explícita.
Segurança: A representação de tipos é inviolável e somente pode ser
alterada através das operações definidas pela linguagem
De forma geral, um tipo de dado é constituído de um nome, um ou mais
domínios de valores e é associado a um conjunto de operações para manipular os
seus valores. Esta representação é inviolável, somente acessível para a máquina. A
Figura 2.3 ilustra dois exemplos de tipos de dados e suas operações.
LINGUAGEM C
EXEMPLO 1
float
- domínios: números inteiros e fracionários;
- operações: soma, divisão, multiplicação e subtração;
- atribuição: recebe valores float e int;
EXEMPLO 2
int
- domínios: números inteiros
- operações: soma, divisão, multiplicação, subtração e resto;
- atribuições: valores int
Figura 2-3 - Exemplos de Tipos de Dados
Sobre os domínios de valores, há duas categorias:
Primitivos – não necessitam de descrição explícita como, por exemplo, o
conjunto dos números reais. Eles são a base de todos os demais tipos das
linguagens de programação;
Definidos – os componentes devem ser explícitos através de enumeração
ou restrição. A Figura 2.4 ilustra um exemplo de enumeração e de restrição.
WILIAM HIROSHI HISATUGU
PARADIGMAS DE LINGUAGEM DE PROGRAMAÇÃO
EXEMPLO ENUMERAÇÃO
O conjunto são os valores: 1, 2, 3, 4,5
EXEMPLO RESTRIÇÃO
O conjunto são os valores entre 2000 e 3000
Figura 2-4 - Enumeração e Restrição
Existem vários propósitos para os tipos:
1. Passagens de parâmetros para funções;
2. Prevenir ou detectar construções incorretas em um programa
3. Determinar os métodos de representação e manipulação de dados no
computador.
Já os tipos definidos pelos usuários:
Mnemônicos associados a tipos existentes
Sinonímia: não criam novos
identificadores simbólicos.
tipos
de
dados;
apenas
usam
Composição: podem ser combinados com outros tipos de dados.
Permitem restrições / enumerações
Os domínios compostos resultam de aplicação de métodos para construir
novos domínios com base em domínios já existentes. Estes domínios compostos
constituirão os tipos de dados estruturados disponíveis nas linguagens de
programação: homogêneos e heterogêneos (estáticos, dinâmicos e variantes). A
Figura 2.5 ilustra a estrutura de construção de um tipo composto.
domínio
simples
método
domínio
estruturado
Figura 2-5 - Domínio Composto
Neste conceito, há duas categorias para os tipos de dados compostos:
Homogêneas – todos os componentes pertencem ao mesmo tipo. Os vetores
e as matrizes pertence a essa categoria;
WILIAM HIROSHI HISATUGU
PARADIGMAS DE LINGUAGEM DE PROGRAMAÇÃO
Heterogênea – os componentes podem pertencer a diferentes tipos
primitivos ou mesmo outros tipos compostos. Nesta categoria se encontram
os registros e estruturas.
Sobre os tipos primitivos, eles podem ser classificados em duas categorias:
Numérico: compreende os tipos de dados utilizados para operações
aritméticas. Conseqüentemente, eles podem armazenar apenas números.
São exemplos de tipos numéricos: int, float na linguagem C e integer, real na
linguagem Pascal;
Caractere: são tipos de dados orientados para caracteres. Como forma de
possibilitar o manuseio de cadeias de caracteres (palavras, frases e
expressões) foi inserido o conceito de strings. Algumas linguagens fazem
esse tratamento de forma explícita como, por exemplo, a linguagem Pascal.
Outras fazem de forma implícita como, por exemplo, a linguagem C. na sua
forma mais pura, uma string é uma matriz do tipo caractere. Para suporte às
operações com strings foram criadas funções específicas para o manuseio
das mesmas.
As matrizes, também chamadas arrays, são definidas como um agregado
homogêneo de dados, cujo elemento individual é identificado por sua posição em
relação ao primeiro. Elas podem ser classificadas como:
Array estático: faixas de índice estão estaticamente vinculadas e a alocação
de armazenamento e estática (eficiente)
Array stack-dinâmico fixo: índices estáticos, com alocação durante a execução;
Array stack-dinâmico: índices e alocações dinâmicas. (flexibiliade)
Array heap-dinâmico:
(flexibilidade.
alocação
pode
alterar
durante
a
execução.
Por outro lado, os registros e estruturas são formados por elementos de
diferentes tipos, onde eles são identificados por um nome. Para ser acessado, o
elemento é associado junto com o nome da variável estrutura. A Figura 2.6 ilustra
um exemplo de uma estrutura feita em linguagem C.
WILIAM HIROSHI HISATUGU
PARADIGMAS DE LINGUAGEM DE PROGRAMAÇÃO
EXEMPLO:
struct Ficha{
char nome[40];
char endereco[40];
char fone[20];
float valor;
}
struct Ficha nova;
gets(nova.nome);
2.3 COMPATIBILIDADE, EQUIVALÊNCIA E INFERÊNCIA
A equivalência de tipos determina quando dois valores possuem o mesmo
tipo
A compatibilidade define quando um tipo pode ser usado em lugar de
outro em um determinado contexto
A inferência de tipos define o tipo de uma expressão com base nos tipos de
operandos envolvidos e a operação a ser realizada.
2.3.1
Compatibilidade
Quando existe compatibilidade de tipos, pode-se misturar valores de tipos
diferentes em expressões, ou mesmo usar um tipo A em lugar de um tipo B, sem
que haja violação das regras de segurança de tipos (erro de tipo). A Figura 2.7
ilustra um exemplo de compatibilidade de dados.
EXEMPLOS:
Seja i um inteiro e f um real e fun (inteiro, real)
São válidas as atribuições: i := r e r:= i?
É válida a invocação: fun(r, i)?
Conversão de Tipos
Quando os tipos envolvidos em uma expressão não são equivalentes, a
linguagem oferece a possibilidade de conversão de tipos. A conversão implícita ou
automática é feita com base nas regras definidas sem a interferência do
programador. A conversão explícita é codificada diretamente pelo programador.
WILIAM HIROSHI HISATUGU
PARADIGMAS DE LINGUAGEM DE PROGRAMAÇÃO
A conversão de tipos primitivos é ditada pelas regras da linguagem de
programação. Normalmente admite a conversão de um tipo de representação
menor para um tipo de representação maior. Por exemplo, em Java, a conversão
entre tipos primitivos, exceto o tipo bool que não admite conversão, considera o
tamanho do tipo (8, 16, 32, 64 bits). A Figura 2.8 ilustra um exemplo de conversões
possíveis de tipos.
de
byte
short
char
int
long
float
para
short,int,long,float,double
int,long,float,double
int,long,float,double
long,float,double
float,double
double
A conversão pode ser feita de três maneiras, ilustradas posteriormente na
Figura 2.9:
Por atribuição, ou conversão implícita para o tipo do lado esquerdo do
comando de atribuição;
Por promoção aritmética para o tipo de resultado esperado da operação
(inferência);
Por conversão explícita (casting).
EXEMPLO DE CONVERSÃO:
2.3.2
Seja float f, int i, float r;
exemplo de atribuição: f = i;
exemplo de promoção: r = f / i;
exemplos de casting: i = (int) f ;
r = (float) i/f;
Equivalência de Tipos
Tipos estruturados e tipos definidos pelo usuário. As formas de
equivalência são:
Equivalência estrutural: mesma representação
Equivalência de nome: mesmo nome de tipo
Equivalência de declaração: mesma declaração
A Figura 2.10 ilustra um exemplo de equivalência de tipos:
WILIAM HIROSHI HISATUGU
PARADIGMAS DE LINGUAGEM DE PROGRAMAÇÃO
type doiscampos = record
a, b: integer;
end;
?
type doiscampos = record
a: integer;
b: integer;
end;
type doiscampos = record
b: integer;
a: integer;
end;
WILIAM HIROSHI HISATUGU
Download

Paradigma Imperativo 1a. Parte