Forum: Mikrocontroller und Digitale Elektronik Kann man mit #define rechnen?


von UnderDog (Gast)


Lesenswert?

Hallo,

bin ziemlich neu hier..

Kann man mit #define rechnen?
1
#define MAJOR 1
2
3
#if (MAJOR < '0')
4
MAJOR += '0'

geht das irgendwie? Das quasie der Preprozessor dies berechnet?

von Horst Günther (Gast)


Lesenswert?

UnderDog schrieb:
> MAJOR += '0'

In C: Nö. Der Präprozessor ist primär ein Textersetzungstool. Warum 
nicht erneutes #define von MAJOR mit dem korrekten Wert?
Davon ab: '0' ist ungleich einer dezimalen Null.

von A. (Gast)


Lesenswert?

Erkläre doch erstmal, was du vor hast.

von (prx) A. K. (prx)


Lesenswert?

Nein. Ausdrücke in #[else]if Statements sind die einzige Stelle, an der 
der Präprozessor tatsächlich selbst rechnet.

von Georg G. (df2au)


Lesenswert?

UnderDog schrieb:
> #define MAJOR 1
>
> #if (MAJOR < '0')
> MAJOR += '0'

Nach dem Durchlauf des Präprozessors sieht das dann so aus:

#if (1 < 48)
 1 += 48

Das ist vermutlich nicht genau das, was dir vorschwebte.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

UnderDog schrieb:
> Kann man mit #define rechnen?
> #define MAJOR 1
>
> #if (MAJOR < '0')
> MAJOR += '0'
>
> geht das irgendwie? Das quasie der Preprozessor dies berechnet?

Wahrscheinlich willst Du die Major-Version Deines Programms ausgeben.
1
#define MAJOR 1
2
3
int main ()
4
{
5
    int major = MAJOR + '0';
6
7
    printf ("major = %c\n", major);
8
    return 0;
9
}

Da sowohl MAJOR als auch '0' eine Konstante ist, rechnet der Compiler 
bereits das Ergebnis '1' aus.

von UnderDog (Gast)


Lesenswert?

Man kann "MAJOR" ja auch als eine int Nummer angeben.
Dies musste ich zur Laufzeit ja erst noch umrechnen. Das wollte ich mit 
dem Prep.. machen.

Falls ich mal vergesse '1' etc. einzugeben und dafür 1 etc.

von UnderDog (Gast)


Lesenswert?

#if (VERSION_MAJOR < '0')
#undef VERSION_MAJOR
#define VERSION_MAJOR (hier der wert vom alten #define VERSION_MAJOR + 
'0')
#endif

ich bräuchte den alten wert

von (prx) A. K. (prx)


Lesenswert?

Was geht:
 #if MAJOR == 0
   #undef MAJOR
   #define MAJOR '0'
 #elseif MAJOR == 1
   #undef MAJOR
   #define MAJOR '1'
  ...
 #endif

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

UnderDog schrieb:
> Falls ich mal vergesse '1' etc. einzugeben und dafür 1 etc.

#if (MAJOR < '0')
 #error Depp!
#endif

: Bearbeitet durch User
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

A. K. schrieb:
> #if (MAJOR < '0')
>  #error Depp!
> #endif

Absolut ACK. Man sollte einen persönlichen Fehler ("Vergessen, in 
Hochkommata zu schreiben") nicht durch irgendwelche Automatismen 
kompensieren, sondern eindeutig auf den Fehler hinweisen, damit er 
anschließend korrigiert wird.

von Adapter (Gast)


Lesenswert?

Frank M. schrieb:
> A. K. schrieb:
>> #if (MAJOR < '0')
>>  #error Depp!
>> #endif
>
> Absolut ACK. Man sollte einen persönlichen Fehler ("Vergessen, in
> Hochkommata zu schreiben") nicht durch irgendwelche Automatismen
> kompensieren, sondern eindeutig auf den Fehler hinweisen, damit er
> anschließend korrigiert wird.

ebenfalls ACK. Die Faustformel hier lautet, dass Fehlererkennung und 
-Korrektur um so besser und effektiver ist, je früher sie angewandt 
werden kann. Also jeder zur Designzeit erkennbare Fehler sollte auch 
dort erkannt werden (Designzeit vor Compilierzeit vor Laufzeit).

Wobei Erkennung in diesem Fall besser ist als Korrektur, denn wenn der 
TO tatsächlich so eine Krücke mit On-the-Fly- Geradebiegen einbauen 
sollte, dann wird lt. Murphy §23 Abs. 4, Satz 2 garantiert irgend Jemand 
im späteren Projektverlauf durch eine ungünstige Verkettung von 
#includes auf MAJOR zugreifen, BEVOR es umgebogen wurde.

Oder der Andere Klassiker: Der Wertebereich von MAJOR wird später so 
uminterpretiert, dass '0' - 1 plötzlich erlaubt ist (z.B. als Broadcast 
o.ä.), und dann wird die Fehlerkorrektur plötzlich zur Fehlerquelle.

Beide Fehler resultieren aus dem einfachen Fakt, dass MAJOR bei der 
Korrektur durch den Präprozessor eine dynamische Komponente bekommt, 
also mehr als einen Wert annehmen kann. Bei der #error Variante ist der 
Wert vollständig statisch, also garantiert immer das, als was er einmal 
definiert worden ist.

Also automatische Erkennung zur Compilezeit und Korrektur zur Hirnzeit. 
Sicherer geht's nicht (natürlich nur in diesem Fall und äquivalenten 
Fällen).

von fop (Gast)


Lesenswert?

Brauchst Du vielleicht so etwas :
1
#define MAJOR 1
2
3
#if (MAJOR < '0')
4
#define ASCII_MAJOR ((MAJOR)+'0')
5
#else
6
#define ASCII_MAJOR (MAJOR)
7
#endif

undef ist nämlich böse :-)

