Stack-Initialisierung
Teil des Abschnitts Objektorientierte Programmierung der C-Journey von Coddy. Lektion 14 von 61.
Nicht jedes Objekt muss auf dem Heap liegen. Wenn eine Struktur klein ist und eine kurze Lebensdauer hat, ist es einfacher und schneller, sie auf dem Stack zu allokieren: kein malloc, kein free, kein Risiko von Speicherlecks.
Statt einen Zeiger zurückzugeben, kann eine Factory-Funktion die Struktur als Wert zurückgeben. Die gesamte Struktur wird an den Aufrufer kopiert:
typedef struct {
int x;
int y;
} Point;
Point create_point(int x, int y) {
Point p;
p.x = x;
p.y = y;
return p;
}
Der Aufrufer erhält eine vollständig initialisierte Kopie:
Point origin = create_point(0, 0);
Point cursor = create_point(100, 50);
printf("Cursor: (%d, %d)\n", cursor.x, cursor.y);
Keine Zeiger, keine Bereinigung erforderlich. Wenn origin und cursor den Gültigkeitsbereich verlassen, werden sie automatisch zerstört.
Dieser Ansatz eignet sich am besten für kleine structs ohne dynamisch zugewiesene Member. Für größere Objekte oder solche, die Zeiger auf Heap-Speicher enthalten, bleibt das Konstruktormuster mit malloc die bessere Wahl.
Aufgabe
EinfachLass uns ein Temperature-Modul erstellen, das mithilfe einer Factory-Funktion Temperaturmesswerte auf dem Stack erzeugt. Anders als die heap-basierten Konstruktoren aus vorherigen Lektionen gibt dieser Ansatz die Struktur als Wert zurück: kein malloc, kein free, nur eine einfache und effiziente Stack-Allokation.
Du wirst drei Dateien erstellen:
temperature.h: Deklariere eineTemperature-Struktur mit zwei Mitgliedern:double celsiusundchar scale(zum Speichern von 'C' für Celsius). Deklariere außerdem zwei Funktionen:create_temperature: akzeptiert einen Double-Wert und gibt eineTemperature-Struktur als Wert zurück (nicht als Zeiger!)temperature_to_fahrenheit: akzeptiert einenconst Temperature *und gibt die entsprechende Temperatur in Fahrenheit als Double-Wert zurück
TEMPERATURE_H.temperature.c: Implementiere beide Funktionen. Deine Factory-Funktion sollte eine lokaleTemperature-Variable erstellen, ihre Felder initialisieren (scaleauf'C'setzen) und sie zurückgeben. Die Umrechnungsformel lautet:fahrenheit = celsius * 9.0 / 5.0 + 32.0main.c: Verwende deine Factory-Funktion, um einen Temperaturmesswert zu erstellen, und gib sowohl die Celsius- als auch die Fahrenheit-Werte aus.
Du erhältst eine Eingabe: die Temperatur in Celsius (als Double-Wert).
Verwende in deiner Hauptdatei create_temperature, um eine Temperature-Struktur mit dem angegebenen Wert zu erstellen. Gib anschließend den ursprünglichen Celsius-Wert und sein Fahrenheit-Äquivalent aus.
Gib die Ausgabe in diesem Format aus:
Celsius: {celsius}
Fahrenheit: {fahrenheit}Verwende für beide Werte %.2f, um zwei Nachkommastellen anzuzeigen.
Bei einer Eingabe von 25.0 würde die Ausgabe beispielsweise so aussehen:
Celsius: 25.00
Fahrenheit: 77.00Beachte, wie übersichtlich dieser Ansatz ist. Du erhältst eine vollständig initialisierte Struktur, ohne dich um die Speicherverwaltung kümmern zu müssen. Wenn deine Temperature-Variable ihren Gültigkeitsbereich verlässt, wird sie automatisch bereinigt.
Probier es selbst
#include <stdio.h>
#include "temperature.h"
int main() {
double celsius_input;
scanf("%lf", &celsius_input);
// TODO: Verwende create_temperature, um ein Temperature-Struct zu erstellen
// TODO: Gib den Celsius-Wert im Format %.2f aus
// TODO: Verwende temperature_to_fahrenheit, um den Fahrenheit-Wert umzurechnen und auszugeben
return 0;
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
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 Box2Objekte 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