mikrocontroller.net

Forum: Compiler & IDEs #define als String "umdefinieren"


Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich würde gerne wissen, ob es eine Möglichkeit gibt, ein define auf zwei 
Arten zu benutzen:

#define ZAHL 123

Das brauche ich irgendwo im Code in folgender Form:

int n = ZAHL;
bla...

Aber ich möchte auch einen String (im ROM) damit initialisiert haben:

char ROMCONST asN[3] = "123";

So funktioniert´s nicht, klar:

char ROMCONST asN[3] = "ZAHL";

Wie mach ich dem Compiler klar, daß er für ZAHL in den Hochkommas "123" 
(als String!) einsetzen soll?
Gibt´s da ne Möglichkeit?

Gruß, Dirk.

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

Bewertung
0 lesenswert
nicht lesenswert
Dirk wrote:
> Gibt´s da ne Möglichkeit?

Ja gibt es.
Du brauchst dazu das 'Stringize' #-Token des Präprozessors.
#define STR(x)   #x
#define XSTR(x)  STR(x)

#define TEST   17

int main()
{
  printf( "%s", XSTR(TEST) );
}

Der Umweg über ein Zwischenmakro ist notwendig, damit die
Makroauswertung korrekt abläuft.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Verstehe noch nicht ganz, was Du wirklich willst, aber von den beiden 
Varianten...
> char ROMCONST asN[3] = "123";
>
> So funktioniert´s nicht, klar:
>
> char ROMCONST asN[3] = "ZAHL";
funktioniert keine . "123" sind in C 4 Zeichen, und die passen nicht 
in ein Array mit 3 Elementen rein, von "ZAHL" (5 Zeichen) mal ganz zu 
schweigen. Meist ist es überflüssig, bei einem Array, das explizit 
initialisiert wird, die Breite anzugeben.

Aber wenn ich das korrekt verstehe, dann macht die erste Variante (wenn 
Du die 3 in den eckigen Klammern weglässt) genau das, was Du willst. 
Nach
char asN[] = "123";
steht in asN[0] eine '1' (0x31), in asN[1] eine '2' (0x32), in asN[2] 
eine '3' (0x33) und in asN[3] eine '\0' (0x00).

EDIT:
Oder wolltest Du doch was anderes? Wenn ja, dann liegt Karl Heinz 
möglicherweise richtig...

NOCH EIN EDIT:
Ich glaub, so langsam fällt der Groschen... Aber wie gesagt und 
unabhängig davon: Achte auf den Nullterminator!

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank euch beiden.

Genau das, was Karl Heinz erläutert hat, hab ich gesucht...
Ich hab den Operator zwar schon gefunden gehabt 
(http://www.tfh-berlin.de/~kempfer/skript_c/Kap12.html), aber ich bin 
natürlich nicht auf die Idee gekommen, das nochmal zu "makrofizieren" ;)

@Johannes: Ja, sorry, das hätte ich sagen sollen: Die Nullterminierung 
will/brauch ich eben nicht, weil ich noch eine zweite Konstante habe, 
die den Platz im Array entsprechend reserviert (wird noch anderswo für 
ein Objekt-Verzeichnis benötigt, deswegen kann ich das Array nicht 
einfach "so" initialisieren...)


Gruß, Dirk.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dirk wrote:
> @Johannes: Ja, sorry, das hätte ich sagen sollen: Die Nullterminierung
> will/brauch ich eben nicht, weil ich noch eine zweite Konstante habe,
> die den Platz im Array entsprechend reserviert (wird noch anderswo für
> ein Objekt-Verzeichnis benötigt, deswegen kann ich das Array nicht
> einfach "so" initialisieren...)
Ob Du die brauchst oder nicht, denk daran, dass ein Ausdruck in "" immer 
nullterminiert ist, und dass der Ausdruck auch in den Speicher 
geschrieben wird, ohne Rücksicht auf Verluste. Wenn hinter dem letzten 
'reservierten' Array-Element schon was anderes steht, dann Peng ...

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johannes M. wrote:

> Ob Du die brauchst oder nicht, denk daran, dass ein Ausdruck in "" immer
> nullterminiert ist,

Jein.

> und dass der Ausdruck auch in den Speicher
> geschrieben wird, ohne Rücksicht auf Verluste.

Nein.

6.7.8 Initialization, Absatz 14:

“An array of character type may be initialized by a character string
literal, optionally enclosed in braces. Successive characters of the
character string literal (including the terminating null character if
there is room or if the array is of unknown size) initialize the
elements of the array.”

Man beachte das “if there is room”.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch wrote:
> 6.7.8 Initialization, Absatz 14:
>
> “An array of character type may be initialized by a character string
> literal, optionally enclosed in braces. Successive characters of the
> character string literal (including the terminating null character if
> there is room or if the array is of unknown size) initialize the
> elements of the array.”
>
> Man beachte das “if there is room”.
Hmmm, bei der Initialisierung kann also tatsächlich nix kollidieren? 
Bedeutet also, dass, wenn die Array-Größe explizit angegeben wird, diese 
Angabe (zumindest bei einer Initialisierung) das mächtigere Argument 
ist? OK, und bei der Initialisierung besteht auch noch die Möglichkeit, 
sich den Speicher nach Bedarf zurechtzubiegen, da Compiler und Co. ja 
sehen, was da passiert...

Aber gilt das nur für den Nullterminator? Wenn andere Zeichen über die 
Array-Grenzen hinaus geschrieben werden sollen, müsste es ja mindestens 
ne Warnung geben.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johannes M. wrote:

> Hmmm, bei der Initialisierung kann also tatsächlich nix kollidieren?

Ja, schließlich hat der Compiler ja eine explizite Anweisung dazu
erhalten, wie groß das Array werden soll.

> Aber gilt das nur für den Nullterminator?

Mehr ist zumindest erstmal vom Standard nicht abgedeckt.

> Wenn andere Zeichen über die
> Array-Grenzen hinaus geschrieben werden sollen, müsste es ja mindestens
> ne Warnung geben.

Würde ich auch erwarten.  Test:
% cat foo.c
char foo[4] = "Hello";
% cc -Os -Wall -Wextra -c foo.c
foo.c:1: warning: initializer-string for array of chars is too long

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Jörg Wunsch:
Aha. Danke vielmals. Wieder was gelernt.

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.