Baixe o app para aproveitar ainda mais
Prévia do material em texto
Amarrações Prof. Saulo C. Campos Amarração (binding) • Amarrações são associações entre entidades de programação. Por exemplo: Variável a um valor ou um identificador a um tipo. • Existem diversos tipos de amarrações que ocorrem diversos momentos diferentes. O momento onde a amarração é realizada é conhecido como tempo. Tempo de amarração • Estática: – Tempo de projeto da Linguagem; – Tempo de implementação do tradutor; – Tempo de compilação; – Tempo de ligação (linking); • Dinâmica: – Tempo de carga; – Tempo de execução; Identificadores • São sequencias de caracteres definidas pelo programador para representar entidades de programação. • Uma vez que identificadores são definidos para entidades, elas podem ser referenciadas em outras partes do programa pelo seu “nome”. Ex.: Variáveis, funções, tipos e etc... • O regras de sintaxe definidas pelas LP para criação de identificadores são variadas: – Quantidade de caracteres; – Tipo de compilador; – Case sensitive; – Caracteres utilizados; • Legibilidade implica na declaração de identificadores. Identificadores Especiais • Estes identificadores tem significado especial para LP e não podem ser utilizados pelo programador. • São conhecidos como “palavras reservadas”. Por exemplo, int, char e break são identificadores especiais na linguagem C. • Alguns identificadores especiais são predefinidos, ou seja, são disponibilizados pela linguagem com significado (ou função) predefinida, mas podem ser alterados pelo usuário posteriormente. Exemplo: fopen e fclose da linguagem C. Ambientes de amarração • A interpretação de comandos e expressões depende do que denotam os identificadores utilizados. • Porém um mesmo identificador pode referenciar entidades diferentes, em partes distintas do programa. • O conceito de ambiente é utilizado para definir o que o identificador referencia em um dado momento. • Um ambiente corresponde a um conjunto de amarrações. Ambientes de amarração • Assim, expressões e comandos idênticos podem ser interpretados de maneira diferente em partes distintas do programa. int a=10; int f(){ int b=10; int a=2; a=10; b=b+a; return b; } int main(){ int b; a=5; b=0; b=b+f(); a=a+b; printf("valor de a=%d\nvalor de b=%d\n", a, b); } Ambientes de amarração int a=10; int f(){ int b=a; int a=2; a=10; b=b+a; return b; } int main() { int b; a=5; b=0; b = b+f(); a = a+b; printf("valor de a=%d\nvalor de b=%d\n", a, b); } Escopo (limite) • A amarração correspondente ao ambiente acontece dentro de um determinado escopo. • O escopo determina até onde uma dada entidade amarrada será visível, consequentemente, até onde ela estará disponível para uso. • O escopo pode ser estático ou dinâmico. Escopo estático • O escopo estático é determinado por blocos. • Um bloco delimita o escopo de qualquer amarração que ele possa conter. • Na prática blocos são subprogramas (funções) ou trechos de código que são delimitados por operadores de início e fim ( { e }, ou, begin e end). • A forma com que os blocos são estruturados dentro de um LP também é variável. Podendo ser: monolítico, não-aninhados e aninhados. Escopo estático – Estrutura de blocos X X X Y Z W Y W Z K Bloco Monolítico Blocos Não-Aninhados Blocos Aninhados Blocos aninhados void main() { int x=10; int i=0; while (++i <= 10) { float x=2.5*i; printf("%d - x=%f\n", i, x); } x = x + 1; printf("x=%d\n", x); } Linguagens semi-aninhadas Estrutura mista, onde funções são não-aninhadas e blocos internos aninhados int f(){ int x=10; return x*2; } void main() { int x=10; int i=0; while (++i <= 10) { float x=2.5*i; printf("%d - x=%f\n", i, x); } x = x + 1; printf("x=%d\n", x); } Linguagens totalmente aninhadas (like ALGOL) • Ver Exemplo pascal Escopo dinâmico • Neste tipo de escopo as entidades são amarradas aos identificadores de acordo com o fluxo de controle do programa. • O escopo dinâmico pode acarretar em sérios problemas e dificuldades de desenvolvimento, por isso poucas linguagens a adotaram. • Linguagens de escopo dinâmico: APL (1962), SNOBOL4 (1971) e as primeiras versões do LISP. Definições e Declarações • São expressões escritas para produzir amarrações. • Definições produzem amarração entre identificadores e entidades determinadas na própria definição. Ex.: tipos. • Declaração produzem amarração entre identificadores e entidades já criadas ou que ainda serão posteriormente. Ex.: variável. • O local para efetuar definições e declarações varia de acordo com a linguagem. Algumas exigem que sejam feitas no início do bloco, outras em local reservado e outras aceitam em qualquer local. Declaração de constantes • A declaração de uma constante amarra um identificador a um valor preexistente, o qual não pode ser alterado ao longo da execução do programa. const float PI = 3.14; #define PI 3.14 • Algumas linguagens fazem a amarração em tempo de compilação, como Pascal. Enquanto outras (C++ e Java) em tempo de execução, podendo assim associar valores oriundos de cálculos. final int cVlr = (int)Math.Randon()*20; Definição de Tipos • Uma definição de tipo amarra um identificador a um tipo criado na própria definição. struct data { int d, m a; }; union ângulo { int graus; float rad; }; enum dia_util { seg, ter, qua, qui, sex } Declaração de Tipos • Uma declaração de tipo amarra um identificador a um tipo definido em outro ponto do programa. struct data; typedef union ângulo curvatura; typedef struct data aniversario; • O uso do typedef não cria um novo tipo, apenas amarra um novo identificador a um tipo definido previamente em outro ponto do programa. Definição de variáveis • A definição de uma variável faz a amarração entre o identificador da variável e um conjunto de células de memória. int k; struct data d; int *p, i, j, v[10]; • As linguagens como C e Java aceita que uma variável seja inicializada junto com sua declaração. • Linguagens como Java fazem inicialização default dos atributos da classe, ou seja, são inicializados com zero do tipo que estão amarradas. Definição de variáveis • Outras inicializações de variáveis – Inicialização através de expressões: void f(int x){ int j = x + 2; int k = j*x; } • Variáveis globais, definidas em tempo de compilação, são aceitas somente se o valor for previamente conhecido. • Variáveis local, definidas em tempo de execução, não tem essa restrição. – Inicialização de variáveis compostas: int v[3] = {1, 2, 3}; Declaração de variáveis • A declaração de uma variável serve para indicar que a variável correspondente a um identificador é definida em outro módulo ou para amarrar um identificador a uma variável existente. • Significa que o compilador não deve alocar células de memória para a variável, pois já foi feito em módulo externo ou por um outro identificador. int r = 10; int &j = r; j++ // Qual o valor de r e j depois? subprogramas • Subprogramas são funções e procedimentos escritos pelo programador fora do fluxo principal do programa. Conhecidos também como sub- rotina.• São constituídos por cabeçalho e corpo. • No cabeçalho são especificados seu identificador, sua lista de parâmetros de entrada e o tipo do retorno. – Algumas linguagens como Pascal não precisam de especificar tipo de retorno para procedimentos. • No corpo é definido a implementação e o valor de retorno. Definição de subprogramas • A definição de um subprograma contém a escrita do cabeçalho e do corpo do subprograma. Declaração de subprogramas • A declaração de um subprograma contém somente a escrita do cabeçalho. • Isso indica ao compilador que a definição do subprograma ocorrerá em outro local do programa, mas que a verificação sintática pode ser feita através do cabeçalho declarado. • Algumas linguagens como Pascal exige (em alguns casos) que os subprogramas sejam primeiramente declarados e depois definidos. Declaração de subprogramas • A declaração de um subprograma contém somente a escrita do cabeçalho. • Isso indica ao compilador que a definição do subprograma ocorrerá em outro local do programa, mas que a verificação sintática pode ser feita através do cabeçalho declarado. • Algumas linguagens como Pascal exige (em alguns casos) que os subprogramas sejam primeiramente declarados e depois definidos. “Definição de definições” • Definições podem ser compostas a partir de outras definições (definições sequenciais) ou a partir delas mesmas (definições recursivas). Definições sequenciais • Utilizam outras definições estabelecidas anteriormente no programa. • Como por exemplo, uma struct que faz uso de outra, ou um subprograma que utiliza outro. struct aluno { int matricula; char nome[30]; }; Struct turma { int ano; struct aluno listAlunos[50]; }; Definições sequenciais numeroPar :: Int -> Bool numeroPar a | mod a 2 == 0 = True | otherwise = False dividePor2 :: Int -> Bool dividePor2 a = numeroPar a Definições recursivas • São aquelas que usam as próprias amarrações que produzem. • Linguagens que não suportam recursividade perderam espaço como Fortran e Cobol. • O ideal é que a recursividade seja oferecida de forma indiscriminada, mas a maioria das LP suportam recursão somente em funções, sendo que o uso para tipos são proibidos. • A linguagem C possibilita a criação de tipos recursivos através da utilização de ponteiros. Definições recursivas Struct lista { int elemento; struct lista * proxima; }; Conclusão • O que são amarrações? • O que é ambiente e escopo? • Tipos de amarrações X tipos de identificadores. – Constantes, variáveis, subprogramas e outras definições • Diferenças entre definição e declaração.
Compartilhar