Prévia do material em texto
Guia da Disciplina de Introdução à Informática – Parte III – 2015
5 Estruturas de Dados Homogêneas
As estruturas de dados homogêneas possibilitam o armazenamento de grupos de valores em uma única. Essas estruturas são ditas
homogêneas porque os valores que serão armazenados devem pertencer a um mesmo tipo (ex: int, float, char) de dado.
As estruturas homogêneas são divididas em unidimensionais e multidimensionais. Normalmente, as estruturas unidimensionais
são chamadas de vetores e as multidimensionais são chamadas de matrizes.
No intuito de compreender as facilidades do processamento de valores usando uma estrutura de dados observe o código a seguir,
supondo a necessidade de armazenamento da altura de 5 atletas.
int main(){
float altura1, altura2, altura3, altura4, altura5;
printf("Informe a altura do 1º atleta: ");
scanf(“%f”,&altura1);
printf("Informe a altura do 2º atleta: ");
scanf(“%f”,&altura2);
printf("Informe a altura do 3º atleta: ");
scanf(“%f”,&altura3);
printf("Informe a altura do 4º atleta: ");
scanf(“%f”,&altura4);
printf("Informe a altura do 5º atleta: ");
scanf(“%f”,&altura5);
return 0;}
Esse código possibilita a leitura das alturas de 5 atletas diferentes e as armazena em 5 variáveis distintas (altura1, altura2, altura3,
altura4, altura5). Uma instrução de repetição não melhoraria muito esta lógica, pois existe uma variável para cada atleta. Agora
imagine desenvolver um código para a leitura das alturas de 100 atletas.
Nessas situações as estruturas de dados fazem a diferença, sendo essenciais ao processamento dos dados de forma eficiente por
um computador.
5.1 Estruturas Unidimensionais (vetor)
Uma estrutura de dados homogênea e unidimensional, ou vetor, é um conjunto de elementos (dados) armazenados na memória do
computador, sendo esses dados organizados em localizações contíguas de memória, sob um mesmo identificador. Suas principais
características são:
Contém vários valores (número definido);
Todos os valores devem pertencer ao mesmo tipo de dado (homogênea);
Possui um único nome (identificador da variável);
Cada valor do conjunto é acessível independentemente, permitindo o acesso aleatório, de acordo com o seu índice (ou
posição na estrutura de dados);
Modificando o código anterior, que possuía 5 variáveis para guardar 5 alturas de atletas, é possível empregar um vetor (utilizando
um único identificador para estrutura de dados alturas) para armazenar as 5 alturas.
valores
índice 0 1 2 3 4
Os valores correspondem aos conteúdos lidos do usuário, ou seja, são as alturas dos atletas.
O índice aponta um determinado elemento do vetor, ou seja, o índice permite que os valores armazenados no vetor sejam
manipulados (recuperados ou armazenados) de forma independente. Como o vetor é unidimensional, possui apenas um índice.
Todo índice de uma estrutura de dados inicia sempre a partir de zero, por exemplo, a quarta altura (2.20) está armazenada na
posição referenciada pelo índice 3 da estrutura.
5.1.1 Declaração
Para declaração de um vetor em C deve-se utilizar a seguinte sintaxe:
<tipo de dado> <identificador> [<tamanho do vetor>];
onde:
1.80 2.03 1.75 2.20 2.12
<tipo de dado> - tipo de dado que será armazenado no vetor. Ex.: int, float, char, etc..
<identificador> - nome definido ao vetor, respeitando as regras de identificação.
<tamanho do vetor> - define a quantidade de elementos que o vetor pode armazenar.
Exemplo:
float alturas[5]; //declara um vetor chamado alturas que pode armazenar até 5 números reais.
Uma atenção especial deve ser dedicada na compreensão de que este tipo estrutura de dados tem seu primeiro elemento
armazenado na posição (índice) zero.
Exemplo: Suponha a necessidade de leitura e armazenamento das 5 alturas de atletas em um vetor.
int main(){
float alturas[5];
int indice;
for(indice=0;indice<5;indice++)
{ printf(“Informe a altura do %i atleta: “,indice+1);
scanf(“%f”,&alturas[indice]);
}
return 0;
}
Neste exemplo serão criadas somente duas variáveis, sendo uma denominada indice e a outra alturas que consistirá em um vetor
de 5 posições (índice de zero até quatro). Esse vetor possui um único identificador, mas tem a capacidade de armazenar até 5
valores reais, similar a criação das cinco variáveis (altura1, altura2, altura3, altura4, altura5) da proposta de solução anterior.
Suponha que o usuário digite os seguintes valores: 1.80, 2.03, 1.75, 2.20, 2.12. Uma representação gráfica do vetor seria:
Isso indica que a posição 3 do vetor possui como conteúdo o valor de 2.20. A terceira altura informada é 1.75 e está armazenada
no índice 2, que corresponde ao terceiro conteúdo armazenado nesse vetor.
5.1.2 Inicializando um vetor
Quando se declara um vetor, como no tópico anterior, não existe um valor pré-definido para seus elementos. Mas é possível
inicializar os elementos de um vetor no momento da declaração colocando os valores iniciais entre chaves {}. Por exemplo:
int foo [5] = { 16, 2, 77, 40, 12071 };
A instrução acima declara um vetor que pode ser representado da seguinte forma:
O número de valores entre chaves {} não deve ser maior do que o tamanho do vetor. Por exemplo, no exemplo acima, foo foi
declarado com 5 elementos (como indicado pelo número entre os colchetes), e as chaves continha exatamente 5 valores, um para
cada elemento. Se declarado com menos, os elementos restantes são definidos para seus valores padrão (para tipos numéricos
significa que são preenchidos com zeros). Por exemplo:
int bar [5] = { 10, 20, 30 };
Vai criar uma matriz como esta:
O inicializador pode até ter nenhum valor, apenas as chaves:
INÍCIO
alturas[5]
indice=0;indice<5;indice++
“Informe a altura do”,
indice+1, “atleta” alturas[indice] FIM
V F
int baz [5] = { };
Isto cria um vetor com capacidade de armazenar cinco valores do tipo inteiro, cada um inicializado com o valor zero:
Quando um vetor é inicializado, é possível deixar os colchetes vazio []. Nesse caso, o compilador assume automaticamente um
tamanho para o vetor que coincide com o número de valores compreendidos entre as chaves {}:
int foo [] = { 16, 2, 77, 40, 12071 };
Após esta declaração o vetor foo teria tamanho 5 uma vez que temos 5 valores de inicialização.
5.1.3 Acessando os valores de um vetor
Os valores de qualquer um dos elementos de um vetor podem ser acessados de forma semelhante à de uma variável regular do
mesmo tipo. A sintaxe é:
nome_do_vetor[indice]
Seguindo os exemplos anteriores nos quais o vetor foo tinha 5 elementos e cada um dos elementos era do tipo int , o nome que
deve ser usado para se referir a cada elemento é o seguinte:
Por exemplo, a seguinte instrução armazena o valor 75 no terceiro elemento de foo:
foo [2] = 75;
e, por exemplo, a seguinte copia o valor do terceiro elemento de foo para uma variável chamada x :
x = foo[2];
Portanto, a expressão foo[2] é em si uma variável do tipo int.
Note que o terceiro elemento de foo é especificado foo[2], uma vez que o primeiro é foo[0], o segundo é foo[1], e, por
conseguinte, o terceiro é foo[2]. Por esta mesma razão, o seu último elemento é foo[4]. Portanto, se utilizar foo[5], estaria
acessando o sexto elemento de foo , e, portanto, excedendo o tamanho da matriz.
Em C exceder o intervalo válido do índice de um vetor não gera um erro de sintaxe. Isso pode criar problemas, uma vez que o
acesso a elementos fora da faixa do vetor não causa erros de compilação, mas pode causar erros em tempo de execução.
Neste ponto, é importante ser capaz de distinguir claramente entre os dois usos dos colchetes [] relacionados com vetores. Eles
executam duas tarefas diferentes: uma é para especificar o tamanho dos vetores que tenham sido declarados; e a segunda é
especificaros índices para os elementos do vetor quando eles são acessados. Não confunda esses dois usos possíveis de colchetes
[] com vetores.
int foo[5]; // declaração de um novo vetor. O número entre colchetes define o tamanho do vetor
foo[2] = 75; // acesso a um elemento do vetor. O número entre colchetes define a posição onde o valor 75 será armazenado.
A principal diferença é que a declaração é precedida pelo tipo dos elementos que o vetor irá armazenar, enquanto o acesso não é.
Algumas outras operações válidas com vetores:
foo[0] = a; foo[a] = 75; b = foo [a+2]; foo[foo[a]] = foo[2] + 5;
Exercícios Propostos:
1. Faça um programa que leia um vetor de números inteiros N[20]. A seguir, encontre o menor elemento do vetor N e a sua
posição dentro do vetor, mostrando: “O menor elemento de N é ..., e sua posição dentro do vetor é:...”.
2. Faça um programa que, usando vetor, armazene as idades de quarenta alunos e exiba na tela a média de idade, a maior
idade e a menor idade desses alunos.
3. Faça um programa que leia 10 números inteiros do teclado e os armazene num vetor. Depois, percorrer esse vetor
mostrando os números ímpares.
4. Dados os vetores A={7,5,11,4,17,8} e B={4,6,2,3,7,5}, faça um programa que subtraia o vetor B de A e armazene o
resultado em um vetor C (C[i] = A[i] – B[i]) e depois exiba o conteúdo do vetor C na tela.
5. Faça um programa que leia 20 números inteiros, e os armazene em um vetor, e um valor inteiro x, e exiba a
quantidade de vezes que x aparece nesse vetor.
Leitura Recomendada
Livro da disciplina: Ricardo Sonaglio; Albano, Silvie Guedes. Programação em Linguagem C. 3ª ed. Rio de Janeiro: Editora
Ciência Moderna, 2010. 410p. Seção 5.1 – Vetores.
http://www.cprogressivo.net/p/vetores-em-linguagem-c.html
http://www.mtm.ufsc.br/~azeredo/cursoC/aulas/c510.html
5.2 Estruturas Multidimensionais (Matriz)
Estruturas multidimensionais podem ser descritas como "matrizes". Por exemplo, uma matriz bidimensional pode ser visualizada
como uma tabela bidimensional feita de elementos, todos eles de um mesmo tipo de dados uniforme.
jimmy representa uma matriz bidimensional de 3 por 5 elementos do tipo int . Para criar essa matriz a sintaxe utilizada é:
int jimmy [3][5];
Por exemplo, a forma de fazer referência ao segundo elemento verticalmente (linha) e o quarto horizontalmente (coluna) a
expressão seria:
jimmy[1][3]
Lembre-se que os índices sempre começam com zero.
Matrizes multidimensionais não estão limitadas a dois índices (ou seja, duas dimensões). Elas podem conter tantos índices
conforme necessário. Segue abaixo um exemplo de código que utiliza uma matriz bidimensional.
int main(){
int jimmy[3][5];
int linha,coluna;
for(linha=0;linha<3;linha++)
{ for(coluna=0;coluna<5;coluna++)
jimmy[linha][coluna]=(linha+1)*(coluna+1);
}
return 0;}
INÍCIO
jimmy[3][5]
linha=0;linha<3;linha++
FIM
V F
coluna=0;coluna<5;coluna++
F
jimmy[linha][coluna]=(linha+1)*(coluna+1)
V
O código acima não produz nenhuma saída na tela, mas atribui valores para a matriz jimmy da seguinte maneira:
Exercícios Propostos:
1. Faça um programa que receba 16 números inteiros e os armazene em uma matriz 4x4, e depois exiba o conteúdo dessa
matriz.
2. Faça um programa que receba 5 apostas da Quina e as exiba na tela. Dica: Usar uma matriz [5 apostas][5 números].
3. Faça um programa que receba os valores para uma matriz inteira 2x4, gere e exiba na tela uma matriz transposta (4x2).
Uma matriz transposta é gerada trocando a linha pela coluna.
4. Faça um programa que some as matrizes abaixo e armazene o resultado em uma matriz C.
9 4 4 7
A = 7 5 B= 5 8
6 2 2 1
5. Faça um programa que calcule o produto das matrizes A e B, do exercício 4, e armazene o resultado em uma matriz C.
Leitura Recomendada
Livro da disciplina: Ricardo Sonaglio; Albano, Silvie Guedes. Programação em Linguagem C. 3ª ed. Rio de Janeiro: Editora
Ciência Moderna, 2010. 410p. Seção 5.2 – Matrizes.
http://www.cprogressivo.net/2013/03/Vetores-multidimensionais-Matrizes-em-C--vetor-de-vetores.html
http://www.mtm.ufsc.br/~azeredo/cursoC/aulas/c530.html#c531.html
5.3 Vetor de Caracteres - String
Palavras e textos são formados por uma cadeia de caracteres (letras, caracteres especiais e até dígitos numéricos). Em C para
armazenar essa cadeia de caracteres é utilizada uma estrutura de dados homogênea do tipo caractere (char). Na área de informática
é atribuída a expressão String a essa cadeia de caracteres.
Sintaxe: char nome_do_vetor[tamanho_do_vetor];
O exemplo a seguir declara um vetor de caracteres chamado palavra e que possui a capacidade de armazenar até 14 caracteres,
pois é reservada uma posição do vetor para armazenar o caractere null (‘\0’) que sinaliza o fim da cadeia de caracteres.
Ex: char palavra[15];
Considerando que foi armazenado o texto “Linguagem C” uma representação gráfica desse vetor seria:
conteúdo
índice
É importante observar que o espaço também é um caractere e ocupa uma posição do vetor. O caractere null (‘\0’) é
automaticamente inserido após o término da String.
5.3.1 Inicializando Strings
Considerando que vetores de caracteres (Strings) são vetores comuns este seguem as mesmas regras dos vetores numéricos. Por
exemplo, para inicializar um array de caracteres com uma sequência predeterminada de caracteres, podemos fazê-lo como
qualquer outro vetor:
char palavra[] = { 'H' , 'e' , 'l' , 'l' , 'o' , '\0' };
L i n g u a g e m C \0
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
A instrução anterior declara um vetor de 6 elementos do tipo char inicializado com os caracteres que formam a palavra "Hello"
mais um caractere nulo '\0' no final.
Também é possível inicializar usando sequências de caracteres entre aspas (“). Neste caso o caractere nulo (\0) é anexado
automaticamente ao final da sequência. Portanto, o conjunto de elementos de char chamado palavra pode ser inicializado com
uma sequência terminada com o caractere nulo por qualquer uma das instruções abaixo:
char palavra[] = { 'H' , 'e' , 'l' , 'l' , 'o' , '\0' };
char palavra[] = "Hello" ;
Por favor, note que aqui estamos inicializando um vetor de caracteres no momento em que está sendo declarado, e não sobre a
atribuição de valores realizados mais tarde (uma vez que eles já tenham sido declarados). Dessa forma, as seguintes expressões
não são válidas:
myword = "Bye" ;
myword[] = "Bye" ;
myword = { 'B' , 'y' , 'e' , '\0' };
Observe, porém, que cada um dos seus elementos pode ser atribuído um valor individualmente. Por exemplo, isso seria correto:
myword[0] = 'B' ; myword[1] = 'y' ; myword[2] = 'e' ; myword[3] = '\0' ;
5.3.2 Acessando uma String
As operações mais comuns com uma String é armazenar um conteúdo digitado pelo usuário e exibir o conteúdo de uma String na
tela. No caso do scanf e printf será utilizado o especificador de conversão (vide guia II parte2) %s. Por exemplo:
scanf(“%s”,palavra); // Irá armazenar a sequência digitada pelo usuário. Note que não é utilizado o &.
printf(“%s”,palavra); Exibe a String armazenada no vetor palavra.
O comando scanf é genérico e serve tanto para valores numéricos quanto para caracteres. Essa característica apresenta uma
desvantagem no caso de Strings que é a impossibilidade de ler Strings que possuam o caractere espaço. Por exemplo, se o usuário
digitar a palavra “Engenharia FAENG” o scanf irá armazenar apenas “Engenharia” no vetor e descartar o restante.
Para solucionar esse problema é utilizado um comando mais específico que é o gets() que vem de get string. A sintaxe é:
gets(nome_da_string); Ex: gets(palavra);
Também existe o comando puts() que vem de put string. Esse comando é menos utilizado,pois o printf não possui a restrição do
caractere espaço e é mais flexível para a formatação da saída a ser exibida. A sintaxe é:
puts(nome_da_string); Ex: puts(palavra);
Exemplo de código:
int main(void)
{ char nome[31], sobrenome[31], nascimento[11];
int idade;
printf("Nome: ");
gets(nome);
printf("Sobrenome: ");
gets(sobrenome);
printf("Idade: ");
scanf("%d", &idade);
fflush(stdin); //utilizado para limpar o buffer do teclado
printf("Data de nascimento: ");
gets(nascimento);
printf("\nNome completo: %s %s\n", nome, sobrenome);
printf("Idade: %d\n", idade);
printf("Data de nascimento: "); puts(nascimento);
return 0;}
5.3.3 Funções para manipulação de String
A linguagem C possui a biblioteca string.h que disponibiliza uma série de funções para a manipulação de Strings. Dentre essas
funções destacam-se as seguintes:
strlen
Sua sintaxe é: strlen (string);
A função strlen() retorna o comprimento da String fornecida. O terminador nulo (\0) não é contado. Um exemplo do seu uso:
#include <stdio.h>
#include <string.h> //Carrega a biblioteca string.h
int main ()
{
int size;
char str[100];
printf ("Entre com uma string: ");
gets (str);
size=strlen (str);
printf ("\n\nA string que voce digitou tem tamanho %i",size);
return(0);
}
strcpy
Sua sintaxe é: strcpy (string_destino,string_origem);
A função strcpy() copia a String-origem para a String-destino. A seguir um exemplo de uso da função strcpy():
#include <stdio.h>
#include <string.h>
int main ()
{
char str1[100],str2[100],str3[100];
printf ("Entre com uma string: ");
gets (str1);
strcpy (str2,str1); // Copia str1 em str2
strcpy (str3,"Voce digitou a string "); // Copia "Voce digitou a string" em str3
printf ("\n\n%s%s",str3,str2);
return(0);
}
Exercícios Propostos:
1. Faça um programa que leia duas strings (A e B) e mostre uma terceira string (C) formada pelos caracteres contidos em A
e B de forma intercalada. Exemplo: Se A=”quarta” e B=”segunda”, a resposta obtida deverá ser “qsueagrutnada”.
2. Faça um programa que pede ao usuário: (i) Uma string s, (ii) Um caractere ch1, (iii) Um caractere ch2. O programa deve
substituir todas as ocorrências do caractere ch1 em s pelo caractere ch2.
3. Faça um programa que recebe uma data (numérica), dividida em dias, meses e anos e exibe na tela a mesma data, mas
com o mês por extenso. Por exemplo, para 14 04 2012 exibe 14 de abril de 2012. Dica: usar uma matriz que armazene os
nomes dos meses.
4. Faça um programa que recebe uma frase de até 50 caracteres (utilizar o comando gets) e exiba a frase sem os espaços em
branco. Exibir também a quantidade de espaços em branco da frase.
Leitura Recomendada
Livro da disciplina: Ricardo Sonaglio; Albano, Silvie Guedes. Programação em Linguagem C. 3ª ed. Rio de Janeiro: Editora
Ciência Moderna, 2010. 410p. Capítulo 6 - MANIPULANDO STRINGS.
http://www.cprogressivo.net/p/strings-e-caracteres-em-c.html
http://www.mtm.ufsc.br/~azeredo/cursoC/aulas/c520.html