Arrays vs Vektoren: Einführende Ähnlichkeiten und Unterschiede [geschlossen]

111

Was sind die Unterschiede zwischen einem Array und einem Vektor in C ++? Ein Beispiel für die Unterschiede könnten Bibliotheken, Symbolik, Fähigkeiten usw. sein.

Array

Arrays enthalten eine bestimmte Anzahl von Elementen eines bestimmten Typs. Damit der Compiler beim Kompilieren des Programms den erforderlichen Speicherplatz reservieren kann, müssen Sie den Typ und die Anzahl der Elemente angeben, die das Array bei seiner Definition enthalten soll. Der Compiler muss diesen Wert beim Kompilieren des Programms ermitteln können. Sobald ein Array definiert wurde, verwenden Sie den Bezeichner für das Array zusammen mit einem Index, um auf bestimmte Elemente des Arrays zuzugreifen. [...] Arrays sind nullindiziert; Das heißt, das erste Element befindet sich am Index 0. Dieses Indexierungsschema zeigt die enge Beziehung in C ++ zwischen Zeigern und Arrays und die Regeln an, die die Sprache für die Zeigerarithmetik definiert.

- C ++ - Taschenreferenz

Vektor

Ein Vektor ist eine dynamisch große Folge von Objekten, die einen operator[]Direktzugriff im Array-Stil ermöglicht. Die Member-Funktion push_backkopiert ihre Argumente über den Kopierkonstruktor, fügt diese Kopie als letztes Element im Vektor hinzu und erhöht ihre Größe um eins.pop_backmacht genau das Gegenteil, indem das letzte Element entfernt wird. Das Einfügen oder Löschen von Elementen am Ende eines Vektors benötigt eine amortisierte konstante Zeit, und das Einfügen oder Löschen von einem anderen Ort benötigt lineare Zeit. Dies sind die Grundlagen von Vektoren. Sie haben noch viel mehr zu bieten. In den meisten Fällen sollte ein Vektor Ihre erste Wahl gegenüber einem Array im C-Stil sein. Erstens sind sie dynamisch dimensioniert, was bedeutet, dass sie nach Bedarf wachsen können. Sie müssen nicht alle möglichen Untersuchungen durchführen, um eine optimale statische Größe zu ermitteln, wie im Fall von C-Arrays. Ein Vektor wächst nach Bedarf und kann bei Bedarf manuell vergrößert oder verkleinert werden. Zweitens bieten Vektoren die Überprüfung von Grenzen mit der atElementfunktion (jedoch nicht mitoperator[]), damit Sie etwas tun können, wenn Sie auf einen nicht vorhandenen Index verweisen, anstatt nur zu beobachten, wie Ihr Programm abstürzt oder schlimmer noch, und die Ausführung mit beschädigten Daten fortsetzen.

- C ++ Kochbuch

Trancot
quelle
Grundlegendster Unterschied: Es gibt Zwecke, für die der Vektor eine gute Wahl ist.
Jerry Coffin
1
"erschöpfend" und "konsistent" sind orthogonal. Das heißt, nicht nur eine nicht das andere bedeuten, aber sie sind nicht einmal in der gleichen Größenordnung.
Leichtigkeitsrennen im Orbit
2
Ich ärgere mich sehr über Leute, die Fragen schließen, die genau die Informationen sind, nach denen ich suche. Das passiert viel zu oft.
Robert Tamlyn

Antworten:

142

Arrays:

  • sind ein eingebautes Sprachkonstrukt;
  • kommen fast unverändert von C89;
  • Stellen Sie nur eine zusammenhängende, indizierbare Folge von Elementen bereit . keine Schnickschnack;
  • sind von fester Größe; Sie können die Größe eines Arrays in C ++ nicht ändern (es sei denn, es handelt sich um ein POD-Array, dem es zugewiesen ist malloc).
  • Ihre Größe muss eine Kompilierungszeitkonstante sein, es sei denn, sie werden dynamisch zugewiesen.
  • Sie belegen ihren Speicherplatz abhängig vom Umfang, in dem Sie sie deklarieren.
  • Wenn sie dynamisch zugewiesen werden, müssen Sie sie explizit freigeben.
  • Wenn sie dynamisch zugewiesen werden, erhalten Sie nur einen Zeiger und können ihre Größe nicht bestimmen. Andernfalls können Sie verwenden sizeof(daher die allgemeine Redewendung sizeof(arr)/sizeof(*arr), die jedoch unbeabsichtigt fehlschlägt, wenn sie versehentlich für einen Zeiger verwendet wird).
  • in den meisten Situationen automatisch zu Zeigern zerfallen; Dies geschieht insbesondere, wenn sie an eine Funktion übergeben werden, für die normalerweise ein separater Parameter für ihre Größe übergeben werden muss.
  • kann nicht von einer Funktion zurückgegeben werden;
  • kann nicht direkt kopiert / zugewiesen werden;
  • Dynamische Arrays von Objekten erfordern einen Standardkonstruktor, da alle ihre Elemente zuerst erstellt werden müssen.

