Programação Imperativa
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.0;
      while( c <= 40.0 )
       {
         f = 9.0/5.0 * c + 32.0;
         printf(" %5.1lf   %5.1lf\n", c, f );
         c = c + 2.0;
       }
    }

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.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.0;
      printf("Introduz uma série de números e termina com -1\n");
      do

        {
          scanf("%lf", &x );
          if (x!=-1.0)
           {
             soma = soma + x;
             n++;
           }

        }
      while ( x != -1 );

      if (n!=0) 
        printf("A média é %lf\n", soma / (double) n);
      else
        printf("Média indefinida\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.0;
      printf("Introduz uma série de números e termina com -1\n");
      do
       {
         scanf("%lf", &x);

         if (x!=-1.0)
           {
             if (n==0)

               {
                 min = x;
                 max = x;
               }
             soma = soma + x;
             if (x<min) min = x;
             if (x>max) max = x;
             n++;
           }
       } 
      while (x!=-1.0);

      if (n!=0)
        {
          printf("O mínimo é %lf\n", min);
          printf("O máximo é %lf\n", max);
          printf("A média é %lf\n", soma / (double) n);
        }

      else
        printf("Média, máximo e mínimo indefinidos\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 */
         for (i=2; i<n; i++)
          {
            if( n % i == 0 )
              /* afinal não é primo */
              primo = 0;
          }
         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 assim que houver uma divisão que dê resto 0. Apenas faz sentido com o ciclo while. Pois já não é bem contável:

    #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( (double) 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.

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);
}


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 );
      for (i=1; i<=n; i++)
       {
         if( (n%i)==0 )
           printf("%d ", i);
       }
      printf("\n");
    }


Programa 8

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

Resolução
    #include <stdio.h>
    
    
    
    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<=20; 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.