Você está na página 1de 39

Resumão de CLP - P2

Fonte: Material do Edirlei, livro e aulas do


Bernardo

O que é uma linguagem de programação?


Na programação de computadores, uma
linguagem de programação serve como meio
de comunicação entre o indivíduo que deseja
resolver um determinado problema e o
computador. A linguagem de programação
deve fazer a ligação entre o pensamento
humano (muitas vezes de natureza não
estruturada) e a precisão requerida para o
processamento pelo computador.
De forma geral são abstrações da arquitetura
de computadores.

O que são 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. Os programadores
geralmente pensam em variáveis como nomes
para locais de memória, mas existe muito mais
acerca de uma variável do que apenas um
nome.
Variáveis possuem nome, tipo, valor, tamanho,
endereço, escopo e tempo de vida.

Apelidos (aliases)

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 porque permite que uma
variável tenha seu valor modificado por uma
atribuição à uma variável diferente. Por
exemplo, se as variáveis total e soma são
apelidos, quaisquer mudanças à total também
modificam soma e vice-versa.
Duas variáveis de ponteiro são apelidos
quando elas apontam para a mesma posição
de memória. O mesmo ocorre com as variáveis
de referência.

Vinculação
De um modo geral, 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.

- Considere a seguinte sentença em Java:


count = count + 5;
Algumas das vinculações e seus tempos de
vinculação para as partes dessa sentença
são:
• O tipo de count é vinculado em tempo de
compilação.
• O conjunto dos valores possíveis de count
é vinculado em tempo de
projeto do compilador.
• O significado do símbolo de operador + é
vinculado em tempo de compilação,
quando os tipos dos operandos tiverem
sido determinados.
• A representação interna do literal 5 é
vinculada ao tempo de projeto do
compilador.
• O valor de count é vinculado em tempo de
execução com essa sentença

- Tempo de projeto
- Tempo de compilação
- Tempo de carga
- Tempo de ligação
- Tempo de execução
- Tempo de implementação

Vinculação de atributos a variáveis

Uma vinculação é estática se ela ocorre


pela primeira vez antes do tempo de execução
e 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 da
execução do programa, é chamada de
dinâmica. A vinculação física de uma variável a
uma célula de armazenamento em um
ambiente de memória virtual é complexa,
porque a página ou o segmento do espaço de
endereçamento no qual a célula reside pode
ser movido para dentro ou para fora da
memória muitas vezes durante a execução do
programa. De certa forma, tais variáveis são
vinculadas e desvinculadas repetidamente.

Vinculação de tipo
Antes de uma variável poder ser
referenciada em um programa, ela deve ser
vinculada a um tipo de dados. Os dois aspectos
importantes dessa vinculação são como o tipo
é especificado e quando a vinculação ocorre.
Os tipos podem ser especificados
estaticamente por alguma forma de declaração
explícita ou implícita.

Vinculação de tipo estática

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 declaração. Nesse
caso, a primeira aparição de um nome de
variável em um programa constitui sua
declaração implícita. Tanto as declarações
explícitas quanto implícitas criam
vinculações estáticas a tipos.
Em Fortran, um identificador que
aparece em um programa e não é
explicitamente declarado é implicitamente
declarado de acordo com a seguinte
convenção: se o identificador começar com
uma das letras I, J, K, L, M ou N, ou em
suas versões minúsculas, ele é
implicitamente declarado do tipo Integer;
caso contrário, é implicitamente declarado
do tipo Real.
Apesar de serem uma pequena
conveniência para os programadores, 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. No Fortran, as variáveis
acidentalmente deixadas sem declaração
pelo programador recebem tipos
padronizados e atributos inesperados, que
podem causar erros sutis difíceis de ser
diagnosticados.
Vinculação de tipos dinâmica

