Wie füge ich ein Element zum C ++ - Array hinzu?

74

Ich möchte einem Array ein int hinzufügen, aber das Problem ist, dass ich nicht weiß, wie der Index jetzt ist.

int[] arr = new int[15];
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
arr[3] = 4;
arr[4] = 5;

Dieser Code funktioniert, weil ich weiß, welchem ​​Index ich ihn zuordne, aber was ist, wenn ich den Index nicht kenne ...

In PHP kann ich das einfach tun arr[]=22;, wodurch automatisch 22 zum nächsten leeren Index des Arrays hinzugefügt werden. Aber in C ++ kann ich das nicht, es gibt mir einen Compilerfehler. Was schlägt ihr vor?

r4ccoon
quelle
12
Tatsächlich wird "dieser Code" nicht einmal kompiliert. "int [] arr" deklariert kein Array in C / C ++ - es ist "int arr []". Ihr Code weist jedoch schwerwiegendere Probleme auf, auf die sich die anderen Antworten beziehen.
j_random_hacker

Antworten:

82

Es gibt keine Möglichkeit, das, was Sie in C ++ sagen, mit einfachen Arrays zu tun. Die C ++ - Lösung hierfür ist die Verwendung der STL-Bibliothek, mit der Sie die std::vector.

Sie können a folgendermaßen verwenden vector:

std::vector< int > arr;

arr.push_back(1);
arr.push_back(2);
arr.push_back(3);
Jab
quelle
10
Sie benötigen "#include <vector>"! = D
Eduardo Lucio
Bemerkenswert - Sie können das Array wie folgt
netpoetica
73

Arrays in C ++ können zur Laufzeit die Größe nicht ändern. Zu diesem Zweck sollten Sie vector<int>stattdessen verwenden.

vector<int> arr;
arr.push_back(1);
arr.push_back(2);

// arr.size() will be the number of elements in the vector at the moment.

Wie in den Kommentaren erwähnt, vectorwird in vectorHeader und stdNamespace definiert. Um es zu verwenden, sollten Sie:

#include <vector>

und auch entweder std::vectorin Ihrem Code verwenden oder hinzufügen

using std::vector; 

oder

using namespace std;

nach der #include <vector>Linie.

mmx
quelle
1
+1 -> Ich stimme zu, Vektoren sind bei weitem der einfachste Weg, dies zu tun. Vergessen Sie nicht, dass Sie Folgendes benötigen: #include <vector>
Jon Cage
2
Verwenden Sie außerdem std :: vector oder fügen Sie vor der Instanziierung std :: vector hinzu.
Bastien Léonard
19

Sie müssen keine Vektoren verwenden. Wenn Sie bei einfachen Arrays bleiben möchten, können Sie Folgendes tun:

int arr[] = new int[15];
unsigned int arr_length = 0;

Wenn Sie nun am Ende des Arrays ein Element hinzufügen möchten, können Sie Folgendes tun:

if (arr_length < 15) {
  arr[arr_length++] = <number>;
} else {
  // Handle a full array.
}

Es ist nicht so kurz und anmutig wie das PHP-Äquivalent, aber es erreicht das, was Sie versucht haben. Um die Größe des Arrays in Zukunft einfach ändern zu können, können Sie ein #define verwenden.

#define ARRAY_MAX 15

int arr[] = new int[ARRAY_MAX];
unsigned int arr_length = 0;

if (arr_length < ARRAY_MAX) {
  arr[arr_length++] = <number>;
} else {
  // Handle a full array.
}

Dies erleichtert die zukünftige Verwaltung des Arrays erheblich. Durch Ändern von 15 auf 100 wird die Arraygröße im gesamten Programm ordnungsgemäß geändert. Beachten Sie, dass Sie das Array auf die maximal erwartete Größe einstellen müssen, da Sie es nach dem Kompilieren des Programms nicht mehr ändern können. Wenn Sie beispielsweise ein Array der Größe 100 haben, können Sie niemals 101 Elemente einfügen.

Wenn Sie Elemente am Ende des Arrays verwenden, können Sie Folgendes tun:

if (arr_length > 0) {
  int value = arr[arr_length--];
} else {
  // Handle empty array.
}

Wenn Sie Elemente von Anfang an löschen möchten (z. B. ein FIFO), wird die Lösung komplizierter. Sie benötigen auch einen Anfangs- und einen Endindex.

#define ARRAY_MAX 15

int arr[] = new int[ARRAY_MAX];
unsigned int arr_length = 0;
unsigned int arr_start = 0;
unsigned int arr_end = 0;

// Insert number at end.
if (arr_length < ARRAY_MAX) {
  arr[arr_end] = <number>;
  arr_end = (arr_end + 1) % ARRAY_MAX;
  arr_length ++;
} else {
  // Handle a full array.
}

// Read number from beginning.
if (arr_length > 0) {
  int value = arr[arr_start];
  arr_start = (arr_start + 1) % ARRAY_MAX;
  arr_length --;
} else {
  // Handle an empty array.
}

// Read number from end.
if (arr_length > 0) {
  int value = arr[arr_end];
  arr_end = (arr_end + ARRAY_MAX - 1) % ARRAY_MAX;
  arr_length --;
} else {
  // Handle an empty array.
}

Hier verwenden wir den Moduloperator (%), um zu bewirken, dass die Indizes umbrochen werden. Zum Beispiel ist (99 + 1)% 100 0 (ein Umbruchinkrement). Und (99 + 99)% 100 ist 98 (ein Umbruchdekrement). Auf diese Weise können Sie if-Anweisungen vermeiden und den Code effizienter gestalten.

Sie können auch schnell erkennen, wie hilfreich die #define ist, wenn Ihr Code komplexer wird. Leider können Sie selbst mit dieser Lösung niemals mehr als 100 Elemente (oder ein von Ihnen festgelegtes Maximum) in das Array einfügen. Sie verwenden auch 100 Byte Speicher, selbst wenn nur 1 Element im Array gespeichert ist.

Dies ist der Hauptgrund, warum andere Vektoren empfohlen haben. Ein Vektor wird hinter den Kulissen verwaltet und neuer Speicher wird zugewiesen, wenn sich die Struktur erweitert. Es ist immer noch nicht so effizient wie ein Array in Situationen, in denen die Datengröße bereits bekannt ist, aber für die meisten Zwecke sind die Leistungsunterschiede nicht wichtig. Jeder Ansatz hat Kompromisse und es ist am besten, beide zu kennen.

Azoundria
quelle
Ich bin definitiv ein Neuling in C ++, aber ich erhalte einen ziemlich konsistenten Array initializer must be an initializer listFehler, wenn ich versuche, int arr[] = new int[15];das Array zu initialisieren arr.
Yu Chen
13

Verwenden Sie einen Vektor:

#include <vector>

void foo() {
    std::vector <int> v;
    v.push_back( 1 );       // equivalent to v[0] = 1
}

quelle
13
int arr[] = new int[15];

Die Variable arrenthält eine Speicheradresse. An der Speicheradresse befinden sich 15 aufeinanderfolgende Ints hintereinander. Sie können mit Index 0 bis einschließlich 14 referenziert werden.

In PHP kann ich dies einfach tun arr [] = 22; Dadurch wird automatisch 22 zum nächsten leeren Index des Arrays hinzugefügt.

Beim Umgang mit Arrays gibt es kein Konzept für "Weiter".
Eine wichtige Sache, die Sie meiner Meinung nach vermissen, ist, dass alle Elemente des Arrays bereits vorhanden sind, sobald das Array erstellt wurde. Sie sind nicht initialisiert, aber sie existieren alle bereits. Sie "füllen" also nicht die Elemente des Arrays, sondern sie sind bereits gefüllt, nur mit nicht initialisierten Werten. Es gibt keine Möglichkeit, ein Array auf ein nicht initialisiertes Element zu testen.

