Wie weist man eine C-Struktur inline zu?

Lesezeit: 4 Minuten

Benutzeravatar von mindthief
Gedankendieb

typedef struct {
    int hour;
    int min;
    int sec;
} counter_t;

Und im Code möchte ich Instanzen dieser Struktur initialisieren, ohne jede Mitgliedsvariable explizit zu initialisieren. Das heißt, ich möchte so etwas tun:

counter_t counter;
counter = {10,30,47}; //doesn't work

für 10:30:47

statt

counter.hour = 10;
counter.min = 30;
counter.sec = 47;

Erinnern Sie sich nicht an die Syntax dafür und haben beim Googeln nicht sofort einen Weg gefunden, dies zu tun.

Vielen Dank!

  • Ja, sieht so aus, als ob es funktioniert, wenn ich die Deklaration in derselben Zeile so mache counter_t counter = {10,30,47} jedoch nicht, wenn die Erklärung vor dieser Abtretung erfolgt ist.

    – Gedankendieb

    23. Januar 2011 um 23:52 Uhr

  • @Oli: Warum sollte das funktionieren? Wie geschrieben, das ist eine Zuweisung, keine Initialisierung.

    – etw

    23. Januar 2011 um 23:53 Uhr

  • @sth: Es scheint, dass die Frage geändert wurde …

    – Oliver Charlesworth

    23. Januar 2011 um 23:54 Uhr

  • Wie in Steves Antwort angedeutet, was Sie haben, ist Abtretung statt Initialisierung (wie du schon in der Überschrift gesagt hast). C verwischt diese Linien viel mehr als C++, aber wie Oli auch betont, funktioniert die Initialisierung (sowohl in C als auch in C++) bereits so, wie Sie es erwarten.

    – Fred Nurk

    24. Januar 2011 um 0:47 Uhr

  • @Oli @sth: Ja, ich habe mich gefragt, ob Sie es vielleicht vor der Änderung gesehen haben. Für einen sehr kurzen Zeitraum (ungefähr eine Minute) hatte ich die Arbeitsversion der Erklärung oben, dh counter_t counter = {10,30,47};. Ich habe es geändert, als ich gemerkt habe, dass es tatsächlich funktioniert :). Jedenfalls wollte ich es eigentlich getrennt vom Auftrag deklarieren. @Fred Nurk: Guter Anruf, ich werde den Titel ändern, um “Zuweisung” zu sagen. Vielen Dank!

    – Gedankendieb

    24. Januar 2011 um 1:13 Uhr

Initialisierung:

counter_t c = {10, 30, 47};

Abtretung:

c = (counter_t){10, 30, 48};

Letzteres wird als “zusammengesetztes Literal” bezeichnet.

  • Beachten Sie, dass dies entweder GCC oder C99 erfordert, keinen strikten C89- oder C++-Compiler.

    – Jeremia Willcock

    23. Januar 2011 um 23:48 Uhr

  • @Jeremiah: Guter Punkt, ich habe das C++-Tag nicht bemerkt. Was C89 betrifft, wenn Leute herumlaufen und “C” sagen, wenn sie “C89” meinen, sind sie meiner Meinung nach auf sich allein gestellt 😉

    – Steve Jessop

    23. Januar 2011 um 23:50 Uhr

  • @RBerteig: keine Frage. Ich sage nicht, dass niemand C89 verwenden sollte, ich sage, dass, wenn sie C99 nicht verwenden können, sie nicht einfach sagen sollten, dass das, was sie verwenden, “C” ist, ohne weitere Warnung.

    – Steve Jessop

    24. Januar 2011 um 0:08 Uhr

  • @RBerteig: Nun, halten Sie mich für müde von dem allgemeinen Glauben, dass C89 und C99 dieselbe Sprache sind. Es sind die C89-Leibeigenen, die die zusätzlichen Qualifikationen hinzufügen sollten 😉 Ich sage dies als jemand, der selbst noch 2008 reinen C89-Code geschrieben hat.

    – Steve Jessop

    24. Januar 2011 um 0:16 Uhr


  • @Fred: ist das so einfach? Zum Beispiel, wenn die Plattform nicht mindestens bereitstellt alloca, dann muss Ihr C99-Compiler VLAs dynamisch zuweisen, was Probleme bereitet. Sobald Sie nicht gut mit dem Stack des Ziels spielen, setjmp vielleicht unterhaltsam zu implementieren. Sie könnten sagen: “Nun, machen Sie ein C89-Backend für den Compiler, lassen Sie das alles erledigen”. Ich frage mich, ob ein effizient Backend in C89 für, sagen wir, GCC, ist möglich. Wenn es nicht effizient ist, dann ist es für eingebettete Arbeiten wahrscheinlich tot im Wasser, “kein C99 im Compiler des Anbieters” ist nur eine von mehreren strengen Einschränkungen, die solche Geräte haben …

    – Steve Jessop

    24. Januar 2011 um 0:22 Uhr


