Aula 7 - Resoluções


Exercício 1

Alíneas a) e b)

matriz4x4
inicio
    inteiro matriz[4][4], i, j, traco;

    (* Ler a matriz: *)

    escrever "Introduza uma matriz de 4x4:", linha;
    (* Ler linha a linha: *)
    para i <- 0, 3:
        (* Ler toda a linha i: *)
        para j <- 0, 3:
            ler para matriz[i][j];
        fim para;
    fim para;

    (* Escrever o conteudo da matriz: *)

    escrever "O conteudo da matriz e':", linha;
    (* Escrever a primeira linha: *)
    para i <- 0, 3:
        (* Escrever toda a linha i: *)
        para j <- 0, 3:
            escrever matriz[i][j], " ";
        fim para;
 
        (* Terminar a linha: *)
	escrever linha;
    fim para;

    (* Escrever a diagonal `a medida que se calcula o traco da matriz: *)
    escrever "A diagonal da matriz e': ";
    traco <- 0;
    para i <- 0, 3:
        traco <- traco + matriz[i][i];
        escrever matriz[i][i], " ";
    fim para;
    (* Terminar a linha: *)
    escrever linha;

    (* Escrever o traco: *)
    escrever "O traco da matriz e': ", traco, linha;
fim.

A tradução do algoritmo para C fica como exercício.

Alínea c)

matriz4x4
inicio
    inteiro A[4][3], B[3][4], C[4][4], i, j, k;

    (* Ler as matrizes: *)

    escrever "Introduza a matriz A (4x3):", linha;
    para i <- 0, 3:
        para j <- 0, 2:
            ler para A[i][j];

    escrever "Introduza a matriz B (3x4):", linha;
    para i <- 0, 2:
        para j <- 0, 3:
            ler para B[i][j];

    (* Calcular a multiplicacao C = AB: *)

    para i <- 0, 3:
        para j <- 0, 3:
            (* C[i][j] e' A[i][0]*B[0][j] + ... + A[i][2]*B[2][j]: *)
            C[i][j] <- 0;
            para k <- 0, 2:
                C[i][j] <- C[i][j] + A[i][k] * B[k][j];

    (* Escrever o conteudo da matriz C: *)

    escrever "O conteudo da matriz C e':", linha;
    para i <- 0, 3:
        para j <- 0, 3:
            escrever C[i][j], " ";
	escrever linha;
fim.
#include <stdio.h>
#include <stdlib.h>

#define L 4
#define M 3
#define N 4

int main(void)

{
    int A[L][M], B[M][N], C[L][N], i, j, k;

    printf("Introduza a matriz A (%dx%d):\n", L, M);
    for(i = 0; i < L; i++) 
        for(j = 0; j < M; j++)
            scanf("%d", &A[i][j]);

    printf("Introduza a matriz B (%dx%d):\n", M, N);
    for(i = 0; i < M ; i++)
        for(j = 0; j < N; j++)
            scanf("%d", &B[i][j]);

    for(i = 0; i < L; i++)
        for(j = 0; j < N; j++)
        {
            C[i][j] = A[i][0] * B[0][j];
            for(k = 1; k < M; k++)
                C[i][j] += A[i][k] * B[k][j];
        }

    printf("O conteudo da matriz C e':\n");
    for(i = 0; i < L; i++)
    {
        for(j = 0; j < N; j++)
            printf("%d ", C[i][j]);
	printf("\n");
    }

    return EXIT_SUCCESS;
} 

Exercício 2

Alíneas a), b) e c)

Solução usando matrizes de tamanho NA (primeira sequência), NB (segunda sequência) e NC (sequência de concatenação).

Note-se que esta solução poderia ser encurtada, pois contém redundâncias. No entanto julgou-se vantajoso apresentar pedaços de código tão independentes quanto possível uns dos outros de modo a poderem ser retirados do seu contexto sem problemas, e assim reaproveitar os algoritmos quando for necessário.

MatrizesAteZeroConcatena
inicio
    inteiro A[NA], B[NB], C[NC], i, j;

    escrever "Introduza primeira sequencia (termina com zero):", linha;
    i <- 0;
    fazer:
	ler para A[i];
        i <- i + 1;
    enquanto A[i - 1]  0 e i < NA - 1; (* NA - 1 para caber o zero final! *)
    se A[i - 1]  0: (* se necessario escrever o zero final: *)
        A[i] <- 0;
    
    escrever "Introduza segunda sequencia (termina com zero):", linha;
    i <- 0;
    fazer:
	ler para B[i];
        i <- i + 1;
    enquanto B[i - 1]  0 e i < NB - 1; (* NB - 1 para caber o zero final! *)
    se B[i - 1]  0:
        B[i] <- 0;
    
    (* Calcular os comprimentos das sequencias: *)
    i <- 0;
    enquanto A[i]  0:
        i <- i + 1;
    escrever "A primeira sequencia tem comprimento ", i, ".", linha;

    i <- 0;
    enquanto B[i]  0:
        i <- i + 1;
    escrever "A segunda sequencia tem comprimento ", i, ".", linha;

   (* Escrever as duas sequencias: *)
    escrever "A primeira sequencia e': ";
    i <- 0;
    enquanto A[i]  0:
        escrever A[i], " ";
        i <- i + 1;
    escrever linha;

    escrever "A segunda sequencia e': ";
    i <- 0;
    enquanto B[i]  0:
        escrever B[i], " ";
        i <- i + 1;
    escrever linha;

   (* Copiar A para C: *)
    i <- 0;
    enquanto A[i]  0 e i < NC - 1:
        C[i] <- A[i];
        i <- i + 1;
    C[i] <- 0; (* escrever o zero final. *)

    (* Concatenar B a C: *)
    
    (* Calcular comprimento de C: *)
    j <- 0;
    enquanto C[j]  0:
        j <- j + 1;

    (* Concatenar: *)
    i <- 0;
    enquanto B[i]  0 e j < NC - 1:
        C[j] <- B[i];
        i <- i + 1;
        j <- j + 1;
    C[j] <- 0;

    (* Escrever o resultado da concatenacao: *)
    escrever "Concatenadas sao: ";
    i <- 0;
    enquanto C[i]  0:
        escrever C[i], " ";
        i <- i + 1;
    escrever linha;
fim.
/* Concatena matrizes (ate zero): */
#include <stdio.h>
#include <stdlib.h>

/* Definicao das constantes Na, NB e NC: */
#define NA 1000    
#define NB 500
#define NC 200

int main(void)
{
    int A[NA], B[NB], C[NC], i, j;

    printf("Introduza primeira sequencia (termina com zero):\n");

    i = 0;
    do
	scanf("%d", &A[i]);
    while(A[i++] != 0 && i < NA - 1);

    if(A[i - 1] != 0)
        A[i] = 0;
    
    printf("Introduza segunda sequencia (termina com zero):\n");

    i = 0;
    do
	scanf("%d", &B[i]);
    while(B[i++] != 0 && i < NB - 1);

    if(B[i - 1] != 0)
        B[i] = 0;
    
    /* Calculo do comprimento da primeira sequencia: */

    for(i = 0; A[i] != 0; i++)
        /* Instrucao nula!*/;

    printf("A primeira sequencia tem comprimento %d.\n", i);

    /* Calculo do comprimento da segunda sequencia: */

    for(i = 0; B[i] != 0; i++)
        /* Instrucao nula!*/;

    printf("A segunda sequencia tem comprimento %d.\n", i);

    printf("A primeira sequencia e': ");

    for(i = 0; A[i] != 0; i++)
        printf("%d ", A[i]);
    putchar('\n');

    printf("A segunda sequencia e': ");

    for(i = 0; B[i] != 0; i++)
        printf("%d ", B[i]);
    putchar('\n');

    /* Copiar de A para C: */

    for(i = 0; (C[i] = A[i]) != 0 && i < NC - 1; i++)
        /* Instrucao nula! */;

    if(C[i] != 0)
        C[i] = 0;

    /* Concatenar B a C: */
    
    for(j = 0; C[j] != 0; j++)
        /* Instrucao nula! */;

    for(i = 0; (C[j] = B[i]) != 0 && j < NC - 1; i++, j++)
        /* Instrucao nula! */;

    if(C[j] != 0)
        C[j] = 0;

    printf("Concatenadas sao: ");

    for(i = 0; C[i] != 0; i++)
        printf("%d ", C[i]);
    putchar('\n');

    return EXIT_SUCCESS;
}

O operador ++ usado como afixo incrementa o valor depois de utilizado na expressão, enquanto usado como prefixo incrementa antes da sua utilização. Por exemplo:

    i = 0;
    printf("Antes: %d\n", i++);
    printf("Depois: %d\n", i);
    i = 0;
    printf("Antes: %d\n", ++i);
    printf("Depois: %d\n", i);

imprime:

Antes: 0
Depois: 1
Antes: 1
Depois: 1

Por isso, em

i = 0;
j = i++ + i;

a expressão j = i++ + i coloca em j um de dois possíveis valores: ou 0 ou 1. Tal deve-se a que i ocorre duas vezes na expressão e uma das vezes é afectado por um operador com efeitos laterais (o operador ++). Este tipo de expressões estão pura e simplesmente erradas.

Mas, sendo assim, porque se usa no programa acima a expressão A[i++] != 0 && i < NA - 1? É que neste caso as duas utilizações da variável i se fazem em lados opostos do operador lógico &&. Este operador (e o operador ||) tem as seguintes características:

  1. A expressão à esquerda é calculada na íntegra antes de se pensar sequer na expressão à direita do operador.
  2. Se a expressão à esquerda for falsa (verdadeira no caso do ||), a expressão da direita não chega a ser calculada!

Exercício 3

Alínea a)

(Resolução não publicada)

Alínea b)

O resultado da execução é:

Tabela das letras minusculas:
'a' tem codigo 97
'b' tem codigo 98
'c' tem codigo 99
'd' tem codigo 100
'e' tem codigo 101
'f' tem codigo 102
'g' tem codigo 103
'h' tem codigo 104
'i' tem codigo 105
'j' tem codigo 106
'k' tem codigo 107
'l' tem codigo 108
'm' tem codigo 109
'n' tem codigo 110
'o' tem codigo 111
'p' tem codigo 112
'q' tem codigo 113
'r' tem codigo 114
's' tem codigo 115
't' tem codigo 116
'u' tem codigo 117
'v' tem codigo 118
'w' tem codigo 119
'x' tem codigo 120
'y' tem codigo 121
'z' tem codigo 122
Igual?
'a' tem codigo 97
'b' tem codigo 98
'c' tem codigo 99
'd' tem codigo 100
'e' tem codigo 101
'f' tem codigo 102
'g' tem codigo 103
'h' tem codigo 104
'i' tem codigo 105
'j' tem codigo 106
'k' tem codigo 107
'l' tem codigo 108
'm' tem codigo 109
'n' tem codigo 110
'o' tem codigo 111
'p' tem codigo 112
'q' tem codigo 113
'r' tem codigo 114
's' tem codigo 115
't' tem codigo 116
'u' tem codigo 117
'v' tem codigo 118
'w' tem codigo 119
'x' tem codigo 120
'y' tem codigo 121
'z' tem codigo 122


Tabela dos caracteres de 32 a 126:
' '= 32 '!'= 33 '"'= 34 '#'= 35 '$'= 36 '%'= 37 '&'= 38 '''= 39 '('= 40 
')'= 41 '*'= 42 '+'= 43 ','= 44 '-'= 45 '.'= 46 '/'= 47 '0'= 48 '1'= 49 
'2'= 50 '3'= 51 '4'= 52 '5'= 53 '6'= 54 '7'= 55 '8'= 56 '9'= 57 ':'= 58 
';'= 59 '<'= 60 '='= 61 '>'= 62 '?'= 63 '@'= 64 'A'= 65 'B'= 66 'C'= 67 
'D'= 68 'E'= 69 'F'= 70 'G'= 71 'H'= 72 'I'= 73 'J'= 74 'K'= 75 'L'= 76 
'M'= 77 'N'= 78 'O'= 79 'P'= 80 'Q'= 81 'R'= 82 'S'= 83 'T'= 84 'U'= 85 
'V'= 86 'W'= 87 'X'= 88 'Y'= 89 'Z'= 90 '['= 91 '\'= 92 ']'= 93 '^'= 94 
'_'= 95 '`'= 96 'a'= 97 'b'= 98 'c'= 99 'd'=100 'e'=101 'f'=102 'g'=103 
'h'=104 'i'=105 'j'=106 'k'=107 'l'=108 'm'=109 'n'=110 'o'=111 'p'=112 
'q'=113 'r'=114 's'=115 't'=116 'u'=117 'v'=118 'w'=119 'x'=120 'y'=121 
'z'=122 '{'=123 '|'=124 '}'=125 '~'=126 
Codigo do fim de linha ('\n') = 10
Codigo do apito ('\a') = 7
Ouca o apito: ouve-se um apito!


Abecedario:
abcdefghijklmnopqrstuvwxyz

Página concebida e mantida por Eng. Manuel Menezes de Sequeira (última actualização 2006/07/07)
Copyright © 1996-2001 ISCTE