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 armazena a idade de 12 pessoas.

 

    nome do identificador = idades

 

Os valores correspondem aos conteúdos informados pelo usuário, ou seja, são as idades desejadas.

 

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 seja necessário apresentar somente a idade do sexto indivíduo. Como o índice da estrutura de dados sempre começa em zero, o sexto indivíduo possui a sua idade armazenada na 5ª posição da estrutura, sendo o conteúdo desta posição (5) igual a 7 (idade do sexto indivíduo armazenado na estrutura idades).

 

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 idades[10] é 45, o de idades[2] é 29, e assim por diante.

 

Observe a seguir o exemplo de criação, armazenamento e apresentação de idades fornecidas pelo usuário em um vetor chamado idades, como definido na representação acima.

 
{ observe primeiro o algoritmo desta solução }

algoritmo idades;
//Síntese
  //Objetivo: armazenar a idade de 12 pessoas e apresentá-las
  //Entrada: 12 idades
  //Saída: todas as idades armazenadas 

principal
    //Declarações
       inteiro auxiliar;
       real idades[12];  { supondo o vetor representado acima }
   //Instruções
      para (auxiliar de 0 ate 11 passo 1) faca
         escreva("Informe a idade da ", auxiliar+1, "ª pessoa: ");
         leia(idades[auxiliar]);
         escreval("");
      fimPara
      limpaTela();
      para (auxiliar de 0 ate 11 passo 1) faca
         escreva("Idade da ", auxiliar+1, "ª pessoa= ", idades[auxiliar]);
         escreval("");
      fimPara
fimPrincipal
 

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

 
/*
  SÍNTESE
     Objetivo: armazenar a idade de 12 pessoas e apresentá-las
     Entrada: 12 idades
     Saída: todas as idades armazenadas
*/
#include <stdio.h>  
#include <conio.h>  
int main(void)
{
  //Declarações
      int auxiliar;
      float idades[12];
  //Instruções
       for(auxiliar=0; auxiliar < 12; auxiliar++)
       {
          printf("/nInforme a idade da %3d pessoa: ", auxiliar+1);
          scanf("%f",&idades[auxiliar]);
       }
       clrscr();
       for(auxiliar=0; auxiliar < 12; auxiliar++)
         printf("Idade da %3d pessoa = %3.1f\n", auxiliar+1, idades[auxiliar])
       getch();
       return 0;
}
 

Outro Exemplo:

    Escrever um programa que declare um vetor de reais e leia as notas de 30 alunos, apresentando ao final a média desta turma.

 
/*
  SÍNTESE
     Objetivo: Armazenar a nota de 30 alunos
     Entrada: 30 notas
     Saída: Média aritmética desta turma de 30 aluno
*/
#include <stdio.h>  
#include <conio.h>  
int main(void)
{
  //Declarações
       int auxiliar;
       float soma;
       float notas[30];    { vetor de 30 valores reais }
  //Instruções
     for(auxiliar=0, soma=0; auxiliar < 30; auxiliar++)
     {
        printf("\nInforme a nota do aluno %2d = ", auxiliar + 1);
        scanf("%f",&notas[auxiliar]);
        soma += notas[auxiliar]; 
     }
     printf("Média da turma = %3.1f", 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 Marilda 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 de uma pessoas

principal
	// Declarações
	texto nome;
	logico valido;
	
	// Instruções
	valido = falso ;
	faca
		escreva("Informe o nome: ");
		leia (nome);
		se (tamanhoTexto(nome) > 9) entao
			valido = falso;
			escreval ("Tamanho nome inválido");
		senao
			valido = verdadeiro;
		fimSe
		
	enquanto (nao valido);
	escreval ("O nome informado 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,contador, tamanho;
     char nome[10];
  //Instruções
     auxiliar = 0;
     puts("Informe o nome desejado terminando com ponto final: ");
     do {
         gets(nome);
         tamanho = strlen(nome);
         if (tamanho > 9)
             puts("Nome informado muito grande, informe novamente: ");
         } while (tamanho > 9);   //9 porque o último caracter deve ser o código \0
        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.