web-dev-qa-db-fra.com

Comment trouver la longueur d'un tableau?

Y a-t-il un moyen de trouver combien de valeurs un tableau a? Détecter si j'ai atteint ou non la fin d'un tableau fonctionnerait également.

440
Maxpm

Si vous voulez parler d'un tableau de style C, vous pouvez faire quelque chose comme:

int a[7];
std::cout << "Length of array = " << (sizeof(a)/sizeof(*a)) << std::endl;

Cela ne fonctionne pas sur les pointeurs, c’est-à-dire que ne fonctionnera pas dans les cas suivants:

int *p = new int[7];
std::cout << "Length of array = " << (sizeof(p)/sizeof(*p)) << std::endl;

ou:

void func(int *p)
{
    std::cout << "Length of array = " << (sizeof(p)/sizeof(*p)) << std::endl;
}

int a[7];
func(a);

En C++, si vous souhaitez ce type de comportement, vous devriez utiliser une classe de conteneur. probablement std::vector .

429

Comme d'autres l'ont dit, vous pouvez utiliser la fonction sizeof(arr)/sizeof(*arr), mais cela ne vous donnera pas la bonne réponse pour les types de pointeurs qui ne sont pas des tableaux.

template<class T, size_t N>
constexpr size_t size(T (&)[N]) { return N; }

Cela a la propriété Nice de ne pas compiler pour les types non array (visual studio a _countof qui le fait). Le constexpr en fait une expression lors de la compilation, de sorte qu'il ne présente aucun inconvénient par rapport à la macro (du moins aucune que je connaisse).

Vous pouvez également envisager d'utiliser std::array à partir de C++ 11, qui expose sa longueur sans surcharge sur un tableau C natif.

C++ 17 a std::size() dans l'en-tête <iterator> qui fait la même chose et fonctionne également pour les conteneurs STL (grâce à @Jon C ).

115
Motti

Faire sizeof( myArray ) vous donnera le nombre total d'octets alloués pour ce tableau. Vous pouvez ensuite trouver le nombre d'éléments dans le tableau en divisant par la taille d'un élément du tableau: sizeof( myArray[0] )

73
MahlerFive

Y a-t-il un moyen de trouver combien de valeurs un tableau a? 

Oui!

Essayez sizeof(array)/sizeof(array[0])

Détecter si j'ai atteint ou non la fin d'un tableau fonctionnerait également.

