Stack-Initialisierung
Teil des Abschnitts Object Oriented Programming der C-Journey von Coddy — Lektion 14 von 61.
Nicht jedes Objekt muss auf dem Heap liegen. Wenn ein Struct klein ist und eine kurze Lebensdauer hat, ist die Allokation auf dem Stack einfacher und schneller – kein malloc, kein free, kein Risiko von Speicherlecks.
Anstatt einen Pointer zurückzugeben, kann eine Factory-Funktion das Struct als Wert zurückgeben. Das gesamte Struct 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 funktioniert am besten für kleine Structs ohne dynamisch zugewiesene Member. Für größere Objekte oder solche, die Pointer auf Heap-Speicher enthalten, bleibt das Constructor-Pattern mit malloc die bessere Wahl.
Aufgabe
EinfachLassen Sie uns ein Temperature-Modul erstellen, das Temperaturmesswerte auf dem Stack mithilfe einer Factory-Funktion erzeugt. Im Gegensatz zu den Heap-basierten Konstruktoren aus vorherigen Lektionen gibt dieser Ansatz das Struct als Wert zurück – kein malloc, kein free, nur einfache und effiziente Stack-Allokation.
Sie werden drei Dateien erstellen:
temperature.h: Deklarieren Sie einTemperature-Struct mit zwei Elementen:double celsiusundchar scale(um 'C' für Celsius zu speichern). Deklarieren Sie außerdem zwei Funktionen:create_temperature— nimmt einen double-Wert entgegen und gibt einTemperature-Struct als Wert zurück (keinen Pointer!)temperature_to_fahrenheit— nimmt einenconst Temperature *entgegen und gibt die entsprechende Temperatur in Fahrenheit als double zurück
TEMPERATURE_H.temperature.c: Implementieren Sie beide Funktionen. Ihre Factory-Funktion sollte eine lokaleTemperature-Variable erstellen, deren Felder initialisieren (setzen Siescaleauf'C') und diese zurückgeben. Die Umrechnungsformel lautet:fahrenheit = celsius * 9.0 / 5.0 + 32.0main.c: Verwenden Sie Ihre Factory-Funktion, um einen Temperaturmesswert zu erstellen und sowohl den Celsius- als auch den Fahrenheit-Wert anzuzeigen.
Sie erhalten eine Eingabe: die Temperatur in Celsius (als double).
Verwenden Sie in Ihrer Hauptdatei create_temperature, um ein Temperature-Struct mit dem angegebenen Wert zu erstellen. Geben Sie dann den ursprünglichen Celsius-Wert und dessen Fahrenheit-Entsprechung aus.
Geben Sie die Ausgabe in diesem Format aus:
Celsius: {celsius}
Fahrenheit: {fahrenheit}Verwenden Sie %.2f für beide Werte, um zwei Dezimalstellen anzuzeigen.
Zum Beispiel wäre bei einer Eingabe von 25.0 die Ausgabe:
Celsius: 25.00
Fahrenheit: 77.00Beachten Sie, wie sauber dieser Ansatz ist – Sie erhalten ein vollständig initialisiertes Struct ohne Bedenken hinsichtlich der Speicherverwaltung. Wenn Ihre Temperature-Variable den Gültigkeitsbereich verlässt, wird sie automatisch bereinigt.
Spickzettel
Factory-Funktionen können Structs als Wert (by value) anstelle von Pointern zurückgeben. Dies alloziert das Struct auf dem Stack – kein malloc, kein free und keine Speicherlecks.
Beispiel für eine Factory-Funktion, die einen Wert zurückgibt:
typedef struct {
int x;
int y;
} Point;
Point create_point(int x, int y) {
Point p;
p.x = x;
p.y = y;
return p;
}
Verwendung der Factory-Funktion:
Point origin = create_point(0, 0);
Point cursor = create_point(100, 50);
printf("Cursor: (%d, %d)\n", cursor.x, cursor.y);
Das Struct wird an den Aufrufer kopiert und automatisch zerstört, wenn es den Gültigkeitsbereich verlässt. Dieser Ansatz eignet sich am besten für kleine Structs ohne dynamisch allozierte Elemente.
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 Object Oriented Programming
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-Implementierung