lite-C 101

Top  Previous  Next

Diesen Monat lernen wir, wie Strukturen ("structs") eingesetzt werden können. Eine Struktur ist nichts weiter als eine Sammlung von Daten: Variablen, Pointer, Strings und so weiter. Sie haben auch vermutlich schon viele davon verwendet: CAMERA, PANEL, TEXT, MATERIAL, etc. sind alle vordefinierte Strukturen aus der Acknex Engine. Hier ist ein Beispiel, das in der atypes.h Datei definiert ist, die bei GameStudio und lite-C enthalten ist:

 

typedef struct {

       var blue, green, red;

} COLOR;

 

Eine typische Definition einer Struktur sieht folgendermaßen aus:

 

typedef struct {        

       int age;        

       int kids;        

       char* name;

} PEOPLE;

 

In diesem Fall haben wir eine Struktur namens PEOPLE definiert, welches 2 Intergervariablen (age und kids) und einen String (name) enthält. Wir können nun Strukturen vom Typ PEOPLE definieren und im Code verwenden:

 

PEOPLE james; // creates a PEOPLE struct named james 

PEOPLE* jacob; // creates a pointer to a PEOPLE struct 

 

Dies geschieht, wenn die Datei structs1.c geöffnet und ausgeführt wird:

 

aum72_workshop1

 

Der Code ist wie immer simpel gehalten:

 

var johns_age;

var johns_kids;

 

STRING* johns_str = "                    "; // holds up to 20 characters

 

typedef struct {        

       int age;        

       int kids;        

       char* name;

} PEOPLE;

 

PEOPLE* john =

{        

       age = 42;

       kids = 3;        

       name = "John Doe";

}

 

PANEL* johns_pan =

{        

       digits (20, 30, "Age: %.0f", *, 1, johns_age);

       digits (20, 40, "Number of kids: %.0f", *, 1, johns_kids);        

       digits (20, 20, johns_str, *, 0, 0);        

       flags = visible;

}

 

function main()

{        

       johns_age = john.age;

       johns_kids = john.kids;

       str_cpy(johns_str, john.name);

}

 

Eine Struktur kann nicht einfach bei der Erstellung initialisiert werden, aber bei einem Pointer auf ein struct ist dies möglich, wie bei "john" im Beispiel. Der Code belegt alle Felder in der Struktur: age = 42, kids = 3 und den Namen "John Doe". Die main Funktion kopiert diese Werte einfach in 2 Variablen und einen String, damit wir sie mit Hilfe eines Panels anzeigen können. Natürlich können sich die Werte in der Struktur zur Laufzeit ändern, indem z.B. "john.age = 35;" oder Ähnliches eingegeben wird.

 

Vielleicht wenden Sie jetzt ein, dass Strukturen nicht wirklich nötig sind, da dieselben Resultate auch mit gewöhnlichen Variablen erreicht werden können. Sie haben Recht; allerdings erlaubt eine Struktur, diese Daten besser zu orgainiseren. Eine neue Person ist ganz einfach definiert:

 

PEOPLE* jenny =

{        

       age = 34;

       kids = 1;        

       name = "Jenny Bart";

}

 

Sehen Sie, wie mächtig dieses Konzept ist? Und wir kratzen erst an der Oberfläche! Schauen Sie sich die Beispiele aus structs2.c an, um zu sehen, was ich meine:

 

aum72_workshop2

 

typedef struct {        

       char* author;

       char* title;

       long year;

       char* editor;

} BOOKS;

 

BOOKS entry[100];

 

function main()

{        

       entry[0].author = "Jimmy Page";

       entry[0].title = "Going with the wind";

       entry[0].year = 1999;

       entry[0].editor = "Mc. Miller";

 

       entry[1].author = "Jen Pages";

       entry[1].title = "All your base are belong to us";

       entry[1].year = 2000;

       entry[1].editor = "Worst Press Inc.";

 

       entry[2].author = "Johnny Stark";

       entry[2].title = "Termites all over";

       entry[2].year = 2001;

       entry[2].editor = "Best Failures Inc.";

 

       str_cpy(author1_str, entry[0].author); // these lines display the values on the panel

       str_cpy(author2_str, entry[1].author);

       str_cpy(author3_str, entry[2].author);

       str_cpy(title1_str, entry[0].title);

       str_cpy(title2_str, entry[1].title);

       str_cpy(title3_str, entry[2].title);

       year1 = entry[0].year;

       year2 = entry[1].year;

       year3 = entry[2].year;

       str_cpy(editor1_str, entry[0].editor);

       str_cpy(editor2_str, entry[1].editor);

       str_cpy(editor3_str, entry[2].editor);

}

 

