AULA 14 - Microcontroladores - Técnico

De IFSC
Revisão de 20h14min de 14 de junho de 2017 por imported>Fargoud (→‎Exercícios)
Ir para navegação Ir para pesquisar

MATRIZES

São grupos (de uma ou mais dimensões) de variáveis indexadas, do mesmo tipo.

Matrizes unidimensionais são mais conhecidas por vetores ou "arrays".

Sintaxe:

      tipo  nome[tamanho]   =  { elem0, elem1, ... , elemn} ;

onde,

  • tipo: tipo dos elementos da matriz;
  • nome: nome da matriz;
  • tamanho: número de elementos da matriz;
  • = { } : termo opcional. Representa a definição de uma matriz, já na declaração. Caso a matriz seja definida na declaração é desnecessário especificar-se o tamanho desta.
  • elemx: elemento da matriz de índice x.


Todas as matrizes e vetores em C iniciam pelo elemento de índice 0 (zero).

Elementos não-inicializados recebem o valor 0 (zero) por default.

Os elementos da matriz são referenciados individualmente pela especificação do nome da matriz, seguido do índice do elemento entre colchetes:

           nome[índice]

Ex: Matriz que armazena as notas das 4 provas de um aluno:

   float notas[4] = {9.5, 5.0, 10, 6.8};
      ...
      notas[0] = 9.5;
      notas[2] = 10;
      ...           

ou

   float notas[4];
      ...
      notas[0] = 9.5;
      ...
      notas[3] = 6.8;  

ou

    float notas[] = { 9.5, 5.0, 10, 6.8};
       ...
       notas [0] = 9.5;
       ...                      
                      

STRINGS

Uma string em C equivale a um vetor de caracteres sempre terminado pelo caractere NULL ('\0'). Para inicializar-se um vetor de caracteres pode-se fazê-lo individualmente, elemento a elemento, ou não. Mesmo que se esqueça de incluir o caractere NULL, este será acrescentado à string. Além disto, deve-se sempre lembrar de dimensionar o tamanho da string como o número de caracteres da expressão + 1 (para o caractere NULL). Exs:

      char matcar[] = "ABCD";  

onde:

      matcar[0] = 'A';
      matcar[1] = 'B';
      matcar[2] = 'C';
      matcar[3] = 'D';
      matcar[4] = '\0';

ou

      char matcar[5] = { 'A', 'B', 'C', 'D', '\0'};  

se:

     char matcar[10] = "ABCDE"; 

temos:

       matcar[0] = 'A';
       matcar[1] = 'B';
       ...
       matcar[4] = 'E';
       matcar[5] = '\0'; 
       matcar[6] = '0';
       matcar[7] = '0';
       matcar[8] = '0';
       matcar[9] = '0'

A string nula ("") é: { '\0'}.


MATRIZES MULTIDIMENSIONAIS

Para representar, por exemplo, a matriz bidimensional "Mat", abaixo:

                                  2    4    6    8   
                Mat =             1    2    3    4   
                                  7    8    9    0  

utilizamos a sintaxe:

     tipo   nome [ número_linhas ]  [número_colunas  ]; 

ou seja, no primeiro par de colchetes indicamos o número de linhas da matriz e no segundo par, o número de colunas. O tamanho da matriz será:

         número_linhas X número_colunas

No caso de matrizes multidimensionais, a sintaxe é:

    tipo   nome [ tamanho1 ]  [tamanho2 ] ... [ tamanhon];

onde tamanhoX é o número de elementos da X-ésima dimensão. Ex:

     int mat [3] [4] =   {  { 2, 4, 6, 8 },
                            { 1, 2, 3, 4 },
                            { 7, 8, 9, 0 }  } ;  

onde:

    elemento mat [0] [0] = 2;
    elemento mat [2] [3] = 0;
    elemento mat [1] [2] = 3;
    etc.


Exercícios

  1. Faça o programa que lê os 12 elementos de uma matriz 3x4 e fornece o somatório dos valores de cada linha. Solução
  2. Faça um programa que cria uma matriz de 3 dimensões (2 x 4 x 2) e atribui valores a mesma.Solução

MATRIZES PASSADAS PARA FUNÇÕES

Na linguagem C, o nome de uma matriz é equivalente ao endereço do primeiro elemento da matriz! Isto significa que quando queremos passar uma matriz como argumento ("por referência") a uma função, basta utilizar o nome da matriz, sem os colchetes e índices. Se apenas um elemento da matriz deve ser modificado, então utiliza-se seus índices em colchetes.

Ex:

 /*******************************************************/
 /*** Programa que converte uma string para maiúscula ***/
 /******************************************************/
 #include <ctype.h>
 #include <stdio.h>
 void imprime_maius(char[81]);
 void main(void)
 {  char s[81];
   printf("Digite uma frase:\n");
   gets(s);
   imprime_maius(s);
 }
 void imprime_maius(char string[])
 {  register int t;
    printf("\n\n");
    for(t=0;string[t]; t++)
    {   string[t] = toupper(string[t]);
        printf("%c", string[t]);
     }
    printf("\n\n");
  }
  

