Problem mit Makro
-
Ich muss für einen kleinen Quelltextfetzen ein Makro schreiben der die Fakultät von einer Start-Variablen und einer End-Variablen berechnet.
#include <iostream> using namespace std; int main() { unsigned int ergebnis; PRODUKT(3,5,ergebnis); cout << ergebnis << endl; PRODUKT(3,9,ergebnis); cout << ergebnis << endl; return 0; }Gesagt getan ... Mein Ergebnis ist dieses:
#define PRODUKT(start, ende, ergebnis)\ (ergebnis = 1;\ for (start; start <= ende; start++) ergebnis = start * ergebnis;)Jetzt wirft er mir aber die Fehlermeldung um die Ohren, dass "ergebnis" nicht initialisiert ist, was ich auch verstehe weil der Quelltextfetzen ja keinen Wert zuweist.
Ich habe bloß keine Ahnung wie ich das mit dem Makro behebe weil ich darf den Quelltext nicht verändern.Ich danke schon im voraus für die Hilfe!
-
PRODUKT(3,5,ergebnis); #define PRODUKT(start, ende, ergebnis)\ (ergebnis = 1;\ for (start; start <= ende; start++) ergebnis = start * ergebnis;)expandiert zu
(ergebnis = 1;\
for (1; 1 <= 5; 1++) ergebnis = 1 * ergebnis;)Denke eher an
#define PRODUKT(start, ende, ergebnis)\ ergebnis = 1;\ for (int i=start; i <= ende; i++) ergebnis = i * ergebnis;)
-
Es ist in diesem konkreten Fall nicht notwendig, aber ich halte es für sinnvoll, geschweifte Klammern um das Makro zu setzen, d.h.
#define PRODUKT(start, ende, ergebnis) { \ ergebnis = 1; \ for (int i=start; i <= ende; i++) ergebnis = i * ergebnis; \ }Dann kann man auch
if(foo) PRODUKT(bar, baz, qux);schreiben (Semikolon optional).
Ansonsten zwei Anmerkungen zum Stil: Es ist in C++ eine gute Angewohnheit, das Präinkrement dem Postinkrement vorzuziehen, wo es möglich ist. Bei komplexen Datentypen ist ++x üblicherweise schneller als x++, weil eine Kopie eingespart wird. Außerdem kann man
ergebnis = ergebnis * i;kürzer als
ergebnis *= i;schreiben. Wieder macht das für Basistypen keinen Unterschied, kann aber bei komplexen Datentypen Arbeit einsparen und ist dementsprechend eine gute Angewohnheit.
Natürlich wäre es insgesamt auch besserer Stil, den ganzen Kram als Funktion statt als Makro umzusetzen, aber ich nehme an, dass die Aufgabenstellung das so vorschreibt.
-
Ich danke schon mal für die schnelle Hilfe!
Und ja, das mit dem Makro ist Aufgabenstellungsbedingt.
Ich habe das jetzt umgesetzt:#include <iostream> using namespace std; #define PRODUKT(start, ende, ergebnis) { \ ergebnis = 1; \ for (int i = start; i <= ende; i++) ergebnis *= i;) \ } int main() { unsigned int ergebnis; PRODUKT(3,5,ergebnis); cout << ergebnis << endl; PRODUKT(3,9,ergebnis); cout << ergebnis << endl; return 0; }Zwei neue Fragen ergeben sich mir dann:
Wozu das "int i = start"? Was macht das?
Und er schreibt nun als Fehlermeldung "Error: Es wurde ein Ausdruck erwartet" mit rot unterstrichenem "PRODUKT" in der main.
Was habe ich falsch gemacht?
(Ich benutze MS Visual 2010)edit: Das mit den
\in einer Reihe ganz hinten in dem Makro werde ich mir merken sieht hübscher aus

-
seldon schrieb:
(Semikolon optional)
Hmm, dann aber bis zum Ende führen.
Das macht dannif(foo) PRODUKT(bar, baz, qux); else PRODUKT(bar, bza, qxu);kaputt. Das ; nach } sperrt das else ab.
#define PRODUKT(start, ende, ergebnis) do { \ ergebnis = 1; \ for (int i=start; i <= ende; i++) ergebnis = i * ergebnis; \ } while(false)könnte klappen.
-
user369 schrieb:
for (int i = start; i <= ende; i++) ergebnis *= i;) \Die runde Klammer zu am Ende ist ja Quatsch.
Ich hab sie auch gemacht, bin nicht so präzise wie seldon.
-
Ahh perfekt!
Aber naja, ist schon spät ...
und ich hocke schon wieder seit 4std vor der Kiste ...
da vergisst man auch mal eine runde Klammer zu entfernen
aber es funkioniert jetzt!#include <iostream> using namespace std; #define PRODUKT(start, ende, ergebnis) do { \ ergebnis = 1; \ for (int i = start; i <= ende; i++) ergebnis *= i; \ } while (false) int main() { unsigned int ergebnis; PRODUKT(3,5,ergebnis); cout << ergebnis << endl; PRODUKT(3,9,ergebnis); cout << ergebnis << endl; return 0; }Bleibt meine Frage: Wieso das "int i = start" Was macht das?
-
user369 schrieb:
Ahh perfekt!
Aber naja, ist schon spät ...
und ich hocke schon wieder seit 4std vor der Kiste ...
da vergisst man auch mal eine runde Klammer zu entfernen
aber es funkioniert jetzt!#include <iostream> using namespace std; #define PRODUKT(start, ende, ergebnis) do { \ ergebnis = 1; \ for (int i = start; i <= ende; i++) ergebnis *= i; \ } while (false) int main() { unsigned int ergebnis; PRODUKT(3,5,ergebnis); cout << ergebnis << endl; PRODUKT(3,9,ergebnis); cout << ergebnis << endl; return 0; }Bleibt meine Frage: Wieso das "int i = start" Was macht das?
Nur ne moderne Schreibweise für
#include <iostream> using namespace std; #define PRODUKT(start, ende, ergebnis) do { \ ergebnis = 1; \ int i; \ for (i=start; i <= ende; i++) ergebnis *= i; \ } while (false) int main() { unsigned int ergebnis; PRODUKT(3,5,ergebnis); cout << ergebnis << endl; PRODUKT(3,9,ergebnis); cout << ergebnis << endl; return 0; }Und i bleibt dadurch innerhalb der for-Schleife lokal, was hier aber egal ist.
-
Ahh ok.
Dann bedanke ich mich für die Hilfe!
Mal wieder schneller und besser als meine Tutoren!
-
volkard schrieb:
user369 schrieb:
Bleibt meine Frage: Wieso das "int i = start" Was macht das?
Nur ne moderne Schreibweise für
Diese Schreibweise ist älter als viele Forenteilnehmer, den Threadersteller vermutlich eingeschlossen (falls er mit dem Studium gerade anfängt).

-
Nochwas: unsigned i ist angemessener, wenn der Prof schon mit unsigned int vorlegt.