mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Frage zu #define


Autor: Lutz (Gast)
Datum:

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

Autor: johnny.m (Gast)
Datum:

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

Autor: Rolf Magnus (Gast)
Datum:

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

Autor: johnny.m (Gast)
Datum:

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

Autor: johnny.m (Gast)
Datum:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

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

Autor: Lutz (Gast)
Datum:

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

Autor: johnny.m (Gast)
Datum:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

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

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]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [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.