ESTRUTURAS DE DADOS

 

As estruturas de dados consistem em organizações lógicas sobre o armazenamento e manipulação dos dados que serão necessários ao programa utilizar.

 

Existem algumas estruturas de dados fundamentais a serem implementadas sobre os recursos computacionais, onde a primeira é apresentada a seguir.

 
ESTRUTURA DE DADOS COMPOSTA HOMOGÊNEA
 

Conforme abordado anteriormente, no estudo de estruturas de dados homogêneas na representação em algoritmo, esta estrutura permite o armazenamento e a manipulação de dados na memória do computador de forma mais organizada e eficiente no programa desenvolvido.

 

A primeira estrutura abordada foi Estrutura de Dados Composta Homogênea Unidimensional, também chamada de VETOR. Esta estrutura de dados consiste em uma única variável que pode armazenar vários valores (por isso composta), sendo todos estes valores do mesmo tipo (por isso homogênea). Suas principais características são:

 
     
  • Contém vários valores (número definido);
  • Todos valores são do mesmo tipo de dado;
  • Possui um único nome (identificador da variável);
  • Cada valor do conjunto é independente, de acordo com sua posição na estrutura.
 

Exemplo:

 

Suponha a existência de uma estrutura que armazenou o resultado dos 15 números sorteados do jogo lotérico "LotoFácil" na virada do ano de 2017.

 

    nome do identificador = nSorteados

 

Os valores correspondem aos conteúdos informados pelo usuário, ou seja, os números sorteados.

 

Os índices correspondem às posições que identificam os valores armazenados independentemente uns dos outros, sendo através destes índices realizada a manipulação específica e independente de cada valor armazenado.

 

Suponha que o apostador quisesse verificar somente o sexto número que foi sorteado. Como o índice da estrutura de dados sempre começa em zero, o sexto número sorteado possui está armazenado na 5° posição da estrutura, sendo o conteúdo desta posição (5) igual a 10 (sexto número sorteado no jogo lotérico armazenado na estrutura nSorteados).

 

Estas estruturas de dados compostas homogêneas também são chamadas de vetores, quando possuem variação de dados somente em uma dimensão.

 
     
  • Composta: porque podem armazenar vários valores;
  • Unidimensional: porque vetor só possui variação em uma dimensão;
  • Homogênea: porque só armazena um único tipo de dado.
 

A sintaxe necessária para a criação de uma estrutura de dados composta unidimensional (vetor) em um programa na linguagem C difere um pouco da abordada em algoritmo, porém apresenta a mesma funcionalidade lógica e operacional.

 
  • Declaração da estrutura de dados composta unidimensional:
 

<tipo de dado> <identificador>[<tamanho>];

 

    onde:

       <tipo de dado> é o tipo de dado que será armazenado na estrutura;

       <identificador> é o nome atribuído à estrutura (vetor);

       <tamanho> é a quantidade de elementos que o vetor poderá armazenar.

 
    Exemplo:

       float notas[100];


No exemplo anterior está sendo criado um vetor chamado notas que pode armazenar até 100 números reais diferentes, correspondendo estes 100 números a notas de 100 alunos.

 

O acesso a um elemento do vetor pode acontecer por meio da especificação do nome do vetor seguido da posição entre colchetes.

 
 
    Exemplo:

    O valor de nSorteados[10] é 15, o de nSorteados[2] é 8, e assim por diante.

 

Observe a seguir o exemplo de criação, armazenamento e apresentação dos némeros sorteados fornecidos pelo usuário em um vetor chamado nSorteados, como definido na representação acima.

 
{ observe primeiro o algoritmo desta solução }

algoritmo jogo_de_loteria;
// Síntese
//  Objetivo:	Armazenar os 15 números sorteados na Lotofácil da virada.
//  Entrada :	15 números sorteados.
//  Saída   :	Apresentar todos os números sorteados. 
	 
principal
    //Declarações
    inteiro auxiliar,nSorteados[15];  { supondo o vetor representado acima }
   //Instruções
    para (auxiliar de 0 ate 14 passo 1) faca 
      escreva("Informe o ",auxiliar + 1,"° numero sorteado: ");
      leia(nSorteados[auxiliar]);
      limpaTela();
    fimPara
    para (auxiliar de 0 ate 14 passo 1) faca 
      escreval("auxiliar+1","° numero sorteado = ",nSorteados[auxiliar]);
    fimPara	
