Buscar

UNIDADE2 - TÉCNICAS DE PROGRAMAÇÃO

Prévia do material em texto

• Pergunta 1 
1 em 1 pontos 
 
Com a recursividade, os laços de repetição são substituídos pelas chamadas recursivas. 
Esse tipo de implementação tem os seus estudos aprofundados na área da computação 
denominada como matemática discreta. Para essa questão, pense em uma solução 
recursiva, implementada em C, para resolver a expressão 2 n. Dentre as alternativas a 
seguir, escolha aquela que tiver uma codificação que corresponda à solução. 
 
Escolha a opção correta: 
 
Resposta 
Selecionada: 
 
. int dois_a_n(int n) { if(n == 0) return 1; return 
2*dois_a_n(n-1); } 
 . 
Resposta Correta: 
. int dois_a_n(int n) { if(n == 0) return 1; return 
2*dois_a_n(n-1); } 
 . 
Comentário da 
resposta: 
Parabéns! Sua resposta foi a correta! Você observou a relação entre a 
condição de parada e a variação do parâmetro passado. Como a 
condição de parada é 0, os parâmetros devem ser passados de forma 
descrescente. 
 
 
• Pergunta 2 
1 em 1 pontos 
 
Os compiladores C/C++, para realizar a verificação de consistência de uso das funções, faz 
uso dos arquivos de cabeçalhos ( headers ). Nestes arquivos, por exemplo, o protótipo das 
funções são declarados. Desta forma, o compilador verifica se as chamadas implementadas 
estão compatíveis com as definições das funções. Para essa questão, suponha a existência de 
dois arquivos: um contendo o arquivo header e outro contendo a implementação em C . 
 
(A) Arquivo header : 
 
#ifndef _ARQHEADER 
#define _ARQHEADER 
 
int func1(int *, int); 
float func2(float, char []); 
void func3(int *, int *, float); 
int func4(char[],int, char); 
 
#endif 
 
(B) Arquivo de implementação 
 
int main() 
{ 
 int a,b,c; 
 float f1,f2; 
 char str[20],carac; 
 c=func1(a,b); //Linha 1 
 f2=func2(f1,str[0]); //Linha 2 
 
 c=func3(&a, &b, f1); //Linha 3 
 c=func4(str,a,carac); //Linha 4 
 func1(&c,a); //Linha 5 
 return 0; 
} 
 
Analisando a parte de implementação com o arquivo header, assinale a alternativa que contém 
os possíveis erros que seriam acusados pelo compilador: 
Resposta 
Selecionada: 
 
.Na linha 1, o parâmetro “ a” não está sendo passado por referência 
(falta o “ &”); na linha 2, está sendo passado o caracter da posição 0 e 
não toda a string 
“ str”; na linha 3, está sendo atribuído um valor à variável “ c” por 
intermédio de uma função que nada retorna ( func3); as demais linhas 
estão corretas. 
Resposta 
Correta: 
 
.Na linha 1, o parâmetro “a” não está sendo passado por referência (falta 
o “&”); na linha 2, está sendo passado o caracter da posição 0 e não toda 
a string 
“str”; na linha 3, está sendo atribuído um valor à variável “c” por 
intermédio de uma função que nada retorna (func3); as demais linhas 
estão corretas. 
Comentário 
da resposta: 
Parabéns! Sua resposta foi a correta! Você fez a correspondência correta 
dos protótipos das funções (interfaces) definidos no arquivo de 
cabeçalhos nas chamadas inseridas no programa principal. Você observou 
bem que, apesar de uma função retornar um valor, não é obrigatório fazer 
uso do retono no momento da chamada da função (como está codificada 
a linha 5). 
 
 
• Pergunta 3 
1 em 1 pontos 
 
Um valor binário pode ser representado no padrão conhecido como BCD 8421 ( Binary-coded 
Decimal – Decimal Codificado em Binário). Nesta codificação, os valores 8421 representam o 
resultado de 2 i , onde i denota a posição do dígito dentro da palavra. Por exemplo, 1001 (2) = 
1*8 + 0*4 + 0*2 +1*1 = 9 (10) . Para essa questão, suponha o seguinte código recursivo: 
 
#include <stdio.h> 
#include <string.h> 
 
int Bin2Dec(char bin[],int pos,int exp) 
{ 
 if(____) return 0; 
 return (bin[pos]-48)*exp + Bin2Dec(bin,____,____); 
} 
 
