wake-up-neo.net

Korrekter Weg durch die C++ - Arrays

In letzter Zeit habe ich viele Beispiele gefunden, die meisten davon betreffen C++ 98, jedenfalls habe ich mein einfaches Array und eine Schleife ( codepad ) erstellt:

#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:

wert von a: Apple 
 Wert von a: Banane 
 Wert von a: Orange 

 Segmentierungsfehler

Es funktioniert gut, abgesehen von dem Segmentierungsfehler am Ende.

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

38
Lucas

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

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

Die beste Möglichkeit, dies auf C++ 11 zu tun, ist wahrscheinlich

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

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

BEARBEITEN: Wie andere darauf hingewiesen haben, wird std::array in C++ 11 gegenüber unformatierten Arrays bevorzugt. In keiner der anderen Antworten ging es darum, warum sizeof so scheitert, wie ich finde. Ich denke immer noch, dass dies die bessere Antwort ist.

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

Nee. Eine völlig falsche Methode, um durch ein Array zu iterieren. sizeof(texts) ist nicht gleich der Anzahl der Elemente im Array!

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

  • verwenden Sie std::array, wenn Sie ein Array benötigen, dessen Größe zur Kompilierzeit bekannt ist. oder
  • verwenden Sie std::vector, wenn seine Größe von der Laufzeit abhängt

Verwenden Sie dann range-for, wenn Sie 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 fragen sich vielleicht, wie std::array besser ist als das alte C-Array. Die Antwort ist, dass es die zusätzliche Sicherheit und die Funktionen anderer Standard-Bibliothekscontainer bietet, die std::vector weitgehend ähneln. Die Antwort ist außerdem, dass es nicht die Macken hat, zu Zeigern zu zerfallen und somit Typinformationen zu verlieren. Wenn Sie den ursprünglichen Array-Typ verloren haben, können Sie nicht range-for oder std::begin/end verwenden.

15
Mark Garcia

sizeof gibt die Größe eines Dings an, nicht die Anzahl der Elemente. Eine weitere Möglichkeit, das zu tun, was Sie tun, wäre C++ 11:

#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

8
kfsone

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

Wenn Sie eine sehr kurze Liste von Elementen haben, die Sie behandeln möchten, können Sie die in C++ 11 eingeführte std :: initializer_list zusammen mit auto verwenden:

#include <iostream>

int main(int, char*[])
{
    for(const auto& ext : { ".slice", ".socket", ".service", ".target" })
        std::cout << "Handling *" << ext << " systemd files" << std::endl;

    return 0;
}
1
Phidelux

sizeof(texts) auf meinem System wurde mit 96 bewertet: Die Anzahl der Bytes, die für das Array und seine Zeichenfolgeninstanzen erforderlich sind.

Wie bereits an anderer Stelle erwähnt, würde sizeof(texts)/sizeof(texts[0]) den Wert von 3 angeben, den Sie erwartet hatten.

1
bvj