Existe-t-il un moyen de trouver le nombre de valeurs d'un tableau? Détecter si j'ai atteint ou non la fin d'un tableau fonctionnerait également.
Existe-t-il un moyen de trouver le nombre de valeurs d'un tableau? Détecter si j'ai atteint ou non la fin d'un tableau fonctionnerait également.
Réponses:
Si vous voulez dire 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 cela ne fonctionnera pour aucun des éléments 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 devez utiliser une classe conteneur; probablement std::vector
.
Comme d'autres l'ont dit, vous pouvez utiliser le sizeof(arr)/sizeof(*arr)
mais cela vous donnera la mauvaise 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 belle propriété de ne pas pouvoir compiler pour les types non matriciels (Visual Studio l'a _countof
fait). Le constexpr
fait de cette expression de compilation il n'a pas des inconvénients sur la macro (au moins pas que je sache).
Vous pouvez également envisager d'utiliser std::array
C ++ 11 qui expose sa longueur sans surcharge sur un tableau C natif.
C ++ 17 a std::size()
dans l'en- <iterator>
tête qui fait de même et fonctionne aussi pour les conteneurs STL (grâce à @Jon C ).
T(arg&)[N]
.
extent
, en le regardant maintenant, il y a deux caractéristiques qui le rendent moins utile que la fonction ci-dessus (pour ce cas d'utilisation). (1) Il renvoie zéro pour les pointeurs (plutôt qu'une erreur de compilation). (2) Il nécessite un paramètre de type afin de vérifier une variable que vous devriez fairedecltype
Faire sizeof( myArray )
vous obtiendrez le nombre total d'octets alloués à ce tableau. Vous pouvez ensuite connaître le nombre d'éléments dans le tableau en divisant par la taille d'un élément du tableau:sizeof( myArray[0] )
Bien qu'il s'agisse d'une vieille question, cela vaut la peine de mettre à jour la réponse à C ++ 17. Dans la bibliothèque standard, il y a maintenant la fonction de modèle std::size()
, qui renvoie le nombre d'éléments dans un conteneur std ou un tableau de style C. Par exemple:
#include <iterator>
uint32_t data[] = {10, 20, 30, 40};
auto dataSize = std::size(data);
// dataSize == 4
Existe-t-il un moyen de trouver le nombre de valeurs d'un tableau?
Oui!
Essayer 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).
PS: En C ++, utilisez toujours std::vector
. Il existe plusieurs fonctions intégrées et une fonctionnalité étendue.
std::vector
a une méthode size()
qui retourne le nombre d'éléments dans le vecteur.
(Oui, c'est une réponse ironique)
#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;
}
Depuis C ++ 11, de nouveaux modèles sont introduits pour aider à réduire la douleur liée à la longueur du tableau. Tous sont définis dans l'en-tête <type_traits>
.
Si T
est un type de tableau, fournit la valeur de constante de membre égale au nombre de dimensions du tableau. Pour tout autre type, la valeur est 0.
Si T
est un type de tableau, fournit la valeur de constante de membre égale au nombre d'éléments le long de la N
e dimension du tableau, si N
est dans [0, std::rank<T>::value
). Pour tout autre type, ou si T
est un tableau de bornes inconnues le long de sa première dimension et N
vaut 0, la valeur est 0.
Si T
est un tableau d'un certain type X
, fournit le type typedef 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 d'un certain type X
, fournit le type typedef membre égal àX
, sinon le type est T
.
Pour obtenir la longueur sur n'importe quelle dimension d'un réseau multidimential, decltype
peut être utilisé pour se combiner 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.
Il y a aussi la manière TR1 / C ++ 11 / C ++ 17 (voir Live on Coliru):
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
Au lieu d'utiliser la fonction tableau intégrée, alias:
int x[3] = {0, 1, 2};
vous devez utiliser la classe de tableau et le modèle 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, tout ce que vous avez à faire est d'utiliser la fonction taille dans la classe du tableau.
Name_of_Array.size();
et cela devrait renvoyer la longueur des éléments du tableau.
En C ++, en utilisant la classe std :: array pour déclarer un tableau, on peut facilement trouver la taille d'un tableau et aussi 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 comme conteneur standard.
Référence 1 à la classe std :: array C ++
Référence 2 à la classe std :: array
Les exemples des références sont utiles.
C'est une question assez ancienne et légendaire et il existe déjà de nombreuses réponses étonnantes. Mais avec le temps, de nouvelles fonctionnalités sont ajoutées aux langues, nous devons donc continuer à mettre à jour les choses selon les nouvelles fonctionnalités disponibles.
Je viens de remarquer que personne n'a encore parlé de C ++ 20. Alors pensé à écrire la réponse.
En C ++ 20, il y a un nouveau meilleur moyen ajouté à la bibliothèque standard pour trouver la longueur du tableau ie std:ssize()
. Cette fonction renvoie a signed value
.
#include <iostream>
int main() {
int arr[] = {1, 2, 3};
std::cout << std::ssize(arr);
return 0;
}
En C ++ 17, il y avait un meilleur moyen (à l'époque) pour le même qui est std::size()
défini dans iterator
.
#include <iostream>
#include <iterator> // required for std::size
int main(){
int arr[] = {1, 2, 3};
std::cout << "Size is " << std::size(arr);
return 0;
}
PS Cette méthode fonctionne pour vector
également.
Cette approche traditionnelle est déjà mentionnée dans de nombreuses autres réponses.
#include <iostream>
int main() {
int array[] = { 1, 2, 3 };
std::cout << sizeof(array) / sizeof(array[0]);
return 0;
}
Juste pour info, si vous vous demandez pourquoi cette approche ne fonctionne pas lorsque le tableau est passé à une autre fonction . La raison est,
Un tableau n'est pas passé par valeur en C ++, à la place le pointeur vers tableau est passé. Comme dans certains cas, le passage de l'ensemble des tableaux peut être une opération coûteuse. Vous pouvez tester cela en passant le tableau à une fonction et y apporter des modifications, puis réimprimer le tableau dans main. Vous obtiendrez des résultats mis à jour.
Et comme vous le savez déjà, la sizeof()
fonction donne le nombre d'octets, donc dans d'autres fonctions, elle retournera le nombre d'octets alloués au pointeur plutôt qu'au tableau entier. Cette approche ne fonctionne donc pas.
Mais je suis sûr que vous pouvez trouver un bon moyen de le faire, selon vos besoins.
Codage heureux.
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;
Voici une mise en œuvre de ArraySize
de 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 # d'octets dans le tableau) et sizeof (* (arr)) (le # d'octets dans un élément du tableau). Si le premier est divisible par le second, arr est peut-être en effet un tableau, auquel cas le résultat de la division est le # d'éléments du tableau. Sinon, arr ne peut pas être un tableau et nous générons une erreur de compilation pour empêcher la compilation du code.
Étant donné que la taille de bool est définie par l'implémentation, nous devons convertir! (Sizeof (a) & sizeof (* (a))) en size_t afin de nous assurer que le résultat final a le type size_t.
Cette macro n'est pas parfaite car elle accepte à tort certains pointeurs, à savoir lorsque la taille du pointeur est divisible par la taille de la pointe. Étant donné que tout notre code doit passer par un compilateur 32 bits, où un pointeur est de 4 octets, cela signifie que tous les pointeurs vers un type dont la taille est 3 ou supérieure à 4 seront (justement) rejetés.
int nombres[5] = { 9, 3 };
cette fonction renvoie 5
au lieu de 2
.
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 size()
fonction.
Code source:
string myArray[] = { "Example1", "Example2", "Example3", "Example4" };
int size_of_array=size(myArray);
Si vous cout
la size_of_array
sortie sera:
>>> 4
sizeof(array_name)
donne la taille du tableau entier et sizeof(int)
donne la taille du type de données de chaque élément du tableau.
Ainsi, la division de la taille de l'ensemble du tableau par la taille d'un seul élément du tableau donne la longueur du tableau.
int array_name[] = {1, 2, 3, 4, 5, 6};
int length = sizeof(array_name)/sizeof(int);
RÉPONSE :
int number_of_elements = sizeof(array)/sizeof(array[0])
EXPLICATION :
Étant donné que le compilateur définit une taille de mémoire spécifique pour chaque type de données et qu'un tableau est simplement un groupe de ceux-ci, vous divisez simplement la taille du tableau par la taille du type de données. Si j'ai un tableau de 30 chaînes, mon système réserve 24 octets pour chaque élément (chaîne) du tableau. À 30 éléments, c'est un total de 720 octets. 720/24 == 30 éléments. Le petit algorithme serré pour cela est:
int number_of_elements = sizeof(array)/sizeof(array[0])
ce qui équivaut à
number_of_elements = 720/24
Notez que vous n'avez pas besoin de connaître le type de données du tableau, même s'il s'agit d'un type de données personnalisé.
Juste une pensée, mais juste décidé 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 avoir quitté la boucle, prime [0] se voit attribuer la valeur finale de «a». J'ai essayé d'utiliser des vecteurs mais VS Express 2013 n'aimait pas beaucoup ça. Notez également que «a» commence par un 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 juste 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;
}
Une bonne solution qui utilise des génériques:
template <typename T,unsigned S>
inline unsigned arraysize(const T (&v)[S]) { return S; }
Appelez ensuite simplement arraysize(_Array);
pour obtenir la longueur du tableau.
constexpr
est le correctif. inline
n'est pas. constexpr
est assez moderne cependant. Êtes-vous sûr que votre programme de test n'utilise pas une autre fonctionnalité moderne, où vous pouvez déclarer un tableau local dont la longueur est donnée par une variable? Essayez-le avec deux tableaux globaux.
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;
}
Je fournis ici une solution délicate:
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
lors de l'invocationfree
arr
est d'un type compatible avec int
et que le tableau n'est pas plus long que la valeur maximale du type. Par exemple, les chaînes Pascal sont en fait des tableaux d'octets utilisant cette astuce; la longueur maximale des chaînes en Pascal est de 255 caractères.
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;
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/
Évitez d'utiliser le type avec sizeof, car sizeof(array)/sizeof(char)
, est soudainement corrompu si vous changez le type du tableau.
Dans Visual Studio, vous avez l'équivalent if sizeof(array)/sizeof(*array)
. Vous pouvez simplement taper_countof(array)
Personnellement, je suggère (si vous ne pouvez pas 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 rendriez l'élément du tableau 1 plus grand que ce dont vous avez besoin pour le faire. Pour le dernier élément, vous mettriez un type qui est 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.
L'une des raisons les plus courantes pour lesquelles vous finirez par rechercher cela est que vous souhaitez passer un tableau à une fonction et ne pas avoir à passer un autre argument pour sa taille. Vous aimeriez aussi généralement que la taille du tableau soit dynamique. Ce tableau peut contenir des objets, pas des primitives, et les objets peuvent être complexes de telle sorte que size_of () n'est pas une option sûre pour calculer le nombre.
Comme d'autres l'ont suggéré, envisagez d'utiliser un vecteur ou une liste std ::, etc. au lieu d'un tableau primitif. Sur les anciens compilateurs, cependant, vous n'auriez toujours pas la solution finale que vous souhaitez probablement en faisant simplement cela, car le remplissage du conteneur nécessite un tas de lignes push_back () moches. Si vous êtes comme moi, vous voulez une solution sur une seule ligne avec des objets anonymes impliqués.
Si vous optez pour une alternative de conteneur STL à un tableau primitif, ce message SO peut vous être utile pour savoir comment l'initialiser: Quelle est la façon la plus simple d'initialiser un vecteur std :: avec des éléments codés en dur?
Voici une méthode que j'utilise pour cela qui fonctionnera universellement sur les compilateurs et les plates-formes:
Créez une structure ou une classe comme conteneur pour votre collection d'objets. Définissez 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 en une seule ligne épurée!
Disons que vous avez déclaré un tableau global en haut de la page
int global[] = { 1, 2, 3, 4 };
Pour savoir combien d'éléments sont présents (en c ++) dans le tableau, tapez le code suivant:
sizeof(global) / 4;
La taille de (NAME_OF_ARRAY) / 4 vous donnera le nombre d'éléments pour le nom de tableau donné.