std::vector::

  • ist eine Vorlagenklasse;
  • ist ein C ++ - Konstrukt;
  • wird als dynamisches Array implementiert ;
  • wächst und schrumpft dynamisch;
  • verwalten automatisch ihr Gedächtnis, das bei Zerstörung freigesetzt wird;
  • kann an Funktionen übergeben / von diesen zurückgegeben werden (nach Wert);
  • kann kopiert / zugewiesen werden (dies führt eine tiefe Kopie aller gespeicherten Elemente durch);
  • zerfällt nicht in Zeiger, aber Sie können explizit einen Zeiger auf ihre Daten erhalten ( &vec[0]funktioniert garantiert wie erwartet);
  • bringt immer die Größe (wie viele Elemente aktuell gespeichert sind) und die Kapazität (wie viele Elemente im aktuell zugewiesenen Block gespeichert werden können ) mit;
  • Das interne dynamische Array wird nicht innerhalb des Objekts selbst zugeordnet (das nur einige "Buchhaltungs" -Felder enthält), sondern dynamisch durch den im entsprechenden Vorlagenparameter angegebenen Allokator zugewiesen. Die Standardeinstellung bezieht den Speicher aus dem Freestore (dem sogenannten Heap), unabhängig davon, wie das eigentliche Objekt zugeordnet ist.
  • Aus diesem Grund sind sie möglicherweise weniger effizient als "normale" Arrays für kleine, kurzlebige lokale Arrays.
  • Bei der Neuzuweisung werden die Objekte kopiert (verschoben, in C ++ 11).
  • erfordert keinen Standardkonstruktor für die gespeicherten Objekte;
  • ist besser in den Rest der sogenannten STL integriert (es liefert die begin()/ end()Methoden, die üblichen STLs typedef, ...)

Betrachten Sie auch die "moderne Alternative" zu Arrays - std::array; Ich habe bereits in einer anderen Antwort den Unterschied zwischen std::vectorund beschrieben std::array, vielleicht möchten Sie einen Blick darauf werfen.

Matteo Italia
quelle
1
Vielen Dank, @MatteoItalia. Ein oder zwei Referenzen wären schön.
Trancot
1
@Trancot: Jedes gute C ++ - Buch reicht aus.
Matteo Italia
6
@Trancot: Ich kann Ihnen wirklich keine besseren Referenzen geben - die in diesem Beitrag hervorgehobenen Unterschiede stammen aus vielen verschiedenen Teilen des Standards und werden mithilfe eines guten C ++ - Handbuchs besser verstanden.
Matteo Italia
Ein Beispiel für eine so ausführliche Beschreibung wäre toll!
Carloswm85
26

Ich werde hinzufügen, dass Arrays in C ++ Konstrukte auf sehr niedriger Ebene sind und Sie sollten versuchen, sich so weit wie möglich von ihnen fernzuhalten, wenn Sie "die Seile lernen" - sogar Bjarne Stroustrup empfiehlt dies (er ist der Designer von C ++).

Vektoren kommen der Leistung von Arrays sehr nahe, bieten jedoch zahlreiche Annehmlichkeiten und Sicherheitsfunktionen. Sie werden wahrscheinlich Arrays verwenden, wenn Sie eine Schnittstelle zu APIs herstellen, die sich mit Raw-Arrays befassen, oder wenn Sie Ihre eigenen Sammlungen erstellen.

John Källén
quelle
1
Anwendungsprogrammschnittstelle: ( en.wikipedia.org/wiki/API ). Es ist eine Sammlung von Einstiegspunkten für eine Software-Entität (Paket, Bibliothek, Betriebssystem). Einige APIs haben Einstiegspunkte wie strcat (char * dst, char * src), wobei dst und src als Zeichenarrays behandelt werden (obwohl die Funktionssignatur Zeiger auf Zeichen impliziert).
John Källén
11

Diese Referenzen haben Ihre Frage ziemlich genau beantwortet. Einfach ausgedrückt sind die Längen der Vektoren dynamisch, während Arrays eine feste Größe haben. Wenn Sie ein Array verwenden, geben Sie seine Größe bei der Deklaration an:

int myArray[100];
myArray[0]=1;
myArray[1]=2;
myArray[2]=3;

Für Vektoren deklarieren Sie es einfach und fügen Elemente hinzu

vector<int> myVector;
myVector.push_back(1);
myVector.push_back(2);
myVector.push_back(3);
...

Manchmal wissen Sie nicht, wie viele Elemente benötigt werden, sodass ein Vektor für eine solche Situation ideal ist.

Nicolas Brown
quelle