Delphi und Visual C#.pdf - Informatik
Delphi und Visual C#.pdf - Informatik
Delphi und Visual C#.pdf - Informatik
Erfolgreiche ePaper selbst erstellen
Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.
2. Visuelle Programmiersprachen<br />
<strong>Delphi</strong> <strong>und</strong> <strong>Visual</strong> <strong>C#</strong><br />
Windows-Programmierung<br />
Das Struktogramm für die Lösung quadratischer Gleichungen lässt sich durch eine<br />
Liste von Anweisungen realisieren. Das verw<strong>und</strong>ert nicht, weil man ahnt, dass ein<br />
Prozessor ja nur einen Befehl nach dem andern abarbeiten kann. Programmieren in<br />
diesem Sinn wäre daher das Notieren eventuell sehr langer Anweisungslisten.<br />
Mit <strong>Delphi</strong> <strong>und</strong> <strong>Visual</strong> <strong>C#</strong> betreten wir jedoch das Land der Windowsprogrammierung.<br />
Und da ist alles anders:<br />
Alle Aktionen laufen objekt- <strong>und</strong> ereignisorientiert ab. Schluss mit der Befehlsliste!<br />
Das bedeutet, dass das Betriebssystem ständig darüber wacht, ob der Benutzer<br />
irgend etwas mit Tastatur (Maus, USB-Ports etc) tut. Das klappt gut, solange der<br />
Rechner nicht „abgestürzt“ ist, also nicht mehr auf Eingaben reagieren kann oder will.<br />
Gibt der Benutzer etwas ein, so sollte sich, falls diese Eingabe vom Programmierer<br />
vorgesehen wurde, ein Programmteil zuständig „fühlen“ <strong>und</strong> auf dieses Ereignis<br />
reagieren.<br />
Um diese Art der Programmierung zu verstehen, sollten Sie mindestens die<br />
folgenden drei Begriffe kennenlernen: Objekte, Eigenschaften, Methoden <strong>und</strong><br />
Ereignisse.<br />
Besonders der Objekt-Begriff wird in Kapitel 5 ausführlich behandelt werden. Hier soll<br />
daher nur soviel, wie unbedingt nötig erklärt werden.<br />
• Objekte (Objects):<br />
Das sind zunächst alle Elemente der Windows-Bedienungsoberfläche.<br />
Betrachten wir der Einfachheit halber nur visuelle Benutzerschnittstellen, dann<br />
hat man es in <strong>Delphi</strong> mit diesen Objekten zu tun:<br />
o Formulare:<br />
Das sind zum Beispiel Windowsfenster wie das schon recht<br />
komplizierte Word-Fenster, das Sie gerade geöffnet haben.<br />
Die Menge der Formulare wird mit TForm bezeichnet. Darin können<br />
Grafiken, Text oder andere Komponenten enthalten sein.<br />
o Komponenten:<br />
Da gibt es Menus (TMenu),<br />
Schaltflächen bzw. Buttons (TButton),<br />
Textfelder bzw Edits (TEdit)......<br />
(Welche Komponenten erkennen Sie<br />
im Formular rechts?)<br />
o Sonstige Objekte:<br />
Dazu gehören z.B. der Bildschirm<br />
(TScreen) <strong>und</strong> der Drucker (TPrinter).<br />
125
• Eigenschaften (Properties):<br />
Das sind Dinge wie Farbe (Color), Breite (Width) oder Schrift (Font) des<br />
Objekts. Jedes Objekt hat „seine“ Eigenschaften.<br />
Manche muss kann man nur in der Entwurfzeit,<br />
andere nur zur Laufzeit verändern.<br />
Beispiel: Hier wurde zur Entwurfzeit festgelegt, dass<br />
das Formular rot sein soll. Auch die Aufschrift<br />
(Caption) wurde festgelegt („Formular soll rot sein“)<br />
Hier lässt sich die Farbe durch den Befehl<br />
Form1.color:= clgreen;<br />
auch zur Laufzeit verändern. Dabei ist Form1 der<br />
Name des Formulars. Auch er gehört zu den<br />
Eigenschaften!<br />
• Methoden (Methods):<br />
Der Begriff meint das „Verhalten“ des Objekts auf<br />
bestimmte Ereignisse. Diese können vom Benutzer<br />
ausgelöst werden. Aber auch das Programm selbst<br />
kann Methoden auslösen.<br />
Beispiel: Immer wenn eine Taste gedrückt wird, soll<br />
die Farbe zwischen rot, grün <strong>und</strong> blau umgeschaltet<br />
<strong>und</strong> die Aufschrift entsprechend verändert werden.<br />
Damit haben Sie selbst eine Methode für das<br />
Formular programmiert. ( Beispiel:<br />
FarbeAendern.exe)<br />
Objekte können bestimmte Methoden auch „besitzten“. Mit der Methode „Hide“<br />
für Formulare kann man die Eigenschaft visible der Formulars von true auf<br />
false setzten. Das Ergebnis der Methode ist nicht schwer zu erraten. (Beispiel:<br />
Form_Hide.exe )<br />
.<br />
• Ereignisse (Events):<br />
Das sind alle Nachrichten, die vom Objekt empfangen<br />
werden. Im obigen Fall also die Nachricht, dass eine<br />
Taste gedrückt wurde. Diese Ereignisse sind das Herz<br />
jeder Windowsprogrammierung. Sie sind die<br />
Schnittstelle zwischen Programm <strong>und</strong> Benutzer. Die<br />
Fähigkeit auf Ereignisse zu reagieren wird in<br />
Ereignisbehandlungsroutinen (Event Handler) erledigt.<br />
Noch ein Beispiel: Wenn man mit der Maustaste auf den obigen Knopf drückt,<br />
soll das Formular grün werden. Hier hat ganz offensichtlich schon einer<br />
gedrückt! Das Ereignis ist schon eingetreten <strong>und</strong> das Progamm hat<br />
entsprechend reagiert.<br />
Holen Sie sich zur Anschauung das Programm FarbwechselKnopfdruck.exe<br />
aus dem Tauschverzeichnis.<br />
Ein wichtiger Tipp: Wenn Sie wissen wollen, welche Eigenschaften, Methoden <strong>und</strong><br />
Ereignisse ein visuelles Objekt hat, dann setzten Sie es auf das Formular, markieren<br />
es <strong>und</strong> drücken dann Taste F 1 .<br />
126
<strong>Delphi</strong> mit Oracle<br />
<strong>Delphi</strong> an der Schule<br />
<strong>Informatik</strong>lehrer an den Gymnasien werden häufig mit folgender Schüler-Frage<br />
konfrontiert:<br />
Warum behandeln alle Lehrer als Programmiersprache <strong>Delphi</strong> im <strong>Informatik</strong>unterricht?<br />
Es gibt doch so viele ander Sprachen!<br />
Die Frage ist berechtigt! Zwar gibt es hie <strong>und</strong> da auch Lehrer, die Java unterrichten.<br />
Bisher muss man sie aber noch mit der Lupe suchen.<br />
Hier der Versuch einer Antwort:<br />
• Es gibt viele gute Lehrbücher für <strong>Delphi</strong>.<br />
• <strong>Delphi</strong> beruht auf Object Pascal <strong>und</strong> das kennen viele Lehrer noch vom<br />
Studium.<br />
• Die ersten Schritte in <strong>Delphi</strong> sind recht einfach.<br />
• Es ist alles so schön bunt ;-))<br />
Das sind sicher alles gute Argumente. Leider hat man aber keine Schüler gefragt. Bei<br />
vielen ist im Moment C++ oder <strong>C#</strong> hoch im Kurs. Manche beschäftigen sich aber<br />
eigentlich nur mit PHP <strong>und</strong> HTML <strong>und</strong> wollen nur darüber etwas hören. (Von denen,<br />
die eigentlich nur Computerspiele im Unterricht machen wollen, soll hier keine Rede<br />
sein!!)<br />
Und dann gibt es eine kleine (aber feine!) Menge von Lehrern, die sich ganz <strong>und</strong> gar<br />
nicht für <strong>Delphi</strong> begeistern können. Und auch sie haben handfeste Gründe. Es geht<br />
ihnen eigentlich nicht um <strong>Delphi</strong>, sondern sie hadern mit all den graphischen Fertigprodukten,<br />
wie <strong>Visual</strong> Basic oder <strong>Visual</strong> <strong>C#</strong>.<br />
Damit Sie das nachvollziehen können, machen wir nun ein kleines Experiment:<br />
Öffnen Sie <strong>Delphi</strong> 7. Dann<br />
sehen Sie dies:<br />
Jetzt ist wichtig, dass Sie<br />
sich genau an die folgenden<br />
Anweisungen halten:<br />
Gehen Sie zu file / save<br />
project as<br />
<strong>und</strong> wählen Sie einen neuen<br />
Ordner namens „Test“ auf<br />
D:<br />
Dann müssen Sie zwei mal<br />
auf „Speichern“ drücken.<br />
Beim ersten Mal sieht es so<br />
aus:<br />
127
Hier speichern Sie<br />
offensichtlich eine Datei<br />
namens Unit1.pas ab.<br />
Beim zweiten Mal wird eine<br />
Datei namens Project1.dpr<br />
ebenfalls dort<br />
abgespeicher.<br />
Nun erzeugen wir durch<br />
Drücken auf den grünen<br />
Pfeil (er bedeutet<br />
„run“<strong>und</strong> leitet die<br />
Kompilierung ein) oben<br />
links eine „Programmdatei“.<br />
Sie erhält autmatisch den<br />
Namen Project1.exe. Ein<br />
sehr anspruchsloses<br />
Programm!<br />
Es tut rein garnichts. Man<br />
sieht ein Fenster das leer<br />
ist. Man kann es eigentlich<br />
nur wieder wegklicken oder<br />
minimieren bzw auf den<br />
gesamten Bildschirm<br />
vergrößern :<br />
Und jetzt werfen Sie einen Blick in den Ordner Test in<br />
dem alle Dateien dieses „Programms“ versammelt sind.<br />
Richtig, - es sind acht (!!) Dateien! Die meisten kann<br />
man mit <strong>Delphi</strong> ansehen. Tun Sie das!<br />
Ahnen Sie, weshalb diesen Daten-Erzeugungs-<br />
Vorgang manche überhaupt nicht gut finden?<br />
Selbst bei den banalsten Vorgängen laufen bestimmte<br />
Automatismen ab, von denen man nichts weiß. Damit<br />
wird einem „das Heft aus der Hand genommen“.<br />
Sicher ist es gut gemeint: Man will dem Programmierer zeitraubende <strong>und</strong> langweilige<br />
Arbeiten ersparen. Damit erkauft man sich jedoch den Nachteil, dass besonders<br />
Programmier-Anfänger beim ersten auftretenden Problem überhaupt nicht verstehen,<br />
was nun denn wieder nicht geht. „<strong>Delphi</strong> spinnt!“ , bekommt man dann recht häufig<br />
zu hören.<br />
So kommt es, dass manche Lehrerinnen <strong>und</strong> Lehrer bei den Schulnetz-<br />
128
Administratoren nachfragen, ob man nicht noch das alte Pascal in Windows XP<br />
installieren kann.<br />
Das funktioniert vielleicht sogar mit einer virtuellen Windows 98 Oberfläche, - der<br />
Aufwand ist jedoch unnötig, denn Java ist nicht schlechter <strong>und</strong> ist vor allem<br />
kostenlos!<br />
<strong>Delphi</strong>s Lebenslauf<br />
Die folgenden Zeilen stellen nur einen stark vereinfachten Ablauf der <strong>Delphi</strong>-<br />
Geschichte dar.<br />
(Die systematische Einordnung der Sprache haben wir schon in Kapitel 2.0<br />
behandelt)<br />
Bis anfang der 80-iger Jahre gab es im Wesentlichen BASIC-, C-, Fortran- <strong>und</strong><br />
Pascal-Compiler. All diese Sprachen waren auf der Gr<strong>und</strong>lage von MS-DOS sehr<br />
umständlich zu bedienen. Das lag vor allem daran, dass MS-DOS nicht multitaskfähig<br />
war. Mit anderen Worten: Die Technik, durch timesharing mehrer Tasks<br />
„gleichzeitig“ ablaufen zu lassen, gab es in MS-DOS nicht.<br />
Zudem waren die genannten Sprachen vor allem wegen des stattlichen Preises nur<br />
für den professionellen Einsatz sinnvoll.<br />
(Die privaten Nutzer <strong>und</strong> Schulen verwendeten den zu MS-DOS mitgelieferten sehr<br />
langsamen Microsoft BASIC-Interpreter – wohin gegen die Universitäten mit dem<br />
teuren Pascal-Compiler arbeiteten.)<br />
Weshalb waren die Compiler „umständlich“? Sie dürfen nicht vergessen, dass es zu<br />
der damaligen Zeit kaum Festplatten gab. Sie waren einfach zu teurer. Man musste<br />
sich mit Disketten der maximalen Speichergröße von 1,4 MB begnügen. So blieb ein<br />
mehrfacher Disketten-Wechsel nicht aus!<br />
1983 endlich brachte Anders Hejlesberg Turbo-Pascal heraus. (Dem Namen werden<br />
Sie noch einige Male begegnen!)<br />
Dass diese Programmier-Sprache zum Standard wurde, hat mehrere Gründe:<br />
• Relativ güngstig zu kaufen<br />
• Sehr kleiner Speicherbedarf: 60 kB!!!<br />
• Dadurch kein Diskettenwechsel mehr nötig<br />
• Verwirklichung eines IDE-Konzepts (IDE = Integrierte Entwicklungsumgebung)<br />
Es mag Sie erstaunen, aber in den Jahren 1983 bis 1990 wurden zwischen 70% <strong>und</strong><br />
80% aller Programme in Turbo-Pascal geschrieben!!<br />
Um einschätzen zu können, wie stark sich die Programmiersprachen in den letzten<br />
Jahren entwickelt haben, muss man sich vor Augen halten, dass bis etwa 1985 eine<br />
Programmiersprache aus einem Editor, einem Compiler, einem Linker <strong>und</strong> einer<br />
Bibliothek bestand.<br />
Mit dem Editor gab man den Programm-Quelltext ein. Der Compiler übersetzte<br />
diesen Quelltext in Prozessorbefehle, der Linker verband das „Compilat“ mit den<br />
vorgefertigten Teilen der Bibliothek. Eine Bibliothek ist hier eine Sammlung von<br />
129
vorgefertigten Funktionen. Die Sammlung geht von A wie Ausgabe über G wie<br />
Gleitkomma bis Z wie Zeichnen von Linien. Die .NET Bibliothek, die wie einige Seiten<br />
später im Zusammenhang mit <strong>C#</strong> behandeln werden, ist solch eine Bibliothek.<br />
Für jeden der oben beschriebenen Prozesse musste man eine riesige Diskette (5¼inch:<br />
380kB - 1,2 MB!!) in das Laufwerk schieben. Bis das Programm schließlich<br />
fertig war, hatte man vielleicht mehr als h<strong>und</strong>ert Mal die Disketten gewechselt!<br />
Vor allem war es sehr zeitaufwändig <strong>und</strong> schwierig, Fehler zu lokalisieren. Selbst<br />
kleinste grafische Bestandteile des Programms erforderten einen riesigen<br />
Programmieraufwand. Um die Hilfe der Programmiersprache in Anspruch zu<br />
nehmen, musste man wieder mit Disketten jonglieren. Die Hilfe für die Bibliothek war<br />
freilich wieder auf anderen Disketten. Kurzum: Programmieren war ziemlich öde <strong>und</strong><br />
erforderte vom Programmierer ein erhebliches Maß an Frustrationstoleranz!<br />
Heute freilich sieht die Sache erheblich besser aus. Eine Programmiersprache hat,<br />
wie wir schon im letzten Kapitel erfahren haben, in der Regel eine Integrated<br />
Development Environment, also eine Integrierte Entwicklungsumgebung, kurz: IDE.<br />
In einer IDE sind die oben genannten Komponenten, wie Editor, Compiler bzw.<br />
Interpreter <strong>und</strong> Linker zusammengefasst. Darüber hinaus gibt es einen Debugger,<br />
einen visueller Designer <strong>und</strong> eine integrierte Hilfe für die Programmiersprache <strong>und</strong><br />
die Bibliothek. Der Programmierer gibt nur den Quelltext ein, drückt auf den<br />
besagten grünen Pfeil <strong>und</strong> die ganzen Prozesse laufen mehr oder weniger<br />
vollautomatisch ab. Mehr noch: Wenn der Compiler Fehler findet, dann werden diese<br />
aufgelistet <strong>und</strong> der Vorgang gestoppt.<br />
Es gab 7 Versionen der Sprache Turbo-Pascal. Die IDE der 6.Version sah so<br />
beispielsweise so aus:<br />
(Bild-Quelle: www.schulen.freiepresse.de )<br />
Erst 1991 kam, parallel zur Version 6, Turbo-Pascale für Windows in die Läden.<br />
Wäre Windows nicht der Quasi-Standard geworden, so hätte diese<br />
Programmiersprach wohl kaum einer gekauft, denn mit dem in C programmierten<br />
130
Windows war Turbo-Pascal keine Freude! Die Vorteile der Sprache waren dahin.<br />
Dennoch: Derart umständlich <strong>und</strong> langsam, konnte auch die Portierung in Windows<br />
als Kaufargument nicht mehr lange überzeugen.<br />
Mit Version 7 kam die Firma Borland ins Spiel. Die Sprache hieß nun Borland-Pascal.<br />
Vermutlich war das Microsoftsche <strong>Visual</strong> Basic Vorbild für die nächste Version von<br />
Pascal, die jetzt <strong>Delphi</strong> genannt wurde, wobei man den zugr<strong>und</strong>e liegenden Code<br />
weiterhin Object-Pascal nennt.<br />
In Delpi wurde, wie in <strong>Visual</strong> Basic, das sogenannte RAD-Prinzip (Rapid-<br />
Application-Development) verwendet. Man klickt sich seine Anwendungen mit der<br />
Maus zusammen <strong>und</strong> ein Großteil des nötigen Programmcodes wird automatisch<br />
generiert. Genau das haben Sie ja oben schon kennengelernt!<br />
Ganz im Gegensatz zu den Sprachen Java <strong>und</strong> PHP findet in Objekt-Pascal eine<br />
strenge Typenprüfung statt. Durch sie <strong>und</strong> durch die sehr gute Lesbarkeit des Codes<br />
wird die Gefahr nicht gewollten Verhaltens des Programms verringert.<br />
Bleibt zu klären, woher der Name <strong>Delphi</strong> kommt. Angeblich liegt dies daran, dass<br />
<strong>Delphi</strong> sehr stark im Erzeugen von Datenbanken ist. Die bekannteste Datenbank<br />
heißt Oracle. Von da ist es nicht mehr weit zu Orakel <strong>und</strong> schließlich <strong>Delphi</strong>! (Gibt es<br />
etwa jemanden, der dies nicht verstanden hat?!?)<br />
Behalten wir die Vorteile von <strong>Delphi</strong> im Auge <strong>und</strong> schreiben unser erstes „Hallo<br />
Welt!“ – Programm.<br />
Programmieren in <strong>Delphi</strong><br />
Starten wir <strong>Delphi</strong> <strong>und</strong> verkleinern wir mit der Maus das Form1-Fenster. Dann sehen<br />
wir dies:<br />
131
Dabei ist die Unit1 offensichtlich der Teil, in den man den Pascal-Programm-Code<br />
schreibt oder von <strong>Delphi</strong> schreiben lässt.<br />
Platzieren wir einen Button irgendwo auf dem Formular mit Namen Form1: Mit<br />
linker Maustaste anklicken <strong>und</strong> auf dem Formular erneut klicken. Dann sieht das<br />
Formular so aus:<br />
Da liegt er nun unser Button mit<br />
Name Button1. Ein Schaltknopf auf<br />
den man klicken kann.<br />
Auf der linken Seite der <strong>Delphi</strong>-Programmoberfläche gibt es ein<br />
sehr wichtiges Instrument: Den Projektinspektor!<br />
Hier können Sie alle „Eigenschaften“ (Properties) des Buttons<br />
einstellen. Ein Beispiel: Wenn man unter der Eigenschaft<br />
Caption den Text „Hier drücken!“ schreibt, so sieht der<br />
Schaltknopf so aus:<br />
Wer nun noch die Schrift verändern will,<br />
stellt diese unter der Eigenschaft Fonts<br />
ein.<br />
Frage: Was ist der Unterschied zwischen den Eigenschaften<br />
Caption <strong>und</strong> Name?<br />
Bevor man weiter arbeitet sollte man unbedingt das Projekt<br />
speichern. Speichern Sie den bisherigen Stand in einem<br />
Ordner namens 03_HalloWelt. (Wie das geht ist zwei Seiten<br />
weiter oben gezeigt!)<br />
Dann drücken wir den<br />
grünen Pfeil, um das<br />
Progrämmchen<br />
kompilieren zu<br />
lassen. Nun bekommt<br />
man eine exe-Datei,<br />
die geöffnet wie links<br />
dargestellt aussieht.<br />
Leider kann man auf den Button drücken sooft man will, - es<br />
passiert einfach nichts!<br />
Und das liegt daran, dass wir dem<br />
Button noch kein Onclick –<br />
„Ereignis“ mitgegeben haben.<br />
Schauen Sie sich nochmal den<br />
132
Objektinspektor an: Hier gibt es auch einen Tab „Events“. Leider steht hier noch<br />
nichts. Das werden wir sofort ändern:<br />
Gehen Sie zurück in den Programmier-Modus <strong>und</strong> führen Sie einen Doppelklick auf<br />
dem Button aus.<br />
Jetzt passiert zweierlei:<br />
1. Es gibt einen Eintrag unter Events :<br />
Da steht das Ereignis „Button1Click“.<br />
Ist doch w<strong>und</strong>erbar, diese Automatik!<br />
2. In Unit1 erscheint wie von Zauberhand ein Zusatz:<br />
procedure TForm1.Button1Click(Sender: TObject);<br />
begin<br />
end;<br />
Und zwischen begin <strong>und</strong> end schreiben wir den Auftrag, dem wir dem Programm<br />
geben wollen:<br />
Showmessage(‚Hallo Welt!);<br />
Dann noch alles speicher mit<br />
Zu guter Letzt kompilieren <strong>und</strong> das Programm sollte die Welt grüßen:<br />
Somit haben Sie Ihr erstes <strong>Delphi</strong>-Programm geschreiben!<br />
Aber haben Sie es auch verstanden? Was bedeutet beispielsweise<br />
procedure TForm1.Button1Click(Sender: TObject); ?<br />
Auch wenn das Thema „Objektorientierte Programmierung“ erst später behandelt<br />
werden wird, so sollten Sie dennoch den Hintergr<strong>und</strong> für diese Schreibweise kennen:<br />
• „procedure“ ist klar, oder? Wenn nicht: Es soll heißen, dass in den folgenden<br />
Zeilen zwischen begin <strong>und</strong> end ein Programm bzw Unterprogramm<br />
ausgeführt werden soll. Wie Sie gelernt haben, wird die procedure von einem<br />
Ereignis ausgelöst werden (In diesem Fall dem Knopfdruck).<br />
• „TForm1“ ist ein Objekt. Dieses hat, wie wir oben dargelegt haben, bestimmte<br />
Eigenschaften, Methoden <strong>und</strong> Ereignisse.<br />
• „TForm1.Button1Click“ besagt, dass das Ereignis Button1Click des Buttons1<br />
dem Objekt TForm1 zugeordnet ist.<br />
133
• „Sender: TObject“ soll klarstellen, dass die aufrufende Instanz ein Objekt, in<br />
diesem Fall Button1 ist.<br />
Denken Sie jetzt kurz darüber nach, wie Sie bei der Programmierung vorgegangen<br />
sind! Danach lesen Sie die folgenden Zeilen:<br />
Erkenntnisse bezüglich der Windowsprogrammierung:<br />
• Man beginnt die Programmierung mit dem Entwurf einer visuellen Oberfläche.<br />
• Wenn alle Objekte auf der Oberfläche untergebracht sind, müssen diesen ihre<br />
Eigenschaften, die von den voreingestellten Werten abweichen, zugewiesen<br />
werden.<br />
• Die Objekte werden mit Ereignissen verknüpft.<br />
• Jetzt erst wird im alten Sinn „programmiert“, in dem man in die Unit mittels<br />
Pascal-Code die durchzuführenden Methoden schreibt.<br />
Diese Erkenntnisse gelten selbstverständlich auch für <strong>Visual</strong> <strong>C#</strong> oder für <strong>Visual</strong><br />
Basic.<br />
Vergleichen Sie diese Methode beispielsweise mit dem nicht-grafischen Java <strong>und</strong> Sie<br />
verstehen sofort, weshalb sich diese Programmiersprachen großer Beliebtheit<br />
erfreuen!<br />
Sehen wir uns diese Eigenschaft / Ereignis / Methode - Charakterisierung am Beipiel<br />
eines Schaltknopfes nochmals an:<br />
Objekttyp TButton (Schaltflächen-Komponente)<br />
Eigenschaften<br />
Caption<br />
Name<br />
Width<br />
Ereignisse<br />
OnClick<br />
OnExit<br />
Methoden<br />
Hide<br />
SetFocus<br />
Click<br />
Text für die Aufschrift des Buttons<br />
Name des Objektes<br />
Länge des Buttons in Pixel<br />
usw.<br />
Das Ereigniss wird ausgelöst, wenn man mit der linken<br />
Maustaste auf den Button klickt.<br />
Das Ereignis wird ausgelöst, wenn die Komponente<br />
verlassen wird.<br />
usw.<br />
Versteckt den Button<br />
Der Fokus wird auf den Button gesetzt<br />
Simuliert einen Mausklick<br />
usw.<br />
134
Wie bereits oben erwähnt, können Sie diese Informationen stets mit der F 1 -Taste<br />
abrufen.<br />
Aufabe 1<br />
Öffnen Sie <strong>Delphi</strong>. Identifizieren Sie die unten beschriebenen Teile der Oberfläche:<br />
• ein Hauptfenster mit Menüleiste, Symbolleiste <strong>und</strong> Komponentenpalette.<br />
Hier finden Sie die vorgefertigten <strong>Delphi</strong>-Komponenten wie z.B. Buttons, Radio-<br />
Buttons usw.<br />
• ein Hauptformular für die zu schreibende Anwendung, in dem Komponenten wie<br />
z.B. Buttons eingefügt werden.<br />
• ein Objektinspektor, mit dessen Hilfe die Eigenschaften <strong>und</strong> Ereignisse einer<br />
Komponente festgelegt werden.<br />
• ein Quelltexteditor, in welchem der Programmcode bearbeitet wird.<br />
Bevor man nun ein etwas anspruchsvolleres Programm, wie „Hallo Welt“ schreiben<br />
will, sollte man, wie bei Java <strong>und</strong> PHP auch, die wichtigsten Datentypen kennen. Wie<br />
so oft ist ein Blick zu Wikipedia sehr aufschlussreich:<br />
Elementare Datentypen<br />
Name Größe Wertebereich Beschreibung<br />
Boolean 1 Byte true oder false boolescher Wert<br />
Byte 1 Byte 0 bis 255<br />
Word 2 Byte 0 bis 65535<br />
Cardinal 4 Byte 0 bis 4.294.967.295<br />
ShortInt 1 Byte −128 bis 127<br />
SmallInt 2 Byte −32.768 bis 32.767<br />
LongInt<br />
4 Byte −2 31 bis 2 31 −1<br />
vorzeichenlose 8-Bit-<br />
Ganzzahl<br />
vorzeichenlose 16-Bit-<br />
Ganzzahl<br />
vorzeichenlose 32-Bit-<br />
Ganzzahl<br />
vorzeichenbehaftete 8-Bit-<br />
Ganzzahl<br />
vorzeichenbehaftete 16-Bit-<br />
Ganzzahl<br />
vorzeichenbehaftete 32-Bit-<br />
Ganzzahl<br />
Int64 8 Byte −2 63 bis 2 63 −1<br />
vorzeichenbehaftete 64-Bit-<br />
Ganzzahl<br />
Real48 6 Byte 2,9·10 −39 bis 1,7·10 38 48-Bit-Gleitkommazahl<br />
Single 4 Byte 1,5·10 −45 bis 3,4·10 38 32-Bit-Gleitkommazahl (IEEE<br />
754-float)<br />
Double 8 Byte 5,0·10 −324 bis 1,7·10 308 64-Bit-Gleitkommazahl (IEEE<br />
754-double)<br />
Extended 10 Byte 3,6·10 −4951 bis 1,1·10 4932 80-Bit-Gleitkommazahl<br />
Comp 8 Byte −2 63 bis 2 63 −1 vorzeichenbehaftete 64-Bit-<br />
135
Currency<br />
8 Byte<br />
Char 1 Byte #0 bis #255<br />
WideChar 2 Byte #0 bis #65535<br />
bis 256<br />
ShortString<br />
Byte<br />
AnsiString bis 2<br />
GByte<br />
WideString bis 2<br />
GByte<br />
−922.337.203.685.477,5808 bis<br />
922.337.203.685.477,5807<br />
Aneinanderreihung von bis zu<br />
255 Chars<br />
Aneinanderreihung von bis zu 2 31<br />
Chars<br />
Aneinanderreihung von bis zu 2 30 WideChars<br />
Ganzzahl, mit der über die<br />
FPU gerechnet wird<br />
vorzeichenbehaftete 64-Bit-<br />
Festkommazahl<br />
8-Bit-Zeichen, z. B. ASCII-<br />
/ANSI-Zeichen<br />
16-Bit-Zeichen, z. B. Unicode-<br />
Zeichen<br />
Der Datentyp Real entspricht in <strong>Delphi</strong> standardmäßig dem Double.<br />
Der Datentyp Integer hängt von der jeweiligen Pascal-Implementierung ab. In 16-Bit-<br />
Implementierungen (z. B. Turbo Pascal) entsprach er einem SmallInt, in 32-Bit-<br />
Implementierungen einem LongInt <strong>und</strong> in 64-Bit-Implementierungen wird er einem<br />
Int64 entsprechen.<br />
Viele Variablen-Bezeichnungen kennen Sie schon von Java <strong>und</strong> PHP. Dort war die<br />
Art der verwendeten Variablen nicht all zu wichtig. Man konnte zum Beispiel<br />
ungestraft string mit integer mulitplizieren. Ist das in <strong>Delphi</strong> auch so?<br />
Aufgabe 2<br />
Erzeugen Sie einen Ordner 04_Multiplikation.<br />
Stellen Sie mit <strong>Delphi</strong> etwa diese Oberfläche her <strong>und</strong> speichern Sie alles im Ordner<br />
04_Multiplikation<br />
ab<br />
Jetzt ein Doppelklick auf „Berechnen“. Schreiben Sie folgender Programmcode in<br />
den sich öffnenden procedure-Rumpf:<br />
procedure TForm1.Button1Click(Sender: TObject);<br />
var x,y,Ergebnis: double;<br />
136
egin<br />
x:=strtofloat(Edit1.Text); y:=strtofloat(edit2.Text);<br />
Ergebnis:=x*y;<br />
edit3.text:=floattostr(Ergebnis);<br />
end;<br />
Die fett gedruckten Teile hat <strong>Delphi</strong> selbst geschrieben.<br />
strtofloat ist eine Methode, die einen übergebene Stringvariable in eine Gleitkomma-<br />
Variable umwandelt. Die Methode ist hier unverzichtbar, da alle Einträge in Editfelder<br />
Stringvariable sind. Und mit denen multipliziert es sich etwas schlecht...<br />
Was bedeuten die verschiedenen Zeilen? Was tut floattostr <strong>und</strong> wozu wird die<br />
Methode gebraucht?<br />
Überprüfen Sie, ob folgende für Multiplikation in PHP <strong>und</strong> Java erlaubte<br />
Variablendefinition (x <strong>und</strong> y) auch in <strong>Delphi</strong> zugelassen ist, wenn man beide Variable<br />
durch eine Rechenoperation verknüpft:<br />
var x, Ergebnis: double; y:integer;<br />
Erweitern Sie das Programm für weitere Rechenoperationen. (Taschenrechner). Die<br />
Zeichen für die Rechenoperationen unterscheiden sich nicht wesentlich von denen in<br />
Java.<br />
Zum Abschluss wieder unser „Universalproblem“ quadratische Gleichung lösen:<br />
Die Oberfläche erstellt man äußerst komfortabel mit der Maus: Einfach die<br />
gewünschten Komponenten in das Formular ziehen. So kann das Fenster aussehen:<br />
Man benötigt zwei<br />
Eingabe-Komponenten.<br />
Hier ist wie oben auch<br />
TEdit geeignet. Die<br />
Ausgabe-Komponenten<br />
sind hier ebenfalls<br />
Editfelder, könnten aber<br />
auch TLabel sein.<br />
Achten Sie auf gute<br />
Lesbarkeit <strong>und</strong><br />
Übersichtlichkeit! Eventuell<br />
die Eigenschaften Font<br />
<strong>und</strong> Color anpassen!<br />
Doppelklicken Sie auf die<br />
beiden Buttons <strong>und</strong> fügen<br />
Sie in den Programmrumpf<br />
zum Beispiel diesen Code ein:<br />
137
procedure TForm1.BerechneClick(Sender: TObject);<br />
var diskr, p, q :double;<br />
begin<br />
if (edit1.text = '') or (edit2.text = '') // leere Eingabe vermeiden<br />
then begin edit3.visible :=true; edit3.text:= 'Zunächst p <strong>und</strong> q angeben!' ; end<br />
else<br />
begin<br />
p:= strtofloat(edit1.text); q:= strtofloat(edit2.text);<br />
diskr:= p*p/4 - q;<br />
if diskr > 0 then //positive Diskriminante : zwei Lösungen<br />
begin<br />
edit3.Visible:= true; edit4.Visible:= true; //sonst sieht man nichts!<br />
label3.Visible:= true; label4.Visible:= true;<br />
edit3.Text:= FloatToStr(-p/2 + sqrt(diskr)); //erste Lösung<br />
edit4.Text:= FloatToStr(-p/2 - sqrt(diskr)); //zweite Lösung<br />
end<br />
else if diskr = 0 then //Diskriminante 0: genau eine Lösung<br />
begin<br />
edit3.Visible:= true; label3.Visible:= true;<br />
edit3.Text:= FloatToStr(-p/2);<br />
end<br />
else<br />
begin<br />
edit3.Visible:= true;<br />
edit3.Text:='Keine Lösung';<br />
end;<br />
end;<br />
end;<br />
Hier der zweite Button:<br />
procedure TForm1.NeueRechnungClick(Sender: TObject);<br />
begin<br />
edit1.Text:=''; edit2.Text:='';<br />
edit3.Visible:= false; edit4.Visible:= false;<br />
label3.Visible:= false; label4.Visible:= false;<br />
end;<br />
Der besseren Lesbarkeit wegen wurden für den Programmcode Farben verwendet.<br />
Dabei ist der fettgedruckte, schwarze Teil immer von <strong>Delphi</strong> selbst geschrieben.<br />
Aufgabe 3<br />
Versuchen Sie den Quellcode<br />
nachzuvollziehen <strong>und</strong> erstellen Sie<br />
das Programm. (Ordner<br />
05_quadratischeGleichung )<br />
Schreiben Sie danach, wie bei Java<br />
auch, eine Variante dieses<br />
138
Programms, bei der die andere Mitternachtsformel für<br />
ax 2 + bx + c = 0 gelöst wird!<br />
Lösung: x 1/2 = (-b +/- sqrt(d)) / (2a) wobei d = b 2 - 4ac<br />
Ordner:06_quadratischeGleichung2.<br />
Wie im letzten Kapitel auch wollen wir uns anhand eines Primzahlprogramms einige<br />
Schleifen in <strong>Delphi</strong> ansehen.<br />
Die Oberfläche ist schnell zusammengeklickt:<br />
Ein Doppelklick auf den Button <strong>und</strong> zum Beispiel folgenden Programmcode einfügen:<br />
(Nochmals zur Erinnerung: Die fett gedruckten Zeilen sind von <strong>Delphi</strong> geschrieben!)<br />
procedure TForm1.Button1Click(Sender: TObject);<br />
var zahl : int64; i,j : cardinal;<br />
begin<br />
zahl:= strtoint64(edit1.text);<br />
if zahl=1 then label1.caption:= 'Die Zahl ist keine Primzahl'<br />
else<br />
if zahl=2 then label1.caption:= 'Die Zahl ist eine Primzahl'<br />
else<br />
if zahl mod 2 = 0 then label1.caption:= 'Die Zahl ist keine Primzahl'<br />
else<br />
begin<br />
i:= 1; j:= 0;<br />
if zahl > 2 then<br />
repeat<br />
i:= i + 2; j:= j + 1;<br />
until (zahl mod i = 0) or (i > zahl div i);<br />
end;<br />
if i > zahl div i then label1.caption:= 'Die Zahl ist eine Primzahl'<br />
else label1.caption:= 'Die Zahl ist keine Primzahl';<br />
end;<br />
139
Es gibt natürlich mehrere Möglichkeiten in <strong>Delphi</strong>, eine Schleife zu programmieren.<br />
Oben haben wir es mit repeat / until versucht. Hier wird die Bedingung, ob die<br />
Schleife verlassen werden soll, erst nach dem Durchlauf geprüft.<br />
Genauer:<br />
Jede Iteration (Schleife) besteht aus einer Anweisungsfolge, die mehrfach ausgeführt<br />
werden kann <strong>und</strong> einer Bedingung, die<br />
• als Austrittsbedingung aus der Schleife<br />
oder<br />
• als Eintrittsbedingung für die Schleife dient.<br />
Struktogramm für eine Iterationen mit einer Austrittsbedingung<br />
( repeat....until)<br />
Struktogramm für eine Iterationen mit einer Eintrittsbedingung<br />
(while....do)<br />
Iteration mit Austrittsbedingung<br />
Syntax :<br />
repeat<br />
<br />
until <br />
Iteration mit Eintrittsbedingung<br />
Syntax :<br />
while do<br />
140
• Eine Anweisungsfolge muss bei der while-Schleife mit begin/end zu einem<br />
Anweisungsblock geklammert werden.<br />
• Eine repeat-Schleife wird mindestens einmal durchlaufen, eine while-Schleife<br />
muss nicht unbedingt durchlaufen werden.<br />
Iterationen mit einer festen Zahl von Wiederholungen<br />
Beispiel:<br />
for i:=1 to 10 do<br />
begin<br />
dZinsen:=dKapital*dZinssatz/100;<br />
dKapital:=dKapital+dZinsen;<br />
end;<br />
Struktogramm für eine Zählschleife:<br />
Gezählte Iteration (aufwärts)<br />
Syntax :<br />
for := to do<br />
<br />
Gezählte Iteration (abwärts)<br />
Syntax :<br />
for := downto do<br />
<br />
• Eine for-Schleife kann nur benutzt werden, wenn im Voraus die Anzahl der<br />
Schleifendurchläufe bekannt ist.<br />
• Eine Anweisungsfolge muss bei der for-Schleife mit begin/end zu einem<br />
Anweisungsblock geklammert werden.<br />
Aufgabe 4<br />
141
Erstelle einen Ordner namens 07_Primzahltest bis 10hoch18 <strong>und</strong> erstelle dort das<br />
Programm Primzahltest wie oben beschrieben.<br />
Aufgabe 5<br />
Um die anderen<br />
Schleifen<br />
kennenzulernen,<br />
versuchen Sie nun mit<br />
Hilfe der obigen<br />
Primfaktorbestimmung<br />
ein Programm zu<br />
schreiben, das eine<br />
gegebene ganze Zahl<br />
(bis 10 18 – also int64) in<br />
ihre Primfaktoren zerlegt.<br />
Die Oberfläche kann<br />
zum Beispiel so<br />
aussehen:<br />
Das Feld rechts heißt „Listbox“ <strong>und</strong> ist unter Standard zu finden.<br />
Will man die Zahl i auf der Listbox hinzufügen, so lässt sich das mit dieser Zeile<br />
erledigen:<br />
Listbox1.Items.Add(inttostr(i))<br />
Je nach Geschwindigkeit des Rechners kann die Zerlegung einige Zeit (1-2 Minuten)<br />
in Anspruch nehmen. Allerdings nur, wenn man eine sehr große Primzahl<br />
eingegeben hat.<br />
Sollte Ihnen das im Moment noch zu schwer sein, so können Sie den Programmcode<br />
im Tauschverzeichnis finden (08_Primfaktorzerlegung)….<br />
<strong>Delphi</strong> ganz ohne Optik<br />
Wie wir schon mehrfach erwähnt haben, ist<br />
der ganze optische „Krimskrams“ mit den<br />
vielen Automatismen mitunter eher eine<br />
Last denn eine Hilfe. Will man beispielsweise<br />
einen bestimmten mathematischen<br />
Algorithmus testen, dann wäre eine<br />
Konsole wie bei Java eigentlich viel besser.<br />
Kein Problem. Für die Puristen unter Ihnen<br />
wird folgender Tipp hilfreich sein:<br />
Öffnen Sie <strong>Delphi</strong>. Gehen Sie zu File / New<br />
/ Other:<br />
Hier wählen Sie Console Application.<br />
(siehe rechts!)<br />
142
Danach öffnet sich ein solches Fenster:<br />
Interessant ist, dass beispielsweise der Object TreeView <strong>und</strong> der Objectinspector<br />
leer bleiben. Ist ja klar: Wir programmieren eine Konsolenanwendung! Was soll man<br />
da mit Buttons, Edits etc anfangen?!<br />
Aufgabe 6<br />
Erstellen Sie einen Ordner (09_<strong>Delphi</strong>konsole) <strong>und</strong> ergänzen Sie mit dem Editor wie<br />
unten angegeben:<br />
143
Speichern Sie das Projekt unter dem Namen „Hallo“. (Dann wird der Name bei<br />
program automatisch angepasst!)<br />
Und nun das Programm<br />
kompilieren!<br />
Kommt Ihnen das bekannt<br />
vor??<br />
Wenn ja, dann schreiben Sie<br />
doch in <strong>Delphi</strong> eine<br />
Konsolenanwendung für das<br />
Addieren zweier Zahlen<br />
oder, wenn Sie höhere Ziele<br />
haben, wie wäre es mit<br />
einem Konsolenprogramm<br />
für den Primzahltest...????<br />
Zur Hilfe ist nebenstehend der<br />
Pascal-Quellcode für ein<br />
Additionsprogramm angegeben.<br />
Die Ähnlichkeit zu Java <strong>und</strong> PHP<br />
fällt Ihnen hoffentlich auf!<br />
Noch eine abschließende Frage<br />
hier zu: Weshalb steht einige<br />
Zeilen weiter oben „Pascal-“ <strong>und</strong><br />
nicht „<strong>Delphi</strong>-Quellcode“?<br />
Wir arbeiten doch mit <strong>Delphi</strong>?!<br />
<strong>Delphi</strong> entwanzen<br />
Zu einer guten Programmiersprache gehört ein ausgezeichneter Debugger. Denn,<br />
machen Sie sich keine Illusionen, ca. 50% der Programmierzeit ist debug-Zeit! Was<br />
genau ist ein Debugger? Schlagen wir nach bei Wikipedia:<br />
Ein Debugger (von engl. bug) ist ein Werkzeug zum Auffinden, Diagnostizieren <strong>und</strong><br />
Beheben von Fehlern in Hardware <strong>und</strong> Software. Ein Debugger ermöglicht in der<br />
Regel eine Ablaufverfolgung des zu untersuchenden Programmes in einzelnen<br />
Schritten oder zwischen definierten Haltepunkten (Breakpoints). Ist ein Programm auf<br />
diese Weise angehalten, kann der Entwickler die Inhalte von Prozessorregistern <strong>und</strong><br />
Variablen einsehen, verändern oder sich den Verlauf der Funktionsaufrufe bis zum<br />
Breakpoint ansehen (callstack). Moderne Debugger (bei kompilierten Sprachen, z.B.<br />
C/C++) haben die Möglichkeit, Änderungen am Quelltext on the fly zu übersetzen<br />
144
<strong>und</strong> mit diesen Änderungen die Programmausführung fortzusetzen. Diese Technik<br />
wird auch als just in time debugging bezeichnet.<br />
Klingt gut! So gut, dass wir uns gleich weiter unten mit dieser Technik in <strong>Delphi</strong><br />
auseinandersetzen werden. Aber zuvor noch eine Warnung: Ein Debugger findet<br />
(prinzipiell) nicht alle Fehler.<br />
Dies wirft die Frage auf: Welche Fehlerarten gibt es denn? Und welche kann der<br />
Debugger finden, welche aber nicht?<br />
Hier eine Aufzählung:<br />
Syntaxfehler<br />
Fehler dieser Art treten während der Compilierung des Programmcodes auf, wenn<br />
gegen die Syntaxregeln von Objekt-Pascal verstoßen wird. <strong>Delphi</strong> stoppt die<br />
Compilierung nach dem ersten Fehler (oft erst in der Zeile danach), hebt die<br />
entsprechende Zeile farblich hervor <strong>und</strong> gibt eine entsprechende Fehlermeldung in<br />
der Statuszeile aus. Der eigentliche Fehler kann sich jedoch an einer anderen Stelle<br />
im Programmcode befinden. Ein konkretes Beispiel, das Ihnen vermutlich sehr<br />
bekannt vorkommt:<br />
(Der obige Screenshot ist aus unserem Primzahlprogramm)<br />
Beispiele für Syntaxfehler:<br />
• Als Bezeichner werden reservierte Wörter (z. B. var, begin, end, procedure, etc.)<br />
benutzt.<br />
• Es werden Sonderzeichen vergessen (z. B. Semikolon, Kommata, etc.)<br />
• Reservierte Wörter werden falsch geschrieben<br />
• Unzulässige Operationen bei gewissen Dateitypen (zB.:. sText := 'Hallo' * 'Welt';<br />
ist nicht zulässig);<br />
145
Laufzeitfehler<br />
Diese Fehler treten nicht während der Compilierung, sondern während der<br />
Ausführung der Anwendung auf, wenn das Programm zwar gültige Anweisungen<br />
enthält, diese Anweisungen bei ihrer Ausführung aber Fehler verursachen. Das<br />
Betriebssystem stellt Laufzeitfehler fest <strong>und</strong> bricht dann die Programmausführung ab.<br />
Erkennen Sie den Fehler? (Variation des Programms „Multiplikation“)<br />
Übrigens: <strong>Delphi</strong> reagiert bei Division mit Null nicht immer mit einem Laufzeitfehler!<br />
Das können Sie leicht selbst testen. Ändern Sie den Quelltext wie folgt ab:<br />
(Die Eingabefelder sind hier unnötig <strong>und</strong> daher gelöscht)<br />
Typische Beispiele für Laufzeitfehler sind:<br />
• Division durch 0<br />
• Öffnen einer Datei, die gar nicht exisitiert<br />
• Fehlerhafte Speicherreservierung<br />
146
Logische Fehler<br />
Diese Art von Fehler wird vom Compiler nicht wahrgenommen. Es sei denn, der<br />
logische Fehler führt zu einem Laufzeitfehler.<br />
Ein einfaches Beispiel:<br />
Will man die natürlichen Zahlen von 1 bis N addieren, so benötigt man eigentlich<br />
keine Schleife, denn es gibt dafür eine leicht herzuleitende Formel: N*(N+1)/2<br />
Ist etwa N=5 so errechnet man mit der Formel: 1+2+3+4+5 = 5*6/2=15<br />
Will man dennoch die Formel durch eine Schleife überprüfen, so könnte Quelltext<br />
<strong>und</strong> Formular so aussehen:<br />
Der Compiler verrichtet seine Arbeit klaglos, beim Klicken auf den Button „Berechne“<br />
scheint sich der Rechner aber „aufzuhängen“. (Unterprechen kann man den Vorgang<br />
durch Run / Program Reset )<br />
Wo steckt der Fehler?<br />
Die Meisten werden es sofort sehen: An der while-Schleife stimmt etwas nicht.<br />
Um den Debugger ins Spiel zu bekommen, spielen wir jedoch zunächst den<br />
Ahnungslosen ( was sicher Einige erfreuen wird ;-) )<br />
147
Mit Hilfe eines Debuggers kann man nämlich<br />
überprüfen, was genau mit den Variablen<br />
passiert. Dazu muss man lediglich einen<br />
Haltepunkt im Quelltext platzieren, ab dem<br />
dann das Programm in Einzelschritten<br />
kontrolliert weiterlaufen soll. Den blauen Punkt<br />
links an der betreffenden Zeile anklicken <strong>und</strong><br />
fertig!<br />
Auswerten der Variableninhalte<br />
Startet man das Programm, so wird es an dem Haltepunkt gestoppt. Nun können<br />
Variableninhalte überprüft werden, indem man mit der Schaltfläche oder mit F7<br />
den nächsten Schritt durchführen lässt. Zuvor sollten Sie allerdings mit Strg+F7 das<br />
Evaluate/Modify-Fenster starten. Dort tragen Sie in der ersten Zeile die zu<br />
untersuchende Variable namens E ein.<br />
Nach jedem Schleifendurchlauf drücken Sie nun auf Evaluate. Dabei werden Sie<br />
bemerken, dass sich E überhaupt nicht verändert.<br />
Vermutlich ist Ihnen spätestens jetzt klar, dass die Schleifenvarible i immer gleich<br />
bleibt. Lösung: i müsste eigentlich immer um 1 größer werden, daher i:=i+1;<br />
einfügen.<br />
Tipp:<br />
Will man mehrere Variable gleichzeitig überwachen, so wählt man besser das Watch<br />
List-Fenster. Und das geht so:<br />
148
Mit Strg+F5 das Watch<br />
List-Fenster starten.<br />
Gleichzeitig erscheint dann<br />
ein zweites Fenster<br />
(Watch Properties) in das<br />
Sie alle zu überprüfenden<br />
Variablennamen eintragen<br />
können.<br />
(Siehe Bild!)<br />
Hier sieht man direkt, dass sich i nicht ändert.<br />
Aufgabe 7<br />
Schreiben Sie das Programm 12_Summenformel <strong>und</strong> testen Sie den Debugger wie<br />
oben gezeigt. (Natürlich können Sie auch ein eigenes Programm, dass nicht recht<br />
laufen will, für den Test verwenden!)<br />
149
<strong>Visual</strong> <strong>C#</strong> 2005 ist .NET<br />
Weshalb nun noch eine zweite visuelle Windows- Programmiersprache, wenn <strong>Delphi</strong><br />
doch weitgehend zufriedenstellend funktioniert?<br />
Dafür gibt es mehrere Gründe:<br />
• Auch hier soll, wie im letzten Kapitel erkannt werden, dass sich die beiden<br />
Sprachen nicht wesentlich unterscheiden. Kennt man Eine, so ist die Andere<br />
auch kein Problem.<br />
• Wir arbeiten in der Schule im Moment mit <strong>Delphi</strong> 7. Ab <strong>Delphi</strong> 8 wird die<br />
überaus praktische Microsoft Plattform .NET („Dot-Net“) unterstützt. (Dazu<br />
gleich mehr.) Leider hat Borland ab dieser Version für Mehrplatz-Linzenzen<br />
die Einrichtung eines Lizenzen-Servers gefordert. Weil der sehr umständlich<br />
einzurichten ist <strong>und</strong> weil zudem der Preis für eine Schullizenz nicht gerade ein<br />
Schnäppchen genannt werden kann, verzichten die meisten Schulen<br />
zugunsten von <strong>Visual</strong> <strong>C#</strong> oder <strong>Visual</strong> C++. Microsoft verschenkt die Beiden in<br />
der Express-Version. Diese ist absolut ausreichend für den Unterricht <strong>und</strong><br />
kann zudem .NET.<br />
• Vielleicht gefällt manchen <strong>C#</strong> besser während die Anderen eher <strong>Delphi</strong><br />
bevorzugen. Lernt man beide kennen, so kann jeder selbst urteilen!<br />
• Das Hilfe-System mit IntelliSens <strong>und</strong> Onlinehilfe ist deutlich besser, als bei<br />
<strong>Delphi</strong> 7.<br />
(Zum zweiten Punkt eine kurze Bemerkung:<br />
Schon einmal hat Microsoft etwas verschenkt. Das MS-DOS-Betriebssystem! Die<br />
Folgen sind bekannt: Nun zahlen 90% der Computer-Käufer für viel Geld ein<br />
Betriebssystem Vista, das mit den schon gekauften <strong>und</strong> völlig zufriedenstellenden<br />
Programmen aus der XP-Zeit hinten <strong>und</strong> vorne nicht funktioniert <strong>und</strong>, wie wenn das<br />
nicht reichen würde, auch noch die Rechte des Benutzers erheblich einschränkt.<br />
Linux <strong>und</strong> die Anderen helfen leider nur bedingt. Man würde den Schritt ja gerne<br />
wagen, wenn man sich nicht so sehr an Windows, das allseits kompatible<br />
Betriebssystem, gewöhnt hätte! Daher bleibt die Konsequenz: Hier hat Borland ein<br />
klassisches Eigentor geschossen……)<br />
.NET Framework (Gerüst)<br />
Was genau ist das .NET Framework?<br />
Anfang 2000, als Microsoft .NET der erstaunten Öffentlichkeit vorstellte, wusste<br />
vermutlich nicht einmal Bill Gates selbst, was genau man unter .NET verstehen soll!<br />
Vielleicht haben Sie schon einmal vom Begriff COM (Component Object Model) im<br />
Zusammenhang mit Windowsprogrammierung gelesen oder gehört.<br />
Es ist eine inzwischen veraltete Microsoft- proprietäre Plattform, die ein Interface<br />
150
(Schnittstelle) anbietet, mit der die Programmierer auf die Fähigkeiten des jeweiligen<br />
COM-Objekts zugreifen können. Diese Plattform wurde von der .NET-Plattform<br />
abgelöst.<br />
Die Ablösung war nötig, weil das plattformunabhängige Java mit seiner VM (Virtual<br />
Maschine) für fast alle Hochsprachen eine Schnittstellen für eine große Anzahl<br />
fertiger Objekte anbot, die die Arbeit des Programmierers erheblich vereinfachte.<br />
Darauf musste Microsoft reagieren. Java drohte nicht nur den Computer, sondern<br />
auch den inzwischen stark gewachsenen Mark der Kleingeräte zu erobern. Gerade<br />
im letzten Bereich war Microsoft so gut wie nicht vertreten!<br />
Außerdem war die gängige Microsoft-Sprache <strong>Visual</strong> Basic 6 den gewachsenen<br />
Anforderungen nicht gewachsen. Wie sollte sie auch!? VB6 war ja nicht dafür<br />
konzipiert worden Probleme zu lösen, von deren Existenz man zur Entwicklungszeit<br />
noch gar nicht wusste!<br />
Natürlich kann man meist auch mit hinreichend komplizierten Tricks ältere<br />
Programmiersprachen an aktuelle Probleme anpassen. Je länger man sich so behilft,<br />
desto komplizierter wird das Prozedere. Irgendwann ist dann der Punkt gekommen,<br />
an dem man sich eine angepasste Programmiersprache wünscht. Microsoft muss<br />
wohl schon mitte der 90-er Jahre mit der Entwicklung begonnen haben. Denn was<br />
mit .NET <strong>und</strong> <strong>C#</strong> das Licht der Welt erblickte, war eine sehr ausgereifte<br />
Klassenbibliothek mit einer geradezu unglaublichen Anzahl an Funktionen.<br />
Im Anfangstadium der Entwicklung allerdings versuchte Microsoft das von der Firma<br />
SUN entwickelte Java zu imitieren. Das war nun gar nicht lustig, denn so begann<br />
Java seine Plattform-unabhängigkeit zu verlieren. (Die Firma SUN strengt<br />
diesbezüglich auch erfolgreich die Gerichte an).<br />
Also holte sich Microsoft die weltbesten Fachleute <strong>und</strong> ließen sie ein eigenes,<br />
weitgehend plattformunabhängiges Objektmodell entwickeln, das den neuen<br />
Anforderungen der Programmierergemeinde stand halten sollte.<br />
Einen dieser Fachleute kennen Sie: Anders Hejlsberg, den Entwickler von Turbo-<br />
Pascal!!! Er schrieb nun die speziell für .NET konzipierte Sprache <strong>C#</strong>. Was für ein<br />
Genie!<br />
Nun dürfen Sie raten: Welchen Sprachen ähnelt <strong>C#</strong> nicht nur auf den ersten Blick?<br />
Hejlsberg sei Dank: <strong>Delphi</strong> <strong>und</strong> Java! W<strong>und</strong>ert sich da noch jemand?<br />
Der Vorwurf, <strong>C#</strong> mit .NET sei bei Java abgekupfert, kann nicht aufrecht erhalten<br />
werden. Zu groß ist die Fülle der Klassenbibliotheken bei <strong>C#</strong>. Davon kann Java nur<br />
träumen! (Seit JDK 5 kann man mitunter eher den gegenteiligen Eindruck<br />
bekommen, dass Java bei <strong>C#</strong> abgekupfert hat…..)<br />
Für das Verständnis ist wichtig, dass die .NET-Plattform mit ihrer CLI (Common<br />
Language Infrastructure) nun ebenfalls eine Schnittstelle für die wichtigsten<br />
Programmiersprachen darstellt. Wie bei Java wird dies durch Verwendung einer<br />
virtuelle Maschine <strong>und</strong> der BCL (Base Class Library = gemeinsame Klassenbiliothek)<br />
erreicht. Demnächst kommt .NET in der 3. Version heraus <strong>und</strong> die Programmierer<br />
wenden sich wieder Microsoft zu, die ihre Programmsprachen ja teilweise<br />
verschenken. Aber das haben wir ja schon eine Seite weiter oben bemerkt….)<br />
Fassen wir zusammen:<br />
151
Das .NET Framework ist gekennzeichnet durch:<br />
• Konsequente Objektorientierung (im Gegensatz zu <strong>Delphi</strong>!)<br />
• Plattformunabhängiges Softwarekomponentenmodell mit Laufzeitumgebung<br />
<strong>und</strong> Klassenbibliothek<br />
• Integration einer (transparenten) Verteilungsplattform<br />
• Unabhängigkeit von einer Programmiersprache<br />
• Weit mehr als 10 000 Datentypten (von denen Sie allenfalls 50 brauchen!)<br />
Aufgabe 8<br />
Lesen Sie sich den ausgezeichneten Artikel von Michael Stal (2001) zu .NET <strong>und</strong> <strong>C#</strong><br />
durch. Lassen Sie sich nicht entmutigen, wenn Sie nicht alles auf Anhieb verstehen!<br />
Einen groben Überblick gekommen Sie durch die Lektüre in jedem Fall:<br />
http://www.heise.de/ix/artikel/2001/12/122/<br />
Da wir Kapitel 5 „Objekt-Orientierte Programmierung“ außer mit <strong>Delphi</strong> <strong>und</strong> Java an<br />
geeigneter Stelle auch mit <strong>Visual</strong> <strong>C#</strong> durchführen, werden Sie auch später noch mit<br />
.NET zu tun haben. Daher ist es kein Schaden, wenn Sie sich hier schon mit einer<br />
Besonderheit vertraut machen:<br />
Das Sicherheitskonzept von .NET ist sehr restriktiv. So es es zum Beispiel ohne die<br />
Voreinstellungen zu ändern, nicht möglich, eine erstellte Release (exe-Datei) von<br />
einem Netzlaufwerk aus durch Doppelklick zu starten. Daher der Tipp:<br />
Arbeiten Sie in <strong>C#</strong> auf Laufwerk D:/ !!!<br />
So finden Sie heraus welche Version<br />
von .NET Framework auf einem<br />
Windows XP System installiert ist:<br />
• Klicken Sie auf Start, auf<br />
Einstellungen <strong>und</strong> anschließend<br />
auf Systemsteuerung.<br />
• Doppelklicken Sie in der<br />
klassischen Ansicht auf<br />
Verwaltung.<br />
Wenn Sie nach der anstrengenden Arbeit mal wieder so richtig lachen wollen, dann<br />
klicken Sie folgenden Link an:<br />
http://www.nickles.de/c/n/5645.htm<br />
152
<strong>Visual</strong> <strong>C#</strong> 2005<br />
Wenn man <strong>C#</strong> öffnet, sieht man eine „Begrüßungsseite“, die den unerfahrenen<br />
Programmierer zunächst überfordert:<br />
„Erste Schritte“ werden angezeigt, Neuigkeiten von Entwicklern von <strong>C#</strong> gilt es zu<br />
bestaunen <strong>und</strong> schließlich <strong>und</strong> endlich soll man auch noch ein Feedback geben.<br />
Lassen Sie die großen Fenster links liegen <strong>und</strong> wählen Sie statt dessen Datei /<br />
Neues Projekt.<br />
Damit am Anfang nicht zu viele Informationen auf Sie prasseln, wollen wir uns<br />
zunächst mit einer Konsolenanwendung begnügen.<br />
Geben Sie, wie hier im Bild auch, als Name HalloConsole1 ein.<br />
Der Editor für den Quelltext ist<br />
links zu sehen.<br />
Auf der rechten Seite erkennt<br />
man den Projektmappen-<br />
Explorer:<br />
153
Für ein Konsolenprogramm, bei dem bisher schlicht nichts passiert, ist das schon<br />
eine Menge Information. Noch mehr wird es bei den Windows-Anwendungen.<br />
Wählen Sie nun Datei / HalloConsole1 speichern unter <strong>und</strong> geben Sie einen Ordner<br />
auf D: oder Ihrem USB-Stick an.<br />
Schauen Sie sich danach die Dateien an, in denen eigentlich „nichts“ gespeichert ist!<br />
Speichert man nicht ab, dann befinden sich die im Projektmappen-Explorer<br />
angezeigten Dateien nur im RAM (Hauptspeicher), sind also lediglich temporär.<br />
Die auch schon im Projektmappen-Explorer erkennbare relativ komplexe Hierarchie<br />
muss Sie nicht interessieren. Sie ist größtenteils nur für die IDE da.......<br />
Die entscheidende Projektdatei hat die Endung .sln<br />
Wenn man auf sie doppeltklickt, wird das Projekt in <strong>C#</strong> geöffnet, ähnlich wie bei der<br />
.dpr-Datei in <strong>Delphi</strong>.<br />
Der Quelltext kommt in die<br />
Program.cs-Datei (entspricht der<br />
.pas-Datei = Unit in <strong>Delphi</strong>). Diese<br />
kann man auch mit dem normalen<br />
Windows-Editor öffnen.<br />
Probieren Sie es aus!<br />
Wo kommt eigentlich der eigene<br />
Quelltext hin?<br />
Richtig! Hier<br />
dazwischen!<br />
Schließen Sie den Windows-Editor noch nicht. Denn Sie brauchen Ihn für die<br />
folgende<br />
Aufgabe 9<br />
Damit das Programm HalloConsole1 auch etwas tut, schreiben Sie folgenden<br />
Programmcode zwischen die geschweiften Klammern.<br />
string name;<br />
Console.WriteLine("Wie heißen Sie?");<br />
name = Console.ReadLine();<br />
Console.WriteLine("Hallo, " + name + "!");<br />
Einmal machen Sie das mit dem Windows-Editor <strong>und</strong> dann mit dem <strong>C#</strong> -Editor.<br />
Wichtig für diese Übung ist, dass sie es selbst eintippen – <strong>und</strong> nicht etwa mit copy<br />
<strong>und</strong> paste ans Werk gehen!<br />
Was fällt Ihnen auf?<br />
Die Hilfe in <strong>Visual</strong> <strong>C#</strong> 2005 ist fast schon perfekt zu nennen. Auch hier ein Beispiel:<br />
Angenommen, Sie wollen einen Kommentar in den Quelltext schreiben <strong>und</strong> wissen<br />
nicht wie das bei <strong>C#</strong> funktioniert.<br />
Wählen Sie Hilfe / suchen <strong>und</strong> geben Sie in die Suchzeile Kommentar <strong>C#</strong> ein.<br />
154
Zusätzlich lässt sich die Trefferliste geschickt durch so genannte Filter verkleinen.<br />
Man erkennt sofort, dass es nicht eine Hifle gibt. Vielmehr werden mehrere Quellen<br />
angeboten! (Siehe nächstes Bild rechts). Besonders fällt die sehr ausführliche<br />
deutsche Online-Hilfe auf! Bereits hier sollte sich alles selbst für fortgeschrittene<br />
Programmierer finden lassen.<br />
Links im Bild unten ist ein ausgewähltes Ergebnis zu sehen.<br />
Einfacher geht wirklich nicht!<br />
Ausgesprochen hilfreich ist die bereits erwähnte IntelliSens .<br />
In Aufgabe 9 konnten Sie testen, wie komfortabel die<br />
Eingaben für den Quellcode dadurch werden.<br />
Man muss meist nur ein bis zwei Buchstaben tippen, dann<br />
hilft einem IntelliSens weiter.<br />
Aber damit ist es nicht getan. Die gegebene Hilfe ist auch<br />
kontext-sensitiv, was nichts anderes heißt, dass von den<br />
vielen tausend Möglichkeiten mit .NET nur die sinnvoll<br />
Möglichen gezeigt werden.<br />
Mehr noch: In einem kleinen gelben Fenster werden<br />
Erläuterungen zum gewählten Begriff angezeigt!<br />
Im obigen Beispiel wurden nur die Buchstaben Co für<br />
Console eingegeben.<br />
Wählt man diese Option durch die Enter-Taste <strong>und</strong> gibt danach einen Punkt gefolgt<br />
von den Buchstaben Wr ein, so wird eine weitere sehr wichtige Hilfe sichtbar:<br />
155
Die gewünschte Funktion WriteLine besitzt eine Parameter-Liste. Das bedeutet, dass<br />
der Funktion Werte übergeben werden <strong>und</strong> / oder dass sie welche erzeugt. Daher<br />
wird bei Wahl der Option WriteLine gleich eine Klammer für die Parameter<br />
mitgeliefert: WriteLine()<br />
Im kleinen gelben Fenster werden die Arten der möglichen Parameter ebenfalls<br />
angezeigt.<br />
Wenn, wie im Bild unten, von 18 Überladungen geschrieben wird, so heißt dies<br />
lediglich, dass von dieser Funktion 18 Varianten gibt, die den selben Namen haben,<br />
sich aber durch Anzahl <strong>und</strong> Art der Parameter unterscheiden.<br />
Gehen wir nun davon aus, dass Sie Aufgabe 9 korrekt durchgeführt haben. Dann<br />
haben Sie auch bemerkt, dass der <strong>C#</strong> - Editor selbst auch schon gewisse Korrekturfunktionen<br />
mit sich bringt: Syntaxfehler etwa werden sofort durch eine Schlangenlinie<br />
gekennzeichnet:<br />
Was ist hier falsch?<br />
Wenn die fünf Zeilen, wie in Aufgabe 9 angegeben, korrekt eingetragen sind, dann<br />
sollte man den Compiler laufen lassen. Wie in <strong>Delphi</strong> auch geht das mit dem kleinen<br />
grünen Pfeil oder mit F5.<br />
Der Compiler untersucht noch deutlich genauer als der Editor nach Ungereimtheiten<br />
<strong>und</strong> zeigt eventuelle Fehler in einem weiteren Fenster unter dem Quellcode an.<br />
Hat alles geklappt, dann erscheint die Konsole <strong>und</strong> tut<br />
genau das, was sie soll.<br />
Würde die letzte, anscheinend sinnlose Zeile fehlen,<br />
dann müssten Sie schon sehr schnell schauen, um zu<br />
sehen, ob die Begrüßung nach Plan verläuft.<br />
So wartet die Anwendung auf eine erneute Eingabe.<br />
Nach dieser verschwindet die Konsole wieder.<br />
Selbstverständlich lässt sich auch ein <strong>C#</strong> -Code „entlausen“ (debuggen). Und das<br />
geht noch deutlich komfortabler, als in <strong>Delphi</strong> 7:<br />
Zunächst den Cursor in die Stopp-Zeile setzten. Einen Haltepunkt bekommt man mit<br />
F9. Wie bei <strong>Delphi</strong> erscheint dann ein roter Punkt auf der linken Seite.<br />
(Wir nehmen hier die Zeile: Console.WriteLine("Hallo, " + name + "!"); )<br />
156
Nun mit F5 bis zum markierten Punkt compilieren lassen. In diesem Fall muss man<br />
bevor es zum Haltepunkt geht, seinen Namen in die Konsole eingeben:<br />
Die Variable name ist somit, wie nebenstehend zu<br />
sehen, konkrekt belegt worden.<br />
Mit F11 geht es jetzt im Einzelschrittmodus weiter<br />
<strong>und</strong> der Compiler hält am roten Punkt.<br />
Bewegen Sie den Cursor über name.<br />
Wenn Sie einen Augenblick warten, ist ein kleines Popup-Fenster zu sehen. Hier<br />
kann man den Variablen-Inhalt kontrollieren <strong>und</strong> zu Kontrollzwecken auch abändern.<br />
Die Belegung der Variablen kann man ohne große Umstände im darunter liegenden<br />
Fenster auslesen. Beachten Sie im nächsten Screenshot die Wirkung der Änderung<br />
des Strings der Variablen name:<br />
157
Wie Sie weiter oben schon gelernt haben, arbeitet .NET mit mehr als 10 000 Datentypen.<br />
Da heißt es Ordnung halten! .NET verwendet daher das Konzept der<br />
Namensräume. Dazu einige Erläuterungen, die sich auf unser kleines Programm<br />
HalloConsole1 beziehen:<br />
• using-Anweisungen verwendet man bei häufig vorkommenden<br />
Namensräumen. using System erspart uns zum Beispiel, den dem<br />
Namensraum System zugeordneten Datentyp Console immer seinen<br />
Namensraum voranzustellen. Also statt System.Console.Readline() dürfen wir<br />
bei Verwendung der Zeile using System einfach Console.Readline()<br />
schreiben.<br />
• Jede Anwendung bekommt ihren eigenen Namensraum. Je nach dem was Sie<br />
eingegeben haben steht hinter namespace Console1 oä.<br />
• Jede Anwendung bekommt eine Datentypdefinition (class program) <strong>und</strong> eine<br />
Funktion namens Main() <strong>und</strong> bei Bedarf weitere Datentypendefinitionen mit<br />
auf den Weg. Main() gibt den Start- <strong>und</strong> den Endpunkt des Programms an.<br />
Name <strong>und</strong> Deklaration mit dem Teil static sind vorgeschrieben.<br />
Vielleicht der einzige Kritikpunkt für <strong>Visual</strong> <strong>C#</strong>:<br />
Für Namensräume dient der Punkt lediglich der besseren Lesbarkeit. System.Text<br />
bedeutet also nicht, dass Text eine Untergruppe von Namensraum System ist!!<br />
System.Text ist mitsamt dem Punkt der Name eines bestimmten Namensraumes.<br />
Man kann den Punkt vermeiden, wenn man innerhalb des Namensraum System<br />
einen weiteren Namensraum Text definiert.<br />
Für Datentypen trennt der Punkt die Hierarchieebenen: System.Console ist kein<br />
eigener Namensraum, sondern der Datentyp Console im Namensraum System!!<br />
Für Methoden trennt der Punkt ebenfalls Hierarchieebenen: Console.ReadLine() ist<br />
eine Methode von Console!<br />
Alles klar?!?<br />
Vermutlich nicht! Daher jetzt<br />
Aufgabe 10<br />
Lesen Sie aufmerksam den Wikipedia-Artikel (19.08.07) über Namensräume durch!<br />
Namensraum (englisch namespace) ist ein Begriff aus der <strong>Informatik</strong>.<br />
Ein Name identifiziert ein Objekt. Zur eindeutigen Zuordnung ist jedoch der<br />
entsprechende Kontext – eben der Namensraum - zu beachten. Die Beschreibung<br />
geschieht üblicherweise durch die "Punkt"-Notation. Neben der "Punkt"-Notation sind<br />
aber auch andere Zeichen gebräuchlich, z. B. bei Dateinamen "\" oder "/". Einige<br />
Namensräume (z. B. Dateisysteme) sind hierarchisch aufgebaut; d. h. Namensräume<br />
können selbst wieder aus Namensräumen bestehen. Namensräume werden dazu<br />
verwendet, Konflikte bei der Namensvergabe zu verhindern. Graphisch sind<br />
Namensräume mit Bäumen äquivalent; d. h. Namensräume haben eine Wurzel<br />
158
(einen festen, definierten Ausgangspunkt), Knoten (Verzeichnisse) <strong>und</strong> Blätter<br />
(Objekte).<br />
Die Idee von Namensräumen wird auch in anderen Bereichen unter anderen Namen<br />
verwendet, z. B. in der Telefonie. Jeder Teilnehmer erhält eine individuelle<br />
Rufnummer (z. B. 4711) <strong>und</strong> diese wird lokal vergeben. Das Telefonnetz ist hierbei in<br />
Unternetze unterteilt, <strong>und</strong> die Identifikation erfolgt über die Vorwahl. Somit kann jede<br />
Rufnummer mehrfach vergeben werden, sie muss nur innerhalb des Unternetzes<br />
eindeutig sein. Bei einem Anruf im selben Vorwahlbereich reicht somit die Angabe<br />
der Rufnummer 4711. Soll ein Teilnehmer aus dem Vorwahlbereich 0815 kontaktiert<br />
werden, der ebenfalls die Rufnummer 4711 besitzt, so wählt man die 0815 vor. Durch<br />
diese Technik können zwei Teilnehmer die gleiche Rufnummer 4711 besitzen. In<br />
diesem Beispiel wäre die 0815 der Namensraum, 4711 der eigentliche Name, <strong>und</strong><br />
das Telefon das identifizierte Objekt.<br />
Beim Erstellen von Programmen kann ein Autor unter Benutzung von<br />
Namensräumen große Programmpakete mit vielen definierten Namen schreiben,<br />
ohne sich Gedanken machen zu müssen, ob die neu eingeführten Namen in Konflikt<br />
zu anderen Namen stehen. Im Unterschied zu der Situation ohne Namensräume wird<br />
hier nicht der ganze Name neu eingeführt, sondern nur ein Teil des Namens, nämlich<br />
der des Namensraumes.<br />
Ein Namensraum ist ein deklaratorischer Bereich, der einen zusätzlichen<br />
Bezeichner an jeden Namen anheftet, der darin deklariert wurde. Dieser<br />
zusätzliche Bezeichner macht es weniger wahrscheinlich, dass ein Namenskonflikt<br />
auftritt mit Namen, die anderswo im Programm deklariert wurden. Es ist möglich, den<br />
gleichen Namen in unterschiedlichen Namensräumen ohne Konflikt zu verwenden,<br />
auch wenn der gleiche Name in der gleichen Übersetzungseinheit vorkommt.<br />
Solange er in unterschiedlichen Namensräumen erscheint, ist jeder Name eindeutig<br />
aufgr<strong>und</strong> des zugefügten Namensraumbezeichners.<br />
Ein weiteres Beispiel:<br />
Der Namensraum System besitzt zum Beispiel den Datentyp Math. Dieser besitzt<br />
recht viele mathematische Funktionen. Um zu erfahren, welche genau das sind,<br />
können Sie wieder die IntelliSens verwenden. Am besten erzeugen Sie dazu eine<br />
neue Consolenanwendung.<br />
Geben Sie folgende Zeile ein:<br />
Console.WriteLine(Math.<br />
Sobald Sie beim Punkt angekommen sind, sollte es wie folgt aussehen:<br />
159
Das gelbe Fenster zeigt 19 mögliche Parameter für Console.WriteLine() an.<br />
Im weißen Fenster darüber werden die mathematischen Funktionen aufgezählt.<br />
Aufgabe 11<br />
Erstellen Sie eine neue Consolen-Anwendung ConsoleRechnen1 <strong>und</strong> testen Sie<br />
damit einige Rechnungen.<br />
Beispiel:<br />
Bei <strong>Delphi</strong>programmen landet nach der Compilierung eine exe-Datei im Programmodner,<br />
die man unter Windows auch ohne <strong>Delphi</strong> starten kann.<br />
Bei <strong>Visual</strong> <strong>C#</strong> ist das auch nicht viel anders. Allerdings sollte man<br />
wissen, dass bei Compilation mit F5 (falls keine Fehler da sind) eine<br />
exe-Datei unter bin\Debug zu finden ist. Um eine endgültige Fassung in<br />
den Release-Ordner zu bekommen, muss man mit F6 compilieren. Das Programm<br />
wird dann aber nicht gestartet.<br />
Nun aber zur grafischen Windows-Programmierung:<br />
Wir wählen:<br />
Windows-<br />
Anwendung.<br />
Falls man keine<br />
Namensänderungen<br />
vornimmt <strong>und</strong> die<br />
„Toolbox“ links mit<br />
dem „Reißnagel“<br />
fixiert, dann sieht der<br />
obere Teil der IDE<br />
(Integrierte<br />
Entwicklungsebene)<br />
so aus:<br />
160
Links sind von Windows XP bekannte Steuerelemente<br />
angebracht. Man zieht sie wie in <strong>Delphi</strong> einfach auf das<br />
Formular daneben.<br />
Das Fenster rechts oben entspricht in etwa dem<br />
Projektmanager <strong>und</strong> zeigt alle Teile des Projekts „Hallo Welt“<br />
an.<br />
Darunter (<strong>und</strong> auch rechts vergrößert) sehen Sie das<br />
Eigenschaften-Fenster der jeweiligen Komponenten. (In<br />
<strong>Delphi</strong> war das der Objektinspektor). Wenn das Fenster<br />
nicht zu sehen ist, führt man<br />
einen Rechtsklick auf der<br />
gewünschten Komponente<br />
aus <strong>und</strong> das Fenster<br />
erscheint.<br />
Wenn Sie in der Leiste oben<br />
das „Blitz“-Icon anklicken,<br />
dann sind die zugehörigen<br />
Ereignisse zu sehen.<br />
Oberhalb des Formulars ist<br />
ein Tab namens Form1.cs* zu<br />
erkennen. Hier wird, wie in<br />
der Unit bei <strong>Delphi</strong> der<br />
Quelltext geschrieben. Wie<br />
üblich wurden hier alle Teile, die <strong>C#</strong> selbst geschrieben hat, fett gedruckt. Da bleibt<br />
für unser „Hallo Welt“- Programm nicht mehr viel zu tun:<br />
161
using System;<br />
using System.Collections.Generic;<br />
using System.ComponentModel;<br />
using System.Data;<br />
using System.Drawing;<br />
using System.Text;<br />
using System.Windows.Forms;<br />
namespace WindowsApplication1<br />
{<br />
public partial class Form1 : Form<br />
{<br />
public Form1()<br />
{<br />
InitializeComponent();<br />
}<br />
private void label2_Click(object sender, EventArgs e)<br />
{<br />
}<br />
}<br />
}<br />
private void button1_Click(object sender, EventArgs e)<br />
{<br />
label1.Text = "Hallo Welt!";<br />
label2.Text = "Alles wie in <strong>Delphi</strong>, oder?!";<br />
}<br />
Auch in <strong>C#</strong> gelten die gleichen Gr<strong>und</strong>regeln wie für <strong>Delphi</strong>:<br />
• Ändern Sie nichts, was <strong>C#</strong> geschrieben hat!<br />
• Erstellen Sie zuerst einen Ordner <strong>und</strong> speichern Sie das Projekt mit<br />
Datei/Alle speichern ab!<br />
• Wenn Sie die Arbeit am Projekt beendenen wollen, dann wählen Sie Datei /<br />
Projektmappe schließen.<br />
Wie weiter oben erwähnt, beruhen alle Programme bei imperativen Programmiersprachen<br />
auf drei Techniken. Etwas überspitzt formuliert: Beherrschen sie die drei<br />
genannten Techniken, dann können Sie programmieren. Und das sind die drei:<br />
• Anweisungen<br />
• Schleifen<br />
• Verzweigungen<br />
Natürlich gibt es für jede von ihnen verschiedene Varianten. In <strong>C#</strong> beispielsweise gibt<br />
es for-, while <strong>und</strong> do-Schleifen. Das ändert aber nichts daran, dass die Idee immer<br />
die gleiche bleibt: Das mehrfache Durchlaufen eines Programmsegements.<br />
162
Anweisungen haben Sie bereits kennengelernt. (z.B.: label1.Text = "Hallo Welt!";)<br />
Daher jetzt zunächst zu<br />
Schleifen<br />
Ein Schleife braucht man, wenn viele Male der gleiche Programmcode zu<br />
durchlaufen ist. In Mathematik (Klasse 11, 12, 13) werden Folgen <strong>und</strong> Grenzwerte<br />
behandelt.<br />
Ein Beispiel:<br />
1 1 1<br />
f ( n)<br />
= 1+<br />
+ +… +<br />
2 2<br />
2<br />
2 3 n<br />
Ist zum Beispiel n = 30, so muss die Schleife 30 mal durchlaufen werden. Bei jedem<br />
Druchlauf kommt ein Summand zur bisherigen Summe hinzu. Wir realisieren dies<br />
durch eine for-Schleife:<br />
Ein Doppelklick auf den Button öffnet den Editor <strong>und</strong> man kann dann den<br />
Programmcode für das „button1_Click“- Ereignis eingeben:<br />
Die oberste Zeile hat der Editor beim Doppelklick selbst geschrieben. Man benötigt<br />
zunächst zwei Variable: Die Summe s <strong>und</strong> die Grenze n.<br />
Den „Rahmen“ für die for-Schleife muss man nicht selbst erstellen. Vielmehr wählt<br />
man durch einen Rechtsklick die Option Ausschnitt einfügen / <strong>Visual</strong> <strong>C#</strong> .<br />
163
In der sich öffnenden Listbox wählt man den gewünschten Code. Meist muss man<br />
dann noch den Code an die vorliegenden Situation anpassen:<br />
Hier ist die Variable length durch n + 1 <strong>und</strong><br />
i = 0 duch i = 1 zu ersetzten.<br />
Aufgabe 12<br />
• Was besagt die einzelenen Elemente im Kopf der for-Schleife?<br />
• Wie kann der Programmcode zwischen den geschweiften Klammern<br />
aussehen?<br />
• Weshalb ergibt der Code s = s + 1 / (i * i); als Gesamtsumme immer nur 1 ?<br />
(Kontrollieren Sie durch einen geeigneten Haltepunkt die Speicherinhalte!)<br />
Eine mögliche Lösung:<br />
Testen Sie das Programm!<br />
Vermuten Sie einen Grenzwert?<br />
(n < 1 000 000 000 – sonst<br />
warten Sie eventuell recht lange!)<br />
Der Wertetyp Int64 hat keinen<br />
eigenen Bezeichner in <strong>C#</strong>.<br />
Man muss ihn daher mit dem<br />
Bezeichner aus .NET aufrufen -<br />
erkennbar am großen Anfangsbuchstaben. Es wäre sicher günstiger gewesen, für n<br />
<strong>und</strong> i nur den Wertetyp int (von -2.147.483.648 bis 2.147.483.647) zu wählen. Sie<br />
können das ruhig mal testen: Das Programm wird etwas schneller. Kein W<strong>und</strong>er: Für<br />
Int64 ( von -9.223.372.036.854.775.808 bis +9.223.372.036.854.775.808 ) müssen,<br />
wie der Name schon sagt, 64 Bit im RAM reserviert werden. Wählen Sie allerdings<br />
dann ein n, das größer ist, als 2.147.483.647, dann passiert etwas merkwürdiges....<br />
164
Die for-Schleifen sind Zählschleifen. Das Verfahren ist immer dann praktisch, wenn<br />
es etwas zu zählen gibt. Manchmal weiß man aber im Voraus gar nicht, wie oft eine<br />
Schleife zu durchlaufen ist. Eine Abbruchbedingung wäre dann wünschenswert:<br />
Durchlaufe die Schleife solange bis diese oder jene Bedingung erfüllt ist.<br />
Die while-Schleife erfüllt genau diesen Zweck!<br />
Als Beispiel soll eine sehr seltsame Folge aus dem Mathematikunterricht herhalten:<br />
f ( n)<br />
= r ⋅ f ( n)<br />
⋅ (1 − f ( n))<br />
; f ( 0) = 0, 5<br />
Für r wählt man zum Beispiel zunächst 2,8.<br />
Aufgabe 13<br />
Berechnen Sie von Hand die nächsten 5 Folgenglieder!<br />
Zugegeben: Das ist ziemlich mühsam! Vor allem müsste man deutlich mehr, als 5<br />
Folgenglieder berechnen, um zu erkennen, worauf die Sache hinausläuft! Leider<br />
kann man ja f(100) nicht berechnen, ohne f(99) zu kennen.....<br />
Machen wir es kurz! Erstellen Sie folgendes Formular:<br />
Soviele Folgenglieder (n) sollen<br />
berechnet <strong>und</strong> ausgegeben<br />
werden.<br />
Das Ergebnis der Folgenglieder<br />
hängt offensichtlich sehr stark von<br />
der Wahl von r (Textbox links) ab.<br />
Das Textfeld zur Linken ist eine<br />
ListBox.<br />
Ihre wichtigste Eigenschaft ist<br />
Items. Dem konkreten Objekt<br />
listBox1 kann man durch<br />
listBox1.Items.Add() Text<br />
anhängen.<br />
So kann der Programmcode<br />
aussehen:<br />
165
Aufgabe 14<br />
Versuchen Sie den Code nachzuvollziehen <strong>und</strong> tragen sie ihn in das button1_Click-<br />
Ereignis ein. Wenn Sie eine andere Idee haben: Ausprobieren!<br />
Erstellen Sie eine eigene Folge <strong>und</strong> prüfen Sie mit einer Variation des obigen<br />
Programms, ob sie konvergent ist (konvergent = hat einen Grenzwert).<br />
Verzweigungen<br />
Nun fehlt als letzter Gr<strong>und</strong>baustein lediglich die Verzweigung. Führt man sie mit if<br />
…else aus, dann muss man sich an folgende Syntax halten:<br />
if (Bedingung erfüllte)<br />
{<br />
//Anweisungsblock<br />
}<br />
else<br />
{<br />
//Anweisungsblock<br />
}<br />
Testen wir die neu gelernte Thematik durch Erweiterung des obigen Beispiels:<br />
• Das Programm soll stoppen <strong>und</strong> eine Warnung ausgeben, wenn einer der<br />
TextBoxes leer ist.<br />
• Es sollen nur die letzten s (int) Folgenglieder ausgegeben werden.<br />
• Durch einen Menueintrag soll der Eintrag in der ListBox gelöscht werden<br />
können.<br />
166
So kann das Formular aussehen:<br />
Das Menu-Steuerelement bekommen<br />
Sie durch MenuStrip (siehe oben).<br />
Wenn das neue Steuerelement auf<br />
dem Formular untergebracht ist, kann<br />
man direkt die einzelnen Menu- <strong>und</strong><br />
Untermenu-Texte eintragen.<br />
Durch Doppelklick auf einen Eintrag,<br />
wie Liste löschen, geht ein Fenster im<br />
Editor auf <strong>und</strong> der Rahmen für das<br />
listeLöschenToolStripMenuItem_Click<br />
Ereignis kann programmiert werden.<br />
Suchen Sie im Programmcode unten<br />
die betreffenden Stellen <strong>und</strong> sehen Sie<br />
sich die Anweisungen zwischen den<br />
geschweiften Klammern an.<br />
Den Vergleichsoperator oder muss<br />
man mit zwei senkrechten Strichen<br />
schreiben: || . Tastenkombination<br />
AltGr + < >-Taste.<br />
private void button1_Click(object sender, EventArgs e)<br />
{<br />
if ((textBox1.Text=="")||(textBox2.Text=="")||(textBox3.Text=="")||(textBox4.Text==""))<br />
{<br />
label2.Text = "Bitte alle Felder ausfüllen!";<br />
}<br />
else<br />
{<br />
Int64 n = Convert.ToInt64(textBox1.Text);<br />
int s = Convert.ToInt32(textBox4.Text); //Angezeigt werden die letzten s Elemente<br />
double r = Convert.ToDouble(textBox2.Text);<br />
double summe_alt = Convert.ToDouble(textBox3.Text);<br />
double summe_neu = 0; Int64 i = 0;<br />
while (i
summe_alt = summe_neu;<br />
i++;<br />
if ((n - i) < s)<br />
{<br />
listBox1.Items.Add(Convert.ToString(summe_neu));<br />
}<br />
}<br />
}<br />
}<br />
private void listeLöschenToolStripMenuItem_Click(object sender, EventArgs e)<br />
{<br />
listBox1.Items.Clear();<br />
}<br />
}<br />
private void beendenToolStripMenuItem_Click(object sender, EventArgs e)<br />
{<br />
Application.Exit();<br />
}<br />
Hinweis:<br />
Das Programm wird im Unterricht entwickelt. Denken <strong>und</strong> schreiben Sie mit. Beim<br />
bloßen Kopieren lernen Sie nichts!<br />
Auch wenn Sie das Skript im Selbststudium durcharbeiten, sollten Sie den<br />
Programmcode selbst schreiben!<br />
Durch die erste if-Abfrage wird verhindert, dass das Programm abstürzt, wenn eine<br />
Textbox leer bleibt. Gegen sinnlose Eingaben, wie n = Hallo, ist das Programm so<br />
allerdings noch nicht geschützt! Dies kann man mit dem try-catch – Block erledigen:<br />
try<br />
{<br />
//Programmcode<br />
}<br />
catch<br />
{<br />
//Bei einer „Ausnahme“ (= „Absturz“) im obigen Programm<br />
//werden alle Speicher freigegeben <strong>und</strong> man landet hier!<br />
//z.B.:<br />
label1.Text = „Das Programm wäre abgestürzt!“<br />
}<br />
Aufgabe 15<br />
Sichern Sie das obige Programm durch einen try-catch-Block ab!<br />
168
Der obige Screenshot stammt vom Programm „Feigenbaum“ (Tauschverzeichnis).<br />
Auf der x-Achse sind die verschiedenen r-Werte aufgetragen, auf der y-Achse die<br />
Werte der Folge ab dem Folgenelement f(100). Man erkennt, dass für Werte<br />
unterhalb von r = 3 ein Grenzwert existiert. Zwischen r = 3 <strong>und</strong> r = 3,4 alterniert die<br />
Folge zwischen genau zwei Werten. Danach wird es komplizierter! Um das Verhalten<br />
der Folge genauer zu studieren, kann man im Programm mit der Maustaste in das<br />
Bild zoomen. Das obige Rechteck sieht dann vergrößert so aus:<br />
169
Die Vergrößerungen sehen dem ursprünglichen Bild sehr ähnlich. Man spricht dann<br />
von Selbstähnlichkeit. Sie ist eine wesentliche Eigenschaft von Fraktalen. Zoomt<br />
man noch weiter in das Bild, so erkennt man, dass immer wieder Bereiche existieren,<br />
in denen die Folge nur zwischen wenigen Werten alterniert. Testen Sie<br />
beispielsweise r = 3,5829 mit Ihrem <strong>C#</strong>-Programm!<br />
170
In <strong>Delphi</strong> haben Sie bereits ein Programm geschrieben, das überprüft, ob eine<br />
eingegebene natürlich Zahl eine Primzahl ist. Wir verwenden hier den gleichen<br />
Algorithmus. Auf diese Weise können Sie die erlernten Techniken in <strong>C#</strong> nochmals<br />
etwas vertiefen.<br />
Hier der Quelltext für die button1_Click- Routine.<br />
Sie werden unschwer die Parallelen zu Java <strong>und</strong> <strong>Delphi</strong> erkennen!<br />
private void button1_Click(object sender, EventArgs e)<br />
{<br />
string s1 = textBox1.Text;<br />
Int64 zahl = Convert.ToInt64(s1);<br />
label1.Text = "";<br />
if (zahl == 1)<br />
label1.Text = "Die Zahl ist keine Primzahl!";<br />
else<br />
{<br />
if (zahl == 2)<br />
label1.Text = "Die Zahl ist eine Primzahl!";<br />
else<br />
{<br />
if (zahl % 2 == 0)<br />
label1.Text = "Die Zahl ist keine Primzahl!";<br />
else<br />
{<br />
long i = 1;<br />
if (zahl > 2)<br />
{<br />
do<br />
{<br />
i = i + 2;<br />
} while ((zahl % i != 0) & (i*i < zahl));<br />
}<br />
if (i*i > zahl)<br />
else<br />
label1.Text = "Die Zahl ist eine Primzahl!";<br />
label1.Text = "Die Zahl ist keine Primzahl!";<br />
}<br />
}<br />
}<br />
}<br />
171
Das zugehörige Formular kann so aussehen:<br />
(Wer will kann sich das fertige Programm aus dem<br />
Tauschverzeichnis holen!)<br />
Der Einfachheit halber wurde oben auf die an sich<br />
nötige Behandlung der Format-Exception<br />
verzichtet. Nötig ist sie deshalb, weil sonst für<br />
Zahlen wie 32,5 sinnlose Aussagen über prim<br />
oder nicht prim gemacht werden.<br />
Und hier nochmals das Abfangen eines Fehlers:<br />
private void button1_Click(object sender, EventArgs e)<br />
{<br />
string s1 = textBox1.Text;<br />
try<br />
{<br />
Int64 zahl = Convert.ToInt64(s1);<br />
…................................................……..............<br />
}<br />
catch (FormatException) { label1.Text = "Das war keine natürliche Zahl!! "; }<br />
}<br />
}<br />
}<br />
Aufgabe 16<br />
Da nur die Übung den Programmier-Meister macht, erstellen Sie nun mit Hilfe des<br />
obigen Quelltextes <strong>und</strong> der <strong>Visual</strong> <strong>C#</strong> -Hilfe ein Programm zur Bestimmung der<br />
Lösung quadratischer Gleichungen (vergleiche Aufgabe 3).<br />
Tipp:<br />
Es gibt eine Seite von Microsoft, die alle Programmierer ansprechen soll, die mit <strong>C#</strong><br />
ein Spiel programmieren wollen. Es gibt dort Tutorials <strong>und</strong> halb fertige<br />
Programmcodes, so dass man ohne Probleme recht schnell zu eigenen<br />
Programmcode kommt :<br />
http://www.microsoft.com/germany/msdn/coding4fun/antme/default.mspx<br />
172