Com a 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. Em
vez disso, 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.
As linguagens nas quais os tipos são
vinculados dinamicamente são
drasticamente diferentes daquelas nas
quais os tipos são vinculados
estaticamente.
A vantagem principal da vinculação
dinâmica de variáveis a tipos é que ela
fornece uma flexibilidade maior ao
programador. Por exemplo, um programa
para processar dados numéricos em uma
linguagem que usa a vinculação de tipos
dinâmica pode ser escrito como um
programa genérico, ou seja, ele será capaz
de tratar dados de quaisquer tipos
numéricos.
Existem duas desvantagens da
vinculação de tipos dinâmica. Primeiro, ela
faz os programas serem menos confiáveis,
porque a capacidade de detecção de erros
do compilador é diminuída em relação a um
compilador para uma linguagem com
vinculações de tipo estáticas. A vinculação
de tipos dinâmica permite valores de
quaisquer tipos serem atribuídos a
quaisquer variáveis. Tipos incorretos de
lados direitos de atribuições não são
detectados como erros; em vez disso, o
tipo do lado esquerdo é trocado para o tipo
incorreto. Por exemplo, suponha que em
um programa JavaScript em particular, i e x
estivessem armazenando valores
numéricos escalares e y estivesse
armazenando um vetor. Além disso,
suponha que o programa precise da
sentença de atribuição
i = x;
mas por causa de um erro de digitação, ele
tem a seguinte sentença de atribuição
i = y;
Em JavaScript (ou qualquer outra
linguagem que usa vinculação de tipos
dinâmica), nenhum erro é detectado nessa
sentença pelo interpretador – i
simplesmente se transforma em um vetor.
Mas os resultados seguintes de i esperam
que ele seja um escalar, e resultados
corretos serão impossíveis. Em uma
linguagem com vinculação de tipos
estática, como Java, o compilador
detectaria o erro na atribuição i = y, e o
programa não seria executado.

Vinculação 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.
O tempo de vida de uma variável é o durante o
qual ela está vinculada a uma posição
específica da memória. Então, o tempo de vida
de uma variável começa quando ela é
vinculada a uma célula específica e termina
quando ela é desvinculada dessa célula .

Variáveis estáticas

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 do programa termine.
Variáveis vinculadas estaticamente têm
diversas aplicações valiosas em
programação. Variáveis acessíveis
globalmente são usadas ao longo da
execução de um programa, tornando
necessário tê-las vinculadas ao mesmo
armazenamento durante essa execução.
Algumas vezes, é conveniente ter
subprogramas sensíveis ao histórico. Tal
subprograma deve ter variáveis locais
estáticas.
Outra vantagem das variáveis estáticas
é a eficiência. Todo o endereçamento de
variáveis estáticas pode ser direto; outros
tipos de variáveis geralmente requerem
endereçamento indireto, que é mais lento.
Além disso, não há sobrecarga em tempo
de execução para a alocação e a liberação
de variáveis estáticas, apesar de esse
tempo ser normalmente negligenciável.
Uma desvantagem da vinculação
estática ao armazenamento é a redução da
flexibilidade; em particular, uma linguagem
que tem apenas variáveis estáticas não
permite o uso de subprogramas recursivos.
Outra desvantagem é o armazenamento
não ser compartilhado entre variáveis. Por
exemplo, suponha que um programa tem
dois subprogramas que requerem grandes
vetores. Suponha, também, que os dois
subprogramas nunca estão ativos ao
mesmo tempo. Se os vetores são estáticos,
eles não podem compartilhar o mesmo
armazenamento para seus vetores.

ESCOPO

Um dos fatores mais importantes para o


entendimento das variáveis é o escopo. O
escopo de uma variável é a faixa de sentenças
nas quais ela é visível. Uma variável é visível
em uma sentença se ela pode ser referenciada
nessa sentença. As regras de escopo de uma
linguagem determinam como uma ocorrência
em particular de um nome é associada com
uma variável.

Escopo estático

O escopo estático é chamado assim


porque o escopo de uma variável pode ser
determinado estaticamente – ou seja, antes da
execução. Isso permite a um leitor de
programas humano (e um compilador)
determinar o tipo de cada variável.
Existem duas categorias de linguagens de
escopo estático: aquelas nas quais os
subprogramas podem ser aninhados, as quais
criam escopos estáticos aninhados, e aquelas
nas quais os subprogramas não podem ser
aninhados. Nessa última categoria, os escopos
estáticos também são criados para
subprogramas, mas os aninhados são criados
apenas por definições de classes aninhadas ou
de blocos aninhados
Considere o seguinte procedimento em
Ada, chamado Big, no qual estão aninhados os
procedimentos Sub1 e Sub2:
procedure Big is
X : Integer;
procedure Sub1 is
X : Integer;
begin -- de Sub1
...
end; -- de Sub1
procedure Sub2 is
begin -- de Sub2
...X...
end; -- de Sub2
begin -- de Big
...
end; -- de Big

De acordo com o escopo estático, a


referência à variável X em Sub2 é para o X
declarado no procedimento Big. Isso é verdade
porque a busca por X começa no procedimento
no qual a referência ocorre, Sub2, mas
nenhuma declaração para X é encontrada lá. A
busca continua no pai estático de Sub2, Big,
onde a declaração de X é encontrada. O X
declarado em Sub1 é ignorado, porque ele não
está nos ancestrais estáticos de Sub2.

Escopo dinâmico

O escopo dinâmico é baseado na


sequência de chamadas de subprogramas, não
em seu relacionamento espacial uns com os
outros. Logo, o escopo pode ser determinado
apenas em tempo de execução.
Considere o procedimento Big:

procedure Big is
X : Integer;
procedure Sub1 is
X : Integer;
begin -- de Sub1
...
end; -- de Sub1
procedure Sub2 is
begin -- de Sub2
...X...
end; -- de Sub2
begin -- de Big
...
end; -- de Big

Assuma que as regras de escopo dinâmico


se aplicam a referências não locais. O
significado do identificador X referenciado em
Sub2 é dinâmico – ele não pode ser
determinado em tempo de compilação. Ele
pode referenciar a qualquer uma das
declarações de X, dependendo da sequência
de chamadas.
Uma maneira pela qual o significado
correto de X pode ser determinado em tempo
de execução é iniciar a busca com as variáveis
locais. Essa também é a maneira pela qual o
processo começa no escopo estático, mas é
aqui que a similaridade entre os dois tipos de
escopo termina. Quando a busca por
declarações locais falha, as declarações do pai
dinâmico, o procedimento que o chamou, são
procuradas. Se uma declaração para X não é
encontrada lá, a busca continua no pai
dinâmico desse procedimento chamador, e
assim por diante, até que uma declaração de X
seja encontrada. Se nenhuma for encontrada
em nenhum ancestral dinâmico, ocorre um erro
em tempo de execução.
Considere as duas sequências de
chamadas diferentes para Sub2 no exemplo
anterior. Primeiro, Big chama Sub1, que chama
Sub2. Nesse caso, a busca contínua a partir do
procedimento local, Sub2, para seu chamador,
Sub1, onde uma declaração de X é encontrada.
Logo, a referência a X em Sub2, nesse caso, é
para o X declarado em Sub1. A seguir, Sub2 é
chamado diretamente por Big. Nesse caso, o
pai dinâmico de Sub2 é Big, e a referência é
para o X declarado em Big.
Note que se o escopo estático fosse usado,
em qualquer uma das sequências de
chamadas discutidas, a referência a X em Sub2
seria o X de Big.

CAPÍTULO 6

TIPOS PRIMITIVOS
São tipos de dados não definidos em
termos de outros e alguns dos tipos primitivos
são meramente reflexos de hardware – por
exemplo, a maioria dos tipos inteiros. Outros
requerem apenas um pouco de suporte externo
ao hardware para sua implementação. São
usados, com um ou mais construtores de tipo,
para fornecer os tipos estruturados.

MATRIZES

Em muitas linguagens, como C, C++, Java,


Ada e C#, todos os elementos de uma matriz
precisam ser do mesmo tipo. Nelas, ponteiros e
referências são restritos, para que possam
apontar ou referenciar um único tipo, de forma
que os objetos ou valores de dados sendo
apontados ou referenciados são também de um
tipo único. Em outras linguagens, como
JavaScript, Python e Ruby, as variáveis são
referências sem tipo para objetos ou valores de
dados. Nesses casos, as matrizes ainda
consistem em elementos de um único tipo, mas
os elementos podem referenciar objetos ou
valores de dados de tipos diferentes. Tais
vetores ainda são homogêneos, porque os
elementos da matriz são do mesmo tipo.

Tipos são permitidos para índices


Normalmente é utilizado uma subfaixa do
tipo inteiro, mas algumas linguagens como
Ada, permitem o uso de outros tipos ordinais
como: booleanos*, caracteres e enumerações.
* Como? e se houver + de 2 elementos?

Matrizes Regulares

Uma matriz retangular é uma


multidimensional na qual todas as linhas têm o
mesmo número de elementos, todas as
colunas têm o mesmo número de elementos.
Uma matriz irregular é uma na qual o tamanho
das linhas não precisa ser o mesmo. Por
exemplo, uma matriz irregular pode ser
composta de três linhas, uma com 5 elementos,
uma com 7 e outra com 12. Isso também se
aplica às colunas e às dimensões superiores.
Então, se existir uma terceira dimensão
(camadas), cada camada pode ter um número
diferente de elementos.
Matrizes Irregulares

Matrizes irregulares são possíveis quando


as multidimensionais são matrizes de matrizes.
Por exemplo, uma matriz poderia aparecer
como uma matriz de matrizes de uma
dimensão.

As matrizes multidimensionais
irregulares ou retangulares são permitidas,
ou ambas?

Isso vai depender da linguagem, pois


algumas oferecem suporte somente para
matrizes irregulares, como C, C++ e Java.
Nessas linguagens, uma referência a um
elemento de uma matriz multidimensional usa
um par de colchetes separado para cada
dimensão(Ex, meuArray[3][7]).
Outras linguagens oferecem suporte
somente a matrizes quadradas como Fortran e
Ada em que referências a elementos são
colocadas em um único par de colchetes (Ex.
meuArray[3, 7] ). Uma linguagem que oferece
suporte a ambas é o C#.
REGISTRO

Um registro é um agregado de elementos


de dados no qual os elementos individuais são
identificados por nomes e acessados por meio
de deslocamentos a partir do início da
estrutura. Em geral, existe uma necessidade
nos programas de modelar coleções de dados
que não são do mesmo tipo ou tamanho. Por
exemplo, informações sobre um estudante
universitário podem incluir seu nome, seu
número de estudante, sua média de notas no
histórico e assim por diante. Um tipo de dados
para tal coleção pode usar uma cadeia de
caracteres para o nome, um inteiro para o
número de estudante, um ponto flutuante para
a média de notas no histórico e assim por
diante. Registros são projetados para esse tipo
de necessidade.
A diferença fundamental entre um registro
e uma matriz é que elementos de registro, ou
campos, não são referenciados por índices. Em
vez disso, os campos são nomeados com
identificadores, e referências para os campos
são feitas usando esses identificadores.
PONTEIROS

Um tipo ponteiro é um no qual as variáveis


têm uma faixa de valores que consistem em
endereços de memória e um valor especial, nil.
O valor nil não é um endereço válido e é usado
para indicar que um ponteiro não pode ser
usado atualmente para referenciar uma célula
de memória.

Ponteiros são projetados para dois tipos de


uso:
● Endereçamento indireto:
○ Frequentemente usado em
programação de linguagem de
montagem.

● Gerenciar o armazenamento dinâmico:


○ Um ponteiro pode ser usado para
acessar uma posição na área onde
o armazenamento é
dinamicamente alocado, chamado
de monte (heap).

As variáveis dinamicamente alocadas a


partir do monte são chamadas de variáveis
dinâmicas do monte. Em geral, elas não
têm identificadores associadas a elas e
logo podem ser referenciadas apenas por
variáveis dos tipos ponteiro ou referência.
Variáveis sem nomes são chamadas de
variáveis anônimas. É nessa última área de
aplicação de ponteiros que surgem as
questões de projeto mais importantes.

Atribuição

Modifica o valor de uma variável de


ponteiro para algum endereço útil. Se as
variáveis de ponteiro são usadas apenas
para gerenciar armazenamento dinâmico, o
mecanismo de alocação, seja por operador
ou por subprograma pré-definido, serve
para inicializar a variável de ponteiro. Se os
ponteiros são usados para endereçamento
indireto às variáveis que não são dinâmicas
do monte, então deve existir um operador
explícito ou um subprograma pré-definido
para obter o endereço de uma variável, o
qual pode ser então atribuído à variável de
ponteiro.
Desreferenciamento

Desreferenciar, que leva uma


referência por meio de um nível de
indireção, é a segunda operação
fundamental dos ponteiros.

