In einem Interview wurde ich mit einer Frage wie dieser konfrontiert:
Ihr Freund hat Ihnen eine einzige Quellcodedatei gegeben, die die Fibonacci-Zahlen auf der Konsole druckt. Beachten Sie, dass der Block main () leer ist und keine Anweisungen enthält.
Erklären Sie, wie dies möglich ist (Hinweis: globale Instanz!)
Ich möchte wirklich wissen, wie so etwas überhaupt möglich sein kann!
assert
oder#pragma message
usw. zu protokollieren . Dadurch wird die Ausgabe während der Kompilierung an die Konsole umgeleitet. Das Programm wird möglicherweise nie vollständig kompiliert, aber dies ist sicher eine unterhaltsame Möglichkeit, Ihr "out-of-the-box" -Denken während des Interviews zu zeigen. Dies erfüllt die zitierte Frage, da nichts über die Erzeugung von Binärdateien erwähnt wird. Vielmehr handelt es sich nur um eine C-Datei, die "Zeug" auf der Konsole anzeigen kann. ;-)Antworten:
Es wird höchstwahrscheinlich implementiert als (oder eine Variante davon):
In diesem Code muss die globale Variable
ignore
vor dem Eintritt in diemain()
Funktion initialisiert werden. Um nun das Globale zu initialisieren,print_fibs()
muss es ausgeführt werden, wo Sie alles tun können - in diesem Fall Fibonacci-Zahlen berechnen und ausdrucken! Eine ähnliche Sache habe ich in der folgenden Frage gezeigt (die ich vor langer Zeit gestellt hatte):Beachten Sie, dass ein solcher Code nicht sicher ist und generell vermieden werden sollte. Beispielsweise kann das
std::cout
Objekt nicht initialisiert werden, wennprint_fibs()
es ausgeführt wird. Wenn ja, was würdestd::cout
dann in der Funktion tun? Wenn dies jedoch unter anderen Umständen nicht von einer solchen Initialisierungsreihenfolge abhängt, können Initialisierungsfunktionen sicher aufgerufen werden (was in C und C ++ üblich ist).quelle
std::ios_base::Init
Objekts initialisiert werden. Und es<iostream>
wird garantiert, dass es sich so verhält, als ob es eine Instanz einesstd::ios_base_Init
Objekts im Namespace-Bereich enthält.(print_fibs(), 0)
istint
. Hier ist die Online-Demo .bool
und der Variablenbool fibsPrinted
. Das ist wahrscheinlich etwas sauberer, wenn die Funktion nur hier dient. (Aber der Unterschied ist wahrscheinlich nicht genug, um sich Sorgen zu machen.)std::cout
befindet sich irgendwo in der Bibliothek. Wie ich bereits erwähnt habe, muss es nach dem Standard initialisiert werden, bevor der erste Konstruktor einesstd::ios_base::Init
Objekts fertig ist, und es muss sich so<iostream>
verhalten, als ob einstd::ios_base::Init
Objekt im Namespace-Bereich definiert wäre. Wenn die Übersetzungseinheit<iostream>
vor der Definition des zu initialisierenden Objekts enthält,std::cout
wird garantiert konstruiert.Hoffe das hilft
Sobald eine globale Variable der Klasse deklariert ist, wird der Konstruktor aufgerufen und dort fügen Sie die Logik zum Ausdrucken der Fibonacci-Reihe hinzu.
quelle
Ja, es ist möglich. Sie müssen eine globale Instanz eines Objekts deklarieren, die die Fibonacci-Zahlen im Objektkonstruktor berechnet.
quelle
Ich kenne einige Beispiele, die Sie erzählen. Eine Möglichkeit, dies zu erreichen, ist die Verwendung der Metaprogrammierung für Vorlagen. Mit ihm können Sie einen Rechenprozess in die Kompilierung verschieben.
Hier Sie ein Beispiel mit den Fibonacci-Zahlen
Wenn Sie es in einem statischen Klassenkonstruktor verwenden und die Zahlen schreiben können, ohne Code in die Hauptfunktion schreiben zu müssen.
Hoffe es hilft dir.
quelle
Während der Initialisierung globaler / statischer Variablen können Dinge passieren. Der Code wird beim Start der Anwendung ausgelöst.
quelle
Alle [*] Konstruktoren für Dateibereichsobjekte werden vor dem Erreichen aufgerufen
main
, ebenso wie alle Initialisiererausdrücke für Nichtobjekt-Dateibereichsvariablen.Bearbeiten: Außerdem werden alle [*] Destruktoren für alle Dateibereichsobjekte in umgekehrter Reihenfolge aufgerufen
main
Beenden . Theoretisch könnten Sie Ihr Fibonacci-Programm in den Destruktor eines Objekts einfügen.[*] Beachten Sie, dass 'all' das Verhalten beim dynamischen Laden und Entladen von Bibliotheken ignoriert, mit denen Ihr Programm nicht direkt verknüpft war. Diese befinden sich jedoch technisch außerhalb der C ++ - Basissprache.
quelle
main
?main
ist leer, so dass diese DLLs / DSOs von Destruktoren geladen werden müssten, was verdammt pervers ist. Aber da dies Informatik ist, sollten wir mit Worten wie "alle" vorsichtig sein.