Pointer vs. Wert
Teil des Abschnitts Objektorientierte Programmierung der C-Journey von Coddy. Lektion 9 von 61.
Wenn du eine Struktur an eine Funktion übergibst, bietet dir C zwei Möglichkeiten: Sie als Wert zu übergeben (die gesamte Struktur zu kopieren) oder sie als Zeiger zu übergeben (nur die Adresse zu kopieren). Diese Wahl ist für die Leistung von großer Bedeutung.
Die Übergabe als Wert erstellt eine vollständige Kopie der Struktur auf dem Stack. Für eine kleine Struktur mit einigen Ganzzahlen ist das in Ordnung. Aber stell dir eine Struktur mit Hunderten von Bytes vor: Jeder Funktionsaufruf kopiert all diese Daten:
typedef struct {
char name[100];
int scores[50];
double average;
} Student;
// Per Wert: kopiert ~308 Bytes bei jedem Aufruf
void print_by_value(Student s) {
printf("%s: %.2f\n", s.name, s.average);
}
// Per Zeiger: kopiert nur 8 Bytes (die Adresse)
void print_by_pointer(const Student *s) {
printf("%s: %.2f\n", s->name, s->average);
}
Auch die Syntax unterscheidet sich. Bei einem Wertparameter verwendest du den Punktoperator (s.name). Bei einem Zeiger verwendest du den Pfeiloperator (s->name).
Die Zeigerversion ist effizienter, weil sie nur eine Speicheradresse übergibt, typischerweise 8 Byte unabhängig von der Größe der Struktur.
Deshalb übergeben C-Programmierer Strukturen fast immer per Zeiger. Verwende const, wenn die Funktion die Daten nicht ändern soll, und einen gewöhnlichen Zeiger, wenn sie es soll. So erhältst du sowohl Effizienz als auch eine klare Absicht.
Aufgabe
EinfachErstellen wir ein Product-Modul, das den Unterschied zwischen der Übergabe von Strukturen per Wert und per Zeiger demonstriert. Du erstellst zwei Anzeigefunktionen: eine, die die gesamte Struktur als Kopie erhält, und eine, die nur einen Zeiger darauf erhält.
Du erstellst drei Dateien:
product.h: Deklariere eineProduct-Struktur mit drei Membern:char name[50],double priceundint quantity. Deklariere außerdem zwei Funktionen:display_by_value: erhält einProductper Wert und gibt dessen Informationen ausdisplay_by_pointer: erhält einenconst Product *und gibt dieselben Informationen aus
PRODUCT_H.product.c: Implementiere beide Funktionen. Beachte den Syntaxunterschied: Die Version per Wert verwendet den Punktoperator (p.name), während die Zeigerversion den Pfeiloperator (p->name) verwendet. Beide Funktionen sollten dasselbe Format ausgeben.main.c: Erstelle ein Product und rufe anschließend beide Anzeigefunktionen auf, um zu zeigen, dass sie trotz unterschiedlicher Parameterstile eine identische Ausgabe erzeugen.
Du erhältst drei Eingaben: den Produktnamen (eine Zeichenkette), den Preis (eine Gleitkommazahl vom Typ double) und die Menge (eine Ganzzahl).
Initialisiere in deiner Hauptdatei ein Product mit diesen Werten und rufe anschließend zuerst display_by_value und danach display_by_pointer auf.
Beide Funktionen sollten dieses Format ausgeben:
Product: {name}, Price: {price}, Qty: {quantity}Verwende %.2f für den Preis, um zwei Dezimalstellen anzuzeigen.
Bei den Eingaben Laptop, 999.99 und 5 würde die Ausgabe beispielsweise so aussehen:
Product: Laptop, Price: 999.99, Qty: 5
Product: Laptop, Price: 999.99, Qty: 5Probier es selbst
#include <stdio.h>
#include <string.h>
#include "product.h"
int main() {
char name[50];
double price;
int quantity;
// Eingaben lesen
scanf("%s", name);
scanf("%lf", &price);
scanf("%d", &quantity);
// TODO: Erstelle eine Product-Variable und initialisiere sie mit den Eingabewerten
// Hinweis: Verwende strcpy, um den Namen in das name-Feld der Struktur zu kopieren
// TODO: Rufe display_by_value mit dem Product auf
// TODO: Rufe display_by_pointer mit einem Zeiger auf das Product auf
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