Korrekte Methode zum Durchlaufen von C++-Arrays

Lesezeit: 6 Minuten

Benutzer-Avatar
Lukas

In letzter Zeit habe ich viele Beispiele gefunden, die meisten beziehen sich auf C++ 98, trotzdem habe ich mein einfaches Array und eine Schleife erstellt (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;
}

Ausgabe:

value of a: Apple
value of a: Banana
value of a: Orange

Segmentation fault

Es funktioniert gut, mit Ausnahme des Segmentierungsfehlers am Ende.

Meine Frage ist, ist dieses Array/Durchschleifen ein guter Weg? Ich verwende C++ 11, also möchte ich sicher sein, dass es den Standards entspricht und nicht besser gemacht werden könnte?

  • Benutz einfach std::array und sein size() Funktion.

    – Chris

    27. November 2013 um 5:57 Uhr

Benutzer-Avatar
Nicu Stiurca

In C/C++ sizeof. gibt immer die Anzahl der Bytes im gesamten Objekt an, und Arrays werden als ein Objekt behandelt. Notiz: sizeof Ein Zeiger – auf das erste Element eines Arrays oder auf ein einzelnes Objekt – gibt die Größe von an Zeiger, nicht die Objekte, auf die gezeigt wird. In jedem Fall, sizeof tut nicht Geben Sie die Anzahl der Elemente im Array (seine Länge) an. Um die Länge zu erhalten, müssen Sie durch die Größe jedes Elements teilen. z.B.,

for( unsigned int a = 0; a < sizeof(texts)/sizeof(texts[0]); a = a + 1 )

Was die C++ 11-Methode betrifft, so ist dies wahrscheinlich die beste Methode

for(const string &text : texts)
    cout << "value of text: " << text << endl;

Dadurch kann der Compiler herausfinden, wie viele Iterationen Sie benötigen.

wie andere schon gesagt haben, std::array wird in C++11 gegenüber rohen Arrays bevorzugt; Keine der anderen Antworten befasste sich jedoch mit dem Grund sizeof scheitert so, wie es ist, also denke ich immer noch, dass dies die bessere Antwort ist.

  • Versuchen Sie es für zusätzliche Einfachheit for(auto & text : texts)

    – edA-qa mort-ora-y

    27. November 2013 um 7:51 Uhr

  • @edA-qamort-ora-y oder noch besser: for(auto &&text: texts)

    – RamblingMad

    9. Dezember 2015 um 5:04 Uhr

  • Funktioniert das für den ersten Weg nicht nur, wenn alle Saiten gleich lang sind?

    – tmath

    3. Dezember 2018 um 20:09 Uhr

  • @tmath Meine Mathematik sollte mit dem Beispiel von OP gut funktionieren, weil jedes string Das Objekt hat tatsächlich eine konstante Größe, unabhängig von der Länge der gekapselten Zeichenfolge. Insbesondere a string Objekt ist im Wesentlichen nur eine Struktur mit a Zeiger zu den Daten und ein paar andere Metadaten mit konstanter Größe.

    – Nicu Stiurca

    26. Februar 2019 um 7:38 Uhr

  • Beachten Sie, dass dies für C++ funktionieren kann, aber die Verwendung in C gefährlich ist. Es funktioniert in C für statisch deklarierte Arrays, die sich auf dem Stapel befinden, funktioniert aber nicht in einer Funktion. In einer Funktion kennt der sizeof-Operator nicht das gesamte Array und gibt stattdessen die Größe des Zeigers zurück.

    – jvriesem

    16. April 2020 um 20:12 Uhr

Benutzer-Avatar
Markus García

string texts[] = {"Apple", "Banana", "Orange"};
for( unsigned int a = 0; a < sizeof(texts); a = a + 1 )
{
    cout << "value of a: " << texts[a] << endl;
}

Nö. Eine völlig falsche Art, ein Array zu durchlaufen. sizeof(texts) ist nicht gleich der Anzahl der Elemente im Array!

Die modernen C ++ 11-Möglichkeiten wären:

  • benutzen std::array wenn Sie ein Array wollen, dessen Größe zur Kompilierzeit bekannt ist; oder
  • benutzen std::vector wenn seine Größe von der Laufzeit abhängt

Verwenden Sie dann range-for beim Iterieren.

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

Live-Beispiel


