Literaler String-Initialisierer für ein Zeichen-Array

Lesezeit: 4 Minuten

Benutzer-Avatar
Tim

In den folgenden Regeln für den Fall, dass ein Array zu einem Zeiger zerfällt:

Ein lvalue [see question 2.5] vom Typ array-of-T, das in einem Ausdruck erscheint, zerfällt (mit drei Ausnahmen) in einen Zeiger auf sein erstes Element; der Typ des resultierenden Zeigers ist Zeiger auf T.

(Die Ausnahmen sind, wenn das Array der Operand eines sizeof- oder &-Operators oder ein Literal-String-Initialisierer für ein Zeichen-Array ist.)

Wie ist der Fall zu verstehen, wenn das Array “literaler String-Initialisierer für ein Zeichen-Array” ist? Bitte ein Beispiel.

Vielen Dank!

  • Verwandte: Ausnahme von Array, das nicht in einen Zeiger zerfällt?

    – legends2k

    9. Juli 2014 um 8:26 Uhr

Benutzer-Avatar
Prasun Saurav

Die drei Ausnahmen, bei denen ein Array nicht in einen Zeiger zerfällt, sind die folgenden:

Ausnahme 1. — Wenn das Array der Operand von ist sizeof.

int main()
{
   int a[10];
   printf("%zu", sizeof(a)); /* prints 10 * sizeof(int) */

   int* p = a;
   printf("%zu", sizeof(p)); /* prints sizeof(int*) */
}

Ausnahme 2. — Wenn das Array der Operand von ist & Operator.

int main()
{
    int a[10];
    printf("%p", (void*)(&a)); /* prints the array's address */

    int* p = a;
    printf("%p", (void*)(&p)); /*prints the pointer's address */
}

Ausnahme 3. — Wenn das Array mit einer Literalzeichenfolge initialisiert wird.

int main()
{
    char a[] = "Hello world"; /* the literal string is copied into a local array which is destroyed after that array goes out of scope */

    char* p = "Hello world"; /* the literal string is copied in the read-only section of memory (any attempt to modify it is an undefined behavior) */
}

  • Ihre Antwort hat mir vor all den Änderungen viel besser gefallen. Kurz und beantwortet die Frage. Jetzt beantwortet es viele Fragen, die nicht einmal gestellt werden. 🙂

    – Alok Singhal

    10. Januar 2010 um 4:58 Uhr

  • Danke Prason. Einige Fragen: (1) in Ausnahme 3, also hier lvalue “Hello world” ist der String-Literal-Initialisierer des char-Arrays “a”, und daher zerfällt “Hello world” nicht zu einem Zeiger? (2) in Ausnahme 2, ist “&a” identisch mit der Adresse des ersten Elements des Arrays “a”?

    – Tim

    10. Januar 2010 um 5:03 Uhr

  • Die Antwort ist (1) ja, (2) nein. Für (2) werden auf den meisten Computern, wenn Sie die Werte drucken, dieselben gedruckt (ich kenne keine, bei denen dies nicht der Fall ist). Aber &a zeigt auf das gesamte Array, während &a[0] zeigt auf das erste Element von a. Also, wenn Sie drucken &a + 1 und &a[0] + 1sie werden anders sein, auch wenn &a und &a[0] denselben Wert drucken.

    – Alok Singhal

    10. Januar 2010 um 5:09 Uhr


  • Ja, der Wert von &a ist derselbe wie der Wert der Adresse des ersten Elements des Arrays ‘a’, aber ihre Typen sind unterschiedlich.

    – Prasun Saurav

    10. Januar 2010 um 5:11 Uhr

  • Danke Alok. Ich denke, ein Stirng-Literal ist ein Rvalue und kein Lvalue, da es der Wert eines Speichers im Nur-Lese-Speicher ist, nicht der Speicher selbst, und nicht auf der linken Seite von = erscheinen kann. Wenn ich falsch liege, kann also jedes Literal außer String-Literal auch Lvalue sein? Was bedeutet dann lvalue und was unterscheidet einen lvalue von einem rvalue?

    – Tim

    10. Januar 2010 um 5:18 Uhr

Benutzer-Avatar
Johannes Bode

Übernehmen Sie die Erklärungen

char foo[] = "This is a test";
char *bar  = "This is a test";

In beiden Fällen ist der Typ des Zeichenfolgenliterals “This is a test” ist “Array aus char mit 15 Elementen”. In den meisten Fällen werden Array-Ausdrücke implizit vom Typ “Array aus N-Elementen von T” in “Zeiger auf T” konvertiert, und der Ausdruck ergibt die Adresse des ersten Elements von array In der Deklaration für bargenau das passiert.

In der Erklärung für fooder Ausdruck wird jedoch verwendet, um den Inhalt eines anderen Arrays zu initialisieren, und ist daher nicht in einen Zeigertyp konvertiert; stattdessen die Inhalt des String-Literals kopiert werden foo.

  • +1 für die klare und prägnante Antwort; vielleicht der einzige hier, der zeigt, dass es um die ausnahme geht wörtliche Zeichenfolge und nicht das char-Array, dem es zugewiesen ist (vorausgesetzt, dass beide Zeichen-Arrays sind).

    – legends2k

    9. Juli 2014 um 8:36 Uhr


  • "This is a test" als String-Initialisierer ist eine Anordnung. Als Ausdruck zerfällt er nicht zu einem Zeiger, sondern bleibt ein Array. Exzellent.

    – cdosborn

    21. Juni 2015 um 4:47 Uhr


Benutzer-Avatar
Eli Bendersky

Dies ist ein Literal-String-Initialisierer für ein Zeichen-Array:

char arr[] = "literal string initializer";

Könnte auch sein:

char* str = "literal string initializer";

Definition aus K&R2:

Ein Zeichenfolgenliteral, auch Zeichenfolgenkonstante genannt, ist eine Folge von Zeichen, die von doppelten Anführungszeichen umgeben sind, wie in “…”. Ein String hat den Typ „Array of Characters“ und die Storage-Klasse „Static“ (siehe Abschnitt A.3 unten) und wird mit den gegebenen Zeichen initialisiert. Ob identische Zeichenfolgenliterale verschieden sind, ist implementierungsdefiniert, und das Verhalten eines Programms, das versucht, ein Zeichenfolgenliteral zu ändern, ist undefiniert.

  • Wie Prasoon erwähnt, sind dies nicht dasselbe

    – BlueRaja – Danny Pflughoeft

    10. Januar 2010 um 4:58 Uhr


  • Danke Eli. Was ist also in diesen Beispielen der String-Literal-Initialisierer von was? Und was ist “Ein Lvalue vom Typ Array-of-T”, der nicht in einen Zeiger zerfällt?

    – Tim

    10. Januar 2010 um 5:07 Uhr

Es scheint, als hätten Sie dieses Zitat aus der comp.lang.c-FAQ gezogen (vielleicht eine alte Version oder vielleicht die gedruckte Version; sie stimmt nicht ganz mit dem aktuellen Stand der Online-Version überein):

http://c-faq.com/aryptr/aryptrequiv.html

Der entsprechende Abschnitt enthält Links zu anderen Abschnitten der FAQ, um diese Ausnahmen zu erläutern. In Ihrem Fall sollten Sie Folgendes beachten:

http://c-faq.com/decl/strlitinit.html

1383490cookie-checkLiteraler String-Initialisierer für ein Zeichen-Array

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy