Programação Imperativa

Aula 15

Sumário

Continuação da aula passada.




Arrays com mais de uma dimensão

Pode-se definir arrays com mais de uma dimensão. Exemplo:

    int a[3][4];

define um array de 2 dimensões, uma tabela com 3 linhas e 4 colunas. Cada elemento da tabela é do tipo inteiro. Não se esqueçam que na linguagem C os arrays começam na posição zero.

O programa seguinte soma os elementos de duas tabelas de dimensão M x N. Cada elemento da linha i coluna j da tabela M é somado ao elemento da linha i coluna j da tabela N.

    #include <stdio.h>
    #include <math.h>
    
    #define M 3   
    #define N 4
        
    main()
    {
      float a[M][N], b[M][N], c[M][N];    /* tabelas A, B, e C */
      int i,j;
      
      /* introdução dos elementos da tabela a */
      printf("Introduz os elementos da tabela A de %d x %d: ", M, N );      
      for( i=0; i<M; i++ )
        for( j=0; j<N; j++ )
          scanf("%f", &a[i][j] );

      /* introdução dos elementos da tabela b */
      printf("Introduz os elementos da tabela B de %d x %d: ", M, N );      
      for( i=0; i<M; i++ )
        for( j=0; j<N; j++ )
          scanf("%f", &b[i][j] );
          
      /* soma os elementos da tabela */
      for( i=0; i<M; i++ )
        for( j=0; j<N; j++ )
          c[i][j] = a[i][j] + b[i][j];
                 
      /* escreve o resultado */
      printf("A tabela soma é:\n");      
      for( i=0; i<M; i++ )
       {
         for( j=0; j<N; j++ )
           printf("%f ", c[i][j] );
         printf("\n");
       }     
    }   

Quando se define um array, o compilador tem de saber a sua dimensão. Para tornarmos o programa anterior mais geral, podemos definir uma dimensão máxima, MAX_DIM, e depois controlamos as dimensões da tabela através de duas variáveis: m e n. Isso torna o programa um pouco mais geral.

    ...
    #define MAX_DIM 100  /* número máximo de linhas e colunas */   
        
    main()
    {
      float a[MAX_DIM][MAX_DIM],   /* tabela A */
            b[MAX_DIM][MAX_DIM],   /* tabela B */
            c[MAX_DIM][MAX_DIM];   /* tabela C */
      int   m,n,
            i,j;
      
      printf("Introduz as dimensões da tabela A\n");
      printf("O número máximo de linhas e colunas é %d\n: ", MAX_DIM );
      printf("Linhas: "); scanf("%f", &m );
      printf("Colunas: "); scanf("%f", &n );
      printf("Introduz os elementos da tabela A de %d x %d: ", m, n );      
      for( i=0; i<m; i++ )
        for( j=0; j<n; j++ )
          scanf("%f", &a[i][j] );
      ...    
    }   

Mais tarde vamos aprender um modo ainda mais geral do que este em que não é necessário conhecer a dimensão dos arrays apriori.

NOTA: não há limite em relação ao número de dimensões de um array. Pode-se definir arrays com n dimensões. A seguinte definição declara um array de 10 x 3 x 5.

    int a[10][3][5];

Inicialização de arrays

Os elementos de um array podem ser inicializados individualmente, tal e qual como se inicializa outro tipo de variáveis. Por exemplo, suponhamos que queríamos ter um array para guardar 5 números inteiros.

    int x[5];

Nesta altura, o conteúdo dos elementos do array ainda está indefinido. Podemos inicializa-lo utilizando instruções de atribuição:

    x[0] = 77;
    x[1] = 3;
    x[2] = 21;
    x[3] = 25;
    x[4] = 9;

mas também podemos inicializar durante a definição do próprio array:

    int x[5] = { 77, 3, 21, 25, 9 };

De facto, as outras variáveis também podem ser inicializadas durante a sua definição.

    int a = 0, b = 1;

é equivalente a:

    int a,b;
    
    a = 0;
    b = 1;

Um array com mais de uma dimensão também podem ser inicializado durante a sua definição. A seguinte tabela:

     1 2 3 4
     0 1 0 5
     0 0 1 0

pode ser declarada e inicializada do seguinte modo:

    int a[3][4];
    
    a[0][0] = 1;  
    a[0][1] = 2;  
    a[0][2] = 3;  
    a[0][3] = 4;  
    a[1][0] = 0;  
    a[1][1] = 1;  
    a[1][2] = 0;  
    a[1][3] = 5;  
    a[2][0] = 0;  
    a[2][1] = 0;  
    a[2][2] = 1;  
    a[2][3] = 0;

mas também pode ser declarada e inicializada assim:

    int a[3][4] = { 
                    {1, 2, 3, 4},
                    {0, 1, 0, 5},
                    {0, 0, 1, 0} 
                  };

Cadeias de caracteres

Quase todos os programas que fizemos até agora são programas que manipulam informação numérica, mas também podemos fazer programas para manipular informação não numérica tais como nomes e moradas de pessoas.

