(Poscomp, 2024) Analise as assertivas abaixo sobre estruturas em linguagens de programação:
Quais das assertivas apresentadas estão corretas?
a. apenas as assertivas I e II.
b. apenas as assertivas I e III.
c. apenas as assertivas II e III.
d. apenas as assertivas II e IV.
e. apenas as assertivas III e IV.
(Enade, 2023) Memory leak, ou vazamento de memória, é um problema que ocorre em sistemas computacionais quando uma parte da memória, alocada para uma determinada operação, não é liberada quando se torna desnecessária. Na linguagem C, esse tipo de problema é quase sempre relacionado ao uso incorreto das funções malloc()
e free()
. Esse erro de programação pode levar a falhas no sistema se a memória for completamente consumida. A partir dessas informações, assinale a opção que apresenta um trecho com memory leak.
a.
void f( ){
void *s;
s = malloc(50);
free(s);
}
b.
int f( ){
float *a;
return 0;
}
c.
int f(char *data){
void *s;
s = malloc(50);
int size = strlen(data);
if (size > 50)
return(-1);
free(s);
return 0;
}
d.
int *f(int n){
int *num = malloc(sizeof(int)*n);
return num;
}
int main(void){
int *num;
num = f(10);
free(num);
return 0;
}
e.
void f(int n){
char *m = malloc(10);
char *n = malloc(10);
free(m);
m = n;
free(m);
free(n);
}
(Poscomp, 2023) Nas linguagens de programação imperativas, o caractere + é usado para especificar a adição tanto de inteiros quanto de valores de ponto flutuante. Esse uso múltiplo de um operador é chamado de:
a. conversão de tipos.
b. sobrecarga de operadores.
c. transparência referencial.
d. efeito colateral.
e. associatividade.
(Sebesta, 2000) O custo final de uma linguagem de programação é uma função de muitas de suas características, como por exemplo, o custo de treinamento de programadores para usar a linguagem, o custo para escrever programas nessa linguagem, o custo para compilar programas na linguagem, o custo para executar os programas escritos nessa linguagem, e vários outros. De todos os fatores que contribuem para os custos de uma linguagem de programação, dois são os mais importantes e tem tido forte influência no projeto de linguagens de programação ao longo dos últimos 40 anos. Quais são eles?
O custo final de uma linguagem de programação é determinado por uma combinação de diversos fatores.
O primeiro deles é o custo de treinamento dos programadores. Esse custo está diretamente relacionado à simplicidade e à ortogonalidade da linguagem, bem como à experiência prévia dos profissionais. Embora linguagens mais poderosas não sejam necessariamente mais difíceis de aprender, frequentemente apresentam maior complexidade.
O segundo fator é o custo de desenvolvimento de programas na linguagem, que depende de sua expressividade e adequação ao domínio da aplicação. Um dos principais motivos para a criação e adoção de linguagens de alto nível foi justamente a redução dos custos envolvidos na construção de software.
Tanto o custo de treinamento quanto o de desenvolvimento podem ser significativamente reduzidos com um bom ambiente de programação.
O terceiro fator é o custo de compilação dos programas. No caso da linguagem Ada, por exemplo, sua adoção inicial foi prejudicada pelos altos custos de execução dos primeiros compiladores. Esse obstáculo foi superado com o tempo, à medida que compiladores mais eficientes foram desenvolvidos.
Em quarto lugar, está o custo de execução dos programas, fortemente influenciado pelo projeto da linguagem. Se a linguagem exigir muitas verificações em tempo de execução, a performance do código será prejudicada, mesmo que o compilador seja de alta qualidade. Embora a eficiência de execução tenha sido prioridade nas primeiras linguagens, hoje esse fator é menos determinante.
Existe, nesse contexto, um trade-off entre o tempo de compilação e a velocidade de execução do código. "Otimização" refere-se ao conjunto de técnicas utilizadas pelos compiladores para reduzir o tamanho e/ou aumentar o desempenho do código gerado. Quanto menor o esforço de otimização, mais rápida será a compilação — porém, com impacto na eficiência do código executável. A escolha entre essas alternativas depende do ambiente em que o compilador será utilizado. Em laboratórios educacionais, por exemplo, onde os programas são pequenos e executados poucas vezes, uma compilação rápida com pouca ou nenhuma otimização é preferível. Em ambientes profissionais, onde programas completos são executados repetidamente, vale a pena investir mais tempo na otimização do código.
O quinto fator refere-se ao custo do sistema de implementação da linguagem. A rápida adoção do Java pode ser explicada, em parte, pela disponibilidade imediata de compiladores e interpretadores logo após o lançamento da linguagem. Quando o sistema de implementação é caro ou depende de hardware específico e igualmente caro, as chances de uma linguagem se popularizar diminuem consideravelmente.
O sexto fator é o custo associado à falta de confiabilidade. Falhas em sistemas críticos, como os de usinas nucleares ou equipamentos médicos, podem acarretar prejuízos imensuráveis. Mesmo em sistemas não críticos, os danos podem ser significativos, especialmente se envolverem perdas comerciais ou ações judiciais motivadas por falhas de software.
Por fim, o sétimo fator é o custo de manutenção dos programas, que engloba tanto correções quanto atualizações para novas funcionalidades. A manutenção está diretamente ligada à legibilidade do código, uma vez que muitas vezes é realizada por pessoas que não participaram do desenvolvimento original. Linguagens que dificultam a leitura e a compreensão do código tendem a tornar esse processo mais caro e complexo.
A importância da manutenção de software não deve ser subestimada. Estima-se que, em sistemas de grande porte com vida útil prolongada, os custos de manutenção podem ser de duas a quatro vezes maiores que os custos de desenvolvimento inicial.
Entre os diversos fatores que compõem o custo total de uma linguagem de programação, três se destacam como os mais relevantes: o custo de desenvolvimento, de manutenção e a confiabilidade dos sistemas construídos. Esses fatores estão diretamente ligados à capacidade de expressão (writability) e à legibilidade (readability) da linguagem — ou seja, à facilidade com que os programadores conseguem escrever códigos corretos, concisos e fáceis de entender e manter. Por isso, writability e readability são considerados os critérios mais importantes na determinação do custo de uma linguagem de programação.
Fonte: Sebesta, Robert W. (2000). Conceitos de Linguagens de Programação. 4ª edição. Porto Alegre: Bookman. 624 páginas.
Por curiosidade, fazendo a mesma pergunta ao ChatGPT, em 11 de abril de 2025, a resposta obtida foi:
(Sebesta, 2000) A ideia existente por trás da semântica operacional é descrever o significado de um programa ao executar suas instruções em uma máquina, seja ela real ou simulada. As alterações que ocorrem no estado de uma máquina, quando ela executa determinada instrução, definem o significado desta. Usando as instruções da máquina virtual definida a seguir, apresente uma definição semântica operacional da instrução switch
em C apresentada a seguir.
ident := var
ident := var op_bin var
ident := op_un var
goto label
if var relop var goto label
ident é um identificador.
var é um identificador ou uma constante.
op_bin pode ser um dos operadores aritméticos do conjunto {+, -, *, /}.
op_un pode ser um dos operadores unários do conjunto {+, -}.
relop pode ser um dos operadores relacionais do conjunto {=, <>, >, <, >=, <=}.
switch (var) {
case c1: expr1; break;
case c2: expr2; break;
case c3: expr3; break;
default: expr4;
}
if var = c1 goto label1;
if var = c2 goto label2;
if var = c3 goto label3;
goto label4;
label1: expr1;
goto label5;
label2: expr2;
goto label5;
label3: expr3;
goto label5;
label4: expr4;
label5:
(Poscomp, 2024) Analise o código em Linguagem C (Compilador Ansi C) abaixo:
int f_rec(char s[]) {
if (s[0] == '\0') {
return 0;
}
return 1 + f_rec(s + 1);
}
int main() {
char str[] = "Ola mundo!";
int var = f_rec(str);
double resultado = var / 2;
printf("%f\n", resultado);
return 0;
}
Considerando o código apresentado, assinale a alternativa correta.
a. a saída é o número de caracteres de str
dividido por 2, mostrado como um número de ponto flutuante.
b. a saída é o número de caracteres de str
dividido por 2, mostrado como um inteiro.
c. o código tem um erro de tipos porque a função f_rec
não pode aceitar um char array
.
d. o código tem um erro de tipos porque var
é um inteiro, mas é usado em uma operação de divisão com double
.
e. o código tem um erro de tipos porque a função printf
está usando o especificador de formato errado.
(Poscomp, 2024) Analise o texto a seguir, que descreve um programa que solicita um salário ao usuário e mostra o imposto a pagar:
Para resolver o problema descrito acima, qual instrução deve ser utilizada?
a. laço encadeado.
b. atribuição composta.
c. laço infinito.
d. condicional encadeada.
e. atribuição simples.
Eventualmente, uma mesma palavra pode ser associada a duas ou mais árvores de derivação, determinando uma ambiguidade. Em muitas aplicações como, por exemplo, no desenvolvimento e otimização de alguns tipos de algoritmos de reconhecimento, é conveniente que a gramática usada não seja ambígua. Entretanto, nem sempre é possível eliminar ambiguidades. Na realidade, é fácil definir linguagens para as quais qualquer gramática livre de contexto é ambígua. Nesse contexto, prova que a gramática a seguir é uma gramática ambígua.
G = ({S, A, B, X, Y}, {a, b, c}, P, S)
P = {S → A | B
A → Ac | X
X → aXb | ε
B → aB | Y
Y → bYc | ε}