Wie erstellt man ein Array von Strukturen in C?

100

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

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

Weitere Informationen für diejenigen, die bisher gelesen haben: Ich brauche nichts davon, um dynamisch zu sein, ich kenne / definiere die Größe von allem im Voraus. Ich brauche dies auch, um ein globales Array zu sein, da ich mit verschiedenen Methoden, die Argumente definiert haben (dh GLUT-Methoden), darauf zugreife.

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 meiner beschlagenen Sprache zu unklar bin, die folgende Zeile ist über dem Zeug oben):

struct body bodies[n];

Nur damit Sie wissen, nist etwas, das ich legitim definiert habe (dh #define n 1).

Ich verwende dieses Array in verschiedenen Methoden, aber die einfachste und platzsparendste ist eine vereinfachte Form meiner Hauptmethode. Hier initialisiere ich alle Variablen in jeder der Strukturen, 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 typewo in Zeile 32 das Array der Strukturen erstellt wird.

Eine letzte Klarstellung, mit Header meine ich das Leerzeichen darüber, int main(void)aber in derselben *.cDatei.

Amndeep7
quelle
Nun, es funktioniert gut für mich. Erklären Sie nicht struct body bodies[n];vor der struct body {}Erklärung?
Jack
Beachten Sie, dass die Verwendung von Arrays mit variabler Länge häufig mysteriöse Fehler oder Abstürze verursachen kann, wenn die Größe des Arrays die Stapelgröße des Programms auf Ihrem System überschreitet (was als Programmierer völlig außerhalb Ihrer Kontrolle liegt). Es ist besser, malloc () für solche Dinge zu verwenden.
Adrian

Antworten:

107
#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 oben Gesagte an.

Nims
quelle
Außerdem habe ich eine Frage zur Platzierung zwischen der Deklaration des Strukturtyps und der tatsächlichen Erstellung einer Instanz - ich habe eine andere Struktur, die ich im Folgenden definiert habe, wo ich zuerst eine Instanz davon erstelle (nur eine diesmal kein Array), warum hat dies dann nicht die massive Reihe von Fehlern verursacht? Es hat gut funktioniert, was mich zu der Annahme veranlasste, dass mein Versuch, ein Array zu erstellen, auch hätte funktionieren sollen, aber diesmal hat es nicht funktioniert. Vielen Dank auch für Ihre Antwort, es hat funktioniert.
Amndeep7
1
Hallo, .... 59 Likes? Ich habe keine Arrays von struct gesehen, ich sehe nur Arrays von variablen von geschlagen ...
12

Ich denke, du könntest es auch so schreiben. Ich bin auch ein Student, also verstehe ich Ihren Kampf. Eine etwas späte 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];
Christakitos
quelle
11

Um alles zusammenzusetzen, indem Sie Folgendes 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);
}
Dounchan
quelle
8
Sollte Ihre Malloc-Linie numStudents * sizeof (STUDENT) haben?
Todd
@Todd Es ist besser nicht zu. sizeof *studentsist das gleiche und es wird nicht falsch sein, wenn sich STUDENT jemals ändert.
Trentcl
@trentcl Er hat Speicher für die Anzahl der Zeiger {numStudents} 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 durch 4 teilbare Zahlen, daher ist kein Auffüllen erforderlich, und die Struktur wird auf jedem 20. Byte ab der Startadresse gespeichert. Dies funktioniert nur, weil Sie nur für einen bestimmten Fall Speicher zuweisen. Andernfalls könnten andere Mallocs das Gedächtnis Ihrer Strukturen überschreiben, da es nicht zugeordnet ist und Sie das Gedächtnis Ihres Schülers überflogen haben.
John Smith
3
@ JohnSmith Sie irren sich; Lies es nochmals. sizeof *studentsist die Größe dessen, worauf hingewiesen wird , dh sizeof(STUDENT)nicht sizeof(STUDENT*). Sie machen genau den Fehler, vor dem sich die ptr = malloc(num * sizeof *ptr)Redewendung schützen soll. Überprüfen Sie dies hier (beachten Sie, dass der Server wie die meisten modernen PCs über 8-Byte-Zeiger verfügt, sodass die Größen 8 und 32 anstelle von 4 und 20 sind).
Trentcl
@trentcl Danke für die Erklärung. Die Syntax des Dereferenzierungszeigers in seiner eigenen Initialisierung hat mich verwirrt. Ich würde sagen, es ist eine etwas verwirrende, aber definitiv kompaktere Lösung.
John Smith
8

Bewegung

struct body bodies[n];

nachher

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

Ruhe alles sieht gut aus.

vrk001
quelle
6

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 den Bezeichner typedef, um zu vermeiden, dass die structAnweisung jedes Mal wiederverwendet wird, 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 zu wiederholen, dies ist eine ziemlich einfache und unkomplizierte Lösung, wenn Sie nicht zu viele Array-Elemente und große Strukturelemente haben und wenn Sie, wie Sie sagten, nicht an einem dynamischeren Ansatz interessiert sind. Dieser Ansatz kann auch nützlich sein, wenn die Strukturelemente 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 Elemente in bestimmten Fällen erhält Anwendungen.

Abdel Aleem
quelle
1
Ich liebe das! Schöne und einfache Antwort 👍
Ethan
1

Dieser Fehler bedeutet, dass der Compiler die Definition des Strukturtyps vor der Deklaration des Strukturarrays nicht finden kann, da Sie sagen, dass Sie die Definition der Struktur in einer Header-Datei haben und der Fehler nbody.cdann vorliegt Sie sollten überprüfen, ob Sie die Header-Datei korrekt einfügen. Überprüfen Sie Ihre #includeund stellen Sie sicher, dass die Definition der Struktur erfolgt, bevor Sie eine Variable dieses Typs deklarieren.

David
quelle
Ich bezweifle, dass OP Header als Header-Datei bedeutet, wie er schrieb, "die Zeile darunter steht über dem Material oben" vor der Struktur-Array-Deklaration, die sich in seiner Datei nbody.c befindet. Warten wir, bis er aufwacht und den Zweifel beseitigt.
Nims
@nims ist korrekt, mit Header meinte ich den Bereich über der mainAnweisung.
Amndeep7
1

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;
}
Bean helfen
quelle