O ponteiro também poderia ser


interpretado como uma referência ao valor
dentro da célula de memória apontado pela
célula a qual a variável de ponteiro está
vinculada. Nesse caso, o ponteiro é
interpretado como uma referência indireta.
O desreferenciamento de ponteiros
pode ser tanto explícito quanto implícito. No
Fortran 95, é implícito, mas em muitas
outras linguagens contemporâneas, ocorre
apenas quando explicitamente
especificado. Em C++, ele é explicitamente
especificado com o asterisco (*) como um
operador unário pré-fixado.

Ponteiros soltos

Um ponteiro solto*, ou referência solta,


é um ponteiro que contém o endereço de
uma variável dinâmica do monte já
liberada. Ponteiros soltos são perigosos por
diversas razões. Primeiro, a posição sendo
apontada pode ter sido realocada para
alguma variável dinâmica do monte nova.
Se a nova variável não for do mesmo tipo
da antiga, as verificações de tipos dos usos
do ponteiro solto são inválidas. Ainda que a
nova variável dinâmica seja do mesmo tipo,
seu novo valor não terá relacionamento
com o valor desreferenciado do ponteiro
antigo.
Variáveis dinâmicas do monte perdidas

Uma variável dinâmica do monte perdida é


uma alocada que não está mais acessível
para os programas de usuário. Elas são
frequentemente chamadas de lixo, pois não
são úteis para seus propósitos originais e
não podem ser realocadas para algum
novo uso no programa. Variáveis dinâmicas
do monte perdidas são em geral criadas
pela seguinte sequência de operações:

1. O ponteiro p1 é configurado para


apontar para uma variável dinâmica do
monte recém-criada.
2. p1 é posteriormente configurado para
apontar para outra variável dinâmica do
monte recém-criada.

A primeira variável dinâmica do monte


é agora inacessível, ou perdida. Isso às
vezes é chamado de vazamento de
memória e, independentemente de a
linguagem usar liberação implícita ou
explícita, é um problema.
CAPÍTULO 5

1) O que é apelido de uma variável?


R.: São variáveis que podem ser usadas para
acessar a mesma posição de memória.
Duas variáveis de ponteiro são apelidos
quando elas apontam para a mesma posição
de memória. O mesmo ocorre com as variáveis
de referência.

2) Cite três atributos das variáveis.


R.: Nome, endereço e tipo.

3) Defina vinculação e tempo de vinculação.


R.: De um modo geral, vinculação é uma
associação, como entre um atributo e uma
entidade ou entre uma operação e um símbolo.
Tempo de vinculação é o momento no qual
uma vinculação ocorre.

4) Quais são as vantagens de declaração


implícita?
R.: É uma forma de conveniência para o
programador declarar o tipo da variável. Como
no Fortran, que para declarar uma variável do
tipo inteiro, as inicializam com I, J, K, L M, N e
O, e também na forma minúscula.

R-2.: Tanto as declarações explícitas quanto


implícitas criam vinculações estáticas de tipos,
logo assim como vinculações estáticas, todo o
endereçamento pode ser feito de forma direta,
não há sobrecarga em tempo de execução
para a alocação e a liberação de variáveis
estáticas.

5) Cite três vantagens das linguagens que


não requerem declaração de variáveis.
R.: Fornece uma flexibilidade maior ao
programador. Por exemplo, um programa pode
ser escrito como um programa genérico, ou
seja, ele será capaz de tratar dados de
quaisquer tipos numéricos.

6) Explique a relação entre vinculação


dinâmica e variáveis dinâmicas.
R.: A células de memória de variáveis
dinâmicas são alocadas durante o tempo de
execução, e com isso, são feitas as
vinculações. Como é durante o tempo de
execução logo, as vinculações serão do tipo
dinâmico. (Tá certo isso galera?)Superficial,
mas acho que sim. Me ajude nessa cara.
Vamos aprofundar mais isso aí!

7) Qual a diferença entre escopo estático e


dinâmico. Dê exemplos.
R.: No escopo estático se uma variável é
declarada com o mesmo nome dentro de uma
função, o valor dela será o primeiro declarado
no programa. Já no dinâmico o valor
representado por essa variável sempre será o
mais recente, ou seja o último a ter sido
declarado. (CERTO? )

