4
respostas

[Dúvida] Tamanho do array difente quando chamado em uma função

Alguém pode me explicar o porque o tamanho do array 'numeros' muda quando ele é usado como parametro dentro da função 'soma(arg1)'``?

#include <stdio.h>

int soma(int arg1[])
{
    printf("%d %d \n", &arg1[0], arg1);
    printf("%d \n", &arg1[1]);
    printf("%d \n", &arg1[2]);
    printf("%d \n", &arg1[3]);
    printf("%d \n", &arg1[4]);

    int reg1 = sizeof(arg1);
    printf("Tamanho: %d \n",reg1 );
}

void main()
{
    int numeros[] = {1,2,3,4,5};

    printf("%d %d \n", &numeros[0], numeros);
    printf("%d \n", &numeros[1]);
    printf("%d \n", &numeros[2]);
    printf("%d \n", &numeros[3]);
    printf("%d \n", &numeros[4]);
    
    int reg1 = sizeof(numeros);
    printf("Tamanho: %d \n",reg1 );

    soma(numeros);
}

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

4 respostas

Olá. Tudo certo?

Oque acontece é que quando você faz isso

int reg1 = sizeof(numeros); 

está recebendo o valor 20 que significa 20 bytes, pois você tem 5 inteiros que geralmente tem 4 bytes cada um.

Já quando você passa um array para uma função em C, ele decai para um ponteiro para o primeiro elemento do array. Dentro da função soma, arg1 é, na verdade, um ponteiro para um inteiro. Portanto, quando você usa sizeof(arg1), está obtendo o tamanho do ponteiro para um inteiro, que é 4 bytes.

Adicione isso ao seu código no main:

int tamanho = sizeof(numeros) / sizeof(numeros[0]);
printf("Tamanho array: %d \n", tamanho);

Aqui você pega a quantidade de bytes geral e divide por 4 bytes, obtendo assim o tamanho real do array que é de 5 números inteiros no seu caso.

Fala Cristiano, belezinha my friend?

Então cara, na main eu consigo pegar o tamanho do array, mas eu estva querendo passar está responsabilidade para a função soma, de maneira a generalizar a soma dos valores de vetores de qualquer tamanho.

Acha que dá pra passar a responsabilidade de saber o tamaho do vetor apenas para a função soma, ou pelo fato que você expos dela apenas pegar o ponteiro do vetor 'numeros' e não todos os seus valores, isso seria impossível?

Até onde eu sei essa informação do tamanho é perdida quando você passa o array pra soma, ele vai apontar para o ponteiro.

O melhor seria você passar o tamanho como argumento para a função soma e tratar a informação lá...

Olá Pedro!

Na linguagem C, quando vc passa um vetor por parâmetro, na verdade vc está passando, de maneira implícita, um ponteiro para aquele vetor (passar um vetor por cópia pode reduzir muito o desempenho, então a linguagem faz isso para ter otimização).

Por se tratar de um ponteiro, não há como saber ao certo o tamanho do elemento que ele está apontando, ou seja, infelizmente não há como obter, em C, o tamanho de um elemento (array) dentro de uma função, sendo necessário passar o tamanho desse elemento por parâmetro na chamada da função.

#include <stdio.h>

int soma(int arg[], size_t size)
{
    int soma = 0;
    
    for(int i = 0; i < size; ++i)
    { soma += arg[i]; }
    
    return soma;
}


int main()
{
    int numeros[] = {1,2,3,4,5};
    
    //posso determinar o tamanho de um array de maneira genérica,
    //dividindo o tamanho total do array pelo do seu primeiro elemento
    int tam_numeros = sizeof(numeros) / sizeof(numeros[0]);
    
    printf("a soma do array eh: %d\n", soma(numeros,tam_numeros));
    
    return 0;
}

Essa seria a solução. Em C++ vc consegue passar o array por referência, ou seja, vc não passa um ponteiro, mas sim o endereço de memória do array para a função, assim vc consegue, mesmo dentro de uma função, determinar o tamanho de um array, além disso, pode-se utilizar a sobrecarga de função para ter varias funções "soma()" para diferentes tipos ou utilizar os "templates" ( que "gera" essa sobrecarga de função de maneira "automática"), para receber tipos genéricos por parâmetro e retornar tbm esses tipos.

Veja um código de C++ fazendo o mesmo, mas de uma maneira mais versátil:

#include <iostream>

//com template a função recebe array de todos os tipos (int, float, ...)
template <typename T, size_t S>
T soma(T (&arg)[S]) //recebe uma referência de memória
{
    T soma = 0;
    
    //eh calculado o tamanho dentro da função "soma()"
    size_t size = sizeof(arg) / sizeof(arg[0]);
    
    for(int i = 0; i < size; ++i)
    {
      soma += arg[i];
    }
    
    return soma;
}

int main()
{
    int numeros[] = {1,2,3,4,5};

    //eh passado apenas o array, sem o seu tamanho!
    std::cout << soma(numeros) << std::endl;
    
    return 0;
}

espero ter ajudado! se sim, não esqueça de marcar esse post como solução!

Bons estudos irmão.