Ich komme leider auch nicht dahinter, was du genau verstanden / nicht verstanden hast
Ich versuche mal, das ganze etwas anschaulich zu erklären:
Denke dir ein Programm mal als eine Ansammlung von Zetteln (ich verwende jetzt die Analogie Zettel = Funktion). Jeder Zettel hat einen Namen (den Namen der Funktion) und ferner stehen auf ihm beliebig viele Befehle, die von oben nach unten abgearbeitet werden. Jetzt spielen wir mal ein kleines Beispielszenario durch:
Es gibt eine Hauptfunktion, das ist ein besonderer Zettel. Dieser nennt sich
main. Außerdem hast du noch zwei Zettel, der eine nennt sich
meineFunktion1 und der andere
meineFunktion2. Auf dem Zettel
main steht jetzt:
|
Quellcode
|
1
2
3
|
Mache irgendwas;
meineFunktion1 ();
Mache noch mehr irgendwas;
|
Und auf dem Zettel
meineFunktion1 könnte stehen:
|
Quellcode
|
1
2
3
|
Mache irgendwas;
meineFunktion2 ();
Mache Quatsch;
|
Und schließlich auf dem Zettel
meineFunktion2:
|
Quellcode
|
1
|
cout << "Hallo" << endl;
|
Nun starten wir mal das Programm. Das ist jetzt zwar aus technischer Sicht nicht ganz korrekt, hilft aber der Anschauung: Der Rechner ließt immer zuerst den Zettel
main und führt aus, was darauf steht, und zwar in derselben Reihenfolge wie es dort steht. Zuerst wird also irgendwas gemacht, was uns nicht weiter interessiert, dann ließt der Rechner die Zeile "meineFunktion1 ()". Hier erkennt er: "Jetzt geht's weiter auf dem Zettel
meineFunktion1!" Also holt er den Zettel
meineFunktion1 raus und fängt hier wieder von Anfang an an zu lesen und die Befehle auszuführen: Zuerst wird irgendwas blödes erledigt, dann stößt er auf die Zeile "meineFunktion2 ();" - Und wieder versteht der Rechner: "Jetzt geht's weiter auf Zettel
meineFunktion2!" Auf diesem Zettel jedoch nur ein einziger Befehl, und der bedeutet: "Gebe den Text
hallo[i] aus!" Dies wird erledigt, und da dies der letzte Befehl auf dem Zettel war, wird er wieder weggelegt und der vorherige rausgekramt ([i]meineFunktion1). Hier macht der Rechner wieder dort weiter, wo er vorhin stehen geblieben war und führt deswegen die 3. Zeile aus, die irgend einen Quatsch erledigt. Da auch das wieder die letzte Zeile des jeweiligen Zettels ist, wird dieser Zettel auch wieder weggelegt und stattdessen der Zettel, der vorher dran war, nämlich
main[i], wieder hervor geholt. Hier geht es weiter mit der Zeile "Mache noch mehr irgendwas". Da auch dieser Zettel nun fertig abgearbeitet ist, wird das Programm beendet.
Das ist so das grundlegende Prinzip hinter Funktionen. Es ist übrigens sogar technisch korrekt, sich die Zettel beim Abarbeiten durch den Rechner als einen Stapel vorzustellen, wobei der oberste Zettel immer der ist, der gerade abgearbeitet wird: Und wenn ein neuer Zettel hervorgekramt wird, wird dieser ganz oben auf den Stapel gelegt, und sobald er fertig ist, wieder runtergeholt.
Nun mal zu den Besonderheiten. Man kann einen Zettel als "inline" kennzeichnen. Dies hat zur Folge, dass der als "inline" gekennzeichnete Zettel, sobald er "aufgerufen" wird, nicht herausgekramt und oben auf den Stapel gelegt wird, sondern das, was auf dem Zettel steht, an der Stelle auf dem Zettel, der den "inline"-Zettel aufgerufen hat, quasi per "copy&paste" eingefügt wird. Für den Gelenheitsprogrammierer ist der Unterschied, der sich dadurch ergibt, wohl nicht weiter von Belang. Anschaulich kannst du dir den Unterschied aber so denken: Du sparst durch "inline"-Zettel im Vergleich zu nicht-"inline"-Zettel etwas Zeit ein, da du dir nicht die Arbeit machen musst, ihn zu suchen und auf den Stapel zu legen und später wieder vom Stapel runterzuholen. Ein Nachteil ergibt sich dann, wenn du dir mal vorstellst, der "inline"-Zettel würde mehrmals aufgerufen werden. In dem Fall wird der Inhalt des "inline"-Zettels vielfach an anderer Stelle eingefügt, wodurch sich die Gesamtmenge an Befehlen (Code) aufbläht.
Das mit dem "bool" habe ich jetzt keine Zeit mehr zu erklären und "forceinline" ist mir nicht bekannt