R-2.: O escopo estático é chamado assim


porque o escopo de uma variável pode ser
determinado estaticamente – ou seja, antes da
execução. Isso permite a um leitor de
programas humano (e um compilador)
determinar o tipo de cada variável.
O escopo dinâmico é baseado na
sequência de chamadas de subprogramas, não
em seu relacionamento espacial uns com os
outros. Logo, o escopo pode ser determinado
apenas em tempo de execução.
MAIS QUESTÕES

1. O que são palavras-reservadas?


R.: São palavras especiais que não podem
ser utilizadas para uso de nomeação de
variáveis e funções, pois pertencem à
gramática da linguagem.

2. O que é sensibilidade à capitalização?


R.: É quando uma mesma palavra escrita
na forma minúscula denotar um significado
diferente a sua forma maiúscula. Ou seja, para
uma linguagem com sensibilidade a
capitalização, as palavras iprj, IPRJ e ipRJ são
nomes diferentes.

3. O que é endereço de memória?


4. Quais são os tipos primitivos comuns às
linguagens?
R.: Geralmente, os tipos primitivos das
linguagens de programação são: numéricos,
booleanos e de caracteres.

5. O que é vinculação estática?


6. O que é vinculação dinâmica?
7. O que tempo de vida de uma variável?
8.

CAPÍTULO 6

TIPOS

1. O que são tipos primitivos?


Resp. Simples: São tipos de dados não
definidos em termos de outros.

Resp. Completa: São tipos de dados não


definidos em termos de outros e alguns dos
tipos primitivos são meramente reflexos de
hardware – por exemplo, a maioria dos tipos
inteiros. Outros requerem apenas um pouco de
suporte externo ao hardware para sua
implementação. São usados, com um ou mais
construtores de tipo, para fornecer os tipos
estruturados.

Matrizes

Questões de projeto:
1. Os elementos de uma matriz necessitam
ser do mesmo tipo?
Resp. Simples: Na maioria das
linguagens, como C, C++ e Java, é necessário
que todos os elementos sejam no mesmo tipo,
pois ponteiros e referências apontam para um
único tipo e os dados apontados e
referenciados também são de tipo único. No
entanto, existem outras linguagens como
JavaScript, Python e Ruby em que as matrizes
ainda consistem em elementos de um único
tipo, mas os elementos podem referenciar
objetos ou valores de dados de tipos diferentes.

Resp. Completa: Em muitas linguagens,


como C, C++, Java, Ada e C#, todos os
elementos de uma matriz precisam ser do
mesmo tipo. Nelas, ponteiros e referências são
restritos, para que possam apontar ou
referenciar um único tipo, de forma que os
objetos ou valores de dados sendo apontados
ou referenciados são também de um tipo único.
Em outras linguagens, como JavaScript,
Python e Ruby, as variáveis são referências
sem tipo para objetos ou valores de dados.
Nesses casos, as matrizes ainda consistem em
elementos de um único tipo, mas os elementos
podem referenciar objetos ou valores de dados
de tipos diferentes. Tais vetores ainda são
homogêneos, porque os elementos da matriz
são do mesmo tipo.

2. Que tipos são permitidos para índices?


R.: Normalmente é utilizado uma subfaixa
do tipo inteiro, mas algumas linguagens como
Ada, permitem o uso de outros tipos ordinais
como: booleanos*, caracteres e enumerações.
* Como? e se houver + de 2 elementos?

3. Quando as faixas de índices são


vinculadas?

4. Quando ocorre a alocação da matriz?

5. Defina matrizes irregulares e regulares.


Resp. Simples: Uma matriz retangular é
uma multidimensional na qual todas as linhas
têm o mesmo número de elementos, todas as
colunas têm o mesmo número de elementos.
Uma matriz irregular é uma na qual o tamanho
das linhas não precisa ser o mesmo. Matrizes
irregulares são possíveis quando as
multidimensionais são matrizes de matrizes.
Por exemplo, uma matriz poderia aparecer
como uma matriz de matrizes de uma
dimensão.

Resp. Completa: Uma matriz retangular


