Buscar

Tecnicas-de-Programacao-Atv2

Prévia do material em texto

Pergunta 1
1 em 1 pontos
	
	
	
	Para a evocação de uma função, algumas informações deverão ser armazenadas, como o endereço da linha que contém a evocação (registrador PC – Program Counter – Contador de Programa), para que, quando a função for finalizada, o computador saiba voltar ao ponto de chamada. Dentre as afirmativa abaixo, assinale com “V” aquela(s) que você julgar estar correta e, com “F”, a(s) falsa(s).
 
( ) As informações para o retorno, em função da evocação da função, são empilhadas em uma região da memória principal do computador chamada “ stack” (pilha).
( ) Não precisamos nos preocupar com a quantidade de evocações aninhadas (uma função chamando outra e assim por diante, em uma ação de profundidade) independentemente dos dispositivo para o qual estamos implementando nosso código.
( ) Funções recursivas são aquelas que demandam muito recurso da máquina.
( ) O sistema operacional também empilha as informações decorrentes das funções associadas às interrupções do computador.
 
Assinale a alternativa abaixo que contenha a sequência que você julgue ser a correta:
	
		Resposta Selecionada:
	 
.V; F; F; V.
	Resposta Correta:
	 
.V; F; F; V.
	Comentário da resposta:
	Parabéns! Sua resposta foi a correta! Realmente, o sistema operacional deve salvar o endereço da linha na qual ocorreu a evocação da função para que se possa, ao término da função, voltar à linha subsequente à chamada. Esse salvamento ocorre em uma estrutura de pilha ( stack) da memória principal. Essa região de pilha pode ser extremamente limitada em ambientes com pouca memória, tal como nos sistemas embarcados. As interrupções da máquina são tratadas, superficialmente falando, de forma análoga às funções.
Pergunta 2
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 3
1 em 1 pontos
	
	
	
	Uma das etapas iniciais da implementação das funções consiste na definição de suas interfaces, ou seja, definição dos tipos de retornos e de suas listas de parâmetros. Para essa questão, suponha o seguinte enunciado: “Um certa loja apresenta um programa de incentivo aos seus vendedores atribuindo premiações àqueles que realizaram mais vendas no mês (independentemente do valor vendido) e àqueles que conseguiram maiores montantes de venda (maior valor vendido independentemente do número de vendas efetuadas). As vendas estão lançadas em uma matriz – cada linha denota um vendedor e as colunas representam as vendas de cada vendedor. A última posição das colunas de cada vendedor contém o valor -1 indicando o término dos lançamentos. Os nomes dos vendedores estão lançados em um vetor de strings – cada vendedor respresenta um índice do vetor“.
 
Para tanto, serão criadas as funções abaixo:
 
NomeVendedorMaiorQtdVendas( );
NomeVendedorMaiorValorVendas( );
 
Para a questão, suponha que a quantidade máxima de vendas vale 30 e os nomes têm o tamanho máximo de 40 caracteres. Assinale a opção abaixo que contenha as interfaces das funções apropriadas ao enunciado:
	
		Resposta Selecionada:
	 
. int NomeVendedorMaiorQtdVendas(float vendas[][30], char nomes[][40],
 char nomemaior[]) ;
 float NomeVendedorMaiorValorVendas(float vendas[][30], char nomes[][40],
 char nomemaior[]) .
	Resposta Correta:
	 
. int NomeVendedorMaiorQtdVendas(float vendas[][30], char nomes[][40],
 char nomemaior[]) ;
 float NomeVendedorMaiorValorVendas(float vendas[][30], char nomes[][40],
 char nomemaior[]) .
	Comentário da resposta:
	Parabéns! Sua resposta foi a correta! Você interpretou bem o enunciado realizando corretamente o tipo de retorno das funções e seus respectivos parâmetros. Podemos reforçar o fato da escolha do tipo “ int” para a maior quantidade de vendas (o número de vendas é um valor inteiro) e do tipo “ float” para o valor vendido (o montande de valor é uma grandeza que manipula os centavos, portanto, um valor do tipo real – float). Salientamos o fato de que, quando passamos matrizes como parâmetros, temos que informar o tamanho de pelo menos a última dimensão – essa foi o motivo de preenchermos o tamanho das colunas.
