web-dev-qa-db-fra.com

Trouver la longueur d'un tableau dans une fonction

Dans le programme ci-dessous, la longueur du tableau ar est correcte dans main mais dans temp, elle indique la longueur du pointeur sur ar qui sur mon ordinateur vaut 2 (en unités de sizeof(int)). 

#include <stdio.h>

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;
}

Je voulais savoir comment définir la fonction pour que la longueur du tableau soit lue correctement dans la fonction.

13
makhlaghi

Il n'y a pas de méthode intégrée pour déterminer la longueur à l'intérieur de la fonction. Cependant, si vous passez arr, sizeof(arr) retournera toujours la taille du pointeur. Le meilleur moyen est donc de passer le nombre d'éléments sous forme d'argument séparé. Alternativement, vous pourriez avoir une valeur spéciale telle que 0 ou -1 qui indique la fin (comme c'est \0 dans les chaînes, qui sont juste char []). Mais bien sûr, la taille du tableau 'logique' était sizeof(arr)/sizeof(int) - 1 

16
Ingo Leonhardt

Comme d'autres l'ont dit, la solution évidente consiste à définir la longueur d'un tableau en tant que paramètre. Vous pouvez également stocker cette valeur au début du tableau.

#include <stdio.h>

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;
}
9
Keine Lust

N'utilisez pas de fonction, utilisez une macro pour cela:

//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;
}

Vous ne pouvez toujours pas utiliser cette macro dans une fonction telle que votre temp où le tableau est passé en tant que paramètre pour les raisons que d'autres ont mentionnées.

Si vous souhaitez transmettre un type de données, vous pouvez également définir un type comportant à la fois un tableau et une capacité:

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;
}

Cela prend plus de temps à mettre en place, mais est utile si vous vous sentez en train de le faire tourner autour de beaucoup de fonctions.

6
weston

Lorsque vous écrivez size(ar), vous passez un pointeur et et non un tableau

La taille d'un pointeur et d'un int est de 4 ou 8 - selonABI(ou, comme @ H2CO3 l'a mentionné - quelque chose de complètement différent), vous obtenez donc sizeof(int *)/sizeof int (4/4 = 1 pour Machines 32 bits et 8/4 = 2 pour les machines 64 bits), ce qui correspond à 1 ou 2 (ou .. quelque chose de différent).

N'oubliez pas qu'en C, lorsque vous transmettez un tableau en tant qu'argument à une fonction, vous transmettez un pointeur à un tableau.
Si vous souhaitez transmettre la taille du tableau, vous devez le transmettre en tant qu'argument séparé.

4
Maroun

Je ne pense pas que vous puissiez faire cela en utilisant une fonction. Il retournera toujours la longueur du pointeur plutôt que la longueur de l'ensemble du tableau.

1
user2560622

À l'intérieur de la fonction ar se trouve un pointeur. L'opérateur sizeof renvoie la longueur d'un pointeur. La seule façon de le calculer est de rendre ar global et/ou de changer son nom. Le moyen le plus simple de déterminer la longueur est size (nom_ array)/(size_of (int). Vous pouvez également transmettre ce calcul à la fonction.

0
ojblass

Vous devez envelopper le tableau dans une structure:

#include<stdio.h>

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;
}
0
Greg Buchholz