Strukts

Ein Strukt ist ein zusammengesetztes Objekt, welches Variablen, Pointer oder weitere Strukts beinhaltet. Für Engine-Objekte gibt es einige vordefinierte Strukt-Typen wie ENTITY, VIEW, PANEL, TEXT, oder MATERIAL. Sie sind in der Datei include\atypes.h definiert. Auf die Teile eines Strukts wird individuell zugegriffen, indem der Strukt-Name, gefolgt von einem '.' und dem Namen des entsprechenden Teils verwendet wird. Beispiel:

myentity.alpha = 33;
mypanel.red = 255;
mymaterial.emissive_blue = 100;

 LC  In lite-C können Sie außerdem individuelle Strukts definieren (der Rest dieses Kapitels betrifft also nur lite-C). Beispiel für ein User-definiertes Strukt:

typedef struct { 
  int x; 
  int y; 
  char name[10];
} SPOT;  // defines a struct type named "SPOT"
...
SPOT myspot; // creates an uninitalized SPOT struct named "myspot"
SPOT* pspot; // creates an uninitalized pointer to a SPOT struct ... myspot.x = 10; myspot.name = "test!";

Ein Strukt kann Pointer auf früher definierte Strukts beinhalten und sogar Pointer auf sich selbst, jedoch keine Pointer zu später definierten Strukts:

typedef struct SPOT { 
  int x; 
  int y; 
  char name[10];
  struct SPOT* next; // pointer to a SPOT struct
} SPOT;  // defines a struct type named "SPOT"

Anders als Variablen können Strukts nicht beim Generieren initialisiert werden, globale Strukt-Pointer aber können (um Rückwärtskompatibilität mit C-Skript zu bewahren). Beispiel:

SPOT* myspot = { x = 1; y = 2; name = "my struct"; }  
// creates a new SPOT struct with initial values that is then referenced through the myspot pointer

 !!  Beachten Sie, dass dieses Initialisieren nur für globale Strukt-Pointer funktioniert, nicht aber für lokale, innerhalb einer Funktion definierte Strukt-Pointer und auch nicht für Arrays. Zwar können Sie Strukt-Pointer-Arrays (wie SPOT* pspots[100];) erstellen, aber Sie können sie in der Definition nicht initialisieren. Innerhalb der Strukt-Intitialisierung lassen sich jedwede Zahlen, Variablen, Zeichen-Strings oder Pointer auf andere Strukts verwenden, interne Engine-Variablen aber (wie etwa "camera") und #defines (wie etwa vorher definierte "NUMBER_OF_ARRAY_ELEMENTS") können nicht benutzt werden.

In Standard C / C++, wird per Punkt '.' auf die Teile eines Strukts zugegriffen und auf die Teile eines Strukt-Pointers per Pfeil '->'. In lite-C oder C-Skript erkennt der Kompilierer automatisch ob es sich um ein Strukt oder einen Strukt-Pointer handelt und der Punkt '.' lässt sich für beides verwenden. Beispiel:

SPOT* myspot = { x = 1; y = 2; name = "my struct"; }
...
myspot->x = 1; // standard C/C++; works also in lite-c
myspot.y = 2;  // C-Script / lite-C 

Das Arbeiten mit Structen ist in jedem C/C++-Buch beschrieben, wir werden uns hier also nicht im Detail damit beschäftigen. Um Structs oder Arrays von Structen während der Laufzeit zu erstellen, lassen sich die Standard C-Bibliotheksfunktionen malloc() and free() verwenden. Zum Initialisieren oder Kopieren von Structen, verwenden Sie die C-Bibliotheksfunktionen memset() und memcpy():

function foo()
{
  SPOT* myspot = malloc(sizeof(SPOT)); // creates a new SPOT struct at runtime
  memset(myspot,0,sizeof(SPOT)); // set the struct content to zero (it's undefined after malloc)
  myspot->x = 1;  
  SPOT* spot_array = malloc(100*sizeof(SPOT)); // creates an array of 100 SPOT structs
  memcpy(&spot_array[0],myspot,sizeof(SPOT));  // copy the myspot struct to the first member of the array
  ...
  free(myspot); // removes the created structs
  free(myspot_array);
}

 !!  Es gibt im Internet oder in Online-C-Kursen eine Vielfalt von Informationen über Bibliothekstfunktionen von C, C++ oder Windows. Für fortgeschrittenes lite-C-Programmieren ist es äusserst empfehlenswert, sich durch solch einen Kurs zu arbeiten oder ein diesbezügliches Buch zu lesen und dabe etwas über malloc, memcpy und all die anderen Bibliotheksfunktionen, die man verwenden kann, zu lernen.

Vektoren

Neben den Engine-Objekten gibt es auch Standard-Strukts, die als Parameter für Funktionen benutzt werden können: ein VECTOR-Strukt mit x, y, z vars, ein Euler ANGLE-Strukt mit pan, tilt, roll vars (s. "coordinates") und ein COLOR-Strukt mit blau, grün, rot vars. Auch sie sind in include\atypes.h gespeichert und werden in vielen Engine-Funktionen benutzt.

Strukts selber werden nicht als Argumente an Funktionen weitergegeben, noch von Funktionen zurückgeliefert. Strukt-Pointer aber schon. Lite-C stellt automatisch fest, ob das Argument ein Pointer ist und konvertiert es, falls nicht, in einen Pointer. Beispiel:

function spot_init(SPOT* spot) 
{ 
  if (!spot) return; // prevent crash when an empty pointer is passed
  spot.x = 1; 
  spot.y = 1; 
}
...
SPOT myspot; // creates an uninitalized SPOT struct named "myspot"
...
spot_init(myspot); // passes a pointer to myspot

sizeof(struct)

Das Macro sizeof(), das in obigem Beispiel verwendet wird, gibt die Größe einer Variablen oder eines Strukts in Bytes an. Dies lässt sich zum Initialisieren von Strukts über das in include\acknex.h definierte zero (null) -Macro verwenden..
#define zero(struct) memset((void*)&struct,0,sizeof(struct))
...
VECTOR speed;
zero(speed);	// initializes the VECTOR struct "speed" to zero

 !!  Beachten Sie, daß Arrays intern als Pointer auf einen Speicherbereich gehandhabt werden. sizeof(any_array) liefert also immer Werte, die 4 entsprechen zurück, denn das ist die Größe eines Pointers.

 !!  sizeof() ist ein Macro und keine Funktion. Es läßt sich zum Setzen einer Variablen oder zum Übergeben eines Parameters an eine Funktion verwenden, kann aber nicht in Ausdrücken benutzt werden. Daher ist also long_size = sizeof(long); in Ordnung, long_size_times_ten = sizeof(long)*10; jedoch nicht. Diese Einschränkung gilt nicht für oder A7.7 höher.

Siehe auch:

Variables, strings, pointers, functions,

► Aktuelle Version Online