Pointer vs. Wert
Teil des Abschnitts Object Oriented Programming der C-Journey von Coddy — Lektion 9 von 61.
Wenn Sie ein struct an eine Funktion übergeben, bietet C Ihnen zwei Optionen: die Übergabe by value (Kopie des gesamten struct) oder die Übergabe by pointer (Kopie nur der Adresse). Die Wahl ist für die Performance von erheblicher Bedeutung.
Die Übergabe als Wert erzeugt eine vollständige Kopie des Structs auf dem Stack. Für ein kleines Struct mit ein paar Integern ist das in Ordnung. Aber stellen Sie sich ein Struct 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 bei jedem Aufruf ~308 Bytes
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);
}
Die Syntax unterscheidet sich ebenfalls. Bei einem Wertparameter verwenden Sie den Punkt-Operator (s.name). Bei einem Zeiger verwenden Sie den Pfeil-Operator (s->name).
Die Pointer-Version ist effizienter, da sie nur eine Speicheradresse übergibt – typischerweise 8 Bytes, unabhängig von der Größe des Structs.
Aus diesem Grund übergeben C-Programmierer Structs fast immer per Pointer. Verwenden Sie const, wenn die Funktion die Daten nicht ändern soll, und einen regulären Pointer, wenn sie es soll. Sie erhalten sowohl Effizienz als auch eine klare Absicht.
Aufgabe
EinfachLassen Sie uns ein Product-Modul erstellen, das den Unterschied zwischen der Übergabe von Structs als Wert (by value) und als Zeiger (by pointer) demonstriert. Sie werden zwei Anzeige-Funktionen erstellen – eine, die das gesamte Struct als Kopie erhält, und eine, die nur einen Zeiger darauf erhält.
Sie werden drei Dateien erstellen:
product.h: Deklarieren Sie einProduct-Struct mit drei Elementen:char name[50],double priceundint quantity. Deklarieren Sie außerdem zwei Funktionen:display_by_value— nimmt einProductals Wert entgegen und gibt dessen Informationen ausdisplay_by_pointer— nimmt einenconst Product *entgegen und gibt dieselben Informationen aus
PRODUCT_H.product.c: Implementieren Sie beide Funktionen. Beachten Sie den Syntaxunterschied: Die "by-value"-Version verwendet den Punkt-Operator (p.name), während die Zeiger-Version den Pfeil-Operator (p->name) verwendet. Beide Funktionen sollten im gleichen Format drucken.main.c: Erstellen Sie ein Product und rufen Sie dann beide Anzeige-Funktionen auf, um zu zeigen, dass sie trotz unterschiedlicher Parameterstile eine identische Ausgabe erzeugen.
Sie erhalten drei Eingaben: den Produktnamen (ein String), den Preis (ein Double) und die Menge (ein Integer).
Initialisieren Sie in Ihrer Hauptdatei ein Product mit diesen Werten und rufen Sie dann display_by_value gefolgt von display_by_pointer auf.
Beide Funktionen sollten in diesem Format drucken:
Product: {name}, Price: {price}, Qty: {quantity}Verwenden Sie %.2f für den Preis, um zwei Dezimalstellen anzuzeigen.
Zum Beispiel wäre bei den Eingaben Laptop, 999.99 und 5 die Ausgabe:
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
// Hint: Verwende strcpy, um den Namen in das name-Feld des Structs 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 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-ImplementierungRechteck-ImplementierungPolymorphe VerwendungShape-Container