was passiert hier genau?



  • Hi,

    ich hab ein Problem mit folgender Aufgabe:

    #define maxm(x,y) ((x) > (y) ? (x) : (y))
    #define eval(x) (++cnt, (x))
    
    int main (void){
    
    long f[] = {0,+2,-4,+6,-8};
    long res;
    
    cnt = 0;
    res = maxm(maxm(eval(f[1]),eval(f[2])), eval(f[3]) );
    
    printf(" res = %ld, cnt = %u\n), res, cnt);
    
    return 0;
    }
    

    So, ich soll nun sagen was er ausgibt.
    Ich hab jetzt folgendes raus:

    res = maxm(maxm((1,2),(2,-4)),(3,6));

    Mein Problem ist, maxm hat ja nur 2 Parameter, hier hab ich ja auch nur 2 Parameter, aber die sind ja nochmal Paare, wie vergleiche ich die dann in maxm?
    Oder ist meine Zeile schon falsch?



  • Du ersetzt die jeweiligen formalen Parameter durch die entsprechenden Paare (z.B. x durch (1,2) und y durch (2,4) und siehst dir dann an, wie das Gesamtergebnis aussieht (innerhalb der Zahlenpaare steht , für den Komma-Operator).

    PS: Übrigens solltest du das ++cnt besser nicht durch die jeweiligen Zahlenwerte ersetzen - für deine Auswertung dürfte es interessanter sein, wo und wie oft der Teil im fertigen Programm auftraucht.



  • int i = (1,2,3); // i ist 3

    der kommaoperator (nicht verwechseln mit argumentlistentrennzeichen) ist was ganz lustiges. merk dir die eigenheit und du kannst schoen verwirrenden code schreiben.

    edit: bei makroexpansion musst du ZU ERST alles expandieren, und erst danach die komma-operatoren und ternaeroperatoren aufloesen etc.
    komplett expandiert:

    res = 
    	(((++cnt, f[1]) > (++cnt, f[2]) ?
    	(++cnt, f[1]) : (++cnt, f[2])))
    	>
    	((++cnt, f[3]))
    
    	? 
    
    	(((++cnt, f[1]) > (++cnt, f[2]) ?
    	(++cnt, f[1]) : (++cnt, f[2])))
    
    	:
    
    	((++cnt, f[3]));
    

    erst jetzt kannst du zusammenfassen.



  • Irgendwie scheck ich das nicht.

    Wenn ich folgendes habe:

    (1,2) > (4,5)

    Wie gehe ich bei dem Vergleich vor?
    1 mit 4, 2 mit 5?

    oder einfach nur 2 mit 5?
    oder wie?

    Ich hab mal eben nach dem Komma-Operator gesucht, aber in diesen Zusammenhang finde ich dazu natürlich nichts 😉

    Ich habe in selber immer bei for-Schleifen eingesetzt, bei der initialisierung verstehe ich es ja auch noch, aber hier irgendwie nicht.



  • Der Kommaoperator macht nichts ausser den rechtesten Ausdruck zurückgeben (und natürlich alle anderen Ausdrücke auswerten)... Hier c.rackwitz' Beispiel mal etwas krasser:

    int i = (NULL, printf("Hallo, Welt\n"), 134); // i ist jetzt 134 UND auf dem Bildschirm ercheint "Hallo, Welt"
    


  • (1,2) > (4,5)
    wird so gelesen:
    2 > 5

    von den listen werden die ersten elemente ausgefuehrt/ausgewertet, aber nur vom letzten wird das ergebnis benutzt.



  • c.rackwitz schrieb:

    (1,2) > (4,5)
    wird so gelesen:
    2 > 5

    von den listen werden die ersten elemente ausgefuehrt/ausgewertet, aber nur vom letzten wird das ergebnis benutzt.

    Alles klar, vielen Dank euch!



  • Nebenbei - nach der Arbeit des Präprozessors steht dort nicht "(1,2)>(2,4)", sondern "(++cnt,2)>(++cnt,4)" - und dieses ++cnt wird überall dort ausgeführt, wo es im fertig übersetzten Programm auftaucht.

    #define maxm(x,y) ((x) > (y) ? (x) : (y))
    #define eval(x) (++cnt, (x))
    long f[] = {0,+2,-4,+6,-8};
    
    cnt = 0;
    res = maxm(maxm(eval(f[1]),eval(f[2])), eval(f[3]) );
    
    res = maxm(maxm((++cnt,(f[1])),(++cnt,(f[2]))), (++cnt,(f[3])) );
    
    res = maxm(((++cnt,(f[1]))>(++cnt,(f[2])) ? (++cnt,(f[1]) : (++cnt,(f[2])), (++cnt,(f[3])) );
    
    res = (((++cnt,(f[1]))>(++cnt,(f[2])) ? (++cnt,(f[1]) : (++cnt,(f[2]))>(++cnt,(f[3])) ? ((++cnt,(f[1]))>(++cnt,(f[2])) ? (++cnt,(f[1]) : (++cnt,(f[2])) : (++cnt,(f[3])))
    

    bis hierher war das sture Makro-Ersetzung, als nächstes kürze ich ein paar Klammern und setze die f[..]-Werte ein:

    res = ( (++cnt,2)>(++cnt,-4)?(++cnt,2):(++cnt,-4) )>(++cnt,6) ? ((++cnt,2)>(++cnt,-4)?(++cnt,2):(++cnt,-4)) : (++cnt,6)
    

    Und jetzt kommt der entscheidende Punkt - dieser Ausdruck wird ausgewertet:

    res = ( (++cnt,2)>(++cnt,-4)?(++cnt,2):(++cnt,-4) )>(++cnt,6) ? ((++cnt,2)>(++cnt,-4)?(++cnt,2):(++cnt,-4)) : (++cnt,6)
          (     2    >   -4     ?    2    :   ---     )>    6     ?                    ---                      :     6
    

    Punkt 1: Der Gesamtwert des Ausdrucks ist 6.
    Punkt 2: Während der Berechnung wird 5 mal ++cnt ausgeführt, also hat cnt (normalerweise) den Endwert 5
    Punkt 3: Die Reihenfolge der Nebeneffekte ist undefiniert, also könnte sich da auch etwas überlagern



  • Jo, hab ich auch rausbekommen. Aber danke für die Ausführliche Antwort 🙂



  • erklaerungswut, der schwache moment eines jeden lehrers. einfach ausnutzbar durch viele schnell gestellte komplizierte fragen, die ausschweifende antworten benoetigen. 🤡



  • c.rackwitz schrieb:

    erklaerungswut, der schwache moment eines jeden lehrers. einfach ausnutzbar durch viele schnell gestellte komplizierte fragen, die ausschweifende antworten benoetigen. 🤡

    So kann man es auch formulieren 🕶 und dabei bin ich nichtmal Lehrer.



  • c.rackwitz schrieb:

    erklaerungswut

    naja, aber dein homepage ist das bescheuertste was ich je gesehen habe...



  • net schrieb:

    naja, aber dein homepage ist das bescheuertste was ich je gesehen habe...

    suchst du streit?



  • c.rackwitz schrieb:

    net schrieb:

    naja, aber dein homepage ist das bescheuertste was ich je gesehen habe...

    suchst du streit?

    nee, das war nur ne nüchterne feststellung meinerseits. was blöderes hab ich noch nicht gesehen. aber das ist ja gschmackssache...


Anmelden zum Antworten