Ich habe die Definitionen der Variablen und Strings und das Panel weggelassen, das zur Anzeige verwendet wird, aber all der andere code steht da. Wie Sie sehen definiere ich eine Struktur namens BOOKS und dann kann ein Array von BOOKS Strukturen erstellt werden, das 100 Elemente besitzt. Wir können also nun die Informationen für bis zu 100 Bücher elegant speichern, wobei der Name des Autors, der Titel des Buches, das Erscheinungsjahr und der Name des Verlags gespeichert werden. Natürlich hätten wir das gleiche Ergebnis auch mit 300 Strings und 100 Variablen erzielen können, aber das hätte viel schlimmer ausgesehen, oder? Und bei den ganzen Variablen hätte ich den Code nicht sehen wollen, der nach einem bestimmten Autor oder Buchtitel sucht...

 

Ich habe die korrekten Werte für die ersten 3 Bücher eingesetzt, um ein Beispiel zu geben wie man mit der Struktur arbeitet: das erste Buch wird über entry[0] angesprochen, das zweite über entry[1] und so weiter.

 

Bereit für mehr Strukturen? Öffnen Sie die Datei structs3.c und starten Sie diese.

 

aum72_workshop3

 

var results1;

var results2;

 

STRING* team1_str = "                    "; // holds up to 20 characters

STRING* coder1_str = "                    "; // holds up to 20 characters

 

typedef struct {        

       char* name;

       long successes;

       long failures;

} PROGRAMMER;

 

typedef struct {        

       char* team_name;

       PROGRAMMER coders[10];

} TEAM;

 

TEAM abt;

 

PANEL* info_pan =

{        

       digits (20, 20, team1_str, *, 0, 0);

       digits (20, 30, coder1_str, *, 0, 0);

       digits (20, 40, "Successes: %.0f", *, 1, results1);

       digits (20, 50, "Failures: %.0f", *, 1, results2);

       flags = visible;

}

 

function main()

{        

       abt.team_name = "Alpha Betatronics";

       abt.coders[0].name = "Johnny Stamina";

       abt.coders[0].successes = 10;

       abt.coders[0].failures = 3;

 

       str_cpy(team1_str, abt.team_name); // these lines display the values on the panel

       str_cpy(coder1_str, abt.coders[0].name);

       results1 = abt.coders[0].successes;

       results2 = abt.coders[0].failures;

}

 

Sehen Sie sich den Code gut an; wie Sie sehen definieren wir 2 Strukturen: PROGRAMMEr und TEAM. Ob Sie es glauben oder nicht, bei der Definition einer Struktur kann eine andere Struktur genutzt werden und genau dies ist hier geschehen. Es gibt bei dieser Schachtelung nur eine Regel zu beachten: Sie können keine Struktur in einer anderen verwenden bevor diese definiert ist.

 

In der Struktur PROGRAMMER werden alle Daten des Programmierers gespeichert: der Name, die Anzahl der Erfolge und die fehlgeschlagenen Projekte. Die Struktur TEAM speichert den Teamnamen und Informationen über bis zu 10 Programmierer.

 

Dann wurde eine TEAM Struktur namens abt definiert. Damit können wir alle Daten darin ansprechen (zum Beispiel team_name) und auch alle Datenfelder, die in PROGRAMMER definiert sind. Die main Funktion weist dem "team_name" einen Wert zu ebenso wie den Feldern des ersten Programmierers.

 

Das ist es im Wesentlichen; Sie sollten nun in der Lage sein, den hässlichen Inventar-Code fortzuwerfen und das Ganze mit Strukturen wesentlich eleganter aufzubauen. Vergessen Sie nicht, im "Plug and Play" Bereich des Magazins nachzusehen, dort findet sich eine einfache Datenbank Anwendung, die Strukturen verwendet.