Pergunta 4
0 em 1 pontos
	
	
	
	Para essa questão, suponha o seguinte enunciado. “A resistência de uma liga metálica se dá pelos percentuais de utilização de carbono misturados a outros elementos, essencialmente o ferro. Suponha a necessidade de se implementar uma função que, dada uma métrica de resistência (tipo de resistência – suponha que existam disponíveis 10 níveis de resistência) e um volume de ferro (em toneladas) calcule e retorne o percentual e a massa (em toneladas) de carbono a ser utilizada na liga metálica”. Para esse enunciado foi implementada uma função cuja chamada ocorrerá na forma:
 
. . .
float massaCarbono;
massaCabono = CalculaQtdCarbono(tipo_resist,massaFerro, &percentual_carbono);
. . .
 
Assinale a opção abaixo que represente a interface mais apropriada para a questão:
	
		Resposta Selecionada:
	 
. float CalculaQtdCarbono(unsigned char, float, int *); .
	Resposta Correta:
	 
. float CalculaQtdCarbono(unsigned char, float, float *); .
	Comentário da resposta:
	Infelizmente a sua resposta está incorreta. Para responder essa questão, você deve refletir sobre o fato de a função deve retornar dois valores: um valor é representado pela massa do carbono a ser usada na liga e, o outro, refere-se ao percentual de carbono. Reflita, também, sobre a faixa de valores possíveis para o tipo da liga e escolha um tipo de dados mais condizente para a referida faixa.
Pergunta 5
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! Suaresposta 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 6
0 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); na linha 5, falta uma variável para receber o retorno da função “ func1”. A linha 4 está correta.
	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:
	Infelizmente a sua resposta está incorreta. Para responder essa questão, analise os parâmetros das e o tipo de retorno das funções descritos no arquivo de cabeçalhos e faça a correspondência exata nas chamadas das funções. Os tipos devem bater com exatidão.
Pergunta 7
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 8
0 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:
	Infelizmente a sua resposta está incorreta. Observe que a função “ swap” não está recebendo o vetor por completo e, sim, elementos específicos. Esses elementos, neste caso, estão se comportando como variáveis do tipo “ char” (sem ser vetor).
Pergunta 9
1 em 1 pontos
	
	
	
	Gerar números aleatórios tem a sua serventia em diversas situações, tais como geração de sequências para testes de softwares, solução inicial em problemas de otimização e definição do intervalo de tempo para o reenvio de informações em redes de computadores. Para o teste, imaginemos um cenário onde dois jogares disputam uma partida de lançamento de dados – ganha aquele que obtiver maior pontuação no dado lançado. Para simular esse cenário, imaginemos o código abaixo:
 
#include <stdio.h> //arquivo header para a funcao printf()
#include <stdlib.h> //arquivo header para as funcoes srand() e rand()
#include <time.h> //arquivo header para a funcao time()
 
 
void Compara(int __jog1, int __jog2)
{
 if(jog1 > jog2) printf("Jogador 1 vencedor (1=%d x 2=%d)\n",jog1,jog2);
 else if (jog1 < jog2) printf("Jogador 2 vencedor!(1=%d x 2=%d)\n",jog1,jog2);
 else printf("Empate (%d)\n",jog1);
}
 
___ Dado()
{
 return ____;
}
 
int main()
{
 srand(time(NULL));
 Compara(Dado(),Dado());
 return 0;
}
 
 
Assinale a opção abaixo que contenha os trechos de código para preencher as lacunas (o caracter “_” significa para deixar a lacuna vazia):
	
		Resposta Selecionada:
	 
. __ ; __ ; int ; (rand()%6)+1 .
	Resposta Correta:
	 
. __ ; __ ; int ; (rand()%6)+1 .
	Comentário da resposta:
	Parabéns! Sua resposta foi a correta! Realmente nenhuma função requer passagem de parâmetros por referência pois o único valor retornado é feito através do retorno da função “ Dado()”. A geração do número aleatório segue a forma “ (rand()%6)+1” pois a soma por um impede a geração do valor 0 e o resto da divisão define o valor limite superior do número gerado.
Pergunta 10
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”.

Continue navegando