PR1022804 2021 1 AULA09

De MediaWiki do Campus São José
Ir para navegação Ir para pesquisar
A versão imprimível não é mais suportada e pode ter erros de renderização. Atualize os favoritos do seu navegador e use a função de impressão padrão do navegador.

Arranjos Multidimensionais (Arrays)

Os Arrays Multidimensionais, também chamados de matrizes, são estruturas de dados que possuem duas ou mais dimensões. Em resumo, temos que um Array que contém uma única dimensão (vetor) funciona internamente como um Array multidimensional. A diferença está na quantidade de índices que cada elemento da nossa estrutura terá como identificador (veremos mais tarde).

Objetivos
  • Definindo matrizes no C.
  • Operações com matrizes e passagem de parâmetros tipo matriz.
  • Matrizes com caracteres.

Como definir e operar com matrizes no C

De forma similar ao vetor, basta definir a matriz usando colchetes para indicar a dimensão da variável.

Exemplo: Definir duas matrizes 2x3 já inicializadas e computar a soma das mesmas:

#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;

  for(i=0;i<2;i++){
     for(j=0;j<3;j++) {
        mC[i][j] = mA[i][j] + mB[i][j];
     }
  }
  
}
Exercícios
  1. Modificar este exercício para que a função receba um parâmetro adicional do tipo inteiro. A função deve retornar a média de todos os valores da matriz soma que estão acima do valor passado como parâmetro.
  2. implementar um programa para calcular a média de todos elementos da matriz C do exemplo acima.
    #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;
    }
    
  3. 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].
    #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 matrizes como parâmetro

Como matrizes também são vetores, a mesma característica da passagem de parâmetros é considerada. Observe os exemplos a seguir:

Exemplo 1
#include <stdio.h>

void somar_mat(int aA[][3],int aB[][3], int cC[][3])
{
  int i,j;

  for(i=0;i<2;i++){
     for(j=0;j<3;j++) {
        cC[i][j] = aA[i][j] + aB[i][j];
     }
  }
}

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

 somar_mat(mA,mB,mC);
  
}

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

Exemplo 2
#include <stdio.h>

void somar_mat(int m1[][3],int m2[][3], int m3[][3]);
void imprimir_mat(int mat[][3]);

void main()
{
  int mA[2][3]={ 11,12,13,
                 21,22,23},
      mB[2][3]={1,2,3,
                1,2,3},
      mC[2][3]={4,5,6,
                7,8,9 },
      mR[2][3];
  int i,j;
 somar_mat(mA,mB,mR); // somar matrix A com B
 imprimir_mat(mR);
 somar_mat(mB,mC,mR);
 imprimir_mat(mR);
 somar_mat(mA,mC,mR);
 imprimir_mat(mR);
}

void somar_mat(int m1[][3],int m2[][3], int m3[][3])
{
  int i,j;

  for(i=0;i<2;i++){
     for(j=0;j<3;j++) {
        m3[i][j] = m1[i][j] + m2[i][j];
     }
  }
}

void imprimir_mat(int mat[][3]){
  int i,j;
  for(i=0;i<2;i++){
     for(j=0;j<3;j++) {
        printf("%d\t",mat[i][j]);
     }
     printf("\n");
  }
  printf("\n");
}

Exercícios 1

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.

Resposta
#include <stdio.h>


float media_soma_mat(int aA[][3],int aB[][3])
{
  int i,j;
  int soma_ac=0;
  /*int cC[2][3];*/

  for(i=0;i<2;i++){
     for(j=0;j<3;j++) {
        /*cC[i][j] = aA[i][j] + aB[i][j];*/
        soma_ac = soma_ac +aA[i][j] + aB[i][j];
     }
  }
  return (soma_ac/6.0);
}

void main()
{
  int mA[2][3]={ 
                 11,12,13,
                 21,22,23},
      mB[2][3]={
                1,2,3,
                1,2,3};
  float media;

  media =  media_soma_mat(mA,mB);
  
}

2. Implementar uma programa para calcular o determinante de uma matriz 3x3 (de reais) a ser fornecida pelo teclado.
3. Implementar um programa para ler duas matrizes (matA e matB) e multiplicá-las, colocando o resultado em uma matriz matC.
4. Vamos implementar um jogo similar a batalha naval da seguinte forma.

4.1. Crie uma matriz de inteiros global chamada ZonaDeGuerra com 10x10 posições (iniciada com 0). 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.
4.2. Crie um contador global de tiros iniciado com 0.
4.3. 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).
4.4. Ao final do jogo é mostrado o nome do jogador, o número de tiros dados e a pontuação obtida.
Resposta
/*
   Batalha Naval
   Versão Turma PRG2014-1-IFSC
*/

#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

/**********************************/
/***** 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]=0;
}

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

PosicionarFragatas()
{ 
  int i;
  for(i=0;i<5;i++){
  	 SortearCasa();
     ZonaDeGuerra[x_sorteado][y_sorteado]=2; 	 	 
  }
}

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

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

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("| %d ",ZonaDeGuerra[linha][j]); 
  }
  printf("|\n");
  printf("     +---+---+---+---+---+---+---+---+---+---+\n");
}


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

int Tiro()
{
}

main()
{
  ZerarMatriz();
  PosicionarNavios();
  ImprimeMatriz();
  do {
     situacao = Tiro();
  while (situacao!=0);
}

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>

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

  for (i=0;i<4;i++)
       printf("%s\n",&TabelaUsuarios[i][0]);
}

Note a forma como é realizada a inicialização da matriz.

Exercícios 2

1. Implementar um programa para "abrir uma porta" para um usuário que se encontra na tabela acima.

Reposta
#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 && str2[i]!=0) {
     if (str1[i]!=str2[i])
        break; 
     i++;
  }
  if(str1[i]==0 && str2[i]==0) 
     return 0; // Perceba que retorna "0" quando as strings forem iguais
  else
     return 1; // e "1" quando forem diferentes (tomem cuidado com o entendimento)
  
}
        
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");   
}

2. 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.
3. Implementar uma modificação do exercício anterior que permite ao programa ficar em loop até que se entre com userID igual a "fim".
4. 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).
5. No exercício anterior, acrecente 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 desbloquado e o sistema volta a perguntar por um userID.

Exercício MEGASENA
#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();
}




Icone voltar.png Icone menu.png Icone prox.png