Curso de C

Gabarito de Lista de Exercícios

 Aula 3: Estruturas de Controle de Fluxo

Clique aqui para acessar a Lista 3

 

Exercício 1: Página c410.html

Enunciado:
Altere o último exemplo da página para que ele escreva cada letra 5 vezes seguidas. Para isto, use um 'if' para testar se o contador é divisível por cinco (utilize o operador %) e só então realizar a atualização em index.

Solução:
Neste exercício, segundo a sugestão apresentada, bastava se adicionar a linha de código que está comentada, no exercício abaixo. A variável índex, que aponta qual letra da string será impressa, e que era incrementada circularmente a cada iteração, agora só é incrementada de 5 em 5 iterações, ou seja, quando o resto da divisão de contador por 5 for 0.

#include <stdio.h>
main()
{
int índex = 0, contador;
char letras[5] = "Joao";
for (contador=0; contador<1000; contador++)
     {
     printf("\n%c",letras[índex]);
     if (( contador % 5 ) == 0)   /* Se o resto da divisão == 0, entao incrementa */
        índex = (índex == 4)? index=0: ++índex;
     }
}
 
 

Exercício 2: Página c420.html

Enunciado:
Escreva um programa utilizando o comando switch que leia uma string (use gets()) e substitua todos os espaços e tabulações ('\t') por caracteres de nova linha. O loop deve encerrar quando encontrar o caracter de final de linha '\0'.

Solução:

#include <stdio.h>
main()
{
int índex;
char frase[30];

printf("\n\nEntre com a frase (max 30 caracteres): ");
gets(frase);
for (índex =0 ; frase[índex] != '\0'; index++)
   {
   switch(frase[índex])
     {
     case '\t': frase[índex] = '\n';    break;
     case ' ': frase[índex] = '\n';    break;
     }
   }
printf("\n\nNova frase: \n%s", frase);
}
 
 

Exercício 3: Página c430.html

Enunciado:
Faça um programa que inverta uma string (uma sequência de caracteres). Use o comando for para varrer a string até o seu final. Lembre-se que a string sempre termina com o caracter '\0'.

Solução:
Neste exercício existem alguns detalhes interessantes. Muitas pessoas não conseguiram chegar ao resultado por causa de um pequeno detalhe na 'linha em destaque'. Lembre-se sempre que se você tem um string de 10 posições, o seu índice pode variar de 0 a 9, e o '\0' vai estar na posição 9. Logo, você deve inverter a posição 8 com a 0, 7 com a 1, e assim por diante. É por isto que a expressão fica:

         copia[i] = str[strlen(str)-i-1]

Não podemos também deixar de colocar o '\0' no final da nova string.

#include <stdio.h>
#include <string.h>
#define MAX 15

main()
{
char str[MAX], copia[MAX];
int i;
printf("\n\nEntre com uma palavra: ");
gets(str);
for(i=0; str[i] != '\0'; i++)
   {
   copia[i] = str[strlen(str)-i-1];   /* Linha em destaque */
   }
copia[i] = '\0';
printf("\n\nString Invertida: %s\n", copia);
}
 
 

Exercício 4: c440.html

Enunciado:
Refaça o programa da página anterior. Use o comando while para fechar o loop.

Solução:
Como o comando while não tem o incremento próprio, precisamos fazê-lo dentro do seu loop. Outra observação importante é a necessidade de se inicializar a variável com i = 0.
Entao temos:

#include <stdio.h>
#include <string.h>
#define MAX 15

main()
{
char str[MAX], copia[MAX];
int i = 0;
printf("\n\nEntre com uma palavra: ");
gets(str);
while (str[i] != '\0')
   {
   copia[i] = str[strlen(str)-i-1];   /* Linha em destaque */
   i++;
   }
copia[i] = '\0';
printf("\n\nString Invertida: %s\n", copia);
}
 
 

Exercício 5: Página c450.html

Enuncicado:
Refaça o exercício da página c410.html utilizando o laço do-while para controlar o fluxo.

