Array in C-Struktur

Lesezeit: 4 Minuten

Benutzer-Avatar
Greg

Ich möchte zwei Arrays in einer Struktur haben, die beim Start initialisiert werden, aber weiter bearbeitet werden müssen. Ich brauche drei Instanzen der Struktur, damit ich in eine bestimmte Struktur indizieren und sie nach Belieben ändern kann. Ist es möglich?

Das ist, was ich dachte, ich könnte tun, aber ich bekomme Fehler:

struct potNumber{
    int array[20] = {[0 ... 19] = 10};
    char *theName[] = {"Half-and-Half", "Almond", "Rasberry", "Vanilla", …};
} aPot[3];

Dann greife ich wie folgt auf die Strukturen zu:

 printf("some statement %s", aPot[0].array[0]);
 aPot[0].theName[3];
 …

  • Welche Fehler erhalten Sie?

    – Andreas Weiß

    2. März 2011 um 16:38 Uhr

  • Ist das wirklich so bei dir struct ist definiert?

    – Wo

    2. März 2011 um 16:46 Uhr

Benutzer-Avatar
pmg

Die Struktur selbst enthält keine Daten. Sie müssen Objekte des Strukturtyps erstellen und die Objekte festlegen …

struct potNumber {
    int array[20];
    char *theName[42];
};

/* I like to separate the type definition from the object creation */
struct potNumber aPot[3];
/* with a C99 compiler you can use 'designated initializers' */
struct potNumber bPot = {{[7] = 7, [3] = -12}, {[4] = "four", [6] = "six"}};

for (i = 0; i < 20; i++) {
  aPot[0].array[i] = i;
}
aPot[0].theName[0] = "Half-and-Half";
aPot[0].theName[1] = "Almond";
aPot[0].theName[2] = "Rasberry";
aPot[0].theName[3] = "Vanilla";
/* ... */

for (i = 0; i < 20; i++) {
  aPot[2].array[i] = 42 + i;
}
aPot[2].theName[0] = "Half-and-Half";
aPot[2].theName[1] = "Almond";
aPot[2].theName[2] = "Rasberry";
aPot[2].theName[3] = "Vanilla";
/* ... */

  • Vergessen Sie nicht, dass Sie Strukturen initialisieren können; Entschuldigen Sie die beschissene Formatierung: struct potNumber aPot = { { [0]…[19] = 10 }, {“Half-and-Half”, “Mandel”, “Himbeere”, “Vanille”…….} };

    – David gegeben

    2. März 2011 um 16:48 Uhr

  • @David: ja, bis auf die ..., das funktioniert. Beispiel in meinem Snippet oben hinzugefügt. Vielen Dank.

    – pmg

    2. März 2011 um 16:55 Uhr

  • @David: Das sind sehr GCC-artige Initialisierungen (und da es Linux ist, nehme ich GCC an). Ich habe die noch nie gesehen ...... Zeug aber, ist das überhaupt gültig?

    – Wo

    2. März 2011 um 16:56 Uhr


  • Es ist nur der Beispielcode, der aus dem OP ausgeschnitten und eingefügt wurde. TBH, das dachte ich mir [0]…[19] war C99, ist es aber nicht. gcc unterstützt [0…19] obwohl.

    – David gegeben

    2. März 2011 um 17:08 Uhr

  • Sollten das nicht Saiten sein strcpyd in die Strukturen?

    Benutzer4945014

    30. März 2021 um 21:54 Uhr

In C struct müssen Array-Elemente eine feste Größe haben, also die char *theNames[] ist ungültig. Auch können Sie eine Struktur auf diese Weise nicht initialisieren. In C sind Arrays statisch, dh man kann ihre Größe nicht dynamisch ändern.

Eine korrekte Deklaration der Struktur würde wie folgt aussehen

struct potNumber{
    int array[20];
    char theName[10][20];
};

und du initialisierst es so:

struct potNumber aPot[3]=
{
    /* 0 */
    { 
        {10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 /* up to 20 integer values*/ },
        {"Half-and-Half", "Almond", "Raspberry", "Vanilla", /* up to 10 strings of max. 20 characters */ }
    },
    /* 1 */
    { 
        {10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 /* up to 20 integer values*/ },
        {"Half-and-Half", "Almond", "Raspberry", "Vanilla", /* up to 10 strings of max. 20 characters */ }
    },
    /* 2 */
    { 
        {10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 /* up to 20 integer values*/ },
        {"Half-and-Half", "Almond", "Raspberry", "Vanilla", /* up to 10 strings of max. 20 characters */ }
    }
};

Aber ich bin mir ziemlich sicher, dass das nicht das ist, was Sie wollen. Der vernünftige Weg, dies zu tun, erforderte einen Boilerplate-Code:

struct IntArray
{
    size_t elements;
    int *data;
};

struct String
{
    size_t length;
    char *data;
};

struct StringArray
{
    size_t elements;
    struct String *data;
};
/* functions for convenient allocation, element access and copying of Arrays and Strings */

struct potNumber
{
    struct IntArray array;
    struct StringArray theNames;
};

Ich persönlich rate dringend davon ab, nackte C-Arrays zu verwenden. Alles über Hilfsstrukturen und -funktionen zu erledigen, hält Sie von Pufferunter-/überläufen und anderen Problemen fern. Jeder ernsthafte C-Programmierer erstellt im Laufe der Zeit eine umfangreiche Code-Bibliothek mit solchen Dingen.

  • ok danke für deine hilfe, könntest du mir ein beispiel geben, wie ich die daten eingeben würde und wie ich dann darauf zugreifen könnte?

    – Greg

    2. März 2011 um 20:04 Uhr

  • herabgestuft, weil Flexible Array-Mitglieder sind seit C99 verfügbar, 12 Jahre bevor diese Antwort geschrieben wurde.

    – Janus Troelsen

    17. Mai 2021 um 23:08 Uhr


  • @JanusTroelsen: Wenn Sie wüssten, wie Flexible Array Members funktionieren, hätten Sie diesen schlecht informierten Kommentar nicht geschrieben (und abgelehnt). FAMs funktionieren nur für das allerletzte Element in einer Struktur und sind mit mehreren Einschränkungen verbunden. OP muss sich damit auseinandersetzen mehr als ein Array unterschiedlicher Länge. FAMs können das nicht.

    – Datenwolf

    18. Mai 2021 um 5:25 Uhr

  • @datenwolf Auch wenn FAMs hier nicht anwendbar sind, ist der Satz “In C struct array elements must have a fixed size” bei Vorhandensein von FAMs falsch.

    – Janus Troelsen

    18. Mai 2021 um 6:05 Uhr

  • @JanusTroelsen: Auch bei FAMs darf nur das allerletzte Element in einer Struktur ein FAM sein. Alles, was nicht das letzte Element einer Struktur ist, einschließlich Arrays, muss eine feste Größe haben.

    – Datenwolf

    18. Mai 2021 um 10:14 Uhr

1205420cookie-checkArray in C-Struktur

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

Privacy policy