012
05.01.2008, 17:50 Uhr
Hans
Library Walker (Operator)
|
Hi,
es gibt noch eine weitere Möglichkeit, das Programm zu prüfen: Da es ja erst mal darum geht, die Logik des Programms auf ihre Richtigkeit zu überprüfen, wäre es noch eine Massnahme, die Grafik erst mal weg zu lassen. Aber nicht, indem jetzt alle Grafikbefehle aus dem Quelltext gestrichen werden, sondern indem man den Compiler anweist, sie nicht zu übersetzen. Das Prinzip nennt sich "bedingte compilierung", und funktioniert so: Du setzt am Anfang des Quelltextes eine sogenannte #define-Direktive. Damit definierst Du eine Bedingung, die der Compiler (genauer der Präprozessor) überprüfen kann. Wenn die Bedingung erfüllt ist, werden bestimmte Codeabschnitte übersetzt, ist sie nicht erfüllt, werden andere Codeabschnitte übersetzt. Beispiel:
C++: |
#define something ... #ifdef something /* tue dies */ #else /* tue das */ #endif
|
Das ganze funktioniert fast genau so, wie die if-Abfragen in C auch, dient aber dazu, dem Compiler bestimmte Codeteile nach bestimmten Kriterien vorzusetzen, d.h. das Programm anhand bestimmter Kriterien zu übersetzen. Ich demonstier das mal an einem längeren Beispiel. Am Anfang definiere ich eine Bedingung, die nennt sich Graph_On. Wenn diese Bedingung erfüllt ist, arbeitet das Programm im Grafik-modus, und malt ein Zifferblatt für eine Uhr. Ist die Bedingung nicht erfüllt, lässt es die Grafik weg, berechnet aber dennoch die Positionen für die Markierungen auf dem Zifferblatt, und gibt die Koordinaten als (Werte-)Tabelle aus. Danach wartet es auf einen Tastendruck, und wird anschliessend beendet.
C++: |
/* Beispiel zur bedingten Compilierung eines Grafikprogramms unter DOS. Compiler: Turbo-C++ V3.0 By: Hans */
/* Bedingung festlegen - Wenn Graph_On definiert ist, wird das Programm als Grafikprogramm übersetzt, - wenn die #define-Zeile auskommentiert ist, wird die Grafik weg gelassen, es werden nur die Koordinatenberechnungen durchgeführt, und auf dem Bildschirm ausgegeben. */ #define Graph_On
#include <stdio.h> #include <stdlib.h> #include <math.h> #include <conio.h>
/* Bedingung prüfen */ #ifdef Graph_On #include <graphics.h> #endif
int main() { int xm, ym, /* Mittelpunkt koordinaten */ xr, yr, /* Koordinaten auf dem Kreisbogen */ r, /* Kreisradius */ i;
double w, w2, /* Winkel im Bogenmass */ pi; /* Kreiskonstante im Bogenmass */
/* Die folgenden Zeilen werden nur übersetzt, wenn Graph_On definiert ist. */ #ifdef Graph_On int gd, gm;
detectgraph(&gd, &gm); initgraph(&gd, &gm, "D:\\turboc\\bgi"); #endif
/* Ich geh hier von der kleinsten Bildauflösung aus: 320 x 200 Punkte */ xm=160; ym=100; r=60;
pi=4*atan(1.); /* Arkus-tangens von 1 = 45° ; 4*45°=180° ; */ /* entspricht pi im Bogenmass, nähere Erläuterungen in Mathe */ w=30.*pi/180.; /* Der Punkt teilt dem Compiler mit, das es sich um Gleit- */ /* kommazahlen handelt. */ w2=90.*pi/180.;
#ifdef Graph_On putpixel(xm, ym, getcolor()); circle(xm, ym, r); #else printf ("\n"); #endif
r-=4; /* Damit die Markierungen innerhalb des Zifferblatts bleiben */ for (i=12; i>=1; i--) { xr=r*cos(w*i-w2); yr=r*sin(w*i-w2);
#ifdef Graph_On circle(xm+xr, ym+yr, 2); #else printf ("xr=%3d, yr=%3d\n", xm+xr, ym+yr); #endif
} /* for-Schleife */
/* Die folgende Textausgabe ist nur Sinnvoll, wenn die Grafik nicht aktiv ist. Bei aktivierter Grafik sieht man sie eh nicht. Deshalb wird hier geprüft, ob Graph_on nicht definiert ist. */ #ifndef Graph_On printf ("Bitte eine Taste drücken...\n"); #endif
getch(); closegraph();
return 0; }
|
Soweit das Programm. Zugegeben es wird etwas unübersichtlich, aber durch diese bedingte Compilierung eröffnet dich die Möglichkeit, Variablen auf den Bildschirm auszugeben, Man kann das Programm damit auch so gestalten, das es erst mal nur im Textmodus arbeitet, indem man das Spielfeld aus Textzeichen zusammensetzt, etwa so:
Code: |
1 2 3 4 +---+---+---+---+- | | | | | +---+---+---+---+- | | | | | +---+---+---+---+- | | | | |
|
Als Spielsteine nimmt man dann das grosse O. Die Position, wo das nächste O hin soll, lässt sich im Textmodus mit gotoxy() angeben, und Farben lassen sich da auch setzen. Das Spielfeld wird so etwa 15 Zeilen hoch, also ist darunter noch Platz, um Variablenwerte auszugeben. (Damit dabei nichts nach oben aus dem Bild rollt, muss auch mit gotoxy() gearbeitet werden.)
Wenn das mit den Variablenausgaben zu umständlich ist, kannst Du es jetzt auch noch mal mit dem Debugger versuchen, und damit die Variablen beobachten (watches). Du hast dabei den Vorteil, das nicht ständig zwischen Text und Grafik hin und her geschaltet werden muss. Der Debugger ist nämlich gar nicht so schlecht. Das Problem des Debuggens bei Grafikprogrammen liegt meiner Meinung nach nämlich im hin- und herschalten begraben. Und unter Windows kommt wahrscheinlich noch erschwerend hinzu, das der Debugger Windows ins Handwerk pfuscht, was letztlich zu unvorhersehbarem Verhalten führt, wie die plötzlichen Warmstarts, die bei mir aufgetreten sind. Denn es ist noch zu beachten, dass der Debugger von Turbo C++ für DOS entwickelt wurde. Unter DOS kann aber immer nur ein einziges Programm laufen, und nicht mehrere nebeneinander, wie unter Windows. Dem entsprechend gehen DOS-Programme davon aus, das sie auf dem Rechner alleine sind, und folglich fast alles machen können, was möglich ist. Das tun sie auch sehr häufig, und weil Windows oft nicht in der Lage ist, solches Verhalten von DOS-Programmen zu unterbinden, führt das zu Systemabstürzen.
So, ich denke, das ist jetzt erst mal genug Stoff zum experimentieren und nachdenken...
Hans -- Man muss nicht alles wissen, aber man sollte wissen, wo es steht. Zum Beispiel hier: Nachdenkseiten oder Infoportal Globalisierung. |