Forum: Mikrocontroller und Digitale Elektronik #define mit if


von rasked (Gast)


Lesenswert?

Hallo!

Habe nur eine kurze Frage:
Ein define mit Bedingungsoperator kann man ja so realisieren:

#define X ((auswahl==1)?(!(0x02)):(0x03))

Hier habe ich das Problem das ich natürlich nur eine Bedingung habe.
Weiters sind auch nur zwei Werte für X möglich.

Ist es möglich, dass hier mit einer If-Anweisung zu realisieren?
Wenn ja, wie?

Danke euch allen!

Grüße

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

rasked schrieb:
> Ist es möglich, dass hier mit einer If-Anweisung zu realisieren?
> Wenn ja, wie?

Ein C-Preprocessor ist nichts anderes als ein Textersetzer. Du kannst 
also alles mögliche da reinschreiben.

Aber ehrlich gesagt: ganz habe ich Deine Frage nicht verstanden. Sag 
doch erstmal was Du willst. Dein Beispiel ist auch ziemlich wirr, Du 
weisst, was das Ergebnis von !(0x02) ist?

Gruß,

Frank

von Oliver (Gast)


Lesenswert?

Gegenfrage: Warum willst oder musst du dafür ein define (bzw. ein 
define-Makro verwenden?

Dein Beispiel ist übrigens kein define-Makro. So etwas ist üblicherweise 
nur was für die Endrunden-Teilnahme am Obfuscated C-Contest.

Aber um deine Frage zu beantworten: #define ist nichts anderes als eine 
Textersetzung. Du kannst da also hinschreiben, was du willst, so lange 
die Textersetzung im Programm gültigen C-Code ergibt. Wenn es sein muß, 
auch komplette Programmblöcke (am einfachtsen in geschweiftren 
Klammern).

Obs sinnvoll ist, sei dahingestellt.

Oliver

von Klaus W. (mfgkw)


Lesenswert?

Vielleicht will er die ?: schachteln?
1
#define X ( (auswahl==1) ? 0x02 : ( (auswahl==2) ? 0x04 : ( (auswahl==3) ? 0x08 : 0x10 ) ) )

von rasked (Gast)


Lesenswert?

Zur Klarstellung:

X will ich wenn die Variable Auswahl 1 ist 0x02 setzen
und bei 2 0x03 setzen
und bei 3 0x04 setzen.

So wie es Klaus macht wäre es natürlich auch möglich ist aber leider 
nicht mehr so übersichtlich.

Wie mache ich die Variante von Klaus mit if-else?
1
#define X {
2
           if (auswahl==1) 0x02;
3
           else if (auswahl==2) 0x04;
4
           else if (auswahl==3) 0x08;
5
           else 0x10;
6
          }

So stimmt es sicher nicht. Könnt ihr das berichtigen?

Sorry das ! kommt natürlich weg.

Danke nochmals!

von Peter D. (peda)


Lesenswert?

Wie wärs mit:
1
#define X (1<<(auswahl))


Peter

von Karl H. (kbuchegg)


Lesenswert?

rasked schrieb:

> So wie es Klaus macht wäre es natürlich auch möglich ist aber leider
> nicht mehr so übersichtlich.

Ganz ehrlich:

Wenn du auf Übersichtlichkeit stehst, mach dir dafür eine Funktion.
Makros sehen nur auf den ersten Blick 'übersichtlich' aus. Sie sind es 
nicht. Sie sind ein besonders eleganter Weg, wie man sich ohne viel 
Nachdenken, ganz schnell bei komplizierteren Dingen möglichst 
schmerzhaft selbst in den Fuss schiessen kann.

> Wie mache ich die Variante von Klaus mit if-else?
>
1
> #define X {
2
>            if (auswahl==1) 0x02;
3
>            else if (auswahl==2) 0x04;
4
>            else if (auswahl==3) 0x08;
5
>            else 0x10;
6
>           }
7
>
>
> So stimmt es sicher nicht. Könnt ihr das berichtigen?

Wenn eine Makrozeile mit einem \ (und nichts mehr dahinter) beendet 
wird, so bedeutet das, das die nächste Zeile auch noch zum Makro gehört.

Und jetzt probierst du dann dein neues Makro hier aus

   if( irgendwas )
     X;
   else
     was anderes

und versuchst aus den Fehlermeldungen auf das Problem zu schliessen.

Fazit: Wenn Makros komplizierter werden, ist eine Funktion die bessere 
Lösung.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

rasked schrieb:

> So wie es Klaus macht wäre es natürlich auch möglich ist aber leider
> nicht mehr so übersichtlich.
>
1
> #define X {
2
>            if (auswahl==1) 0x02;
3
>            else if (auswahl==2) 0x04;
4
>            else if (auswahl==3) 0x08;
5
>            else 0x10;
6
>           }
7
>
1
#define X(zielvariable_,auswahl_)              \
2
{                                              \
3
  if (auswahl_==1) zielvariable_ = 0x02;       \
4
  else if (auswahl_==2) zielvariable_ = 0x04;  \
5
  else if (auswahl_==3) zielvariable_ = 0x08;  \
6
  else zielvariable_ = 0x10;                   \
7
}

(Beachte die Backslashes am Ende jeder (ausser der letzten!) Zeile)

Dann kannst Du im C-Source einfach schreiben:

    X(xyz, auswahl);

Das Ergebnis steht dann in der Variablen xyz.

Aber Du solltest Dich mal erkundigen, was ein switch() macht, der ist 
wesentlich eleganter und effizienter. Ausserdem weiss ich nicht, warum 
Du sowas als Preprocessor-Makro und nicht als Funktion definieren 
willst...

Gruß,

Frank

von Simon K. (simon) Benutzerseite


Lesenswert?

Am besten direkt eine static-inline Funktion benutzen. Da hat man dann 
Typüberprüfung der Parameter usw. Und man schießt sich halt nicht in den 
Fuß, wie Karl Heinz shcon sagte.
Ist außerdem genau so schnell wie ein Makro.

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.