Wat is Struct (C-structuur)?

Een mechanisme in C dat meerdere waarden (members), mogelijk van verschillende typen, samenvoegt tot één type. Een struct wordt gedefinieerd zoals in struct sensor { int id; float value; }; de members van een variabele s worden gebruikt als s.id, en via een pointer p naar een struct als p->id. De members liggen in de volgorde van declaratie in het geheugen, maar voor de uitlijning kan er opvulling (padding) tussen worden ingevoegd, zodat het geheel groter kan zijn dan de som van de groottes van de members.

Japanse benaming: 構造体

“Struct (C-structuur)” komt voor in 11 oefenvragen uit 7 onderwerpen, bijv. Instructieset en assembly, Basis van programmeren in C, Geheugenhiërarchie en prestaties.

Vakgebied: Basis van programmeren in C

Definitie en gebruik

Met de definitie struct point { int x; int y; }; wordt een variabele gemaakt zoals in struct point p = {1, 2}; en wordt elke member gebruikt als p.x of p.y. Met typedef een alias geven, zoals in typedef struct { … } Point;, maakt de declaratie Point p; mogelijk zonder struct te schrijven. Structs kunnen met = in hun geheel worden toegekend, als argument aan functies worden doorgegeven en als retourwaarde worden teruggegeven, maar grote structs worden in het algemeen via een pointer doorgegeven.

Indeling in het geheugen

Members worden in de volgorde van declaratie geplaatst, van lagere adressen naar hogere. Vóór een type dat uitgelijnd moet worden, zoals een int van 4 bytes op een grens van 4 bytes, wordt opvulling (padding) ingevoegd, en de grootte van de hele struct wordt naar boven afgerond op een veelvoud van de strengste uitlijning. Een struct met char, int en char in die volgorde neemt daardoor in een gebruikelijke omgeving met een int van 4 bytes 12 bytes in, en door de int vooraan te zetten, daalt dat tot 8 bytes.

Aandachtspunten in embedded systemen en communicatie

De indeling van registers van randapparaten met een struct weergeven is gebruikelijk, maar de padding en de bitvolgorde van bitvelden mogen per implementatie verschillen, dus wie ze zonder controle gebruikt, kan verschoven adressen krijgen. Wie communicatiegegevens of een bestandsformaat behandelt als de ruwe geheugeninhoud van een struct, verliest door verschillen in padding en endianness de compatibiliteit met andere omgevingen, dus worden de gegevens vaak byte voor byte samengesteld.

Nu oefenen: vragen over Struct (C-structuur)

Waarop moet worden gelet wanneer in C met een struct met bitvelden de registers van een randschakeling worden voorgesteld?

  1. ABitvelden maken het programma altijd twee keer zo snel
  2. BDe volgorde van de bits in bitvelden mag per compiler verschillen, dus met een andere compiler kunnen onbedoeld andere bits worden bewerkt
  3. CBitvelden kunnen geen waarden van 8 bit of meer weergeven
Antwoord en toelichting tonen

Antwoord: B. De volgorde van de bits in bitvelden mag per compiler verschillen, dus met een andere compiler kunnen onbedoeld andere bits worden bewerkt

Bitvelden zijn leesbaar te schrijven, maar de C-norm laat het aan de implementatie of bits in een struct van hoog naar laag of van laag naar hoog worden geplaatst, hoe velden die een grens overschrijden worden behandeld en welke toegangsbreedte wordt gebruikt. Wat bij de ene compiler goed werkt, kan daarom bij een andere compiler of CPU andere bits lezen of schrijven. De headers van microcontrollerfabrikanten zijn vaak geschreven met maskers en verschuivingen.

Veelgestelde vragen

Wat is het verschil tussen een struct en een array?

Een array zet elementen van hetzelfde type achter elkaar, die met een index worden gekozen. Een struct voegt members van mogelijk verschillende typen samen, die met hun naam worden gekozen. De twee worden vaak gecombineerd, zoals in een array van structs of een struct met een array als member.

Waarom moet de grootte van een struct met sizeof worden gecontroleerd?

Hoeveel padding er tussen en na de members komt, hangt af van de groottes van de typen en de regels voor uitlijning (de ABI), dus het optellen van de groottes van de members geeft niet de juiste grootte. Bij het reserveren van een struct met malloc of het wegschrijven naar een bestand wordt de werkelijke grootte bepaald met sizeof(struct naam).

“Struct (C-structuur)” in de toelichting

Vragen met “Struct (C-structuur)” (11)

  1. Waarom wordt een bewerking die alleen de x-coördinaten optelt vaak sneller wanneer een array van structs wordt omgeschreven tot een structuur van arrays (elke component in een eigen array)?
  2. Waarop moet worden gelet wanneer in C met een struct met bitvelden de registers van een randschakeling worden voorgesteld?
  3. Welke werking van de RISC-V-instructie „lw t0, 8(sp)” is juist?
  4. Waar worden in de standaard RISC-V-aanroepconventie het 9e en 10e argument doorgegeven bij het aanroepen van een functie met 10 gehele-getalargumenten?
  5. Wat kan er gebeuren als het adres van een lw-instructie die 4 bytes leest in RISC-V geen veelvoud van 4 is (niet uitgelijnd)?
  6. Welke omschrijving van de ABI (application binary interface) is juist?
  7. Wanneer wordt bij gedeelde bibliotheken op Linux het versienummer van de soname, zoals de „.1” in libfoo.so.1, in het algemeen verhoogd?
  8. Bij een array van tellers per thread zoals 'long cnt[8];' treedt false sharing op. Welke maatregel is het meest geschikt?
  9. Welke rangschikking is voordelig voor coalesced geheugentoegang wanneer data van deeltjes met posities x, y en z op een GPU wordt verwerkt?
  10. Neem een gebruikelijke omgeving aan waarin char 1 byte en int 4 bytes is, en int op adressen wordt geplaatst die een veelvoud van 4 zijn. Wat is de uitvoer als de bovenstaande code wordt uitgevoerd?
  11. Het headerbestand sensor.h is geschreven zoals hierboven. Wat is het doel van de drie regels #ifndef, #define en #endif?

Verwante termen

Array SIMD Variabele Stack (stapelgeheugen) Aanroepconventie (calling convention) Pointer Uitlijning en padding (alignment and padding) Vectorisatie Bitveld (bit-field) Argument

Naar de woordenlijst