Wie erstellt man ein Array von Structs in C?

Lesezeit: 8 Minuten

Benutzeravatar von Amndeep7
Amdeep7

Ich versuche, ein Array von Strukturen zu erstellen, bei denen jede Struktur einen Himmelskörper darstellt.

Ich habe nicht so viel Erfahrung mit Strukturen, weshalb ich mich entschieden habe, sie anstelle einer ganzen Reihe von Arrays zu verwenden. Ich stoße jedoch weiterhin auf zahlreiche verschiedene Fehler. Ich habe versucht, die Techniken zu implementieren, die ich in verschiedenen Threads und auf StackOverflow gesehen habe (z. B. Array of structs in C und C – initialize array of structs), aber nicht alle waren anwendbar.

Weitere Informationen für diejenigen, die bis hierher gelesen haben: Ich brauche nichts davon, um dynamisch zu sein, ich kenne/definiere die Größe von allem vorher. Ich brauche dies auch als globales Array, da ich in mehreren verschiedenen Methoden darauf zugreife, die Argumente definiert haben (z. B. GLUT-Methoden).

So definiere ich die Struktur in meinem Header:

struct body
{
    double p[3];//position
    double v[3];//velocity
    double a[3];//acceleration
    double radius;
    double mass;
};

Ich habe eine Liste anderer globaler Variablen, die ich definiere, bevor ich das Innere der Struktur definiere, und eine davon ist das Array dieser Struktur (im Grunde genommen, wenn ich in meinem Nebel zu unklar bin, die Zeile unten ist über dem Zeug oben):

struct body bodies[n];