Sie können fragen, wie ist std::array besser als das alte C-Array? Die Antwort ist, dass es die zusätzliche Sicherheit und die Funktionen anderer Standard-Bibliothekscontainer hat, die meistens sehr ähnlich sind std::vector. Außerdem ist die Antwort, dass es nicht die Macken hat, zu Zeigern zu zerfallen und somit Typinformationen zu verlieren, die Sie, sobald Sie den ursprünglichen Array-Typ verlieren, nicht mehr range-for or verwenden können std::begin/end darauf.

  • Hinweis: Sie könnten weiterhin die bereichsbasierte Schleife mit ihrem ursprünglichen Array verwenden.

    – Juanchopanza

    27. November 2013 um 6:46 Uhr

  • Ich mag die nicht std::array Ansatz, da ich die Elemente selbst zählen muss. Auf herkömmliche Weise erstellt der Compiler das Array in der richtigen Größe für mich.

    – edA-qa mort-ora-y

    27. November 2013 um 7:53 Uhr

  • @edA-qamort-ora-y Dafür gibt es eine Problemumgehung.

    – Markus García

    27. November 2013 um 7:57 Uhr

sizeof sagt Ihnen die Größe einer Sache, nicht die Anzahl der Elemente darin. Eine weitere C ++ 11-Methode, um das zu tun, was Sie tun, wäre:

#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

  • Hey, das ist toll! sollte aber wahrscheinlich erklären, was es bedeutet und wie es funktioniert.

    – cnst

    26. April 2016 um 23:18 Uhr

Sie müssen den Unterschied zwischen den Operatoren std::array::size und sizeof() verstehen. Wenn Sie Array-Elemente auf herkömmliche Weise durchlaufen möchten, können Sie std::array::size verwenden. Dies gibt die Anzahl der Elemente im Array zurück, aber wenn Sie C++ 11 verwenden möchten, bevorzugen Sie den folgenden Code

for(const string &text : texts)
    cout << "value of text: " << text << endl;

Fügen Sie dem Array einen Stoppwert hinzu:

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

  • Das ist falsch. Texte[a].length() ist die Länge des Wortes bei Index a. Nicht die Länge des Arrays.

    – hellez

    24. Mai 2018 um 21:07 Uhr

  • @htellez Ja, das ist der Punkt. Die Schleife wird beendet, wenn sie auf eine Zeichenfolge mit einer Länge von Null trifft.

    – Zenexer

    26. Mai 2018 um 1:56 Uhr

  • Ah! Das hatte ich nicht mitbekommen.

    – hellez

    29. Mai 2018 um 22:19 Uhr

  • Der Code funktioniert gut, danke, dass er auch mein Problem gelöst hat, aber wie kann string texts[] arbeiten, um Arrays zu deklarieren? warum meins nicht? Ich verwende Codeblock minGW 17.12

    – Irwan Hilmi

    30. Dezember 2018 um 14:31 Uhr


Benutzer-Avatar
Phidelux

Wenn Sie eine sehr kurze Liste von Elementen haben, die Sie handhaben möchten, können Sie die verwenden std::initializer_list eingeführt in C++11 zusammen mit 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;
}

  • Das ist falsch. Texte[a].length() ist die Länge des Wortes bei Index a. Nicht die Länge des Arrays.

    – hellez

    24. Mai 2018 um 21:07 Uhr

  • @htellez Ja, das ist der Punkt. Die Schleife wird beendet, wenn sie auf eine Zeichenfolge mit einer Länge von Null trifft.

    – Zenexer

    26. Mai 2018 um 1:56 Uhr

  • Ah! Das hatte ich nicht mitbekommen.

    – hellez

    29. Mai 2018 um 22:19 Uhr

  • Der Code funktioniert gut, danke, dass er auch mein Problem gelöst hat, aber wie kann string texts[] arbeiten, um Arrays zu deklarieren? warum meins nicht? Ich verwende Codeblock minGW 17.12

    – Irwan Hilmi

    30. Dezember 2018 um 14:31 Uhr


Benutzer-Avatar
orte

sizeof(texts) auf meinem System auf 96 ausgewertet: die Anzahl der Bytes, die für das Array und seine String-Instanzen erforderlich sind.

Wie an anderer Stelle erwähnt, die sizeof(texts)/sizeof(texts[0]) würde den erwarteten Wert 3 ergeben.

1012330cookie-checkKorrekte Methode zum Durchlaufen von C++-Arrays

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy