webentwicklung-frage-antwort-db.com.de

Wie man ein Array von Strukturen durchläuft

In meiner Anwendung verwende ich ein Array von Strukturen, und ich muss das Array durchlaufen. Was ist der richtige Weg, dies zu tun? Wie kann ich überprüfen, ob ich das Ende des Arrays erreicht habe?

// structure
struct MyData {
  int count;
  char name[20];
  float average;
}

Ich habe versucht, so zu iterieren, aber meine Anwendung stürzt ab:

struct MyData data[2] = { {3, "name1", 1.0}, {5, "name2", 2.5} };
struct MyData* ptr = data;

while (*ptr != NULL) {
  // print the contents, works ok for 2 elements

  ptr++; // increment the pointer
}
10
Dariusz

Wie wird ein Array von Strukturen zugewiesen?

In Ihrem Fall sieht das MyData[2]-Array im Speicher folgendermaßen aus:

| count | name | average | count | name | average |
^ -- your ptr points here 

Dies ist ein einzelner, durchgehender Raum mit der Größe 3 * sizeof (struct MyData).

Wenn Sie eine ptr++-Operation ausführen, bewegt sich der Zeiger zur nächsten Struktur im Array. Dies bedeutet, dass die Größe eines einzelnen struct MyData berücksichtigt wird. 

| count | name | average | count | name | average |
                         ^ -- after ptr++ your ptr points here

Nach einem weiteren ptr++ zeigt Ihr Zeiger auf den Speicher gleich nach Ihr Array.

| count | name | average | count | name | average | 
                                                  ^ -- another ptr++ and your ptr points here

Wenn Sie Ihren ptr-Zeiger dereferenzieren, greifen Sie auf Speicher zu, der noch nicht belegt oder sogar belegt ist. Dies ist undefiniertes Verhalten, und deshalb stürzt Ihre Anwendung ab.

Wie iterieren?

Es gibt mehrere Möglichkeiten, dies zu tun. Beachten Sie, dass nicht alle Möglichkeiten in allen Fällen anwendbar sind.

Ein einfaches für

Sehr oft kennen wir einfach die Größe des Arrays. Wir können dann einfach eine normale for-Schleife verwenden, um den Inhalt zu durchlaufen.

int len = 2;
struct MyData data[len] = { {3, "name1", 1.0}, {5, "name2", 2.5} };
struct MyData* ptr = data;
for (int i=0; i<2; i++, ptr++ ) {
   // do your thing with the ptr
   // and note that ptr gets increased inside for
}

Mit sizeof die Arraylänge bestimmen

struct MyData data[2] = { {3, "name1", 1.0}, {5, "name2", 2.5} };
struct MyData* ptr = data;
struct MyData* endPtr = data + sizeof(data)/sizeof(data[0]);
while ( ptr < endPtr ){
   // do your thing with the ptr
   ptr++;
}

Die Funktion sizeof(data)/sizeof(data[0]) berechnet die Anzahl der Elemente: Ermittelt die Gesamtgröße eines Arrays und dividiert sie durch die Größe eines einzelnen Elements. 

Diese Methode hat ihre Nachteile. Es kann nicht verwendet werden, wenn das Array als Zeiger deklariert ist! Wenn wir beispielsweise das Array als Parameter an eine Funktion übergeben, wird es normalerweise in einen Zeiger konvertiert - und dann können wir die Größe des Arrays nicht bestimmen.

19
Dariusz

Wenn Sie keine Kontrolle über die Größe des Arrays haben und nicht einmal danach fragen können, können Sie versuchen, Ihren Code zu reorganisieren, ohne ein Array von MyData, sondern ein Array von Zeigern auf MyData. .] Ihr Array muss dann um einen Slot länger sein, um einen Guard mit dem Wert NULL zu speichern.

Ihre Iteration wird wie die aussehen, die Sie als Beispiel geschrieben haben.

// N is the number of MyData instances you have
MyData* vData[N+1];
// vData[i] is filled, and vData[N] = NULL

// ...

MyData* vPtr = vData[0];
while(vPtr) {
    // ...
}

Dazu müssen Sie jedoch den Typ Ihres Arrays von MyData[] in MyData*[] ändern. Wenn Sie nicht können, sollten Sie der Antwort von Dariusz folgen.

0
Oragon Efreet