Forum: Mikrocontroller und Digitale Elektronik Frage zu #define


von Lutz (Gast)


Lesenswert?

Hallo, ich stehe vor einem kleinen Problem.

Ich habe folgendes vor:

#define VAR1 100
#define VAR2 VAR1 / 50

funktion("VAR2");

Ist AVR Studio so schlau und rechnet mir VAR2 aus, der eigentliche 
Aufruf solle funktion("2"); lauten. Funktioniert aber nicht, im fertigen 
programm wird nur der String "VAR2" übergeben

Wie kann ich #define Makros als String verwenden?

Gibt es eine Übersicht was man mit #define alles machen kann?

von johnny.m (Gast)


Lesenswert?

Wenn Du VAR2 in Anführungszeichen setzt, wird das natürlich als String 
interpretiert. Wie kommst Du überhaupt auf die Idee mit den 
Anführungszeichen? "" schließt grundsätzlich einen ASCII-String ein.

von Rolf Magnus (Gast)


Lesenswert?

Das geht nicht. Erstens kannst du innerhalb eines Strings keine Makros 
benutzen, zweitens berechnet ein #define erstmal gar nichts. Es macht 
nichts weiter als eine Textersetzung. Wenn es also ginge, das in Strings 
zu verwenden, würde trotzdem nicht "2", sondern "100 / 50" rauskommen.

von johnny.m (Gast)


Lesenswert?

Ach, ich glaub, so langsam dämmert mir, was Du vorhast... Nein, das geht 
selbstverständlich nicht! #define macht eine reine Textersetzung. Wenn 
Du aber den Text in Anführungszeichen setzt, dann wird die Textersetzung 
nicht vorgenommen. Wenn Du den ASCII-Character '2' als Funktion von VAR2 
an eine Funktion übergeben willst, dann kannst Du das z.B. machen, indem 
Du anstatt "VAR2" (char)(VAR2 + '0') übergibst. Das funktioniert aber 
nur dann, wenn VAR2 eine einzige Ziffer darstellt.

von johnny.m (Gast)


Lesenswert?

EDIT:
> Das funktioniert aber nur dann, wenn VAR2 eine einzige Ziffer darstellt.
Das funktioniert aber nur dann, wenn der Wert von VAR2 durch eine 
einzige Ziffer darstellbar ist.

von Karl H. (kbuchegg)


Lesenswert?

Dein Problem ist, dass #define innerhalb eines bereits
vorhandenen Strings keine Ersetzungen mehr vornimmt.

Also musst du dafür sorgen, dass in

function( VAR2 );

die Ersetzung für VAR2 bereits ein String ist.

#define VAR2  "17"

Jetzt hast du aber keinen konstanten String, sondern du
möchtest das Ergebnis einer Berechnung in einen String
gefasst haben. Und hier hast du dein Problem: Ich denke
nicht dass du das so hinkriegst. Begründung: Konstante
Ausdrücke ausrechnen ist Sache des Compilers. Ersetzungen
vorzunehmen ist Sache des Präprozessors. Der Präprozessor
läuft vor dem Compiler. Nur: Wie soll der Präprozessor einen
konstanten Ausdruck einsetzen, den der Compiler erst viel
später berechnet?

Das wird wohl auf eine 2.te Funktion hinauslaufen, die
einen int als Argument nimmt, diesen int zb mittels itoa
in einen string umwandelt und mit diesem String dann function()
aufruft.

#define VAR1 100
#define VAR2 VAR1 / 50

void foo( int Tmp )
{
  char Buffer[10];
  itoa( Tmp, Buffer, 10 );
  function( Buffer );
}

int main()
{
  foo( VAR2 );
}

von Lutz (Gast)


Lesenswert?

Danke,

wie schaut es den z.B. mit
#define UART_BAUD_SELECT(baudRate,xtalCpu) 
((xtalCpu)/((baudRate)*16l)-1)
zum berechnen von UBRR aus.

Wird da dann der konkrete Wert reingesetzt oder auch nur die ganze 
Formel mit gefüllten Werten? Wenn die Formel da reingesetzt wird währe 
es doch irgendwie sinnlos.

von johnny.m (Gast)


Lesenswert?

Es wird zunächst immer nur der Text eingesetzt. Der Compiler selbst 
berechnet aber konstante Werte, die zu seiner Laufzeit bekannt sind, 
beim Compilieren. Im Assembler-Code steht dann hinterher tatsächlich nur 
noch ein Zahlenwert (vorausgesetzt, alle Werte sind dem Compiler bereits 
bekannt).

von Karl H. (kbuchegg)


Lesenswert?

Lutz wrote:
> Danke,
>
> wie schaut es den z.B. mit
> #define UART_BAUD_SELECT(baudRate,xtalCpu)
> ((xtalCpu)/((baudRate)*16l)-1)
> zum berechnen von UBRR aus.
>
> Wird da dann der konkrete Wert reingesetzt oder auch nur die ganze
> Formel mit gefüllten Werten? Wenn die Formel da reingesetzt wird währe
> es doch irgendwie sinnlos.


Wieso soll das sinnlos sein.

Du machst dir eine falsche Vorstellung davon, was #define
bzw. der Präprozessor eigentlich macht. Der macht nur
eine Textersetzung. Das ist so wie wenn du in deinem Editor
Suchen/Ersetzen benutzt (nur das der Präprozessor noch
mit Argumenten hantieren kann).

#define UART_BAUD_SELECT .....

bedeutet für den Präprozessor lediglich, dass er im Programm-
text überall wo UART_BAUD_SELECT steht, dieses UART_BAUD_SELECT
durch ..... ersetzt. An der Quelle muss dabei das
UART_BAUD_SELECT ein einzelnes Wort sein (UART_BAUD_SELECT2
lässt er also in Ruhe) und alles was in " oder ' eingeschlossen
ist, lässt der Präprozessor ebenfalls in Ruhe.

Mehr macht das nicht.

Daher ersetzt der Präprozessor in
int main()
{
  UART_BAUD_SELECT( 8000000, 9600 );

das UART_BAUD_SELECT durch die definierte Formel, wobei
er dir als Zuckerl noch die Zahlenwerte in die Formel
einsetzt. Der Compiler, der sich danach den dadurch
bearbeiteten Text vornimmt, kriegt zu Gesicht:

int main()
{
  ((8000000)/((9600)*16l)-1);

und da das alles Konstante sind, rechnet der Compiler
(nicht der Präprozessor!) diesen Ausdruck aus und ersetzt
ihn durch:

int main()
{
  51;


Der Präprozessor ist nichts anderes als ein Texteditor, der
perverserweise seine Kommandos aus dem Text entnimmt den
er bearbeitet.

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.