Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Industrial programming >> C Sprache

Flexible Array-Member in C-Strukturen für dynamische Datenbehandlung meistern

Flexible Array Member ermöglichen die Handhabung von Arrays innerhalb von Strukturen ohne festgelegte Größe. Diese Arrays erhalten ihre Größe zur Laufzeit. Eine Struktur in C ist ein benutzerdefinierter Datentyp, bei dem mehrere Member verschiedener Datentypen unter einem Namen zusammengefasst werden.

Nachfolgend die Syntax für die Deklaration einer Struktur in C:

 struct StructName {
    daten_typ member1;
    daten_typ member2;
    // ...
}; 

Jeder Member kann einen unterschiedlichen Datentyp haben.

Flexible Array Member erweitern Strukturen, indem sie ein dynamisch dimensioniertes Array am Ende der festen Member halten – alles zusammen in einem zusammenhängenden Speicherblock. In diesem Kapitel sehen wir, wie sie innerhalb von Strukturen funktionieren.

Flexible Array Member in Strukturen

flexibler Array-Member ist ein Array innerhalb einer Struktur ohne feste Größe. Sein Speicher wird zur Laufzeit dynamisch mittels malloc(), calloc() oder ähnlicher Funktionen allokiert und er wird mit leeren eckigen Klammern [] deklariert.

Der flexible Array-Member muss am Ende der Struktur deklariert werden, und es muss mindestens ein weiterer Member davor existieren.

Folgende Syntax deklariert ein flexibles Array-Member in einer Struktur:

 struct StructName {
    daten_typ member1;
    daten_typ flexibles_array[]; // flexibles Array-Member
}; 

Hier ist daten_typ der Datentyp des Arrays und arrayName[] das flexible Array ohne feste Größe.

Speicherallokation für flexible Array-Member

Da ein flexibler Array-Member keine feste Größe hat, allokiert der Compiler keinen Speicher dafür innerhalb der Struktur. Der sizeof-Operator berechnet nur die Größe der festen Member, ohne das flexible Array. Daher müssen wir den Speicher manuell allokieren, wenn wir solche Strukturen erstellen.

Der gesamte benötigte Speicher berechnet sich wie folgt:

 Gesamtspeicher = sizeof(Struktur) + (Anzahl Elemente × sizeof(Elementtyp)) 

Hierbei gibt sizeof(Struktur) den Speicher für die festen Member an, und (Anzahl Elemente × sizeof(Elementtyp)) den Speicher für das flexible Array. Die Summe ergibt den insgesamt zu allokierenden Speicher.

Beispiel 1: Speicherallokation für ein flexibles Array-Member

Im folgenden Beispiel definieren wir eine Struktur mit einem festen Member und einem flexiblen Array und allokieren Speicher für das flexible Array.

 #include <stdio.h>
#include <stdlib.h>
struct Example {
    int id;
    int arr[]; // flexibles Array-Member
};
int main() {
    int size = 5;
    // Speicher für Struktur + flexibles Array allokieren
    struct Example *e = malloc(sizeof(struct Example) + size * sizeof(int));
    if (e != NULL) {
        printf("Gesamt allokierter Speicher: %zu Bytes\n", sizeof(struct Example) + size * sizeof(int));
        free(e);
    }
    return 0;
} 

Hier liefert sizeof(struct Example) 4 Bytes für den Member id. Der Speicher für das flexible Array beträgt 5 × sizeof(int) = 20 Bytes. Gesamt allokierter Speicher: 4 + 20 = 24 Bytes. Die Ausgabe:

 Gesamt allokierter Speicher: 24 Bytes 

Beispiel 2: Zugriff auf ein flexibles Array in einer Struktur

In diesem Beispiel definieren wir eine Student-Struktur mit einem festen Member (id) und einem flexiblen Array-Member (marks). Wir allokieren dynamisch Speicher für das flexible Array und greifen auf seine Elemente zu. Zugriff über die allokierte Größe hinaus führt zu undefiniertem Verhalten, daher greifen wir nur auf marks[0] bis marks[2] zu.

 #include <stdio.h>
#include <stdlib.h>
struct Student {
    int id;
    int marks[]; // flexibles Array-Member
};
int main() {
    int subjects = 3;
    // Speicher für Struktur + flexibles Array allokieren
    struct Student *s = malloc(sizeof(struct Student) + subjects * sizeof(int));
    if (s != NULL) {
        s->id = 102;
        s->marks[0] = 80;
        s->marks[1] = 75;
        s->marks[2] = 88;
        printf("Studenten-ID: %d\n", s->id);
        printf("Noten: %d, %d, %d\n", s->marks[0], s->marks[1], s->marks[2]);
        printf("Gesamt allokierter Speicher: %zu Bytes\n", sizeof(struct Student) + subjects * sizeof(int));
        free(s);
    }
    return 0;
} 

