#define als String "umdefinieren"

Gast #779219
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.
#779239
Lesenswert?
• ▲
▼
Dirk wrote:
> Gibt´s da ne Möglichkeit?

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

4
#define TEST   17
5

6
int main()
7
{
8
  printf( "%s", XSTR(TEST) );
9
}

Der Umweg über ein Zwischenmakro ist notwendig, damit die
Makroauswertung korrekt abläuft.
#779244
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
1
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!
Gast #779357
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.
#779378
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 ...
Moderator Persönliche Seite #779432
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”.
#779470
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.
Moderator Persönliche Seite #779542
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:
1
% cat foo.c
2
char foo[4] = "Hello";
3
% cc -Os -Wall -Wextra -c foo.c
4
foo.c:1: warning: initializer-string for array of chars is too long

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 18 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.