int main() 
{ 
 char binario[9]="10011101"; //valor em decimal = 157 
 printf("Valor convertido: %d", Bin2Dec(binario,strlen(binario)-1,1)); 
 return 0; 
 
} 
 
Assinale a opção abaixo que contenha os trechos de código para preencher as lacunas: 
Resposta Selecionada: 
. pos<0 ; pos-1 ; exp*2 . 
Resposta Correta: 
. pos<0 ; pos-1 ; exp*2 . 
Comentário 
da resposta: 
Parabéns! Sua resposta foi a correta! Realmente o código foi 
implementado para que a última posição fosse evocada antes para 
facilitar o cálculo do expoente – à medida que se aproxima da posição 0 
(início do vetor – posição mais significativa do número binário), o expoente 
vai sendo multiplicado por 2. Sendo assim, a posição foi descrementada a 
cada evocação da função recursiva. A posição 0 do vetor também deveria 
ser manipulada – essa a razão do ( pos<0). 
 
 
• Pergunta 4 
1 em 1 pontos 
 
Quando construimos aplicações para que sejam executadas a partir do comando de linha 
(prompt ou console), temos a possibilidade de passarmos informações ao programa. Para 
tanto, usamos os parâmetros comumente identificados por “ argc ” e “ argv ”. Considerando o 
trecho: 
 
 int main(int argc, char *argv[]) 
 
Analise as afirmativas a seguir, marcando com “V” a(s) verdadeira(s) e, com “F” a(s) falsa(s): 
 
( ) caso colocarmos, em nosso código “ printf(“%s”,argv[0]) ”, será impresso o nome do próprio 
programa. 
( ) caso não passemos nenhum parâmetro ao programa, “ argv ” assumirá o valor 0. 
( ) o parâmetro “ argv ” é uma lista de strings . 
( ) o parâmetro “ argc ” sempre será positivo e maior ou igual a 1. 
 
Marque a opção que tiver a sequência que você julgue ser a correta: 
 
Resposta Selecionada: 
.V ; F; V ; V . 
Resposta Correta: 
.V ; F; V ; V . 
Comentário da 
resposta: 
Parabéns! Sua resposta foi a correta! Realmente, o parâmetro “ argv” 
sempre conterá pelo menos um item – que é o nome do arquivo 
executável evocado para a execução, inserido na posição 0 do parâmetro 
“ argv”. Desta forma, o “ argc” sempre será maior ou igual a 1. 
 
 
• Pergunta 5 
1 em 1 pontos 
 
Em algumas situações, como inversão de vetores, surge a necessidade de implementar uma 
função que realiza a troca de dois elementos entre si, ou seja, o elemento “ vet[i] ” recebe o 
valor de “ vet[j] ” e “ vet[j] ” recebe o valor de “ vet[i] ”. Sendo assim, pode-se codificar uma 
 
função que realizará exatamente essa permuta. Para essa questão, considere o código 
apresentado a seguir: 
 
 
#include <stdio.h> 
#include <string.h> 
 
void swap(char __c1, char __c2) 
{ 
 char tmp; 
 tmp = __c1; 
 __c1 = __c2; 
 __c2 = tmp; 
} 
 
void Ordena(char str[]) 
{ 
 for(int i=0; i < strlen(str)-1; i++) 
 for(int j=i+1; j < strlen(str); j++) 
 if(str[i]>str[j]) swap(__str[i],__str[j]); 
} 
 
int main() 
{ 
 char str[11]="icbjdgfeah"; 
 printf("Vetor original: %s\n",str); 
 Ordena(str); 
 printf("Vetor ordenado: %s\n",str); 
 return 0; 
} 
 
Assinale a opção abaixo que contenha os elementos para preencher as lacunas (nas opções 
abaixo, o símbolo ”_” significa deixar a lacuna sem preenchimento): 
Resposta Selecionada: 
. * ; * ; * ; * ; * ; * ; & ; & . 
Resposta Correta: 
. * ; * ; * ; * ; * ; * ; & ; & . 
Comentário da 
resposta: 
Parabéns! Sua resposta foi a correta! Você observou que, apesar da 
função “ swap” manipular elementos do vetor, foram passadas posições 
específicas, ou seja, foram passados apenas caracteres. Sendo assim, é 
necessário passar as referências dos itens “ str[i]” e “ str[j]” para que as 
alterações realizadas dentro da função “ swap” tenham validade na função 
“ Ordena”. 
 
 
• Pergunta 6 
1 em 1 pontos 
 
