Question Comment puis-je déterminer la taille de mon tableau en C?


Comment puis-je déterminer la taille de mon tableau en C?

C'est-à-dire, le nombre d'éléments que le tableau peut contenir?


718
2017-09-01 06:49


origine


Réponses:


Résumé:

int a[17];
size_t n = sizeof(a)/sizeof(a[0]);

Pour déterminer la taille de votre tableau en octets, vous pouvez utiliser le sizeof opérateur:

int a[17];
size_t n = sizeof(a);

Sur mon ordinateur, les ints ont une longueur de 4 octets, donc n est 68.

Pour déterminer le nombre d'éléments dans le tableau, nous pouvons diviser la taille totale du tableau par la taille de l'élément de tableau. Vous pourriez le faire avec le type, comme ceci:

int a[17];
size_t n = sizeof(a) / sizeof(int);

et obtenir la bonne réponse (68/4 = 17), mais si le type de a changé vous auriez un méchant bug si vous avez oublié de changer la sizeof(int) ainsi que.

Donc, le diviseur préféré est sizeof(a[0]), la taille de la zeroeth élément du tableau.

int a[17];
size_t n = sizeof(a) / sizeof(a[0]);

Un autre avantage est que vous pouvez maintenant facilement paramétrer le nom du tableau dans une macro et obtenir:

#define NELEMS(x)  (sizeof(x) / sizeof((x)[0]))

int a[17];
size_t n = NELEMS(a);

909
2017-09-01 06:49



le sizeof façon est la bonne façon sff vous avez affaire à des tableaux non reçus en tant que paramètres. Un tableau envoyé en paramètre à une fonction est traité comme un pointeur, donc sizeof retournera la taille du pointeur, au lieu de celle du tableau.

Ainsi, à l'intérieur des fonctions, cette méthode ne fonctionne pas. Au lieu de cela, passez toujours un paramètre supplémentaire size_t size indiquant le nombre d'éléments dans le tableau.

Tester:

#include <stdio.h>
#include <stdlib.h>

void printSizeOf(int intArray[]);
void printLength(int intArray[]);

int main(int argc, char* argv[])
{
    int array[] = { 0, 1, 2, 3, 4, 5, 6 };

    printf("sizeof of array: %d\n", (int) sizeof(array));
    printSizeOf(array);

    printf("Length of array: %d\n", (int)( sizeof(array) / sizeof(array[0]) ));
    printLength(array);
}

void printSizeOf(int intArray[])
{
    printf("sizeof of parameter: %d\n", (int) sizeof(intArray));
}

void printLength(int intArray[])
{
    printf("Length of parameter: %d\n", (int)( sizeof(intArray) / sizeof(intArray[0]) ));
}

