Daniel schrieb:
> Ok, danke, nun habe ich verstanden.
> Dann ist es aber ungeschickt eigentlich, dies als Textersetzung zu
> machen, denn schließlich kostet das ja auch Rechenzeit. Besser wäre es
> doch, wenn ich es dann wirklich "vorab" ausgerechnet als #define
> schreibe oder?
Aber geh.
Sobald der Präprozessor alle Textersetzungen gemacht hat, kommt da raus
test = test/((8000000UL*256)/8000000UL) ;
und dann kommt der eigentliche Compiler, der dann den konstanten
Ausdruck auswertet und durch 256 ersetzt.
Solange du dir bewusst bist, dass der Präprozessor reine Textersetzung
macht und du deine Makros so schreibst, dass auch dann keine
Fehlinterpretation möglich ist, solange bist du auf der sicheren Seite.
Im Zweifelsfall macht man einfach selbst mal die Textersetzungen und
sieht sich an was da raus kommt.
zb
was ist das Problem bei
1 | #define TWICE(x) 2 * x
|
2 |
|
3 | i = TWICE( 3+2 );
|
offensichtlich wollte der Programmierer ein Makro schreiben, welches
immer das Doppelte ergibt. 3+2 macht 5, und das Doppelte davon ergibt
10.
Nur: Im Programm kommt 8 raus.
Warum?
Na, mach mal die Textersetzung.
Ersetze in der Makroverwendung das Makro gegen den Ersatztext und
tausche gleichzeitig x durch 3+2 aus. Dann steht da
und das ergibt nun mal 8 und nicht die erhofften 10. Denn den
Präprozessor kümmert nicht, dass das * jetzt nur auf die 3 wirkt und
nicht auf die 2. Textersetzung! Ohne Rücksicht auf Verluste! Was immer
dann rauskommt, kommt raus.
Schreibt man es so
1 | #define TWICE(x) 2*(x)
|
2 |
|
3 | i = TWICE( 3+2 );
|
dann stimmts wieder, denn wenn man jetzt die Ersetzung vornimmt
ist klar, dass hier in der Berechnung die Absicht des Programmierers,
nämlich das Doppelte von 3+2 zu erhalten durch die Klammern um x erfüllt
wird.
Was ist hier das Problem
1 | #define MWST 0.2
|
2 | #define PREIS_BRUTTO(x) x + MWST*x
|
3 |
|
4 |
|
5 | double Einzelpreis = 5.0;
|
6 |
|
7 | double Preis_fuer_1_Stueck = PREIS_BRUTTO( Einzelpreis );
|
8 | double Preis_fuer_5_Stueck = 5 * PREIS_BRUTTO( Einzelpreis );
|
Warum ist zwar der Preis für 1 Stück korrekt, der Preis für 5 aber
nicht?
(Wieder: mach die Textersetzungen und du siehst das Problem)
Aber Vorsicht: Nicht alle Probleme lassen sich mit Klammern lösen!
1 | #define MAX(x,y) ((x) > (y) ? (x) : (y))
|
2 |
|
3 | int j = 5, k = 8;
|
4 |
|
5 | i = MAX( j++, k++ );
|
welche Werte würdest du nach dem Statement für i, j und k erwarten. Wie
sind die Werte tatsächlich?