Frage

fand ich einige struct Initialisierungscode gestern, dass für eine Schleife warf mich. Hier ein Beispiel:

typedef struct { int first; int second; } TEST_STRUCT;
void testFunc() {
    TEST_STRUCT test = {
        second: 2,
        first:  1
    };
    printf("test.first=%d test.second=%d\n", test.first, test.second);
}

Überraschenderweise (für mich), hier ist der Ausgang:

-> testFunc
test.first=1 test.second=2

Wie Sie sehen können, wird die Struktur richtig initialisiert. Ich war nicht bewusst etikettierten Anweisungen könnte so verwendet werden. Ich habe struct Initialisierung zu tun, mehr andere Möglichkeiten gesehen, aber ich habe keine Beispiele für diese Art von Struktur-Initialisierung auf einen des Online-C FAQs. Ist jemand bewusst, wie / warum das funktioniert?

War es hilfreich?

Lösung

Hier

ist der Abschnitt des gcc Handbuch, das die Syntax der designierten Initialisierer für beide structs erklärt und Arrays:

  

In einer Struktur initializer, geben Sie den Namen eines Feldes zu initialisieren   mit ' .fieldname = ' vor dem Elementwert. Zum Beispiel, angesichts der   folgende Struktur,

 struct point { int x, y; };
     

die folgende Initialisierung

 struct point p = { .y = yvalue, .x = xvalue }; 
     

entspricht

 struct point p = { xvalue, yvalue }; 
     

Eine andere Syntax, die die gleiche Bedeutung hat, überholt, da GCC 2.5, ist ' Feldname: ', wie hier gezeigt:

 struct point p = { y: yvalue, x: xvalue };

Die entsprechende Seite finden Sie finden hier .

Ihr Compiler sollten ähnliche Dokumentation haben.

Andere Tipps

Diese sind weder Etiketten noch bitfields.

Dies ist eine Syntax struct Mitglieder zu initialisieren, um die Tage vor C99 zurückgeht. Es ist nicht genormt, sondern in z.B. gcc.

typedef struct { int y; int x; } POINT;
POINT p = { x: 1, y: 17 };

In C99, Syntax für bestimmte Strukturkomponenten initialisiert wurde zum ersten Mal in einem Standard eingeführt, aber es sieht ein wenig anders:

typedef struct { int y; int x; } POINT;
POINT p = { .x = 1, .y = 17 };

Ja, wie oben erwähnt, sind diese bezeichnet initializers, die Standard-C sind, wenn Sie mit Perioden statt Doppelpunkte wechseln sollte. Und wie Sie beachten Sie, sind die meisten Bücher da draußen noch irgendwo um 1984 in ihrer Syntax stecken und nicht, sie zu erwähnen. Weitere interessante Fakten:

- Wenn bezeichnet initializers verwenden, alles nicht angegeben wird auf Null initialisiert. Dies hilft bei der außergewöhnlich großen Strukturen, z.

typedef struct {
   double a, b, c, d, e;
   char label[100];
} too_many_type;

too_many_type tm = {.a = 1, .e = 2, .b=1.5};
assert(tm.a + tm.b + tm.c + tm.d + tm.e == 4.5);
assert(!strlen(label));

- Sie können aber auch die Verbindung wörtliche Form verwenden Sie dieses Formular auf einer nicht-Initialisierung Linie zu verwenden, z:

.
too_many_type tm2;
tm2 = (too_many_type) {.a = 3, .e=6};

Das sind wirklich tolle Features und wird von jedem C-Compiler unterstützt, die ich mir vorstellen kann, ist, dass es die Norm ist. Es ist eine Schande, dass sie nicht so gut bekannt.

Es ist nicht wirklich „etikettierte Anweisungen“, sondern eine Möglichkeit, Anfangswerte zu den genannten Feldern in der Struktur zu geben.

Gcc gibt eine Warnung über „veraltete Verwendung einer bestimmten Initialisierung mit‚:‘“, und in C99 sollten Sie stattdessen schreiben:

    TEST_STRUCT test = {
        .second = 2,
        .first =  1
    };

Das Syntax wird nicht durch den C-Standard definiert. Abschnitt 6.7.8 Initialization sagt

         designation:
                designator-list =
         designator-list:
                designator
                designator-list designator
         designator:
                [ constant-expression ]
                . identifier

Wenn Ihr Compiler eine Bezeichnung mit einem Doppelpunkt ohne Diagnosemeldung akzeptiert, bedeutet es Compiler ist nicht (oder ist nicht konfiguriert werden) Standards konform ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top