Baixe o app para aproveitar ainda mais
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”.
Compartilhar