Na definição do protótipo da função, em sua interface, temos que definir o tipo de retorno 
da função e, também, a lista de parâmetros. Para essa questão, suponha o trecho de 
código a seguir: 
 
#include <stdio.h> 
#include <stdlib.h> 
 
int func(int a, int __b, char __c[]) 
 
{ 
 a +=++__b; 
 itoa(a,c,10); 
 return a; 
} 
 
int main() 
{ 
 char c[10]; 
 int x=5, y=6; 
 printf("%d %s %d %d",func(x,&y,c),c,x,y); 
} 
 
 
Escolha a afirmativa que contém o resultado da impressão pela função“ printf” e os 
trechos a serem inseridos nas lacunas: 
Resposta Selecionada: 
.12 12 ; * ; deixar em branco ; * . 
Resposta Correta: 
.12 12 ; * ; deixar em branco ; * . 
Comentário 
da resposta: 
Parabéns! Sua resposta foi a correta! Você observou bem o fato de que a 
chamada da função, dentro do programa principal, requer uma passagem 
por valor para a variável “x” e uma passagem por referência para a variável 
“y”. Isso implica em “ int func(int a, int *b, char __c[])“ e, 
consequentemente, “ a +=++(*b);”. Uma string sempre é passada por 
referência – sendo assim, não necessita o uso de “ *”. 
 
 
• Pergunta 7 
1 em 1 pontos 
 
Na computação, existem várias formas de representação numérica, dentre as quais, podemos 
citar as representações decimal, hexadecimal, octal e binária. Para realizar a conversão, por 
exemplo, de um valor formatado na base decimal para uma base K , basta realizar divisões 
sucessivas por K e coletar o último quociente e todos os restos das divisões em ordem 
inversa. 
Suponha a necessidade de criar uma função recursiva para a conversão de um número na 
base decimal para a representação binária (base 2). Para essa questão, suponha o trecho a 
seguir: 
 
#include <stdio.h> 
 
void Dec2Bin(int n) 
{ 
 if(__) printf("%d",n); 
 else 
 { 
 ___; 
 ___; 
 } 
} 
 
int main() 
{ 
 
 Dec2Bin(14); 
 
 return 0; 
} 
 
Assinale a opção abaixo que contenha os trechos de código para preencher as lacunas: 
Resposta Selecionada: 
. n<2 ; Dec2Bin(n / 2) ; printf("%d",n%2) . 
Resposta Correta: 
. n<2 ; Dec2Bin(n / 2) ; printf("%d",n%2) . 
Comentário 
da resposta: 
Parabéns! Sua resposta foi a correta! Você interpretou corretamente o 
fato de a impressão dos restos das divisões sucessivas é realizada na 
ordem reversa às divisões, ou seja, a impressão necessita ser do tipo “pós-
ordem”, inserida após a chamada recursiva. Como critério de parada, a 
cláusula que indica a não possibilidade de continuar as divisões por 2. 
 
 
• Pergunta 8 
1 em 1 pontos 
 
Em funções recursivas, a posição da chamada recursiva em relação às demais linhas de seu 
código influencia o resultado. Dependendo da posição, a recursividade é dita como pré-ordem 
(quando o processamento antecede a chamada recursiva); ordem simétrica (quando o 
processamento encontra-se entre duas chamadas recursivas) ou, finalmente, pós-ordem 
(processamento após as chamadas recursivas). Para essa questão, suponha o código a 
seguir: 
 
#include <stdio.h> 
 
void Recursao1(int i) 
 { 
 if(i>=5) return; 
 printf("%d ",i); 
 Recursao1(i+1); 
 } 
 
void Recursao2(int i) 
 { 
 if(i>=5) return; 
 Recursao2(i+1); 
 printf("%d ",i); 
 } 
 
int main() 
{ 
 printf("Recursao1\n"); 
 Recursao1(0); 
 printf("\n\nRecursao2\n"); 
 Recursao2(0); 
 return 0; 
} 
 
Assinale a opção que você julgue ser a correta: 
 
Resposta 
Selecionada: 
 
