Encontrando comprimento de array dentro de uma function

No programa abaixo o comprimento da matriz ar está correto no principal, mas em temp mostra o comprimento do ponteiro para ar que no meu computador é 2 (em unidades de sizeof(int) ).

 #include  void temp(int ar[]) // this could also be declared as `int *ar` { printf("%d\n", (int) sizeof(ar)/sizeof(int)); } int main(void) { int ar[]={1,2,3}; printf("%d\n", (int) sizeof(ar)/sizeof(int)); temp(ar); return 0; } 

Eu queria saber como definir a function para que o comprimento da matriz seja lido corretamente na function.

Não existe uma maneira ’embutida’ para determinar o comprimento dentro da function. No entanto você passa arr , sizeof(arr) sempre retornará o tamanho do ponteiro. Portanto, a melhor maneira é passar o número de elementos como um argumento separado. Alternativamente, você poderia ter um valor especial como 0 ou -1 que indica o final (como é \0 em seqüências de caracteres, que são apenas char [] ). Mas, claro, o tamanho do array ‘lógico’ era sizeof(arr)/sizeof(int) - 1

Como outros disseram que a solução óbvia é passar o comprimento da matriz como parâmetro, também é possível armazenar esse valor no início da matriz

 #include  void temp(int *ar) { printf("%d\n", ar[-1]); } int main(void) { int ar[]= {0, 1, 2, 3}; ar[0] = sizeof(ar) / sizeof(ar[0]) - 1; printf("%d\n", ar[0]); temp(ar + 1); return 0; } 

Não use uma function, use uma macro para isso:

 //Adapted from K&R, p.135 of edition 2. #define arrayLength(array) (sizeof((array))/sizeof((array)[0])) int main(void) { int ar[]={1,2,3}; printf("%d\n", arrayLength(ar)); return 0; } 

Você ainda não pode usar essa macro dentro de uma function como sua temp onde a matriz é passada como um parâmetro pelas razões que outros mencionaram.

Alternativa se você quiser passar um tipo de dados ao redor é definir um tipo que tenha uma matriz e capacidade:

 typedef struct { int *values; int capacity; } intArray; void temp(intArray array) { printf("%d\n", array.capacity); } int main(void) { int ar[]= {1, 2, 3}; intArray arr; arr.values = ar; arr.capacity = arrayLength(ar); temp(arr); return 0; } 

Isso leva mais tempo para configurar, mas é útil se você se encontrar passando muitas funções.

Quando você escreve size(ar) então você está passando um ponteiro e não uma matriz .

O tamanho de um ponteiro e um int é 4 ou 8 – dependendo da ABI (Ou, como @ H2CO3 mencionado – algo completamente diferente), então você está obtendo sizeof(int *)/sizeof int ( sizeof(int *)/sizeof int = 1 para 32 -bit máquinas e 8/4 = 2 para máquinas de 64 bits), que é 1 ou 2 (ou .. algo diferente).

Lembre-se, em C quando passar uma matriz como um argumento para uma function, você está passando um ponteiro para uma matriz.
Se você quiser passar o tamanho da matriz, você deve passá-lo como um argumento separado.

Eu não acho que você poderia fazer isso usando uma function. Ele sempre retornará o comprimento do ponteiro em vez do comprimento de toda a matriz.

Dentro da function ar é um ponteiro para que o operador sizeof retorne o comprimento de um ponteiro. A única maneira de calculá-lo é torná-lo global e ou alterar seu nome. A maneira mais fácil de determinar o tamanho é size (array_name) / (size_of (int). A outra coisa que você pode fazer é passar este cálculo para a function.

Você precisa envolver a matriz em uma estrutura:

 #include struct foo {int arr[5];}; struct bar {double arr[10];}; void temp(struct foo f, struct bar g) { printf("%d\n",(sizeof f.arr)/(sizeof f.arr[0])); printf("%d\n",(sizeof g.arr)/(sizeof g.arr[0])); } void main(void) { struct foo tmp1 = {{1,2,3,4,5}}; struct bar tmp2; temp(tmp1,tmp2); return; } 

10 de março de 2018 Revisão :

O código do OP chama temp () e passa um ponteiro para os dados do tipo int através do nome da matriz que, por padrão, pertence a arr [0] . O argumento formal de temp () indica um ponteiro para dados do tipo int com notação de matriz indicando que o ponteiro está relacionado a um elemento em uma matriz.

Por geeksforgeeks :

parameters de matriz [são] tratados como pointers por causa da eficiência.

Outro artigo no geeksforgeeks explica que usar sizeof com um ponteiro significa o número de bytes necessários para o tipo de dados, e não o comprimento do array. O artigo recomenda passar um parâmetro adicional: o tamanho real da matriz. Nesse sentido, criei uma constante codificando esse valor, como mostra o exemplo a seguir:

  #define ARR_SIZE 3 #include  void temp(int arr[], size_t arr_size) { int i; puts ("In temp:"); for (i = 0; i < = arr_size - 1; i++) { printf(" %d",arr[i]); } puts("\nExiting temp...\n"); } int main(void) { int ar[ARR_SIZE]={1,2,3}; int i=0; temp(ar,ARR_SIZE); puts("In main():"); for(i = 0; i < sizeof(ar)/sizeof(ar[i]); i++) printf(" %d ", ar[i]); return 0; } 

Veja demo

Uma alternativa melhor envolve passar o tamanho do array sem codificar esse valor. @weston oferece uma excelente sugestão no que diz respeito à codificação de uma macro de function para determinar o tamanho de uma matriz. Enquanto você não pode usar a macro dentro do corpo da function temp (), você pode utilizar a macro para passar os dados para temp (), da seguinte maneira:

 #define array_len(array) sizeof(array)/sizeof(array[0]) #include  void temp(int arr[], size_t arr_size) { int i; printf("\nArray size is: %d\nValues are:\n", (int) arr_size); for (i = 0; i < = arr_size - 1; i++) { printf(" %d",arr[i]); } } int main(void) { int ar[]={1,2,3}; int i=0; temp( ar, array_len(ar) ); return 0; } 

Veja o código ao vivo

Discussão relacionada interessante e boa leitura sobre macros aqui .