AULA 14 - Microcontroladores - Técnico: mudanças entre as edições

De IFSC
Ir para navegação Ir para pesquisar
imported>Fargoud
imported>Fargoud
Linha 111: Linha 111:
===Exercícios===
===Exercícios===


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


==MATRIZES PASSADAS PARA FUNÇÕES==
==MATRIZES PASSADAS PARA FUNÇÕES==

Edição das 14h16min de 18 de maio de 2017

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”);
  gets(s);
  imprime_maius(s);
}
void imprime_maius(char string[])
{  register int t;
   for(t=0;string[t]; t++)
   {   string[t] = toupper(string[t]);

printf("%c", string[t]);

   }
}     


/************************************/
/*** 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

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.