Gibt es gezackte Arrays in C/C++?

Lesezeit: 4 Minuten

Gibt es gezackte Arrays in CC
Unbekannt

Gibt es so etwas wie ein gezacktes Array in C oder C++?

Wenn ich das kompiliere:

int jagged[][] = { {0,1}, {1,2,3} };

Ich bekomme diesen Fehler:

Fehler: Die Deklaration von `jagged’ als mehrdimensionales Array muss Grenzen für alle Dimensionen außer der ersten haben

In CI würde ein Array von Zeigern verwendet.

Zum Beispiel:

int *jagged[5];

jagged[0] = malloc(sizeof(int) * 10);
jagged[1] = malloc(sizeof(int) * 3);

usw usw.

  • Was ist in diesem Beispiel der richtige Weg, um den Speicher freizugeben?

    – papgeo

    29. Juni 2017 um 13:57 Uhr

  • frei (gezackt[0]); frei (gezackt[1]);

    – Nicolás Abram

    2. März 2019 um 5:13 Uhr

Es gibt eine Reihe von Möglichkeiten, dies zu tun. Hier ist ein anderer Weg:

int jagged_row0[] = {0,1};
int jagged_row1[] = {1,2,3};
int *jagged[] = { jagged_row0, jagged_row1 };

  • +1. Hier zeigen sich die zusammengesetzten Literale von C99: int *jagged[] = { (int[]){0,1}, (int[]){1, 2, 3} }; ist das nicht auch schön?

    – Johannes Schaub – litb

    5. Juli 2009 um 9:08 Uhr

  • Das Problem bei dieser Lösung besteht darin, dass die Teilarrays sofort in Zeiger zerfallen, sodass Sie keine Möglichkeit haben, die Grenzen zu bestimmen.

    anon

    5. Juli 2009 um 9:36 Uhr

  • @Neil, daran habe ich überhaupt nicht gedacht. Natürlich haben Sie Recht. Guter Punkt 🙂

    – Johannes Schaub – litb

    5. Juli 2009 um 9:41 Uhr

  • @Neil: Hier sind Wächterwerte praktisch, um das Ende des Arrays zu markieren

    – Christoph

    5. Juli 2009 um 10:06 Uhr

  • @Christoph Guardian-Werte können für Zahlenarrays problematisch sein, da es möglicherweise keinen zulässigen “speziellen” Wert gibt. Ich denke, dass es besser ist, die Array-Dimension irgendwie explizit zu speichern.

    anon

    5. Juli 2009 um 10:15 Uhr

Wenn Sie es nur initialisieren möchten, können Sie sagen:

int jagged[][3] = { {0,1}, {1,2,3} };

aber das Array wird immer noch die Form haben [2][3]. Wenn Sie ein echtes gezacktes Array wünschen, müssen Sie es dynamisch erstellen. Und wenn Sie das tun und C++ verwenden, sollten Sie a verwenden std::vectorwie Friol vorschlägt.

Gibt es gezackte Arrays in CC
Friol

Im C++ (nicht kompiliert, und wahrscheinlich gibt es eine kompaktere Syntax):

std::vector<std::vector<int> > myArray;

myArray.push_back(std::vector<int>());
myArray.push_back(std::vector<int>());

myArray[0].push_back(0);
myArray[0].push_back(1);

myArray[1].push_back(1);
myArray[1].push_back(2);
myArray[1].push_back(3);

So können Sie jetzt beispielsweise mit myArray auf die Elemente zugreifen[0][0]etc.

1646345412 893 Gibt es gezackte Arrays in CC
Faisal Vali

In C99 können Sie Folgendes tun:

int jagged_row0[] = {0,1};
int jagged_row1[] = {1,2,3};

int (*jagged[])[] = { &jagged_row0, &jagged_row1 }; // note the ampersand

// also since compound literals are lvalues ...
int (*jagged2[])[] = { &(int[]){0,1}, &(int[]){1,2,3} };  

Der einzige Unterschied hier (im Vergleich zur Antwort von rampion) besteht darin, dass die Arrays nicht zu Zeigern zerfallen und man über eine andere Indirektionsebene auf die einzelnen Arrays zugreifen muss – (z *jagged[0] – und die Größe jeder Reihe muss aufgezeichnet werden – dh sizeof(*jagged[0]) lässt sich nicht kompilieren) – aber sie sind bis auf die Knochen gezackt 😉

  • Ich dachte, Sie können keine Arrays von unvollständigen Typen erstellen … oh, Sie erstellen eine Reihe von Zeigern auf einen unvollständigen Typ, das ist möglich, aber Sie kaufen nichts über die Antwort von Rampion.

    – Ben Voigt

    20. Juli 2012 um 19:38 Uhr

Der Grund, warum Sie den Fehler erhalten haben, ist, dass Sie die Grenzen für mindestens die äußere Dimension angeben müssen; dh

int jagged[][3] = {{0,1},{1,2,3}};

Du kannst nicht gezackt haben[0] ein 2-Element-Array aus int und gezackt sein[1] ein 3-Element-Array von int sein; ein Array mit N Elementen hat einen anderen Typ als ein Array mit M Elementen (wobei N != M), und alle Elemente eines Arrays müssen denselben Typ haben.

Was du kann tun Sie, was die anderen oben vorgeschlagen haben, und erstellen Sie gezackt als Array von Zeigern auf int; Auf diese Weise kann jedes Element auf Integer-Arrays unterschiedlicher Größe zeigen:

int row0[] = {0,1};
int row1[] = {1,2,3};
int *jagged[] = {row0, row1};

Obwohl row0 und row1 unterschiedliche Typen sind (2-Element- vs. 3-Element-Arrays von int), werden sie im Kontext des Initialisierers beide implizit in denselben Typ konvertiert (int *).

  • Ich dachte, Sie können keine Arrays von unvollständigen Typen erstellen … oh, Sie erstellen eine Reihe von Zeigern auf einen unvollständigen Typ, das ist möglich, aber Sie kaufen nichts über die Antwort von Rampion.

    – Ben Voigt

    20. Juli 2012 um 19:38 Uhr

1646345413 75 Gibt es gezackte Arrays in CC
Gemeinschaft

Mit C++11-Initialisiererlisten lässt sich dies kompakter schreiben:

#include <vector>
#include <iostream>

int main() {
    // declare and initialize array
    std::vector<std::vector<int>> arr = {{1,2,3}, {4,5}};
    // print content of array
    for (auto row : arr) {
        for (auto col : row)
            std::cout << col << " ";
        std::cout << "\n";
    }
}

Die Ausgabe ist:

$ g++ test.cc -std=c++11 && ./a.out
1 2 3 
4 5 

Als Referenz:

927970cookie-checkGibt es gezackte Arrays in C/C++?

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

Privacy policy