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?
|
Forum: Mikrocontroller und Digitale Elektronik Kann man mit #define rechnen?Hallo, bin ziemlich neu hier.. Kann man mit #define rechnen?
geht das irgendwie? Das quasie der Preprozessor dies berechnet? 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. Nein. Ausdrücke in #[else]if Statements sind die einzige Stelle, an der der Präprozessor tatsächlich selbst rechnet. 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. 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.
Da sowohl MAJOR als auch '0' eine Konstante ist, rechnet der Compiler bereits das Ergebnis '1' aus. 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. #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 Was geht: #if MAJOR == 0 #undef MAJOR #define MAJOR '0' #elseif MAJOR == 1 #undef MAJOR #define MAJOR '1' ... #endif :
Bearbeitet durch User
UnderDog schrieb: > Falls ich mal vergesse '1' etc. einzugeben und dafür 1 etc. #if (MAJOR < '0') #error Depp! #endif :
Bearbeitet durch User
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. 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). Brauchst Du vielleicht so etwas :
undef ist nämlich böse :-) Und : nein, #define rechnet nicht... 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. 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? 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. gauss schrieb: > ? Ist '+' keine Rechenoperation? Aus Sicht des Präprozessors ist es ein Text wie jeder andere auch. 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. 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. 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.
|
|