Programação I

Soluções dos exercícios da aula prática 5

Programa 1

Faz um programa que escreve no ecrã uma tabela de conversão de graus Celcius para Fahrenheit. A tabela deve apresentar os graus Celcius de 0 a 40 com intervalos de 2 em 2.

    #include <stdio.h>
    
    main()
    {
      double c, f;
    
      printf("Celcius  Fahrenheit\n");
      c = 0;
      while( c <= 40 )
       {
         f = 9.0/5.0 * c + 32;
         printf(" %5.1lf   %5.1lf\n", c, f );
         c = c + 2;
       }
    }
    

Programa 2

Modifica o programa que calcula a área do círculo de modo a que o programa funcione ininterruptamente até o utilizador introduzir o valor zero para o raio. Nessa altura, o programa deve dizer que a área é zero, e terminar com um "Até logo".

    #include <stdio.h>
    
    #define PI  3.14159
    
    main()
    {
      double area, raio;
      
      do
       {
         printf("Introduz o raio: ");
         scanf("%lf", &raio);
         if( raio < 0 )
           printf("Esse raio é inválido\n");
         else
          {
            area = PI * raio * raio;
            printf("A área é %lf\n", area );
          }
       }
      while( raio != 0 );
      printf("Até logo.\n");
    }
    

Programa 3

Faz um programa que vai pedindo números ao utilizador até que este introduza o número -1. O computador deve dizer a média dos números introduzidos (excluindo o -1).

    #include <stdio.h>
    
    main()
    {
      double x, soma;
      int n;
    
      n = 0;
      soma = 0;
      printf("Introduz uma série de números e termina com -1\n");
      scanf("%lf", &x );
      if( x == -1 )
        printf("Média indefinida\n");
      else
        {
          do
           {
             soma = soma + x;
             n++;
             scanf("%lf", &x );
           } 
          while ( x != -1 );
          printf("A média é %lf\n", soma/n);
        }
    }
    

Programa 4

Modifica o programa anterior, de modo a dar o mínimo, máximo e média.

    #include <stdio.h>
    
    main()
    {
      double x, soma, min, max;
      int n;
    
      n = 0;
      soma = 0;
      printf("Introduz uma série de números e termina com -1\n");
      scanf("%lf", &x );
      if( x == -1 )
        printf("Média, máximo e mínimo indefinidos\n");
      else
        {
          max = x;
          min = x;
          do
           {
             soma = soma + x;
             if( x < min ) min = x;
             if( x > max ) max = x;
             n++;
             scanf("%lf", &x );
           } 
          while ( x != -1 );
          printf("O mínimo é %lf\n", min );
          printf("O máximo é %lf\n", max );
          printf("A média é %lf\n", soma/n);
        }
    }
    
    

Programa 5

Faz um programa para ver se um número é primo ou não (um número só é primo se apenas for divisível por 1 e por si próprio).

Vamos resolver o programa de 4 maneiras diferentes (nota: a definição de número primo é aquela que foi dada no enunciado, mas só é válida para os números Naturais maiores ou iguais a 2. Por outras palavras, o número 1 não é primo. Peço desculpa por não ter referido isto no enunciado).

Solução 1:

    #include <stdio.h>
    
    main()
    {
      int i, n;
      int primo;  /* a variável primo só vai assumir os valores 0 e 1 */
                  /* 0 significa que n não é primo */
                  /* 1 significa que n é primo */ 
    
      printf("Introduz um número: \n");
      scanf("%d", &n );
      if( n <= 1 )
        printf("%d não é primo\n", n );
      else
       {  
         i = 2;
         primo = 1;  /* vamos assumir que n é primo */
         while( i < n )
          {
            if( n % i == 0 )
              /* afinal não é primo */
              primo = 0;
            i++;
          }
         if( primo == 1 )
           printf("%d é primo\n", n );
         else
           printf("%d não é primo\n", n );
       }
    }
    

Solução 2: tem a vantagem de abandonar o ciclo while assim que houver uma divisão que dê resto 0.

    #include <stdio.h>
    
    main()
    {
      int i, n;
      int primo;  /* a variável primo só vai assumir os valores 0 e 1 */
                  /* 0 significa que n não é primo */
                  /* 1 significa que n é primo */ 
    
      printf("Introduz um número: \n");
      scanf("%d", &n );
      if( n <= 1 )
        printf("%d não é primo\n", n );
      else
       {
         i = 2;
         primo = 1;  /* vamos assumir que n é primo */
         while( (i < n) && (primo == 1) )
          {
            if( n % i == 0 )
              /* afinal não é primo */
              primo = 0;
            i++;
          }
         if( primo == 1 )
           printf("%d é primo\n", n );
         else
           printf("%d não é primo\n", n );
       }
    }
    

Solução 3: a mesma coisa que a solução anterior, mas utiliza um break para abandonar o ciclo.

    #include <stdio.h>
    
    main()
    {
      int i, n;
    
      printf("Introduz um número: \n");
      scanf("%d", &n );
      if( n <= 1 )
        printf("%d não é primo\n", n );
      else
       {
         i = 2;
         while( i < n )
          {
            if( n % i == 0 )
              /* não é primo */
              break;
            i++;
          }
         if( i == n )
           printf("%d é primo\n", n );
         else
           printf("%d não é primo\n", n );
       }
    }
    