Je ne vois aucun moyen pour cela sauf si votre tableau est un tableau de caractères (c'est-à-dire une chaîne).

P.S: En C++, utilisez toujours std::vector. Il existe plusieurs fonctions intégrées et une fonctionnalité étendue.

49
Prasoon Saurav

Bien qu’il s’agisse d’une vieille question, il convient de mettre à jour la réponse à C++ 17. La bibliothèque standard contient maintenant la fonction std::size() , qui renvoie le nombre d’éléments contenus dans un conteneur std ou dans un tableau de style C. Par exemple:

#include <iterator>

uint32_t data[] = {10, 20, 30, 40};
auto dataSize = std::size(data);
// dataSize == 4
36
Jon C

std::vector a une méthode size() qui renvoie le nombre d'éléments dans le vecteur.

(Oui, c'est une réponse ironique)

25
eq-
#include <iostream>

int main ()
{
    using namespace std;
    int arr[] = {2, 7, 1, 111};
    auto array_length = end(arr) - begin(arr);
    cout << "Length of array: " << array_length << endl;
}
24
JukkaP

Depuis C++ 11, de nouveaux modèles sont introduits pour aider à réduire la douleur liée à la longueur d'un tableau. Tous sont définis dans l'en-tête <type_traits>

  • std::rank<T>::value

    Si T est un type de tableau, fournit la valeur constante du membre égale au nombre de dimensions du tableau. Pour tout autre type, la valeur est 0.

  • std::extent<T, N>::value

    Si T est un type de tableau, fournit la valeur constante du membre égale au nombre d'éléments le long de la dimension Nth du tableau, si N est dans [0, std::rank<T>::value). Pour tout autre type, ou si T est un tableau de inconnue liée le long de sa première dimension et que N est 0, la valeur est 0.

  • std::remove_extent<T>::type

    Si T est un tableau de type X, fournit le type de membre membre égal à X, sinon le type est T. Notez que si T est un tableau multidimensionnel, seule la première dimension est supprimée.

  • std::remove_all_extents<T>::type

    Si T est un tableau multidimensionnel de type X, fournit le type typedef du membre égal à X, sinon le type est T.

Pour obtenir la longueur de n'importe quelle dimension d'un tableau multidimensionnel, vous pouvez combiner decltype avec std::extent. Par exemple:

#include <iostream>
#include <type_traits> // std::remove_extent std::remove_all_extents std::rank std::extent

template<class T, size_t N>
constexpr size_t length(T(&)[N]) { return N; }

template<class T, size_t N>
constexpr size_t length2(T(&arr)[N]) { return sizeof(arr) / sizeof(*arr); }

int main()
{
    int a[5][4][3]{{{1,2,3}, {4,5,6}}, { }, {{7,8,9}}};

    // New way
    constexpr auto l1 = std::extent<decltype(a)>::value;     // 5
    constexpr auto l2 = std::extent<decltype(a), 1>::value;  // 4
    constexpr auto l3 = std::extent<decltype(a), 2>::value;  // 3
    constexpr auto l4 = std::extent<decltype(a), 3>::value;  // 0

    // Mixed way
    constexpr auto la = length(a);
    //constexpr auto lpa = length(*a);  // compile error
    //auto lpa = length(*a);  // get at runtime
    std::remove_extent<decltype(a)>::type pa;  // get at compile time
    //std::remove_reference<decltype(*a)>::type pa;  // same as above
    constexpr auto lpa = length(pa);
    std::cout << la << ' ' << lpa << '\n';

    // Old way
    constexpr auto la2 = sizeof(a) / sizeof(*a);
    constexpr auto lpa2 = sizeof(*a) / sizeof(**a);
    std::cout << la2 << ' ' << lpa2 << '\n';

    return 0;
}

BTY, pour obtenir le nombre total d'éléments dans un tableau multidimensionnel:

constexpr auto l = sizeof(a) / sizeof(std::remove_all_extents<decltype(a)>::type);

Ou mettez-le dans un modèle de fonction:

#include <iostream>
#include <type_traits>
    

template<class T>
constexpr size_t len(T &a)
{
    return sizeof(a) / sizeof(typename std::remove_all_extents<T>::type);
}

int main()
{
    int a[5][4][3]{{{1,2,3}, {4,5,6}}, { }, {{7,8,9}}};
    constexpr auto ttt = len(a);
    int i;
    std::cout << ttt << ' ' << len(i) << '\n';
    
    return 0;
}

Vous trouverez plus d’exemples sur la façon de les utiliser en suivant les liens.

21
Jaege

Il y a aussi le moyen TR1/C++ 11/C++ 17 (le voir Live on Colir):

const std::string s[3] = { "1"s, "2"s, "3"s };
constexpr auto n       = std::extent<   decltype(s) >::value; // From <type_traits>
constexpr auto n2      = std::extent_v< decltype(s) >;        // C++17 shorthand

const auto     a    = std::array{ "1"s, "2"s, "3"s };   // C++17 class template arg deduction -- http://en.cppreference.com/w/cpp/language/class_template_argument_deduction
constexpr auto size = std::Tuple_size_v< decltype(a) >;

std::cout << n << " " << n2 << " " << size << "\n"; // Prints 3 3 3
17
metal

Au lieu d'utiliser la fonction de tableau intégrée aka:

 int x[2] = {0,1,2};

vous devriez utiliser la classe array et le template de tableau. Essayer:

#include <array>
array<type_of_the_array, number_of_elements_in_the_array> Name_of_Array = {};

alors maintenant, si vous voulez trouver la longueur du tableau, il vous suffit d'utiliser la fonction size de la classe array.

Name_of_Array.size();

et cela devrait retourner la longueur des éléments dans le tableau.

9
Mr. Foots

En C++, en utilisant la classe std :: array pour déclarer un tableau, on peut facilement trouver la taille d'un tableau et le dernier élément.

#include<iostream>
#include<array>
int main()
{
    std::array<int,3> arr;

    //To find the size of the array
    std::cout<<arr.size()<<std::endl;

    //Accessing the last element
    auto it=arr.end();
    std::cout<<arr.back()<<"\t"<<arr[arr.size()-1]<<"\t"<<*(--it);

    return 0;
}

En fait, la classe array a beaucoup d'autres fonctions qui nous permettent d'utiliser array un conteneur standard.
Référence 1 à la classe std :: array C++
Référence 2 à std :: array class
Les exemples dans les références sont utiles.

6
Tarun Maganti

Pour C++/CX (lors de l'écriture, par exemple, d'applications UWP utilisant C++ dans Visual Studio), nous pouvons trouver le nombre de valeurs dans un tableau en utilisant simplement la fonction size().

Code source:

string myArray[] = { "Example1", "Example2", "Example3", "Example4" };
int size_of_array=size(myArray);

Si vous cout le size_of_array, le résultat sera:

>>> 4
3
Arslan Ahmad
 length = sizeof(array_name)/sizeof(int);
2
David Gladson

Voici une implémentation de ArraySize from Google Protobuf .

#define GOOGLE_ARRAYSIZE(a) \
  ((sizeof(a) / sizeof(*(a))) / static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))

// test codes...
char* ptr[] = { "you", "are", "here" };
int testarr[] = {1, 2, 3, 4};
cout << GOOGLE_ARRAYSIZE(testarr) << endl;
cout << GOOGLE_ARRAYSIZE(ptr) << endl;

ARRAYSIZE (arr) fonctionne en inspectant sizeof (arr) (le nombre d'octets dans Du tableau) et sizeof (* (arr)) (le nombre d'octets dans un élément array ,__). Si le premier est divisible par le second, peut-être que arr est en effet un tableau, auquel cas le résultat de la division est le # de éléments dans le tableau. Sinon, arr ne peut pas être un tableau, et nous générons une erreur de compilation pour empêcher le code de compilation.

Puisque la taille de bool est définie par l'implémentation, nous devons convertir ! (sizeof (a) & sizeof (* (a))) to size_t afin d'assurer la finale le résultat a le type size_t.

Cette macro n'est pas parfaite car elle accepte à tort certaines pointeurs, à savoir où la taille du pointeur est divisible par la pointee Taille. Puisque tout notre code doit passer par un compilateur 32 bits, où un pointeur est de 4 octets, cela signifie tous les pointeurs vers un type dont la taille est 3 ou plus grand que 4 sera (justement) rejeté.

2
zangw

Une bonne solution qui utilise des génériques:

template <typename T,unsigned S>
inline unsigned arraysize(const T (&v)[S]) { return S; }

Ensuite, appelez simplement arraysize(_Array); pour obtenir la longueur du tableau.

La source

1

Pour l'ancien compilateur g ++, vous pouvez le faire

template <class T, size_t N>
char (&helper(T (&)[N]))[N];

#define arraysize(array) (sizeof(helper(array)))

int main() {
    int a[10];
    std::cout << arraysize(a) << std::endl;
    return 0;
}
1
Scy

Je propose une solution délicate ici: 

Vous pouvez toujours stocker length dans le premier élément:

// malloc/new

arr[0] = length;
arr++;

// do anything. 
int len = *(arr-1);

free(--arr); 

Le coût est que vous devez --arr lorsque vous appelez free

1
陳 力

Évitez d'utiliser le type avec sizeof, comme sizeof(array)/sizeof(char), soudainement corrompu si vous modifiez le type du tableau.

Dans Visual Studio, vous avez l'équivalent de sizeof(array)/sizeof(*array). Vous pouvez simplement taper _countof(array).

0
Johan Jönsson

Je suggère personnellement (si vous êtes incapable de travailler avec des fonctions spécialisées pour une raison quelconque) d’étendre d’abord la compatibilité des types de tableaux au-delà de ce que vous utiliseriez normalement (si vous stockiez des valeurs ≥ 0:

unsigned int x[] -> int x[]

que vous ne rendriez le tableau 1 plus grand que ce dont vous avez besoin. Pour le dernier élément, vous devez mettre un type inclus dans le spécificateur de type développé, mais que vous n'utiliseriez pas normalement, par exemple. en utilisant l'exemple précédent, le dernier élément serait -1. Cela vous permet (en utilisant une boucle for) de trouver le dernier élément d'un tableau.

0
Raymond Iacobacci

vous pouvez trouver la longueur d'un tableau en suivant:

int  arr[] = {1, 2, 3, 4, 5, 6}; 
int size = *(&arr + 1) - arr; 
cout << "Number of elements in arr[] is "<< size; 
return 0;
0
Rezoanul Alam Riad

Vous pouvez simplement utiliser cet extrait:

#include <iostream>
#include <string>
#include <array>

using namespace std;

int main()
{

  array<int,3> values;
  cout << "No. elements in valuea array: " << values.size() << " elements." << endl;
  cout << "sizeof(myints): " << sizeof(values) << endl;

}

et voici la référence: http://www.cplusplus.com/reference/array/array/size/

0
Amado Saladino

Vous avez un tas d'options à utiliser pour obtenir une taille de tableau C.

int myArray [] = {0, 1, 2, 3, 4, 5, 7};

1) sizeof(<array>) / sizeof(<type>):

std::cout << "Size:" << sizeof(myArray) / sizeof(int) << std::endl;

2) sizeof(<array>) / sizeof(*<array>):

