Összetett adattípusok

Ez a közzétett változat, ellenőrizve: 2023. augusztus 5.

A számítástechnikában az összetett típusok olyan adattípusok, amelyek felépíthetők a programozási nyelvekben ismert elemi adattípusokból vagy más összetett típusokból. Az eljárás, amivel az összetett típusok készülnek felépítés vagy kompozíció néven ismert.

Megvalósítás C/C++-ban

szerkesztés

Egy struct a C-ben és a C++-ban jelzi, hogy összetett adatstruktúráról van szó, az adattípust címkézett mezők vagy tagok alkotják. Azért nevezik így, mert a struct kulcsszót kell használni a deklarálásához, ami a structure rövidítése, vagy még pontosabban a felhasználó által meghatározott adatstruktúra rövidítése.

A C++-ban, a struct és a osztály között csak az alapértelmezett hozzáférési szintben van, ami saját – private – az osztályokra és nyilvános – public – a struct-ra.

Meg kell jegyezni, hogy amíg az osztályok és a class kulcsszó teljesen újak a C++-ban, a C programozási nyelvben már ismert a struct típus. A közös használatra való törekvés ellenére a C struct csak egy részhalmaza a C++ struct-jának: virtuálisan minden érvényes C struct érvényes C++ struct, az azonos szemantika miatt.

Egy struct deklaráció a mezők listájából épül fel, amelyek bármilyen típusúak lehetnek. A struct objektum tárolásához szükséges terület a mezők tárolásához szüksége területek összegéből, valamint az igazítások miatti belső kiegészítőkből áll össze, azaz legalább akkora, mint a mezők összes tárolási igényének az összege.

Például:

struct Account {
   int account_number;
   char *first_name;
   char *last_name;
   float balance;
};

meghatároz egy típust, amelyre a struct Account kifejezéssel lehet hivatkozni. Egy változót a struct Account myAccount; leírásával lehet létrehozni, amelynek van egy egész komponense, amit a myAccount.account_number hivatkozásal lehet elérni, és van egy lebegő pontos komponense, amit pedig myAccount.balance módon érhetünk el, hasonlóan igaz ez a first_name és last_name komponensekre. A struktúra, amit myAccount-nak nevezünk, mind a négy értéket tartalmazza, és minden mező egymástól függetlenül változtatható.

Míg a struct account többször történő leírása a kódot nehézkessé teszi, addig a C-ben használt typedef utasítás egy sokkal kényelmesebb szinonimája a struct-nak. Például:

typedef struct Account_ {
   int    account_number;
   char   *first_name;
   char   *last_name;
   float  balance;
} Account;

A C++ kódban a typedef használata nem szükséges, mivel a típust meghatározza a struct használata, innen már a szabályos névtér részévé vált. Ezért az előző példát C++-ban a következő képen kell írni:

struct Account {
   int    account_number;
   char   *first_name;
   char   *last_name;
   float  balance;
};

Egy másik példa: egy lebegőpontos adatokból álló, háromdimenziós vektor létrehozható a következők leírásával:

struct Vector {
  float x;
  float y;
  float z;
};

Egy változót nevezzünk el velocity-nek és összekapcsolva a Vector-ra előáll a Vector velocity; változó. A velocity tagjait a már ismert pont jelöléssel lehet elérni. Például, a velocity.x = 5; az x velocity komponensnek 5-öt ad értékül.

Hasonlóan, egy a color struktúra létrehozható a következők szerint:

struct Color {
  int red;
  int green;
  int blue;
};

3D grafikáknál, nyilván kell tartani a csúcsok helyzetét és színét is egyidejűleg. Egy lehetséges megoldás erre, ha a létrehozunk egy összetett típust, a Csúcs-ot, felhasználva a már létrehozott Vector és Color összetett típusokat:

struct Csúcs {
  Vector position;
  Color color;
};

Az előzőekben leírt módon létrehozhatunk egy Csúcs típusú változót is Csúcs cs; módon. Értékadás a cs változónál a következők szerint lehetséges:

  cs.position.x = 0.0;
  cs.position.y = 1.5;
  cs.position.z = 0.0;
  cs.color.red = 128;
  cs.color.green = 0;
  cs.color.blue = 255;

A struct használatának elsődleges célja komplex adattípusok létrehozása, felépítése, de néha a szabványos C-konvenciók kijátszása miatt kell létrehozni elemi altípusokat. Például az internetprotokollok számítanak arra a tényre, hogy a C-fordítók belső igazításokat használnak a struktúra elemei között, így a következő kód jól fog működni:

struct ifoo_old_stub {
   long x, y;
};
struct ifoo_version_42 {
   long x, y, z;
   char *name;
   long a, b, c;
};
void operate_on_ifoo(struct ifoo_old_stub *);
struct ifoo_version_42 s;
. . .
operate_on_ifoo(&s);