Forum: PC-Programmierung Präprozessor verständnisproblem


von cfreund (Gast)


Lesenswert?

Hallo,

ich hab ein kleines Programm geschrieben, bei dem 3 mal ein 
präprozessormacro aufgerufen wird.
Das marco überprüft den parameter a auf gleichheit mit 1. wenn 
gleichheit vorliegt wird das makro durch eine 1 ersetzt ansonsten durch 
eine 2.
die ersten beiden aufrufe klappen und erfüllen die gemachten aussagen.
nun wollte ich die beiden ergebnisse einfach addieren, allerdings klappt 
es nicht, weis jemand wieso?
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <stdint.h>
4
5
6
#define check(a) (a==1) ? 1 : 2
7
8
9
10
int main()
11
{
12
    printf(" sollte 1 liefern\t %d\n",check(1));
13
    printf(" sollte 2 liefern\t %d\n",check(2));
14
    printf("warum liefert es nicht 3? \t %d\n",(check(1)+check(2)));
15
16
    return 0;
17
}

: Verschoben durch Admin
von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Lesenswert?

Klammern helfen.

Das letzte Makro loest sich zu
(1==1) ? 1 : 2 + (2==1) ? 1 : 2
also
(1==1) ? 1 : (2 + (2==1) ? 1 : 2)
auf

#define check(a) ((a==1) ? 1 : 2)
macht die Sache eindeutig.

von Peter II (Gast)


Lesenswert?

weil dann das steht

(a==1) ? 1 : 2 + (a==1) ? 1 : 2

und wenn ich die Operator prio richtig versteht, bindet  + mehr als ?

damit steht dort:

((a==1) ? 1 : 2 + (a==1)) ? 1 : 2

von Little B. (lil-b)


Lesenswert?

der Präprozessor führt keine Berechnungen durch (an dieser Stelle).
Es wird nur "check(a)" mit "(a==1) ? 1 : 2" ersetzt.

(check(1)+check(2))
ergibt somit
(1==1) ? 1 : 2+(2==1) ? 1 : 2

Fehler von deiner Seite: Es fehlen Klammern um dein Makro!

#define check(a) ((a==1) ? 1 : 2)

von Karl H. (kbuchegg)


Lesenswert?

cfreund schrieb:
> Hallo,
>
> ich hab ein kleines Programm geschrieben, bei dem 3 mal ein
> präprozessormacro aufgerufen wird.

Ein Makro wird nicht 'aufgerufen'.

Ein Makro ist eine Anweisung, einen Text durch einen anderen Text zu 
ersetzen.

Dein Makro

> #define check(a) (a==1) ? 1 : 2

vereinbart, dass der Text 'check' durch den Text '(a==1) ? 1 : 2' zu 
ersetzen ist, wobei zusätzlich noch ein gewisses 'a' durch den bei der 
Makroverwendung angegebenen Text zu ersetzen ist.

>     printf("warum liefert es nicht 3? \t %d\n",(check(1)+check(2)));

ersetz mal die Texte
aus
1
     ... check(1) + check(2)

wird
1
    ... (1==1) ? 1 : 2 + (2==1) ? 1 : 2

und jetzt lass deine Analysefähigkeiten spielen, wie dieser Ausdruck 
abgearbeitet wird.

von cfreund (Gast)


Lesenswert?

Vielen Dank für eure hilfreichen antworten.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Bei Makros, die aus einem Ausdruck bestehen, ist es ratsam, nicht nur
den gesamten Ausdruck, sondern auch die einzelnen Argumente innerhalb
des Ausdrucks zu klammern.

Was das Fehlern der äußeren Klammern bewirkt, hast du bereits gesehen.

Folgendes liefert aber ebenfalls ein unerwartetes Ergebnis:
1
#define check(a) ((a==1) ? 1 : 2)
2
3
  printf("%d\n", check(5 & 3));

Das bitweise Und von 5 und 3 ergibt 1, so dass man erwarten könnte, dass
"1" ausgegeben wird.

Tatsächlich wird das Makro aber in
1
  ((5 & 3==1) ? 1 : 2);

expandiert. Da "==" stärker bindet als "&", ist das Ergebnis nicht 1,
sondern 2. Abhilfe schafft die Klammerung des Arguments a in der
Makrodefinition:
1
#define check(a) (((a)==1) ? 1 : 2)

Die Klammer um den "=="-Teilausdruck kann man – je nach Geschmack – auch
weglassen:
1
#define check(a) ((a)==1 ? 1 : 2)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.