std::cout << "Size:" << sizeof(myArray) / sizeof(*myArray) << std::endl;

3) sizeof(<array>) / sizeof(<array>[<element>]):

std::cout << "Size:" << sizeof(myArray) / sizeof(myArray[0]) << std::endl;
0
Ito

Juste une pensée, mais vient de décider de créer une variable de compteur et de stocker la taille du tableau en position [0]. J'ai supprimé la plupart du code que j'avais dans la fonction, mais vous verrez qu'après la sortie de la boucle, prime [0] se voit attribuer la valeur finale de 'a'. J'ai essayé d'utiliser des vecteurs mais VS Express 2013 ne l'aimait pas beaucoup. Notez également que 'a' commence à 1 pour éviter d'écraser [0] et qu'il est initialisé au début pour éviter les erreurs. Je ne suis pas un expert, je pensais partager. 

int prime[] = {0};
int primes(int x, int y){
    using namespace std; int a = 1;
    for (int i = x; i <= y; i++){prime[a] = i; a++; }
    prime[0] = a; return 0;
}
0
Das_Newb

Une des raisons les plus courantes pour lesquelles vous finissez par rechercher ceci est que vous voulez passer un tableau à une fonction sans avoir à passer un autre argument pour sa taille. Vous voudriez aussi généralement que la taille du tableau soit dynamique. Ce tableau peut contenir des objets, et non des primitives, et des objets complexes, tels que size_of () ne soit pas une option sûre pour le calcul du nombre. 

