Hvordan klargjøre en struct i samsvar med programmeringsspråket C standarder

stemmer
361

Jeg ønsker å klargjøre en struct element, delt i erklæring og initialisering. Dette er hva jeg har:

typedef struct MY_TYPE {
  boolean flag;
  short int value;
  double stuff;
} MY_TYPE;

void function(void) {
  MY_TYPE a;
  ...
  a = { true, 15, 0.123 }
}

Er dette måten å erklære og klargjøre en lokal variabel av MY_TYPEi samsvar med programmeringsspråket C standarder (C89, C90, C99, C11, etc.)? Eller er det noe bedre eller minst jobbe?

Oppdater Jeg endte opp med å ha en statisk initialisering element der jeg satt hver underelement i henhold til mine behov.

Publisert på 01/12/2008 klokken 13:13
kilden bruker
På andre språk...                            


14 svar

stemmer
603

I (ANSI) C99, kan du bruke en utpekt initializer å klargjøre en struktur:

MY_TYPE a = { .flag = true, .value = 123, .stuff = 0.456 };

Edit: Andre medlemmer er initialisert som null: "Utelatte felt medlemmer er implisitt initialisert det samme som objekter som har statisk lagring varighet." ( Https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html )

Svarte 01/12/2008 kl. 13:39
kilden bruker

stemmer
164

Du kan gjøre det med en forbindelse bokstavelig . Ifølge den siden, det fungerer i C99 (som også teller som ANSI C ).

MY_TYPE a;

a = (MY_TYPE) { .flag = true, .value = 123, .stuff = 0.456 };
...
a = (MY_TYPE) { .value = 234, .stuff = 1.234, .flag = false };

Betegnelsene i initializers er valgfritt; du kan også skrive:

a = (MY_TYPE) { true,  123, 0.456 };
...
a = (MY_TYPE) { false, 234, 1.234 };
Svarte 01/12/2008 kl. 13:28
kilden bruker

stemmer
82

Jeg ser du allerede har fått svar om ANSI C 99, så jeg skal kaste et bein om ANSI C 89. ANSI C 89 gjør det mulig å klargjøre en struct på denne måten:

typedef struct Item {
    int a;
    float b;
    char* name;
} Item;

int main(void) {
    Item item = { 5, 2.2, "George" };
    return 0;
}

En viktig ting å huske, i det øyeblikket du initial enda ett objekt / variabel i struct, alle sine andre variabler blir initialisert til standardverdi.

Hvis du ikke initial verdiene i din struct, vil alle variabler inneholde "søppel verdier".

Lykke til!

Svarte 09/06/2013 kl. 03:51
kilden bruker

stemmer
35

a = (MYTYPE){ true, 15, 0.123 };

ville gjøre det bra i C99

Svarte 01/12/2008 kl. 13:27
kilden bruker

stemmer
17

Du har nesten fått det ...

MY_TYPE a = { true,15,0.123 };

Rask søk på 'struct initial c' viser meg dette

Svarte 01/12/2008 kl. 13:21
kilden bruker

stemmer
12

som Ron Nuni sa:

typedef struct Item {
    int a;
    float b;
    char* name;
} Item;

int main(void) {
    Item item = {5, 2.2, "George"};
    return 0;
}

En viktig ting å huske på: i det øyeblikket du initial enda ett objekt / variabel i struct, alle sine andre variabler blir initialisert til standardverdi.

Hvis du ikke initialisere verdiene i struct (dvs. hvis du bare erklære at variabel), alle variable.membersvil inneholde "søppel verdier", bare hvis erklæringen er lokale!

Dersom erklæringen er global eller statisk (som i dette tilfellet), alle initialisert variable.membersvil bli initialisert automatisk til:

  • 0 for heltall og flytepunkt
  • '\0'for char(selvfølgelig dette er akkurat det samme som 0, og charer et heltall type)
  • NULL for pekere.
Svarte 04/09/2013 kl. 09:37
kilden bruker

stemmer
11

C programmeringsspråket standard ISO / IEC 9899: 1999 (vanligvis kjent som C99) gjør det mulig å bruke en utpekt initializer for å initial medlemmer av en struktur eller union som følger:

MY_TYPE a = { .stuff = 0.456, .flag = true, .value = 123 };

Det er definert i paragraph 7§ 6.7.8 Initializationav ISO / IEC 9899: 1999-standarden, som:

Hvis en benevnelse har form
. identifikatoren
da det aktuelle objektet (definert nedenfor), skal ha struktur eller union type og en identifikator skal være navnet på et medlem av denne typen.

Legg merke til at paragraph 9den samme seksjonen står det at:

Unntatt der annet er uttrykkelig nevnt, i forbindelse med denne pkt navngitte medlemmer av gjenstander av struktur og union typen deltar ikke i initialisering. Unnamed medlemmer av struktur objekter har ubestemmelige verdi selv etter initialisering.

I GNU GCC implementering imidlertid utelatt medlemmer er initialisert som null eller null-lignende type passende verdi. Som nevnt i avsnitt 6.27 Eget Initializers av GNU GCC dokumentasjon:

Utelatte felt medlemmer er implisitt initialisert det samme som objekter som har statisk lagring varighet.

Microsoft Visual C ++ kompilator bør støtte utpekt initializers siden versjon 2013 i henhold til offisielle blogginnlegg C ++ Conformance Roadmap . Avsnitt Initializing unions and structsav Initializers artikkelen på MSDN Visual Studio dokumentasjon tyder på at navngitte medlemmer initialisert til null-lignende passende verdier på samme måte som GNU GCC.

