Gast
#1966422
Hallo. Kleines Quiz: #define MUL(a, b) a * b int c = MUL(2+ 3, 2 + 4); Frage: Was ist das Ergebnis für c? Was interessant wäre: Wie lang habt ihr für die richtige Antwort gebraucht? Gruß Christian
|
Anzeige
|
Programmier Quiz
Gast
#1966422
Hallo. Kleines Quiz: #define MUL(a, b) a * b int c = MUL(2+ 3, 2 + 4); Frage: Was ist das Ergebnis für c? Was interessant wäre: Wie lang habt ihr für die richtige Antwort gebraucht? Gruß Christian
Gast
#1966430
Tippe mal auf 30 mfG ingo
Gast
#1966433
12
Gast
#1966434
Ergebnis = 6 Das ist ja nun wirklich einer der bekanntesten Fallstricke bei der Verwendung vom Makros... int c = 2+ 3 * 2 + 4; Tippe auf 12, denn mit den 30 von ingo sind das dann 42 LOL 12 @Christian: Was kommt hier raus? #define MUL (a, b) -a*b- int a = 1; int b = 2; int c = MUL(2+ 3, 2 + 4);
Gast
#1966583
Ergebnis = -6
Gast
#1966590
12 Fabian schrieb: > 12 für meine Aufgabe? Nö. für das Original? ja.
Gast
#1966599
Deswegen schreibt man auch #define MUL(a, b) (a)*(b) Christian schrieb: > Ergebnis = -6 ok, das kommt raus, wenn man es laufen lässt. Die Frage ist natürlich, warum?
Gast
#1966625
>Die Frage ist natürlich, warum?
Das ist eine gute Frage! Das originale Rätsel ist ja gerade zu trivial,
dieses hier ist es deutlich weniger. Man beachte das Leerzeichen hinter
MUL, ohne compiliert das schon mal nicht. Hab mal geguckt was der
Präprozessor von GCC da bastelt, kann das aber nicht nachvollziehen, ich
komme auf -5 oder 1. Sehr komisch...
Damit hält sich der GCC gar nicht lange auf. Der optimiert das einfach
weg.
00000088 <main>:
int main(void)
{
int c = MUL(2+ 3, 2 + 4);
Initialize();
88: f1 df rcall .-30 ; 0x6c <Initialize>
8a: ff cf rjmp .-2 ; 0x8a <main+0x2>
0000008c <SetDAC>:
}
Wenn du Code sehen willst, musst du den Wert natürlich noch verwenden. Es geht aber nicht darum, den fertigen Wert ausgespuckt zu bekommen, sondern wie es dazu kommt, also warum zum Schluß ein bestimmter Wert erscheint. User schrieb: > Deswegen schreibt man auch > #define MUL(a, b) (a)*(b) Nur wenn man es immer noch nicht kapiert hat. Denn sonst schriebe man: #define MUL(a, b) ((a)*(b))
Gast
#1966713
User schrieb: > Deswegen schreibt man auch > > #define MUL(a, b) (a)*(b) Um genau zu sein, schreibt man sogar
Das Ergebnis in Klammern zu setzen, verhindert Fehler wie (am Beispiel von ADD(a,b) := ((a)+(b))): ADD(1,2)*3. Ohne Klammern wäre dies (1)+(2)*3 = 7, mit Klammern korrekterweise ((1)+(2))*3 = 9. Auch bei MUL sind die Klammern außenrum nötig, da es auch Operatoren mit höherer Präzedenz als "*" gibt, nämlich (in C) z.B. unäres "+"/"-", oder Adress- und Dereferenzoperator "&" bzw. "*", oder "++"/"--", oder Array-Zugriff "[]", oder Funktionsaufruf "()", usw.
Gast
#1966730
Ich hab mir das nochmal angeschaut, scheint mit dem oft gelobten / verfluchten Kommaoperator und der Operatorenpriorität zutun zu haben... Aus
macht der Präprozessor
. Wenn man die Variablen "auflöst" gibt das
was das gleiche Ergebnis wie
oder "schöner" formatiert
liefert. Wenn man die Klammern wegnimmt
compiliert das ganze noch, liefert aber ein falsches Ergebnis (1). Komische Sache dieses "C"!
Gast
#1966856
Bei
macht der Präprozessor aus der letzten Zeile
die wie folgt ausgewertet wird
1: Zuerst werden die Klammern ausgewertet. 2: Der Komma-Operator bewirkt, daß Wert und Typ des Ausdrucks dem letzten Teilausdruck entsprechen. 3: Multiplikation hat die höchste, verbleibende Priorität. 4: Es verbleiben nur noch Subtraktionen. 5: Ergebnis is -6. Die niedrigste Priorität hat der Zuweisungsoperator, dieser wird als letztes berücksichtigt und somit am Ende der Variablen c der Wert -6 zugewiesen.
Gast
#1966863
@Clown Danke, sehr anschaulich!
Gast
#1966874
A. K. schrieb: > User schrieb: > >> Deswegen schreibt man auch >> #define MUL(a, b) (a)*(b) > > Nur wenn man es immer noch nicht kapiert hat. Denn sonst schriebe man: > #define MUL(a, b) ((a)*(b)) Ich hatte noch überlegt, aber dann entschieden, dich nicht damit auch noch zu überfordern. Klaus Wachtler schrieb: > Wenn du Code sehen willst, musst du den Wert natürlich noch verwenden. > > Es geht aber nicht darum, den fertigen Wert ausgespuckt zu bekommen, > > sondern wie es dazu kommt, also warum zum Schluß ein bestimmter Wert > > erscheint. Das war mir schon klar. Wenn man die Variable volatile deklariert ist das Ergebnis übrigends 12 mfg.
Gast
#1967338
Zu: #define MUL (a, b) -a*b- Die obige define Direktive wird übrigens nicht von allen Compilern unterstützt.VisualStudio,GCC könnens, spezifische Compiler wie Cross Compiler oder andere nicht. Meckern tun sie alle bei b-. Gruß Christian
Gast
#1967409
@Klaus Was kommt hier raus? #define min(a,b) ( (a < b) ? (a) : (b) ) a = b = 1; c = min(++a,++b); c == ??? Gruß Christian Wieder eher ein Klassiker: a 3 b 2 c 3
Gast
#1967472
Wahr lahm, zugegebenermaßen.
Gast
#1967514
Übersehe ich hier etwas? Bei mir gibt
das Ergebnis
Zuerst wird die Bedingung (++a < ++b) ausgewertet. Dabei zuerst auf beiden Seiten des Vergleichs die Inkrementierung durchgeführt. Die Variablen a und b besitzen damit zu dem Zeitpunkt jeweils beide den Wert 2. Der Vergleich, ob a kleiner b ist, schlägt damit fehl. Dadurch wird also der nicht-wahr-Zweig des ternären Operators ausgewertet, also b noch einmal inkrementiert. Dieser neue Wert von b, also 3, wird nun der Variablen c zugewiesen.
Gast
#1967530
Clown hat recht: b und c haben am Ende 3 -> b==c==3 a wird nur einmal inkrementiert-> also a==2 Gruß Christian Ja, sorry - Schreibfehler von mir Gefragt war ja nur nach c, insofern ist der Fehler vielleicht verzeihlich :-)
Gast
#1968371
> c = min(++a,++b);
undefiniert. Zweimal Seiteneffekt mit der gleichen Variablen in einem
Ausdruck.
sebastians schrieb: > undefiniert. Zweimal Seiteneffekt mit der gleichen Variablen in einem > Ausdruck. Nein. Das ? in ?: ist ein sequence point. Christian schrieb: > Clown hat recht: > b und c haben am Ende 3 -> b==c==3 > a wird nur einmal inkrementiert-> also a==2 Wobei ein fieser Nebenschauplatz an der Situation darin besteht, dass auch der Fall möglich ist, dass hinten nach a gleich c ist und b nur einmal inkrementiert wird. Je nach den konkreten Werten für a und b ja, aber a und b waren doch gegeben. Antwort schreibenBitte melde dich an, um einen Beitrag zu schreiben. |
Anzeige
|