Solução:
É preciso inicializar a variável contador, para garantir o resultado desejado. O incremento também tem que ser feito 'na mão'.

#include <stdio.h>
main()
{
int índex = 0, contador =0;
char letras[5] = "Joao";
do
   {
   printf("\n%c",letras[índex]);
   if (( contador % 5 ) == 0)   /* Se o resto da divisão == 0, entao incrementa */
      índex = (índex == 4)? index=0: ++índex;
   contador ++;
   } while (contador < 1000);
}
 
 

Exercício 6: Página c470.html

Enunciado:
Escreva um programa que peça ao usuário que digite três números inteiros, correspondentes a dia , mês e ano. Teste os números recebidos, e em caso de haver algum inválido, repita a leitura até conseguir valores que estejam na faixa correta (dias entre 1 e 31, mês entre 1 e 12 e ano entre 1900 e 2100). Verifique se o mês e o número de dias batem (incluindo verificação de anos bissextos). Se estiver tudo certo imprima o número que aquele dia corresponde no ano. Comente seu programa. Faça as identações corretamente.
Obs: Um ano é bissesto se for divisível por 4 e não for divisível por 100, exceto para os anos divisíveis por 400, que também são bissestos.

Solução:
Este programa já é um programa mais trabalhado e exige um pouco mais de paciência e atenção. Apresento a seguir para vocês a minha solução para este problema. Vale lembrar que esta solução é apenas mais uma entre milhares possíveis.   Os códigos estão bem comentados. A primeira versão e uma versão básica.
A segunda já e mais avançada, realiza a leitura e testa a consistência da data em um mesmo loop. Mas a filosofia das duas versões é a mesma: O programa testa a validade dos dados assim que os lê, para só entao processar.
A segunda versão também faz o uso do comando goto, o que muitas vezes pode ser evitado. O mesmo efeito teria sido alcançado usando-se um loop qualquer. Eu optei pelo seu uso pela elegância que ele conferiu ao código.

