|
lite-C 101 |
Top Previous Next |
|
Ich habe mich vor vielen Jahren entschlossen, die Programmiersprache C zu erlernen; alles lief reibungslos bis ich das Kapitel über Pointer erreichte. Es dauerte wirklich eine Weile bis ich verstanden habe, wie diese Pointer funktionieren; zwischendurch war ich so entmutigt, dass ich beinahe aufgegeben habe. Daher kann ich nur hoffen, dass es Ihnen besser geht und versuchen, Ihnen mit dem Workshop ein wenig zu helfen.
Worauf warten Sie also noch? Krempeln Sie die Ärmel hoch, setzen Sie sich Ihre Denkermütze auf Sie werden sie brauchen! Nun ja... die Mütze brauchen Sie vielleicht doch nicht, da meine Beispiele wie immer sehr einfach sind.
#include <acknex.h> #include <default.c>
STRING* value_str = "";
TEXT* value_txt = { layer = 15; pos_x = 140; pos_y = 20; string(value_str); flags = VISIBLE; }
function main() { video_mode = 6; // create a program window of 640x480 pixels vec_set(screen_color, vector(55, 55, 55)); // make the background color dark
int a, *p; a = 123; p = &a; str_for_num(value_str, *p); }
Sehen Sie was ich meine? Lite-C ist unschlagbar, wenn es um effiziente Programmierung geht! Dies ist der Inhalt der pointers1.c Datei und hier ist das Ergebnis des Testlaufes:
Die einzigen Zeilen, die unserer Aufmerksamkeit bedürfen sind die folgenden:
int a, *p; a = 123; p = &a; str_for_num(value_str, *p);
Die erste Codezeile definiert zwei Integer Variablen: eine gewöhnliche Variable namens a und einen Pointer namens p.
Vergessen Sie für einen Moment alles, was Sie über die Pointer in Gamestudio wissen und beginnen wir von vorn. Ein Pointer (deutsch: Zeiger) ist nichts anderes als eine Variable. Aber es handelt sich um eine ganz besondere Variable! Ein Pointer speichert keinen Wert, wie unsere gewöhnliche Variable a dies tut, sondern statt dessen Speicheradressen von Objekten (Variablen, Strings, etc.).
In unserem Beispiel setzt das Kommando a = 123; die Variable mit Namen a auf den Wert 123. Bis hierher nichts Ungewöhnliches, richtig? Die nächste Zeile p = &a; weist dem Pointer p die Adresse der Variablen a zu. Das bedeutet auf gut Deutsch, dass falls unsere Variable a im Speicher des Computers beispielsweise bei Adresse 23443 steht, der Pointer p den Wert 23443 erhält. Das folgende Bild sollte dies verdeutlichen.
Wir können nicht vorhersagen, an welcher Stelle im Speicher eine Variable abgelegt wird, aber ein Pointer kann diese Adresse ermitteln und speichern ein nützliches Feature, nicht wahr? Hier ist die letzte Codezeile aus pointers1.c, die wir betrachten wollen:
str_for_num(value_str, *p);
Hier verwenden wir den * Operator, der nichts mit Multiplikation zu tun hat; beide verwenden das gleiche Symbol, haben jedoch verschiedene Funktionen.
Der * Operator liefert den Wert, der an der Speicheradresse steht, auf die der Pointer verweist; da der Inhalt der 23443. Speicherzelle gerade 123 ist, wird *p den Wert 123 haben... klar? Diese Codezeile konvertiert 123 in einen String, der auf dem Bildschirm angezeigt wird; ich habe mich für einen einfachen Text entschieden, um mehrere numerische Werte anzeigen zu können, ohne Digit-Elemente verwenden zu müssen.
Ergibt alles so langsam einen Sinn? Hier ist ein kurzes How to: a) Zunächst müssen wir dem Pointer mitteilen, welches Objekt er verfolgen soll (eine Variable, ein String, etc.). b) Dann können wir mit dem * Operator den Wert ermitteln, der an dieser Adresse steht. Wir können noch viel mehr tun, wie Sie bald sehen werden.
Das folgende Beispiel erlaubt es uns, den Wert einer Variable mit Hilfe eines Pointers zu verändern.
#include <acknex.h> #include <default.c>
STRING* value_str = "";
TEXT* value_txt = { layer = 15; pos_x = 140; pos_y = 20; string(value_str); flags = VISIBLE; }
function main() { video_mode = 6; // create a program window of 640x480 pixels vec_set(screen_color, vector(55, 55, 55)); // make the background color dark
int a = 100, *p; p = &a; *p = 456; str_for_num(value_str, a); }
Diese Zeilen sollten wir uns näher ansehen:
int a = 100, *p; p = &a; *p = 456; str_for_num(value_str, a); // display the new value of a
Die erste Zeile definiert einen Integer namens a und setzt den Wert auf 100; wir definieren auch einen Pointer p. Dann weisen wir diesem die Adresse der Variablen a zu. Die dritte Codezeile setzt den Wert in der Zelle, auf die p zeigt auf 456; ob Sie es glauben oder nicht, auch die Variable a wird nun den Wert 456 haben, da der Wert in der a zugewiesenen Speicherzelle geändert wurde. Die letzte Codezeile zeigt den neuen Wert von a an und zeigt uns, dass der Wert wirklich geändert wurde. Dieses Bild zeigt den gesamten Prozess:
Sind Sie bereit für mehr Pointer Action? Öffnen Sie die Datei pointers3.c.
#include <acknex.h> #include <default.c>
STRING* value_str = " "; // stores up to 40 characters STRING* temp_str = " "; // stores up to 6 characters
TEXT* values_txt = { layer = 15; pos_x = 100; pos_y = 20; string (value_str); flags = VISIBLE; }
int a[5];
function main() { video_mode = 6; // create a program window of 640x480 pixels vec_set(screen_color, vector(55, 55, 55)); // make the background color dark
int *p, i; str_cpy(value_str, "Table values: "); for (i = 0; i < 5; i++) { a[i] = i; str_for_num(temp_str, a[i]); str_cat(value_str, temp_str); str_cat(value_str, " "); } str_cat(value_str, " Pointer values: "); p = a; // assign the starting address of the table named a to the pointer p for (i = 0; i < 5; i++) { str_for_num(temp_str, *(p + i)); str_cat(value_str, temp_str); str_cat(value_str, " "); } }
Die interessanten Dinge geschehen in der Funktion main. Zunächst definieren wir einen Pointer p und eine Variable i, die als Zähler fungiert. Dann nutzen wir eine for-Schleife, um einen Array a mit Werten zu füllen: a[0] wird auf 0 gesetzt, a[1] auf 1 und so weiter. Jeder dieser Werte wird in einen String konvertiert und an den großen value_str String angefügt, der dann auf dem Bildschirm angezeigt wird.
Zu diesem Zeitpunkt sollte der Bildschirm etwa so aussehen:
Hier ist der Rest des Codes:
str_cat(value_str, " Pointer values: "); p = a; for (i = 0; i < 5; i++) { str_for_num(temp_str, *(p + i)); str_cat(value_str, temp_str); str_cat(value_str, " "); }
Die erste Zeile fügt dem angezeigten String etwas Text hinzu. Die zweite Zeile ist die wichtigste in diesem Beispiel: sie weist dem Pointer p die Startadresse des Arrays a zu. Ja, das ist möglich und wir können auf diese Weise alle Elemente des Arrays mit Hilfe des Pointers manipulieren. Hier ist ein Bild, das zeigt was geschieht, wenn die Zeile p = a; ausgeführt wird:
Zu diesem Zeitpunkt sollte der Bildschirm etwa so aussehen:
Dies beweist, dass unser Pointer Zugriff auf alle Speicherzellen des Arrays hat; etwas wie *(p+2) = 333; wird den Wert von a[2] auf 333 ändern, klar?
Nun zum letzten Beispiel; es ist ein Ausschnitt, der die wahre Macht von Pointern demonstriert:
#include <acknex.h> #include <default.c>
STRING* text_str = "";
TEXT* commercial_txt = { layer = 15; pos_x = 140; pos_y = 20; string(text_str); flags = VISIBLE; }
function display_text(char *p) { while (1) { while (*p) { str_cpy(text_str, *p); p++; wait (-0.1); } p--; while (*p) { str_cpy(text_str, *p); p--; wait (-0.1); } p++; } }
function main() { video_mode = 6; // create a program window of 640x480 pixels vec_set(screen_color, vector(55, 55, 55)); // make the background color dark display_text(" This text will be scrolled back and forth on the screen! "); }
Der Code scrollt einen Text horizontal auf dem Bildschirm hin und her, wie in einigen Werbespots. Die Funktion main ruft einfach display_text() auf und liefert den anzuzeigenden Text als Argument mit.
function display_text(char *p) { while (1) { while (*p) { str_cpy(text_str, *p); p++; wait (-0.1); } p--; while (*p) { str_cpy(text_str, *p); p--; wait (-0.1); } p++; } }
Die Funktion setzt einen Pointer p auf die Adresse des Strings, der angezeigt werden soll. Schauen wir uns die while (*p) Schleife genauer an:
while (*p) { str_cpy(text_str, *p); p++; wait (-0.1); } p--;
Die Schleife läuft solange, wie der Pointer noch nicht das Ende des Strings (das Null Byte) erreicht hat. Wir kopieren das Objekt, auf das p zeigt in text_str und zeigen diesen auf dem Bildschirm an, bevor wir unseren Pointer um 1 erhöhen; auf diese Weise wird mit jedem Durchlauf ein Zeichen weniger angezeigt. Die schleife pausiert für 0,1 Sekunden und erzeugt so eine moderate, nicht zu schnelle Scrollgeschwindigkeit; die Bewegung wird folgendermaßen aussehen:
This text will be scrolled back and forth on the screen! his text will be scrolled back and forth on the screen! is text will be scrolled back and forth on the screen! s text will be scrolled back and forth on the screen! text will be scrolled back and forth on the screen! text will be scrolled back and forth on the screen! ext will be scrolled back and forth on the screen! xt will be scrolled back and forth on the screen! t will be scrolled back and forth on the screen! .................... screen! creen! reen! een! en! n! !
Die erste Schleife ist beendet der Pointer hat das Ende des Strings erreicht. Wir verwenden eine p--; Anweisung und verschieben den Zeiger damit wieder eine Zelle nach hinten, bis es das letzte richtige Zeichen im String erreicht hat. Eine ähnliche Schleife folgt, die den Pointer verringert und somit wieder mehr und mehr Zeichen darstellt.
! n! en! een! reen! creen! screen! .................... t will be scrolled back and forth on the screen! xt will be scrolled back and forth on the screen! ext will be scrolled back and forth on the screen! text will be scrolled back and forth on the screen! text will be scrolled back and forth on the screen! s text will be scrolled back and forth on the screen! is text will be scrolled back and forth on the screen! his text will be scrolled back and forth on the screen! This text will be scrolled back and forth on the screen!
Die große while(1) Schleife stellt sicher, dass der Text dauernd vor und zurück gescrollt wird. Wir hätten einen ähnlichen Effekt mit str_clip und str_strunc erreichen können, aber der Code wäre viel länger gewesen und die Anwendung langsamer. Generell gilt, dass Pointer zu sehr schneller Verarbeitung führen.
Dies beendet unsere Einführung zum Thema Pointer. Ich hoffe, Sie haben keine Angst mehr vor ihnen, denn ich weiß aus einer zuverlässigen Quelle, dass sie nun große Angst vor Ihnen haben...
|