Die Ausgabe des Programms:

 Studenten-ID: 102
Noten: 80, 75, 88
Gesamt allokierter Speicher: 16 Bytes 

Dynamische Größenänderung flexibler Array-Member

Flexible Arrays können mit der realloc()-Funktion vergrößert oder verkleinert werden. Diese Funktion erweitert entweder den bestehenden Speicherblock oder allokiert einen neuen Block und kopiert die vorhandenen Daten automatisch.

Um ein flexibles Array zu vergrößern, rufen wir realloc() mit der neuen Gesamtgröße auf, berechnet nach der Formel:

 sizeof(Struktur) + (neue_Anzahl_Elemente × sizeof(Elementtyp)) 

Hinweis: Speichern Sie das Ergebnis von realloc() immer in einem temporären Zeiger. Schlägt die Allokation fehl, bleibt der ursprüngliche Zeiger erhalten. Aktualisieren Sie nach der Größenänderung den Größen-Zähler und initialisieren Sie nur die neu hinzugefügten Elemente.

Beispiel 3: Dynamische Größenänderung flexibler Array-Member

In diesem Beispiel erstellen wir eine Student-Struktur, die zunächst 3 Noten hält. Später vergrößern wir das flexible Array auf 6 Noten mittels realloc(). Die bereits gespeicherten Noten bleiben unverändert, manuelles Kopieren entfällt.

 #include <stdio.h>
#include <stdlib.h>
struct Student {
    int id;
    int count; // Dieses Feld hilft, die aktuelle Array-Größe zu verfolgen
    int marks[]; // Flexibles Array-Member
};
int main() {
    // Schritt 1: Initialallokation für 3 Noten
    int initial_elements = 3;
    struct Student *s = malloc(sizeof(struct Student) + initial_elements * sizeof(int));
    if (s != NULL) {
        s->id = 101;
        s->count = initial_elements; // Aktuelle Array-Größe speichern
        // Initiale Größen anzeigen
        printf("Strukturgröße: %zu Bytes\n", sizeof(struct Student)); // Ausgabe: 8 Bytes (id + count)
        printf("Initiale Array-Elemente: %d\n", s->count); // Ausgabe: 3
        printf("Initialer Gesamtspeicher: %zu Bytes\n", sizeof(struct Student) + initial_elements * sizeof(int)); // Ausgabe: 20 Bytes
        // Schritt 2: Vergrößerung auf 6 Noten
        int new_elements = 6;
        struct Student *temp = realloc(s, sizeof(struct Student) + new_elements * sizeof(int));
        if (temp != NULL) {
            s = temp;
            s->count = new_elements; // Array-Größen-Tracker aktualisieren
            // Neue Größen anzeigen
            printf("\nNach Vergrößerung:\n");
            printf("Strukturgröße: %zu Bytes\n", sizeof(struct Student)); // Immer noch 8 Bytes
            printf("Neue Array-Elemente: %d\n", s->count); // Ausgabe: 6
            printf("Neuer Gesamtspeicher: %zu Bytes\n", sizeof(struct Student) + new_elements * sizeof(int)); // Ausgabe: 32 Bytes
        }
        free(s);
    }
    return 0;
} 

Die folgende Ausgabe zeigt die Strukturgröße und den Gesamtspeicher für das initiale und das vergrößerte flexible Array.

 Strukturgröße: 8 Bytes
Initiale Array-Elemente: 3
Initialer Gesamtspeicher: 20 Bytes
Nach Vergrößerung:
Strukturgröße: 8 Bytes
Neue Array-Elemente: 6
Neuer Gesamtspeicher: 32 Bytes 

In diesem Kapitel haben wir flexible Array-Member in C-Strukturen kennengelernt. Sie werden am Ende einer Struktur deklariert, verarbeiten variabel lange Daten, sparen Speicher und passen sich leicht an unterschiedliche Datengrößen an. Wir haben auch gesehen, wie man sie allokiert, darauf zugreift und ihre Größe ändert.


C Sprache

  1. Die C for-Schleife meistern: Syntax, Mechanik und praktische Beispiele
  2. std::map in C++ meistern: Umfassender Guide mit Code‑Beispielen
  3. C# Interfaces verstehen: Definition, Beispiel und praktische Anwendung
  4. C++ Klassen & Objekte: Praktischer Leitfaden zur objektorientierten Programmierung
  5. C Variablen, Datentypen und Konstanten – Ein praktischer Leitfaden
  6. Top 15 C++ Online-Kurse, um die Sprache zu meistern (2024 Update)
  7. C++ Vererbung: Public, Protected & Private erklärt
  8. C# Programmstruktur verstehen: Kernkomponenten & Beispiel
  9. C# Mehrdimensionale Arrays: 2D Arrays mit Codebeispielen erklärt
  10. C# Queues meistern: Enqueue, Dequeue und First-In-First-Out Operationen erklärt