Versão 1:
/* -------------------------------------------------------- */
/* CONTADORE DE DIAS: Versão 1 ---------------------------- */
#include <stdio.h>
main()
{
int dia, mes, ano, i;   /* Variaveis.. */
int ndias;
int meses[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

printf("\n\n ----Contador de dias----- \n");

/* Leitura da data */
do
   {
   printf("\nDia: ");
   scanf("%d", &dia);
   } while ((dia > 31) || (dia < 1));
do
   {
   printf("\nMes: ");
   scanf("%d", &mes);
   } while ((mes > 12) || (mes < 1));
do
   {
   printf("\nAno: ");
   scanf("%d", &ano);
   } while ((ano < 1900) || (ano > 2100));

/* E isto garante que a data seja valida */
/* Agora, ao processamento ------------------------------------ */
/* Primeiro inicializamos ndias. Em seguida, somamos os dias    */
/* do mes corrente e por fim somamos os dias dos meses passados */

ndias = 0;

/* Descobrindo se o ano e bissexto */
/* Caso seja, iremos somar um dia na soma final, mas somente se */
/* o mes corrente for posterior ao mes de fevereiro.. */

if ( ((ano%4) == 0) && ((ano%100) != 0) || (ano%400 == 0)) /* Se e bissexto */
  if (mes > 2) ndias += 1;  /* Se já passou o mes de fevereiro */

/* Computa os dias do mes corrente */
ndias += dia;

/* O mes corrente já foi contado. Portanto o contador vai ate mes-1 */
for (i=0; i< (mes-1); i++)
  ndias += meses[i];

printf("\nDia Numero: %ld", ndias);
}
 

Versão 2:
/* -------------------------------------------------------- */
/* CONTADORE DE DIAS: Versão 2 ---------------------------- */
#include <stdio.h>
main()
{
int dia, mes, ano, i;
long int ndias;
int meses[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

printf("\n\n ----Contador de dias----- \n");

/* Leitura da data
   Lê ate que a data seja valida */
le_data:                         /* Rotulo usado para o comando goto */
do
   {
   printf("\nEntre com a data no formato DD/MM/AA: ");
   scanf("%d/%d/%d", &dia, &mes, &ano);
   } while (((dia > 31) || (dia < 1)) &&
            ((mes > 12) || (mes < 1)) &&
            ((ano < 1900) || (ano > 2100)) );

/* Verificando se o ano e bissexto */
/* Caso seja, o mes de fevereiro ganha mais um dia.. */

if ( ((ano%4) == 0) && ((ano%100) != 0) || (ano%400 == 0))
  meses[1] += 1;

/* Verifica a consistencia da data. Caso inconsistente volta a le_data */
if (dia > meses[mes-1])     /* DATA INCONSISTENTE!! */
  {
  printf("\n DATA INCONSISTENTE! \n ");
  meses[1] = 28;           /* Desfaz a soma de um dia no mes de fevereiro */
  goto le_data;
  }

/* E isto garante que a data seja valida */
/* Agora, ao processamento -----------------------*/

ndias = 0;

/* Computa os dias do mes corrente */
ndias += dia;

for (i=0; i< (mes-1); i++)  /* O mes corrente já foi contado (mes-1)*/
  ndias += meses[i];

printf("\nDia Numero: %ld", ndias);
}
 
 

Exercício de Fixação:

Enunciado:
Faça um programa de conversão de base numérica. O programa deverá apresentar uma tela de entrada com as seguintes opções:

    < Conversao de base >

  1: decimal para hexadecimal
  2: hexadecimal para decimal
  3: decimal para octal
  4: octal para decimal
  5: Encerra

  Informe sua opcao:

A partir da opção escolhida, o programa deverá pedir o numero na base escolhida, lê-lo e apresentá-lo na base desejada. Em seguida, o programa deve perguntar ao usuário se ele deseja retornar ao menu principal ou finalizar o programa. O problema pode ser estendido a outras bases, de acordo com o interesse do aluno.

Solução:
A seguir é apresentada uma solução. O código está bem comentado, com a intenção de torná-lo de fácil entendimento. Mais uma vez, esta é apenas uma forma de implementar, havendo muitos outros caminhos para se chegar à solução.

/*------------------------------------------------------------------*/
/* Programa de conversao de bases ----------------------------------*/
/* Versão 1 --------------------------------------------------------*/

#include <stdio.h>
main()
{
int entrada, opcao = 0;
char opcao_c;

/* Loop principal do programa --------------------------------------*/
while (opcao != 5)
       {
       printf("\n\n");

/* Imprime a tela */
       printf("\n\n\t< Conversao de base >");
       printf("\n  1: decimal para hexadecimal");
       printf("\n  2: hexadecimal para decimal");
       printf("\n  3: decimal para octal");
       printf("\n  4: octal para decimal");
       printf("\n  5: Encerra");

       printf("\n\n\t\tOpcao: ");
       scanf("%d", &opcao);
       if ((opcao > 4)||(opcao <1))
          continue;           /* Opcao invalida ou saida */
                              /* Volta ao inicio do loop */

       printf("\nEntre com o numero: ");
       switch (opcao)
          {
          case 1:
                  scanf("%d", &entrada);
                  printf("Numero convertido: %x", entrada);
          break;
          case 2:
                  scanf("%x", &entrada);
                  printf("Numero convertido: %d", entrada);
          break;
          case 3:
                  scanf("%d", &entrada);
                  printf("Numero convertido: %o", entrada);
          break;
          case 4:
                  scanf("%o", &entrada);
                  printf("Numero convertido: %d", entrada);
          break;
          }
          do
             {
             printf("\n\n(F) Finaliza e (M) Retorna ao Menu. Opcao: ");
             fflush(NULL);
             scanf("%c", &opcao_c);
             } while ((opcao_c != 'F')&&(opcao_c != 'M'));
          if (opcao_c == 'F') opcao = 5;
       }
}
 

  Sumário

Dúvidas? Dê uma olhadinha em nosso FAQ

Perguntas para a lista do Curso de C
Curso de C do CPDEE/UFMG - 1996-1998