Ir ao conteúdo

Posts recomendados

Postado
Em 29/08/2019 às 19:40, mateusiniciante disse:

como alocar dinamicamente um vetor de números inteiros do tamanho fornecido como parâmetro ?

 

Olá!

 

pense em construir na ordem inversa do que está escrito no enunciado até chegar à resposta

 

Veja

  • tamanho fornecido como parâmetro: então falamos de uma função que aceita parâmetros. Pode até ser a função main() mas vamos pensar em outra e usar main() para testar a nossa função.
  • Um parâmetro deve ser o tamanho do vetor, um número inteiro. Deve ver positivo claro. E maior que zero,  claro.  E constante, claro. Não faria sentido mudar dentro da função esse valor. Então deveria ser algo como
unsigned int const tamanho

mas vamos deixar como int e testar no código mesmo.

 

Como alocar memória? malloc(n) onde n é o tamanho em bytes. malloc() reside normalmente em stdlib.h

 

Como saber o tamanho em bytes? usando sizeof() eu sei o tamanho de um int. Multiplicando pelo parâmetro tamanho eu sei quanto devo alocar. Então a funçao podia ser assim declarada:

int aloca_vetor_de_tamanho(int quantos){};

Só que alocar o espaço e não retornar quer dizer que não serve pra nada. E pior: não tem como liberar depois.

Como liberar? usando free() para o mesmo ponteiro que malloc() retornou. Então a função deve ser assim:

int* aloca_vetor_de_tamanho(int quantos){};

Aí sim. Estamos chegando em algo. Aloca o vetor e devolve o endereco para ser usado no programa. Podia ser testada em uma função main() assim:

int main(int arc, char** argv)
{
    int* p;
    p = aloca_vetor_de_tamanho(1);
    if (p == NULL)
    {
        printf("erro alocando p para 1 int\n");
        return -1;
    }
    printf("alocado p para 1 int sem problemas\n");
    free(p);    // libera esse um

    p = aloca_vetor_de_tamanho(10);
    if (p == NULL)
    {
        printf("erro alocando p para 10 int\n");
        return -1;
    }
    printf("alocado p para 10 int sem problemas\n");
    free(p);

    return 0;
}

que com sorte ia mostrar isso

um (int) ocupa 4 bytes
para alocar 1 deles preciso de 4 bytes
alocado p para 1 int sem problemas
um (int) ocupa 4 bytes
para alocar 10 deles preciso de 40 bytes
alocado p para 10 int sem problemas

Uma possível função seria 

int* aloca_vetor_de_tamanho(int quantos)
{
    unsigned const teste = 0;
    if (quantos < 1) return NULL;
    int tamanho = sizeof(int);
    printf("um (int) ocupa %d bytes\n", tamanho);
    tamanho = tamanho * quantos;
    printf("para alocar %d deles preciso de %d bytes\n", quantos, tamanho);
    // malloc() ja retorna NULL se nao conseguir alocar o espaco necessario
    return malloc(tamanho);
}

Uma versão mais normal da função seria

int* em_silencio_aloca_vetor_de_tamanho(int quantos)
{
    return malloc(quantos*sizeof(int));
}

e podia testar assim

    // agora com a função mais discreta
    printf("\n\nUsando a funcao sem mensagens\n");
    p = em_silencio_aloca_vetor_de_tamanho(1);
    if (p == NULL)
    {
        printf("erro alocando p para 1 int\n");
        return -1;
    }
    printf("alocado p para 1 int sem problemas\n");
    free(p);    // libera esse um

    p = em_silencio_aloca_vetor_de_tamanho(10);
    if (p == NULL)
    {
        printf("erro alocando p para 10 int\n");
        return -1;
    }
    printf("alocado p para 10 int sem problemas\n");
    free(p);

Note que você pode usar o ponteiro para acessar todos os int que alocou. E se tentar acessar além do espaco alocado seu programa deve cancelar com uma exceção for violação de acesso ou algo assim.

 

Exemplo:

int main(int arc, char** argv)
{
    int* p;
    printf("aloca 5 int\n");
    p = em_silencio_aloca_vetor_de_tamanho(5);
    if (p == NULL)
    {
        printf("erro alocando p para 5 int\n");
        return -1;
    }
    printf("alocado p para 5 int sem problemas\n");
    for (int i = 0; i<5; i++)
    {
        printf("vai fazer p[%d] = %d\n", i, i);
        p[i] = i;
        printf("acessando p[%d]: valor %d\n", i, p[i]);
    }    // end for 
    // exemplo
    p[4] = 3;
    p[2] = p[4];
    p[p[2]] = 5; 
    printf("Exemplos de atribuicoes\n");
    for (int i = 0; i < 5; i++)
    {
        printf("acessando p[%d]: valor %d\n", i, p[i]);
    }    // end for 
    return 0;
}

Mostra

aloca 5 int
alocado p para 5 int sem problemas
vai fazer p[0] = 0
acessando p[0]: valor 0
vai fazer p[1] = 1
acessando p[1]: valor 1
vai fazer p[2] = 2
acessando p[2]: valor 2
vai fazer p[3] = 3
acessando p[3]: valor 3
vai fazer p[4] = 4
acessando p[4]: valor 4
Exemplos de atribuicoes
acessando p[0]: valor 0
acessando p[1]: valor 1
acessando p[2]: valor 3
acessando p[3]: valor 5
acessando p[4]: valor 3

Recomendo ler esse código e o resultado até parecer natural. Esse é talvez o grande recurso de C.

 

 

  • Curtir 1
  • Obrigado 1
Postado

Note que em código de produção o mais comum é não usar colchetes e sim usar aritmética direto com os endereços

Exemplo:
    *(p+4) = 3;
    *(p+2) = *(p+4);
    *(p + *(p +2) ) = 5;
Ao invés de

    p[4] = 3;
    p[2] = p[4];
    p[p[2]] = 5; 
Como mesmo resultado, claro...

Exemplos de atribuicoes
acessando p[0]: valor 0
acessando p[1]: valor 1
acessando p[2]: valor 3
acessando p[3]: valor 5
acessando p[4]: valor 3
Exemplos de atribuicoes usando os enderecos
acessando p[0]: valor 0
acessando p[1]: valor 1
acessando p[2]: valor 3
acessando p[3]: valor 5
acessando p[4]: valor 3

Para esse programa

    // exemplo
    p[4] = 3;
    p[2] = p[4];
    p[p[2]] = 5; 
    printf("Exemplos de atribuicoes\n");
    for (int i = 0; i < 5; i++)
    {
        printf("acessando p[%d]: valor %d\n", i, p[i]);
        p[i] = i;
    }    // end for 

    *(p+4) = 3;
    *(p+2) = *(p+4);
    *(p + *(p +2) ) = 5;

    printf("Exemplos de atribuicoes usando os enderecos\n");
    for (int i = 0; i < 5; i++)
    {
        printf("acessando p[%d]: valor %d\n", i, p[i]);
        p[i] = 34;
    }    // end for 

 

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!