Klammern um das String-Literal in der char-Array-Deklaration gültig? (zB Zeichen s[] = {“Hallo Welt”})

Lesezeit: 4 Minuten

Klammern um das String Literal in der char Array Deklaration gultig zB Zeichen
halex

Durch Zufall habe ich festgestellt, dass die Linie char s[] = {"Hello World"}; ist richtig kompiliert und wird anscheinend gleich behandelt wie char s[] = "Hello World";. Ist nicht der erste ({"Hello World"}) ein Array, das ein Element enthält, das ein Array von char ist, daher sollte die Deklaration für s lauten char *s[]? Tatsächlich, wenn ich es ändere in char *s[] = {"Hello World"}; der Compiler akzeptiert es auch, wie erwartet.

Auf der Suche nach einer Antwort, der einzige Ort, den ich gefunden habe, der dies erwähnt hat, ist Dieses hier aber es gibt kein Zitieren des Standards.

Meine Frage ist also, warum die Linie? char s[] = {"Hello World"}; wird kompiliert, obwohl die linke Seite vom Typ . ist array of char und die rechte Seite ist vom Typ array of array of char?

Nachfolgend ein Arbeitsprogramm:

#include<stdio.h>
int main() {
    char s[] = {"Hello World"};
    printf("%s", s); // Same output if line above is char s[] = "Hello World";
    return 0;
}

Danke für eventuelle Klarstellungen.

PS Mein Compiler ist gcc-4.3.4.

  • Ich habe vor ein paar Monaten eine ähnliche Frage gestellt: stackoverflow.com/questions/8061346/…

    – Antoine

    18. April ’12 um 8:46

1642068964 264 Klammern um das String Literal in der char Array Deklaration gultig zB Zeichen
Christoph

Es ist erlaubt, weil der Standard es so sagt: C99 Abschnitt 6.7.8, §14:

Ein Array vom Zeichentyp kann durch ein Zeichenfolgenliteral initialisiert werden, das optional in geschweifte Klammern eingeschlossen ist. Aufeinanderfolgende Zeichen des Zeichenkettenliterals (einschließlich des abschließenden Nullzeichens, wenn Platz vorhanden ist oder das Array eine unbekannte Größe hat) initialisieren die Elemente des Arrays.

Das bedeutet, dass beides

char s[] = { "Hello World" };

und

char s[] = "Hello World";

sind nichts anderes als syntaktischer Zucker für

char s[] = { 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', 0 };

In einer verwandten Anmerkung (gleicher Abschnitt, §11) erlaubt C auch geschweifte Klammern um skalare Initialisierer wie

int foo = { 42 };

was übrigens gut zur Syntax für zusammengesetzte Literale passt

(int){ 42 }

  • Fast identischer Text ist in C++2003, Abschnitt 8.5.2.

    – Robᵩ

    13. April ’12 um 20:36 Uhr

  • Die Möglichkeit, die überflüssigen geschweiften Klammern um Initialisierer für skalare Objekte zu verwenden, unterstützt auch das Idiom des “universalen Nullinitialisierers” in der Sprache C, wo die = { 0 } kann verwendet werden, um ein Objekt virtuell zu initialisieren beliebig mit Nullen eingeben.

    – AnT

    13. Apr. ’12 um 21:24


  • Im Allgemeinen gruppieren geschweifte Klammern einfach alle darin enthaltenen Anweisungen zu einer einzigen, größeren Anweisung. Deshalb brauchst du nicht { } für eine Zeile if Zweige (oder während, etc). Der Compiler sucht einfach nach dem nächste Aussage nach dem if und führt es bedingt aus. Wenn Sie also zwei Aussagen wünschen, lassen Sie sie einfach als eine erscheinen, indem Sie sie in Locken umschließen.

    – dcow

    14. April ’12 um 4:02


  • @DavidCowden: Das ist falsch. a = (x = 1, y = 2, z = 3); wird setzen a zu 3, nicht 1.

    – Nawaz

    14. April ’12 um 5:41


  • @David Cowden: Die Verwendung von {} im Kontext der Initialisierung hat absolut keinen Bezug zu ihrer Verwendung in der Syntax der zusammengesetzten Anweisung.

    – AnT

    14. April ’12 um 17:24

Klammern um das String Literal in der char Array Deklaration gultig zB Zeichen
Nawaz

Die geschweiften Klammern sind optional und der Ausdruck entspricht nur einem char-Array.

Das kannst du auch schreiben:

 int a = {100}; //ok

Demo: http://ideone.com/z0psd

In der Tat, C++11 verallgemeinert genau diese Syntax, um sowohl Nicht-Arrays als auch Arrays einheitlich zu initialisieren. Also in C++11, Sie können diese haben:

int a{}; //a is initialized to zero, and it is NOT an array

int b[]{1,2,3,4}; //b is an array of size 4 containing elements 1,2,3,4

int c[10]{}; //all 10 elements are initialized to zero

int *d{}; //pointer initialized to nullptr

std::vector<int> v{1,2,3,4,5}; //vector is initialized uniformly as well.

Jede Variable in (int, char, etc.) ist nur ein Array der Länge 1.

char s = {0};

funktioniert auch.

[…] Tatsächlich, wenn ich es in char *s ändere[] = {“Hallo Welt”}; der Compiler akzeptiert es auch, wie erwartet

Der Compiler akzeptiert dies, da Sie tatsächlich ein 2D-Array von Elementen mit undefinierter Größe erstellen, in dem Sie nur ein Element gespeichert haben, das "Hello World" Schnur. Etwas wie das:

char* s[] = {"Hello world", "foo", "baa" ...};

Du kannst das nicht weglassen bracets in diesem Fall.

1642068964 503 Klammern um das String Literal in der char Array Deklaration gultig zB Zeichen
eerorika

Dies ist auch vom C++-Standard erlaubt, Zitat:

[dcl.init.string] §1

Ein Array mit schmalen Zeichentypen ([basic.fundamental]), char16_t Array, char32_t Array oder wchar_t Array können durch ein schmales String-Literal, char16_t String-Literal, char32_t String-Literal bzw. breites String-Literal initialisiert werden. oder durch ein entsprechend typisiertes Zeichenfolgenliteral in geschweifte Klammern eingeschlossen ([lex.string]). [snip]

.

484860cookie-checkKlammern um das String-Literal in der char-Array-Deklaration gültig? (zB Zeichen s[] = {“Hallo Welt”})

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

Privacy policy