Benutzeravatar von MuhsinFatih
Muhsin Fatih

Aus Gründen der Wartbarkeit bevorzuge ich die Listensyntax MIT explizit identifizierten Variablen, wie folgt:

counter_t counter = {.hour = 10, .min = 30, .sec = 47};

oder für die Rückgabe inline zum Beispiel:

return (struct counter_t){.hour = 10, .min = 30, .sec = 47};

Ich kann mir ein Szenario vorstellen, in dem man die Reihenfolge ändert, in der die Variablen deklariert werden, und wenn Sie Ihre Variablen nicht explizit identifizieren, müssten Sie den gesamten Code durchlaufen, um die Reihenfolge der Variablen zu korrigieren. Auf diese Weise ist es sauberer und besser lesbar

  • Ich mag das auch, aber nicht so gut, wenn Sie auch mit einem C++-Compiler kompilieren möchten, da es sich um eine C99-Funktion handelt, die von C++ nicht unterstützt wird. stackoverflow.com/questions/12122234/…

    – Ashley Duncan

    5. Dezember 2017 um 20:27 Uhr


  • Wusste das nicht. Schade aber, es ist so ein nützliches Feature. Der beste Ansatz, den ich in diesem Fall denke, ist die Lösung von Don Doerner: stackoverflow.com/a/14206226/2770195 . Einfach ausgedrückt: Verwenden Sie Klassen mit Variablen und einem einzigen Initialisierer. Scheint keine gute Praxis zu sein, tut aber genau das, was Strukturen tun. Ich werde die Antwort mit Klarstellungen aktualisieren, danke für die Erinnerung

    – MuhsinFatih

    5. Dezember 2017 um 21:29 Uhr

  • Ich bin verwirrt, ich habe gerade ein Beispiel mit der Option -gnu++11 kompiliert: 1drv.ms/i/s!ArNqKg0GFwIE0HVGDPPHvpEgaGrh . Übersehe ich etwas?

    – MuhsinFatih

    5. Dezember 2017 um 21:47 Uhr


  • @AshleyDuncan irgendwelche Ideen?

    – MuhsinFatih

    7. Dezember 2017 um 13:52 Uhr

  • @MuhsinFatih gnu++11 bedeutet, GNU-Erweiterungen zu verwenden

    – MM

    9. Dezember 2017 um 1:31 Uhr

Als Ergänzung zur Antwort von @MuhsinFatih und mit mehr maßgebliche Referenzen.

Wir können C99 verwenden Bezeichner um das Ziel zu erreichen, genau wie das, was @MuhsinFatih vorgeschlagen hat:

counter_t counter = {.hour = 10, .min = 30, .sec = 47};

Die gleiche Regel gilt für Array auch:

int num[5] = { [0]=123, [2]=456, [4]=789 };

printf("%d %d %d %d %d \n",num[0], num[1], num[2], num[3], num[4]);
// Output:
//    123 0 456 0 789 

1414620cookie-checkWie weist man eine C-Struktur inline zu?

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

Privacy policy