Sortie (dans un système d'exploitation Linux 64 bits):

sizeof of array: 28
sizeof of parameter: 8
Length of array: 7
Length of parameter: 2

Sortie (dans un système d'exploitation Windows 32 bits):

sizeof of array: 28
sizeof of parameter: 4
Length of array: 7
Length of parameter: 1

612
2018-04-27 11:14



Il est à noter que sizeof n'aide pas quand il s'agit d'une valeur de tableau qui est tombée en pointeur: même si elle pointe vers le début d'un tableau, elle est identique au pointeur vers un seul élément de ce tableau. Un pointeur ne "mémorise" rien d'autre sur le tableau qui a été utilisé pour l'initialiser.

int a[10];
int* p = a;

assert(sizeof(a) / sizeof(a[0]) == 10);
assert(sizeof(p) == sizeof(int*));
assert(sizeof(*p) == sizeof(int));

103
2017-09-01 06:55



La taille de "truc" est la meilleure façon que je connais, avec un petit mais (pour moi, ce qui est une bête noire) un changement important dans l'utilisation de la parenthèse.

Comme l'indique l'article de Wikipédia, C sizeof n'est pas une fonction; c'est un opérateur. Ainsi, il ne nécessite pas de parenthèse autour de son argument, sauf si l'argument est un nom de type. Cela est facile à retenir, car cela fait ressembler l'argument à une expression cast, qui utilise également des parenthèses.

Donc: Si vous avez ce qui suit:

int myArray[10];

Vous pouvez trouver le nombre d'éléments avec du code comme ceci:

size_t n = sizeof myArray / sizeof *myArray;

Cela, pour moi, lit beaucoup plus facile que l'alternative avec des parenthèses. Je suis également favorable à l'utilisation de l'astérisque dans la partie droite de la division, car elle est plus concise que l'indexation.

Bien sûr, tout ceci est également à la compilation, il n'y a donc pas lieu de s'inquiéter de la répartition qui affecte la performance du programme. Alors utilisez ce formulaire partout où vous le pouvez.

Il est toujours préférable d'utiliser sizeof sur un objet réel quand vous en avez un, plutôt que sur un type, puisque vous n'avez pas besoin de vous soucier de faire une erreur et d'indiquer le mauvais type.

Par exemple, supposons que vous ayez une fonction qui génère des données sous la forme d'un flux d'octets, par exemple sur un réseau. Appelons la fonction send(), et lui faire prendre comme arguments un pointeur vers l'objet à envoyer, et le nombre d'octets dans l'objet. Ainsi, le prototype devient:

void send(const void *object, size_t size);

Et puis vous devez envoyer un entier, donc vous le codez comme ceci:

int foo = 4711;
send(&foo, sizeof (int));

Maintenant, vous avez introduit une manière subtile de vous tirer dans le pied, en spécifiant le type de foo à deux endroits. Si l'un change et l'autre non, le code se casse. Ainsi, faites-le toujours comme ceci:

send(&foo, sizeof foo);

Maintenant vous êtes protégé. Bien sûr, vous dupliquez le nom de la variable, mais il y a une forte probabilité de rupture d'une manière que le compilateur peut détecter, si vous le changez.


35
2017-10-15 10:11



int size = (&arr)[1] - arr;

Check-out ce lien pour l'explication


31
2017-12-07 22:43



Vous pouvez utiliser l'opérateur sizeof mais cela ne fonctionnera pas pour les fonctions car il prendra la référence du pointeur vous pouvez faire ce qui suit pour trouver la longueur d'un tableau:

len = sizeof(arr)/sizeof(arr[0])

Code trouvé à l'origine ici: C programme pour trouver le nombre d'éléments dans un tableau


20
2018-05-27 12:56



Si vous connaissez le type de données du tableau, vous pouvez utiliser quelque chose comme:

int arr[] = {23, 12, 423, 43, 21, 43, 65, 76, 22};

int noofele = sizeof(arr)/sizeof(int);

Ou si vous ne connaissez pas le type de données du tableau, vous pouvez utiliser quelque chose comme:

noofele = sizeof(arr)/sizeof(arr[0]);

Note: Cette chose ne fonctionne que si le tableau n'est pas défini lors de l'exécution (comme malloc) et que le tableau n'est pas passé dans une fonction. Dans les deux cas, arr (nom du tableau) est un pointeur.


18
2018-01-18 19:30



La macro ARRAYELEMENTCOUNT(x) que tout le monde utilise évalue incorrectement. Ceci, de manière réaliste, est juste une question sensible, parce que vous ne pouvez pas avoir des expressions qui aboutissent à un type 'array'.

/* Compile as: CL /P "macro.c" */
# define ARRAYELEMENTCOUNT(x) (sizeof (x) / sizeof (x[0]))

ARRAYELEMENTCOUNT(p + 1);

Réellement évalue comme:

(sizeof (p + 1) / sizeof (p + 1[0]));

Tandis que

/* Compile as: CL /P "macro.c" */
# define ARRAYELEMENTCOUNT(x) (sizeof (x) / sizeof (x)[0])

ARRAYELEMENTCOUNT(p + 1);

Il évalue correctement à:

(sizeof (p + 1) / sizeof (p + 1)[0]);

Cela n'a vraiment pas grand chose à voir avec la taille des tableaux explicitement. Je viens de remarquer beaucoup d'erreurs en n'observant pas vraiment le fonctionnement du préprocesseur C. Vous enveloppez toujours le paramètre macro, pas une expression dans pourrait être impliqué dans.


C'est correct; mon exemple était mauvais. Mais c'est exactement ce qui devrait arriver. Comme je l'ai mentionné précédemment p + 1 finira comme un type de pointeur et invalidera la macro entière (comme si vous essayiez d'utiliser la macro dans une fonction avec un paramètre pointeur).

À la fin de la journée, dans ce particulier par exemple, la faute n'a pas vraiment d'importance (donc je perds tout le temps, huzzah!), parce que vous n'avez pas d'expressions avec un type de 'tableau'. Mais je pense que le point sur les subtilités de l'évaluation du préprocesseur est important.


14
2018-02-28 01:49