Wiederholung: Generisches Array
Teil des Abschnitts Objektorientierte Programmierung der C-Journey von Coddy. Lektion 53 von 61.
Aufgabe
EinfachErstellen wir einen GenericArray-Container: eine flexible Datenstruktur, die mithilfe von void*-Zeigern eine Mischung aus Ganzzahlen und Zeichenketten in derselben Sammlung aufnehmen kann.
Du organisierst deinen Code über drei Dateien:
generic_array.h: Definiere die StrukturGenericArraymit drei Mitgliedern: einemvoid**-Array zum Aufnehmen von Zeigern, einemintfür die aktuelle Anzahl und einemintfür die Kapazität. Deklariere die Funktionsprototypen zum Erstellen des Arrays, Hinzufügen von Elementen, Abrufen von Elementen per Index und Freigeben des Arrays.generic_array.c: Implementiere die Funktionalität deines Containers:create_array: reserviert ein GenericArray mit einer vorgegebenen Anfangskapazität und initialisiert count mit 0add_element: speichert einenvoid*-Zeiger am nächsten verfügbaren Platz und erhöht count (vorausgesetzt, die Kapazität ist ausreichend)get_element: gibt denvoid*-Zeiger am angegebenen Index zurückfree_array: gibt das items-Array und die GenericArray-Struktur selbst frei
main.c: Demonstriere dein generisches Array, indem du sowohl Ganzzahlen als auch Zeichenketten speicherst. Lies die Anzahl der hinzuzufügenden Elemente ein und lies anschließend für jedes Element einen Typindikator (ifür Ganzzahl,sfür Zeichenkette), gefolgt vom Wert, ein. Nachdem alle Elemente hinzugefügt wurden, durchlaufe das Array und gib jeden Wert aus. Gib Ganzzahlen direkt als Zahl aus. Gib Zeichenketten direkt als Text aus.
Dein Programm erhält:
- Die Anzahl der hinzuzufügenden Elemente
- Für jedes Element: einen Typindikator (
ioders), gefolgt vom Wert
Beim Hinzufügen von Ganzzahlen reservierst du Speicher für den int und speicherst den Zeiger. Beim Hinzufügen von Zeichenketten reservierst du Speicher und kopierst die Zeichenkette. Beim Abrufen wandelst du den Zeiger zurück in den passenden Typ um, um ihn auszugeben.
Wichtig: Um die Typen für die Ausgabe zu verfolgen, kannst du in main ein einfaches paralleles Array mit Typindikatoren verwenden oder das Typindikatorzeichen zusammen mit jedem Element speichern.
Beispielausgabe bei den Eingaben 3, anschließend i 42, s Hello, i 100:
42
Hello
100Beispielausgabe bei den Eingaben 4, anschließend s World, s Generic, i -5, s Arrays:
World
Generic
-5
ArraysDenke daran, Include-Guards in deiner Headerdatei zu verwenden. Der Container selbst muss nicht wissen, welche Typen er speichert. Er enthält lediglich void*-Zeiger. Die Verantwortung dafür, den Typ zu kennen, liegt bei dem Code, der Elemente hinzufügt und abruft.
Probier es selbst
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "generic_array.h"
int main() {
int n;
scanf("%d", &n);
// TODO: Erstelle ein GenericArray mit Kapazität n
// TODO: Erstelle ein paralleles Array zur Typverfolgung (char-Array der Größe n)
// TODO: Für jedes Element:
// - Lies den Typindikator (i oder s)
// - Lies den Wert
// - Falls Ganzzahl: Speicher für int allokieren, Wert speichern, zum Array hinzufügen
// - Falls Zeichenkette: Speicher für string allokieren, Wert kopieren, zum Array hinzufügen
// - Speichere den Typindikator in deinem parallelen Array
// TODO: Iteriere durch das Array und gib jedes Element aus
// - Prüfe den Typ aus deinem parallelen Array
// - Caste den void* zurück zum entsprechenden Typ und gib aus
// TODO: Gib allen allokierten Speicher frei (Ganzzahlen, Strings und das Array)
return 0;
}
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der modularen Programmierung
Header-DateienInclude GuardsQuelldateienStatische FunktionenWiederholung: Modularer Taschenrechner4Kapselung
Konzept der Opaque PointersOpaque Structs definierenGetter und SetterValidierung in SetternRückblick: Die geheime Box7Funktionszeiger
Funktionszeiger deklarierenFunktionszeiger aufrufenTypedef für FunktionszeigerFunktionen als Argumente übergebenZusammenfassung: Calculator Dispatch10Generische Container
Wiederholung: Void-PointerGenerischer WrapperGenerisches SwapGenerisches VergleichenWiederholung: Generisches Array2Objekte und Methoden
Structs als ObjekteDer 'Self'-PointerConst-CorrectnessPointer vs. WertHilfsmethodenZusammenfassung: Point Manager5Projekt: Einfaches Bankkonto
Projekt-SetupImplementierung des Kontos3Objekt-Lebenszyklus
Konstruktor-MusterDestruktor-MusterStack-InitialisierungTiefe KopieRückblick: String-Wrapper6Vererbung durch Komposition
Struct-EinbettungDie First-Member-RegelZugriff auf Parent-MemberUpcastingRückblick: Formenhierarchie9Projekt: Formen-Zeichner
ProjektübersichtKreis-ImplementierungRechteck-ImplementierungPolymorphe VerwendungShape-ContainerÜbe selbstständig: Online-C-Compiler