Solução 4: para ver se um número n é primo, não é necessário fazer as divisões todas desde 2 até n-1. Basta fazer as divisões desde 2 até sqrt(n). Porquê?

    #include <stdio.h>
    #include <math.h>
    
    main()
    {
      int i, n, raiz;
    
      printf("Introduz um número: \n");
      scanf("%d", &n );
      if( n <= 1 )
        printf("%d não é primo\n", n );
      else
       {
         raiz = (int) sqrt(n);
         i = 2;
         while( i <= raiz  )
          {
            if( n % i == 0 )
              /* não é primo */
              break;
            i++;
          }
         if( i > raiz )
           printf("%d é primo\n", n );
         else
           printf("%d não é primo\n", n );
       }
    }

Programa 6

Faz um programa para calcular o factorial de um número.

Tenta fazer três versões deste programa, uma usando a instrução FOR, outra utilizando a instrução WHILE e uma terceira com a instrução DO... WHILE.

Versão 1. Com a instrução for:

#include <stdio.h>

main()
{
  int factorial,n,i;

  printf("Diz um numero: ");
  scanf("%d",&n);
  factorial=1;
  for (i=n; i>1; i--)
     factorial=factorial*i;
  printf("O factorial de %d e %d",n,factorial);
}

Versão 2. Com a instrução while:

#include <stdio.h>

main()
{
  int factorial,n,i;

  printf("Diz um numero: ");
  scanf("%d",&n);
  factorial=1;
  i=n;
  while (i>1)
  {
     factorial=factorial*i;
     i--;
  }
  printf("O factorial de %d e %d",n,factorial);
}

Versão 3. Com a instrução do ... while:

#include <stdio.h>

main()
{
  int factorial,n,i;

  printf("Diz um numero: ");
  scanf("%d",&n);
  factorial=1;
  i=n;
  do
  {
     factorial=factorial*i;
     i--;
  } while (i>1);
  printf("O factorial de %d e %d",n,factorial);
}

Programa 7

Faz um programa que calcula todos os divisores de um número.

Resolução

    #include <stdio.h>
    
    main()
    {
      int n, i;
    
      printf("Introduz um número:\n");
      scanf("%d", &n );
      printf("Os divisores de %d são ", n );
      i = 1;
      while( i <= n )
       {
         if( n % i == 0 )
           printf("%d ", i );
         i++;
       }
      printf("\n");
    }

Também podiam ter feito assim:

    #include <stdio.h>
    
    main()
    {
      int n, i;
    
      printf("Introduz um número:\n");
      scanf("%d", &n );
      printf("Os divisores de %d são ", n );
      for( i = 1; i <= n; i++ )
        if( n % i == 0 )
          printf("%d ", i );
      printf("\n");
    }

NOTA: Em ambos os casos, o ciclo pode ir só até n/2.


Programa 8

Faz um programa que escreve no ecrã os primeiros 20 números de Fibonacci.

Resolução

    #include <stdio.h>
    
    #define N  20
    
    main()
    {
      int i,
          fi,      /* F(i)   */
          fi_1,    /* F(i-1) */
          fi_2;    /* F(i-2) */
    
      fi_1 = 1; 
      fi_2 = 1; 
      printf("1\n");
      printf("1\n");
      for( i = 3; i <= N; i++ )
       {
         fi = fi_1 + fi_2;    /* F(i) = F(i-1) + F(i-2) */
         printf("%d\n", fi );
         fi_2 = fi_1;
         fi_1 = fi;
       }
    }

Programa 9

Faz um programa que pede um valor decimal inteiro positivo e o converte para binário.

Resolução

#include <stdio.h>

main()
{
   int dec, pot10;
   unsigned long nbin;

   printf("Introduza um valor decimal: ");
   scanf("%d",&dec);
   pot10=1;
   nbin=0;
   while (dec > 0)
      {
	nbin = nbin + pot10 * (dec % 2);
	dec = dec / 2;
	pot10 = pot10 * 10;
      }
   printf("O valor em binario: %ld\n",nbin);
}

Programa 10

Altera o programa do exercício 9 de forma a que converta o número de decimal para qualquer outra base.

Resolução

#include <stdio.h>

main()
{
   int dec, pot10, base;
   unsigned long nconv;

   printf("Introduza um valor decimal: ");
   scanf("%d",&dec);
   printf("Introduza a base de conversao: ");
   scanf("%d",&base);
   pot10=1;
   nconv=0;
   while (dec > 0)
      {
	nconv = nconv + pot10 * (dec % base);
	dec = dec / base;
	pot10 = pot10 * 10;
      }
   printf("O valor na base %d: %ld\n",base,nconv);
}

A resolução apresentada funciona correctamente apenas para bases de conversão menores ou iguais a 10.

Porque não funciona correctamente para bases superiores? Pensa sobre o assunto.