Unterschied zwischen Funktion und Makro ?
-
Was ist da der Unterschied ?
-
Makros werden vor der Übergabe deines Quelltextes an den Compiler ausgewertet und übersetzt.
Wenn du also z.B. mit #define eine Variable definiert hast, wird in deinem Quelltext überall dort, wo anschließend die "Variable" steht, der Wert eingesetzt. Erst danach übersetzt der Compiler den so "überarbeiteten" Code.
-
Eine Funktion wird aufgerufen und dann der Funktionscode ausgeführt.
int area(int l, int h) { return l * h; } int main() { area(123, 456); // Bei jedem Funktionsaufruf wird nach oben zur Funktion area(342, 2459); // gesprungen und nach deren ausführung zurück in die // ... // main funktion. }
Ein Makro dagegen wird einfach immer neu in den Quelltext kopiert was zu Geschwindigkeitsvorteilen führt, jedoch erhöht sich damit auch die Programmgröße.
So sieht dieser Quelltext#define AREA(l,h) l * h int main() { AREA(123,456); AREA(342,2459); // ... }
nach dem Präprozessor durchlauf folgendermaßen aus:
int main() { 123 * 456; 342 * 2459; // ... }
Gut ich weis das dieser Code keinen Sinn ergibt, aber er soll ja auch nur die Verwendung demonstrieren
Aber da Funktions-Makros und allgemein der Präprozessor C-Style ist, gibt es für C++ eine eigene Lösung und zwar inline:
inline int area(int l, int h) { return l * h; } int main() { area(123, 456); area(342, 2459); // ... }
Hier wird das selbe wie bei einem Makro gemacht, es wird nämlich die Funktion area an die entsprechende stelle in main kopiert. Hierdurch wird zwar das Programm größer aber es wird hierdurch auch schneller.
P.S.: inline ist nur eine EMPFEHLUNG an deinen Compiler, d. h. er kann die Funktion inline setzen muss es aber nicht.
-
ok, danke.
Aber wieso wird eine Funktion eigentlich mit int erstellt ?
-
Eine Funktion muss nicht mit int erstellt werden.
Rückgabewert Funktionsname(Parameter1, Parameter2, ... ParameterN);
Bsp:
void tueNichts() {} int area(int l, int h) { return l * h; } char input() { while(!kbhit()); return getch(); } // ...
-
ich meine , wieso sie nicht mit bool erstellt wird.
Denn eine Function ist entweder an , oder nicht
-
Ich weis nicht was du für eine Vorstellung von Funktionen hast, aber man kann keine Funktionen an- oder ausschalten, man kann sie nur aufrufen.
Was du dann mit welchem bool auch immer vorhast kann ich nicht nachvollziehen.
Zeig mir doch mal ein Beispiel wie du das mit bool meinst.
-
...oder einfach mal ein Buch lesen. Die Grundlagen der C++ Programmierung würden hier glaub ich etwas zu weit führen.
-
Wolle. schrieb:
Ich weis nicht was du für eine Vorstellung von Funktionen hast, aber man kann keine Funktionen an- oder ausschalten, man kann sie nur aufrufen.
Was du dann mit welchem bool auch immer vorhast kann ich nicht nachvollziehen.
Zeig mir doch mal ein Beispiel wie du das mit bool meinst.Eine Funktion enthält doch keine Zahl, aber wird trotzdem als Variable gehandlet.
Das finde ich ziemlich verwirrend.Meine Vorstellung einer Funktion war eben, dass eine Funktion aufgerufen ist(true), oder nicht (false). Also vom typ bool
-
Du hast eine völlig falsche Vorstellung. Lies lieber mal ein Buch oder ein Tutorial.
-
sbrog schrieb:
Eine Funktion enthält doch keine Zahl, aber wird trotzdem als Variable gehandlet.
Das finde ich ziemlich verwirrend.Meine Vorstellung einer Funktion war eben, dass eine Funktion aufgerufen ist(true), oder nicht (false). Also vom typ bool
Eine Funktion wird nicht als Variable behandelt, du scheinst die grundlegende idee hinter Funktionen nicht zu verstehen.
Da kann ich dir auch nur Empfehlen einmal ein Buch oder Tutorial über Funktionen zu bemühen.
-
vom aufruf unterscheiden sich funktion & makro eigentlich nicht, jedoch sind makros ein bisschen schneller. der entscheidende punkte jedoch liegt darin, dass sich funktionen mitm debugger anschauen kann, sprich ich kann zwischenergebnis in variablen einsehen und bei makros NICHT. d.h. wenn der algorithmus des makros nicht stimmt kann ich das nicht überprüfen bzw. ich muss mir ganz sicher sein das er stimmt ansonsten krieg ich lauter müll raus.
-
Doch, es gibt einen riesigen Unterschied beim Aufruf. Selbst wenn man den Mechanismus (Textersetzung beim Makro) mal außer Acht läßt: Die Argumente einer Funktion werden erst ausgewertet, dann wird die Funktion aufgerufen. Bei einem Makro passiert das nicht. Die Art und Weise, in der das Makro geschrieben ist, entscheidet, ob, wie oft und in welcher Reihenfolge die Argumente ausgewertet werden.
-
ich meinte auch nur die schreibweise, was sich im einzelnen dahinter versteckt glaub ich interessiert die wenigsten
-
Dann hast du nicht verstanden worauf ich hinauswill. Was, wenn ein Argument einen Seiteneffekt hat?
-
Nochmal zum Beispiel von oben und warum man Makros - wenn man sie überhaupt
benutzen will - nur *sehr* vorsichtig benutzen soll:#define AREA(l,h) l * h int main() { // Soll (2+3)*(4+6) = 5 * 10 = 50 ausgeben ... cout << AREA(2+3,4+6); } //nach Präprozessor: int main() { // gibt aber 2+3*4+6 = 2+12+6 = 20 aus !!! cout << 2+3*4+6; }
Das kann man umgehen, wenn man das Makro neu schreibt:
#define AREA(l,h) ((l)*(h))
Aber es gibt noch viele andere Schrecken und Teufeleien, die dir mit Makros
passieren können (s. Bashar)!
-
jedoch sind makros ein bisschen schneller.
Du hättest schreiben sollen, dass man inline-Funktionen einsetzen kann, die dann auch genauso schnell sind...
-
[EDIT]Zu langsam
[/EDIT]
-
Mis2com schrieb:
jedoch sind makros ein bisschen schneller.
Du hättest schreiben sollen, dass man inline-Funktionen einsetzen kann, die dann auch genauso schnell sind...
Der größte Bullshit den ich je gelesen habe! Kennste sowas wie einen Profiler? Wenn ja würd ich an Deiner Stelle mal Deine lepsche Theorie mal erst Testen bevor Du hier so einen Schwachsinn postest. Zieh Dir erstmal den generierten Assembler code an und dann reden wir erst weiter.
Aber inline-Funktionen genau so schnell wie Makros? LOL nee komm, probier besser erstmal aus... So einen Schwachsinn gibts echt selten.
Was behauptest Du als nächstes?
class CX { public: inline void bar (void) { std::cout << "x" << std::endl; } }; // ist im speed her äquivalent zu: #define BAR std::cout << "x" << std::endl;
Merk Dir eines: Ob inline oder nicht, Funktionen kosten Zeit, zwar bei Inline weniger aber Zeit ist Zeit und Markos kosten nix an Zeit, da sie nicht aufgerufen werden sondern eingebunden werden.
Ansonsten falls der Herr es ja nich glauben will: Zieh Dir den Assemblercode zu rate.
-
Aber inline-Funktionen genau so schnell wie Makros? LOL nee komm,
Doch.
-
nix da schrieb:
Aber inline-Funktionen genau so schnell wie Makros? LOL nee komm, probier besser erstmal aus... So einen Schwachsinn gibts echt selten.
Zeig doch einfach nur einmal einen Beweis her.
Hier ist meiner:_main PROC NEAR .B1.1: ; Preds .B1.0 ;;; { push ebx ;9.1 mov ebx, esp ;9.1 and esp, -16 ;9.1 ;;; std::cout<<"start\n"; push OFFSET FLAT: ??_C@_06A@start?6?$AA@ ;10.3 push OFFSET FLAT: ?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ;10.3 call ??6std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z ;10.3 ; LOE ebp esi edi .B1.2: ; Preds .B1.1 ;;; ;;; { ;;; std::cout<<"direkt im code\n"; push OFFSET FLAT: ??_C@_0BA@A@direkt?5im?5code?6?$AA@ ;13.5 push OFFSET FLAT: ?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ;13.5 call ??6std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z ;13.5 ; LOE ebp esi edi .B1.3: ; Preds .B1.2 ;;; } ;;; ;;; std::cout<<"halbzeit\n"; push OFFSET FLAT: ??_C@_09A@halbzeit?6?$AA@ ;16.3 push OFFSET FLAT: ?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ;16.3 call ??6std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z ;16.3 ; LOE ebp esi edi .B1.4: ; Preds .B1.3 ;;; ;;; { ;;; test(); push OFFSET FLAT: ??_C@_0BA@A@ich?5bin?5inline?6?$AA@ ;19.5 push OFFSET FLAT: ?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ;19.5 call ??6std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z ;19.5 ; LOE ebp esi edi .B1.5: ; Preds .B1.4 ;;; } ;;; ;;; std::cout<<"ende\n"; push OFFSET FLAT: ??_C@_05A@ende?6?$AA@ ;22.3 push OFFSET FLAT: ?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ;22.3 call ??6std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z ;22.3 ; LOE ebp esi edi .B1.9: ; Preds .B1.5 add esp, 40 ;22.3 ; LOE ebp esi edi .B1.6: ; Preds .B1.9 ;;; } xor eax, eax ;23.1 mov esp, ebx ;23.1 pop ebx ;23.1 ret ;23.1 ALIGN 4 ; LOE ; mark_end; _main ENDP
Der C++ Code dazu:
#include <iostream> inline int test() { std::cout<<"ich bin inline\n"; } int main() { std::cout<<"start\n"; { std::cout<<"direkt im code\n"; } std::cout<<"halbzeit\n"; { test(); } std::cout<<"ende\n"; }
Ansonsten falls der Herr es ja nich glauben will: Zieh Dir den Assemblercode zu rate.
Dies habe ich hiermit getan
Ja, ich weiss, du willst nur trollen - aber damit habe ich dir wohl den Wind aus den Segeln genommen - obwohl die Idee garnicht mal schlecht ist, darauf zu bauen, dass alle zu faul sind dir einen Gegenbeweis zu bringen (und du selbst kannst ja keinen beweis bringen) - dann hast du eine Pattstellung und Newbies glauben dir dann vielleicht sogar.
Nicht dumm, nicht dumm.