VOLPITI - Tecnologia da Informação
 
Busca
Tópicos
  Cadastre-se :: Hospedagem LinuxDicas :: Acessórios LinuxDicas :: Fórum LinuxDicas   

Usuários LinuxDicas
· AvantGO
· Backend XML (RSS)
· Contato/Publicidade
· Enviar Notícias/Artigos
· Fórum LinuxDicas
· Lista de Discussão
· Mensagens Privadas

Casa do Linux


Lista de Discussão
·[linuxdicas] quetão de linux
·Ferramenta de Backup
·redes
·Search Engine

Leia mais...

Artigos LinuxDicas
· Resistência ao Linux
· Guia para o Novato
· Licenciamento do SuSE
· Foca GNU/Linux - Iniciante
· Foca GNU/Linux - Intermediário
· Foca GNU/Linux - Avançadoe
· Curso C
· Outras Seções de Artigos

FAQ LinuxDicas
· Licença
· Servidores
· Ambiente X
· Hardware
· Instalação
· Internet
· Aplicativos
· Sistema
· StarOffice

Notícias Velhas
Segunda, abril 21
· MON - Monitorando a disponibilidade de serviços
Quinta, abril 17
· Últimos dias para Inscrições de Palestras no Flisol Campinas
· Acessando seus arquivos de sua máquina de qualquer computador do mundo
Terça, abril 15
· Artigo sobre o Moregroupware
Segunda, abril 14
· Análise do Mandriva Xtreme2 Pack
Terça, março 18
· Como migrar dados do msaccess para mysql
· A verdadeira razão para usarmos Linux
· usando o rsync 3.0.0 para fazer backup entre linux e xp
· Firefox3 : Como Instalar manualmente.
Sábado, fevereiro 09
· Configurando um DNS CHROOTED Primário e Reverso para o seu site.
Quinta, dezembro 27
· Censurando a internet com o OpenDNS
Domingo, outubro 14
· Bandwidth Monitoring Tools For Linux
Quinta, outubro 11
· Variáveis de ambiente
Quinta, agosto 02
· Rodando processos em múltiplos servidores, Cluster!!!
· Instalando XEN no seu Ubuntu/Debian
Domingo, junho 17
· Vovó, faz backup pra mim?
Quarta, junho 13
· Canetas: Idealismo Antártico
Quinta, junho 07
· CA confiável com certificados digitais
Domingo, junho 03
· Equações Matemáticas via Shell
Sábado, junho 02
· Permanent Link to Garimpar é preciso [2]: Confira seu e-mail

Notícias antigas

Versões Estáveis
· Kernel Linux
· *nix e *BSD ISOs da Unicamp
· Linux ISO
· FreeBSD Releases

Curso de C - 8. Matrizes e Strings

(2299 total de palavras neste texto)
(5062 vizualização(ões))   Imprimir




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:

1 5 8
-2 0 7
12 -1 4

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:

1 4 2
2 6 -2
-7 9 0

mat2:

7 1 -4
11 0 3
1 19 6

A matriz resultado da soma de mat1 por mat2 será:

8 5 -2
13 6 1
-6 28 6

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
  

[ Voltar Curso C | Índice de Seções ]


Copyright © 2002 - 2007 LinuxDicas - Todos Os Direitos Reservados.
LinuxDicas: lucas.martinez @linuxdicas.com.br
Web site engine's code is Copyright © 2003 by PHP-Nuke. All Rights Reserved. PHP-Nuke is Free Software released under the GNU/GPL license.
Tempo para gerar esta página: 0.163 segundos.