Ich implementiere einen generischen Stapel in C für Lernzwecke. Dies ist die Pop-Funktion davon:Funktion obere Stapelimplementierung in C
void* StackPop(Stack *s) {
assert(s != NULL);
assert(s->logicalLen > 0); // there must be at least on element
void *object = (char*) s->elems + (s->logicalLen--) * s->elemSize; // decrement logical length
// on the fly
return object;
}
In diesem Fall (StackPop) ist mir klar, dass ich das Eigentum an dem Objekt an der Spitze an den Anrufer übertragen müssen. Das Zurückgeben eines generischen Zeigers ist also in Ordnung, da der Aufrufer entscheiden soll, was mit dem Objekt zu tun ist. Auf der anderen Seite möchte ich eine StackTop() -Funktion schreiben, um das oberste Element zurückzugeben. Hier kommt so Ungewissheit zu mir: Ich weiß, dass beide Funktionen sehr ähnlich sein sollten mit dem Unterschied, dass ich die Größe des Stapels nicht verringern oder einen Zeiger zurückgeben sollte, da ich nicht möchte, dass der Client es ändert. Wie übertrage ich dann nur eine Kopie des obersten Elements? Akzeptiere ich einen generischen Zeiger als Argument, meine einzige Option, und mache eine tiefe Kopie in diese Adresse?
void StackPop(void *target) {
// make a deep copy into target address with memcopy or whatever?
}
Gibt es einen besseren Ansatz?
Unrelated, würde ich anfangen zu schreiben "StackPop", um einige Anschein von Verstand zu zeigen und nach einem leeren Stapel vor all den anderen Calisthenics zu überprüfen.Und wähle eine Sprache: Die Passung und Form suggeriert C; nicht C++. – WhozCraig
@WhozCraig wahr, ich habe es nur schnell geschrieben. Ich achte momentan nicht sehr auf die Fehlerüberprüfung. Ich werde es korrigieren. – blade
Ein "richtiger" Weg, um Ihr Problem zu lösen, ist, dass Ihre Pop-Funktion * nichts * zurückgibt (außer vielleicht ein Fehlerzustand). Erlauben Sie nur den Zugriff auf das "Top" -Objekt (falls vorhanden) über die Top-Funktion. Wenn der Anrufer eine Kopie des Objekts möchte, so sei es; sie können einen vor dem Knallen machen. Das ist nicht zufällig die Art und Weise, wie der C++ - Standardbibliotheks-Containeradapter "std :: stack" funktioniert. Und außerdem wird "Assert" zu einem No-Op-Code, so dass Sie immer noch eine logische Fehlerüberprüfung benötigen, nur für den Fall, dass Sie sich dessen nicht bewusst waren. –
WhozCraig