Programação Imperativa

Aula 13 e 14

Sumário




Conversão de tipos

Por vezes há situações em que temos de converter tipos de dados. Por exemplo, algumas pessoas obtiveram um erro quando fizeram o exercício de conversão de graus Celcius para Fahrenheit numa das aulas práticas.

    ...
    c = 30;
    f = 9/5 * c + 32;
    ...
O problema acontece porque o computador vai fazer apenas a divisão inteira e nesse caso, 9/5 = 1. O problema resolve-se escrevendo 9.0/5.0 em vez de 9/5. Mas imaginem que em vez de 9 e 5 tínhamos variáveis inteiras:
    int a,b;
    float f;

    ...
    a = 9;
    b = 5;
    f = a/b;
    ...
Tal com está, o valor de f vai ser 1. No entanto, podemos dar ordem ao computador para converter o valor de uma expressão/variável para outro tipo de dados. No exemplo acima teríamos de fazer o seguinte:
    int a,b;
    float f;

    ...
    a = 9;
    b = 5;
    f = (float) a / (float) b;
    ...
Isto faz com que o valor de a e b sejam convertidos para float antes do computador executar a divisão. Deste modo o valor de f vai ser 1.8. Reparem que depois da instrução f = ..., a e b continuam a ser variáveis inteiras, a conversão só foi feita temporariamente.

Arrays de uma dimensão

Existem situações em que necessitamos de ter muitas variáveis, cada qual mais ou menos com a mesma função. Isso acontece muitas vezes quando trabalhamos com listas ou sequências de números. Por exemplo, a média de uma lista de n números, X1, X2, ..., Xn, é definida como:

    média = (X1 + X2 + ... + Xn) / n

e o desvio de cada número em relação à média é dado pela fórmula:

    desvio = Xi - média    , para i = 1,2,...,n

Imaginem que queríamos fazer um programa para calcular a média de uma lista de 10 números e o desvio de cada número em relação à média. Com a matéria que aprendemos até agora, teríamos de fazer qualquer coisa deste estilo:

    float x1, x2, x3, x4, x5, x6, x7, x8, x9, x10;
    float d1, d2, d3, d4, d5, d6, d7, d8, d9, d10;
    float media;
    
    ...
    media = (x1+x2+x3+x4+x5+x6+x7+x8+x9+x10) / 10;
    d1 = x1 - media;
    d2 = x2 - media;
    ...
    d10 = x10 - media;    

Se em vez de 10 números fossem 100, teríamos de declarar 100 variáveis e isso seria uma grande chatice. É aqui que surge o conceito de array. A definição seguinte:

    float x[10];

define um array de nome x com 10 posições, cada uma correspondendo a uma variável do tipo float. Um array é como se fosse uma lista ou sequência de variáveis. Na linguagem C, os arrays começam sempre na posição 0. Por isso, a declaração float x[10] define as variáveis:

    x[0], x[1], x[2], ..., x[9]

Depois de definido o array, os seus elementos podem ser acedidos e modificados individualmente, tal e qual como nas variáveis que vimos até agora. Por exemplo:

    x[7] = 54;
    a = x[7];
O caso geral da definição de um array é:
    tipo nome[dimensão]
Se quisermos definir um array de nome a com 5 posições, cada qual podendo conter um número inteiro, temos de escrever:
    int a[5];

Podem pensar no array a como se fosse uma sequência de 5 caixas, cada qual do tipo int, indexadas pelos índices 0,1,2,3,4.

depois de efectuar as seguintes instruções:

    a[0] = 134;
    a[1] = 5;
    a[2] = 71;
    a[3] = -65;
    a[4] = 12;

o estado do array a passa a ser

Depois desta breve introdução, vamos fazer o programa para calcular a média de uma lista de 10 números e os respectivos desvios em relação à média.

    #include <stdio.h>
    
    main()
    {
      float x[10];        /* lista de números */
      float desvio[10];   /* desvios em relação à média */
      float soma;   
      float media;  
      int   i;
      
      /* introdução dos números e cálculo da média */
      soma = 0;
      printf("Introduz 10 números: ");      
      for( i=0; i<10; i++ )
       {
         scanf("%f", &x[i] );
         soma = soma + x[i];
       }
      media = soma / 10;
      
      /* calculo dos desvios */
      for( i=0; i<10; i++ )
        desvio[i] = x[i] - media;
      
      /* escreve a média, os números, e os respectivos desvios */              
      printf("A média é %f\n", media );
      for( i=0; i<10; i++ )
        printf("x[%d] = %f    desvio[%d] = %f\n", i, x[i], i, desvio[i] );
    }   

