Programação 1 - Engenharia - Arrays Multidimensionais

De MediaWiki do Campus São José
Ir para: navegação, pesquisa

Objetivos

Após esta aula o aluno deverá ser capaz de:

  • Visualizar o uso de arranjos multidimensionais como uma forma de organizar dados para fins de processamento;
  • Definir/Declarar arranjos multidimensionais (matrizes) em programas no C;
  • Iniciar valores na definição de arranjos multidimensionais;
  • Usar/operar sobre arranjos em instruções de programas C utilizando de indexação (sem usar ponteiros);
  • Passar arranjos multidimensionais como parâmetros de funções;
  • Usar arranjos bidimensionais de 'char' para armazenamento de 'strings';
  • Ter noção de como arranjos multidimensionais são mapeados na memória de um computador.
  • Utilizar arranjos multidimensionais em aplicações de matemática;
  • Utilizar arranjos multidimensionais em aplicações gerais, tais como, um jogo de tabuleiro.

Como definir e operar com matrizes no C

Na aula anterior estudamos os vetores, que são estruturas de dados que permitem organizar os dados tal como se fossem uma tabela unidimensional. O acesso a cada elemento do vetor é realizado pela indexação do mesmo, ou seja , um número inteiro que permite identificar a posição de um determinado vetor.

De forma similar ao vetor, pode-se criar arranjos multidimensionais. Por exemplo, uma matriz bidimensional pode ser definida usando um nome seguido de suas dimensões (de uma dupla de colchetes para indicar linha e a coluna). Os elementos da matriz serão todos de um mesmo tipo.

Um Exemplo de Soma de Matrizes da Matemática

A soma de duas matrizes na matemática é realizada pela soma dos elementos de mesma linha e coluna. A dimensão das matrizes deve ser a mesma. Podemos usar os arranjos bidimensionais no C para acomodar estas matrizes. OBSERVAR que a operação de soma deve ser realizada elemento por elemento. Dois loops aninhados serão usados para iterar sobre as linhas e colunas.

Vejamos o exemplo abaixo.

PROBLEMA: Definir duas matrizes de inteiros de dimensão 2x3 e computar a soma das mesmas. As matrizes serão iniciadas na definição.

Dados de Entrada: Matrizes mA[2][3] e mB[2][3] de inteiros. Por questões de facilidade, já serão iniciadas na definição.
Dados de Saída: Matriz mC[2][3] resultante da soma de mA com mB

PRG29002-MatrizC.png

#include <stdio.h>

#define MAX_LIN 2
#define MAX_COL 3

int main()
{
  int mA[MAX_LIN][MAX_COL]={ 11,12,13,
                             21,22,23},
      mB[MAX_LIN][MAX_COL]={1,2,3,
                            1,2,3},
      mC[MAX_LIN][MAX_COL];
  int i,j;

  for(i=0;i<MAX_LIN;i++){
     for(j=0;j<MAX_COL;j++) {
        mC[i][j] = mA[i][j] + mB[i][j];
     }
  }

  return 0;
}

Exercícios

  1. Implementar um programa para calcular a média de todos elementos da matriz C do exemplo acima.
    solução média
    #include <stdio.h>
    
    void main()
    {
      int mA[2][3]={ 11,12,13,
                     21,22,23},
          mB[2][3]={1,2,3,
                    1,2,3},
          mC[2][3];
      int i,j, soma_ac=0;
      float media;
    
      for(i=0;i<2;i++){
         for(j=0;j<3;j++) {
            mC[i][j] = mA[i][j] + mB[i][j];
            soma_ac = soma_ac + mC[i][j];
         }
      }
      media = (soma_ac/6.0);
      printf("O valor da media eh: %.2f\n", media);
    }
    
  2. Implementar um programa para ler uma matriz quadrada NxN pelo teclado e armazená-la em uma matriz matA. Defina matA com um tamanho máximo matA[N_MAX][N_MAX].
    solução preenchimento Matriz
    #include <stdio.h>
    
    #define N_MAX 50
     
    void main()
    {
      int mA[N_MAX][N_MAX];
      int i,j,dimN;
      
      /*  Entrada da dimensão   */
      printf("Entre com a dimensao\n");
      scanf ("%d",&dimN);
      
      /*      Entrada de dados  */  
      for (i=0;i<dimN;i++) {
        for (j=0;j<dimN;j++) {
           printf("Entre com  mA[%d][%d]\n",i,j);
           scanf("%d",&mA[i][j]);  
        }
      }
      
      /* impressao dos dados lidos */
      for (i=0;i<dimN;i++) {
        for (j=0;j<dimN;j++) {
           printf("=>  mA[%d][%d] => %d\n",i,j,mA[i][j]);  
        }
      }  
    }
    

Passando matriz como parâmetro de uma função

O código abaixo resolve o problema de soma de matrizes explorado acima mas usando usando uma função para realizar a soma, mostrando portanto, como passar matrizes como parâmetros de uma função.

OBSERVE que matrizes, tal como vetores, são sempre passadas como referência. 


#include <stdio.h>

#define TAM_LIN 2
#define TAM_COL 3

void somar_mat(int aA[TAM_LIN][TAM_COL],int aB[TAM_LIN][TAM_COL], int aC[TAM_LIN][TAM_COL])
{
  int i,j;

  for(i=0;i<TAM_LIN;i++){
     for(j=0;j<TAM_COL;j++) {
        aC[i][j] = aA[i][j] + aB[i][j];
     }
  }
}

int main()
{
  int mA[TAM_LIN][TAM_COL]={ 11,12,13,
                             21,22,23},
      mB[TAM_LIN][TAM_COL]={1,2,3,
                            1,2,3},
      mC[TAM_LIN][TAM_COL];

 somar_mat(mA,mB,mC);

 return 0;
  
}
 NOTAR que, por questões de facilidade, as matrizes de ENTRADA (mA e MB) já são iniciadas com valores. Normalmente o usuário fornecerá estes valores por teclado ou através de um arquivo.

