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.
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.
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!
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.
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 ...
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”.
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.
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 |
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.