lÓgica de programaÇÃo linguagem c. caracterÍsticas na linguagem c, o vetor possui um número n...
TRANSCRIPT
LÓGICA DE PROGRAMAÇÃO Linguagem C
Computação Depressão
O Portal do Estudante de Computação
www.facebook.com/ComputacaoDepressaowww.ComputacaoDepressao.com.br
CARACTERÍSTICAS Na linguagem C, o vetor possui um número N de posições, porém ao declararmos, acessamos seus índices que começam em 0 e vão até N-1. Ou seja, a linguagem C tem a característica “0 a N-1” nos seus vetores.
int idades[10]; //10 índices
int idades[35]; //35 índices
DECLARAÇÃO int idade; int idades[10]; //10 índices char letra; char letras[26]; //26 índices ou uma string de 26 (ou 25) posições char nome[30]; //string de 30 (ou 29) posições char nomes[50][30]; //50 índices de strings de 30 (ou 29) posições float notas; float notas[30]; //30 índices
Toda STRING é um vetor de CHAR!
PREENCHIMENTO É possível preencher um vetor índice a índice, como se fossem variáveis isoladas. Assim como é possível utilizar uma estrutura de repetição para auxiliar o preenchimento do vetor.
int main() { int idades[10]; idades[0] = 18; idades[1] = 25; ⋮ idades[9] = 33;
PREENCHIMENTO int main() { int idades[10]; printf(“Digite a idade:”); scanf(“%d”, &idades[0]); printf(“Digite a idade:”); scanf(“%d”, &idades[1]); ⋮ printf(“Digite a idade:”); scanf(“%d”, &idades[9]);
PREENCHIMENTO Se declararmos um vetor, não será possível inserir um dado nele como se fosse uma variável! Por exemplo: int main() { int idades[10];
idades = 18;
E também não será possível inserir um valor num índice fora da faixa de índices do vetor! Por exemplo:
idades[15] = 34;
PREENCHIMENTO int main() { int idades[10], contador; for(contador = 0; contador < 10; contador++) { printf(“Digite a idade:”); scanf(“%d”, &idades[contador]); }
PREENCHIMENTO int main() { int idades[10];
Na memória do computador teremos algo mais ou menos assim:Nome:
idades
Índice:
0 1 2 3 4 5 6 7 8 9
Valor:
PREENCHIMENTO Digamos que, após uma rotina para preencher os valores baseada em estrutura de repetição, esses valores foram inseridos nos índices do vetor:
Nome:
idades
Índice:
0 1 2 3 4 5 6 7 8 9
Valor: 18 25 54 34 2 95 81 42 108
33
LEITURA Para lermos e/ou exibirmos os valores em cada índice do vetor, usamos basicamente os mesmos conceitos vistos no preenchimento do vetor.
Digamos que o vetor foi devidamente declarado e preenchido. Podemos ler os valores deles indicando o índice diretamente ou usando uma estrutura de repetição para vários índices.
printf(“%d”, idades[0]);
printf(“%d”, idades[1]);
⋮
printf(“%d”, idades[9]);
LEITURA int main() { int idades[10], contador; for(contador = 0; contador < 10; contador++) { printf(“%d\n”, idades[contador]); }
LEITURA Podemos realizar operações matemáticas (caso o tipo de dado seja numérico) dos valores do vetor! Por exemplo, calcular a média das idades: int main() { int contador, soma = 0, idades[10]; float media; for(contador = 0; contador < 10; contador++) { soma += idades[contador]; } media = (soma / 10); printf(“Média das idades: %0.2f”, media);
LEITURA Assim como os índices podem se tornar elementos de operações condicionais. Por exemplo, mostrar todos os números pares no vetor: int main() { int contador, idades[10]; for(contador = 0; contador < 10; contador++) { if((idades[contador] % 2) == 0) { printf(“%d é par\n”, idades[contador]); } }
PESQUISA SEQUENCIAL E se quisermos pesquisar algo num vetor? Para nos certificarmos se algo está lá ou não? Afinal, já que podemos percorrer um vetor para preenchê-lo/lê-lo, por que não para indicar se algo existe lá?
Temos alguns tipos de pesquisa que podem ser feitas, e abordaremos a pesquisa linear (ou sequencial), e será exibida resumidamente a pesquisa binária.
Como procuramos nossas coisas em nossa casa? Primeiro pensamos nos lugares que elas podem estar e depois procuramos nos lugares até achá-las.
No vetor é basicamente a mesma coisa: temos os lugares que elas podem estar (os índices) e procuramos até encontrar um dado.
PESQUISA SEQUENCIAL int main() { int contador, item, idades[10], achou = 0; for(contador = 0; contador < 10; contador++) { if(idades[contador] == item) { achou = 1; } } if(achou) { printf(“Seu item está presente no vetor”); } else { printf(“Seu item não está presente no vetor”); }
PESQUISA SEQUENCIAL Ele irá percorrer todo o vetor e irá trocar o valor da variável de “0” para “1” quando encontrar o valor que você deseja.
Problemas? Sim! Nesse caso o problema é de performance, visto que o vetor inteiro será percorrido em busca de itens iguais ao que você deseja. E após encontrar o item em algum índice, ele continuará percorrendo o vetor.
Que tal se pararmos a busca caso encontremos o item?
PESQUISA SEQUENCIAL int main() { int contador = 0, item, idades[10], achou = 0; while((contador < 10) && !achou) { if(idades[contador] == item) { achou = 1; } else { contador++; } } if(achou) { printf(“Seu item está presente no vetor”); } else { printf(“ Seu item não está presente no vetor”); }
PESQUISA SEQUENCIAL Resolvemos o problema! Agora ele só irá pesquisar no vetor inteiro na pior das hipóteses: quando o item que você quer encontrar estiver na última posição do vetor ou quando o item não existir no vetor. while((contador < 10) && !achou) { if(idades[contador] == item) { achou = true; } else { contador++; } } Mas em compensação, ele continuará buscando somente se ele não tiver chegado ao fim do vetor e se não tiver achado.
PESQUISA BINÁRIA Há também outros algoritmos com melhor performance do que o de pesquisa linear. Um deles é o de pesquisa binária.
Ele vai comparando as pontas e o meio do vetor, e dependendo do valor, ele vai “quebrando” na metade, e novamente comparando as pontas e o meio do vetor, para novamente “quebrá-lo” pela metade, e assim sucessivamente. Ele é um algoritmo que usa a técnica “dividir para conquistar”.
Como ele é um algoritmo mais avançado, não o veremos aqui no curso, mas será exibido representativamente.
Primeiramente devemos saber que para uma pesquisa binária ser feita, o vetor tem de estar ordenado.
PESQUISA BINÁRIA
ORDENAÇÃO Assim como podemos preencher, ler e pesquisar num vetor, podemos ordená-lo alfanumericamente.
Após uma rotina de ordenação, ele ficará assim:
Nome: idadesÍndice: 0 1 2 3 4 5 6 7 8 9Valor: 18 25 54 34 2 95 81 42 108 33
Nome: idadesÍndice: 0 1 2 3 4 5 6 7 8 9Valor: 2 18 25 33 34 42 54 81 95 108
ORDENAÇÃO Como ordenamos um vetor? Percorremos todos os itens, um a um, do começo ao fim. Cada item é comparado com os demais. Se há algum item nos demais que é menor que o que eu estou comparando, eu troco a posição desses dois itens, e então ele passa a estar mais para o começo do vetor.
Para esse exemplo, usaremos um vetor mais simples, com 5 índices:
E no final ele tem de ficar assim:
1 4 3 5 2
1 2 3 4 5
ORDENAÇÃO
Índice atual: 1.
Comparando 1 com 4, quem é menor? 1. Então continuam onde estão.
Comparando 1 com 3, quem é menor? 1. Então continuam onde estão.
Comparando 1 com 5, quem é menor? 1. Então continuam onde estão.
Comparando 1 com 2, quem é menor? 1. Então continuam onde estão.
1 4 3 5 2
ORDENAÇÃO
Índice atual: 2.
Comparando 4 com 3, quem é menor? 3. Então trocam de posições.
Comparando 3 com 5, quem é menor? 3. Então continuam onde estão.
Comparando 3 com 2, quem é menor? 2. Então trocam de posições.
1 4 3 5 2
1 3 4 5 2
1 2 4 5 3
ORDENAÇÃO
Índice atual: 3.
Comparando 4 com 5, quem é menor? 4. Então continuam onde estão.
Comparando 4 com 3, quem é menor? 3. Então trocam de posições.
1 2 4 5 3
1 2 3 5 4
ORDENAÇÃO
Índice atual: 4.
Comparando 5 com 4, quem é menor? 4. Então trocam de posições.
1 2 3 5 4
1 2 3 4 5
ORDENAÇÃO
Índice atual: 5.
Comparando 5 com... não tem mais o que comparar! Está ordenado!
Para o aprendizado, esse algoritmo é o mais simples para ser entendido e implementado. Há diversos outros algoritmos para ordenação de vetores e listas. Aí entramos em um assunto chamado “complexidade de algoritmos”, que visa testar e garantir resultados mais eficientes nos algoritmos de ordenação.
E para codificar esse algoritmo... será que é difícil? Não!
1 2 3 4 5
ORDENAÇÃO int main() { int a, b, temp, idades[10]; for(a = 0; a < 9; a++) { for(b = (a + 1); b < 10; b++) { if(idades[a] > idades[b]) { temp = idades[a]; idades[a] = idades[b]; idades[b] = temp; } } }
ORDENAÇÃO E se eu quisesse ordenar decrescentemente? Ou seja, se tenho:
Ficar assim:
Basta na verificação de quem é “menor”, alterar o símbolo para “maior”, ou seja, ele trocará de posição se o item a ser comparado for maior que o outro. Os itens maiores estarão no começo do vetor.
if(idades[a] > idades[b]) {
if(idades[a] < idades[b]) {
1 4 3 5 2
5 4 3 2 1
ORDENAÇÃO Este algoritmo de ordenação de vetores funciona com quase todos os tipos básicos vistos: int, float, e char.
No caso do char, como sabemos que uma letra é “menor” que a outra, para podermos ordená-los? Na tabela ASCII, as letras possuem um valor numérico, e a letra A vem antes dos restantes.
Mas e no caso das strings, ou vetores de char? Lembram que foi dito no início da aula que toda string é um vetor de char? Lembram que uma string, a ser declarada, ela sempre irá possuir um espaço a menos por causa do símbolo \0?
Então vamos para a 2ª parte da aula: vetores de caracteres.
FFLUSH(STDIN); int main() {
char letras[10];
int contador;
for(contador = 0; contador < 10; contador++) {
printf(“Digite um caractere:”);
scanf(“%c”, &letras[contador]);
}
FFLUSH(STDIN); Há um problema no preenchimento do vetor de caracteres. O <enter> é tido como um caractere, para o computador. Ou seja, ele irá armazenar o caractere no índice atual, o depois armazenar o <enter> (no caso, um caractere vazio) no próximo. Experimente!
Para resolver isso, usamos um procedimento chamado fflush(stdin);.
Ela limpa o buffer do teclado. Com isso aquele <enter> que normalmente fica armazenado no buffer some do buffer e não segue para a próxima instrução de leitura.
FFLUSH(STDIN); int main() {
char letras[10];
int contador;
for(contador = 0; contador < 10; contador++) {
printf(“Digite um caractere:”);
scanf(“%c”, &letras[contador]);
fflush(stdin);
}
FFLUSH(STDIN); int main() {
char a, b, c;
scanf("%c", &a);
scanf("%c", &b);
scanf("%c", &c);
printf("%c\n", a);
printf("%c\n", b);
printf("%c\n", c);
Ainda no exemplo do fflush(stdin);, se fizermos dessa forma, a variável “a” receberá um valor. A variável “b” automaticamente recebe o <enter>, e quando estamos achando que estamos preenchendo o valor da variável “b”, ele já está preenchendo a variável “c” com o valor digitado.
FFLUSH(STDIN); int main() {
char a, b, c;
scanf("%c", &a);
fflush(stdin);
scanf("%c", &b);
fflush(stdin);
scanf("%c", &c);
fflush(stdin);
printf("%c\n", a);
printf("%c\n", b);
printf("%c\n", c);
Colocando o fflush(stdin) após cada leitura do teclado para armazenar na variável, ela apaga o buffer do teclado, que armazenou o <enter>, e preencherá a próxima variável com o que for digitado.
\0 A “barra invertida zero”, ou “backslash zero”, é um caractere invisível, não-imprimível, que indica o fim de uma string.
char nome[15] = “computação”;
Isso é uma string, simplesmente por causa do \0 no final!
Nome:
nome
Índice:
0 1 2 3 4 5 6 7 8 9 10
11
12
13
14
Valor: c o m p u t a ç ã o \0
\0 char nome[15];
nome[0] = ‘c’; nome[1] = ‘o’; nome[2] = ‘m’; nome[3] = ‘p’;
nome[4] = ‘u’; nome[5] = ‘t’; nome[6] = ‘a’; nome[7] = ‘c’;
nome[8] = ‘a’; nome[9] = ‘o’;
Isso é um vetor de caracteres, por não ter o \0 no final!
Nome:
nome
Índice:
0 1 2 3 4 5 6 7 8 9 10
11
12
13
14
Valor: c o m p u t a ç ã o
\0 Para manipularmos strings, devemos importar uma biblioteca, como já vimos:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
E as funções para leitura e escrita:
scanf(“%s”, variável); gets(variável);
printf(“%s”, variável); puts(variável);
\0 Se eu imprimir o vetor dessa forma:
printf(“%s”, nome);
Será impresso isto:
Nome:
nome
Índice:
0 1 2 3 4 5 6 7 8 9 10
11
12
13
14
Valor: c o m p u t a ç ã o
\0 Porque não houve o delimitador \0 para finalizar a string. Ou seja, quando usamos o procedimento printf(), ele imprime o vetor, caractere a caractere, até encontrar o \0.
printf(“%s”, nome);
Será impresso isto:
Nome:
nome
Índice:
0 1 2 3 4 5 6 7 8 9 10
11
12
13
14
Valor: c o m p u t a ç ã o \0
VETORES DE STRING Como já foi dito, um vetor de strings é um vetor de vetor de caracteres. Futuramente veremos que um vetor de vetores é uma matriz, que inclusive é a nossa próxima aula.
char nomes[5][10];
Um vetor chamado “nomes”, com 5 índices, e em cada índice é possível armazenar 10 caracteres, ou strings de 9 caracteres (sempre lembrando que um está reservado para o \0).
PREENCHENDO VETORES DE STRINGS int main() {
char nomes[5][10];
int contador;
for(contador = 0; contador < 5; contador++) {
printf(“Digite o nome:”);
scanf(“%s”, nomes[contador]);
}
LENDO VETORES DE STRINGS int main() {
char nomes[5][10];
int contador;
for(contador = 0; contador < 5; contador++) {
printf(“%s”, nomes[contador]);
}
PESQUISANDO EM VETORES DE STRINGS int main() { int contador = 0, nomes[5][10], achou = 0; char item[10]; while((contador < 5) && !achou) { if(strcmp(nomes[contador], item) == 0) { achou = 1; } else { contador++; } } if(achou) { printf(“Seu item está presente no vetor”); } else { printf(“Seu item não está presente no vetor”); }
ORDENANDO VETORES DE STRINGS int main() { int, a, b; char nomes[10], temp[10]; for(a = 0; a < 4; a++) { for(b = (a + 1); b < 5; b++) { if(strcmp(nomes[a], nomes[b]) == 1) { strcpy(temp, nomes[a]); strcpy(nomes[a], nomes[b]); strcpy(nomes[b], temp); } } }