Exercícios

  1. Fazer uma função que recebe duas matrizes 2x3 como parâmetros e retorna a média entre todos elementos da matriz soma destas matrizes.
  2. Solução - Exercício 01
    #include <stdio.h>
    #define DIM_1 2
    #define DIM_2 3
    
    float cal_media (int matA[DIM_1][DIM_2], int matB[DIM_1][DIM_2]){
        int i,j, soma=0, matS[DIM_1][DIM_2];
        float media;
    
        for(i=0;i<DIM_1;i++){
            for(j=0;j<DIM_2;j++) {
                matS[i][j] = matA[i][j] + matB[i][j];
                soma = soma + matS[i][j];
            }
        }
        media = (float)soma/(DIM_1 * DIM_2);
        return media;
    }
    
    int main(){
        int mA[DIM_1][DIM_2]={ 10,20,30,
                               30,20,10},
                mB[DIM_1][DIM_2]={1,2,3,
                                  3,2,1};
    
        printf("O valor da media eh %2.f", cal_media(mA, mB));
        return 0;
    }
    
  3. Implementar uma programa para calcular o determinante de uma matriz 3x3 (de reais) a ser fornecida pelo teclado.
  4. Solução - Exercício 02
    //Autor: Victor Cesconetto De Pieri
    #include <stdio.h>
     
    #define DIM_1 3
    #define DIM_2 3
     
    void main()
    {
    
      float mA[DIM_1][DIM_2];
      int i,j;
      float detA,diagPrin,diagSec;
    
      for(i=0;i<DIM_1;i++){
    	 for(j=0;j<DIM_2;j++){
      		printf("Digite o valor mA[%d][%d] da matriz: \n",i,j);
    		scanf("%f",&mA[i][j]);
    	 }
      }
      //formula para calcular o determinante 3x3
      diagPrin = (mA[0][0]*mA[1][1]*mA[2][2]) + (mA[0][1]*mA[1][2]*mA[2][0]) + (mA[0][2]*mA[1][0]*mA[2][1]);
     
      diagSec = (mA[2][0]*mA[1][1]*mA[0][2]) + (mA[2][1]*mA[1][2]*mA[0][0]) + (mA[2][2]*mA[1][0]*mA[0][1]);
    
      detA = diagPrin - diagSec;
      printf("Determinante : %f\n",detA);
    }
    
  5. Implementar um programa para ler duas matrizes (matA e matB) e multiplicá-las, colocando o resultado em uma matriz matC. Assumir dimensões de matA e matB de 2x3 e 3x4 respectivamente.
    Solução - Exercício 03
    #include <stdio.h>
    
    #define DIM_1 2
    #define DIM_2 3
    #define DIM_3 4
    
    int main()
    {
      int matA[DIM_1][DIM_2]={{2,5,7},
                              {4,7,5}
                             },
          matB[DIM_2][DIM_3]={{7,5,6,4},
                              {4,6,4,3},
                              {9,2,2,1}
                              },
          matR[DIM_1][DIM_3] ={
                               {0,0,0,0},
                               {0,0,0,0}
                              },
          i,j,k;
    
    
      for (i=0;i<DIM_1;i++) 
         for (j=0;j<DIM_3;j++) {
            for (k=0;k<DIM_2;k++)
                 matR[i][j]=matR[i][j]+matA[i][k]*matB[k][j];
            printf("MatR[%d][%d] => %d \n", i, j,  matR[i][j]);
         } 
      return 0;     
    }
    

Batalha Naval - Uma aplicação de arranjo bidimensional

A batalha naval é um jogo clássico que nas décadas passadas era jogado no papel. Uma pessoa desenhava e posicionava navios em um tabuleiro. Uma outra pessoa tentava adivinhar a posição onde estava cada navio. Ao acertar, recebia uma pontuação, que dependia do tipo navio.

A figura abaixo ilustra um tabuleiro contendo os navios. O tabuleiro é relacionado com uma matriz de inteiros no C:

  int ZonaDeGuerra[10][10]

PRG29002-BatalhaNaval.jpg


Vamos implementar um jogo similar a batalha naval da seguinte forma.

  1. Crie uma matriz de inteiros global chamada ZonaDeGuerra com 10x10 posições (iniciada com 0).
  2. Construa uma função para gerar randomicamente a posição de 1 porta-aviões (colocando 1 na sua posição), 5 fragatas (número 2) e 5 submarinos (número 3). Assuma que a cada casa onde o inimigo alvejar será somado 10 ao número da casa.
  3. Crie um contador global de tiros iniciado com 0.
  4. Crie uma função de tiro. Esta função deve ler a posição de tiro, verificar se a casa ainda não foi alvejada. Se alvejada pergunta novamente a posição. Se a posição for válida e tiver um navio então o usuário ganha pontos da seguinte forma: 10 para o porta aviões, 5 para o submarino e 3 para fragata. A função deve retornar 0 se o jogo continua, 1 se o usuário atingiu todos os navios ou 2 se o usuário teve um número máximo de tiros ultrapassado (assumir 30 tiros).
  5. Ao final do jogo é mostrado o nome do jogador, o número de tiros dados e a pontuação obtida.

Veja um possível ESQUELETO DO PROGRAMA:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

/**********************************/
/***** DEFINIÇÕES DESTE MÓDULO  ****/
/**********************************/

#define TAM_MAT 10
#define MAX_TIROS 30
#define MAX_NOME 30

#define LIVRE 0
#define PORTA_AVIOES 1
#define FRAGATA 2
#define SUBMARINO 3

/**********************************/
/***** VARIÁVEIS GLOBAIS **********/
/**********************************/

int ZonaDeGuerra[TAM_MAT][TAM_MAT];/* Matriz do espaço de batalha */
int ContadorTiros=0;
int PontuacaoFinal;    			   /* acumula a pontuação do jogador */
char nome[MAX_NOME];
int x_sorteado;
int y_sorteado;


/***********************************/
/****  FUNÇÕES DESTE MÓDULO ********/
/***********************************/

/***** FUNÇÕES DE INICIALIZAÇÃO ****/