é uma multidimensional na qual todas as linhas
têm o mesmo número de elementos, todas as
colunas têm o mesmo número de elementos.
Uma matriz irregular é uma na qual o tamanho
das linhas não precisa ser o mesmo. Por
exemplo, uma matriz irregular pode ser
composta de três linhas, uma com 5 elementos,
uma com 7 e outra com 12. Isso também se
aplica às colunas e às dimensões superiores.
Então, se existir uma terceira dimensão
(camadas), cada camada pode ter um número
diferente de elementos. Matrizes irregulares
são possíveis quando as multidimensionais são
matrizes de matrizes. Por exemplo, uma matriz
poderia aparecer como uma matriz de matrizes
de uma dimensão.

6. As matrizes multidimensionais
irregulares ou retangulares são
permitidas, ou ambas?
R.: Isso vai depender da linguagem, pois
algumas oferecem suporte somente para
matrizes irregulares, como C, C++ e Java.
Nessas linguagens, uma referência a um
elemento de uma matriz multidimensional usa
um par de colchetes separado para cada
dimensão(Ex, meuArray[3][7]).
Outras linguagens oferecem suporte
somente a matrizes quadradas como Fortran e
Ada em que referências a elementos são
colocadas em um único par de colchetes (Ex.
meuArray[3, 7] ). Uma linguagem que oferece
suporte a ambas é o C#.

7. As matrizes podem ser inicializadas


quando elas têm seu armazenamento
alocado? Que tipos de fatias são permitidas
(caso sejam)?

8. Quais são as operações com matrizes?


Cite exemplos de linguagens que
permitem tais operações.
R.: As operações do tipo algébrica são:
multiplicação e soma. Outras operações:
atribuição, concatenação e comparação
(igualdade e desigualdade).
As linguagens baseadas em C não
fornecem suporte a operações de matrizes,
exceto através de métodos presentes em Java,
C++ e C#. Ada permite atribuição e
concatenação. Python possui as operações de:
atribuição, concatenação e comparação. Uma
linguagem dedica ao processamento de
matrizes como a APL possui suporte a todas as
operações.

PONTEIROS

1. Qual é o escopo e qual é o tempo de


vida de uma variável do tipo ponteiro?

2. Qual é o tempo de vida de uma


variável dinâmica do monte?

3. Os ponteiros são restritos em relação


ao tipo de valores aos quais eles
podem apontar?

4. Os ponteiros são usados para


gerenciamento de armazenamento
dinâmico, endereçamento indireto ou
ambos?
Resumo cap 5:

A sensibilidade à capitalização e o
relacionamento de nomes com palavras
especiais, que são palavras reservadas ou
palavras-chave, são as questões de projeto
para nomes. Variáveis podem ser
caracterizadas por seis atributos: nome,
endereço, valor, tipo, tempo de vida e escopo.
Apelidos são duas ou mais variáveis vinculadas
ao mesmo endereço de armazenamento. Eles
são considerados prejudiciais à confiabilidade,
mas são difíceis de serem eliminados
completamente de uma linguagem.
A vinculação é a associação de atributos com
entidades de programa. O conhecimento dos
tempos de vinculação de atributos a entidades
é essencial para entender a semântica das
linguagens de programação. A vinculação pode
ser estática ou dinâmica. Declarações, tanto
explícitas quanto implícitas, fornecem uma
forma de especificar a vinculação estática de
variáveis a tipos. Em geral, a vinculação
dinâmica permite uma maior flexibilidade, às
custas da legibilidade, eficiência e
confiabilidade. Variáveis escalares podem ser
separadas em quatro categorias, considerando
seus tempos de vida: estáticas, dinâmicas da
pilha, dinâmicas do monte explícitas e
dinâmicas do monte implícitas. O escopo
estático é um recurso central do ALGOL 60 e
de alguns de seus descendentes. Ele fornece
um método simples, confiável e eficiente de
permitir visibilidade a variáveis não locais em
subprogramas. O escopo dinâmico fornece
mais flexibilidade do que o escopo estático,
mas à custa da legibilidade, confiabilidade e
eficiência. O ambiente de referenciamento de
uma sentença é a coleção de todas as variá-
veis visíveis para aquela sentença. Constantes
nomeadas são simplesmente variáveis
vinculadas a valores apenas uma vez.