/************************************/
/*** MATRIZ DO JOGO DA VELHA        ***/
/*************************************/
#include <stdlib.h>
#include <stdio.h>
void pega_mov_jogador(void);
void pega_mov_computador(void);
void exibir_matriz(void);
int check(void);
char matriz[3][3] = { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '};
void main(void)
{  char feito;
  printf(" ** Este e' o jogo da velha!! ***\n");
  printf(" Voce vai jogar contra o computador \n");
  feito = ' ' ;
  do
  {    exibir_matriz();
       pega_mov_jogador();
       feito = check();   // verifica quem ganhou
       if(feito != ' ' )
         break;
       pega_mov_computador();
       feito = check();    // verifica quem ganhou
  }while (feito == ' ' );
  if (feito== 'X' ) printf(" Voce venceu!*** \n");
  else printf(" Eu ganhei!!\n");
  exibir_matriz();     // mostra posicoes finais
}
void pega_mov_jogador(void)
{   int x, y;
   int ok = 0;
   printf(" Digite as coordenadas para o seu X: " );
   do
   {  scanf(" %d %d", &x, &y);
      x--; y--;
      if (matriz[x][y] != ' ')
          printf(" Movimento invalido, \nTente de novo.\n");
      else
      {  matriz[x][y] = 'X';
         ok = 1;}
   }while(!ok);  }
void pega_mov_computador(void)
{  register int t, i;
  // procura lugar nao usado ainda
  for(t=0;t<3;t++)
     for(i=0;i<3;i++)
        if(matriz[t][i] == ' ')
           if(t*i==9)
           {  printf(" Empate!! \n");
               exit(0);  // terminar o programa
           }else
           {matriz[t][i] = 'O';
            t=3; i=3;
           }
}
void exibir_matriz(void)
{  int t;
  for(t=0;t<3;t++)
  {   printf(" %c | %c | %c " , matriz[t][0], matriz[t][1], matriz[t][2]);
      if(t!=2) printf("\n---|---|---\n");
  }
  printf("\n");
}
// verifica se existe um ganhador; caso contrario, retorna ' '
int check(void)
{  int t;
  for(t=0;t<3; t++)
    if(matriz[t][0]==matriz[t][1] && matriz[t][1]==matriz[t][2])
      return matriz[t][0];
  for(t=0;t<3;t++)
    if(matriz[0][t]==matriz[1][t] && matriz[1][t]==matriz[2][t])
      return matriz[0][t];
  if(matriz[0][0]==matriz[1][1] && matriz[1][1]==matriz[2][2])
     return matriz[0][0];
  if(matriz[0][2]==matriz[1][1] && matriz[1][1]==matriz[2][0])
     return matriz[0][2];
  return ' ';
}

ORGANIZAÇÃO DE MATRIZES NA MEMÓRIA

Como já foi dito, o nome de uma matriz contém o endereço do primeiro elemento da matriz (ou seja, é um ponteiro para o primeiro elemento) . Além disto, os elementos são armazenados um em seguida do outro, em endereços consecutivos. Ou seja, numa matriz de caracteres (variáveis de 1 palavra), se o endereço do primeiro elemento (índice 0) for 1500, por exemplo, o endereço do segundo (índice 1) será 1501 e assim por diante. Quando utilizamos o nome de uma matriz como parâmetro para uma função, não estaremos passando a matriz, mas na verdade apenas o endereço do primeiro elemento desta, e por consequência, os outros. Ex:

 char alfa[27];
  ...
  alfa[0] = 'A';
  alfa[1] = 'B';
   ...
  alfa[25] = 'Z';
   ...
   escreve(alfa);
  ...      

Note que, apesar de termos reservado 27 bytes para a matriz 'alfa', utilizamos apenas 26. Como trata-se de uma string, o último lugar é reservado para o caractere NULL ('\0'). Na memória, a representação desta matriz seria (suponha o endereço de 'alfa' como sendo 1492 e do primeiro elemento, alfa[0] como sendo 1500):


Orgmatmem.png

onde o valor 65 é o código ASCII do caractere 'A' , 90 é o código do caractere 'Z' e 00 é o código do caractere NULL.


Observação Importante sobre Matrizes:

A linguagem C não verifica se alguma matriz tomar espaço de memória que não devia. Por exemplo:

int notas[30];
...
for(i=0; i<40; i++)
   scanf("%d", notas + i);            E

No exemplo acima, declaramos a matriz notas como tendo 30 elementos e depois, por descuido provavelmente, atribuímos 40 valores a esta (notas[0] a notas[39]). Neste caso, 10 espaços de memória seguintes ao espaço ocupado pela matriz, serão apagados e receberão valores de notas. Isto pode danificar dados importantes do programa, ao apagar os valores de variaveis ou constantes, ou mesmo partes do código. Não se pode prever o que aconteceria. A responsabilidade do programador redobra, portanto, ao lidar com matrizes e vetores e é preciso muita atenção. Outro erro que poderia ocorrer no exemplo acima, seria pedir a entrada de valores tipo float (usando "%f", por exemplo) em scanf() para elementos de uma matriz de inteiros. Como o tipo float é maior que o tipo int, cada elemento não caberia no espaço reservado para si e tomaria memória do elemento seguinte.

*  Note que utilizamos aqui a expressão   " scanf("%d", notas + i);   ", ao invés de "scanf("%d", &notas[i]);"  ou mesmo "scanf("%d", notas[i]);" . Porque? Todas estas expressões são aceitas? Qual a diferença entre elas??? 


Exercícios

1. Faça o programa que lê um vetor de 10 inteiros e imprime quantos destes números tem valor acima da média.

2. Faça o programa que lê uma string de até 80 caracteres e troca todas as ocorrências da letra "o" por um "X".

3. Faça um programa que lê 4 notas para cada um dos 30 alunos de uma turma, armazena-as em uma matriz, calcula e devolve a média de cada aluno.

Respostas


Outros exemplos e exercícios:

Material do Prof. Douglas Alexandre