Récemment, j'ai trouvé beaucoup d'exemples, la plupart d'entre eux concerne le C++ 98, j'ai quand même créé mon tableau simple et une boucle ( codepad ):
#include <iostream>
using namespace std;
int main ()
{
string texts[] = {"Apple", "Banana", "Orange"};
for( unsigned int a = 0; a < sizeof(texts); a = a + 1 )
{
cout << "value of a: " << texts[a] << endl;
}
return 0;
}
Sortie:
valeur de a: pomme valeur de a: banane valeur de a: orange erreur de segmentation
Cela fonctionne bien, sauf la faute de segmentation à la fin.
Ma question est la suivante: ce tableau/boucle est-il bien conçu? J'utilise C++ 11, alors je voudrais être sûr qu'il respecte les normes et ne pourrait pas être amélioré.
En C/C++ sizeof
. donne toujours le nombre d'octets dans l'objet entier et les tableaux sont traités comme un seul objet. Remarque: sizeof
un pointeur - vers le premier élément d'un tableau ou vers un seul objet - donne la taille du pointeur , et non de l'objet pointé Quoi qu'il en soit, sizeof
donne pas donne le nombre d'éléments dans le tableau (sa longueur). Pour obtenir la longueur, vous devez diviser par la taille de chaque élément. par exemple.,
for( unsigned int a = 0; a < sizeof(texts)/sizeof(texts[0]); a = a + 1 )
Pour le faire à la manière C++ 11, la meilleure façon de le faire est probablement
for(const string &text : texts)
cout << "value of text: " << text << endl;
Cela permet au compilateur de déterminer le nombre d'itérations dont vous avez besoin.
EDIT: comme d'autres l'ont fait remarquer, std::array
est préféré en C++ 11 par rapport aux tableaux bruts; Cependant, aucune des autres réponses n’a expliqué pourquoi sizeof
échouait ainsi, alors je pense toujours que c’est la meilleure réponse.
string texts[] = {"Apple", "Banana", "Orange"};
for( unsigned int a = 0; a < sizeof(texts); a = a + 1 )
{
cout << "value of a: " << texts[a] << endl;
}
Nan. Totalement une mauvaise façon de parcourir un tableau. sizeof(texts)
n'est pas égal au nombre d'éléments dans le tableau!
Les manières modernes, C++ 11, seraient de:
std::array
si vous voulez un tableau dont la taille est connue au moment de la compilation; oustd::vector
si sa taille dépend du temps d'exécutionEnsuite, utilisez range-pour itérer.
#include <iostream>
#include <array>
int main() {
std::array<std::string, 3> texts = {"Apple", "Banana", "Orange"};
// ^ An array of 3 elements with the type std::string
for(const auto& text : texts) { // Range-for!
std::cout << text << std::endl;
}
}
Vous pouvez demander, en quoi std::array
est-il meilleur que le vieux tableau 'C? La réponse est qu’il bénéficie de la sécurité et des fonctionnalités supplémentaires d’autres conteneurs de bibliothèques standard, qui ressemblent le plus souvent à std::vector
. De plus, la réponse est qu’elle n’a pas l’inconvénient de se désintégrer en pointeurs et donc de perdre les informations de type, lesquelles, une fois que vous perdez le type de tableau original, vous ne pouvez plus utiliser range-for ou std::begin/end
.
sizeof
vous indique la taille d'une chose, pas le nombre d'éléments qu'elle contient. Une façon plus C++ 11 de faire ce que vous faites serait:
#include <array>
#include <string>
#include <iostream>
int main()
{
std::array<std::string, 3> texts { "Apple", "Banana", "Orange" };
for (auto& text : texts) {
std::cout << text << '\n';
}
return 0;
}
ideone demo: http://ideone.com/6xmSrn
Ajoutez une valeur d'arrêt au tableau:
#include <iostream>
using namespace std;
int main ()
{
string texts[] = {"Apple", "Banana", "Orange", ""};
for( unsigned int a = 0; texts[a].length(); a = a + 1 )
{
cout << "value of a: " << texts[a] << endl;
}
return 0;
}
Si vous souhaitez gérer une très courte liste d'éléments, vous pouvez utiliser le std :: initializer_list introduit en C++ 11 avec auto:
#include <iostream>
int main(int, char*[])
{
for(const auto& ext : { ".slice", ".socket", ".service", ".target" })
std::cout << "Handling *" << ext << " systemd files" << std::endl;
return 0;
}
sizeof(texts)
sur mon système évalué à 96: nombre d'octets requis pour le tableau et ses instances de chaîne.
Comme mentionné ailleurs, la sizeof(texts)/sizeof(texts[0])
donnerait la valeur de 3 que vous attendiez.