.A função “ Recursao1” segue uma recursão pré-ordem – logo o seu 
resultado é “ 0 1 2 3 4”. Por sua vez, a função “ Recursao2” é pós-ordem, 
por consequência, o seu resultado é: “ 4 3 2 1 0” . 
Resposta 
Correta: 
 
.A função “Recursao1” segue uma recursão pré-ordem – logo o seu 
resultado é “0 1 2 3 4”. Por sua vez, a função “Recursao2” é pós-ordem, 
por consequência, o seu resultado é: “4 3 2 1 0” . 
Comentário 
da resposta: 
Parabéns! Sua resposta foi a correta! Você observou corretamente a 
ordem de chamada e impressão do resultado. Na pré-ordem, a impressão 
acontece antes da chamada, por consequência, a impressão é realizada, 
neste caso, na ordem crescente. Na pós-ordem, a impressão acontece na 
ordem descrescente pois a recursão caminha por todos os níveis da 
contagem e imprime o resultado na volta das chamadas recursivas. 
 
• Pergunta 9 
1 em 1 pontos 
 
Na linguagem C/C++, encontramos alguns comandos capazes de modificar o fluxo de 
execução de um programa: “ return ” (retorno de uma função), “ break ” (finaliza, por exemplo, 
um laço de repetição) e “ continue ” que volta para a linha que contém a definição do laço de 
repetição (por exemplo, a linha que contém a palavra “ for ”). Para essa questão, suponha que 
seja necessário implementar uma função hipotética que, passados como parâmetros os 
valores de “ início ” e de “ final ” de uma contagem, imprima os elementos de acordo com o 
seguinte conjunto de regras: não imprimir os números ímpares; caso seja encontrado um valor 
múltiplo de 5, sair de laço de repetição; caso seja encontrado o valor 48, sair da função. Para 
tanto, analise o código a seguir: 
 
 
#include <stdio.h> 
 
void func(int inicio, int final) 
{ 
 int i=inicio; 
 for(; i<final; i++) 
 { 
 if(i%2) ____; 
 printf("%d ",i); 
 if(!(i%5)) ____; 
 if(i==48) 
 { 
 printf("\nSaindo da funcao pois encontrou 48.\n"); 
 ____; 
 } 
 } 
 if(i==final) printf("\nsaiu do laco pelo limite da contagem\n"); 
 else printf("\nsaiu do laco pois encontrou um multiplo de 5\n"); 
} 
 
int main() 
{ 
 printf("Execucao 1:\n"); 
 func(6,15); 
 printf("Execucao 2:\n"); 
 
 func(46,55); 
 printf("Execucao 3:\n"); 
 func(36,39); 
 return 0; 
} 
 
Assinale a opção abaixo que contenha a ordem correta de aparição dos comandos “ return ”, 
“ break ” e “ continue ”: 
Resposta Selecionada: 
. continue ; break ; return . 
Resposta Correta: 
. continue ; break ; return . 
Comentário 
da resposta: 
Parabéns! Sua resposta foi a correta! Realmente, para pular os ímpares, 
deve-se incrementar o contador de contagem e voltar ao início do laço de 
repetição, usando, para tal, o “ continue”. Por sua vez, a finalização do laço 
(quando for múltiplo de 5) é conseguido pelo comando “ break”. Por fim, 
para encerrar totalmente a função, ao se deparar com o valor 48, utiliza-se 
o comando “ return”. 
 
 
• Pergunta 10 
1 em 1 pontos 
 
Recursividade é uma técnica que permite a escrita de códigos de forma mais sucinta 
porém faz uso de forma mais massivo da pilha de memória. Para essa questão, analise o 
código a seguir: 
 
#include <stdio.h> 
 
int f(int a, int b) 
 { 
 if(!b)return a; 
 return f(b, a % b); 
 } 
 
int main() 
{ 
 int x=3, y=10; 
 printf("%d",f(x,y)); 
} 
 
Escolha a opção correta: 
 
Resposta 
Selecionada: 
 
.O código calcula o MDC (Máximo Divisor Comum) usando o 
algoritmo de Euclides. 
Resposta Correta: 
.O código calcula o MDC (Máximo Divisor Comum) usando o 
algoritmo de Euclides. 
Comentário da 
resposta: 
Parabéns! Sua resposta foi a correta! Você lembrou bem que a fórmula de 
Euclides é originalmente recursiva: MDC(a,b) = MDC(b,r) onde, “ r”= resto 
da divisão de “ a” por “ b”.

Continue navegando