Es klingt wie Sie eine Datenstruktur , wie zum Beispiel eine verwenden möchten Warteschlange oder Stapel oder Vektor .

Brian R. Bondy
quelle
6

Ich stimme dem vectorWeg bei der Implementierung eines dynamischen Arrays voll und ganz zu . Beachten Sie jedoch, dass STL Ihnen eine Vielzahl von Containern zur Verfügung stellt, die unterschiedliche Laufzeitanforderungen erfüllen. Sie sollten einen sorgfältig auswählen. Beispiel: Für ein schnelles Einsetzen auf der Rückseite haben Sie die Wahl zwischen a vectorund a deque.

Und ich hätte fast vergessen, mit großer Leistung geht eine große Verantwortung vectoreinher :-) Da s eine flexible Größe haben, werden sie häufig automatisch neu zugewiesen, um das Hinzufügen von Elementen anzupassen. Achten Sie also auf die Ungültigmachung des Iterators (ja, dies gilt auch für Zeiger). Solange Sie jedoch operator[]für den Zugriff auf die einzelnen Elemente verwenden, sind Sie sicher.

dirkgently
quelle
3

Möglicherweise fehlt mir hier der Punkt Ihrer Frage, und wenn ja, entschuldige ich mich. Wenn Sie jedoch keine Elemente löschen und nur hinzufügen möchten, weisen Sie dem nächsten leeren Steckplatz einfach eine Variable zu. Jedes Mal, wenn Sie dem Array einen neuen Wert hinzufügen, erhöhen Sie den Wert, um auf den nächsten zu zeigen.

In C ++ besteht eine bessere Lösung darin, den Standardbibliothekstyp zu verwenden std::list< type >, mit dem das Array auch dynamisch wachsen kann, z.

#include <list>

std::list<int> arr; 

for (int i = 0; i < 10; i++) 
{
    // add new value from 0 to 9 to next slot
    arr.push_back(i); 
}

// add arbitrary value to the next free slot
arr.push_back(22);
Binärbob
quelle
2

Initialisieren Sie zuerst alle Array-Elemente auf null und suchen Sie dann nach null, um den leeren Steckplatz zu finden

kurzwellige Welle
quelle
1

Wenn Sie in C ++ schreiben, ist es besser, Datenstrukturen aus einer Standardbibliothek wie Vektor zu verwenden.

Arrays im C-Stil sind sehr fehleranfällig und sollten nach Möglichkeit vermieden werden.

Trauriger Entwickler
quelle
1

Sie können eine Variable verwenden, um Stellen im Array zu zählen. Wenn Sie also ein neues Element hinzufügen, platzieren Sie es an der richtigen Stelle. Zum Beispiel:

int a = 0;
int arr[5] = { };
arr[a] = 6;
a++;
JavaCakes
quelle
-2

Da ich so viele negative Rückmeldungen erhielt, stellte ich fest, dass meine Lösung falsch war, und änderte sie.

int arr[20] = {1,2,3,4,5};
int index = 5;

void push(int n){
    arr[index] = n;
    index++;
}

push(6)

Das neue Array enthält Werte von 1 bis 6, und Sie können auch eine solche Löschfunktion festlegen.

Prinz kushwaha
quelle
2
Sie haben jedoch nur einen Speicher zugewiesen, der nicht zugeordnet ist. das ist undefiniertes Verhalten.
Toby Speight
@prince kushwaha Dies setzt voraus, dass Sie mehr Speicher zuweisen, als Sie benötigen, anstatt ihn zu verwenden realloc.
Sapphire_Brick
Die Frage, die er stellte, war, wie man den Index des Arrays nach jeder Einfügung verfolgt, was nichts mit der Arraygröße zu tun hat.
Prince Kushwaha