W wywiadzie stanąłem przed pytaniem takim jak to:
Twój przyjaciel dał ci pojedynczy plik kodu źródłowego, który drukuje liczby Fibonacciego na konsoli. Zauważ, że blok main () jest pusty i nie zawiera żadnych instrukcji.
Wyjaśnij, jak to jest możliwe (wskazówka: instancja globalna!)
Naprawdę chcę o tym wiedzieć, jak to jest w ogóle możliwe!
assert
lub#pragma message
itp. Spowoduje to przekierowanie danych wyjściowych do konsoli podczas kompilacji. Program może nigdy nie zostać w pełni skompilowany, ale z pewnością jest to świetny sposób na pokazanie swojego „nieszablonowego” myślenia podczas rozmowy kwalifikacyjnej. To spełnia cytowane pytanie, ponieważ NIE wspomina o generowaniu plików binarnych; raczej mówi o pliku C, który może wyświetlać "rzeczy" na konsoli. ;-)Odpowiedzi:
Najprawdopodobniej jest zaimplementowany jako (lub jego wariant):
void print_fibs() { //implementation } int ignore = (print_fibs(), 0); int main() {}
W tym kodzie zmienna globalna
ignore
musi zostać zainicjowana przed wejściem domain()
funkcji. Teraz, aby zainicjować globalną,print_fibs()
należy wykonać, gdzie możesz zrobić wszystko - w tym przypadku oblicz liczby Fibonacciego i wydrukuj je! Podobną rzecz pokazałem w następującym pytaniu (które zadałem dawno temu):Należy pamiętać, że taki kod nie jest bezpieczny i należy go generalnie unikać. Na przykład
std::cout
obiekt może nie zostać zainicjowany podczasprint_fibs()
wykonywania, jeśli tak, to co zrobiłobystd::cout
w funkcji? Jeśli jednak w innych okolicznościach nie zależy to od takiej kolejności inicjalizacji, można bezpiecznie wywołać funkcje inicjalizacyjne (co jest powszechną praktyką w C i C ++).źródło
std::ios_base::Init
obiektu. I<iostream>
gwarantuje zachowywać się „jak gdyby” zawierała ona instancjęstd::ios_base_Init
obiektu w zakresie przestrzeni nazw.(print_fibs(), 0)
jestint
. Oto demo online .bool
i zmiennejbool fibsPrinted
. To prawdopodobnie nieco czystsze, jeśli funkcja służy tylko tutaj. (Ale różnica prawdopodobnie nie jest wystarczająca do zmartwień.)std::cout
jest gdzieś w bibliotece. Ale jak już wspomniałem, standard wymaga zainicjowania go przed zakończeniem pierwszego konstruktorastd::ios_base::Init
obiektu i wymaga, aby w tym<iostream>
zachowywał się tak, jakbystd::ios_base::Init
obiekt był zdefiniowany w zakresie przestrzeni nazw. Jeśli jednostka translacyjna zawiera<iostream>
przed definicją inicjowanego obiektu,std::cout
to jest gwarantowane.Mam nadzieję że to pomoże
class cls { public: cls() { // Your code for fibonacci series } } objCls; int main() { }
Tak więc, gdy tylko zostanie zadeklarowana zmienna globalna klasy, wywoływany jest konstruktor i dodajesz logikę do wydrukowania serii Fibonacciego.
źródło
Tak to mozliwe. Musisz zadeklarować globalne wystąpienie obiektu, który oblicza liczby Fibonacciego w konstruktorze obiektów.
źródło
Znam kilka przykładów, które opowiadasz. Jednym ze sposobów uzyskania tego jest użycie metaprogramowania szablonu. Używając go, możesz przenieść jakiś proces obliczeniowy do kompilacji.
Tutaj możesz uzyskać przykład z liczbami Fibonacciego
Jeśli używasz go w konstruktorze klasy statycznej i możesz pisać liczby bez konieczności pisania kodu w funkcji main.
Mam nadzieję, że ci to pomoże.
źródło
Podczas inicjalizacji zmiennych globalnych / statycznych może się zdarzyć. Kod zostanie wyzwolony podczas uruchamiania aplikacji.
źródło
Wszystkie konstruktory [*] dla obiektów o zasięgu plikowym są wywoływane przed osiągnięciem
main
, podobnie jak wszystkie wyrażenia inicjalizujące dla zmiennych niebędących obiektami o zasięgu plikowym.Edycja: Ponadto wszystkie [*] destruktory dla wszystkich obiektów o zasięgu plikowym są wywoływane w odwrotnej kolejności do konstrukcji po zakończeniu
main
. Teoretycznie można by umieścić swój program Fibonacciego w destruktorze obiektu.[*] Zauważ, że 'all' ignoruje zachowanie dynamicznego ładowania i usuwania bibliotek, z którymi twój program nie był bezpośrednio powiązany. Jednak technicznie są one poza podstawowym językiem C ++.
źródło
main
?main
jest pusty, więc te biblioteki DLL / DSO musiałyby być ładowane przez destruktory, co jest cholernie przewrotne. Ale ponieważ jest to informatyka, przypuszczam, że powinniśmy uważać na słowa takie jak „wszystko”.