New ISO / IEC 9899: 2011 standard (kjent som C11) som hadde avløst ISO / IEC 9899: 1999 beholder utpekt initializers etter § 6.7.9 Initialization. Den beholder også paragraph 9uendret.

Svarte 08/06/2016 kl. 11:43
kilden bruker

stemmer
4
void function(void) {
  MY_TYPE a;
  a.flag = true;
  a.value = 15;
  a.stuff = 0.123;
}
Svarte 01/12/2008 kl. 13:19
kilden bruker

stemmer
2

Jeg fant en annen måte å initial structs.

Struct:

typedef struct test {
    int num;
    char* str;
} test;

initialisering:

test tt = {
    num: 42,
    str: "nice"
};

Per GCC dokumentasjon, er denne syntaksen foreldet siden GCC 2.5 .

Svarte 04/12/2015 kl. 03:15
kilden bruker

stemmer
2

Dersom MS ikke har oppdatert til C99, MY_TYPE en = {sann, 15,0.123};

Svarte 20/04/2014 kl. 19:39
kilden bruker

stemmer
1

Jeg liker ikke noen av disse svarene, så jeg laget min egen. Jeg vet ikke om dette er ANSI C eller ikke, det er bare GCC 4.2.1 i sin standardmodus. Jeg kan aldri huske bracketing så jeg begynner med en undergruppe av mine data og kjemper med kompilatoren feilmeldinger før den slår opp. Lesbarhet er min første prioritet.

    // in a header:
    typedef unsigned char uchar;

    struct fields {
      uchar num;
      uchar lbl[35];
    };

    // in an actual c file (I have 2 in this case)
    struct fields labels[] = {
      {0,"Package"},
      {1,"Version"},
      {2,"Apport"},
      {3,"Architecture"},
      {4,"Bugs"},
      {5,"Description-md5"},
      {6,"Essential"},
      {7,"Filename"},
      {8,"Ghc-Package"},
      {9,"Gstreamer-Version"},
      {10,"Homepage"},
      {11,"Installed-Size"},
      {12,"MD5sum"},
      {13,"Maintainer"},
      {14,"Modaliases"},
      {15,"Multi-Arch"},
      {16,"Npp-Description"},
      {17,"Npp-File"},
      {18,"Npp-Name"},
      {19,"Origin"}
    };

Dataene kan starte livet som en tabulatordelt fil du søke-erstatt å massere inn i noe annet. Ja, dette er Debian ting. Slik at en utenfor par av {} (som angir matrisen), og deretter et annet par til hver konstruere inne. Med komma mellom. Å sette ting i en header er strengt tatt ikke nødvendig, men jeg har ca 50 elementer i min struct så jeg vil ha dem i en egen fil, både for å holde rotet ut av min kode og slik at det er lettere å erstatte.

Svarte 12/05/2016 kl. 17:14
kilden bruker

stemmer
0

Jeg har vært på utkikk etter en fin måte å initial min struct, og jeg er nødt til å bruke under (C99). Dette lar meg initial enten en enkelt struktur eller en rekke konstruksjoner på samme måte som vanlige typer.

typedef struct {
    char *str;
    size_t len;
    jsmntok_t *tok;
    int tsz;
} jsmn_ts;

#define jsmn_ts_default (jsmn_ts){NULL, 0, NULL, 0}

Dette kan brukes i koden som:

jsmn_ts mydata = jsmn_ts_default; /* initialization of a single struct */

jsmn_ts myarray[10] = {jsmn_ts_default, jsmn_ts_default}; /* initialization of
                                                    first 2 structs in the array */
Svarte 02/12/2018 kl. 17:46
kilden bruker

stemmer
0

Jeg har lest Microsoft Visual Studio 2015 Dokumentasjon for Initial Aggregate Typer ennå, alle former for initialisering med {...}er forklart der, men initialisering med dot, kalt '' betegnelse '' er ikke nevnt der. Det fungerer ikke også.

Den C99 standard kapittel 6.7.8 Initialisering forklarer muligheten for betegnelser, men i mitt sinn er det egentlig ikke klar for komplekse structs. Den C99 standard som pdf .

I mitt sinn, kan det være bedre å

  1. Bruk = {0};-initialization for alle statiske data. Det er mindre innsats for maskinkode.
  2. Bruk makroer for initialisering, for eksempel

    typedef MyStruct_t{ int x, int a, int b; } MyStruct; define INIT_MyStruct(A,B) { 0, A, B}

Makro kan tilpasses, kan dets argumentliste være uavhengig av endret struct innhold. Det er riktig hvis færre elementer bør initialisert. Det er også riktig for nestet struct. 3. En enkel form er: Initial i en subrutine:

void init_MyStruct(MyStruct* thiz, int a, int b) {
  thiz->a = a; thiz->b = b; }

Denne rutinen ser ut som objekt i C. Bruk thizikke thiså kompilere den med C ++ også!

MyStruct data = {0}; //all is zero!
init_MyStruct(&data, 3, 456);
Svarte 12/08/2018 kl. 14:10
kilden bruker

stemmer
0

Struktur i C kan bli erklært og initialisert som dette:

typedef struct book
{
    char title[10];
    char author[10];
    float price;
} book;

int main() {
    book b1={"DS", "Ajay", 250.0};

    printf("%s \t %s \t %f", b1.title, b1.author, b1.price);

    return 0;
}
Svarte 06/09/2017 kl. 18:38
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more