Atenção: Têm que ter cuidado e não aceder a posições fora dos limites do array. Por exemplo, se definirem:

       
    float x[10];

e tentarem aceder a x[12] o compilador não dá erro, mas o programa vai comportar-se de um modo imprevisível.

Apesar de funcionar correctamente, o programa pode ser melhorado através da definição de uma constante.

    #include <stdio.h>
    
    #define N 10    
        
    main()
    {
      float x[N];        /* lista de números */
      float desvio[N];   /* desvios em relação à média */
      float soma;   
      float media;  
      int   i;
      
      /* introdução dos números e calculo da média */
      soma = 0;
      printf("Introduz %d números: ", N);      
      for( i=0; i<N; i++ )
       {
         scanf("%f", &x[i] );
         soma = soma + x[i];
       }
      media = soma / N;
      
      /* calculo dos desvios */
      for( i=0; i<N; i++ )
        desvio[i] = x[i] - media;
      
      /* escreve a média, os números, e os respectivos desvios */              
      printf("A média é %f\n", media );
      for( i=0; i<N; i++ )
        printf("x[%d] = %f    desvio[%d] = %f\n", i, x[i], i, desvio[i] );
    }   

Este é um bom exemplo para ilustrar a vantagem da utilização de constantes. Se em vez de 10 números quisermos 100, basta alterar a linha da definição da constante para:

    #define N 100

Se não tivéssemos usado a constante N, teríamos de vasculhar o programa todo e substituir as ocorrências de 10 por 100. Isso torna o programa mais difícil de modificar. Além disso, mais facilmente se pode introduzir erros de execução. Por exemplo, podíamos esquecer de substituir um dos 10 por 100. O programa funcionaria na mesma, mas iria dar resultados errados.


Ordenação de uma lista de números

Numa das primeiras aulas práticas fizeram um programa que ordenava por ordem crescente 3 números introduzidos pelo utilizador. Pensa agora num programa para ordenar uma lista de N números por ordem crescente. Por exemplo, se N=10 e os números introduzidos forem:
    12  3  8  21  5  93  76  5  32  16
O programa deveria escrever:
    3  5  5  8  12  16  21  32  76  93
Para fazer este programa vamos utilizar um algoritmo de ordenação. Um algoritmo é uma espécie de receita que deve ser executada passo a passo.
    Algoritmo de ordenação
    
    Entrada: uma sequência de N números: a[0], a[1], ... a[N-1]
    Saída: uma permutação desses N números de tal modo que
           a[0] <= a[1] <= ... <= a[N-1]
              
    1. k = 0;
    2. m = posição do mínimo( a[k] ... a[N-1] )
    3. trocar a[k] com a[m]
    4. k = k+1
    5. Se k < N-1 voltar ao passo 2.


    Exemplo de execução do algoritmo:        
 
    12  3  8  21  5  93  76  5  32  16   ->  sequência inicial de números

    3  12  8  21  5  93  76  5  32  16   ->  k=0, m=1, troca a[0] com a[1]

    3  5  8  21  12  93  76  5  32  16   ->  k=1, m=4, troca a[1] com a[4]

    3  5  5  21  12  93  76  8  32  16   ->  k=2, m=7, troca a[2] com a[7]

    3  5  5  8  12  93  76  21  32  16   ->  k=3, m=7, troca a[3] com a[7]

    3  5  5  8  12  93  76  21  32  16   ->  k=4, m=4, troca a[4] com a[4]

    3  5  5  8  12  16  76  21  32  93   ->  k=5, m=9, troca a[5] com a[9]

    3  5  5  8  12  16  21  76  32  93   ->  k=6, m=7, troca a[6] com a[7]

    3  5  5  8  12  16  21  32  76  93   ->  k=7, m=8, troca a[7] com a[8]

    3  5  5  8  12  16  21  32  76  93   ->  k=8, m=8, troca a[8] com a[8]

    3  5  5  8  12  16  21  32  76  93   ->  sequência final está ordenada