A linguagem C não tem um tipo de dados próprio para guardar nomes de pessoas. Em C vimos que existem variáveis do tipo inteiro (int), real (float e double) e caracter (char). Apesar de não haver um tipo próprio para guardar nomes, podemos utilizar uma sequência (um array) de caracteres (estas sequências também se costumam designar por cadeias de caracteres ou strings).

    char nome[100];

    nome[0]  = 'L';
    nome[1]  = 'u';
    nome[2]  = 'i';
    nome[3]  = 's';
    nome[4]  = ' ';
    nome[5]  = 'F';
    nome[6]  = 'i';
    nome[7]  = 'g';
    nome[8]  = 'o';
    nome[11] = '\0';

O caracter '\0' é um caracter especial que indica o fim da cadeia de caracteres. Também podíamos ter declarado e inicializado a variável de uma só vez

    char nome[100] = "Luis Figo";

Neste caso, o computador coloca automaticamente o caracter '\0' logo após o 'o' de 'Figo'.

Podemos escrever uma cadeia de caracteres com a instrução printf. Para tal, utiliza-se %s.

    char nome[100] = "Luis Figo";
    printf("O nome é %s\n", nome );

A biblioteca string.h

Existe uma biblioteca chamada string.h (string significa cadeia de caracteres em inglês). Essa biblioteca tem um série de funções para manipular cadeias de caracteres.

    strlen(p)    dá o comprimento da string p
    strcpy(p,q)  copia a string q para a string p  
    strcat(p,q)  junta a string q ao final da string p
    strcmp(p,q)  devolve um número negativo se p<q, 
                                       zero se p==q, 
                                   positivo se p>q

Estes nomes são um bocado esquisitos mas não se assustem. Os nomes são abreviaturas do inglês.

    strlen --> string length
    strcpy --> string copy
    strcat --> string concatenate
    strcmp --> string compare

A biblioteca string.h contem muitas outras funções, mas estas 4 que acabei de apresentar são aquelas que costumam ser mais utilizadas.

Exemplo:

    #include <stdio.h>
    #include <string.h>
    
    main()
    {
      char a[100] = "Ronaldo";
      char b[100] = "Luis Figo";
      int x;
    
      printf("Comprimento de %s é %d\n", a, strlen(a) );
      printf("Comprimento de %s é %d\n", b, strlen(b) );
      strcpy(a, "Zinedine" );
      printf("Comprimento de %s é %d\n", a, strlen(a) );
      strcat(a, " Zidane");
      printf("Comprimento de %s é %d\n", a, strlen(a) );
      x = strcmp(a,b);
      if( x == 0 )
        printf("%s é igual a %s\n", a, b );
      else if( x < 0 )
        printf("Por ordem alfabética, %s aparece antes de %s\n", a, b );
      else
        printf("Por ordem alfabética, %s aparece antes de %s\n", b, a );
    }

Ao ser executado o programa vai escrever o seguinte no ecrã

    Comprimento de Ronaldo é 7
    Comprimento de Luis Figo é 9
    Comprimento de Zinedine é 8
    Comprimento de Zinedine Zidane é 15
    Por ordem alfabética, Luis Figo aparece antes de Zinedine Zidane

Introdução de cadeias de caracteres

Se quisermos pedir ao utilizador para introduzir uma string, podemos utilizar a função gets que está definida em stdio.h.

    #include <stdio.h>
    #include <string.h>
    
    main()
    {
      char a[100];
      char b[100];
      int x;
    
      printf("Diz um nome: ");
      gets(a);
      printf("Diz outro nome: ");
      gets(b);
      x = strcmp(a,b);
      if( x == 0 )
        printf("%s é igual a %s\n", a, b );
      else if( x < 0 )
        printf("Por ordem alfabética, %s aparece antes de %s\n", a, b );
      else
        printf("Por ordem alfabética, %s aparece antes de %s\n", b, a );
    }

Ao ser executado o programa vai escrever o seguinte no ecrã

    Diz um nome: porto
    Diz outro nome: sporting
    Por ordem alfabética, porto aparece antes de sporting

NOTA: a função gets é um bocado "perigosa". No exemplo que acabamos de ver, se o utlizador introduzir uma string com mais de 100 caracteres o programa pode "estoirar" porque o computador vai tentar aceder a posições que já estão fora dos limites do array (mais tarde, quando dermos a matéria de apontadores, ensino-vos como é que se pode resolver este problema).

Uma lista de nomes

Se quisermos ter uma lista de nomes temos de declarar um array de nomes, isto é, um array de cadeias de caracteres. O seguinte exemplo define um array de 5 cadeias de caracteres, cada qual podendo ter a dimensão máxima de 100 caracteres (incluindo o '\0').
    #include <stdio.h>
    
    main()
    {
      char a[5][100] = {
                         "Luis Figo",
                         "Ronaldo",
                         "Zinedine Zidane",
                         "Rui Costa", 
                         "Rivaldo"
                       };
      int i;
    
      for( i=0; i<5; i++ )
        printf("%s\n", a[i] );
    }