Baixe o app para aproveitar ainda mais
Esta é uma pré-visualização de arquivo. Entre para ver o arquivo original
Resumo Vetor: ****************************************************************************** OBS: Essa matéria cai na P2 e P3! ****************************************************************************** - Definição: Toda variável que declaramos possui um endereço, como se fosse uma "casinha" na memória. Vetor é simplesmente um conjunto de variáveis, ou seja, um conjunto de "casinhas" que armazena variáveis do mesmo tipo. (int, float, etc). OBS: Cada vetor só pode armazenar >> UM ÚNICO << tipo! Ou seja, um vetor pode ser todo de int ou todo de float, mas nunca de ambos! ------------------------------------//---------------------------------------- - Como declarar um vetor? Após decidir qual será o seu tipo: Ex: int valores[10]; float medias[5]; Sempre que declarar um vetor precisa ser nessa ordem: O tipo, nome do vetor e a quantidade de posições (casinhas) entre colchetes. Esse número [10] representa a quantidade total de posições do vetor, são 10 posições, mas é contando >> A PARTIR << do zero! Ou seja, só podemos acessar as "casinhas" da posição 0 até 9! A posição 10 é totalmente inválida! Isso é um erro comum e fatal em toda P2 e P3! OBS: Nos parâmetros da função é o >>ÚNICO<< lugar onde podemos omitir a quantidade de posições! Ex: float calcula_media (float valores[], int n); Mas quando declaramos o vetor não tem escapatória! É obrigatório especificar a quantidade de posições do vetor entre colchetes! Ex: float valores[10]; Declarando um vetor do tipo Float com 10 posições (De 0 até 9!) -------------------------------------//------------------------------------ - Como se envia um vetor como parâmetro? int notas[10]; preenche_notas(notas, 10); Exatamente da mesmo forma como enviamos uma variável comum! Wait...além do vetor, eu enviei como parâmetro o número 10 também! Pq será? :O ***************************************************************************** Regra importante: >> TODO vetor é sempre acompanhado pela sua quantidade de posições!!! << Então >>SEMPRE<< que enviamos um vetor como parâmetro pra qualquer função, também precisamos enviar a sua quantidade de posições! Mas por que isso? Porque quase tudo que envolve manipulação de vetor envolve sua quantidade de posições! ***************************************************************************** EX: Uma função que lê e armazena no vetor as notas de cada aluno: void preenche_vetor (int notas[], int n){ int i; for(i=0;i<n;i++){ puts("Digite a nota:\n"); scanf("%d", ¬as[i]); } } int main (void){ int notas[10]; preenche_vetor (notas, 10); return 0; } Vamos por partes: Precisamos armazenar a nota de cada aluno em cada posição do vetor. Pra fazer isso temos que passar por todas as posições (casinhas) do vetor, certo? :) É por isso que usamos a repetição for (Repetição Determinada/Finita), ou seja, a cada repetição, será armazenada a nota de um aluno. Mas como se trata de uma repetição finita...Qual será a condição desse for? Ele vai repetir até quando? for(i=0;i<n;i++) É exatamente nessa parte que precisamos da quantidade de posições do vetor! pois o for vai começar da posição 0 até a 9. Lembrando que são 10 posições no total, começando de zero! E NÃO podemos acessar a posição 10 em diante! ------------------------------------//---------------------------------------- - Função que recebe vetor como parâmetro: void preenche_vetor (int notas[], int n); Percebeu que deixei os colchetes em branco? :) **************************************************************************** Regra importantíssima: O protótipo de uma função é o >>>ÚNICO<<< lugar onde podemos omitir a quantidade de posições do vetor! Escrever >> int notas[] << é exatamente o mesmo que >> int *notas << Porque na verdade o que estamos passando como parâmetro >>NÃO<< é uma cópia do vetor e >>SIM<< um ponteiro que "aponta" pro começo do vetor! Ou seja, a primeira posição! notas[0] É por isso que podemos omitir a quantidade de posições, mas >>SOMENTE<< nos parâmetros da função! **************************************************************************** OBS: Não sabe o que é ponteiro? Ainda não foi dado em aula? Foi dado em aula, mas nem sabe do que se trata? Sem problemas! :D Recomendo que leia urgentemente meu "Resumo_Ponteiro"! :) ------------------------------------//---------------------------------------- Agora vamos analisar a repetição for: for(i=0;i<n;i++){ puts("Digite a nota:\n"); scanf("%d",¬as[i]); } O i começa valendo zero e o 'for' vai repetir enquanto o i for menor que n! A variável 'n' sempre representa a quantidade de posições do vetor! No exemplo acima, 'n' vale 10. OBS: Assim como a letra 'i' é sempre usada como contador nas repetições, a letra 'n' é sempre usada pra representar a quantidade de posições de qualquer vetor. scanf("%d",¬as[i]); Como nessa repetição o i começa valendo zero, a primeira leitura feita pelo scanf irá armazenar o valor digitado em notas[0] e a última irá armazenar em notas[9]. (Passando por cada uma das posições na ordem!) -------------------------------------//--------------------------------------- - Quando e como inicializar um vetor? Sempre que precisar usar um vetor como um contador. Por exemplo: Somar ou subtrair algo nele. Levando em conta que no momento em que declaramos uma variável, antes de inicializar com algum valor, ela possui lixo de memória e >>NÃO<< podemos acessar seu conteúdo e nem fazer contas com lixo de memória! Esse é outro erro comum e fatal em P2/P3! X.X Então pra evitar esse tipo de problema, temos que passar por todas as posições do vetor, inicializando cada posição com o valor zero. Esse é o protótipo da função inicializa vetor: void inicializa_vetor (int v[], int n){ int i; for(i=0;i<n;i++){ v[i] = 0; } } 'v' é um nome genérico de vetor , 'n' é a quantidade total de posições. E temos que usar a repetição pra passar por cada posição, atribuindo o valor zero. Essa função é sempre cobrada! Em praticamente todas as questões que envolvem vetores. 300% de chance de cair na P2 e na P3! Resumindo: Decore urgentemente a função acima! :D -----------------------------------//---------------------------------------- - Quando usar vetor? SOMENTE quando temos um número >> Exato ou de "Até no Máximo" << da quantidade de algo (Alunos, turmas, notas, etc) e sempre quando for um conjunto de valores! Então esse número irá representar a quantidade de posições do vetor. Se NÃO for o caso, NÃO use vetor! Use uma variável comum para armazenar tal informação. Ex: O enunciado diz que o arquivo VOTOS.txt armazena o resultado dos votos e contém o código do candidato e tipo de voto em cada linha. Como o enunciado não disse a quantidade de votos, é exatamente nesse caso que >> NÃO << podemos criar um vetor pra armazenar os votos, pois não sabemos quantos são! -----------------------------------//---------------------------------------- - Como utilizar macros em vetores? Primeiro passo é descobrir no enunciado o que vai ser um vetor. De acordo com a explicação acima de quando usar vetor. Se for realmente um vetor, vamos ter um número exato ou de "até no máximo" de alguma quantidade, certo? :) Ex: O enunciado diz que uma turma tem >>No Máximo<< 20 alunos e cada um vai digitar sua nota. Ao invés de criar um vetor dessa forma: int notas[20]; Vamos criar um define lá no começo do programa (perto do #include <stdio.h>) pra criar um "atalho": #include <stdio.h> #define MAX 20 MAX >>NÃO<< é uma variável! É na verdade uma Macro, ou seja, uma palavra que quando usamos no programa é substituída pelo valor 20. OBS: Existe uma convenção que recomenda sempre usar palavras maiúsculas nas Macros, justamente pra evitar confundir Macro com variável comum. A única mudança é que vamos escrever assim na declaração do vetor: int notas[MAX]; Dessa forma, quando o programa for executado, ele vai automaticamente interpretar a palavra MAX como o valor 20. OBS: Se vc colocar o ponteiro do mouse em cima da palavra MAX por alguns segundos (Visual Studio), ele vai mostrar o valor 20. -----------------------------------//---------------------------------------- - Mas qual a vantagem disso? Imagina um programa que vc precise criar uma vetor e chamar várias funções. (enviando sempre como parâmetro o vetor e sua quantidade de posições!) Sem usar o #define MAX 20: #include <stdio.h> int main(void){ int dados[20]; inicializa_vetor(dados,20); preenche_vetor(dados,20); compara_valores(dados,20); imprime_resultado(dados,20); return 0; } Agora imagina se o enunciado muda para 30 notas, vc teria que fazer 5 alterações no programa né? E isso pq é um programa com poucas linhas, imagina esse número 20 se repetindo umas 300 vezes, ia ser muito triste né? =x Usando o #define MAX 20: #include <stdio.h> #define MAX 20 int main(void){ int dados[MAX]; inicializa_vetor(dados,MAX); preenche_vetor(dados,MAX); compara_valores(dados,MAX); imprime_resultado(dados,MAX); return 0; } Dessa vez, se caso o enunciado for alterado pra 30 notas, é só colocar: #define MAX 30 É só alterar o #define no começo do programa e essa mudança será feita no programa inteiro! OBS: As duas formas estão totalmente certas! Mas eu recomendo que vc use sempre o #define pra deixar o programa mais organizado e prático pra alterações. ------------------------------------//--------------------------------------- - Quando e como fazer busca em vetores? Sempre que já temos um vetor inicializado (Preenchido com valores) e precisamos buscar um valor, verificar se um determinado valor pertence a esse vetor e descobrir em qual posição o valor está armazenado. Esse é o protótipo da função busca: int busca (int v[], int n, int chave){ int i; for(i=0;i<n;i++){ if(v[i] == chave){ return i; } } return -1; } 'v' é um nome genérico de vetor, 'n' é a quantidade de posições e chave é o valor que queremos procurar no vetor. Bom, pra "variar" um pouco, precisamos usar uma repetição 'for' pra passar por todas as posições do vetor. Notou que esse 'for' é usado em quase tudo? :) A condição 'if' verifica se alguma posição do vetor possui valor igual a chave (valor que queremos achar), se for igual, retorna o 'i' que representa a posição do vetor onde a chave foi encontrada. E se após passar pelo vetor todo e não encontrar, a função busca retorna -1, ou seja, o -1 quer dizer que >>NÃO<< foi encontrado a chave em nenhuma posição do vetor! Resumindo: Sempre que precisamos passar por todas as posições de um vetor, inicializar um vetor, fazer busca em vetores, preencher um vetor com dados lidos. >>SEMPRE<< use essa mesma repetição 'for'! Por isso que eu recomendo usar sempre a letra 'n' pra representar o tamanho do vetor em todos os casos, justamente pra facilitar! OBS: Se o vetor é do tipo Float, obrigatoriamente a chave também será float! Pois só podemos procurar por valores do tipo float num vetor que é do tipo float! O protótipo seria: int busca (float v[], int n, float chave); OBS: Essa função cai em >>TODAS<< as P2 e P3! Sempre tem no mínimo uma função busca! Sim! Essa é outra função que eu recomendo que vc decore urgentemente! :D -----------------------------------//------------------------------------------ - Como fazer busca em vetores ordenados? Ex: Um vetor ordenado de forma crescente por matrícula e queremos procurar por exemplo a matrícula de número 100: O protótipo da função continua sendo exatamente o mesmo! Temos um vetor, a sua quantidade de posições e uma variável chamada 'chave' que armazena o que queremos buscar no vetor, no caso, a matrícula 100. int busca (int v[], int n, int chave){ int i; for(i=0;i<n;i++){ if(v[i] == chave){ return i; } else if(v[i] > chave){ return -1; } } return -1; } Percebeu que só precisamos acrescentar mais uma condição? :) else if(v[i] > chave){ return -1; } Como se trata de um vetor ordenado de forma crescente, se v[i] vale 105 por exemplo, faz sentido continuar a busca? Não! Pois como o vetor está ordenado por matrícula, daí em diante só vamos encontrar matrículas maiores que 100! Por isso retornamos -1 pra encerrar a busca! Ou seja, a matrícula 100 não foi encontrada no vetor! OBS: Se o vetor estiver ordenado de forma decrescente, é só usar o símbolo de menor na segunda condição! else if(v[i] < chave) --------------------------------------//--------------------------------------- - Ajuste de Índice: EX: Faça uma função que leia do teclado o preço e o código de cada produto (Código 1 até 10) e armazena o preço num vetor recebido como parâmetro. Primeiro vamos analisar: São quantos produtos no total? Levando em conta que cada produto possui um código que varia entre 1 e 10. São 10 produtos diferentes! E já sabemos que vamos precisar usar uma repetição 'for' onde o 'n' representa a quantidade de produtos! void preenche_vetor (float dados[], int n){ int i, cod; for(i=0;i<n;i++){ puts("Codigo: "); scanf("%d", &cod); puts("Preco: "); scanf("%f", &dados[cod-1]); } } WAIT! De onde surgiu esse dados[cod-1]!? :o Lembra que o índice de >>Qualquer<< vetor começa sempre do zero? :) O código do produto representa o índice em que precisamos armazenar o preço correspondente. Mas >> Não << podemos armazenar direto! Pois o código do primeiro produto >> NÃO << corresponde ao começo do vetor! Então se queremos armazenar o preço do primeiro produto (Código 1) na primeira posição do vetor (Posição zero), precisamos fazer um ajuste nesse índice que varia de acordo com o enunciado! Nesse caso o código do primeiro produto é 1, então basta diminuir >> 1 << pra ajustar o índice pro começo do vetor! OBS: A forma mais tranquila de fazer ajuste em índice é justamente pensando no caso mais simples de todos, ou seja, ajustar o índice do primeiro produto! Pois daí em diante, qualquer outro código já será ajustado da forma correta! EX2: E se o código variasse de 40 até 59? O que muda na função? Antes de tudo precisamos saber quantos produtos são: OBS: Ihh, agora as contas estão ficando mais complexas! Bem que podia ter um pré requisito de Cálculo 2 né? :D 59 - 40 = 19 Mas como precisamos contar >> A partir << do código 40, ele também precisa ser considerado! 19 + 1 = 20 (20 códigos no total!) Agora só falta ajustar o índice: Novamente, vamos pensar no caso mais simples: Se o código do primeiro produto é 40, é só diminuir 40 pra ajustar o índice pro começo do vetor! :) void preenche_vetor (float dados[], int n){ int i, cod; for(i=0;i<n;i++){ puts("Codigo: "); scanf("%d", &cod); puts("Preco: "); scanf("%f", &dados[cod-40]); } } OBS: Esse tipo de questão com ajuste de índice é certeza absoluta total de cair na P2! --------------------------------------//--------------------------------------- - Notação alternativa de vetor: (Aritmética de ponteiro) Existem duas formas de manipular vetores. (acessar o contéudo e o endereço) A forma mais conhecida e usada é através da indexação: Onde usamos colchetes e o número que está dentro representa a posição que será acessada. EX: Declarando um vetor: int notas[10]; OBS: Independente da notação, todo vetor é declarado dessa forma! A notação alternativa é baseada em aritmética de ponteiro. Lembra que o nome do vetor na verdade é um ponteiro que "aponta" pra sua primeira posição? :) OBS: Tudo que fizemos até então foi usando indexação! ******************************************************************************* Regra Importante: - Como acessar o endereço de cada posição? int notas[10]; >> notas << representa o endereço do começo do vetor, ou seja, endereço da primeira posição. Então >> notas + 1 << representa o endereço da segunda posição! E assim por diante! - Como acessar o conteúdo de cada posição? Como já sabemos que >> notas << é o endereço do começo do vetor, ou seja, um ponteiro! Como fazemos pra acessar conteúdo de um ponteiro? Usamos o >> * << antes do nome do ponteiro pra acessar o seu conteúdo! EX: *notas E como notas é um ponteiro que aponta pro começo do vetor (Posição zero), então *notas representa o conteúdo da primeira posição do vetor! E pra acessar o conteúdo da segunda posição? Lembrando que (notas + 1) representa o endereço! Mesmo esquema! Só usar >> *(notas + 1) << e assim por diante! :) ******************************************************************************** - Usando indexação: Leitura: scanf("%d", ¬as[i]); Exibindo conteúdo: printf("Nota: %d ", notas[i]); - Usando aritmética de ponteiro: Leitura: scanf("%d", (notas + i)); Exibindo conteúdo: printf("Nota: %d ", *(notas + i)); OBS: (notas + i) representa o endereço da posição atual! *(notas + i) representa o conteúdo da posição atual! OBS: Recomendo usar sempre indexação por ser uma forma mais intuitiva e simples, mas alguns professores exigem o uso da notação alternativa! Então antes de decorar qualquer coisa, confirme isso antes com o seu professor! :) ----------------------------------//-------------------------------------------
Compartilhar