fimPrincipal
 

Acompanhe abaixo a tradução do exemplo acima para um programa na Linguagem C.

 
/*
  SÍNTESE
     Objetivo: Armazenar os 15 números sorteados na Lotofácil da virada.
     Entrada: 15 números sorteados.
     Saída: Apresentar todos os números sorteados.	
*/
#include <stdio.h>  
#include <conio.h>  
int main(void)
{
  //Declarações
   int auxiliar;
   int nSorteados[15];
  //Instruções
   for(auxiliar = 0; auxiliar < 15;auxiliar++)
   {
      printf("Informe o %d numero sorteado: \n",auxiliar+1);
      scanf("%d",&nSorteados[auxiliar]);
      clrscr();
   }
   for(auxiliar = 0; auxiliar < 15;auxiliar++)
   {
      printf("O %d numero sorteado = %d\n",auxiliar+1, nSorteados[auxiliar]);
   }
   getch();
   return 0;
}
 

Outro Exemplo:

    Escrever um programa que declare um vetor de reais e leia os preços de 30 produtos de um supermercado, apresentando ao final a média de preços desse mercado.

 
/*
SÍNTESE
	Objetivo: Armazernar o preço de 30 produtos de um supermercado. 
	Entrada: 30 preços.
	Saída: Média Aritmética dos preços dos 30 produtos.	
*/	
#include <stdio.h>  
#include <conio.h>  
int main(void)
{
  //Declarações
       int auxiliar;
       float soma;
       float precos[30];  // { vetor de 30 valores reais } 
  //Instruções
     for(auxiliar=0, soma=0; auxiliar < 30; auxiliar++)
     {
        printf("\nInforme o preco  do produto %2d = ", auxiliar + 1);
        scanf("%f",&precos[auxiliar]);
        soma += precos[auxiliar]; 
        clrscr();
     }
     printf("Media dos precos dos produtos = %3.2f", soma / 30);
     getch();
     return 0;
}
 
Vetor do Tipo Caracter
 

Um caso especial no uso de vetores é a estrutura de dados composta homogênea do tipo de dados caracter. Somente este tipo de estrutura possui algumas características adicionais em sua manipulação, sendo as características principais apresentadas abaixo:

 
  • marcador de fim da string corresponde ao caracter codificado pelo \0;
  • marcador necessita de um espaço de memória correspondente a um caracter para ser armazenado na string.
 

A primeira característica específica é que toda string (estrutura de caracteres) termina com o código \0, que ocupa o espaço de um caracter nesta string. Isso indica que se uma estrutura composta homogênea unidimensional de caracter for definida com 30 caracteres ela só poderá armazenar 29 caracteres fornecidos pelo usuário, pois seu último caracter será o código \0 que marca o fim desta cadeia de caracteres (string).

 

A leitura de dados para string pode ser feita pela função scanf ou gets, possuindo as duas alguns aspectos que merecem a atenção e cuidado do programador. A função scanf para ler e armazenamento deve referenciar o endereço inicial da string, ou seja, sua posição zero.

 

Suponha a declaração char nome[30];, onde o comando de leitura scanf seria:

 

scanf("%s",nome);

 

onde somente o nome da string corresponde exatamente a &nome[0] e o código %s representa o código de leitura especifico para string.

 

Para esta mesma declaração (char nome[30];) também poderia ser feita a leitura usando a função gets, sendo seu uso:

 

gets(nome); //nome corresponde &nome[0]

 

A função que complementa a gets, apresentando somente string, é a puts. Esta função apresenta uma string no recurso de saída padrão da Linguagem C, ou seja, o vídeo (ou monitor).

 

A função puts apresenta uma string a partir da posição da janela onde o cursor estiver, saltando sempre uma linha após terminar a apresentação total de sua string. Para o exemplo do nome poderia ser apresentada uma mensagem e depois o nome fornecido.

 

    puts("O nome informado foi");

    puts(nome);

 

Apesar das funções de leitura terem um tratamento diferenciado para este tipo de estrutura de dados composta homogênea (string) elas ainda necessitam de um cuidado adicional quando empregadas em um programa, pois ambas as função (scanf e gets) não verificam o limite de caracteres que as variáveis string podem armazenar.

 