void ZerarMatriz()
{
    int i,j;

    for (i=0;i<TAM_MAT;i++)
        for(j=0;j<TAM_MAT;j++)
            ZonaDeGuerra[i][j] = LIVRE;
}

void SortearCasa()
{
    do {
        /* generate secret number: */
        x_sorteado = rand() % TAM_MAT;
        y_sorteado = rand() % TAM_MAT;
    } while (ZonaDeGuerra[x_sorteado][y_sorteado] != LIVRE);

}

void PosicionarFragatas()
{
    int i;
    for(i=0;i<4;i++){
        SortearCasa();
        ZonaDeGuerra[x_sorteado][y_sorteado] = FRAGATA;
    }
}

void PosicionarSubmarinos()
{
    int i;
    for(i=0;i<5;i++){
        SortearCasa();
        ZonaDeGuerra[x_sorteado][y_sorteado] = SUBMARINO;
    }
}

void PosicionarPortaAvioes()
{
    SortearCasa();
    ZonaDeGuerra[x_sorteado][y_sorteado] = PORTA_AVIOES;
}

void PosicionarNavios()
{
    /* initialize random seed: */
    srand ( time(NULL) );

    PosicionarPortaAvioes();
    PosicionarFragatas();
    PosicionarSubmarinos();
}

/*** FUNÇÕES DE IMPRESSÃO NA TELA **/

void ImprimeLinha(int linha)
{
    int j;

    printf("     ");
    for(j=0;j<TAM_MAT;j++) {
        printf("| %2d ",ZonaDeGuerra[linha][j]);
    }
    printf("|\n");
    printf("     +----+----+----+----+----+----+----+----+----+----+\n");
}

void ImprimeLinhaEscondida(int linha)
{
    int j;

    printf("     ");
    for(j=0;j<TAM_MAT;j++) {
        if (ZonaDeGuerra[linha][j]>=0 &&  ZonaDeGuerra[linha][j]<=3)
            printf("| -- ");
        else
            printf("| %2d ",ZonaDeGuerra[linha][j]);
    }
    printf("|\n");
    printf("     +----+----+----+----+----+----+----+----+----+----+\n");
}

void ImprimeMatrizTudo()
{
    int i;

    printf("     +----+----+----+----+----+----+----+----+----+----+\n");
    for(i=0;i<TAM_MAT;i++)
        ImprimeLinha(i);
}

void ImprimeMatrizEscondida()
{
    int i;

    printf("     +----+----+----+----+----+----+----+----+----+----+\n");
    for(i=0;i<TAM_MAT;i++)
        ImprimeLinhaEscondida(i);
}


int Tiro()
{
 /* implementar a função Tiro conforme enunciado acima */
}

int main()
{
    int situacao;
    ZerarMatriz();
    PosicionarNavios();
    ImprimeMatrizEscondida();
    do {
        situacao = Tiro();
    } while (situacao==0);
    /*
      Implementar aqui o tratamento final da variável situação
    */
    return 0;
}


  OBS: Nesta implementação foram usadas variáveis globais para "transportar" a informação da função SortearCasa() uma abordagem mais interessante seria retornar como valor da função. Isto poderia ser feito com structs. Também poderia ser usado um vetor de duas posições passado como parâmetro para a função.


Exercício

Implementar a função tiro do exemplo acima e a parte final do jogo.

Matrizes de caracteres e vetores de strings

Um vetor de strings pode ser construído usando matrizes de char. Cada string será armazenada em uma linha do vetor.

Exemplo

#include <stdio.h>

int main()
{
  char TabelaUsuarios[4][10] = {
         "joao",
         "maria",
         "jose",
         "lara",
  };
  int i;

  for (i=0;i<4;i++)
       printf("%s\n",&TabelaUsuarios[i][0]);
  
  return 0;
}
Note a forma como é realizada a inicialização da matriz.


Uma aplicação simples: Tabelas com Nomes e Notas de uma Turma

No exemplo abaixo são armazenadas notas do semestre (3) em um vetor de inteiros bidimensional. Cada linha do vetor corresponde a uma aluno. O nome do aluno é armazenado em outra tabela. Futuramente vamos ver que é possível ter uma tabela somente.

#include <stdio.h>

int main() {
    char TabelaUsuarios[4][10] = {
            "Eraldo",
            "Silvana",
            "Vica",
            "Lara",
    };
    int Notas[4][3] = {
            {4,  5, 9},
            {10, 9, 10},
            {6,  7, 10},
            {10, 7, 9},
    };
    int i,j;

    for (i = 0; i < 4; i++) {
        printf("%s\n", &TabelaUsuarios[i][0]);
        printf("Notas do Semestre\n");
        for (j = 0; j < 3; j++) {
            printf("%d\t", Notas[i][j]);
        }
        printf("\n");
    }
    return 0;
}

Exercício: Melhorar o exemplo acima colocando defines e calculando a média de cada aluno no Semestre e armazenando em um vetor de médias.

