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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von UnderDog (Gast)


Bewertung
0 lesenswert
nicht 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)


Bewertung
1 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Erkläre doch erstmal, was du vor hast.

von (prx) A. K. (prx)


Bewertung
1 lesenswert
nicht 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)


Bewertung
1 lesenswert
nicht 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


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
2 lesenswert
nicht 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


Bewertung
0 lesenswert
nicht 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)


Bewertung
1 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
-1 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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. (achs)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.