Baixe o app para aproveitar ainda mais
Prévia do material em texto
GCC 105 – LINGUAGENS DE PROGRAMAÇÃO I AULA 5 – Nomes e Vinculação 1º Semestre de 2015 Prof. Janderson Rodrigo de Oliveira Universidade Federal de Lavras Departamento de Ciência da Computação Introdução • Os dois componentes primários da arquitetura dos computadores modernos são: – Memória: armazena tanto instruções quanto dados; – Processador: fornece operações para modificar o conteúdo da memória. • As abstrações para células de memória da máquina em uma linguagem são as variáveis. • Em certos casos, as características das abstrações e das células são muito próximas. Introdução • Uma variável pode ser caracterizada por uma coleção de propriedades, ou atributos, das quais a mais importante é o tipo. • O projeto dos tipos de dados de uma linguagem requer que sejam consideradas diversas questões (Aulas 3 e 4). • Terminologia adotada na disciplina: – Fortran: todas as versões do Fortran – o mesmo caso de Ada; – C: versão original, C89 e C90; – Linguagens baseadas em C: C, C++, Java e C#. Nomes • Nome: outro atributo fundamental das variáveis. • Também associado com subprogramas, parâmetros formais e outras construções. • O termo identificador é muito utilizado como sinônimo de nome. • Características a serem consideradas: – Formato dos nomes; – Palavras Especiais. Nomes • Formato dos nomes: – Um nome é uma cadeia de caracteres usada para identificar alguma entidade em um programa. – O Fortran 95 permite até 31 caracteres em seus nomes. – O C99 não tem limitação em seus nomes internos, mas apenas os 63 primeiros são significativos. – Nomes em Java, C# e Ada não têm limites de tamanho e todos os caracteres são significativos. Nomes – Observação histórica: as primeiras linguagens de programação usavam nomes com apenas um único caractere. – Os nomes, na maioria das linguagens de programação, têm o mesmo formato: uma letra seguida por uma cadeia de letras, dígitos e sublinhados (_). – Todos os nomes de variáveis em PHP devem começar com um cifrão. Em Perl, o caractere especial no início do nome de uma variável, $, @ ou %, especifica o seu tipo. Nomes – Em muitas linguagens, mais notavelmente nas baseadas em C, as letras maiúsculas e minúsculas nos nomes são distintas; ou seja, são sensíveis à capitalização. – Por exemplo: os três nomes seguintes são distintos em C++: auxiliar, AUXILIAR e Auxiliar. – A sensibilidade à capitalização reflete positivamente ou negativamente na legibilidade? E na facilidade de escrita? Nomes • Palavras especiais: – Palavras especiais em linguagens de programação são usadas para : • tornar os programas mais legíveis ao nomearem as ações a serem realizadas. • separar as partes sintáticas das sentenças e programas. – Na maioria das linguagens, elas são classificadas como palavras reservadas, mas em algumas são apenas palavras-chave. Nomes • Palavras especiais: – Uma palavra-chave é uma palavra de uma linguagem de programação especial apenas em alguns contextos. – Fortran é a única linguagem bastante usada cujas palavras especiais são palavras-chave. Exemplo: Integer. • Quando no início de uma sentença e acompanhada por um nome: indica que a sentença é declarativa. • Quando seguida por um operador de atribuição: é considerada um nome de variável. Integer Auxiliar Integer = 4 Nomes • Palavras especiais: – Uma palavra reservada é uma palavra especial de uma linguagem de programação que não pode ser usada como um nome. – Existe um problema em potencial com as palavras reservadas: se a linguagem incluir um grande número de palavras reservadas, o usuário tem dificuldades para inventar nomes que não são reservados. Exemplo: COBOL, que tem 300 palavras reservadas. Nomes • Palavras especiais: – Na maioria das linguagens, nomes que são definidos em outras unidades de programa, como os pacotes em Java e as bibliotecas em C e C++, podem ser tornados visíveis para um programa. – Esses nomes são pré-definidos, mas visíveis apenas se explicitamente importados. Uma vez importados, eles não podem ser redefinidos pelo usuário. Variáveis • Uma variável de programa é uma abstração de uma célula de memória de um computador ou de uma coleção de células. • Contexto histórico: a mudança das linguagens de máquina para as de montagem era dirigida pela necessidade de substituir endereços numéricos e absolutos de memória para dados por nomes, tornando os programas muito mais legíveis e mais fáceis de serem escritos e mantidos. • Quais são os atributos de uma variável? Variáveis • Uma variável pode ser caracterizada como um conjunto de seis atributos: – Nome; – Endereço; – Tipo; – Valor; – Tempo de vida; – Escopo. Variáveis • Nome: – Os nomes de variáveis são os mais comuns nos programas. – Correspondem a identificadores para entidades do programa (variáveis, subprogramas, parâmetros formais e outras construções). – A maioria das variáveis são nomeadas. Variáveis • Endereço: – O endereço de uma variável é o endereço de memória de máquina ao qual ela está associada. – Em muitas linguagens, é possível que a mesma variável seja associada com diferentes endereços em vários momentos em um programa. Exemplo: variável local em um subprograma. – O endereço de uma variável é algumas vezes chamado de seu valor esquerdo (l-value), porque o endereço é o que é necessário quando uma variável aparece no lado esquerdo de uma atribuição. Variáveis • Endereço: – É possível haver múltiplas variáveis com o mesmo endereço. – Quando mais de uma variável pode ser usada para acessar a mesma posição de memória, elas são chamadas de apelidos (aliases). – O uso de apelidos é um problema para a legibilidade. • Permite que uma variável tenha seu valor modificado por uma atribuição à uma variável diferente. Variáveis • Endereço: – Duas variáveis de ponteiro são apelidos quando elas apontam para a mesma posição de memória. • Quando um ponteiro em C++ é configurado para apontar para uma variável nomeada, o ponteiro desreferenciado e o nome da variável são apelidos. – O mesmo ocorre com as variáveis referências. Variáveis • Tipo: – O tipo de uma variável determina a faixa de valores que ela pode armazenar e o conjunto de operações definidas para valores do tipo. – Exemplo: o tipo int em Java especifica: • Faixa de valores: -2.147.483.648 a 2.147.483.647. • Operações: adição, subtração, multiplicação, divisão e módulo. Variáveis • Valor: – O valor de uma variável é o conteúdo da(s) célula(s) de memória associada(s) a ela. – O valor de uma variável é algumas vezes chamado de lado direito (r-value) porque é requerido quando a variável é usada no lado direito de uma sentença de atribuição. – Para acessar o lado direito, o lado esquerdo precisa primeiro ser determinado. Vinculação • Uma vinculação é uma associação, como entre um atributo e uma entidade ou entre uma operação e um símbolo. • O momento no qual uma vinculação ocorre é chamado de tempo de vinculação. • As vinculações podem ocorrer em tempo de projeto de projeto da linguagem, em tempo de implementação, em tempo de compilação, em tempo de ligação ou em tempo de execução. Vinculação • Exemplos: – Tempo de projeto: o símbolo (*) é geralmente ligado à operação de multiplicação; – Tempo de implementação: um tipo de dados int em C é vinculado a uma faixa de valores possíveis; – Tempo de compilação: uma variável em um programa Java é vinculada a um tipo de dado em particular. Vinculação • Vinculação de atributos a variáveis: – Uma vinculação é estática se ela ocorre pela primeira vez antes do tempo de execuçãoe permanece intocada ao longo da execução do programa. – Se a vinculação ocorre pela primeira vez durante o tempo de execução ou pode ser mudada ao longo do curso de execução do programa, a mesma é chamada de dinâmica. Vinculação • Vinculação de tipos: – Vinculação de tipos estática: os tipos podem ser especificados explicitamente ou implicitamente. – Uma declaração explícita é uma sentença em um programa que lista nomes de variáveis e especifica que elas são de um certo tipo. – Uma declaração implícita é uma forma de associar variáveis a tipos por meio de convenções padronizadas, em vez de por sentenças de atribuição. A primeira aparição de um nome de variável constitui sua declaração implícita. Vinculação • Vinculação de tipos estática: – A maioria das linguagens de programação projetadas desde meados dos anos 1960 requer a declaração explícita de todas as variáveis. – Algumas exceções: Perl, JavaScript, Ruby e ML. – As declarações implícitas podem ser prejudiciais à confiabilidade porque previnem o processo de compilação de detectar alguns erros de programação e de digitação. Vinculação • Vinculação de tipos estática: – Uma alternativa para o problema das declarações implícitas: obrigar nomes para tipos específicos começarem com caracteres especiais em particular. – Exemplo: Perl • Qualquer nome que começa com $ é um escalar: pode armazenar uma cadeia ou um valor numérico; • Se começa com @ é um vetor. – Isso cria diferentes espaços de nomes para diferentes variáveis de tipo. Vinculação • Vinculação de tipos dinâmica: – O tipo de uma variável não é especificado por uma sentença de declaração, nem pode ser determinado pelo nome da variável. – A variável é vinculada a um tipo quando é atribuído um valor a ela em uma sentença de atribuição. – Quando a sentença de atribuição é executada, a variável que está recebendo um valor atribuído é vinculada ao tipo do valor da expressão no lado direito da atribuição. Vinculação • Vinculação de tipos dinâmica: – Vantagem: flexibilidade maior ao programador. Exemplo: programa para processar dados numéricos. – Em JavaScript e PHP, a vinculação de uma variável a um tipo é dinâmica. Exemplo em JavaScript: list = [10.2, 3.5] list = 47 Vinculação • Vinculação de tipos dinâmica: – Desvantagem 1: torna os programas menos confiáveis. • A capacidade de detecção de erros do compilador é diminuída em relação a um compilador para uma linguagem com vinculações de tipos estáticas. • Permite valores de quaisquer tipos serem atribuídos a quaisquer variáveis. • Tipos incorretos de lados direitos não são detectados como erros. Vinculação • Vinculação de tipos dinâmica: – Desvantagem 2: custo. Principalmente em tempo de execução. • A verificação de tipos deve ser feita em tempo de execução. • Cada variável deve ter um descritor associado em tempo de execução de forma a manter o tipo atual. • O armazenamento usado para o valor de uma variável deve ser de tamanho variável. Vinculação • Vinculações de armazenamento e tempo de vida: – A célula de memória à qual uma variável é vinculada deve ser obtida, de alguma forma, de um conjunto de células de memória disponíveis. Esse processo é chamado de alocação. – Liberação é o processo de colocar uma célula de memória que foi desvinculada de uma variável de volta ao conjunto de células de memória disponíveis. Vinculação • Vinculações de armazenamento e tempo de vida: – O tempo de vida de uma variável é definido como o tempo durante o qual ela está vinculada a uma posição específica da memória. – Segundo as características das vinculações de armazenamento das variáveis, é conveniente separar as variáveis escalares (não estruturadas) em quatro categorias: • Estáticas; • Dinâmicas da pilha; • Dinâmicas do monte explícitas; • Dinâmicas do monte implícitas. Vinculação • Variáveis estáticas – São vinculadas a células de memória antes do início da execução de um programa e permanecem vinculadas a essas mesmas células até que a execução termine. – Exemplo: variáveis acessíveis globalmente são usadas ao longo da execução de um programa. – Vantagem: eficiência. Todo endereçamento de variáveis estáticas pode ser direto. Vinculação • Variáveis estáticas – Desvantagem: redução da flexibilidade. – Em particular, uma linguagem que tenha apenas variáveis estáticas não permite o uso de subprogramas recursivos. Vinculação • Variáveis dinâmicas da pilha – Variáveis dinâmicas da pilha são aquelas cujas vinculações de armazenamento são criadas quando suas sentenças de declaração são elaboradas, mas cujos tipos são estaticamente vinculados. – A elaboração se refere à alocação do armazenamento e ao processo de vinculação indicado pela declaração. A elaboração ocorre apenas em tempo de execução. – Como o nome indica, as variáveis dinâmicas da pilha são alocadas a partir da pilha de tempo de execução. Vinculação • Variáveis dinâmicas da pilha – Exemplo: as declarações de variáveis que aparecem no início de um método Java são elaboradas quando o método é chamado e as variáveis definidas por essas declarações são liberadas quando o método completa sua execução. – Variáveis definidas em métodos em Java, C++ e C# são dinâmicas da pilha. Vinculação • Variáveis dinâmicas da pilha – Programas recursivos requerem armazenamento dinâmico local. – Desvantagens: • sobrecarga em tempo de execução da alocação e liberação; • endereçamento indireto. Vinculação • Variáveis dinâmicas do monte explícitas – São células de memória não nomeadas (abstratas) alocadas e liberadas por instruções explícitas em tempo de execução pelo programador. – Essas variáveis, alocadas a partir do monte e liberadas para o monte, podem apenas ser referenciadas por ponteiros ou variáveis de referência. – O monte (heap) é uma coleção de células de armazenamento, cuja organização é altamente desorganizada, por causa da imprevisibilidade de seu uso. Vinculação • Variáveis dinâmicas do monte explícitas – Uma variável dinâmica do monte explícita é criada ou por meio de um operador (exemplo: C++) ou de uma chamada a um subprograma de sistema fornecido para esse propósito (exemplo: C). – Em C++, o operador de alocação (new) usa um nome de tipo como seu operando e retorna um ponteiro para uma variável dinâmica do monte explícita do tipo de dado de seu operado. Vinculação • Variáveis dinâmicas do monte explícitas – Algumas linguagens incluem um subprograma ou operador para explicitamente destruir variáveis dinâmicas do monte explícitas. – Exemplo: int *intNode; //Cria um ponteiro intNode = new int; //Cria a variável dinâmica do monte ... delete intNode; //Libera a variável dinâmica do monte Vinculação • Variáveis dinâmicas do monte explícitas – Aplicações: construir estruturas dinâmicas, como listas ligadas e árvores, que precisam crescer e/ou diminuir de tamanho durante a execução. – Desvantagens: • Dificuldade de usar ponteiros e variáveis de referência corretamente. • Complexidade da implementação do gerenciamento de armazenamento. Vinculação • Variáveis dinâmicas do monte implícitas – São vinculadas ao armazenamento no monte apenas quando são atribuídos valores a elas. – São apenas nomes que se adaptam a qualquer uso para o qual são solicitadas a atender. Exemplo em JavaScript: alturas = [74, 84, 86, 90, 71] Vinculação • Variáveis dinâmicas do monte implícitas – Independentemente se a variável alturas foi previamente usada no programa ou para que foi usada, ela agora é um vetor de cinco valores numéricos. – Vantagem: flexibilidade. Permite códigosaltamente genéricos. – Desvantagens: • Sobrecarga em tempo de execução para manter todos os atributos dinâmicos; • Perda de alguma detecção de erros pelo compilador.
Compartilhar