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.