Uma falha na leitura destes dados pode provocar a invasão de áreas de memória que não pertencem ao seu programa ocasionando diversos tipos de problemas correspondentes a área de memória invadida por estes dados. A maioria dos problemas gerados por esta invasão são gravíssimos e não podem ser recuperados estando entre eles o travamento do computador ou do próprio programa.

 

Outro problema pertinente somente ao uso da função scanf para string é a inserção do código \0 no local onde o usuário inserir um espaço em branco. Com esta inserção o final da string será exatamente onde o usuário inseriu o primeiro espaço e não onde a string foi encerrada com o pressionamento da tecla <ENTER>. Por isso esta função de leitura de string só deve ser usada na leitura de conjunto de caracteres simples, sem nenhum espaço em branco, ou seja, somente de uma palavra. Nomes completos, frases e muitos outros exemplos que envolvam mais que uma palavra devem ser lidos somente com a função gets().

 

Suponha a necessidade de armazenar o nome Maryana em uma variável. Se for criada uma variável caracter, com identificador de nome, ela só terá a capacidade de armazenar uma letra do nome desejado. Portanto, será necessário criar uma variável tipo texto para o armazenamento de todos os caracteres do nome desejado.

 
algoritmo guardaNome;
		  
// Síntese
//  Objetivo:	armazenar o primeiro nome de uma pessoa.
//  Entrada :	nome 	
//  Saída   :	apresenta o primeiro nome da pessoa.

principal
	// Declarações
	texto nome;
	
	// Instruções
	escreva("Digite o primeiro nome da pessoa ");
	leia(nome);
	enquanto ((tamanhoTexto(nome) > 10)  ou  (tamanhoTexto(nome) == 0)) faca 
          limpaTela();
          escreval("Nome inválido.Digite o nome da primeira pessoa novamente");
          leia(nome);
	fimEnquanto 
	escreval("O nome digitado foi: ", nome);	
fimPrincipal
 

Acompanhe a seguir a tradução deste algoritmo para um programa na Linguagem C.

 
/*
  SÍNTESE
     Objetivo: Armazenar o primeiro nome de uma pessoa
     Entrada: Nome
     Saída: Apresenta o primeiro nome de uma pessoa
*/
#include <stdio.h>  
#include <conio.h>  
int main(void)
{ 
  //Declarações
    int auxiliar, tamanho;
    char nome[11];
  //Instruções
    auxiliar = 0;
	puts("Digite o primeiro nome da pessoa :  ");
	gets(nome);
	tamanho = strlen(nome);
	while(tamanho > 10 || tamanho == 0){
	  clrscr();
	  puts("Nome invalido.Digite novamente o primeiro nome da pessoa");
	  gets(nome);
	  tamanho = strlen(nome);
	};
	clrscr();
	printf("Nome: %s",nome);
	getch();
	return 0;
}
 

Observe as diferenças significativas nas lógicas que permitem a leitura da string respeitando o tamanho da string e depois apresenta a mesma. Note que na Lingaguem de programação C a representação de uma string é feita através de um vetor de caracter tendo um tamanho pré-estabelecido. Por ter o seu valor pré-estabelecido um cuidado deve ser tomado ao inserir valores que ultrapassem a quantidade de caracteres permitida, por isso é feita a verificação da quantidade de caracteres da entrada informada. Duas observações são importantes, sendo a primeira o uso de uma função pertencente a biblioteca string.h, disponível na Linguagem C padrão ANSI, que retorna um valor inteiro correspondente a quantidade de caracteres inseridos na string até o \0, sendo o código \0 desprezado no valor retornado por esta função denominada strlen().

 

A strlen() só aceita um parâmetro devendo ele ser uma string. Várias outras funções de manipulação de string estão disponíveis nesta biblioteca (string.h), sendo interessante o estudo da mesma.

 

Atividade de Fixação

 

No intuito de fixar a aprendizagem iniciada por meio deste módulo e verificar como seu entendimento sobre este conteúdo está, estão sendo sugeridos alguns exercícios de fixação para serem resolvidos. Clique no link de exercícios ao lado, pois será por meio dele iniciada a lista de exercício sobre os conteúdos estudados até este momento nesta disciplina.