Comme d'autres l'ont suggéré, envisagez d'utiliser un vecteur std :: ou une liste, etc. au lieu d'un tableau primitif. Sur les anciens compilateurs, cependant, vous n’auriez toujours pas la solution finale que vous souhaitiez probablement en procédant simplement ainsi, car remplir le conteneur nécessite un tas de lignes laides Push_back (). Si vous êtes comme moi, recherchez une solution monoligne intégrant des objets anonymes.

Si vous optez pour un conteneur STL comme alternative à un tableau primitif, cet article SO pourrait vous être utile pour l'initialiser: Quel est le moyen le plus simple d'initialiser un vecteur std :: avec code éléments?

Voici une méthode que j'utilise pour cela et qui fonctionnera universellement sur les compilateurs et les plates-formes:

Créez une structure ou une classe en tant que conteneur pour votre collection d'objets. Définir une fonction de surcharge d'opérateur pour <<.

class MyObject;

struct MyObjectList
{
    std::list<MyObject> objects;
    MyObjectList& operator<<( const MyObject o )
    { 
        objects.Push_back( o );
        return *this; 
    }
};

Vous pouvez créer des fonctions qui prennent votre structure en paramètre, par exemple: 

someFunc( MyObjectList &objects );

Ensuite, vous pouvez appeler cette fonction, comme ceci:

someFunc( MyObjectList() << MyObject(1) <<  MyObject(2) <<  MyObject(3) );

De cette façon, vous pouvez créer et transmettre une collection d'objets de taille dynamique à une fonction dans une seule ligne épurée!

0
BuvinJ