Nur damit du es weißt, n ist etwas, das ich rechtmäßig definiert habe (dh #define n 1).

Ich verwende dieses Array in mehreren verschiedenen Methoden, aber die einfachste und am wenigsten Platz verbrauchende ist eine vereinfachte Form meiner main. Hier initialisiere ich alle Variablen in jeder der Strukturen, nur um die Variablen sicher festzulegen, bevor ich sie auf irgendeine Weise ändere:

  int a, b;
 for(a = 0; a < n; a++)
 {
        for(b = 0; b < 3; b++)
        {
            bodies[a].p[b] = 0;
            bodies[a].v[b] = 0;
            bodies[a].a[b] = 0;
        }
        bodies[a].mass = 0;
        bodies[a].radius = 1.0;
 }

Der aktuelle Fehler, mit dem ich konfrontiert bin, ist nbody.c:32:13: error: array type has incomplete element type wo Zeile 32 ist, wo ich das Array der Strukturen mache.

Eine letzte Klarstellung, mit Überschrift meine ich den Raum darüber int main(void) aber im gleichen *.c Datei.

  • Nun, es funktioniert gut für mich. Erklärst du nicht struct body bodies[n]; Vor struct body {} Erklärung?

    – Jack

    6. Mai 2012 um 4:50 Uhr


  • Beachten Sie, dass die Verwendung von Arrays mit variabler Länge oft mysteriöse Fehler oder Abstürze verursachen kann, wenn die Größe des Arrays die Stapelgröße des Programms auf Ihrem System überschreitet (was völlig außerhalb Ihrer Kontrolle als Programmierer liegt). Es ist besser, malloc() für solche Dinge zu verwenden.

    – Adrian

    10. Juli 2020 um 19:00 Uhr

  • @adrian Ich denke, da ist es ein #defined-Wert, es ist nicht variabel. Es wäre genauso wie struct body bodies[1]oder was auch immer der Wert von ist n ist.

    – Radvylf-Programme

    17. September 2020 um 23:41 Uhr

  • @RedwolfPrograms ah sorry, das habe ich nicht bedacht. Fürs Protokoll, wenn n ist eine Konstante, die zur Kompilierzeit bestimmt werden kann, Sie sind wahrscheinlich sicher.

    – Adrian

    17. September 2020 um 23:57 Uhr

Benutzeravatar von nims
Nims

#include<stdio.h>
#define n 3
struct body
{
    double p[3];//position
    double v[3];//velocity
    double a[3];//acceleration
    double radius;
    double mass;
};

struct body bodies[n];

int main()
{
    int a, b;
     for(a = 0; a < n; a++)
     {
            for(b = 0; b < 3; b++)
            {
                bodies[a].p[b] = 0;
                bodies[a].v[b] = 0;
                bodies[a].a[b] = 0;
            }
            bodies[a].mass = 0;
            bodies[a].radius = 1.0;
     }

    return 0;
}

das funktioniert gut. Ihre Frage war übrigens nicht sehr klar, also passen Sie das Layout Ihres Quellcodes an das obige an.

  • Außerdem habe ich eine Frage zur Platzierung zwischen der Deklaration des Strukturtyps und der tatsächlichen Erstellung einer Instanz davon – ich habe eine andere Struktur, eine, deren Inhalt ich definiert habe unter wo ich zuerst eine Instanz davon mache (diesmal nur eine, kein Array), also warum hat das nicht die massive Reihe von Fehlern gemacht? Es funktionierte einwandfrei, was mich zu der Annahme veranlasste, dass mein Versuch, ein Array zu erstellen, auch hätte funktionieren sollen, aber diesmal funktionierte es nicht. Auch danke für deine Antwort, es hat funktioniert.

    – Amdeep7

    6. Mai 2012 um 15:07 Uhr

  • Hallo, …. 59 Likes ? Ich habe keine Arrays von Struct gesehen, ich sehe nur Arrays von Variablen von Strike …

    Benutzer3402040

    15. März 2017 um 23:10 Uhr


Eine andere Möglichkeit, ein Array von Strukturen zu initialisieren, besteht darin, die Array-Mitglieder explizit zu initialisieren. Dieser Ansatz ist nützlich und einfach, wenn nicht zu viele Struktur- und Array-Mitglieder vorhanden sind.

Verwenden Sie die typedef Bezeichner, um die Wiederverwendung von zu vermeiden struct Anweisung jedes Mal, wenn Sie eine Strukturvariable deklarieren:

typedef struct
{
    double p[3];//position
    double v[3];//velocity
    double a[3];//acceleration
    double radius;
    double mass;
}Body;

Deklarieren Sie dann Ihr Array von Strukturen. Die Initialisierung jedes Elements geht mit der Deklaration einher:

Body bodies[n] = {{{0,0,0}, {0,0,0}, {0,0,0}, 0, 1.0}, 
                  {{0,0,0}, {0,0,0}, {0,0,0}, 0, 1.0}, 
                  {{0,0,0}, {0,0,0}, {0,0,0}, 0, 1.0}};

Um es noch einmal zu wiederholen, dies ist eine ziemlich einfache und unkomplizierte Lösung, wenn Sie nicht zu viele Array-Elemente und große Strukturmitglieder haben und wenn Sie, wie Sie sagten, nicht an einem dynamischeren Ansatz interessiert sind. Dieser Ansatz kann auch nützlich sein, wenn die Strukturmitglieder mit benannten Enum-Variablen (und nicht nur Zahlen wie im obigen Beispiel) initialisiert werden, wodurch der Codeleser einen besseren Überblick über den Zweck und die Funktion einer Struktur und ihrer Mitglieder erhält Anwendungen.

  • Ich liebe das! Schöne und einfache Antwort 👍

    – Ethan

    29. Mai 2019 um 1:32 Uhr

  • typedef für einfache Strukturen ist es eine schlechte Praxis.

    – meni181818

    29. März um 10:20 Uhr

Benutzeravatar von Dounchan
Dunchan

Um alles zusammenzufügen, indem Sie verwenden malloc():

int main(int argc, char** argv) {
    typedef struct{
        char* firstName;
        char* lastName;
        int day;
        int month;
        int year;

    }STUDENT;

    int numStudents=3;
    int x;
    STUDENT* students = malloc(numStudents * sizeof *students);
    for (x = 0; x < numStudents; x++){
        students[x].firstName=(char*)malloc(sizeof(char*));
        scanf("%s",students[x].firstName);
        students[x].lastName=(char*)malloc(sizeof(char*));
        scanf("%s",students[x].lastName);
        scanf("%d",&students[x].day);
        scanf("%d",&students[x].month);
        scanf("%d",&students[x].year);
    }

    for (x = 0; x < numStudents; x++)
        printf("first name: %s, surname: %s, day: %d, month: %d, year: %d\n",students[x].firstName,students[x].lastName,students[x].day,students[x].month,students[x].year);

    return (EXIT_SUCCESS);
}

  • Sollte Ihre Malloc-Zeile numStudents * sizeof(STUDENT) haben?

    – Todd

    24. Juli 2014 um 16:57 Uhr

  • @Todd Es ist besser nicht. sizeof *students ist dasselbe und es ist nicht verkehrt, wenn STUDENT sich jemals ändert.

    – Trient

    11. März 2016 um 18:18 Uhr

  • @trentcl Er hat Speicher für {numStudents} Zeiger zugewiesen. Keine Strukturen, sondern Zeiger. Die Zeigergröße beträgt normalerweise 4 Bytes, während die Größe der Struktur 20 Bytes beträgt. 20 Bytes sind eine Zahl, die durch 4 teilbar ist, daher ist kein Auffüllen erforderlich und die Struktur wird auf jedem 20. Byte von der Startadresse gespeichert. Es funktioniert nur, weil Sie Speicher nur für einen bestimmten Fall zuweisen. Andernfalls könnten andere Mallocs den Speicher Ihrer Strukturen überschreiben, da dieser nicht zugewiesen ist und Sie Ihren Schülerspeicher überlaufen haben.

    – John Smith

    14. Oktober 2019 um 17:36 Uhr

  • @JohnSmith Sie irren sich; Lies es nochmals. sizeof *students ist die Größe von worauf hingewiesen wirddh sizeof(STUDENT)nicht sizeof(STUDENT*). Sie machen genau den Fehler, dass die ptr = malloc(num * sizeof *ptr) Idiom soll vor schützen. prüfen Sie hier (Beachten Sie, dass der Server, wie die meisten modernen PCs, 8-Byte-Zeiger hat, sodass die Größen 8 und 32 anstelle von 4 und 20 sind).

    – Trient

    14. Oktober 2019 um 18:10 Uhr


  • @trentcl Danke für die Erklärung. Ich wurde durch die Syntax des Dereferenzierungszeigers in seiner eigenen Initialisierung verwirrt. Ich würde sagen, es ist ein wenig verwirrend, aber definitiv eine kompaktere Lösung.

    – John Smith

    14. Oktober 2019 um 18:49 Uhr

Ich denke, so könnte man es auch schreiben. Ich bin auch ein Student, also verstehe ich Ihren Kampf. Etwas verspätete Antwort, aber ok.

#include<stdio.h>
#define n 3

struct {
    double p[3];//position
    double v[3];//velocity
    double a[3];//acceleration
    double radius;
    double mass;
}bodies[n];

Bewegung

struct body bodies[n];

nach

struct body
{
    double p[3];//position
    double v[3];//velocity
    double a[3];//acceleration
    double radius;
    double mass;
};

Rest sieht alles gut aus.

Benutzeravatar von Bean helfen
Bohne helfen

Lösung mit Zeigern:

#include<stdio.h>
#include<stdlib.h>
#define n 3
struct body
{
    double p[3];//position
    double v[3];//velocity
    double a[3];//acceleration
    double radius;
    double *mass;
};


int main()
{
    struct body *bodies = (struct body*)malloc(n*sizeof(struct body));
    int a, b;
     for(a = 0; a < n; a++)
     {
            for(b = 0; b < 3; b++)
            {
                bodies[a].p[b] = 0;
                bodies[a].v[b] = 0;
                bodies[a].a[b] = 0;
            }
            bodies[a].mass = 0;
            bodies[a].radius = 1.0;
     }

    return 0;
}

Davids Benutzeravatar
David

Dieser Fehler bedeutet, dass der Compiler die Definition des Typs Ihrer Struktur vor der Deklaration des Arrays von Strukturen nicht finden kann, da Sie sagen, dass Sie die Definition der Struktur in einer Header-Datei haben und der Fehler darin liegt nbody.c Dann sollten Sie überprüfen, ob Sie die Header-Datei korrekt einfügen. Überprüfe dein #include‘s und stellen Sie sicher, dass die Definition der Struktur abgeschlossen ist, bevor Sie eine Variable dieses Typs deklarieren.

  • Ich bezweifle, dass OP Header als Header-Datei bedeutet, wie er schrieb: “Die Zeile unten befindet sich über dem Zeug darüber” vor der Struct-Array-Deklaration, die sich in seiner Datei nbody.c befindet. Lasst uns warten, bis er aufwacht und den Zweifel ausräumt.

    – nims

    6. Mai 2012 um 4:52 Uhr


  • @nims ist richtig, mit Header meinte ich den Bereich über dem main Aussage.

    – Amdeep7

    6. Mai 2012 um 14:39 Uhr

1423240cookie-checkWie erstellt man ein Array von Structs in C?

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

Privacy policy