Curso de C - 8. Matrizes e Strings
(2299 total de palavras neste texto) (5062 vizualização(ões)) 
Curso de C - 8. Matrizes e Strings
8.1. Matrizes Unidimensionais
Até agora fizemos programas que armazenam poucas informações de uma vez, algo que a declaração de algumas variáveis resolve bem. Mas pense em
um programa que tem que ler várias informações de um mesmo tipo e armazenar na memória. Por exemplo, um programa que armazene as notas de 50
alunos. Como você faria? Declararia 50 variáveis float para armazená-las?
float nota1, nota2, nota3, nota4, nota5, nota6, nota7, nota8, nota9, ..., nota50;
Com certeza, não seria viável.
É aí que entram em cena as matrizes, estruturas que armazenam vários dados de um mesmo tipo de forma organizada e fácil para o
programador manipular. Os dados na matriz são referenciados por índices numéricos, começando sempre por 0. A declaração de uma matriz
unidimensional tem a seguinte forma:
tipo nome[número de elementos];
Exemplo:
float notas[50];
float é o tipo dos dados da matriz; notas é um nome, dado pelo programador; 50 é a quantidade de dados que a matriz é capaz de
armazenar.
É importante saber que o índice de uma matriz começa sempre em 0. Uma matriz de 50 elementos vai de 0 a 49. Portanto, o elemento:
notas[2]
não é o segundo, e sim o terceiro elemento. O último elemento da matriz é o referenciado pela quantidade de elementos menos 1, ou seja, 49.
Cuidado para não fazer confusão...
Vamos ver um exemplo:
#include
main()
{
int mat[5]; /* matriz que armazena 5 inteiros */
mat[0]= 0;
mat[1]= 2;
mat[2]= 4;
mat[3]= 6;
mat[4]= 8;
printf("%d ", mat[0]);
printf("%d ", mat[1]);
printf("%d ", mat[2]);
printf("%d ", mat[3]);
printf("%d ", mat[4]);
return 0;
}
Ainda está trabalhoso? Com certeza... O potencial das matrizes não seria alcançado se não fosse o poder dos laços:
#include
main()
{
int i;
int mat[5];
for (i=0; i<5. i++)
mat[i]= i*2;
for (i=0; i<5. i++)
printf("%d ", mat[i]);
return 0;
}
Há um casamento perfeito entre as matrizes e as estruturas de repetição... Para ler dados e colocar em uma matriz, não há segredo:
#include
main()
{
int i;
int mat[5];
for (i=0; i<5. i++)
{
printf("Digite um número: ");
scanf("%d", &mat[i]);
}
for (i=0; i<5. i++)
printf("%d ", mat[i]);
return 0;
}
O bom e velho scanf() funciona da mesma forma. Temos sempre que colocar o & antes da matriz, pois mat[i] se comporta como qualquer
outra variável (num ou cont, por exemplo).
Da mesma forma que você trabalha com variáveis simples em expressões, comparações, etc, você pode trabalhar com os elementos de uma matriz.
Algumas operações de exemplo:
num= num + mat[i]; /* operações aritméticas */
cont[0]++; /* incremento ou decremento */
num[i] += 3; /* operadores aritméticos de atribuição (C reduzido) */
valor[i]= sqrt(num[i]); /* passando argumentos e recebendo retorno de funções */
islower(carac[i]); /* no caso de ser uma matriz de caracteres */
8.2. Verificando Limites
É tarefa do programador tomar o cuidado de não estourar o limite de uma matriz. O compilador não o avisará caso isso aconteça. Vejam este
exemplo:
int mat[10];
for (i=0; i<=10; i++)
{
printf("Digite um número: ");
scanf("%d", &mat[i]);
}
Neste trecho de programa, há um erro lógico que o compilador não detectará. Nós declaramos uma matriz de 10 elementos (de 0 a 9) e o critério
de parada do for diz i<=10; se i for igual a 10, o programa gravará o dado fora da matriz, já que em uma matriz de 10 elementos o índice vai
de 0 a 9. Isso poderá causar erros graves, visto que houve uma invasão da memória. O certo seria:
int mat[10];
for (i=0; i<10; i++)
{
printf("Digite um número: ");
scanf("%d", &mat[i]);
}
Agora sim, i vai de 0 a 9.
Quando temos um programa grande, e nossa matriz é usada várias vezes, podemos colocar uma constante no lugar do tamanho do limite. Isto
facilita bastante, caso a matriz precise mudar de tamanho. Exemplo:
#include
#define MAX 10
main()
{
int mat[MAX];
int i;
for (i=0; i
Se quiser que sua matriz mude para 20 elementos basta alterar:
#define MAX 10
por:
#define MAX 20
Sem o ponto-e-vírgula no final. Assim você não precisa mudar todos os trechos do programa onde aparece o tamanho da matriz. Este comando é
uma diretiva do pré-processador de C. O pré-processador "monta" o código de acordo com determinadas regras estabelecidas através das
diretivas do pré-processador. Aqui, o pré-processador vai trocar todas as ocorrências de MAX pelo seu valor associado.
8.3. Inicializando Matrizes
Você pode inicializar uma matriz no ato da declaração. Basta fazer assim:
int mat[5]= {1, 2, 3, 4, 5}; /* para inteiros */
char ch[5]= {'a', 'b', 'c', 'd', 'e'}; /* para caracteres */
int mat[]= {2, 4, 6, 8}; /* sem especificar o tamanho (isto é válido somente se inicializar a matriz) */
Os elementos entre chaves são os valores e não os índices.
Para cada tipo, deve-se inicializar com valores válidos, isto é, constantes adequadas para cada tipo.
Como você pode ver, uma matriz não precisa ter explícito o número de elementos na inicialização. O compilador aloca espaço suficiente para os
elementos entre chaves.
8.4. Matrizes de mais de uma dimensão
Em C podemos ter matrizes de mais de uma dimensão. A forma mais comum é a matriz bidimensional. Para declarar uma matriz de duas
dimensões faça assim:
int mat[3][3];
Uma matriz de duas dimensões pode ser entendida como uma matriz matemática, onde o primeiro índice diz respeito às linhas e o outro
índice diz respeito às colunas da matriz. Vamos dar exemplo de uma matriz 3x3:
Vamos fazer um programa que lê e soma duas matrizes bidimensionais:
#include
#define MAX 3
main()
{
int mat1[MAX][MAX], mat2[MAX][MAX];
register int i, j;
/* lê matriz mat1 */
for (i=0; i< MAX; i++)
for (j=0; j< MAX; j++)
{
printf("[%d,%d]= ", i, j);
scanf("%d", &mat1[i][j]);
}
/* lê matriz mat2 */
for (i=0; i< MAX; i++)
for (j=0; j< MAX; j++)
{
printf("[%d,%d]= ", i, j);
scanf("%d", &mat2[i][j]);
}
/* calcula e imprime a matriz resultado da soma entre mat1 e mat2 */
for (i=0; i< MAX; i++)
{
for (j=0; j< MAX; j++)
{
res= mat1[i][j] + mat2[i][j];
printf("%d",res);
}
printf("
");
}
return 0;
}
Vamos explicar, tim tim por tim tim...
Para ler uma matriz de duas dimensões, são necessários 2 loops aninhados (no caso, usamos 2 for). O loop mais externo trata das linhas da
matriz, enquanto que o loop mais interno trata das colunas. Vamos supor que mat1 e mat2 tiveram as seguintes entradas:
mat1:
mat2:
A matriz resultado da soma de mat1 por mat2 será:
Portanto:
mat1[0][0] + mat2[0][0] = 8
mat1[0][1] + mat2[0][1] = 5
mat1[0][2] + mat2[0][2] = -2
mat1[1][0] + mat2[1][0] = 13
mat1[1][1] + mat2[1][1] = 6
mat1[1][2] + mat2[1][2] = 1
mat1[2][0] + mat2[2][0] = -6
mat1[2][1] + mat2[2][1] = 28
mat1[2][2] + mat2[2][2] = 6
8.5. Inicialização de Matrizes Bidimensionais
Para inicializar uma matriz bidimensional, basta fazer da mesma forma que as matrizes unidimensionais:
int mat[3][3]= { 1, 2, 3, /* mat[0][0], mat[0][1], mat[0][2] */
4, 5, 6, /* mat[1][0], mat[1][1], mat[1][2] */
7, 8, 9 }; /* mat[2][0], mat[2][1], mat[2][2] */
Ou delimitando cada linha da matriz com chaves:
int mat[3][3]= { {1, 2, 3}, /* mat[0][0], mat[0][1], mat[0][2] */
{4, 5, 6}, /* mat[1][0], mat[1][1], mat[1][2] */
{7, 8, 9} }; /* mat[2][0], mat[2][1], mat[2][2] */
Ou então, sem especificar o limite:
int mat[][]= { 1, 2, 3, /* mat[0][0], mat[0][1], mat[0][2] */
4, 5, 6, /* mat[1][0], mat[1][1], mat[1][2] */
7, 8, 9 }; /* mat[2][0], mat[2][1], mat[2][2] */
8.6. Strings
Uma string nada mais é do que uma matriz unidimensional de caracteres terminada pelo caractere nulo ( ). É uma estrutura usada para
manipular textos, como palavras, nomes, sentenças, etc. É importante salientar que string não é um tipo nativo em C, como em outras
linguagens. O caractere no final da string é importante porque é o único jeito que as funções têm de saber onde a string termina.
Cada caractere de uma string pode ser acessado como um elemento de uma matriz, através de seus índices.
Uma string constante deve aparecer entre aspas duplas (" "):
printf("Sou da turma do pinguim
");
8.7. Lendo e Imprimindo Strings
Temos várias funções para ler e imprimir strings em C. Nós já vimos estas funções em lições passadas, e sabemos também suas qualidades e
defeitos.
Leitura
Função scanf():
char str[20];
scanf("%s", str);
Aqui scanf() lê a string até encontrar um caractere branco. Quando encontra um caractere branco, ela armazena a string na variável e adiciona
o caractere ao seu final. Para ler uma string, não é necessário colocar o & antes do nome da variável, visto que o nome da variável
string sem os índices é o endereço do seu início.
Função gets():
char str[20];
gets(str);
gets() é uma função fácil de utilizar, visto que o único argumento é a string. Ela lê a string e coloca o caractere ao seu final.
Mas apresenta uma brecha de segurança, pois se o usuário digitar uma string maior do que a declarada, ocorrerá um erro. O próprio compilador
adverte sobre a utilização de gets().
Função fgets():
char str[20];
fgets(str, 19, stdin);
fgets() é mais segura do que gets(), pois não permite que seja armazenado mais caracteres do que o especificado no segundo argumento. Ela é
originalmente uma função que lê strings de um arquivo, mas colocando-se stdin no lugar do descritor do arquivo faz com que ela leia
strings do console. A string é armazenada com o no final e também o caractere de mudança de linha (
).
Impressão
Para imprimir strings, pode-se usar o printf():
printf("%s", str);
ou a função puts(), específica para a impressão de strings. Seu único argumento é a variável string:
puts(str);
Ela imprime a string e pula para a próxima linha.
8.8. Funções Para Manipulação de Strings
A linguagem C tem uma vasta coleção de rotinas para manipulação de strings, localizadas na biblioteca cujo cabeçalho é o string.h. As
funções a seguir são as mais comuns:
(OBS: dest, orig, e str são strings; n é um número inteiro; ch é um char).
strcpy(dest, orig);
Esta função copia a string "orig" em "dest". Como o comando de atribuição entre strings não funciona, esta função deve ser usada para
copiar uma string em outra.
strncpy(dest, orig, n);
Esta função copia o número de caracteres especificado pelo inteiro n da string "orig" para a string "dest". É similar à strcpy(), mas
só copia n caracteres de uma string para outra.
strcat(dest, orig);
Concatena, ou adiciona, a string "orig" ao final de "dest".
strlen(str);
Retorna o tamanho de str (número de caracteres). Útil quando se quer percorrer uma string que não sabemos o tamanho.
strcmp(dest, orig);
Compara duas strings. Retorna 0 se elas forem iguais, menor que 0 se "dest" for menor que "orig" e maior que 0 se "dest" for maior que
"orig".
strncmp(dest, orig, n);
Compara os primeiros "n" caracteres de "dest" com "orig". Os valores de retornos são os mesmos de strcmp().
strchr(str, ch);
Retorna um ponteiro para a primeira ocorrência do caractere "ch" em "str".
strstr(dest, orig);
Retorna um ponteiro para a primeira ocorrência da string "orig" em "dest".
8.9. Matrizes de Strings
Você pode criar uma matriz de strings declarando uma matriz bidimensional de caracteres. O índice do lado esquerdo indica o número de
strings e o índice do lado direito especifica o comprimento máximo de cada string. Então, a declaração:
char mat_str[20][30];
além de ser uma matriz bidimensional de caracteres únicos, pode também ser uma matriz unidimensional de strings. Pode-se armazenar nesta
matriz 20 strings com 30 caracteres cada.
Para acessar uma string individual, basta especificar o índice esquerdo. O comando:
fgets(mat_str[3], 29, stdin);
tem o mesmo resultado que:
fgets(&mat_str[3][0], 29, stdin);
mas em códigos profissionais a primeira forma é bem mais comum.
Bem... chega de prosa. Vamos aos exercícios.
Exercícios
1) Faça um programa que leia 10 números inteiros, armazene-os em uma matriz unidimensional e inverta a ordem dos números na matriz, ou seja,
o número que está na última posição troca de lugar com o que está na primeira; o que está na penúltima posição troca de lugar com o que está
na segunda, e assim por diante, até trocar a posição de todos os elementos da matriz.
2) Faça um programa que leia 5 números, armazene-os em uma matriz unidimensional e os coloque em ordem. Os menores números devem vir primeiro
na matriz e os maiores por último.
3) Faça um programa que leia uma matriz 3 x 3 e a multiplique por um escalar (um número inteiro). O resultado é uma matriz, onde cada
elemento desta nova matriz é o produto do escalar com o elemento correspondente da matriz lida.
4) Faça um programa que leia duas matrizes 2 x 2 e as multiplique, armazenando o resultado em uma terceira.
5) Faça um programa que leia uma string e a inverta, imprimindo na tela a string invertida.
6) Crie um jogo de forca rudimentar, onde um jogador digita a palavra secreta e o outro tenta adivinhar, através de "chutes" de caracteres.
Powered by txt2tags |