Und : nein, #define rechnet nicht...

von fop (Gast)


Lesenswert?

Zum Thema Murphy :
Ich denke eher, dass er im Programm noch so viel korrigieren muss, dass 
er irgendwann bei Major-Version 10 und höher ist, welche dann als 
Doppelpunkt, Semikolon oder ähnliches ausgegeben werden.

von gauss (Gast)


Lesenswert?

fop schrieb:
> Brauchst Du vielleicht so etwas :#define MAJOR 1
>
> #if (MAJOR < '0')
> #define ASCII_MAJOR ((MAJOR)+'0')
> #else
> #define ASCII_MAJOR (MAJOR)
> #endif
>
> undef ist nämlich böse :-)
>
> Und : nein, #define rechnet nicht...

> #define ASCII_MAJOR ((MAJOR)+'0')

? Ist '+' keine Rechenoperation?

von fop (Gast)


Lesenswert?

Du kannst bei Word auch den Text 17+4 einfügen, ohne das Word versucht 
die beiden Zahlen zu addieren...

Erst nachdem der Precompiler stumpf den Text eingefügt hat, läuft der 
Compiler los, erkennt hoffentlich den Ausdruck als konstant und macht 
sich daran, dessen Wert zu bestimmen. Zu diesem Zeitpunkt ist aber schon 
so gut wie alles, was mit # beginnt Geschichte.

von (prx) A. K. (prx)


Lesenswert?

gauss schrieb:
> ? Ist '+' keine Rechenoperation?

Aus Sicht des Präprozessors ist es ein Text wie jeder andere auch.

von Axel S. (a-za-z0-9)


Lesenswert?

gauss schrieb:
>> Und : nein, #define rechnet nicht...
>
>> #define ASCII_MAJOR ((MAJOR)+'0')
>
> ? Ist '+' keine Rechenoperation?

Das wird nicht im #define (vulgo: vom Präprozessor) ausgerechnet.

Aber wenn irgendwo im Quelltext ASCII_MAJOR steht, ersetzt es der 
Präprozessor (rekursiv) durch ((1)+'0') und weil der Ausdruck konstant 
ist, berechnet ihn der C-Compiler(!) zur Compilezeit.

von A. S. (Gast)


Lesenswert?

UnderDog schrieb:
> Falls ich mal vergesse '1' etc. einzugeben und dafür 1 etc.

Falls Major eine Versionsnummer darstellen soll, wirst Du mit '1' nicht 
glücklich. Mach als int und rechne wie empfohlen um.

von Alex G. (dragongamer)


Lesenswert?

Zu sagen #define rechnet nicht, verwirrt hier mehr als das es aufklärt.
Man definiert damit schlicht sogenannte Makros. Nichts mehr und nichts 
weniger. Der bereits erwähnte Präprozessor führt dann entsprechende 
Ersetzungen durch, so dass dann z.B. das von Georg da steht: 
Beitrag "Re: Kann man mit #define rechnen?"

Ich würde übrigens solche Macros aussagekräftiger bennen, wenn es sowas 
heikles ist.
Also "ASCII_MAJOR" ist da schon ein gutes Beispiel. Oder gar 
"MAJOR_VER_AS_ASCII".

Solang du generell Spagetticode vermeidest, schaden lange, aber 
aussagekräftige Variabelnamen nicht.

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.