Gibt es Nachteile beim Übergeben von Strukturen nach Wert in C, anstatt einen Zeiger zu übergeben?
Wenn die Struktur groß ist, gibt es offensichtlich den leistungsfähigen Aspekt des Kopierens vieler Daten, aber für eine kleinere Struktur sollte dies im Grunde das gleiche sein wie das Übergeben mehrerer Werte an eine Funktion.
Es ist vielleicht noch interessanter, wenn es als Rückgabewerte verwendet wird. C hat nur einzelne Rückgabewerte von Funktionen, aber Sie benötigen häufig mehrere. Eine einfache Lösung besteht also darin, sie in eine Struktur zu setzen und diese zurückzugeben.
Gibt es Gründe dafür oder dagegen?
Da es möglicherweise nicht jedem klar ist, wovon ich hier spreche, gebe ich ein einfaches Beispiel.
Wenn Sie in C programmieren, werden Sie früher oder später Funktionen schreiben, die folgendermaßen aussehen:
void examine_data(const char *ptr, size_t len)
{
...
}
char *p = ...;
size_t l = ...;
examine_data(p, l);
Das ist kein Problem. Das einzige Problem ist, dass Sie mit Ihrem Kollegen vereinbaren müssen, in welcher Reihenfolge die Parameter sein sollen, damit Sie in allen Funktionen dieselbe Konvention verwenden.
Aber was passiert, wenn Sie dieselbe Art von Informationen zurückgeben möchten? Normalerweise erhalten Sie so etwas:
char *get_data(size_t *len);
{
...
*len = ...datalen...;
return ...data...;
}
size_t len;
char *p = get_data(&len);
Dies funktioniert gut, ist aber viel problematischer. Ein Rückgabewert ist ein Rückgabewert, außer dass dies in dieser Implementierung nicht der Fall ist. Aus dem oben Gesagten lässt sich nicht ableiten, dass die Funktion get_data nicht prüfen darf, auf was len zeigt. Und nichts lässt den Compiler überprüfen, ob tatsächlich ein Wert über diesen Zeiger zurückgegeben wird. Wenn also im nächsten Monat jemand anderes den Code ändert, ohne ihn richtig zu verstehen (weil er die Dokumentation nicht gelesen hat?), Wird er beschädigt, ohne dass es jemand merkt, oder er stürzt zufällig ab.
Die Lösung, die ich vorschlage, ist die einfache Struktur
struct blob { char *ptr; size_t len; }
Die Beispiele können folgendermaßen umgeschrieben werden:
void examine_data(const struct blob data)
{
... use data.tr and data.len ...
}
struct blob = { .ptr = ..., .len = ... };
examine_data(blob);
struct blob get_data(void);
{
...
return (struct blob){ .ptr = ...data..., .len = ...len... };
}
struct blob data = get_data();
Aus irgendeinem Grund denke ich, dass die meisten Leute instinktiv untersuchen_data einen Zeiger auf einen Struktur-Blob nehmen lassen würden, aber ich verstehe nicht warum. Es bekommt immer noch einen Zeiger und eine ganze Zahl, es ist nur viel klarer, dass sie zusammenpassen. Und im Fall get_data ist es unmöglich, auf die zuvor beschriebene Weise durcheinander zu kommen, da es keinen Eingabewert für die Länge gibt und es eine zurückgegebene Länge geben muss.
gettimeofday
) Verwendung Zeiger statt, und die Leute nehmen das als Beispiel.
void examine data(const struct blob)
ist falsch.