Exercícios

  1. Implementar uma função que calcula a média de uma linha de uma matriz quadrada 5x5, mas somente considerando elementos que estão acima da média de todos os elementos da matriz. Implementar TAMBÉM uma função parecida com a função proposta mas que tenha a sua contribuição. Mostre o funcionamento das duas funções. Siga o esqueleto abaixo:
    float media_linha(float mat[5][5], int i)
    {
      /* sugestão 1: calcular a média de todos elementos da matriz */
    
      /* sugestão 2: Calcular e retornar a média dos elementos da linha i */
      /*             e que são acima da média da matriz */
      /* retornar o valor */
    }
    
    /* implemente aqui a função de sua autoria, parecida com a função acima */
    
    int main()
    {
      /* declare uma matriz 5x5 iniciada e teste as funções */ 
    }
    
  2. Implementar uma função que calcula a média de uma coluna de uma matriz quadrada 5x5, mas somente considerando elementos que estão acima da média de todos os elementos da matriz. Implementar TAMBÉM uma função parecida com a função proposta mas que tenha a sua contribuição. Mostre o funcionamento das duas funções. Siga o esqueleto abaixo:
    float media_coluna(float mat[5][5], int j)
    {
      /* sugestão 1: calcular a média de todos elementos da matriz */
    
      /* sugestão 2: Calcular e retornar a média dos elementos da coluna j */
      /*             e que são acima da média da matriz */
      /* retornar o valor */
    }
    
    /* implemente aqui a função de sua autoria, parecida com a função acima */
    
    int main()
    {
      /* declare uma matriz 5x5 iniciada e teste as funções */ 
    }
    
  3. Implementar um programa para "abrir uma porta" para um usuário que se encontra em uma tabela similar a mostrada no tópico acima. Faça uma versão com (i) uma função implementada por você para comparar strings (ii) a função strcmp da biblioteca
  4. Solução - Exercício 01
    #include <stdio.h>
    
    char tabelaUsuarios[4][10] = {
             "joao",
             "maria",
             "josefina",
             "lara",
    };
    
    int str_cmp(char str1[],char str2[])
    {
      int i=0;
     
      while(str1[i]!=0) {
         if (str1[i]!=str2[i])
            break; 
         i++;
      }
      if(str1[i]==0 && str2[i]==0) 
         return 0;
      else
         return 1;
      
    }
            
    main()
    {
    
      int i;
      char nome[10];
     
      printf("Entre com seu USERID\n");
      scanf("%s", nome);
      for (i=0;i<4;i++) {
           if (str_cmp(nome,&tabelaUsuarios[i][0])==0) {
           		break;
           }
      }
      if (i==4)
      	  printf("Usuário não existente!\n"); 
      else
          printf("abrir a porta\n");   
    }
    
  5. Faça uma versão do exercício anterior sem usar breaks.
  6. Implementar uma tabela adicional com senhas dos usuários. O acesso deve ser concedido somente se o usuário for validado e a senha. Defina as tabelas como variáveis globais. Fazer uma versão com e sem break.
    Solução
    #include <stdio.h>
     
    char tabelaUsuarios[4][10] = {
             "joao",
             "maria",
             "josefina",
             "lara",
    };
    
    char tabelaSenhas[4][10] = {
             "joao123",
             "maria123",
             "josef123",
             "lara123",
    };
     
    int str_cmp(char str1[],char str2[])
    {
      int i=0;
     
      while(str1[i]!=0 && str2[i]!=0) {
         if (str1[i]!=str2[i])
            break; 
         i++;
      }
      if(str1[i]==0 && str2[i]==0) 
         return 0;
      else
         return 1;
    }
     
    main()
    {
     
      int i;
      char nome[10];
      char senha[10];
     
      printf("Entre com seu USERID\n");
      scanf("%s", nome);
      for (i=0;i<4;i++) {
           if (str_cmp(nome,&tabelaUsuarios[i][0])==0) {
           		break;
           }
      }
      if (i==4)
      	  printf("Usuário não existente!\n"); 
      else {
          /* inserir código aqui !!! */
          printf("Entre com a senha de %s\n", nome);
          scanf("%s", senha);     
          if (str_cmp(senha,&tabelaSenhas[i][0])==0) {
               printf("abrir a porta\n");    
          } else 
               printf("Senha de %s incorreta\n", nome);
      }   
    }
    
  7. Implementar uma modificação do exercício anterior que permite ao programa ficar em loop até que se entre com userID igual a "fim".
  8. Solução
    //Autor : Victor Cesconetto De Pieri
    
    #include <stdio.h>
    
      char tabelaUsuarios[4][10] = {
        "joao",
        "maria",
        "josefina",
        "lara",
      };
    
    char tabelaSenhas[4][10] = {
      "joao123",
      "maria123",
      "josef123",
      "lara123",
    };
    
    int str_cmp(char str1[], char str2[]) {
      int i = 0;
    
      while (str1[i] != 0 && str2[i] != 0) {
        if (str1[i] != str2[i])
          break;
        i++;
      }
      if (str1[i] == 0 && str2[i] == 0)
        return 0;
      else
        return 1;
    
    }
    
    main() {
    
      int i;
      char nome[10];
      char senha[10];
    
      for (;;) { //'for' ou loop infinito
        printf("Entre com seu USERID\n");
        scanf("%s", nome);
        if (str_cmp(nome, "fim") == 0) { //verifica se digitou "fim" no userID
          printf("\nVoce digitou 'fim', adeus!!\n");
          break; //sai do loop infinito e encerra o programa	
        }
        for (i = 0; i < 4; i++) {
          if (str_cmp(nome, & tabelaUsuarios[i][0]) == 0) {
            break;
          }
        }
        if (i == 4)
          printf("Usuário não existente!\n");
        else {
          printf("Entre com a senha de %s\n", nome);
          scanf("%s", senha);
          if (str_cmp(senha, & tabelaSenhas[i][0]) == 0) {
            printf("abrir a porta\n");
          } else
            printf("Senha de %s incorreta\n", nome);
        }
      }
    
    }
    
  9. No exercício anterior, acrescente uma tabela de contadores que permite armazenar o número de tentativas seguidas de um usuário, no caso de erro de senha. Se o número de tentativas for maior que 3 a porta não deverá mais ser aberta para o usuário (usuário bloqueado).
  10. Solução
    //Autor: Victor Cesconetto De Pieri
    
    #include <stdio.h>
    
      char tabelaUsuarios[4][10] = {
        "joao",
        "maria",
        "josefina",
        "lara",
      };
    
    char tabelaSenhas[4][10] = {
      "joao123",
      "maria123",
      "josef123",
      "lara123",
    };
    
    char tabelaContadores[4][1] = {
      0,
      0,
      0,
      0
    };
    
    int str_cmp(char str1[], char str2[]) {
      int i = 0;
    
      while (str1[i] != 0 && str2[i] != 0) {
        if (str1[i] != str2[i])
          break;
        i++;
      }
      if (str1[i] == 0 && str2[i] == 0)
        return 0;
      else
        return 1;
    
    }
    
    main() {
    
      int i;
      char nome[10];
      char senha[10];
    
      for (;;) { //'for' ou loop infinito
        printf("Entre com seu USERID\n");
        scanf("%s", nome);
        if (str_cmp(nome, "fim") == 0) { //verifica se digitou "fim" no userID
          printf("\nVoce digitou 'fim', adeus!!\n");
          break; //sai do loop infinito e encerra o programa	
        }
    
        for (i = 0; i < 4; i++) {
          if (str_cmp(nome, & tabelaUsuarios[i][0]) == 0) {
            break;
          }
        }
    
        if (i == 4) //verifica se o usuario ja excedeu as 3 tentativas
          printf("Usuário não existente\n");
        else {
          printf("Entre com a senha de %s\n", nome);
          scanf("%s", senha);
          if (str_cmp(senha, & tabelaSenhas[i][0]) == 0 && tabelaContadores[i][0] < 3) { //verifica se o usuario não esta bloqueado e a senha esta correta
            printf("abrir a porta\n");
          } else if (tabelaContadores[i][0] < 3) { //se o usuario nao está bloqueado mas a senha esta incorreta acrescenta 1 nos contadores
            tabelaContadores[i][0]++;
            printf("Contagem: %d\n", tabelaContadores[i][0]);
            printf("Senha de %s incorreta\n", nome);
          } else { //se esgotaram as tentativas do usuario
            printf("Usuario Bloqueado!!\n");
          }
        }
      }
    
    }
    
  11. No exercício anterior, acrescente a figura do administrador (armazenado separadamente como user "admin" e senha "12345". Ao logar o administrador será questionado por um usuário a ser desbloqueado. O administrador entra com o usuário a ser desbloquedo e o sistema volta a perguntar por um userID.
  12. Solução
    //Autor: Victor Cesconetto De Pieri
    
    #include <stdio.h>
    #include <string.h>
    
    char tabelaUsuarios[4][10] = {
            "joao",
            "maria",
            "josefina",
            "lara",
    };
    
    char tabelaSenhas[4][10] = {
            "joao123",
            "maria123",
            "josef123",
            "lara123",
    };
    
    char tabelaContadores[4] = {
            0,
            0,
            0,
            0
    };
    
    int main() {
    
        int i;
        char nome[10];
        char senha[10];
    
        for (;;) { //'for' ou loop infinito
            printf("Entre com seu USERID\n");
            scanf("%s", nome);
            if (strcmp(nome, "fim") == 0) { //verifica se digitou "fim" no userID
                printf("\nVoce digitou 'fim', adeus!!\n");
                break; //sai do loop infinito e encerra o programa
            }
    
            for (i = 0; i < 4; i++) {
                if (strcmp(nome, & tabelaUsuarios[i][0]) == 0) {
                    if( tabelaContadores[i] >= 3) {
                        i = 5; // usuario bloqueado
                    }
                    break;
                }
            }
    
            if (i == 4) //verifica se o usuario ja excedeu as 3 tentativas
                printf("Usuário não existente\n");
            else
                if (i==5){
                    printf("Usuário Bloqueado!!!\n");
                }
                else {
                    printf("Entre com a senha de %s\n", nome);
                    scanf("%s", senha);
                    if (strcmp(senha, &tabelaSenhas[i][0]) ==0) { //verifica se o usuario não esta bloqueado e a senha esta correta
                        printf("abrir a porta\n");
                        if(tabelaContadores[i]>0)
                            tabelaContadores[i] = 0;//zerar contador caso não esteja zero;
                    } else { //se o usuario nao está bloqueado mas a senha esta incorreta acrescenta 1 nos contadores
                        tabelaContadores[i]++;
                        printf("Contagem: %d\n", tabelaContadores[i]);
                        printf("Senha de %s incorreta\n", nome);
                    }
                }
        }
        return 0;
    }//Autor: Victor Cesconetto De Pieri
    
    #include <stdio.h>
    #include <string.h>
    
    char tabelaUsuarios[4][10] = {
            "joao",
            "maria",
            "josefina",
            "lara",
    };
    
    char tabelaSenhas[4][10] = {
            "joao123",
            "maria123",
            "josef123",
            "lara123",
    };
    
    char tabelaContadores[4] = {
            0,
            0,
            0,
            0
    };
    
    int main() {
    
        int i;
        char nome[10];
        char senha[10];
    
        for (;;) { //'for' ou loop infinito
            printf("Entre com seu USERID\n");
            scanf("%s", nome);
            if (strcmp(nome, "fim") == 0) { //verifica se digitou "fim" no userID
                printf("\nVoce digitou 'fim', adeus!!\n");
                break; //sai do loop infinito e encerra o programa
            }
    
            for (i = 0; i < 4; i++) {
                if (strcmp(nome, & tabelaUsuarios[i][0]) == 0) {
                    if( tabelaContadores[i] >= 3) {
                        i = 5; // usuario bloqueado
                    }
                    break;
                }
            }
    
            if (i == 4) //verifica se o usuario ja excedeu as 3 tentativas
                printf("Usuário não existente\n");
            else
                if (i==5){
                    printf("Usuário Bloqueado!!!\n");
                }
                else {
                    printf("Entre com a senha de %s\n", nome);
                    scanf("%s", senha);
                    if (strcmp(senha, &tabelaSenhas[i][0]) ==0) { //verifica se o usuario não esta bloqueado e a senha esta correta
                        printf("abrir a porta\n");
                        if(tabelaContadores[i]>0)
                            tabelaContadores[i] = 0;//zerar contador caso não esteja zero;
                    } else { //se o usuario nao está bloqueado mas a senha esta incorreta acrescenta 1 nos contadores
                        tabelaContadores[i]++;
                        printf("Contagem: %d\n", tabelaContadores[i]);
                        printf("Senha de %s incorreta\n", nome);
                    }
                }
        }
        return 0;
    }//Autor: Victor Cesconetto De Pieri
    
    #include <stdio.h>
    #include <string.h>
    
    char tabelaUsuarios[4][10] = {
            "joao",
            "maria",
            "josefina",
            "lara",
    };
    
    char tabelaSenhas[4][10] = {
            "joao123",
            "maria123",
            "josef123",
            "lara123",
    };
    
    char tabelaContadores[4] = {
            0,
            0,
            0,
            0
    };
    
    int main() {
    
        int i;
        char nome[10];
        char senha[10];
    
        for (;;) { //'for' ou loop infinito
            printf("Entre com seu USERID\n");
            scanf("%s", nome);
            if (strcmp(nome, "fim") == 0) { //verifica se digitou "fim" no userID
                printf("\nVoce digitou 'fim', adeus!!\n");
                break; //sai do loop infinito e encerra o programa
            }
    
            for (i = 0; i < 4; i++) {
                if (strcmp(nome, & tabelaUsuarios[i][0]) == 0) {
                    if( tabelaContadores[i] >= 3) {
                        i = 5; // usuario bloqueado
                    }
                    break;
                }
            }
    
            if (i == 4) //verifica se o usuario ja excedeu as 3 tentativas
                printf("Usuário não existente\n");
            else
                if (i==5){
                    printf("Usuário Bloqueado!!!\n");
                }
                else {
                    printf("Entre com a senha de %s\n", nome);
                    scanf("%s", senha);
                    if (strcmp(senha, &tabelaSenhas[i][0]) ==0) { //verifica se o usuario não esta bloqueado e a senha esta correta
                        printf("abrir a porta\n");
                        if(tabelaContadores[i]>0)
                            tabelaContadores[i] = 0;//zerar contador caso não esteja zero;
                    } else { //se o usuario nao está bloqueado mas a senha esta incorreta acrescenta 1 nos contadores
                        tabelaContadores[i]++;
                        printf("Contagem: %d\n", tabelaContadores[i]);
                        printf("Senha de %s incorreta\n", nome);
                    }
                }
        }
        return 0;
    }//Autor: Victor Cesconetto De Pieri
    
    #include <stdio.h>
    #include <string.h>
    
    char tabelaUsuarios[4][10] = {
            "joao",
            "maria",
            "josefina",
            "lara",
    };
    
    char tabelaSenhas[4][10] = {
            "joao123",
            "maria123",
            "josef123",
            "lara123",
    };
    
    char tabelaContadores[4] = {
            0,
            0,
            0,
            0
    };
    
    int main() {
    
        int i;
        char nome[10];
        char senha[10];
    
        for (;;) { //'for' ou loop infinito
            printf("Entre com seu USERID\n");
            scanf("%s", nome);
            if (strcmp(nome, "fim") == 0) { //verifica se digitou "fim" no userID
                printf("\nVoce digitou 'fim', adeus!!\n");
                break; //sai do loop infinito e encerra o programa
            }
    
            for (i = 0; i < 4; i++) {
                if (strcmp(nome, & tabelaUsuarios[i][0]) == 0) {
                    if( tabelaContadores[i] >= 3) {
                        i = 5; // usuario bloqueado
                    }
                    break;
                }
            }
    
            if (i == 4) //verifica se o usuario ja excedeu as 3 tentativas
                printf("Usuário não existente\n");
            else
                if (i==5){
                    printf("Usuário Bloqueado!!!\n");
                }
                else {
                    printf("Entre com a senha de %s\n", nome);
                    scanf("%s", senha);
                    if (strcmp(senha, &tabelaSenhas[i][0]) ==0) { //verifica se o usuario não esta bloqueado e a senha esta correta
                        printf("abrir a porta\n");
                        if(tabelaContadores[i]>0)
                            tabelaContadores[i] = 0;//zerar contador caso não esteja zero;
                    } else { //se o usuario nao está bloqueado mas a senha esta incorreta acrescenta 1 nos contadores
                        tabelaContadores[i]++;
                        printf("Contagem: %d\n", tabelaContadores[i]);
                        printf("Senha de %s incorreta\n", nome);
                    }
                }
        }
        return 0;
    }//Autor: Victor Cesconetto De Pieri
    
    #include <stdio.h>
    #include <string.h>
    
    char tabelaUsuarios[4][10] = {
            "joao",
            "maria",
            "josefina",
            "lara",
    };
    
    char tabelaSenhas[4][10] = {
            "joao123",
            "maria123",
            "josef123",
            "lara123",
    };
    
    char tabelaContadores[4] = {
            0,
            0,
            0,
            0
    };
    
    int main() {
    
        int i;
        char nome[10];
        char senha[10];
    
        for (;;) { //'for' ou loop infinito
            printf("Entre com seu USERID\n");
            scanf("%s", nome);
            if (strcmp(nome, "fim") == 0) { //verifica se digitou "fim" no userID
                printf("\nVoce digitou 'fim', adeus!!\n");
                break; //sai do loop infinito e encerra o programa
            }
    
            for (i = 0; i < 4; i++) {
                if (strcmp(nome, & tabelaUsuarios[i][0]) == 0) {
                    if( tabelaContadores[i] >= 3) {
                        i = 5; // usuario bloqueado
                    }
                    break;
                }
            }
    
            if (i == 4) //verifica se o usuario ja excedeu as 3 tentativas
                printf("Usuário não existente\n");
            else
                if (i==5){
                    printf("Usuário Bloqueado!!!\n");
                }
                else {
                    printf("Entre com a senha de %s\n", nome);
                    scanf("%s", senha);
                    if (strcmp(senha, &tabelaSenhas[i][0]) ==0) { //verifica se o usuario não esta bloqueado e a senha esta correta
                        printf("abrir a porta\n");
                        if(tabelaContadores[i]>0)
                            tabelaContadores[i] = 0;//zerar contador caso não esteja zero;
                    } else { //se o usuario nao está bloqueado mas a senha esta incorreta acrescenta 1 nos contadores
                        tabelaContadores[i]++;
                        printf("Contagem: %d\n", tabelaContadores[i]);
                        printf("Senha de %s incorreta\n", nome);
                    }
                }
        }
        return 0;
    }
    
  13. Repensar e reimplementar o exercício de controle de acesso usando funções. Ver wiki da parte de fluxogramas.
  14. Implementar um gerador de apostas para megasena. O programa deve armazenar 10 sugestões de jogos a serem armazenados em uma matriz. Os números devem ser armazenados em ordem crescente. Sugestão: criar uma matriz global:
  15.   int matriz_megasena[10][6];
    
    Solução - Exercício 06
    //Autor:Victor Cesconetto De Pieri
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    #define NUM_JOGOS 10
    # define NUMS_MEGA 6
    
    int matriz_jogos[NUM_JOGOS][NUMS_MEGA];
    
    int gerar_num_al() {
      return (rand() % 60 + 1);
    }
    
    int testar_num(int numero, int vetor[NUMS_MEGA], int limite) //testa o numero a ser colocado no vetor do jogo
    {
      int i = 0;
      for (i = 0; i < limite; i++) {
        if (vetor[i] == numero) //testa se o numero anterior é igual ao proximo sorteado, se sim, retorna 1 se nao retorna 0
          return 1;
      }
      return 0;
    }
    
    void ordenar_vetor(int vetor[NUMS_MEGA]) // ordena o vetor do jogo em ordem crescente
    {
      int i, j;
      int aux = 0;
      for (i = 0; i < NUMS_MEGA; i++) {
        for (j = 0; j < NUMS_MEGA; j++) {
          if (vetor[i] < vetor[j]) {
            aux = vetor[i];
            vetor[i] = vetor[j];
            vetor[j] = aux;
          }
        }
      }
    
    }
    
    void imprimir_matriz() //imprime a matriz dos jogos
    {
      int i, j;
    
      for (i = 0; i < NUM_JOGOS; i++) {
        for (j = 0; j < NUMS_MEGA; j++)
          printf("%d ", matriz_jogos[i][j]);
        printf("\n");
      }
    
    }
    
    int gerar_jogo(int num_jogo) //gera o jogo numero por numero
    {
      int i, num_al;
    
      matriz_jogos[num_jogo][0] = gerar_num_al();
      for (i = 1; i < 6; i++) {
        do {
          num_al = gerar_num_al();
        } while (testar_num(num_al, matriz_jogos[num_jogo], i)); //faz o teste se retorna 1 continua o sorteio ate aparecer um numero diferente do anterior
        matriz_jogos[num_jogo][i] = num_al;
    
      }
    
    }
    
    main() {
      int i;
    
      srand(time(NULL)); //pega o numero randomico usando como seed o relogio
    
      for (i = 0; i < NUM_JOGOS; i++) {
        gerar_jogo(i);
        ordenar_vetor(matriz_jogos[i]);
      }
      imprimir_matriz();
    }
    
  16. Melhorar o exercício anterior para evitar que dois jogos sejam iguais.
  17. Solução - Exercício 07
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
     
    #define NUM_JOGOS 10
    # define NUMS_MEGA 6
     
    int matriz_jogos[NUM_JOGOS][NUMS_MEGA];
     
    int gerar_num_al() {
      return (rand() % 60 + 1);
    }
     
    int testar_num(int numero, int vetor[NUMS_MEGA], int limite) //testa o numero a ser colocado no vetor do jogo
    {
      int i = 0;
      for (i = 0; i < limite; i++) {
        if (vetor[i] == numero) //testa se o numero anterior é igual ao proximo sorteado, se sim, retorna 1 se nao retorna 0
          return 1;
      }
      return 0;
    }
    
    
    int testar_jogo_igual() {
    
      int i, j;
      int contador = 0;
    
      for (i = 0; i < NUM_JOGOS; i++) {
        for (j = 0; j < NUMS_MEGA; j++) {
          if (matriz_jogos[i][j] == matriz_jogos[i + 1][j]) {
            if (contador < 6) {
              contador++;
            } else {
              printf("tem jogo igual");
              return 1;
              break;
            }
    
          }
        }
      }
    
    }
     
    void ordenar_vetor(int vetor[NUMS_MEGA]) // ordena o vetor do jogo em ordem crescente
    {
      int i, j;
      int aux = 0;
      for (i = 0; i < NUMS_MEGA; i++) {
        for (j = 0; j < NUMS_MEGA; j++) {
          if (vetor[i] < vetor[j]) {
            aux = vetor[i];
            vetor[i] = vetor[j];
            vetor[j] = aux;
          }
        }
      }
     
    }
     
    void imprimir_matriz() //imprime a matriz dos jogos
    {
      int i, j;
     
      for (i = 0; i < NUM_JOGOS; i++) {
        for (j = 0; j < NUMS_MEGA; j++)
          printf("%d ", matriz_jogos[i][j]);
        printf("\n");
      }
     
    }
     
    int gerar_jogo(int num_jogo) //gera o jogo numero por numero
    {
      int i, num_al;
     
      matriz_jogos[num_jogo][0] = gerar_num_al();
      for (i = 1; i < 6; i++) {
        do {
          num_al = gerar_num_al();
        } while (testar_num(num_al, matriz_jogos[num_jogo], i)); //faz o teste se retorna 1 continua o sorteio ate aparecer um numero diferente do anterior
        matriz_jogos[num_jogo][i] = num_al;
     
      }
     
    }
     
    main() {
      int i,mac;
     
      srand(time(NULL)); //pega o numero randomico usando como seed o relogio
     
      for (i = 0; i < NUM_JOGOS; i++) {
        gerar_jogo(i);
        ordenar_vetor(matriz_jogos[i]);
    	
      }
      mac = testar_jogo_igual();	
      printf("%d\n",mac);
      imprimir_matriz();
      
    }
    
  18. Melhorar o exercício anterior para evitar que uma aposta tenha dois números na mesma dezena.
  19. Solução - Exercício 08
    //Autor: Victor Cesconetto De Pieri
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    #define NUM_JOGOS 10
    #define NUMS_MEGA 6
    
    int matriz_jogos[NUM_JOGOS][NUMS_MEGA];
    
    int gerar_num_al() {
      return (rand() % 60 + 1);
    }
    
    int testar_num(int numero, int vetor[NUMS_MEGA], int limite) //testa o numero a ser colocado no vetor do jogo
    {
      int i = 0;
      for (i = 0; i < limite; i++) {
        if (vetor[i] == numero || (vetor[i] / 10) == (numero / 10)) //testa se o numero anterior é igual ou existe dezena igual ao proximo sorteado, se sim, retorna 1 se nao retorna 0
          return 1;
      }
      return 0;
    }
    
    void ordenar_vetor(int vetor[NUMS_MEGA]) // ordena o vetor do jogo em ordem crescente
    {
      int i, j;
      int aux = 0;
      for (i = 0; i < NUMS_MEGA; i++) {
        for (j = 0; j < NUMS_MEGA; j++) {
          if (vetor[i] < vetor[j]) {
            aux = vetor[i];
            vetor[i] = vetor[j];
            vetor[j] = aux;
          }
        }
      }
    
    }
    
    void imprimir_matriz() //imprime a matriz dos jogos
    {
      int i, j;
    
      for (i = 0; i < NUM_JOGOS; i++) {
        for (j = 0; j < NUMS_MEGA; j++)
          printf("%d ", matriz_jogos[i][j]);
        printf("\n");
      }
    
    }
    
    int gerar_jogo(int num_jogo) //gera o jogo numero por numero
    {
      int i, num_al;
    
      matriz_jogos[num_jogo][0] = gerar_num_al();
      for (i = 1; i < 6; i++) {
        do {
          num_al = gerar_num_al();
        } while (testar_num(num_al, matriz_jogos[num_jogo], i)); //faz o teste se retorna 1 continua o sorteio ate aparecer um numero diferente do anterior
        matriz_jogos[num_jogo][i] = num_al;
    
      }
    
    }
    
    main() {
      int i;
    
      srand(time(NULL)); //pega o numero randomico usando como seed o relogio
    
      for (i = 0; i < NUM_JOGOS; i++) {
        gerar_jogo(i);
        ordenar_vetor(matriz_jogos[i]);
      }
      imprimir_matriz();
    }
    
  20. Melhorar o exercício anterior para evitar que uma mesma aposta tenha números consecutivos.
  21. Solução - Exercício 09
    //Autor:Victor Cesconetto De Pieri
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    #define NUM_JOGOS 10
    #define NUMS_MEGA 6
    
    int matriz_jogos[NUM_JOGOS][NUMS_MEGA];
    
    int gerar_num_al() {
      return (rand() % 60 + 1);
    }
    
    int testar_num(int numero, int vetor[NUMS_MEGA], int limite) //testa o numero a ser colocado no vetor do jogo
    {
      int i = 0;
      for (i = 0; i < limite; i++) {
        if (vetor[i] == numero || vetor[i] == (numero+1) || vetor[i] == (numero-1) ) //testa se o numero anterior é igual ou consecutivo ao proximo sorteado, se sim, retorna 1 se nao retorna 0
          return 1;
      }
      return 0;
    }
    
    void ordenar_vetor(int vetor[NUMS_MEGA]) // ordena o vetor do jogo em ordem crescente
    {
      int i, j;
      int aux = 0;
      for (i = 0; i < NUMS_MEGA; i++) {
        for (j = 0; j < NUMS_MEGA; j++) {
          if (vetor[i] < vetor[j]) {
            aux = vetor[i];
            vetor[i] = vetor[j];
            vetor[j] = aux;
          }
        }
      }
    
    }
    
    void imprimir_matriz() //imprime a matriz dos jogos
    {
      int i, j;
    
      for (i = 0; i < NUM_JOGOS; i++) {
        for (j = 0; j < NUMS_MEGA; j++)
          printf("%d ", matriz_jogos[i][j]);
        printf("\n");
      }
    
    }
    
    int gerar_jogo(int num_jogo) //gera o jogo numero por numero
    {
      int i, num_al;
    
      matriz_jogos[num_jogo][0] = gerar_num_al();
      for (i = 1; i < 6; i++) {
        do {
          num_al = gerar_num_al();
        } while (testar_num(num_al, matriz_jogos[num_jogo], i)); //faz o teste se retorna 1 continua o sorteio ate aparecer um numero diferente do anterior
        matriz_jogos[num_jogo][i] = num_al;
    
      }
    
    }
    
    main() {
      int i;
    
      srand(time(NULL)); //pega o numero randomico usando como seed o relogio
    
      for (i = 0; i < NUM_JOGOS; i++) {
        gerar_jogo(i);
        ordenar_vetor(matriz_jogos[i]);
      }
      imprimir_matriz();
    }
    
  22. Melhorar o exercício anterior colocando um switch para o usuário colocar as opções acima.
  23. solução
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    #define NUM_JOGOS 8
    #define NUMS_MEGA 6
    
    int matriz_jogos[NUM_JOGOS][NUMS_MEGA];
    
    int gerar_num_al()
    {
      return (rand()%60 + 1);
    }
    
    int testar_num(int numero, int vetor[NUMS_MEGA], int limite)
    {
      int i=0;
      for (i=0;i<limite;i++) {
         if (vetor[i]==numero)
            return 1;
      }
      return 0;
    }
    
    void ordenar_vetor(int vetor[NUMS_MEGA])
    {
    
    }
    
    void imprimir_matriz()
    {
      int i,j;
      
      for(i=0;i<NUM_JOGOS;i++) {
          for(j=0;j<NUMS_MEGA;j++)
             printf("%d ", matriz_jogos[i][j]);
          printf("\n");
      }
      
    }
    
    int gerar_jogo(int num_jogo)
    {
      int i, num_al;
      
      matriz_jogos[num_jogo][0] = gerar_num_al();
      for(i=1;i<6;i++) {    
      	do {
         	num_al = gerar_num_al();
      	} while(testar_num(num_al, matriz_jogos[num_jogo],i));
      	matriz_jogos[num_jogo][i]=num_al;
      }
    }
    
    main()
    {
      int i;
     
      srand ( time(NULL) );
            
      for (i=0;i<NUM_JOGOS;i++)
          gerar_jogo(i);
      imprimir_matriz();
    }