domingo, 3 de janeiro de 2010

Funções x Vetores. Parte Final (código)

Agora que já vimos os conceitos e como funciona a alocação dinâmica, estamos prontos para ver um código exemplo. Então vamos a ele.


#include <stdio.h>
#include <stdlib.h>
 
int ler_int(){
  int digitado;
 
 printf("Digite um valor inteiro: ");
 scanf("%d",&digitado);
 return digitado;
}
 
void mostra_int(int num){
 printf("%d ",num);
}
 
void exibe_vetor(int* vet, int tamanho){
 int i;
 
 printf("\n");
 for(i = 0; i < tamanho; i++)
    mostra_int(vet[i]);
 printf("\n\n");
}
 
int* preenche_vet_int(int tamanho){
 int *vet=0, i;
 
 vet = (int *) malloc (tamanho * sizeof(int));
 if (vet){
    printf("\nPREENCHENDO O VETOR:\n");
    for(i = 0; i < tamanho; i++)
       vet[i] = ler_int();
 }
 return vet;
}
 
int aumenta_vet_int(int* vet, int* tamanho, int incremento){
 int novo_tam, i;
 
 novo_tam = *tamanho + incremento;
 vet = (int *) realloc (vet, novo_tam * sizeof(int));
 if (vet){
    printf("\nPREENCHENDO OS NOVOS ITENS DO VETOR:\n");
    for(i = *tamanho; i < novo_tam; i++)
       vet[i] = ler_int();
    *tamanho = novo_tam;
    return 1;
 }
 else{
    printf("NAO FOI POSSIVEL AUMENTAR O VETOR!\n");
    return 0;
 }
}
 
int diminui_vet_int(int* vet, int* tamanho, int decremento){
 int novo_tam, i;
 
 novo_tam = *tamanho - decremento;
 if (novo_tam <= 0){
    printf("DECREMENTO INFORMADO INVALIDO!!! NAO FOI POSSIVEL DIMINUIR O VETOR!\n");
    return 0;
 }
 vet = (int *) realloc (vet, novo_tam * sizeof(int));
 if (vet){
    *tamanho = novo_tam;
    return 1;
 }
 else{
    printf("NAO FOI POSSIVEL DIMINUIR O VETOR!\n");
    return 0;
 }
}
 
int main(){
 int *vetor, tamanho, incremento, decremento;
 
 printf("Digite o tamanho do vetor:\n");
 tamanho = ler_int();
 vetor = preenche_vet_int(tamanho);
 if (vetor){
    exibe_vetor(vetor, tamanho);
    printf("Digite o quanto deseja aumentar o vetor:\n");
    incremento = ler_int();
    if (aumenta_vet_int(vetor, &tamanho, incremento))
       exibe_vetor(vetor, tamanho);
    printf("Digite o quanto deseja diminuir o vetor:\n");
    decremento = ler_int();
    if (diminui_vet_int(vetor, &tamanho, decremento))
       exibe_vetor(vetor, tamanho);
    free(vetor);
 }
 else
    printf("NAO FOI POSSIVEL ALOCAR O VETOR!\n");
 system("pause");
}


Depois do que já vimos nos post anteriores, este código ficou muito simples.
Algumas funções já são conhecidas nossas. E dentre as novas funções existe pouca coisa que ainda não foi dita.
A primeira função nova está na linha 25, e é a razão desta sequência de posts. É uma função que retorna um vetor. Um detalhe interessante dela é que damos ao usuário a liberdade de definir o tamanho deste vetor. Seu funcionamento é simples.
Declaramos um ponteiro para inteiros vet e o inicializamos com o valor 0. Este ponteiro irá armazenar o endereço do vetor que será alocado dinamicamente.
Fazemos uma chamada a função malloc com o tamanho definido pelo usuário, e atribuimos o seu retorno ao ponteiro vet.
Se a chamada teve sucesso e o vetor foi alocado, imediatamente vamos preenchê-lo.
Observe o uso do if sem nenhum operador relacional. Na verdade ele verifica o valor de vet. Por isso o inicializamos com 0. Se a função malloc falhou, o valor de vet ainda será 0 (se funcionar perfeitamente, malloc nunca retorna um endereço 0). Este if verifica se o valor de vet é diferente de 0 (cuidado com isto: por diferente entenda qualquer outro valor, inclusive negativo). Este uso do if é muito comum, e passaremos a usá-lo, sempre que possível, daqui pra frente, como pode ser visto nas linhas 84 e 88, onde ele avalia o valor retornado pelas funções que aumentam e diminuem o tamanho do vetor, respectivamente.
A segunda nova função, na linha 37, aumenta o tamanho do vetor com um valor também definido pelo usuário, usando a função realloc. Observe que usando um ponteiro para a variável tamanho, podemos alterar o seu valor dentro da própria função.
A última função nova, na linha 55, diminui o tamanho do vetor de forma semelhante à função que o aumenta, usando a função realloc com um valor definido pelo usuário. A diferença entre elas é a verificação da validade do valor informado pelo usuário, evitando um erro ao tentar alterar o tamanho do vetor para 0 ou um valor negativo.
Observe que na linha 90, já na função main, desalocamos o bloco de memória usado pelo vetor. Isto é muito importante, se não este espaço ficará 'ocupado' mesmo após o término do programa.

Com isto encerramos a nossa série sobre funções que retornam vetores e como isto é possível utilizando a alocação dinâmica.
Alguma dúvida?

Nenhum comentário:

Postar um comentário