Trabalho Linguagem e Programao de Compiladores

Propaganda
Trabalho Linguagem e Programação de Compiladores





Responda as questões.
Os exercícios deverão ser desenvolvidos utilizando as estruturas apresentadas em aula e
adequadas para cada problema.
Forma
de
entrega:
Deverá
ser
enviado
um
único
e-mail
para
[email protected] contendo todos os exercícios desenvolvidos.
Data de entrega: 20/10/2015.
Regras:
o Trabalhos copiados da internet (plágio) terão notas zeradas.
o Trabalhos iguais valerão -10 pontos.
1. Ponteiros são causadores potenciais de erros em programação. Dê exemplos, com
trechos de código em C, de erros causados por ponteiros que provocam violação dos
sistemas de tipos da linguagem, ocorrência de objetos pendentes e ocorrência de
referências pendentes.
2. Uma diferença significativa entre a definição de tipos primitivos em C++ e JAVA se refere
ao intervalo de valores de cada tipo. Enquanto em JAVA os intervalos foram fixados na
definição da LP, em C++ é a implementação do compilador que define esses intervalos.
Compare estas duas abordagens, justificando a opção de cada uma dessas linguagens.
3. Arrays podem ser estáticos, semi-estáticos, semi-dinâmicos e dinâmicos. Enquanto a
criação de arrays estáticos e semi-estáticos pode ser feita facilmente em C, a construção
de arrays semi-dinâmicos e dinâmicos envolve um maior esforço de programação.
Responda como os mecanismos de C permitem a criação desses tipos de arrays. Ilustre
com exemplos.
4. Produtos cartesianos, uniões, mapeamentos e tipos recursivos são categorias de tipos
compostos de dados. Ilustre, com exemplos em C, cada um desses conceitos. Crie ainda
um novo tipo de dados que combine três desses conceitos e diga qual a sua
cardinalidade.
5. Determine a cardinalidade de cada um dos tipos abaixo, usando os conceitos de produto
cartesiano, uniões e mapeamentos para explicar a cardinalidade dos tipos compostos:
enum sexo {masculino, feminino};
enum estado_civil {solteiro, casado, divorciado};
enum classe {baixa, media, alta};
enum instrucao {primario, secundario, superior};
union cidadania {
enum classe c;
enum instrucao i;
}
struct pessoa {
enum sexo s;
enum estado_civil e;
union cidadania c;
};
struct amostra {
int n;
struct pessoa p[10];
}
6. Considere o seguinte programa escrito em C:
#include <stdio.h>
int* calcula(int a){
int p;
p = a;
if (a) {
p*=3;
} else {
p++;
};
return &p;
}
main() {
int x = 1;
int* b = calcula(x);
int* c = calcula (0);
printf("%d\n", *b);
}
Descreva o que ocorre nesse programa. Justifique sua resposta.
7. Muito embora JAVA seja fortemente influenciada por C, os projetistas dessa LP
resolveram incluir o tipo boolean, o qual não existe em C. Explique porque essa decisão
foi tomada. Dê exemplo de situação na qual a postura de C traz alguma vantagem. Faça
o mesmo em relação a postura de JAVA. Justifique suas respostas.
8. Liste pelo menos cinco diferentes tipos de amarrações que ocorrem no seguinte trecho
de código C.
float j = 3.2;
j = j – 1.7;
9. Especifique as regras de formação de identificadores de C, C++ e JAVA. Responda ainda
se existem limites no número máximo de caracteres que podem ser usados e quais tipos
de identificadores especiais são considerados.
10. Compare, em termos de legibilidade, as opções de C e C++ relativas à localização das
definições e declarações nos programas.
11. Identifique o problema que ocorre no seguinte trecho de código C. Explique porque ele
ocorre e indique como poderia ser resolvido.
void circulo () {
#define pi 3.14159
float raio = 3;
float area = pi * raio * raio;
float perimetro = 2 * pi * raio;
}
void pressao () {
float pi = 3.2, pf = 5.3;
float variacao;
variacao = pf – pi;
}
12. Sinonímia ocorre quando uma mesma variável ou constante pode ser referenciada por
mais de um nome em um mesmo ambiente de amarração. Mostre exemplos de
situações nas quais isso pode ocorrer em C e JAVA.
13. Mostre situações nas quais a permissão de acesso ao endereço de variáveis pode ser
benéfica ao programador. Mostre também quando isso pode ser prejudicial a
confiabilidade dos programas.
14. Edite o programa seguinte, compile-o e o execute. Relate o que ocorreu na compilação
e durante a execução.
main() {
char* z = “bola”;
*z = ‘c’;
printf(“%s\n”, z);
printf(“bola”);
}
15. Explique as vantagens de se utilizar um modelo de gerenciamento de memória principal
com regiões de pilha e monte em relação aos modelos que só utilizam a pilha ou só
utilizam o monte ou que alocam variáveis apenas em tempo de carga do programa.
16. Um programa deve ler uma sequência de números inteiros e imprimi-los. O programa
deve ser interrompido quando o número lido for zero. Implemente três versões desse
programa em C usando respectivamente os comandos iterativos com pré-teste, com
pós-teste e um comando de escape. Discuta as soluções apresentadas em termos de
redigibilidade e eficiência, indicando a melhor solução apresentada.
17. Descreva o que ocorre em cada trecho que culmina com impressões no seguinte
programa em C, justificando suas afirmações.
#include <stdio.h>
main () {
int a, b, c;
b = c = 10;
a = b++ + b++;
printf("%d\n", a );
printf("%d\n", b );
a = ++c + ++c;
printf("%d\n", a );
printf("%d\n", c );
b = 10;
a = b++ + b;
printf("%d\n", a );
printf("%d\n", b );
a = 10;
b = 5;
if (a>b || ++b>5)
printf("%d\n", b);
a = 1;
b = 5;
if (a>b || ++b>5)
printf("%d\n", b);
}
Esse programa em C é portável? O que ocorreria se um programa equivalente (isto é, usando
classe e com o comando apropriado de saída) fosse implementado em JAVA? Justifique todas as
suas afirmações.
18. Diga qual o valor das variáveis a e n após cada linha do seguinte trecho de código C.
Justifique suas respostas.
n = 3;
a = - n ++;
a = - n + 1;
a = - n += 1;
19. Modifique o seguinte trecho de código para que ele realize a semântica sugerida pela
sua disposição textual.
if ( x == 7 )
if ( y == 11)
z = 13;
else z = 17;
20. Implemente e teste o seguinte programa em C e descreva o que acontece. Justifique
porque isso ocorre dessa maneira (isto é, apresente o racional da decisão tomada pelos
projetistas ou implementadores dessa LP).
void f() {
int i = 10;
entra:
i++;
}
main() {
f();
goto entra;
}
21. Algumas LPs (tal como, C) consideram a operação de atribuição como sendo uma
espécie de expressão (isto é, a atribuição é uma operação que retorna um valor). Dê
exemplos de situações nas quais isso pode ser vantajoso. Diga também quando essa
característica pode ser danosa para a qualidade da programação. Justifique sua
resposta.
22. É possível implementar, para cada tipo primitivo, funções em JAVA nas quais sejam
trocados os valores dos seus parâmetros formais? Caso sua resposta seja afirmativa,
implemente uma dessas funções e explique como funciona, destacando como a troca é
feita. Em caso de resposta negativa, justifique. Existiria alguma diferença na sua
resposta caso a troca fosse realizada entre parâmetros de um mesmo tipo objeto?
Justifique
23. Um TAD (tipo abstrato de dados) é definido pelo comportamento uniforme de um
conjunto de valores. Embora a linguagem C não suporte a implementação do conceito
de TADs, o programador pode simular o seu uso. Explique como isto pode ser feito.
Descreva os problemas com essa aproximação.
24. Considere uma função em JAVA recebendo um objeto como único parâmetro e
simplesmente realizando a atribuição de null ao seu parâmetro formal. Qual o efeito
dessa atribuição no parâmetro real? Justifique.
25. Uma das vantagens de se programar usando a técnica de tipos abstratos de dados
(TADs) é aumentar a modificabilidade dos programas. Isso ocorre porque a maior parte
das alterações no código do TAD não implicam em necessidade de modificação do
código usuário. Indique em quais tipos de alterações do código do TAD essa vantagem
não pode ser aproveitada.
26. Tipos Abstratos de Dados (TADs) são uma ferramenta poderosa de projeto e
programação. Descreva, de uma forma geral, como a programação com TADs pode ser
feita em C, ADA e C++. Exemplifique com a descrição do tipo abstrato de dados fila de
elementos inteiros (não é necessário implementar as operações da fila). Compare as
três abordagens em termos de encapsulamento, ocultamento de informação,
confiabilidade do uso e necessidade de alteração do código fonte usuário quando
ocorrem alterações no código do TAD.
27. Execute o seguinte trecho de código em C++, mostrando o seu resultado.
void incrementa (int& x, int& y) {
x = x + y;
y++;
}
main ( ) {
int a [ ] = { 1, 2, 3 };
for ( int i = 0; i < 3; i++ ) {
incrementa ( a [ i ], a [ 1 ] );
cout << a [ i ] << "\n" ;
}
}
Explique como o resultado foi produzido. A execução desse código produz algum efeito
estranho prejudicial a legibilidade? Justifique sua resposta.
Download