335

Visual C# 2005 easy

Embed Size (px)

Citation preview

Page 2: Visual C# 2005 easy

Visual C# 2005

Page 3: Visual C# 2005 easy

Unser Online-Tippfür noch mehr Wissen …

... aktuelles Fachwissen rund um die Uhr – zum Probelesen,

Downloaden oder auch auf Papier.

www.InformIT.de

Page 4: Visual C# 2005 easy

Visual C# 2005Mit einfachen Beispielen programmieren

W A L T E R S A U M W E B E R

leicht klar sofort� � �

Markt+Technik Verlag
© Copyright-Hinweis
Copyright Daten, Texte, Design und Grafiken dieses eBooks, sowie die eventuell angebotenen eBook-Zusatzdaten sind urheberrechtlich geschützt. Dieses eBook stellen wir lediglich als persönliche Einzelplatz-Lizenz zur Verfügung! Jede andere Verwendung dieses eBooks oder zugehöriger Materialien und Informationen, einschliesslich der Reproduktion, der Weitergabe, des Weitervertriebs, der Platzierung im Internet, in Intranets, in Extranets, der Veränderung, des Weiterverkaufs und der Veröffentlichung bedarf der schriftlichen Genehmigung des Verlags. Insbesondere ist die Entfernung oder Änderung des vom Verlag vergebenen Passwortschutzes ausdrücklich untersagt! Bei Fragen zu diesem Thema wenden Sie sich bitte an: [email protected] Zusatzdaten Möglicherweise liegt dem gedruckten Buch eine CD-ROM mit Zusatzdaten bei. Die Zurverfügungstellung dieser Daten auf unseren Websites ist eine freiwillige Leistung des Verlags. Der Rechtsweg ist ausgeschlossen.
praktit01
Notiz
Completed festgelegt von praktit01
praktit01
Notiz
MigrationConfirmed festgelegt von praktit01
Page 5: Visual C# 2005 easy

Bibliografische Information Der Deutschen BibliothekDie Deutsche Bibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie;detaillierte bibliografische Daten sind im Internet über http://dnb.ddb.de abrufbar.

Die Informationen in diesem Produkt werden ohne Rücksicht auf einen eventuellen Patentschutz veröffentlicht.Warennamen werden ohne Gewährleistung der freien Verwendbarkeit benutzt.Bei der Zusammenstellung von Texten und Abbildungen wurde mit größter Sorgfalt vorgegangen.Trotzdem können Fehler nicht vollständig ausgeschlossen werden.Verlag, Herausgeber und Autoren können für fehlerhafte Angabenund deren Folgen weder eine juristische Verantwortung nochirgendeine Haftung übernehmen.Für Verbesserungsvorschläge und Hinweise auf Fehler sind Verlag undHerausgeber dankbar.

Alle Rechte vorbehalten, auch die der fotomechanischen Wiedergabe und derSpeicherung in elektronischen Medien. Die gewerbliche Nutzung der in diesem Produkt gezeigten Modelle und Arbeiten ist nicht zulässig.

Fast alle Hardware- und Softwarebezeichnungen und weitere Stichworte und sonstige Angaben,die in diesem Buch verwendet werden, sind als eingetragene Marken geschützt. Da es nicht möglich ist, in allen Fällen zeitnah zu ermitteln, ob ein Markenschutz besteht, wird das ® Symbol in diesem Buch nicht verwendet.

Umwelthinweis:Dieses Buch wurde auf chlorfrei gebleichtem Papier gedruckt.

10 9 8 7 6 5 4 3 2 1

09 08 07 06

ISBN-13: 978-3-8272-4160-3ISBN-10: 3-8272-4160-X

© 2006 by Markt+Technik Verlag,ein Imprint der Pearson Education Deutschland GmbH,Martin-Kollar-Straße 10–12, D-81829 München/GermanyAlle Rechte vorbehaltenCoverkonzept: independent Medien-Design, Widenmayerstraße 16, 80538 MünchenCoverlayout: Thomas Arlt, [email protected]: jupiterimages, StarnbergHerstellung: Monika Weiher, [email protected]: Brigitte Alexandra Bauer-Schiewek, [email protected]: Petra KienleSatz: Ulrich Borstelmann, Dortmund (www.borstelmann.de)Druck und Verarbeitung: Bosch Druck, ErgoldingPrinted in Germany

Page 6: Visual C# 2005 easy

Inhaltsverzeichnis

Liebe Leserin, lieber Leser ......................................................... 9

1 Allgemeine Aspekte der Programmentwicklung 11

Der Quellcode...........................................................................12Kompilierung ...........................................................................13Integrierte Entwicklungsumgebungen ..................................... 18Eine kleine Erfolgskontrolle ..................................................... 19

2 Die Programmierumgebung von C# 21

Besonderheiten bei der Kompilierung in C# ........................... 22Das .NET Framework ............................................................... 24Installation der Visual C# 2005 Express Edition...................... 26Eine kleine Erfolgskontrolle .................................................... 33

3 Ihr erstes C#-Programm 35

Programmentwicklung mit der Visual C# 2005 Express Edition ....................................................................... 36Projektmappen und Projekte .................................................. 43Hätten Sie gedacht ... ............................................................ 45

4 Aufbau von C#-Programmen 47

Aufbau von C#-Programmen ................................................... 48Wo befindet sich nun eigentlich die ausführbare (.exe-)Datei? ........................................................................... 57Eine kleine Erfolgskontrolle .................................................... 57

Page 7: Visual C# 2005 easy

6 Inhaltsverzeichnis

5 Syntaxregeln 59

Textbausteine ......................................................................... 60Anweisungsende .....................................................................61Blöcke .................................................................................... 62Leerräume .............................................................................. 64Programmierstil ...................................................................... 66Kommentare ........................................................................... 67Programm(ier)fehler ............................................................... 69Hätten Sie gedacht ... ............................................................. 72

6 Ausgabe 75

Die Methoden Write() und WriteLine() .................................... 76Zeichenketten ......................................................................... 78Steuerzeichen ..........................................................................81Eine kleine Erfolgskontrolle .................................................... 85

7 Variablen und Datentypen 87

Variablendefinition ................................................................. 88Die Zuweisung ........................................................................ 93Unterschiedliche Bedeutung von Variablenbezeichnern im Quellcode .......................................................................... 99Notationen für Bezeichner ..................................................... 101Die Methode ReadLine() ........................................................103Eine kleine Erfolgskontrolle ................................................... 107

8 Konstanten 109

Literale .................................................................................. 110Benannte Konstanten ............................................................122Implizite Typumwandlungen ..................................................124Explizite Typumwandlungen ..................................................129Eine kleine Erfolgskontrolle ...................................................137

Page 8: Visual C# 2005 easy

Inhaltsverzeichnis 7

9 Rechenoperationen 139

Ausdrücke und arithmetische Operatoren .............................140Erstellen Sie ein Euro-DM-Umrechnungsprogramm ...............143Formatieren von Ausgaben ....................................................147Eine kleine Erfolgskontrolle ..................................................155

10 Verzweigungen 157

Logische Ausdrücke ...............................................................158Prioritätsstufen von Operatoren ............................................162Die if-Anweisung ....................................................................164Die switch-Anweisung ...........................................................177Eine kleine Erfolgskontrolle ................................................... 191

11 Wiederholungsanweisungen 193

Die while-Schleife ..................................................................194Die do-while-Schleife .............................................................198Die for-Schleife ......................................................................199Zufallszahlen generieren ...................................................... 204Realisieren Sie ein Ratespiel ................................................. 209Hätten Sie gedacht ... ............................................................219

12 Arrays 221

Arrays definieren .................................................................. 222Arrays mit der for-Schleife verwalten .................................... 224Arrays sortieren.................................................................... 226Die foreach-Schleife ............................................................. 227Initialisieren von Arrays ........................................................ 230Eine kleine Erfolgskontrolle ...................................................231

Page 9: Visual C# 2005 easy

8 Inhaltsverzeichnis

13 Methoden 233

Methoden definieren ............................................................ 234Methoden verwenden ........................................................... 236Parameterübergabe .............................................................. 238Rückgabewerte von Methoden ............................................. 245Eine kleine Erfolgskontrolle .................................................. 249

14 Klassen und Objekte 251

Vorüberlegungen .................................................................. 252Klassendefinition .................................................................. 254Statische Klassenelemente ................................................... 272Namensräume ...................................................................... 277Eine kleine Erfolgskontrolle .................................................. 279

15 Windows-Anwendungen entwickeln 281

Der Windows Forms-Designer ............................................... 282Steuerelemente mit Code verbinden – Ereignisbehandlungsroutinen ............................................... 293Hätten Sie gedacht ... ........................................................... 302

Anhang – Antworten 303

Glossar 315

Stichwortverzeichnis 323

Page 10: Visual C# 2005 easy

9

Liebe Leserin, lieber Leser,vielen Dank, dass Sie sich für dieses Buch entschieden haben. Es richtet sichin erster Linie an Programmiereinsteiger. Aber auch, wenn Sie bereits erste Er-fahrungen in einer anderen Programmiersprache gesammelt haben und einenschnellen Einstieg in die Programmiersprache C# (sprich »C Sharp«) im Allge-meinen sowie in die objektorientierte Programmierung und in die Programmie-rung von grafischen Benutzeroberflächen im Besonderen erhalten wollen,sollten Sie aus diesem Buch den gewünschten Nutzen ziehen.

Mein oberstes Ziel war es, die genannten Themen übersichtlich und gut ver-ständlich darzustellen. Es beginnt mit den Grundlagen der Programmierspra-che C# selbst und danach schließen sich die Konzepte der objektorientiertenProgrammierung sowie eine Einführung in die Windows-Programmierung an.Da die Grundlagen wichtig für das Verständnis sind und alle Themen aufeinan-der aufbauen, empfiehlt es sich für einen schnellen Lernerfolg, das Buch Seitefür Seite von vorne nach hinten durchzuarbeiten.

Als Software erhalten Sie mit diesem Buch eine komfortable und leistungs-fähige Entwicklungsumgebung für C#-Programme, die Visual C# 2005 ExpressEdition von Microsoft, die auf der Buch-CD enthalten ist. Dabei handelt es sichum eine vollwertige Teilmenge von Visual Studio 2005, die weder funktionaleingeschränkt noch zeitlich befristet ist. Visual C# 2005 Express eignet sich so-wohl für den Hobbyprogrammierer als auch für den professionellen Software-entwickler. Die Installation, die sich in der Regel als problemlos erweist, ist inKapitel 2 ausführlich erklärt. Dort können Sie sich auch über die Systemvor-aussetzungen informieren. Zum Umgang mit Ihrer Entwicklungsumgebungwerden Sie im Buch ebenfalls genügend Hinweise erhalten.

Alle abgedruckten Listings plus weitere Beispiele finden Sie als Projekte aufder Buch-CD, sodass Sie die benötigten Codezeilen bei Bedarf per Copy andPaste in den Code-Editor Ihrer Visual C# 2005 Express Edition übertragen oderdort gleich das ganze Projekt laden können.

Eventuell zusätzliche Infos zum Buch sowie gegebenenfalls eine Fehlerlistefinden Sie auf meiner Webseite http://www.mipueblo.de.

Ich empfehle Ihnen, sich für die Lektüre des Buchs und für das Nachvollziehender Beispiele Geduld und Zeit zu nehmen, um daraus den größtmöglichen Nut-zen zu ziehen.

Nun bleibt mir nur noch, Ihnen viel Spaß beim Lesen und viel Erfolg mit derVisual C#-Programmierung zu wünschen.

Walter Saumweber

Markt+Technik Verlag
Hinweis
Aus lizenzrechtlichen Gründen können wir Ihnen Visual C# 2005 Express auf unseren Seiten leider nicht zum Download anbieten. Sie finden diese Software aber sicher auf den entsprechenden Seiten des Herstellers. Ihr Markt+Technik Verlag
praktit01
Notiz
Completed festgelegt von praktit01
praktit01
Notiz
MigrationConfirmed festgelegt von praktit01
Page 11: Visual C# 2005 easy

Das lernen Sie neu:

Wie ein ausführbares Programm entsteht 11

Die Bedeutung der Begriffe »Quellcode«, »Compiler«, »IDE« 12

Page 12: Visual C# 2005 easy

Kapitel 1

Allgemeine Aspekte der ProgrammentwicklungDieses Kapitel bietet Ihnen einen ersten Einstieg in die Program-mierung. Dabei werden die einzelnen Entwicklungsschritte bis zur fertigen Anwendung dargestellt. Dadurch erhalten Sie ein Grund-verständnis für die Programmierung. Insbesondere werden Sie mit Fachbegriffen bekannt gemacht, die Ihnen im weiteren Verlauf des Buchs immer wieder begegnen werden.

Page 13: Visual C# 2005 easy

12 Kapitel 1

Der QuellcodeIm Folgenden werden die einzelnen Schritte bei der Programmentwicklung un-ter herkömmlichen Programmiersprachen aufgezeigt. Deren Verständnis ist fürdas der zugrunde liegenden Philosophie von C# und dem .NET unerlässlich.

Ursprung jeder fertigen Anwendung ist der so genannte Quellcode. Dieser be-steht aus reinem Text, setzt sich also aus Buchstaben, Ziffern und weiteren Zei-chen zusammen, die Ihnen von der Tastatur Ihres PCs her bekannt sind. DerQuellcode wird daher auch als »Quelltext« bezeichnet (vor allem, wenn nur einTeil des Quellcodes gemeint ist, spricht man auch kurz vom »Code«).

Die Hauptaufgabe für Sie als Programmierer besteht in der Erstellung diesesQuellcodes. Dazu geben Sie diesen in einen Editor ein und speichern ihnschließlich als Quellcode-Datei auf einem Datenträger. Die Dateierweiterungwird dabei von der verwendeten Programmiersprache vorgegeben. Für C#-Quellcode-Dateien lautet sie .cs.

Für die Eingabe des Quellcodes kann prinzipiell jeder beliebige Texteditor Ver-wendung finden, etwa der mit dem Betriebssystem mitgelieferte Editor, z.B.Notepad bei Windows. (Bei Programmen, die neben dem eigentlichen Textauch Formatierungen ablegen, z.B. Microsoft Word, ist allerdings darauf zuachten, dass der Quellcode im richtigen Format – als reiner Text – gespeichertwerden muss).

Der Quelltext selbst setzt sich aus mehreren Befehlen zusammen, von denenspäter jeder eine ganz bestimmte Wirkung während des Programmlaufs habenwird. Diese Programmierbefehle werden »Anweisungen« oder auch einfach»Befehle« genannt. Jede Programmiersprache stellt einen ihr eigenen Befehls-satz zur Verfügung. Sie können sich das in etwa so vorstellen wie eine Landes-sprache, die sich in Wortschatz und Grammatik von anderen unterscheidet. Sowäre eine Programmiersprache denkbar, welche eine Anweisung wie

Schreibe »Guten Tag« auf den Bildschirm

Hinweis

Bei der Eingabe des Quelltexts sind Sie natürlich den Vorgaben der ver-wendeten Programmiersprache unterworfen. Eben das Erlernen dieserVorgaben – oder positiv ausgedrückt: Möglichkeiten – der Programmier-sprache C# bildet das eigentliche Thema dieses Buchs.

Page 14: Visual C# 2005 easy

Kompilierung 13

ermöglicht – mit der Wirkung, dass bei Ausführung dieses Befehls währenddes Programmlaufs die Worte Guten Tag auf dem Bildschirm erscheinen.

Ist der Quellcode einmal erstellt, so ist die eigentliche Programmierarbeit be-reits getan. Wenn Sie den Quellcode syntaktisch und logisch korrekt eingege-ben haben – was das genau bedeutet, werden Sie im weiteren Verlauf nocherfahren –, dann werden die letzten Schritte zum fertigen Programm nichtmehr problematisch sein.

KompilierungLetztlich besteht das Endprodukt jeder erfolgreichen Programmierarbeit in ei-ner ausführbaren Datei (manchmal sind es auch mehrere, die sich dann unterUmständen gegenseitig aufrufen).

Eine Programmdatei wird in den meisten Betriebssystemen an der Dateierwei-terung erkannt. Die am häufigsten anzutreffende Erweiterung von ausführ-baren Dateien unter Windows ist .exe. Auch die Resultate Ihrer zukünftigenBemühungen werden sich in .exe-Dateien zeigen. Wenn Ihr Computer also aufeine Datei mit der Erweiterung .exe trifft, wird er versuchen, den Inhalt dieserDatei als Befehlsfolge zu verstehen und auszuführen. Wenn dieser Versuchmisslingt, wird er dies mit einer Fehlermeldung kundtun (was hier am Beispiel

Hinweis

In C# lautet die entsprechende Anweisung:

Console.Write("Guten Tag");

Es sei angemerkt, dass sich nahezu alle Programmiersprachen anglo-amerikanischer Wörter bedienen.

Hinweis

Die Begriffe »ausführbare Datei«, »Programm«, »ausführbares Pro-gramm« oder auch »Programmdatei« werden im Allgemeinen gleichbe-deutend verwendet. Es handelt sich um solche Dateien, die vomComputer zur Ausführung vorgesehen sind. Dies trifft z.B. für Text- oderGrafikdateien nicht zu.

Page 15: Visual C# 2005 easy

14 Kapitel 1

von .exe-Dateien geschildert wird, gilt natürlich in Abhängigkeit vom Betriebs-system ebenso für bestimmte andere Dateierweiterungen).

Nun versteht jeder Computer aber nur seinen eigenen Befehlssatz, der»Maschinensprache« genannt wird. Da Ihr Computer letztlich auf der Basis vonzwei unterschiedlichen Zuständen arbeitet – Ein und Aus –, bestehen Maschi-nenbefehle ausschließlich aus Nullen und Einsen. Nur so kodierte Befehlekönnen vom Prozessor Ihres Computers verstanden werden.

Folglich wird Ihr Computer den Quelltext in seiner ursprünglichen Form nichtausführen können, da dieser sich aus Sprachmitteln der verwendeten Pro-grammiersprache zusammensetzt (siehe oben). Der Quellcode muss dahererst in Maschinensprache übersetzt werden. Dies besorgt eine Software, die»Compiler« genannt wird. Bei herkömmlichen Programmiersprachen – auf dieBesonderheiten von C# werden wir im nächsten Kapitel zu sprechen kommen– übersetzt der Compiler den Quelltext als Ganzes in Maschinensprache undspeichert das Endprodukt in einer eigenen Datei (unter Windows in der Regelmit der Dateierweiterung .exe). Dies geschieht in verhältnismäßig kurzer Zeitund ohne Ihr weiteres Zutun. Da es sich beim Compiler ebenfalls um ein Com-puterprogramm handelt, müssen Sie dieses lediglich starten.

Hinweis

Genau genommen ist es der Prozessor Ihres Computers, der die Datei zuinterpretieren versucht, und der Mittler zwischen Programmdatei undProzessor ist das Betriebssystem. Mit anderen Worten, das Betriebssys-tem reicht .exe-Dateien an den Prozessor des Computers zur Ausführungweiter.

Ein lauffähiges Programm …

… muss in Maschinencode vorliegen, damit es vom Prozessor des Com-puters verstanden werden kann.

Page 16: Visual C# 2005 easy

Kompilierung 15

Nach erfolgreichem Übersetzungsvorgang liegt das Programm nunmehr in sei-ner ausführbaren Form vor.

Beachten Sie, dass die Quellcode-Datei beim Übersetzungsvorgang unverän-dert erhalten bleibt. Als Ergebnis der Programmierarbeit liegen nunmehr dieQuellcode-Datei und die ausführbare Programmdatei vor. Es sei noch erwähnt,dass bei verschiedenen Programmiersprachen bzw. in modernen Entwick-lungssystemen mit dem Kompilieren in der Regel eine Vielzahl von weiterenZwischen- bzw. Hilfsdateien entstehen, was uns hier jedoch aus Gründen derAnschaulichkeit nicht weiter interessieren soll. In diesem Sinne stellt die fol-gende Skizze eine grobe Betrachtung des Entstehungsablaufs einer Anwen-dung bei herkömmlichen Programmiersprachen dar.

Hinweis

Natürlich verrichtet der Compiler seine Arbeit nur, wenn Ihr Quelltext kor-rekt ist, ansonsten quittiert er den Kompilierversuch mit entsprechendenFehlermeldungen. In diesem Fall müssen Sie den Quellcode nochmalsüberarbeiten und den Kompiliervorgang erneut in Gang setzen.

Hinweis

Die Bezeichnung »Programm« wird – je nach Sichtweise – nicht nur fürdie fertige Anwendung, sondern mitunter auch für den – noch nicht lauf-fähigen – Quellcode verwendet. Während der Anwender unter »Pro-gramm« in der Regel die ausführbare Applikation versteht, meint derProgrammierer mit dieser Bezeichnung oft in erster Linie den von ihmverfassten Quellcode.

Page 17: Visual C# 2005 easy

16 Kapitel 1

Abbildung 1.1: Der Weg zum lauffähigen Programm unter herkömmlichen Programmiersprachen

Je nachdem, wie weit der Quellcode vom ausführbaren Programm »entfernt«ist, also wie viele interne Übersetzungsschritte bis zur fertigen Anwendungstattfinden, spricht man entweder von »maschinennahen Sprachen« oder von»Hochsprachen«. Ein Beispiel für eine maschinennahe Programmierspracheist Assembler. Beispiele für Hochsprachen sind Cobol, Pascal, C und moderneSprachen wie C++, Java und natürlich C#.

Achtung

Mit dem Programmiercode bestimmen Sie die Funktionsweise der aus-führbaren Datei. Oder anders ausgedrückt: Die ausführbare Datei ist diebinärkodierte Entsprechung der Quellcode-Datei.

ausführbares Programm

Compiler übersetztden Quellcode

Quellcode

Programmierererstellt den Quellcode im Editor

Page 18: Visual C# 2005 easy

Kompilierung 17

Allerdings sind auch Compiler keine Multitalente. Compiler unterscheiden sichin Abhängigkeit sowohl von der Programmiersprache als auch vom System, fürdas die zukünftige Anwendung bestimmt ist. So ist etwa ein C-Compiler nichtin der Lage, einen in einer anderen Programmiersprache geschriebenen Quell-

Warum nicht gleich ...

Da der Computer nur in Maschinensprache vorliegende Befehle unmittel-bar verstehen und damit ausführen kann, mag der Gedanke nahe liegen,das Programm in einer maschinennahen Sprache oder gleich in Maschi-nensprache zu kodieren. In diesem Fall liegt der Quellcode in Form vonNullen und Einsen vor:

011010101001010101011100010111001010101011010110010110011110101100101000110101110101100100101010

Der offensichtliche Nachteil von Maschinencode liegt jedoch in seinerschlechten Lesbarkeit. Er lässt sich daher kaum sinnvoll strukturierenund ist somit nur schwer nachvollziehbar. Hinzu kommt, dass sichMaschinenbefehle nur schwer aus dem Gedächtnis reproduzieren las-sen. Alles zusammengenommen gestaltet sich die Entwicklung einesProgramms auf diese Weise sehr schwer, ganz zu schweigen von einereventuellen späteren Überarbeitung. Auf der anderen Seite lässt sich beiAnweisungen wie

Console.WriteLine("Hallo");

oder

name = Console.ReadLine();

schon ohne Vorwissen erahnen, was sie bewirken. Beide stammen ausdem Sprachschatz von C#. So bewirkt der Ausdruck Console.Write-Line("Hallo");, dass das Wort Hallo auf dem Bildschirm erscheint.Das Line in WriteLine deutet darauf hin, dass zusätzlich die Einfüge-marke an den Beginn der nächsten Zeile (engl. line = Zeile) gesetzt wird.Ebenso wird mit der Anweisung name = Console.ReadLine(); eineEingabe vom Anwender gelesen (engl. to read = lesen) und das Line inReadLine führt auch hier im Anschluss zu einer Zeilenschaltung. BeideAnweisungen werden Sie schon bald genauer kennen lernen. Es liegt aufder Hand, dass für den Vorteil der besseren Erinnerbarkeit und Lesbar-keit mehr interne Übersetzungsschritte bis zum Maschinencode in Kaufgenommen werden müssen. Das braucht Sie aber nicht zu kümmern, daIhnen Ihr Compiler diese Arbeit abnimmt.

Page 19: Visual C# 2005 easy

18 Kapitel 1

code zu übersetzen. Aber auch ein unter Windows kompiliertes C-Programmist z.B. unter Unix-Systemen nicht lauffähig. Wenn Sie also ein entsprechendesLinux-Programm erzeugen möchten, dann müssen Sie denselben Quelltext un-ter einem für diese Plattform vorgesehenen C-Compiler erneut kompilieren.

Integrierte EntwicklungsumgebungenWie Sie gerade erfahren haben, ist es für die Programmierung notwendig, Textin einen Editor einzugeben und diesen dann kompilieren zu lassen. Dazu kannjeder beliebige Texteditor benutzt und für den Übersetzungsvorgang ein exter-nes Programm namens Compiler herangezogen werden.

In modernen Entwicklungsumgebungen ist die Software zum Übersetzen desQuellcodes genauso wie ein mit nützlichen Funktionen ausgestatteter Editor alsfester Bestandteil in ein umfassendes Softwareprogramm eingebunden. Dort wirdder Compiler meist über einen entsprechenden Befehl in der Menüleiste oder nocheinfacher mit einem Klick auf ein Symbol gestartet. Zudem werden in der Regeleine Reihe weiterer Hilfsmittel für die Programmentwicklung bereitgestellt. Weilhier alle Programmierwerkzeuge unter einer Bedienoberfläche zusammengefasstsind, bezeichnet man ein solches System als »integrierte Entwicklungsum-gebung« oder kurz »IDE« (für Integrated Development Environment).

Die bekannteste IDE für C#-Programme ist das Visual Studio .NET von Micro-soft. Es fungiert gleichzeitig als Entwicklungsumgebung für C++- und VisualBasic-Programme. Auch Sie werden mit einer integrierten Entwicklungsumge-bung arbeiten, nämlich der Visual C# 2005 Express Edition von Microsoft. Da-bei handelt es sich um eine komfortable und verhältnismäßig bequem zubedienende Benutzeroberfläche, die ausschließlich für die Entwicklung von.NET Framework-Anwendungen konzipiert ist. Die IDE erweist sich für den An-fänger geradezu als ideal und ist auch für die Entwicklung von professionellen.NET-Applikationen bestens geeignet.

Hinweis

Die Visual C# 2005 Express Edition ist eine »relativ bequem« zu bedie-nende Benutzeroberfläche. Die Einschränkung bezieht sich darauf, dassder Umgang mit modernen Entwicklungssystemen nie ganz ohne daserforderliche Know-how auskommt. Im Übrigen ist die Arbeit mit derVisual C# 2005 Express Edition bestens geeignet, um Sie – neben demErlernen der Programmiersprache C# – gleichzeitig mit der Bedienungaufwändiger Programmieroberflächen vertraut zu machen.

Page 20: Visual C# 2005 easy

Eine kleine Erfolgskontrolle 19

Eine kleine Erfolgskontrolle• Was ist ein Compiler?

• Worin unterscheiden sich Hochsprachen von maschinennahen Sprachen?

• Was ist eine IDE?

Page 21: Visual C# 2005 easy

Das können Sie schon:

Entwicklungsschritte zum ausführbaren Computerprogramm 11

Das lernen Sie neu:

Was der Begriff »Laufzeitumgebung« bedeutet 22

Was es mit dem .NET Framework auf sich hat 24

Wie Sie die Visual C# 2005 Express Edition auf Ihrem Computer installieren 26

Page 22: Visual C# 2005 easy

Kapitel 2

Die Programmier-umgebung von C#In diesem Kapitel gehen wir auf die Besonderheiten bei der Kompi-lierung im Zusammenhang mit C#-Programmen ein. Sie erfahren un-ter anderem, welche Rolle das .NET Framework bei der Ausführung von C#-Programmen spielt. Im Anschluss daran installieren Sie die Visual C# 2005 Express Edition, wobei Sie auf das Setup-Programm der Buch-CD zurückgreifen. Das .NET Framework in der aktuellen Ver-sion wird dabei – sofern es noch nicht auf Ihrem Computer vorhan-den ist – automatisch mitinstalliert.

Page 23: Visual C# 2005 easy

22 Kapitel 2

Besonderheiten bei der Kompilierung in C#Wie in Kapitel 1 beschrieben, wird bei den herkömmlichen Programmierspra-chen der Quellcode vom Compiler mehr oder weniger direkt in Maschinencodeübersetzt, sodass das kompilierte Programm in ausführbarer Form vorliegt.Jedes Betriebssystem besitzt jedoch seine Eigenheiten. Daher muss damitgerechnet werden, dass die fertig übersetzten Programme nur auf Betriebssys-temen laufen, auf denen sie kompiliert wurden.

Intermediate Language CodeDiesem Nachteil der herkömmlichen Programmiersprachen wird in C# begeg-net, indem das .NET Framework zwischen Programm und Betriebssystemgeschaltet wird (allerdings setzt die Ausführung eines C#-Programms voraus,dass eben dieses .NET Framework auf dem Computer installiert ist). Der Quell-code wird vom C#-eigenen Compiler zunächst in eine Zwischenform umgewan-delt. Dieser Zwischencode heißt Intermediate Language Code oder kurzIL-Code. Dieser wird dann bei der Ausführung vom Compiler des .NET Frame-work in die Form gebracht, welche vom jeweiligen Betriebssystem verstandenwird. Es sind also insgesamt zwei Compiler am Werk, einmal der von C# und beider Programmausführung der des .NET Framework.

Hinweis

In den Urzeiten der Programmierung war es nicht einmal die Regel, dassein in einer bestimmten Umgebung verfasster Quelltext auf mehrerenBetriebssystemen kompilierbar war. Wenn ein Quelltext auf verschiede-nen Systemen übersetzt werden kann, sagt man, er (bzw. die entspre-chende Programmiersprache) sei portierbar. Ein großer Vorteil derProgrammiersprache C war von Anfang an deren Portierbarkeit. Dasheißt, ein in C geschriebener Quellcode konnte auf nahezu allen Syste-men kompiliert werden. Die Portierbarkeit von Programmiersprachen hatsich erst in den 80er-Jahren zum Standard entwickelt.

Page 24: Visual C# 2005 easy

Besonderheiten bei der Kompilierung in C# 23

Allgemein lässt sich feststellen:

• Das .NET Framework muss auf jedem Computer installiert sein, welcherC#-Anwendungen ausführen soll.

• Umgekehrt kann auf jedem Computer (mit beliebigem Betriebssystem)jede C#-Anwendung ausgeführt werden, sobald dort das .NET Frameworkvorhanden ist.

Daher muss, um den Weg von der Programmierung bis zum erfolgreichen Pro-grammlauf zu verdeutlichen, die Darstellung in Kapitel 1 (Abschnitt »Kompilie-rung«) für C#-Programme etwas modifiziert werden (Abbildung 2.1).

Abbildung 2.1: Vom C#-Quellcode bis zur Programmausführung

Hinweis

Ein Vorläufer dieses Konzepts ist die Programmiersprache Java. Auch derCompiler von Java erzeugt zunächst so genannte class-Dateien, welche beider Ausführung dann die Java Virtual Machine (JVM) benötigen. Inzwischenkann das Vorhandensein der Java Virtual Machine auf den Computern vor-ausgesetzt werden. Die Funktionsweise der JVM für Java-Programme ent-spricht hier der des .NET Framework für C#-Anwendungen.

Programmlauf

der Compiler des .NET Frameworkübersetzt den IL-Code in

systemspezifischen,ausführbaren Code

IntermediateLanguage Code

Quellcode

der Compiler von C# übersetztden Quellcode in IL-Code

Programmierererstellt den Quelltext im Editor

Page 25: Visual C# 2005 easy

24 Kapitel 2

Beachten Sie, dass sich beide Darstellungen nicht widersprechen. Nach derÜbersetzung der C#-Quellcode-Datei durch den C#-Compiler liegt bereits einfertiges Endprodukt vor. Nur benötigt dieses sozusagen ausführbare Pro-gramm eine besondere Laufzeitumgebung, eben das .NET Framework.

Das .NET FrameworkDieser Abschnitt soll Ihnen einen kurzen Überblick über das .NET Frameworkverschaffen. Sie werden einiges Wissenswertes über das .NET Framework er-fahren. Bestimmte Features des .NET Framework werden Sie aber möglicher-weise erst dann näher einordnen können, wenn Sie schon mehr über dieProgrammierung in C# wissen.

Das .NET Framework stellt die Laufzeitumgebung für C#-Programme dar,ähnlich der Java Virtual Machine für Java-Anwendungen. Die Funktionalität des.NET Framework ist aber wesentlich umfassender als die der JVM. So dient das.NET Framework als Laufzeitumgebung für mehrere Programmiersprachen, diein diesem Kontext auch miteinander interagieren können. Weitere Program-miersprachen können für eine Unterstützung an das .NET Framework ange-passt werden. Somit ist das .NET Framework nicht nur unabhängig vomBetriebssystem, sondern in gewisser Weise auch von der verwendeten Pro-grammiersprache.

Daneben stellt das .NET Framework eine Reihe von Hilfsmitteln zur Verfügung,welche die Programmentwicklung erleichtern und eine Verbesserung des Lauf-zeitverhaltens der Programme mit sich bringen. Ganz allgemein lässt sich fest-stellen, dass das .NET Framework nicht nur als Laufzeitumgebung dient,sondern zusätzlich den Programmcode verwaltet.

Laufzeitumgebung – was ist das?

Benötigt ein Programm eine bestimmte Software, damit es ausgeführtwerden kann, spricht man von einer Laufzeitumgebung (engl. RuntimeEnvironment).

Hinweis

Die Entwicklung von C# wurde speziell am Konzept des .NET Frameworkausgerichtet. C# als Systemsprache des .NET Framework zieht somit ausden genannten Vorteilen besonders großen Nutzen.

Page 26: Visual C# 2005 easy

Das .NET Framework 25

Übrigens wird vom .NET Framework auch ein C#-Compiler zur Verfügung ge-stellt. Sein Dateiname ist csc.exe und er lässt sich mit dem Befehl csc auch vonder Konsole aus starten.

Eine Besonderheit beim Kompilieren von C#-Programmen soll nun noch her-ausgestellt werden. Diese Besonderheit betrifft den Compiler des .NET Frame-work. Betrachten Sie dazu nochmals die Abbildung am Ende des letztenAbschnitts. Wir gehen von dem Fall aus, dass die Entwicklung eines Computer-programms bereits abgeschlossen ist (also der IL-Code vorliegt) und nun aus-geführt werden soll. Nehmen wir an, es handle sich um eine Anwendung, diedem Benutzer mehrere mathematische Berechnungsfunktionen zur Verfügungstellt, von denen er eine auswählen kann. Dann könnte sich etwa die in Abbil-dung 2.2 dargestellte Konstellation ergeben.

Abbildung 2.2: Verschiedene Programmzweige

Man spricht in diesem Fall von einer Programmverzweigung, da die Befehle andas Computerprogramm je nach Benutzerauswahl verschieden sind. Ange-nommen, der Benutzer hätte die Potenzfunktion des Programms gewählt. Fürdiesen Fall kommen andere Anweisungen zur Ausführung, als wenn er sichetwa für die Addition entschieden hätte. Es wäre nun schön, wenn nur die Be-

Hinweis

Das .NET Framework wird auch kurz .NET genannt (gesprochen »dotnet«). Die ursprünglich zugedachte Bezeichnung für das .NET Frameworkwar NGWS, was für »Next Generation Windows Services« steht und soviel heißt wie »Windows-Dienste der nächsten Generation«. Dieser Name(Next Generation Windows Services) macht zwei wesentliche Aspektebesonders deutlich: zum einen die Bereitstellung von zusätzlichenDiensten und zum anderen die enge Verbindung des .NET Framework mitdem Betriebssystem.

�����������

����������

��������

�������

�� ��� ������

��������������

Page 27: Visual C# 2005 easy

26 Kapitel 2

fehle in Maschinencode übersetzt werden würden, die tatsächlich gebrauchtwerden (hier die Befehle für das Potenzieren) und nicht alle Programmanwei-sungen.

Und genauso verhält es sich auch. Der Compiler des .NET Framework übersetztnicht auf ein Mal den ganzen Zwischencode und legt ihn in Maschinenspracheab, sondern kompiliert die Befehle des IL-Codes erst dann, wenn sie gebrauchtwerden. Aus diesem Grund bezeichnet man den Compiler des .NET Frameworkauch als »Just-in-Time-Compiler« (oder kurz JITter). Sollte nun während dessel-ben Programmlaufs die Potenzfunktion durch den Anwender erneut aufgeru-fen werden, liegen die entsprechenden Befehle bereits in Maschinencode vorund der JITter des .NET Framework wird den entsprechenden IL-Code nichterneut übersetzen. Er wird stattdessen gleich auf den für diesen Programm-zweig bereits vorhandenen Maschinencode zurückgreifen. Somit gestaltetsich der Übersetzungsvorgang im Kontext des .NET Framework sehr effizient.

Installation der Visual C# 2005 Express EditionBei der Visual C# 2005 Express Edition handelt es sich erfreulicherweise umeine vollwertige Teilmenge des Visual Studio 2005 und nicht etwa um einefunktional eingeschränkte oder gar zeitlich befristete Demoversion. Sie eignetsich vom Hobbyprogrammierer bis zum professionellen Softwareentwickler.Die Software ist konzipiert für Windows 2000 (ab Service Pack 4), Windows XP(ab Service Pack 2), Windows Server 2003 (ab Service Pack 1) und WindowsVista. Außerdem sollten Sie über mindestens 256 MB RAM und einen Prozes-

Hinweis

Wir sprechen oben vom JITter bzw. vom Compiler des .NET Framework.Dies ist eine Vereinfachung, welche der Anschaulichkeit dienen soll, undentspricht nicht ganz den Tatsachen. Denn eigentlich handelt es sichnicht nur um einen, sondern um mehrere Compiler, die zum .NET Frame-work gehören. Zum Beispiel wird das .NET Framework für Windows-Betriebssysteme mit drei verschiedenen Just-in-Time-Compilern ausge-liefert. Es existiert auch ein Programm namens JIT Compiler Manager, mitdem sich bestimmte Einstellungen bezüglich dieser Compiler vornehmenlassen. Damit könnten Sie auf Laufzeit und Speicherplatzbedarf Ihrer C#-Programme Einfluss nehmen. Dies sei nur ergänzend erwähnt; im Allge-meinen besteht keine Notwendigkeit, an den StandardeinstellungenÄnderungen vorzunehmen.

Page 28: Visual C# 2005 easy

Installation der Visual C# 2005 Express Edition 27

sor mit wenigstens 1 Gigahertz verfügen (angegebene Mindestwerte: 192 MBund 600 Megahertz).

Die Installation der Visual C# 2005 Express Edition erweist sich in der Regel alsunkompliziert. Bevor Sie mit der Installation beginnen, sollten Sie alle laufen-den Programme schließen.

1 Legen Sie die Buch-CD in Ihr CD- bzw. DVD-Laufwerk ein. Falls die Installation nicht automatisch startet, navigieren Sie im Windows-Explorer zum entsprechenden Ver-zeichnis und starten das Installationsprogramm durch Doppelklick auf die Datei setup.exe.

Zunächst kopiert das Setup-Programm alle benötigten Dateien in ein temporä-res Verzeichnis und lädt die Installationskomponenten in den Arbeitsspeicher.

Achtung

Über die genauen Systemvoraussetzungen für die Installation der VisualC# 2005 Express Edition können Sie sich in der Datei readme.htm bzw. inder Datei contents.htm auf der Buch-CD informieren.

Achtung

Vor der Installation müssen Sie alle Vorabversionen von Microsoft SQLServer 2005, Visual Studio 2005 und .NET Framework 2.0 deinstallieren.Sollten Sie tatsächlich Beta-Versionen dieser Produkte auf Ihrem Com-puter installiert haben, lesen Sie bitte in der Datei readme.htm bzw. inder Datei contents.htm (Buch-CD) unter Punkt 1.2 Deinstallieren vonExpress-Editionen nach.

Hinweis

Um die Installation des .NET Framework brauchen Sie sich nicht weiterzu kümmern. Es wird bei der Installation der Visual C# 2005 Express Edi-tion – sofern noch nicht vorhanden – automatisch mitinstalliert.

Page 29: Visual C# 2005 easy

28 Kapitel 2

Dieser Vorgang sollte allenfalls einige Minuten in Anspruch nehmen. Danachwerden Sie vom Setup-Assistenten begrüßt.

Abbildung 2.3: Der Setup-Assistent stellt sich vor

Falls Sie Ihre Erfahrungen mit der Installation an Microsoft weitergeben möch-ten, aktivieren Sie das entsprechende Kontrollkästchen.

2 Klicken Sie auf die Schaltfläche Weiter >.

Falls Sie die Lizenzbedingungen ausdrucken möchten, klicken Sie im folgen-den Dialog zunächst die entsprechende Schaltfläche an.

Page 30: Visual C# 2005 easy

Installation der Visual C# 2005 Express Edition 29

3 Sie müssen die Lizenzbedingungen akzeptieren, um die Installation fortsetzen zu können. Setzen Sie daher im Kontrollkästchen unten ein Häkchen. Danach klicken Sie wiederum auf Weiter >.

Entscheiden Sie sich nun bei Bedarf für eine zusätzliche Installation des ange-botenen Programms Microsoft SQL Server. Dieser kann Ihnen für die Zukunft,wenn Sie Anwendungen mit Datenbankanbindung erstellen, sehr von Nutzensein. Es sei jedoch darauf hingewiesen, dass Sie ihn zum Durcharbeiten diesesBuchs nicht benötigen. Das Angebot zur Installation der MSDN Express Librarysollten Sie auf jeden Fall wahrnehmen. Ansonsten müssten Sie bei der Arbeitmit Visual C# Express jedes Mal auf das Internet zugreifen, um Hilfe von MSDNOnline zu erhalten.

Page 31: Visual C# 2005 easy

30 Kapitel 2

4 Klicken Sie erneut auf Weiter >.

Legen Sie im folgenden Dialog den Ort fest, an dem die Software installiertwerden soll. Falls Sie die Voreinstellung C:\Programme\Microsoft Visual Stu-dio 8 nicht übernehmen möchten, klicken Sie auf Durchsuchen... und wählenSie ein anderes Zielverzeichnis aus. Wenn das Verzeichnis, das Sie hier ange-ben, nicht existiert, wird es automatisch angelegt.

Page 32: Visual C# 2005 easy

Installation der Visual C# 2005 Express Edition 31

5 Starten Sie nun den eigentlichen Installationsvorgang mit Klick auf die Schaltfläche Installieren >.

Danach brauchen Sie sich vorerst um nichts mehr zu kümmern. Die Installationselbst nimmt gewöhnlich – in Abhängigkeit von der Computergeschwindigkeitund den Installationsoptionen – eine Weile in Anspruch. Warten Sie einfach ab,bis Ihnen das Setup-Programm das erfolgreiche Ende der Installation mitteilt.Ein Computer-Neustart ist danach in der Regel nicht erforderlich.

Page 33: Visual C# 2005 easy

32 Kapitel 2

Abbildung 2.4: Die eigentliche Installation geht ohne weiteres Zutun vonstatten

Abbildung 2.5: Die Visual C# 2005 Express Edition inklusive .NET Framework ist installiert

Page 34: Visual C# 2005 easy

Eine kleine Erfolgskontrolle 33

6 Klicken Sie auf Beenden.

Haben Sie sich auf der Willkommensseite dafür entschieden, Ihre Erfahrungenmit der Installation weiterzugeben, werden die entsprechenden Informationen– wobei es sich nicht um persönliche Daten handelt – nun zu den Servern vonMicrosoft gesendet.

Damit haben Sie die Visual C# 2005 Express Edition erfolgreich auf Ihrem Com-puter installiert.

Eine kleine Erfolgskontrolle• Was bedeutet der Begriff »Laufzeitumgebung«?

• Was hat es mit dem IL-Code auf sich?

• Welcher Compiler erzeugt aus dem Quellcode den IL-Code?

• Welche Rolle spielt der Compiler des .NET Framework bei der Ausführungvon C#-Programmen?

• Wie lautet eine zusammenfassende Beschreibung der Bedeutung des .NETFramework für die Ausführung von C#-Programmen?

Page 35: Visual C# 2005 easy

Das können Sie schon:

Die Entwicklungsschritte zum ausführbaren Programm 11

Die Bedeutung des .NET Framework für C#-Programme 24

Das lernen Sie neu:

Kompilieren und Ausführen eines C#-Programms 35

Wie Visual C# Express Ihre Projekte verwaltet 43

Page 36: Visual C# 2005 easy

Kapitel 3

Ihr erstes C#-ProgrammIn diesem Kapitel werden Sie Ihr erstes Erfolgserlebnis als C#-Pro-grammierer haben. Sie erstellen Ihr erstes kleines C#-Programm und bringen dieses zur Ausführung. Außerdem erfahren Sie, wie Visual C# Express Ihre Projekte verwaltet.

Page 37: Visual C# 2005 easy

36 Kapitel 3

Programmentwicklung mit der Visual C# 2005 Express EditionWir gehen davon aus, dass Sie nicht länger auf Ihr erstes Programm wartenwollen und die einzelnen Schritte von der Eingabe des Quellcodes über dessenKompilierung bis zur Programmausführung schnell kennen lernen möchten.Daher werden Sie im Folgenden ein Konsolenprogramm erstellen, welches sichallerdings fürs Erste darin erschöpfen wird, den Text Mein erstes C#-Pro-gramm auf den Bildschirm auszugeben.

Konsolenprogramm – was ist das?

Zu alten Zeiten von DOS und anderer älterer Betriebssysteme lief die Kom-munikation zwischen Anwender und Computer in aller Regel über die sogenannte Konsole ab. Zur Eingabe diente die Tastatur und zur Ausgabe derBildschirm. Dabei bildete die Einheit aus Tastatur und Bildschirm die Kon-sole. Die Ausgabe erfolgte zeilenweise von oben nach unten, wobei hierfürder ganze Bildschirm zur Verfügung stand. Der Computer nahm dabei Ein-gaben des Benutzers (Befehle an das Betriebssystem, aber auch Start-befehle für Computerprogramme) in der aktuellen Zeile entgegen. Dabeiforderte eine meist blinkende Einfügemarke zur Eingabe auf. Diese Stellewird eben »Eingabeaufforderung«, »Befehlszeile« oder kurz »Prompt«genannt. Falls am Prompt der Startbefehl für ein Programm eingegebenwurde (durch Eingabe der dafür notwendigen Zeichenfolge über die Tasta-tur und anschließendes Betätigen der (¢)-Taste), übernahm dieses Pro-gramm gewissermaßen die Konsole. Das heißt, das aufgerufeneProgramm nutzte die Konsole – damals also den ganzen Bildschirm – fürMitteilungen an den Benutzer und um Daten vom Benutzer entgegenzu-nehmen (»Geben Sie bitte … ein: «, »Das Ergebnis ... ist …«).

Heutzutage verläuft die Kommunikation zwischen Anwender und Pro-gramm in der Regel über grafische Benutzeroberflächen. Dies gilt z.B.auch für die Interaktion mit dem Betriebssystem. So bietet Windows ver-schiedene grafische Schnittstellen zum Starten von Computerprogram-men an, etwa über Einträge im Start-Menü, Symbole auf dem Desktopund eine Auflistung von ausführbaren Dateien im Windows-Explorer. Dasändert aber nichts an der Tatsache, dass die Konsole unter Windowsnach wie vor zur Verfügung steht. Nur nimmt sie nicht mehr wie früherden ganzen Bildschirm ein, sondern läuft in einem Fenster. Die Fixierungauf die zeilenweise Ausgabe sowie das Prinzip der Eingabe von Befehlengelten weiterhin. Außerdem erscheint die Konsole nicht sofort beim Start

Page 38: Visual C# 2005 easy

Programmentwicklung mit der Visual C# 2005 Express Edition 37

Aus einer ganzen Reihe von Gründen werden wir uns zum Erlernen der Pro-grammiersprache C# zunächst auf Konsolenprogramme beschränken. Dieswird Sie möglicherweise zunächst etwas enttäuschen, da grafische Program-me optisch ansprechender sind und weit mehr Möglichkeiten bieten als dierein textorientierten Konsolenprogramme. Dieses Vorgehensweise ist aber vongroßem Vorteil, für die ersten Schritte beim Erlernen einer Programmierspra-che sogar ideal, da Sie sich auf diese Weise ohne weiteren Ballast auf das We-sentliche konzentrieren können. Umgekehrt wird es Ihnen dann später leichterfallen, sich auf die Windows-Programmierung einzustellen, wenn Sie das ABCder Programmiersprache C# bereits beherrschen. Nichtsdestoweniger werdenSie alle Ihre Programme mit der Visual C# Express-Oberfläche erstellen. Dieseerlaubt es Ihnen, den Quellcode für ein Programm bequem zu kompilieren unddas Programm gleichzeitig aus Visual C# Express heraus zu starten. Dies giltselbstverständlich auch für Konsolenprogramme. Das heißt, Sie brauchen sichum den Aufruf der Eingabeaufforderung (Konsole) nicht selbst zu kümmern,wie Sie im Folgenden gleich sehen werden.

1 Starten Sie Visual C# Express, z.B. über Start/Alle Programme/Microsoft Visual C# 2005 Express Edition.

2 Klicken Sie im Menü Datei auf Neues Projekt....

des Computers, sondern ist ebenfalls über grafische Schnittstellenerreichbar. Unter Windows erreichen Sie die Konsole z.B. über Start/AlleProgramme/Zubehör/Eingabeaufforderung bzw. Start/Programme/Zube-hör/Eingabeaufforderung oder über Start/Ausführen.... Im letzteren Fallmüssen Sie in der dann erscheinenden Dialogbox in das Textfeld cmdeintippen und mit Klick auf die Schaltfläche OK bestätigen; danach befin-den Sie sich auf der Konsole.

Ein Konsolenprogramm zeichnet sich dadurch aus, dass es selbst keinegrafische Benutzeroberfläche (auch GUI genannt; für »Graphical UserInterface«) zur Verfügung stellt, sondern für die Interaktion mit demAnwender eben ausschließlich die Konsole benutzt.

Page 39: Visual C# 2005 easy

38 Kapitel 3

Abbildung 3.1: So beginnen Sie ein neues Programmierprojekt

Daraufhin wird das Dialogfeld Neues Projekt angezeigt, das verschiedene Pro-jektvorlagen zur Auswahl anbietet. Dabei handelt es sich um Standardanwen-dungstypen, welche die Visual C# 2005 Express Edition für Sie erstellen kann.

3 Wählen Sie die Projektvorlage Konsolenanwendung aus und ändern Sie im unte-ren Textfeld den Namen der Anwendung in Mein erstes Programm.

Natürlich könnten Sie Ihrem ersten Projekt auch einen anderen Namen gebenoder es bei der Vorgabe ConsoleApplication1 belassen.

Page 40: Visual C# 2005 easy

Programmentwicklung mit der Visual C# 2005 Express Edition 39

Abbildung 3.2: Mit der Auswahl der Projektvorlage bestimmen Sie den Projekttyp

4 Klicken Sie auf OK.

Die Visual C# 2005 Express Edition erstellt nun eine neue Projektmappe für IhrProjekt und es erscheint ein Fenster für den Codebereich, in dem Sie den C#-Quellcode eingeben bzw. vervollständigen können. Zur besseren Übersichthier das vorgegebene Grundgerüst der Klasse Program:

class Program{ static void Main(string[] args) { }}

Listing 3.1: Von Visual C# Express erzeugtes Grundgerüst der Hauptklasse

5 Fügen Sie der Main()-Methode die beiden nachfolgenden Befehle hinzu:

Console.WriteLine("Mein erstes C#-Programm");Console.ReadLine();

Setzen Sie dazu die Einfügemarke an das Ende der Zeile, welche auf die Zeilestatic void Main(string[] args) folgt – also hinter die öffnende ge-schweifte Klammer ({) – und drücken Sie die (¢)-Taste, um eine neue Zeile zubeginnen. Beachten Sie, wie der Editor die Einfügemarke automatisch nachrechts verschiebt, um einen Zeileneinzug zu erzeugen. Tippen Sie an der vor-

Page 41: Visual C# 2005 easy

40 Kapitel 3

gegebenen Stelle die Anweisung Console.WriteLine("Mein erstes C#-Programm"); ein (vergessen Sie das abschließende Semikolon nicht) unddrücken Sie wiederum (¢). Zum Schluss geben Sie die AnweisungConsole.ReadLine(); ein:

class Program{ static void Main(string[] args) { Console.WriteLine("Mein erstes C#-Programm"); Console.ReadLine(); }}

Listing 3.2: Der vollständige Code der Klasse Program

Die erste Anweisung sorgt dafür, dass beim Programmlauf der Text Mein ers-tes C#-Programm im Konsolenfenster erscheint. Falls Sie eine anderslauten-de Ausgabe wünschen, geben Sie zwischen den Anführungszeichen ("") denentsprechenden Text ein. Die zweite Anweisung hält das Programm an, bis dieEingabetaste gedrückt wird. Falls Sie die letzte Anweisung weglassen, wirddas Konsolenfenster nach der Programmausführung sofort wieder geschlos-sen, sodass Sie von der Ausgabe des Programms kaum etwas zu sehen be-kommen werden. Console ist der Name einer Klasse, WriteLine() undReadLine() sind Methoden dieser Klasse. Was es mit Klassen, Methoden undanderen Programmbestandteilen auf sich hat, wird später noch ausführlich be-schrieben.

Achtung

Halten Sie sich an die vorgegebene Groß- und Kleinschreibung. Schrei-ben Sie also nicht etwa console oder Writeline (richtig: Consolebzw. WriteLine).

Page 42: Visual C# 2005 easy

Programmentwicklung mit der Visual C# 2005 Express Edition 41

Abbildung 3.3: Der Quellcode Ihres ersten C#-Programms

6 Drücken Sie die (F5)-Taste.

Damit bringen Sie Ihr Programm zur Ausführung. Falls Ihr Code fehlerhaft ist,blendet Visual C# Express im unteren Bildschirmbereich ein Fenster mit der Be-zeichnung Fehlerliste ein, welches Ihnen für jeden Fehler eine Beschreibungmit Zeilen- und Spaltennummer anzeigt. Außerdem wird standardmäßig zu-sätzlich ein Dialogfeld mit der Fehlermeldung »Fehler beim Erstellen. MöchtenSie den Vorgang fortsetzen und den letzten erfolgreichen Build ausführen?«eingeblendet, das Sie mit einem Klick auf Nein schließen. Soll das Dialogfeldmit dieser Meldung in Zukunft nicht mehr erscheinen, aktivieren Sie das Kon-

Tipp

Lassen Sie sich bei der Eingabe von Schlüsselwörtern, Klassen- oderMethodennamen von IntelliSense helfen. Dieses Tool ist im Code-Editorvon Visual C# Express fest eingebaut. Es bietet Ihnen während der Ein-gabe eine Popup-Liste mit Namen an, die mit den bereits eingegebenenZeichen beginnen. Mit dem weiteren Eintippen wird die Auswahl immerweiter verfeinert. Damit genügt es oft, nur die ersten Zeichen selbst ein-zutippen und dann einen der Vorschläge zu übernehmen. Sobald dasgewünschte Wort ausgewählt ist, können Sie dieses dem Code hinzufü-gen, indem Sie die Eingabetaste drücken, das Wort doppelt anklickenoder ein Zeichen eingeben, das keinen Buchstaben bzw. keine Ziffer dar-stellt, z.B. eine öffnende Klammer (Letzteres ist besonders praktisch,wenn nach dem Namen ohnehin eine Klammer folgen soll, es lässt sichdann weiter Tipparbeit sparen).

Page 43: Visual C# 2005 easy

42 Kapitel 3

trollkästchen Dieses Dialogfeld nicht mehr anzeigen, bevor Sie auf Nein kli-cken. Überarbeiten Sie nun die fehlerhaften Codeteile und drücken Sie erneut(F5).

Abbildung 3.4: Das Programm wird ausgeführt

Ihr Programm sollte nun genau das machen, wozu Sie es bestimmt haben: dieZeichenfolge Mein erstes C#-Programm auf den Bildschirm ausgeben.

7 Beenden Sie das Programm durch Drücken der (¢)-Taste.

Zum Speichern des aktuellen Projekts verwenden Sie den Menübefehl Datei/Alle Speichern (Shortcut (Strg)+(ª)+(S)) oder klicken Sie das entsprechen-de Icon an. Ansonsten werden Sie beim Beenden der Visual C# 2005 ExpressEdition gefragt (»Sollen die Änderungen in der aktuellen Projektmappe gespei-chert oder verworfen werden?«). Legen Sie im folgenden Dialog denSpeicherort für Ihr Projekt fest.

Es steht Ihnen frei, von Visual C# Express zusätzlich ein Projektmappenver-zeichnis erstellen zu lassen. Dies erscheint allerdings erst dann sinnvoll, wennSie in einer professionellen Anwendung mehrere Projekte zusammenfassenund die entsprechende Struktur auch auf der Festplatte wiedergeben möchten(zu Projektmappen siehe den nächsten Abschnitt).

Hinweis

Beim Anlegen eines neuen Projekts speichert Visual C# Express diebenötigten Dateien vorerst in einem temporären Verzeichnis und verwirftsie später wieder, falls auf eine Speicherung des aktuellen Projekts ver-zichtet wird.

Tipp

Richten Sie der Ordnung halber für Ihre C#-Programme einen separatenOrdner ein – womöglich sogar zwei Unterordner, einen für Ihre Konsolen-programme, den anderen für Ihre Windows-Programme.

Page 44: Visual C# 2005 easy

Projektmappen und Projekte 43

Abbildung 3.5: Mit dem Speichern legt Visual C# Express einen Ordner für Ihr Projekt mit den zugehörigen Dateien und Verweisen an

Projektmappen und ProjekteDie Visual C# 2005 Express Edition verwaltet den Code in Projekten und Pro-jektmappen, wobei eine Projektmappe nicht nur ein Projekt, sondern auchmehrere Projekte enthalten kann und damit als eine Art Container für Projektefungiert. Wenn Sie z.B. ein selbst programmiertes grafisches Steuerelement,etwa eine Schaltfläche, in Form eines eigenes Projekts auslagern, können Siedieses gleichzeitig in mehreren Applikationen – also in mehreren Projektmap-pen – verwenden, indem Sie es einfach den entsprechenden Projektmappenhinzufügen. Solange Sie jedoch noch keine umfangreichen professionellen An-wendungen entwickeln, werden Ihre Projektmappen in der Regel mit nur einemProjekt auskommen.

Zum Verständnis: Die Projektmappe selbst ist grundsätzlich rein virtuell, alsoauch nach dem Speichern eines Projekts nicht als Ordner auf der Festplattevorhanden. Allerdings können Sie Visual C# 2005 Express im Speicherdialoganweisen, einen Projektmappenordner anzulegen (siehe oben).

Auf der CD-ROM

Das Beispiel finden Sie im Ordner Beispiele/Konsolenprogramme derBuch-CD unter dem Projektnamen (= Projektordner) Mein erstes Pro-gramm. Um ein bestehendes Beispiel in Visual C# Express zu öffnen, öff-nen Sie die Projektmappendatei – das ist die Datei mit der Erweiterung.sln. Sobald Sie eine Projektmappendatei laden, werden alle der Projekt-mappe zugeordneten Elemente ebenso geöffnet. Um das Beispiel zuöffnen, rufen Sie in der Menüleiste den Eintrag Datei/Projekt öffnen...auf, navigieren im Dialogfenster Projekt öffnen zum Projektordner Meinerstes Programm und wählen schließlich die Datei Mein erstes Pro-gramm.sln aus.

Page 45: Visual C# 2005 easy

44 Kapitel 3

Projektmappen-ExplorerDer Projektmappen-Explorer ist Teil Ihrer Entwicklungsumgebung (IDE) undstellt ein Werkzeug zum Anzeigen und Verwalten von Projektmappen mit dendazugehörigen Projekten (gegebenenfalls mit nur einem Projekt) und Elemen-ten dar. Bei Letzteren kann es sich um Verweise, Datenverbindungen, Ordnerund Dateien handeln.

Die Datei, auf die es in Ihren weiteren Programmen vor allem ankommt, ist Pro-gram.cs. Sie enthält unter anderem den Code der Main()-Methode, in welcherfürs Erste der Großteil Ihrer Programmiertätigkeit stattfindet (was es mit dieserMethode auf sich hat, erfahren Sie gleich im nächsten Kapitel). Um das Editor-fenster mit dem Code von Program.cs zur Anzeige zu bringen, führen Sie imProjektmappen-Explorer einen Doppelklick auf den Dateieintrag aus.

Abbildung 3.6: Mit dem Projektmappen-Explorer können Sie in Ihren Projekten navigieren

Hinweis

Zum Anzeigen des Projektmappen-Explorers wählen Sie in der Menü-leiste Ansicht/Projektmappen-Explorer oder klicken Sie auf der Symbol-leiste (rechts oben) auf das Symbol Projektmappen-Explorer. Eineweitere Möglichkeit besteht im Shortcut (Strg) + (W), (S) (bei gehalte-ner (Strg)-Taste nacheinander die Tasten (W) und (S) drücken).

Page 46: Visual C# 2005 easy

Hätten Sie gedacht ... 45

Es sei an dieser Stelle darauf hingewiesen, dass Ihre IDE Visual C# 2005 Ex-press sehr komfortabel, aber natürlich auch sehr komplex ist. Das bedeutetunter anderem, dass für eine Funktion in der Regel mehrere Wege zur Verfü-gung stehen. So können Sie das Fenster des Projektmappen-Explorers bei-spielsweise auch mit dessen Kontextmenü ausblenden (Klick mit der rechtenMaustaste auf die Titelleiste und Auswahl von Automatisch im Hintergrund).Es gibt zwei gute Gründe, hier nicht alle Möglichkeiten der Visual C# 2005 Ex-press Edition darzustellen. Zum einen würde es den Umfang dieses Buchs beiweitem überschreiten. Zum anderen würde es Sie zum jetzigen Zeitpunkt ver-mutlich nur verwirren, mit Details Ihrer Visual C#-IDE überfrachtet zu werden.Im Übrigen sei empfohlen, für Informationen zur Oberfläche der Visual C# 2005Express Edition nach und nach die sehr gute und ausführliche Hilfe zu bemü-hen. Sie rufen die Hilfe mit (F1) oder in der Menüleiste unter Hilfe auf.

Hätten Sie gedacht ... ... dass Microsoft auf der Internetseite http://www.learnvisualstudio.net/videos/Visual_CSharp_2005_Express_Edition_for_Beginners.htmeine Reihe von Video-Animationen zur Visual C# 2005 Express Edition an-bietet?

Hinweis

Um den Projektmappen-Explorer zu schließen, klicken Sie rechts in derTitelleiste des Fensters auf den Schließen-Button. Mit dem Stecknadel-symbol blenden Sie das Fenster des Projektmappen-Explorers aus. Diesgilt auch für andere Fenster, etwa das Eigenschaftenfenster oder dieToolbox (Letztere werden für Sie erst später von Bedeutung sein).

Tipp

Das Video Getting started with Visual C# 2005 Express Edition könnenSie mit der URL http://msdn.microsoft.com/vstudio/express/media/en/AbsoluteBeginner/vc/01vcs.wvx kosten-los in Ihrem Windows Media Player anschauen. Für weitere Videosändern Sie einfach die Ziffer im Dateinamen – für das nächste Videogeben Sie also die Adresse http://msdn.microsoft.com/vstudio/express/media/en/AbsoluteBeginner/vc/02vcs.wvxan usw.

Page 47: Visual C# 2005 easy

Das können Sie schon:

Entwicklungsschritte zum ausführbaren C#-Programm 11

Kompilieren und Ausführen von C#-Programmen 35

Programmentwicklung mit Visual C# Express 36

Projekte und Projektmappen 43

Das lernen Sie neu:

Erstellen des Quellcodes 47

Aufbau von C#-Programmen 48

Page 48: Visual C# 2005 easy

Kapitel 4

Aufbau von C#-ProgrammenIn diesem Kapitel erfahren Sie etwas über den grundsätzlichen Auf-bau eines C#-Programms. Dabei wird das Beispiel aus dem vorigen Kapitel noch einmal Schritt für Schritt umgesetzt und näher erklärt, wodurch Sie bereits mit den wesentlichen Grundlagen der Program-miersprache C# vertraut gemacht werden.

Page 49: Visual C# 2005 easy

48 Kapitel 4

Aufbau von C#-ProgrammenWir müssen uns also überlegen, wie unser Quellcode auszusehen hat. C# un-terliegt wie jede andere Programmiersprache bestimmten Syntaxregeln undVorgaben, die Sie beachten müssen. Halten Sie sich dagegen nicht an diese,bricht der Compiler beim Übersetzen den Kompiliervorgang ab und antwortetmit einer oder mehreren Fehlermeldungen.

Jedes einzelne Zeichen hat in C# eine ganz bestimmte Bedeutung. Gerade Pro-grammiersprachen wie C#, deren Entwicklung sich auf die Sprache C zurück-verfolgen lässt, sind darin sehr empfindlich.

Von innen nach außenWie ist nun ein C#-Programm aufgebaut? Die kleinste Einheit eines C#-Pro-gramms wurde schon angesprochen. Es handelt sich um die einzelnenProgrammbefehle. Diese werden »Anweisungen«, »Statements« oder kurz»Befehle« genannt. Jede einzelne, syntaktisch korrekte Anweisung hat eineganz bestimmte Wirkung. Zum Beispiel bewirkt die Anweisung name =Console.ReadLine(); unter anderem, dass eine Eingabe vom Benutzerempfangen wird, und die Anweisung Console.WriteLine("Hallo"); er-zeugt die Bildschirmausgabe Hallo – wobei das »Line« in WriteLine einezusätzliche Zeilenschaltung bewirkt.

Die letzte Anweisung kommt also dem, was wir mit unserem ersten Programmerreichen wollen, sehr nahe. Wir möchten aber nicht Hallo, sondern Meinerstes C#-Programm auf dem Bildschirm stehen haben. Daher notieren Siewie folgt.

Console.WriteLine("Mein erstes C#-Programm");

Denn auf dem Bildschirm wird genau das ausgegeben, was in den Klammernzwischen den doppelten Anführungszeichen steht. Falls Sie einen anderen Textausgeben wollen, müssen Sie dort diesen anstelle von Mein erstes C#-Programm eintippen.

Page 50: Visual C# 2005 easy

Aufbau von C#-Programmen 49

Haben Sie bei den Anweisungen, die Sie bisher gesehen haben, eine Gemein-samkeit entdeckt? Es geht um das Semikolon (;) am Ende. Merken Sie sichschon einmal: Jede Anweisung in C# muss mit einem Semikolon enden. DasFehlen eines Semikolons am Ende einer Anweisung wird als Syntaxfehler inter-pretiert.

Somit besteht unser Code bis jetzt lediglich aus der Anweisung

Console.WriteLine("Mein erstes C#-Programm");

Selbstverständlich ist die Ausgabeanweisung syntaktisch korrekt. Dennochwürde sich Ihr Compiler auf einen Kompilierversuch hin mit einer oder garmehreren Fehlermeldungen beschweren. Da Anweisungen ja die kleinste Ein-heit eines C#-Programms darstellen, müssen sie in eine größere eingebunden– sozusagen »verpackt« – werden. Diese dürfen nicht, so wie es jetzt der Fallist, für sich alleine im freien Raum stehen.

Der Methoden-»Karton«Die nächstgrößere Einheit heißt »Methode«. Ein C#-Programm kann genausowie mehrere Anweisungen auch mehrere Methoden besitzen und jede dieserMethoden kann eine beliebige Anzahl von Anweisungen enthalten. Jede An-weisung in C# muss jedoch innerhalb einer Methode stehen. Sie können sichdas so vorstellen wie eine Aneinanderreihung einzelner Kartons mit Inhalt, den

Achtung

Vermeiden Sie in jedem Fall einen Zeilenumbruch innerhalb des Aus-gabetextes. Wenn dieser zu lang wird, dann benutzen Sie nacheinanderdie Befehle Console.Write(); und Console.WriteLine();:

Console.Write("Dies ist mein erstes, aber nicht");Console.WriteLine(" mein letztes C#-Programm");

Die Wirkungsweise von Console.Write() entspricht der von Con-sole.WriteLine() mit dem Unterschied, dass nach der Ausgabekeine Zeilenschaltung erfolgt. Denken Sie daran, dass Leerzeichen, wel-che innerhalb einer Zeichenkette (das heißt zwischen "...") stehen,ebenfalls auf den Bildschirm ausgegeben werden. Ebenso wirkt es sichauf die Bildschirmausgabe aus, wenn diese fehlen. So ist im obigen Codeein Leerzeichen vor dem Wort mein in der zweiten Ausgabeanweisung –bzw. nach nicht in der ersten – notwendig, da sonst auf dem Bildschirmdie Wörter nicht und mein nicht, wie gewünscht, durch ein Leerzeichengetrennt, sondern als ein Wort dargestellt werden.

Page 51: Visual C# 2005 easy

50 Kapitel 4

Anweisungen (ein solcher »Karton« ist wiederum selbst Inhalt eines größeren»Kartons«, wie wir gleich sehen werden).

Der Aufbau einer Methode gliedert sich grob in einen Methodenkopf und einenMethodenrumpf. Bis wir zu einer ausführlicheren Betrachtung der objektorien-tierten Programmierung kommen, werden wir uns nur mit einer Methode be-fassen, der Methode Main(), die auch gleichzeitig die wichtigste darstellt.Diese Methode wird wie folgt definiert:

static void Main(){}

Die Zeile static void Main() bildet den Methodenkopf von Main(). WennSie in Ihrem Quelltext einen Methodennamen schreiben, dürfen Sie die nach-folgenden Klammern nicht vergessen. Diese gehören zur Methode. Aber auchwenn man in erklärenden Texten auf eine Methode verweist, ist es üblich, hin-ter den Methodennamen ein leeres Klammernpaar zu setzen. Man schreibtalso nicht Main, sondern Main(). Dann weiß der Leser sofort, dass es sichbeim bezeichneten Objekt um eine Methode handelt und nicht etwa um eineVariable, Klasse oder um einen Namensraum (letztgenannte Elemente werdenSie allesamt noch kennen lernen).

Achtung

Beachten Sie, dass Main() mit einem Großbuchstaben beginnt. Schrei-ben Sie nicht main(), wie Sie es vielleicht von C++ oder Java hergewohnt sind.

Hinweis

Vielleicht haben Sie bemerkt, dass Visual C# Express zwischen den rundenKlammern automatisch den Ausdruck string[] args einfügt. Dabeihandelt es sich um einen so genannten Parameter, den der Programmiererverwenden kann, um eventuelle Informationen, die ein Konsolenpro-gramm beim Aufruf auf der Kommandozeile erhält, im Code zu verarbeiten.Wir werden diesen Parameter in unseren Beispielen jedoch nicht verwen-den. Natürlich dürfen Sie die Main()-Methode auch – wie oben gezeigt –parameterlos definieren (was es mit Parametern auf sich hat, erfahren Siein Kapitel 6 im Abschnitt »Die Methoden Write() und WriteLine()«, Genaue-res dann im Zusammenhang mit Methoden in Kapitel 13).

Page 52: Visual C# 2005 easy

Aufbau von C#-Programmen 51

Der Beginn des Methodenrumpfs wird durch eine öffnende ({) und dessenEnde durch eine schließende geschweifte Klammer (}) festgelegt. Alle Anwei-sungen einer Methode stehen zwischen diesen beiden Klammern, also

static void Main(){ // Anweisung(en)}

Bei dem doppelten Slash (//) handelt es sich um ein Kommentarzeichen. Esbewirkt, dass alle nachfolgenden Zeichen bis zum Zeilenende als Kommentarangesehen werden. Kommentare werden beim Übersetzungsvorgang igno-riert, haben also keine Auswirkung auf den späteren Programmlauf. Wirwerden auf Kommentare im nächsten Kapitel noch zu sprechen kommen. Hiersoll mithilfe des Kommentars lediglich darauf hingewiesen werden, an welcheStelle Anweisungen positioniert werden. Wir müssen also die Kommentarzeilegleich durch die tatsächliche Anweisung ersetzen.

Die Methode Main() ist deshalb so wichtig, weil sie den Einstiegspunkt insProgramm darstellt. Wenn Sie den Kompiliervorgang starten, sucht der Compi-ler nach der Methode Main(). Findet er sie nicht, erhalten Sie eine entspre-chende Fehlermeldung. Auch beim fertigen – kompilierten – Programmbeginnt der Programmlauf immer in Main(); oder anders ausgedrückt: BeimStart des Computerprogramms wird die Methode Main() direkt vom Betriebs-system bzw. vom Prozessor Ihres Computers aufgerufen. Die erste Aktion wirdalso von der ersten Anweisung im Rumpf der Methode Main() bestimmt.

Merken Sie sich bitte:

• Jede Anweisung muss innerhalb eines Methodenrumpfs stehen.

• In jedem Programm muss genau eine Methode Main() definiert sein.Damit wird die Stelle festgelegt, an der die Programmausführung beginnt.

Tipp

Geschweifte Klammern sollten in eine extra Zeile geschrieben undAnweisungen innerhalb der beiden Klammern um eine festgelegteAnzahl von Stellen eingerückt werden. Dies trägt wesentlich zur Über-sichtlichkeit Ihres Quellcodes bei. Erfreulicherweise brauchen Sie sich inIhrer IDE nicht weiter darum zu kümmern. Visual C# Express führt dieseEinrückungen automatisch durch.

Page 53: Visual C# 2005 easy

52 Kapitel 4

Nun sieht unser bisheriger Quelltext so aus:

static void Main(){ Console.WriteLine("Mein erstes C#-Programm");}

Über die Zeile static void Main() brauchen Sie sich noch keine Gedankenzu machen. Ihnen soll nur klar sein, dass es sich dabei um den Methodenkopfvon Main() handelt. Die Bedeutung der Wörter static und void einschließ-lich der runden Klammern nach dem Methodennamen werden Sie später nochkennen lernen. Solange Ihre Programme einzig die Methode Main() beinhal-ten, lautet der Methodenkopf stets gleich.

Damit haben Sie nun die Anweisung Console.WriteLine("Mein erstesC#-Programm"); in einen passenden Karton, nämlich in die MethodeMain(), gepackt.

Abbildung 4.1: Anweisungen dürfen nur innerhalb von Methoden stehen

Der Klassen-»Karton«Aber immer noch wäre Ihr Compiler unzufrieden und würde das bei einemKompilierversuch mit einer Fehlermeldung zum Ausdruck bringen. Er würdeIhnen sogar ziemlich deutlich sagen, dass er eine Klasse erwartet. Wir könnendaraus schließen, dass auch Methoden nicht für sich alleine stehen dürfen,sondern ebenfalls in größere Einheiten eingebunden werden müssen.

Diese Einheiten nennt man »Klassen«. Klassen gehören zu den Features derobjektorientierten Programmierung. Ein Computerprogramm darf aus beliebigvielen Klassen bestehen, von denen wiederum jede beliebig viele Methodenenthalten darf. Umgekehrt gilt: Genauso wie eine Anweisung nur innerhalb ei-ner Methode stehen darf, darf auch eine Methode nur innerhalb einer Klassedefiniert sein.

Anweisung(en)

Methode

Page 54: Visual C# 2005 easy

Aufbau von C#-Programmen 53

Klassen definieren Sie folgendermaßen:

class Klassenname{ // Innerhalb diese Blocks // können mehrere Methoden // definiert sein. }

Die Definition einer Klasse beginnt mit dem Schlüsselwort class.

Hinweis

Nicht objektorientierte Programmiersprachen wie etwa ältere Versionen vonPascal, Basic und Cobol, aber auch C kennen weder Klassen noch Metho-den. Stattdessen besitzen sie als Bausteine Funktionen. Was Aufbau undWirkungsweise angeht, entsprechen die Methoden den Funktionen.

Methoden werden nur als solche bezeichnet, weil sie in Klassen einge-bunden sind. C# kennt keine Funktionen, da ein C#-Programm aus-schließlich aus Klassen besteht.

Anders dagegen C++, der objektorientierte Nachfolger von C. Hier gibt essowohl Funktionen als auch Methoden. Steht eine Funktion für sichalleine, ohne in eine Klasse eingebunden zu sein (was in C++ erlaubt ist),nennt man sie eben Funktion. Wird eine »Funktion« innerhalb einerKlasse definiert (auch das ist in C++ möglich, da C++ Klassen und somitMethoden kennt), dann spricht man von einer Methode.

Da die Programmierung in C# ausschließlich in Klassen erfolgt, ist C# –so wie Java – eine rein objektorientierte Programmiersprache, währendC++ sowohl objektorientierte Features (Klassen, Methoden) als auchnicht objektorientierte Features besitzt (z.B. Funktionen).

Schlüsselwörter

So nennt man Wörter, die der Compiler kennt und die eine ganzbestimmte Bedeutung haben. Beispielsweise weiß der Compiler, dass essich um den Beginn einer Klassendefinition handelt, wenn er auf dasSchlüsselwort class trifft. Auch static und void im Methodenkopfvon Main() sind Schlüsselwörter, die eine genau definierte Bedeutunghaben (die Sie noch kennen lernen werden). Keine Programmiersprachekommt ohne Schlüsselwörter aus.

Page 55: Visual C# 2005 easy

54 Kapitel 4

Nach dem Schlüsselwort class steht der Name der Klasse. Bei diesem han-delt es sich um einen grundsätzlich frei wählbaren Bezeichner. Visual C# Ex-press vergibt jedoch für die Hauptklasse stets den Namen Program.

Auch die Definition einer Klasse gliedert sich in einen Kopf und einen Rumpf.Der Kopf unserer Klasse ist nun festgelegt:

class Program

Daran schließt sich der Rumpf an:

class Program{ // Innerhalb diese Blocks // können mehrere Methoden // definiert sein}

Der Rumpf einer Klassendefinition ist wie bei der Methodendefinition gekenn-zeichnet durch ein Anfangs- (öffnende geschweifte Klammer) und ein Endezei-chen (schließende geschweifte Klammer). Dazwischen können eine odermehrere Methoden definiert sein. Sie müssen also Ihre Methode Main() inden Rumpf Ihrer Klasse Program schreiben. Dann sieht Ihr Quelltext so aus:

class Program{ static void Main() { Console.WriteLine("Mein erstes C#-Programm"); }}

Um bei dem Bild mit den Kartons zu bleiben: Sie haben nun Ihre Main()-Methode zusammen mit der Ausgabeanweisung in die Klasse Program ge-packt.

Hinweis

Beachten Sie, dass C# streng zwischen Groß- und Kleinschreibung unter-scheidet. Ein Bezeichner Program ist deshalb ein anderer als programoder PROGRAM.

Page 56: Visual C# 2005 easy

Aufbau von C#-Programmen 55

Abbildung 4.2: Auch Methoden dürfen in C# nur innerhalb von Klassen stehen

Jetzt müssten Sie das Listing nur noch durch die Zeile

using System;

ergänzen. Diese Zeile steht am Anfang eines jeden Programms. Bei using han-delt es sich ebenfalls um ein dem Compiler bekanntes Schlüsselwort, Systembezeichnet einen Namensraum. Mit using wird dieser Namensraum dem Pro-gramm bekannt gemacht. Was das genau zu bedeuten hat, erfahren Sie, wennwir uns im Zuge der objektorientierten Programmierung mit Klassen und Na-mensräumen beschäftigen. Vorläufig reicht es aus, wenn Sie wissen, dass die-se Zeile am Anfang eines jeden Programms stehen muss. Der Quelltext fürunser Programm sieht dann wie folgt aus:

using System;class Program{ static void Main() { Console.WriteLine("Mein erstes C#-Programm"); }}

Was noch fehlt, ist ein Befehl, der das Programm anhält. Ansonsten bekommenSie nach dem Programmstart nicht viel zu sehen, da Windows das Konsolen-fenster sofort wieder schließt, sobald die letzte Anweisung im Rumpf vonMain() ausgeführt ist.

using System;class Program{ static void Main() { Console.WriteLine("Mein erstes C#-Programm"); Console.ReadLine(); }}

Methode

Anweisung(en)

Klasse

Page 57: Visual C# 2005 easy

56 Kapitel 4

Wenn Sie allein diesen Code nun in das Codefenster der Visual C# 2005 Ex-press Edition eingeben, werden Sie sehen, dass er sich kompilieren und mit(F5) ausführen lässt. Allerdings erzeugt Visual C# Express ein etwas umfang-reicheres Programmgerüst. Unter anderem enthält es zwei weitere using-Direktiven und die Main()-Methode wird mit einem Parameter ausgestattet.Außerdem schließt es die Klasse Program in einen Namensraum ein, dessenBezeichner dem Namen des Projekts entspricht.

Sie werden das von Ihrer IDE vorgeschlagene Grundgerüst natürlich schon ausGründen der Bequemlichkeit übernehmen, sodass sich das vollständige Pro-grammlisting wie folgt darstellt:

using System;using System.Collections.Generic;using System.Text;

namespace Mein_erstes_Programm{ class Program { static void Main(string[] args) { Console.WriteLine("Mein erstes C#-Programm"); Console.ReadLine(); } }}

Listing 4.1: Code der Datei »Program.cs« (Projekt »Mein erstes Programm«)

Hinweis

Der Bezeichner für den Namensraum weicht allerdings im Beispiel etwasab und lautet Mein_erstes_Programm. Visual C# Express fügt dieUnterstriche hinzu, da Mein erstes Programm wegen der Leerzei-chen kein gültiger Bezeichner ist (zur Bezeichnerwahl siehe Kapitel 7,Abschnitt »Variablendefinition«). Bei Namensräumen handelt es sichgewissermaßen um einen weiteren »Karton«, der jedoch – anders als dasKlassengerüst – optional ist.

Page 58: Visual C# 2005 easy

Wo befindet sich nun eigentlich die ausführbare (.exe-)Datei? 57

Wo befindet sich nun eigentlich die ausführbare (.exe-)Datei?Diese Frage werden Sie sich vermutlich schon gestellt haben. Sie finden sie imProjektordner, dort unter bin/Debug, auf der Buch-CD also im Ordner Beispiele\Konsolenprogramme\Mein erstes Programm\bin\Debug. Der Dateiname istMein erstes Programm.exe. Zur Wiederholung: Die Datei Mein erstes Pro-gramm.exe ist das Endprodukt Ihrer Programmierarbeit, die ausführbareProgrammdatei. Diese ist jedoch nicht unmittelbar vom Betriebssystem abruf-bar, da sie aus einem Zwischencode, dem so genannten IL-Code besteht. Umsie ausführen zu können, benötigt Ihr Computer das .NET Framework, das Sieja schon zusammen mit Ihrer Visual C# 2005 Express Edition installiert haben.Das .NET Framework fungiert sozusagen als Mittler zwischen C#-Programm(gemeint ist die .exe-Datei) und Betriebssystem (siehe Kapitel 2, Abschnitt»Besonderheiten bei der Kompilierung in C#«).

Eine kleine Erfolgskontrolle• Nennen Sie eine Anweisung, welche die Bildschirmausgabe ***** ein-

schließlich einer Zeilenschaltung bewirkt.

• Woran erkennt der Compiler den Anfang und das Ende eines Methoden-rumpfs?

• Welche Anweisung wird beim Programmlauf als Erstes abgearbeitet?

• Wie wird die Definition einer Klasse eingeleitet?

• Nennen Sie in hierarchisch aufsteigender Reihenfolge drei Bausteine einesC#-Programms.

Auf der CD-ROM

Das Beispiel Mein erstes Programm finden Sie im Ordner Beispiele/Kon-solenprogramme der Buch-CD.

Hinweis

In der Sprache des .NET werden ausführbare Dateien auch Assemblies(Einzahl Assembly) genannt.

Page 59: Visual C# 2005 easy

Das können Sie schon:

Die einzelnen Entwicklungsschritte zum lauffähigen C#-Programm 11

Umgang mit der Benutzeroberfläche der Visual C# 2005 Express Edition 36

Wie C#-Programme aufgebaut sind 48

Das lernen Sie neu:

Grundlegende Syntaxregeln von C# 59

Verwenden von Kommentarzeichen 67

Unterscheiden verschiedener Fehlerarten 69

Page 60: Visual C# 2005 easy

Kapitel 5

SyntaxregelnWie in jeder anderen Programmiersprache müssen Sie auch in C# beim Editieren des Quellcodes bestimmte sprachspezifische Syntax-regeln beachten. Einige davon wurden bereits angesprochen. In die-sem Kapitel fassen wir die wesentlichen Regeln zur Kodierung von C#-Quelltexten zusammen.

Page 61: Visual C# 2005 easy

60 Kapitel 5

TextbausteineWie Sie bereits wissen, ist die kleinste zusammengehörige Einheit in C# die An-weisung. Eine Anweisung setzt sich in der Regel aus einer Reihe von Textbau-steinen zusammen – insofern es sich nicht um eine leere Anweisung handelt(was eine leere Anweisung ist, erfahren Sie gleich im nächsten Abschnitt).

Textbausteine – auch Token genannt – können Schlüsselwörter, Bezeichner,konstante Werte, Operatoren oder Zeichen mit besonderer Bedeutung sein.

Was Schlüsselwörter sind, wissen Sie bereits. Was es mit Operatoren, Bezeich-nern und Konstanten auf sich hat, werden Sie noch erfahren. Beispiele fürZeichen mit besonderer Bedeutung sind etwa in Verbindung mit Zeichenkettendie doppelten Anführungszeichen ("…"), welche den Beginn und das Endeeines Strings festlegen. Auch das Semikolon (;) als Endezeichen einer Anwei-sung fällt darunter.

Die einzelnen Textbausteine müssen innerhalb einer Anweisung eindeutigunterscheidbar sein, um vom Compiler in ihrer Bedeutung erkannt zu wer-den. Wo das nicht automatisch der Fall ist, müssen sie durch mindestens einLeerzeichen voneinander getrennt werden. Nehmen wir als Beispieldie Anweisung

int name = 15;

Die genaue Bedeutung dieser Anweisung und der einzelnen Textbausteinewerden Sie im nächsten Kapitel erfahren. Hier nur soviel: int ist ein Schlüssel-wort zur Angabe eines Datentyps, name ist ein Bezeichner für ein Datenobjekt– nämlich eine Variable –, das =-Zeichen steht für einen Zuweisungsoperatorund bei der Zahl 15 handelt es sich um einen konstanten Wert.

Wenn Sie nun schreiben

intname = 15; // FEHLER

kann das Schlüsselwort int nicht mehr als solches erkannt werden. Auch istjetzt in der Anweisung kein Bezeichner name enthalten – allenfalls ein Bezeich-ner intname. Die Fehlermeldung, die diese Programmierzeile hervorruft, er-gibt sich aber aus dem Fehlen eines einleitenden Schlüsselworts zur Angabe

Hinweis

Eine Zeichenfolge, welche zwischen "…" steht, wird im Programmier-jargon Zeichenkette oder String genannt.

Page 62: Visual C# 2005 easy

Anweisungsende 61

eines Datentyps (was das genau heißt, erfahren Sie ebenfalls im nächstenKapitel).

Im gerade genannten Beispiel ist es also zwingend erforderlich, zwischen demSchlüsselwort int und dem Bezeichner name zumindest eine Leerstelle zusetzen. Andererseits ist die Anweisung

int name=15;

bei der die beiden Leerzeichen zwischen Bezeichner name, Zuweisungsopera-tor (=) und der Zahl 15 weggelassen wurden, syntaktisch in Ordnung. Dies liegtdaran, dass der Compiler hier die einzelnen Textbausteine auch ohne Trennzei-chen unterscheiden kann. Ein Bezeichner name= ist nicht zulässig, folglich wirddieser Ausdruck vom Compiler auch nicht als Bezeichner interpretiert.

AnweisungsendeC# ist nicht zeilenorientiert. Das heißt, das Ende einer Anweisung wird nichtam Zeilenende erkannt. Ausschlaggebend hierfür ist allein das abschließendeSemikolon (;).

Jedes Semikolon wird in C# als Ende einer Anweisung interpretiert. Dabeispielt es keine Rolle, welche Textbausteine vor dem Semikolon stehen. Dasgeht so weit, dass ein Semikolon ohne vorangehende Token ebenfalls als C#-Anweisung angesehen wird. Diese hat sogar einen speziellen Namen. Manspricht in diesem Fall von einer leeren Anweisung.

In dem Codefragment

Console.Write("Syntaxregeln"); // erste Anweisung;; // zwei Anweisungen in einer Zeile

Tipp

Um sich selbst vor Nachlässigkeiten zu schützen und auch um die Les-barkeit des Quellcodes zu verbessern, ist es in jedem Fall sinnvoll, ein-zelne Textbausteine durch ein Leerzeichen voneinander zu trennen. BeimCode-Editor von Visual C# müssen Sie sich allerdings nicht darum küm-mern, da dieser die Leerzeichen gegebenenfalls selbstständig einfügt,zumindest, wenn er durch die verwendeten Sonderzeichen einenAnhaltspunkt hat wie eben im Beispiel int name=15;. Eine Eingabewie intname = 15; kann auch der Code-Editor nicht korrigieren.

Page 63: Visual C# 2005 easy

62 Kapitel 5

sind demzufolge drei Anweisungen enthalten. Natürlich haben die zweite unddritte keinerlei Auswirkungen auf das Geschehen während des Programmlaufs.

Beachten Sie:

• Immer, wenn im C#-Quellcode ein Semikolon auftritt, bildet dieses zusam-men mit dem vorangehenden Text – beginnend beim letzten Semikolonoder { – eine Anweisung.

• Codeteile, welche zwischen { und } stehen und nicht mit einem Semikolonabgeschlossen werden, sind in der Regel unvollständig und damit fehler-haft.

BlöckeBlöcke beschreiben zusammengehörige Teile des Quellcodes. Grundsätzlichwird jeder Bereich zwischen einer öffnenden und einer schließenden ge-schweiften Klammer in C# als Block bezeichnet. Sie haben bereits mehrereBlöcke kennen gelernt. So handelt es sich beim Methodenrumpf von Main()um einen Block. Statt vom Methodenrumpf spricht man deshalb auch vomMethodenblock.

static void Main(){ // Anweisung(en)}

Auch eine Klasse besitzt einen Block, in dem die eigentliche Implementierungder Klasse stattfindet:

class Program{ // Hier können z.B. eine oder // mehrere Methoden stehen }

Ein C#-Programm kann beliebig viele Blöcke enthalten, welche auch ineinan-der liegen dürfen. Ein Beispiel für eine verschachtelte Blockstruktur ist dasGrundgerüst Ihres ersten Programms:

class Program{ static void Main() { // Anweisung(en) }}

Page 64: Visual C# 2005 easy

Blöcke 63

Der Methodenblock von Main() befindet sich dabei innerhalb des Klassen-blocks.

Alle Anweisungen, welche im Block einer Methode stehen, sind Teil dieser Me-thode, so wie alle Methoden, welche sich im Block einer Klasse befinden, alszu dieser Klasse gehörig angesehen werden.

Mithilfe von Blöcken lassen sich also mehrere Anweisungen zusammenfassen.Sie werden davon im Zusammenhang mit Kontrollstrukturen (Kapitel 10 und11) noch intensiv Gebrauch machen.

In den obigen Beispielen ist das Setzen von Blöcken zwingend vorgeschrieben,da Klassen sowie Methoden von einem Block begrenzt werden müssen. Grund-sätzlich ist es aber auch erlaubt, innere Blöcke willkürlich zu setzen, ohne dassdafür eine syntaktische Notwendigkeit besteht:

static void Main(){ … { // innerer Block … } // Ende innerer Block …} // Ende von Main()

Die Auslassungspunkte sollen deutlich machen, dass an den jeweiligen Stelleneine oder mehrere Anweisungen stehen dürfen – und in der Regel auch stehen.

Die Verwendung zusätzlicher Blöcke kann unter Umständen ein Mittel zur bes-seren Strukturierung des Quelltexts sein. In der Regel werden Sie Blöcke abernur dann setzen, wenn es die Syntax von C# vorschreibt.

Hinweis

In unserem Einführungsprogramm ist die Ausgabeanweisung Con-sole.WriteLine("Mein erstes C#-Programm"); Teil der Main()-Methode und damit auch Teil der Klasse Program, da sie innerhalb bei-der Blöcke steht.

Page 65: Visual C# 2005 easy

64 Kapitel 5

LeerräumeWie Sie weiter oben erfahren haben (Abschnitt Textbausteine), ist es häufignotwendig, einzelne Textbausteine durch Leerzeichen voneinander zu trennen.

Umgekehrt würden jedoch Namen (Bezeichner, Schlüsselwörter) oder Opera-toren – sofern sie aus mehreren Einzelzeichen zusammengesetzt sind – durchdas Hinzufügen von Zwischenraumzeichen ihre Bedeutung verlieren. Wenn Siealso schreiben

static v o i d Main()

dann ist das Schlüsselwort void nicht mehr als solches erkennbar und weil derAusdruck v o i d auch nicht anderweitig interpretiert werden kann, ist obigeProgrammierzeile fehlerhaft.

Damit wird deutlich, dass Leerräume im Quelltext in zwei Varianten syntakti-sche Bedeutung erlangen:

• Trennung zweier Textbausteine durch Einfügen von Zwischenraumzeichen,sofern dies zu deren Unterscheidung notwendig ist (wie Sie im Abschnittüber Textbausteine erfahren haben, ist das nicht immer der Fall),

• unerlaubtes Einfügen von Zwischenraumzeichen innerhalb eines Tokens.Dies führt zu Syntaxfehlern.

In allen anderen Zusammenhängen haben Leerräume im Quellcode keinerleiBedeutung. Diese werden beim Kompilieren einfach ignoriert. Das bedeutet,dass Sie zwischen den einzelnen Textbausteinen so viele Zwischenraumzei-chen (Leerzeichen, Tabulatorschritte, Zeilenumbrüche) einfügen dürfen, wieSie wollen. Ebenso können Sie auch ganz darauf verzichten. Auf die Bedeu-tung des Quellcodes hat dies keinen Einfluss.

Es spielt also im Hinblick auf die Kompilierbarkeit und das Endergebnis – dasfertige Programm – keine Rolle, ob Sie Ihr Einführungsprogramm in lesbarerForm, was aus den schon bekannten Gründen zu empfehlen ist, oder in einerKurzform aufbauen, wie hier zu sehen:

using System;using System.Collections.Generic;using System.Text;namespace Mein_erstes_Programm{class Program{static void Main(string[] args){Console.WriteLine("Mein erstes C#-Programm");Console.ReadLine();}}}

Page 66: Visual C# 2005 easy

Leerräume 65

Sie müssen lediglich darauf achten, den String "Mein erstes C#-Pro-gramm" nicht durch eine Zeilenschaltung zu unterbrechen, da Ihr Compiler die-ses Steuerzeichen innerhalb eines Strings nicht zu interpretieren vermag. Mitdem gleichen Ergebnis kompilierbar wäre eine überlange Version des Quell-codes, die wir hier aus Platzgründen nur andeutungsweise wiedergeben:

...namespace Mein_erstes_Programm

{

class Program { static

void Main (...

Dies könnten Sie beliebig weiter treiben. Solange die Bedeutung der einzelnenTextbausteine dabei erhalten bleibt – was in beiden Listings der Fall ist –, istder Programmcode syntaktisch in Ordnung.

Um es ganz deutlich zu machen, sei noch einmal auf die Bedeutung des Semi-kolons und der {} hingewiesen. Da C# eben nicht zeilenorientiert ist, wird dasAnweisungsende allein am Semikolon und das Blockende allein an der schlie-ßenden Klammer erkannt. So sind die Anweisungen

Console.WriteLine("Willkommen bei C#");

oder

Console.WriteLine("Willkommen bei C#")

;

für den Compiler völlig gleichwertig, ebenso die Blockstrukturen

static void Main(){ Console.WriteLine("Hallo");}

und

static void Main(){ Console.WriteLine("Hallo");

}

Page 67: Visual C# 2005 easy

66 Kapitel 5

Der Block ist erst mit dem } zu Ende und selbst wenn die schließende Klammerim Abstand von mehreren Bildschirmseiten folgen würde, erkennt Ihr Compilersie als Blockende.

ProgrammierstilSoviel nur zum Verständnis. Lassen Sie sich gerade von der oben gezeigtenfünfzeiligen Programmvariante nicht verführen und gewöhnen Sie sich einenschlechten Programmierstil erst gar nicht an. Ihre Programme werden im Ver-lauf Ihrer weiteren Programmiertätigkeit immer umfangreicher werden und Siewerden nur dann in der Lage sein, die Übersicht über Ihren Quellcode zu behal-ten, wenn Sie diesen entsprechend strukturieren.

Zudem können Anwendungsprogramme in den seltensten Fällen ohne War-tung über einen längeren Zeitraum hinweg eingesetzt werden. Zum einen ist esauf Grund äußerer Gegebenheiten oft notwendig, die Funktionalität einerApplikation zu erweitern, zum anderen kann das Auftreten logischer Fehler zueiner Überarbeitung des Quellcodes zwingen.

Daher ist es unumgänglich, den Quelltext von Anfang an wartungsfreundlichzu implementieren. Das ausschlaggebende Kriterium hierfür ist eine schnelleNachvollziehbarkeit des Quellcodes. Im Idealfall muss dieser daher so einge-richtet sein, dass er auch von anderen Programmierern ohne große Mühe ge-lesen und verstanden werden kann.

Unter diesem Gesichtspunkt seien hier noch einmal zusammenfassend einigeEmpfehlungen gegeben:

• Schreiben Sie die Zeichen für den Blockanfang ({) und das Blockende (})jeweils in eine separate Zeile.

• Rücken Sie alle Anweisungen – und auch innere Blockstrukturen – inner-halb eines Blocks um eine konstante Anzahl von Leerzeichen ein.

Tipp

Um sich vor Fehlern zu schützen, sollten Sie sich angewöhnen, eine öff-nende Klammer sogleich wieder zu schließen, bevor Sie am Quelltextweiterarbeiten.

Page 68: Visual C# 2005 easy

Kommentare 67

{ // Beginn äußerer Block // Anweisung im äußeren Block // ... { // Beginn innerer Block // Anweisung im inneren Block // ... } // Ende innerer Block // Anweisung im äußeren Block // ...} // Ende äußerer Block

• Beginnen Sie jede Anweisung möglichst in einer eigenen Zeile. Dagegenergibt es Sinn, eine sehr lange Anweisung auf zwei oder mehr Zeilen zuverteilen.

Diese Ratschläge sollten Sie sich grundsätzlich immer zu Herzen nehmen, vorallem dann, wenn Sie mit einem einfachen Text-Editor arbeiten. Allerdings wer-den Sie bei der Formatierung des Quellcodes von Visual C# Express im genann-ten Sinne weitgehend unterstützt (siehe dazu auch unter Hätten Sie gedacht ...am Ende des Kapitels).

KommentareSchließlich gehört es auch zu einem guten Programmierstil, den Quellcode angeeigneten Stellen zu kommentieren. Dafür stehen Ihnen zwei verschiedeneKommentarzeichen zur Verfügung:

• // ...

• /* ... */

Mit dem ersten Zeichen leiten Sie einen einzeiligen Kommentar ein. Das heißt,jedes Zeichen, welches in derselben Zeile nach // steht, sieht Ihr Compiler alsKommentar an. Mit den Zeichen /* und */ erzeugen Sie dagegen einen Kom-mentar über beliebig viele Zeilen. Alles, was zwischen dem einleitenden /*und dem abschließenden */ steht, wird dann als Kommentar interpretiert:

Page 69: Visual C# 2005 easy

68 Kapitel 5

/* Das Programm gibt die Zeichenfolge»Mein erstes C#-Programm« auf derKonsole aus. */using System;class Program{// Hier beginnt die Main()-Methode static void Main() { Console.WriteLine("Mein erstes C#-Programm"); Console.ReadLine(); // Haltebefehl }}

Selbstverständlich soll obiges Listung nur der Demonstration dienen. In IhrerPraxis werden Sie es im Allgemeinen unterlassen, auf triviale Dinge mittelsKommentar hinzuweisen. Schließlich würden Sie damit Ihren Quellcode nichtverständlicher machen, sondern vermutlich sogar den gegenteiligen Effekt er-zielen. Bei größeren Programmen ist der sinnvolle Einsatz von Kommentarenjedoch anzuraten. Übrigens ist ein einleitender Kommentar, der die Funktions-weise eines Programms kurz beschreibt und über ein paar wesentliche Detailswie z.B. den Namen des Programmautors oder die Programmversion infor-miert, durchaus üblich.

Auf der CD-ROM

Die so kommentierte Version Ihres ersten C#-Programms finden Sie aufder Buch-CD im Verzeichnis Beispiele/Konsolenprogramme unter demProjektnamen K05.

Hinweis

Darüber, dass Kommentare möglicherweise den SpeicherplatzbedarfIhrer ausführbaren Programme erhöhen oder gar die Ausführungsge-schwindigkeit reduzieren, brauchen Sie sich keine Sorgen zu machen:Der Compiler entfernt alle Kommentare, bevor er daran geht, den eigent-lichen Quellcode zu kompilieren. Die Anzahl der Kommentare im Codehat also keinerlei Einfluss auf die Größe oder das Laufzeitverhalten derausführbaren Programmdatei.

Page 70: Visual C# 2005 easy

Programm(ier)fehler 69

Programm(ier)fehlerEs wird Ihnen nicht immer gelingen, Ihren Quellcode von Anfang an ohne Syn-taxfehler zu erstellen. Dies gilt umso mehr, je umfangreicher Ihre Programmewerden.

Wenn beim Kompilieren Fehler auftreten, müssen Sie Ihren Quellcode noch-mals überarbeiten und danach den Kompiliervorgang erneut in Gang setzen.Dies kann sich unter Umständen mehrmals wiederholen. Um rechtzeitig aufSyntaxfehler hingewiesen zu werden, ist es deshalb gerade für den Program-mierneuling ratsam, den Quellcode zwischenzeitlich immer mal wieder zukompilieren (z.B. über Taste (F5) in der Visual C# Express-Umgebung).

Bei der Fehlersuche sollten Sie berücksichtigen, dass Fehlermeldungen letzt-endlich aus der Betrachtungsweise Ihres Compilers resultieren. Das hat zurFolge, dass Zeilenangaben – und noch weniger etwaige Spaltenangaben, inso-fern die verwendete IDE solche mitteilt –, die Anzahl der Fehler und auch dieangegebene Fehlerart nicht immer zutreffen müssen.

Um dies zu verdeutlichen, sei angenommen, der Programmautor habe zwi-schen zwei Ausgabeanweisungen ein Semikolon vergessen:

Console.WriteLine("erste Zeichenfolge")Console.WriteLine("zweite Zeichenfolge");

Dann begreift ein Compiler die beiden Codezeilen als eine Anweisung, die mitdem Semikolon in der zweiten Zeile zu Ende ist. Diese Anweisung ist jedoch feh-lerhaft, weil sie Token enthält, welche in diesem Kontext nicht stehen dürfen.

Hinweis

Nach jedem erfolglosen Kompilierversuch erscheint im unteren BereichIhrer Entwicklungsumgebung ein Fenster mit dem Namen Fehlerliste. Indiesem zeigt Visual C# Express alle Syntaxfehler mit Beschreibung undZeilennummer an. Sie können die Fehlerliste mit dem MenübefehlAnsicht/Fehlerliste auch standardmäßig einblenden.

Page 71: Visual C# 2005 easy

70 Kapitel 5

Dabei ist die erste Codezeile noch völlig korrekt. Der fehlerhafte Codebeginnt erst mit dem Console.WriteLine der unteren Zeile, da nachConsole.WriteLine("erste Zeichenfolge") als nächstes Token alleinein Semikolon syntaktisch korrekt ist. Jeder andere Textbaustein wäre in die-sem Kontext nicht erlaubt. Wie Ihnen nun hinlänglich bekannt ist, muss dasSemikolon im obigen Codefragment aber nicht notwendig in der oberen Zeilestehen. Daher wird die Fehlermeldung einiger Compiler möglicherweise aufdie untere Zeile verweisen, obwohl der Programmierer das Semikolon ei-gentlich in der ersten Zeile vergessen hat.

Andererseits würden wir die Fehlerzahl sicherlich mit 1 angeben, es fehlt ja nurein einziges Semikolon. Ein Compiler dagegen könnte beginnend mit der zwei-ten Zeile konsequenterweise jeden einzelnen Textbaustein als Fehler melden,wobei der Ausdruck Console.WriteLine allein aus insgesamt drei Token be-steht.

Es sei hier angemerkt, dass das Compilerverhalten in dieser Hinsicht von Fallzu Fall verschieden und nicht hundertprozentig vorhersehbar ist. Wie gesagt,hat jeder Compiler bei der Fehlerbewertung seine eigenen Maßstäbe und letz-ten Endes handelt es sich bei einem Compiler auch um ein Softwareprogramm,das sich eben so verhält, wie es programmiert ist. Wir möchten Sie mit diesemBeispiel auf die vereinzelt auftretende Notwendigkeit vorbereiten, eventuelleCompiler-Fehlerangaben relativiert zu betrachten. Als Richtlinie für die Fehler-suche sollten Sie Compiler-Fehlermeldungen auf jeden Fall ansehen. Außer-dem gilt ohne Einschränkung: Wenn Ihr Compiler sich weigert, den Quellcodezu übersetzen, sind in diesem ohne Zweifel Syntaxfehler enthalten.

Hinweis

Erfreulicherweise erweist sich Visual C# Express hinsichtlich der Fehler-erkennung als sehr intelligent (beispielsweise meldet der Compiler derVisual C# Express Edition bezüglich des oben gezeigten Codefragmentsdas Fehlen genau eines Semikolons und lokalisiert es auch in der oberenZeile).

Page 72: Visual C# 2005 easy

Programm(ier)fehler 71

FehlerartenIm Allgemeinen nimmt die Fehlersuche einen Großteil der Programmierarbeitin Anspruch. Und leider sind Syntaxfehler nicht die einzigen, mit denen Sie esals Programmierer zu tun haben werden. Schließlich arbeitet kaum ein größe-res Programm (lauffähige Programme liegen in kompilierter Form vor, enthal-ten also keine Syntaxfehler) gänzlich fehlerfrei, wie Ihnen aus eigenerAnwendererfahrung bekannt sein wird. Auch wenn Sie bei der Entwicklungsehr sorgfältig vorgehen, lassen sich Fehler zwar minimieren, jedoch nicht im-mer ganz vermeiden.

Hinsichtlich ihrer Auswirkungen unterscheidet man drei Gruppen von Fehlern:

• Syntaxfehler sind solche, welche vom Compiler erkannt und gemeldetwerden. Quellcode, der Syntaxfehler enthält, kann nicht erfolgreich kompi-liert werden. Da somit keine ausführbare Applikation aus syntaxfehler-behaftetem Code entstehen kann, ist für diese Fehlergruppe allein dieBezeichnung Programmierfehler angebracht. Hinsichtlich der Häufigkeitihres Auftretens stehen Syntaxfehler unbestreitbar an erster Stelle. Den-noch sind sie am einfachsten zu behandeln, weil man in der Regel frühzei-tig von ihnen Kenntnis erlangt. Um dies zu forcieren, empfiehlt es sich, wiegesagt, den Quelltext zwischenzeitlich immer wieder zu kompilieren.

• Laufzeitfehler sind Fehler, welche vom Compiler nicht erkannt werden underst zur Laufzeit, also bei Ausführung des Programms, auftreten. Ein Bei-spiel für einen Laufzeitfehler ist der Lesezugriff auf eine nicht vorhandeneDatei.

• Logische Fehler sind die gefürchtetsten, weil sie in der Regel am schwers-ten zu finden sind. Das Programm scheint zwar fehlerfrei zu arbeiten, esmacht aber eben nicht das, was es eigentlich soll. Ein Beispiel hierfür sindetwa fehlerhafte Berechnungsergebnisse.

Page 73: Visual C# 2005 easy

72 Kapitel 5

Hätten Sie gedacht ...... dass Sie mit der Visual C# 2005 Express Edition bezüglich der Formatierungdes Quelltextes nahezu jede Einstellung treffen können. Wählen Sie dazu inder Menüleiste Extras/Optionen... und aktivieren Sie, falls notwendig, zu-nächst das Kontrollkästchen Alle Einstellungen anzeigen, sonst stehen die imFolgenden erwähnten Optionen nicht zur Verfügung. Öffnen Sie dann im Lis-tenfeld links den Eintrag Text-Editor.

Beispielsweise legen Sie unter Tabstopps (Text-Editor/C#/Tabstopps) dieAnzahl der Leerzeichen fest, die der Code-Editor innerhalb eines Blocks auto-matisch einrücken soll (siehe dazu die Empfehlungen im Abschnitt Program-mierstil oben). Geben Sie dazu in das untere Textfeld, neben Einzugsgröße:,den gewünschten Wert ein.

Abbildung 5.1: Unter Tabstopps bestimmen Sie die Anzahl der Leerzeichen, die der auto-matische Einzug umfassen soll

Hinweis

Wundern Sie sich nicht weiter darüber, dass der Optionen-Dialog zwi-schen C# und anderen Programmiersprachen (Alle Sprachen) unterschei-det. Dies rührt aus der Verwandtschaft der Visual C# 2005 ExpressEdition mit dem Visual Studio her. Die Aufteilung wurde vom Visual Stu-dio, das ja für mehrere Programmiersprachen konzipiert ist, einfachübernommen.

Page 74: Visual C# 2005 easy

Hätten Sie gedacht ... 73

Im Übrigen ist der Editor der Visual C# 2005 Express Edition standardmäßigdarauf ausgerichtet, die Formatierung des Codes in einem strukturierten undgut lesbaren Layout zu halten. Gegebenenfalls – wenn der Code unübersicht-lich aussieht, z.B. nachdem Sie externen Code in Ihr Projekt geladen bzw. ko-piert haben – können Sie mit Bearbeiten/Erweitert/Dokument formatieren oderder Tastenkombination (Strg) + (E), (D) das gesamte Dokument neu forma-tieren lassen.

Page 75: Visual C# 2005 easy

Das können Sie schon:

Entwicklungsschritte zum lauffähigen C#-Programm 11

Umgang mit der Visual C# Express-IDE 36

Aufbau von C#-Programmen 48

Syntaxregeln 59

Kommentare 67

Das lernen Sie neu:

Die Bedeutung von Strings 75

Zeichenkettenverknüpfung 79

Verwenden von Steuerzeichen 81

Page 76: Visual C# 2005 easy

Kapitel 6

AusgabeDie Ausgabe gehört zu den fundamentalsten Operationen in der Datenverarbeitung. In diesem Kapitel lernen Sie die Ausgabeanwei-sungen Console.Write() und Console.WriteLine() näher kennen. In diesem Zusammenhang erfahren Sie auch, was es mit den so ge-nannten Steuerzeichen auf sich hat.

Page 77: Visual C# 2005 easy

76 Kapitel 6

Die Methoden Write() und WriteLine()Beide Anweisungen wurden bereits angesprochen bzw. verwendet. Write()schreibt den Wert eines in Klammern anzugebenden Parameters auf den Bild-schirm. Wir werden gleich sehen, dass es sich dabei nicht in jedem Fall um eineZeichenfolge handeln muss.

Beachten Sie, dass Write() an der Stelle weiterschreibt, an der die Einfüge-marke steht. So können Sie die Bildschirmausgabe

Willkommen bei C#

statt mit der Anweisung

Console.Write("Willkommen bei C#");

beispielsweise auch mit den folgenden Anweisungen erzielen:

Console.Write("Willkommen");Console.Write(" bei C#");

Im Gegensatz zu Write() bewirkt WriteLine() nach Ausgabe des Texts zu-sätzlich einen Zeilenvorschub. Ansonsten entspricht die Funktionsweise dervon Write().

Console.WriteLine("Willkommen");Console.WriteLine(" bei C#");

Obige Anweisungen erzeugen somit die Ausgabe

Willkommen bei C#

Das letzte WriteLine() setzt anschließend die Einfügemarke in die darauffolgende Zeile.

Parameter – was ist das?

Parameter sind Werte, welche beim Aufruf einer Methode an diese über-geben werden. Sie müssen zwischen zwei runden Klammern nach demMethodennamen stehen. Mehrere Parameter werden durch Kommatagetrennt, also

Methodenname(Parameter_1, Parameter_2, Parameter_3)

Die Methoden Write() sowie WriteLine() erwarten beim Aufruf imNormalfall nur einen einzigen Parameter.

Page 78: Visual C# 2005 easy

Die Methoden Write() und WriteLine() 77

Vordefinierte KlassenC# stellt eine Reihe von vordefinierten Klassen mit deren Methoden zur Verfü-gung. Um eine Methode anzuwenden, müssen Sie dem Compiler mitteilen, inwelcher Klasse diese definiert ist. Dies tun Sie, indem Sie den Namen der Klas-se vor den Methodennamen schreiben. Klassenname und Methodenname wer-den dabei durch einen Punkt getrennt, also

Console.WriteLine("Hallo");

da die Methode WriteLine() – ebenso wie die Methode Write() – in derKlasse Console definiert ist. Mit anderen Worten: Die Methoden Write() undWriteLine() gehören zur Klasse Console.

Achtung

Beachten Sie, das C# zwischen Groß- und Kleinschreibung unterschei-det. Sie dürfen z.B. nicht schreiben

Console.Writeline("Willkommen"); // FEHLER

da der Compiler eine Methode Writeline() nicht kennt. Bestenfallskönnte es sich um eine andere Methode handeln, was hier aber nichtzutrifft.

Genauso falsch wäre

console.WriteLine("Willkommen"); // FEHLER

oder

CONSOLE.WriteLine("Willkommen"); // FEHLER

da Sie den Compiler damit anweisen würden, nach einer Klasse con-sole bzw. CONSOLE zu suchen. In beiden Fällen würde er eine entspre-chende Klasse nicht finden und dies mit einer Fehlermeldung zumAusdruck bringen.

Sie wollen aber die Methode WriteLine() der Klasse Console ver-wenden, folglich müssen Sie schreiben

Console.WriteLine("Willkommen");

Programmiersprachen, welche sich so verhalten, werden als case-sensi-tive bezeichnet, was so viel heißt wie »empfindlich für Groß- und Klein-schreibung«.

Page 79: Visual C# 2005 easy

78 Kapitel 6

Die Klasse Console repräsentiert sozusagen die Konsole des Betriebssys-tems. Das heißt, sie stellt Methoden zur Kommunikation mit der Konsole zurVerfügung.

ZeichenkettenZeichenketten sind Zeichenfolgen, welche von zwei doppelten Anführungszei-chen begrenzt werden. Sie haben bereits eine Zeichenkette ("Mein erstesC#-Programm") in Ihrem ersten Programm verwendet. Zeichenketten werdenvom Compiler als konstante Werte behandelt. Man spricht deshalb auch vonZeichenkettenkonstanten bzw. Stringkonstanten.

Merken Sie sich schon einmal:

• C# unterscheidet zwischen verschiedenen Datentypen.

• Auch jeder konstante Wert besitzt einen Datentyp.

Zeichenketten unterliegen dem Datentyp string (die einzelnen Datentypenlernen Sie im nächsten Kapitel kennen). Daher werden Zeichenketten von Pro-grammierern häufig als »Strings« bezeichnet.

Zum Vergleich sei hier noch der Datentyp int genannt. Dieser Datentyp um-fasst alle ganzen Zahlen im Wertebereich von -2147483648 bis 2147483647(also etwa ±2 Milliarden). Beispielsweise besitzt die Zahlenkonstante 2002den Datentyp int. Das Gleiche gilt z.B. für 3, 1, -22, die 0 usw.

Beachten Sie, dass die Regel, nach der alles, was zwischen den "" steht, vomCompiler als Zeichenkette interpretiert wird, also vom Datentyp string ist,uneingeschränkt Gültigkeit beansprucht. Demnach handelt es sich bei "123"um eine string-, nicht etwa um eine Integer-Konstante.

Hinweis

string heißt der Name eines Datentyps in C#. Gleichzeitig ist »String«eine alternative Bezeichnung für »Zeichenkette«, also für eine Konstantevom Datentyp string.

Hinweis

»Integer« ist eine in der Programmierung übliche Bezeichnung für ganz-zahlige Datentypen.

Page 80: Visual C# 2005 easy

Zeichenketten 79

Wie oben bereits angedeutet, muss der an die Methoden Write() bzw.WriteLine() zu übergebende Parameter nicht unbedingt vom Datentypstring sein. So bewirkt z.B. die Anweisung

Console.WriteLine(999);

die Ausgabe von 999 auf den Bildschirm. Natürlich ist die Bildschirmausgabein diesem Fall genau die gleiche, wenn Sie den Wert an die Methode Write-Line() als String übergeben:

Console.WriteLine("999");

Allerdings bestimmt der Datentyp, welche Operationen mit den entsprechen-den Werten möglich sind. Um das zu verdeutlichen, greifen wir im Folgendenein weiteres Mal auf die bekannten Ausgabeanweisungen zurück.

Verknüpfung von StringsStrings lassen sich mithilfe des so genannten Verknüpfungsoperators mitein-ander verketten. Dieser Operator wird durch das Plus-Zeichen (+) dargestellt.Miteinander verknüpfte Strings werden vom Compiler so behandelt, als stün-den alle Zeichen zusammen in einer Zeichenkette. Demzufolge sind die Aus-gabeanweisungen

Console.Write("Guten Tag");

und

Console.Write("Guten" + " Tag");

hinsichtlich des Ergebnisses völlig äquivalent. Beachten Sie aber, dass derCompiler in der zweiten Anweisung intern zwei Arbeitsschritte durchzuführenhat. Zunächst wird die Verknüpfungsoperation "Guten" + " Tag" ausge-

Hinweis

Die Methoden Write() und WriteLine() sind »überladen«. Dasbedeutet, dass in der Klasse Console tatsächlich mehrere Methodengleichen Namens existieren, von denen die eine mit einem string-Para-meter, eine andere mit einem Integer-Parameter definiert ist usw. Mitdem Überladen von Methoden werden Sie sich in Kapitel 14 beschäfti-gen. Im Moment reicht es aus, wenn Sie wissen, dass Sie an Write()bzw. WriteLine() Werte unterschiedlicher Datentypen übergebenkönnen.

Page 81: Visual C# 2005 easy

80 Kapitel 6

führt. Danach erfolgt die Bildschirmausgabe der nunmehr verknüpften Zei-chenketten.

Natürlich ergibt die Stringverknüpfung in diesem Zusammenhang wenig Sinn.Dieser wird erst in Verbindung mit dem Gebrauch von Variablen deutlich. DerGrund, weswegen wir Ihnen die Verknüpfung von Zeichenketten jetzt schonvorstellen, ist eine Gemeinsamkeit mit der mathematischen Addition – beideOperationen werden mit demselben Zeichen repräsentiert.

So dient das Plus-Zeichen (+) nicht nur als Verknüpfungsoperator für Strings,sondern ebenfalls als Additionsoperator. Mit Letzterem verfährt Ihr Compilerso, wie Sie es von der Mathematik her kennen. Das heißt, ein Ausdruck wie z.B.

123 + 33

ergibt bei der Berechnung durch den Compiler den Wert 156. Demnach erzeugtdie Anweisung

Console.Write(17 + 3);

die Bildschirmausgabe 20, da Ihr Compiler zunächst den Ausdruck in der Klam-mer berechnet, bevor er das Ergebnis ausgibt.

Wir haben oben bereits angedeutet, dass ein Compiler anhand des Datentypsentscheidet, welche Operation durchzuführen ist. Handelt es sich bei beidenOperanden – oder auch nur bei einem – um string-Konstanten, so führt er da-gegen eine Stringverknüpfung durch. Dies trifft auch dann zu, wenn die Stringsausschließlich Ziffern enthalten.

Console.Write("17" + "3");Console.Write(17 + "3");

Beide Anweisungen ergeben die Bildschirmausgabe 173.

Beachten Sie folglich, dass Ihr Compiler eine Zeichenkette – also eine Konstan-te vom Typ string – allein an den doppelten Anführungszeichen erkennt. Da-bei bestimmt das erste " den Anfang und das folgende " das Ende des Strings.

Page 82: Visual C# 2005 easy

Steuerzeichen 81

SteuerzeichenMöglicherweise werden Sie sich schon gefragt haben, wie man mehrere Zeilen-vorschübe programmiert, ohne jedes Mal auf die Methode WriteLine() zu-rückgreifen zu müssen. Die Antwort ist, Sie verwenden dazu das Newline-Zeichen \n. Es gehört zur Gruppe der Steuerzeichen. Derartige Zeichen werden– obwohl sie mit zwei Tastaturzeichen dargestellt werden – vom Compiler wieein einziges Zeichen – allerdings mit besonderer Bedeutung – behandelt. Steu-erzeichen dürfen wie jedes »normale« Zeichen innerhalb einer Zeichenkettestehen. Dementsprechend erzeugt Ihr Compiler an jeder Stelle, an der er einNewline-Zeichen (\n) antrifft, einen Zeilenvorschub.

Hinweis

Dem Gesagten zufolge handelt es sich auch bei "" um einen String. Die-ser stellt gewissermaßen einen Sonderfall dar, da er ja keine Zeichenenthält. Man spricht dann von einer leeren Zeichenkette bzw. einemLeerstring. Er ist sozusagen das Pendant zur 0 bei Zahlentypen und istnicht zu verwechseln mit der Zeichenkette " ", welche ein Leerzeichenenthält.

So ist zwar

Console.Write("");

eine syntaktisch korrekte Anweisung, sie erzielt jedoch keinerlei Wir-kung (ebenso wie das bei der Addition von Null zu einem Zahlenwert derFall ist).

Dagegen setzt die Anweisung

Console.Write(" "); // Ausgabe eines Leerzeichens

die Einfügemarke um eine Stelle nach rechts.

Page 83: Visual C# 2005 easy

82 Kapitel 6

1 Starten Sie Visual C# Express.

2 Legen Sie ein neues Projekt mit der Projektvorlage Konsolenanwendung an.

Geben Sie dem Projekt einen Namen Ihrer Wahl (falls Ihnen die notwendigenSchritte zur Programmentwicklung mit der Visual C# Express Edition nochnicht ganz geläufig sind, lesen Sie bitte in Kapitel 3 nach).

3 Fügen Sie der Main()-Methode die folgenden Zeilen hinzu:

Console.Write("**************\n");Console.Write("Willkommen bei\n C#");Console.Write("\n**************");Console.ReadLine();

Abbildung 6.1: Beispiel zum Thema Steuerzeichen

»Der Compiler macht dies, der Compiler macht das ...«

Diese Formulierung ist eine in der Programmierliteratur allgemein übli-che – nicht ganz korrekte – Vereinfachung. Tatsächlich erzeugt ein Com-piler lediglich die Maschinenbefehle bzw. in C# den IL-Code, welcher fürdie genannten Aktionen dann beim Programmlauf verantwortlich ist.Wenn man es also ganz genau nimmt, müsste es oben heißen: »Ihr Com-piler erzeugt an jeder Stelle, an der er ein Newline-Zeichen antrifft, einenIL-Code-Befehl, welcher beim Programmlauf einen Zeilenvorschubbewirkt«.

Page 84: Visual C# 2005 easy

Steuerzeichen 83

4 Bringen Sie Ihr Programm mit (F5) zur Ausführung.

Falls sich Ihr Code nicht kompilieren lässt, weil er Syntaxfehler enthält, korri-gieren Sie diese und drücken Sie erneut (F5).

Sie sollten nun folgende Bildschirmausgabe zu sehen bekommen.:

**************

Willkommen bei

C#

**************

5 Beenden Sie das Programm durch Drücken der (¢)-Taste und speichern Sie Ihr Projekt.

Die wichtigsten Steuerzeichen sind in der folgenden Tabelle aufgelistet:

Auf der CD-ROM

Das Beispiel K06 zu diesem Kapitel finden Sie unter Beispiele/Konsolen-programme auf der Buch-CD. Sie könnten diesem auch die benötigtenCodezeilen entnehmen und sie per Copy and Paste in die Main()-Methode Ihres Projekts einfügen.

Steuerzeichen Bedeutung

\n Zeilenvorschub (Newline)

\t Tabulatorschritt

\b Backspace (Rückschritt)

\a Piepton

\r Wagenrücklauf (Carriage Return)

\f Seitenvorschub (Formfeed)

\v Vertikaler Tabulator

Hinweis

Steuerzeichen werden wegen des führenden Backslash auch als»Escape-Sequenzen« bezeichnet.

Page 85: Visual C# 2005 easy

84 Kapitel 6

Wenn Sie ein doppeltes Anführungszeichen – dessen Bedeutung ja als String-Begrenzungszeichen vorbelegt ist – mit ausgeben wollen, stellen Sie einenBackslash vor jedes auszugebende ":

Console.Write("Ich finde, \"Programmieren macht Spaß\"");

Bildschirmausgabe:

Ich finde, "Programmieren macht Spaß"

Der Backslash nimmt in diesem Fall dem nachfolgenden Zeichen die Sonderbe-deutung. Aus diesem Grund wird er auch verwendet, um den Backslash selbstals Zeichen auszugeben. Man schreibt den Backslash in diesem Fall doppelt indie Zeichenfolge:

Console.Write("Das Newline-Zeichen wird mit \\n darge-stellt");

erzeugt daher die Ausgabe

Das Newline-Zeichen wird mit \n dargestellt

Abbildung 6.2: Das Beispiel wurde noch um ein paar zusätzliche Steuerzeichen erweitert

Page 86: Visual C# 2005 easy

Eine kleine Erfolgskontrolle 85

Eine kleine Erfolgskontrolle• Welche Bildschirmausgabe erzeugt folgende Anweisung?

Console.Write(11 + 22 + "33");

• Schreiben Sie ein Programm, welches folgende Ausgabe erzeugt:Das Newline-Zeichen wird mit "\n" dargestellt

Page 87: Visual C# 2005 easy

Das können Sie schon:

Entwicklungsschritte zum lauffähigen C#-Programm 11

Umgang mit der Visual C# Express-IDE 36

Aufbau von C#-Programmen 48

Syntaxregeln 59

Kommentare 67

Arbeiten mit Strings 75

Steuerzeichen 81

Das lernen Sie neu:

Variablendefinition 88

Wichtige Datentypen in C# 89

Die von Microsoft empfohlene Notation für Bezeichner 101

Verarbeiten von Benutzereingaben 103

Page 88: Visual C# 2005 easy

Kapitel 7

Variablen und DatentypenVariablen gehören zu den wichtigsten Bestandteilen eines Programms. In diesem Kapitel erfahren Sie, wofür Variablen benötigt und wie diese eingesetzt werden. Ebenso steht die Bedeutung unterschiedlicher Daten-typen auf dem Programm. Außerdem wird beschrieben, wie Sie Tastatureingaben vom Benutzer abfragen – schließlich kommt kaum ein Programm ohne Benutzer-eingaben aus. Die bereits in den vorigen Kapiteln erlern-ten Techniken können Sie gut einsetzen, um die eingegebenen Daten zu verarbeiten und das Ergebnis wieder auf dem Bildschirm auszugeben.

Page 89: Visual C# 2005 easy

88 Kapitel 7

VariablendefinitionVielfach ist es beim Programmlauf erforderlich, Werte zwischenzuspeichern,um sie später weiterverarbeiten zu können. Dies können sowohl Benutzerein-gaben als auch Informationen sein, welche vom Programm intern erzeugt wer-den. Zu Letzteren zählen etwa Zwischenergebnisse im Rahmen umfangreicherBerechnungen.

C# stellt, wie alle modernen Programmiersprachen, hierfür das Konzept der Va-riablen zur Verfügung. Eine Variable ist ein benannter Ort im Arbeitsspeicher,an dem Werte abgelegt, gelesen und auch verändert werden können.

Bevor eine Variable verwendet werden kann, das heißt eine Speicherstelle sichmit Namen ansprechen lässt, müssen Sie die Variable zunächst definieren. Erstmit der Variablendefinition reservieren Sie Speicherplatz für Informationen.

Bei der Definition von Variablen gehen Sie wie folgt vor:

• Geben Sie den Datentyp an, den die Variable besitzen soll.

• Wählen Sie einen Bezeichner für die Variable.

Regeln zur Bezeichnerwahl

Für verschiedene Elemente wie z.B. Variablen, Klassen oder Methodenvergeben Sie im Code Namen. Der Fachausdruck für solche Namen ist»Bezeichner«. Grundsätzlich dürfen Sie Bezeichner unter Beachtung fol-gender Regeln frei wählen: • Bezeichner setzen sich aus Buchstaben und Ziffern zusammen. Son-

derzeichen sind mit Ausnahme des Unterstrichs (_) nicht zulässig.Umlaute, das »ß« und andere landesspezifische Zeichen sind zwarerlaubt, wir empfehlen Ihnen jedoch, diese möglichst zu vermeiden.

• Das erste Zeichen darf keine Ziffer sein. • Groß- und Kleinschreibung wird – wie generell in C# – unterschieden.• Bezeichner müssen eindeutig sein.

Letzteres hat zur Folge, dass Sie innerhalb eines Gültigkeitsbereichs(dazu später mehr) grundsätzlich nicht den gleichen Bezeichner für zweiverschiedene Elemente vergeben dürfen. Ebenso wenig dürfen Bezeich-ner gleich lauten wie Schlüsselwörter.

Page 90: Visual C# 2005 easy

Variablendefinition 89

Wie bereits erwähnt, unterscheidet C# zwischen verschiedenen Datentypen.Mit der Angabe des Datentyps legen Sie ein für alle Mal fest:

• die Größe des reservierten Speicherplatzes,

• die Art von Daten, welche an diesem Speicherort abgelegt werden können,

• die Art von Operationen, welche mit diesen Daten ausgeführt werden kön-nen (vergleiche Kapitel 6, »Verknüpfung von Strings «).

So werden z. B. für eine Variable vom Datentyp int, welche zur Aufnahme vonganzen Zahlen vorgesehen ist, vier Byte reserviert. Dagegen beansprucht eineVariable vom Datentyp double acht Byte im Arbeitsspeicher. Letztere wird zurAufnahme von Zahlen mit Nachkommastellen verwendet.

Des Weiteren kann eine Variable nur Werte des Datentyps aufnehmen, für densie vorgesehen ist. So kann eine Variable vom Datentyp string ausschließlichZeichenketten (Strings) speichern, nicht etwa Zahlenwerte. Ebenso ist es z. B.offensichtlich, dass Sie mit Zeichenketten keine mathematischen Operationendurchführen können, wohl aber mit Werten vom Datentyp int. Von daher be-stimmt der Datentyp einer Variablen, welche Operationen mit den enthaltenenWerten möglich sind.

Wir werden uns auf die Verwendung der wichtigsten der von .NET zur Verfü-gung gestellten Datentypen beschränken. Dazu gehört ein Datentyp fürStrings, einer für Ganzzahlen, einer zur Verarbeitung von Zahlen mit Nachkom-mastellen, ein Datentyp zur Aufnahme von einzelnen Zeichen sowie der boole-sche Datentyp zum Speichern von Wahrheitswerten. Mit diesen Datentypenkönnen Sie alle Aufgaben lösen. Daneben existieren eine Reihe weiterer Da-tentypen, die sich von den genannten jedoch allein in puncto Wertebereichund Speicherbedarf unterscheiden. Genannt sei etwa der Datentyp byte zumSpeichern von positiven Ganzzahlen im Bereich von 0 bis 255. Wenn Sie also

Folgende Variablennamen sind z.B. korrekt:

kmProSekkm_pro_sekmyVar1myVar_2

Beispiele für ungültige Bezeichner:

my Var // Leerzeichen nicht erlaubt1abt // erstes Zeichen darf keine Ziffer seinclass // class ist ein Schlüsselwort und darf deshalb // nicht zur Bezeichnerwahl herangezogen werden

Page 91: Visual C# 2005 easy

90 Kapitel 7

wissen, dass eine Variable positive Ganzzahlen aufnehmen wird, die nicht grö-ßer als 255 sind, können Sie an Stelle des Datentyps int auch den Datentypbyte verwenden. Während eine int-Variable vier Byte beansprucht, benötigteine Variable vom Typ byte nur ein Byte im RAM (bei den heutigen Speicher-ressourcen dürfte das allerdings das geringste Problem sein). Die genanntenDatentypen sind in der folgenden Tabelle aufgelistet:

Tabelle 7.1: Wichtige Datentypen in C#

In C# steht hinter jedem Datentyp eine Klasse des .NET Framework und Schlüs-selwörter wie int, string, double usw. sind eigentlich nichts anderes als vonder Sprache C# bereitgestellte Synonyme zur Bezeichnung der entsprechen-den Klassen. Diese Schlüsselwörter (erste Tabellenspalte) verwenden Sie auchzur Angabe des Datentyps bei der Variablendefinition. In der letzten Spaltesteht der Name des eigentlichen Datentyps, so wie er im .NET Framework de-finiert ist.

Die zweite Spalte gibt die Größe an, die eine Variable dieses Datentyps bean-sprucht. Dabei stellt der Datentyp string einen Sonderfall dar. Er bean-sprucht für jedes Zeichen zwei Byte. Sie können in eine Variable vom Datentypstring jede beliebige Zeichenkette ablegen. Die einzige Größenbeschrän-kung ergibt sich aus den Speicherressourcen des Computers, auf dem Ihr Pro-gramm ausgeführt wird. Dies setzt eine dynamische Speicherverwaltungvoraus, worauf wir aber zum jetzigen Zeitpunkt nicht näher eingehen wollen.

Hier die Wertebereiche der anderen Datentypen:

• Der Datentyp int umfasst alle ganzen Zahlen im Bereich von -2147483648bis 2147483647.

• Der Wertebereich des Datentyps double erstreckt sich von ±5.0 * 10-324

bis ±1.7 * 10308.

Alias Größe Datentyp

int 32 Bit Int32

double 64 Bit Double

char 16 Bit Char

string 16 Bit pro Zeichen String

bool 1 Bit Boolean

Page 92: Visual C# 2005 easy

Variablendefinition 91

• Der Datentyp char dient zur Aufnahme von einzelnen Zeichen. C# verwen-det dabei wie beim Datentyp string den Unicode-Zeichensatz. Diesermöglicht die Speicherung praktisch jedes Schriftzeichens jeder beliebi-gen Landessprache.

• Der Wertebereich des Datentyps bool besteht aus den beiden Wahrheits-werten true und false.

Besondere Bedeutung kommt dem booleschen Datentyp im Zusammenhangmit Kontrollstrukturen zu. Diese werden Sie in den Kapiteln 10 und 11 kennenlernen.

Nun gehen Sie daran, Ihre erste Variable zu definieren. Wie schon angedeutet,gestaltet sich dieser Vorgang denkbar einfach. Sie müssen nur festlegen, wel-chen Datentyp die Variable besitzen soll, also eines der in der obigen Tabelle(erste Spalte) angegebenen Schlüsselwörter zur Angabe des Datentyps hin-schreiben.

1 Legen Sie in Ihrer Visual C# Express Edition ein neues Projekt vom Typ Konsolen-anwendung an.

Lassen Sie uns als Erstes eine Variable zur Aufnahme von Strings definieren.Dazu verwenden Sie das Schlüsselwort string.

2 Tippen Sie in der Main()-Methode das Schlüsselwort string ein:

static void Main(string[] args){ string}

3 Wählen Sie einen Bezeichner für die Variable. Nennen Sie diese doch sinniger-weise ersteVariable:

static void Main(string[] args){ string ersteVariable;}

Was ist das?

Der Unicode-Zeichensatz erlaubt die Darstellung von bis zu 65536 ver-schiedenen Zeichen. Jedem Zeichen ist eine Ordnungszahl eindeutigzugeordnet. Die Ordnungsnummern sind fortlaufend. Die ersten 256 Zei-chen entsprechen dabei der bis dato häufig verwendeten ASCII-Tabelle.

Page 93: Visual C# 2005 easy

92 Kapitel 7

Da eine Variablendefinition schließlich auch eine Anweisung wie jede andereist, dürfen Sie das abschließende Semikolon nicht vergessen. Damit ist die De-finition Ihrer string-Variablen bereits abgeschlossen.

Die Variable ersteVariable ist nun existent. Der Name ersteVariable be-zeichnet somit einen Ort im Arbeitsspeicher, an dem Ihr Programm später Wer-te ablegen kann. Zunächst sind dort jedoch noch keine Werte vorhanden.

Eine Variable kann man sich unmittelbar nach der Definition wie einen leerenBehälter vorstellen, wobei der Name des Behälters der Bezeichner der Variab-len ist.

Abbildung 7.1: Die Variable – hier »ersteVariable« – fungiert als eine Art Behälter, der vorerst noch leer ist

Um in diesem Behälter Werte abzulegen oder aber Werte auszulesen, welchein dem Behälter gespeichert wurden (möglicherweise, um damit Berechnun-gen durchzuführen), müssen Sie den Bezeichner der Variablen in den Quell-code schreiben. Dazu gleich mehr.

Hinweis

Der eigentliche Datentyp – der Name der entsprechenden .NET-Klasse –heißt zwar String (siehe Tabelle oben, letzte Spalte). Das von C# zurVerfügung gestellte Schlüsselwort zur Festlegung des Datentyps bei derDefinition wird aber kleingeschrieben – string. Ebenso verhält es sichmit den Datentypen Double (Schlüsselwort double), Char (char),Boolean (bool) und Int32 (int). Genau genommen könnten Sie beider Definition auch den tatsächlichen Klassennamen angeben – wasjedoch nicht üblich ist.

ersteVariable

Page 94: Visual C# 2005 easy

Die Zuweisung 93

Die ZuweisungBei der Zuweisung handelt es sich um eine spezielle Anweisung. Wie der Namebereits andeutet, wird mit der Ausführung einer solchen Anweisung währenddes Programmlaufs in einer Variablen ein neuer Wert abgelegt. Man sagt auch,»die Variable bekommt einen neuen Wert zugewiesen«.

Tatsächlich ändert sich mit einer Zuweisung der Inhalt der in der Zuweisung be-zeichneten Variablen, das heißt der Speicherstelle, für die der Variablennamesteht.

Eine Zuweisung stellt ebenso wie die schon gezeigte mathematische Additionoder die Stringverknüpfung eine Operation dar. Sie wird durch den so genann-ten Zuweisungsoperator repräsentiert. Dieser wird mit dem Gleichheitszei-chen (=) dargestellt. Es sei bereits an dieser Stelle darauf hingewiesen, dass

Hinweis

Tatsächlich besitzt eine Variable nach ihrer Definition einen undefinier-ten (nicht kontrollierbaren) Wert. Denn der Speicherort, welcher im Zugeder Variablendefinition für zukünftige Werte reserviert wird, erfährt vor-erst keine Veränderung. Sind dort bereits Daten vorhanden – die mögli-cherweise von früheren Programmläufen stammen, gegebenenfalls auchRelikte früher ausgeführter Programme darstellen –, werden diesezunächst nicht gelöscht. Dies geschieht erst dann, wenn während desProgrammlaufs neue Werte in die Variable – das heißt an diese Stelle –geschrieben werden.

Um Programmierer vor Fehlern zu schützen, verhindert C# jedoch denZugriff auf Variablen, welche keine kontrollierten Werte enthalten (mit»kontrollierten Werten« sind Werte gemeint, die Variablen per Pro-grammcode nach der Definition zugewiesen werden). Von daher kommtdas Bild vom leeren Behälter der Wirklichkeit ausreichend nahe.

Hinweis

Beachten Sie, dass eine Variable zur gleichen Zeit nur einen einzigenWert enthalten kann. Mit jeder Neuzuweisung geht somit der alte Wertunwiederbringlich verloren.

Page 95: Visual C# 2005 easy

94 Kapitel 7

die Bedeutung des Zuweisungsoperators nicht dem Ist-Gleich-Zeichen in derMathematik entspricht.

Eine Zuweisung setzt sich insgesamt aus drei Teilen zusammen:

• dem Zuweisungsoperator,

• einem linken Operanden. Dieser besteht immer aus genau einem Variab-lennamen. Damit wird die Variable bezeichnet, die mit der Zuweisungeinen neuen Wert erhält.

• Als rechter Operand steht der zuzuweisende Wert. Allerdings darf hierauch ein komplexer Ausdruck stehen, welcher nach – interner – Berech-nung den zuzuweisenden Wert ergibt.

Weisen Sie nun Ihrer Variablen ersteVariable einen Wert zu. Gehen Sie da-bei wie oben beschrieben vor.

4 Schreiben Sie als Erstes den Zuweisungsoperator (also das Zeichen =) in den Quelltext:

static void Main(string[] args){ string ersteVariable; =}

5 Links vor den Zuweisungsoperator setzen Sie den Bezeichner für Ihre Variable, also ersteVariable:

static void Main(string[] args){ string ersteVariable; ersteVariable =}

6 Rechts neben dem Zuweisungsoperator notieren Sie den Wert, den die Variable erhalten soll (plus abschließendes Semikolon).

Hinweis

Beachten Sie, dass alle Anweisungen beim Programmlauf von oben nachunten abgearbeitet werden (in den Kapiteln 10 und 11 werden Sie erfah-ren, wie der Programmierer in diesen Ablauf eingreifen kann). Darausfolgt, dass die Zuweisung nach der Definition stehen muss, da eine Vari-able erst nach ihrer Definition existent ist und verwendet werden kann.

Page 96: Visual C# 2005 easy

Die Zuweisung 95

static void Main(string[] args){ string ersteVariable; ersteVariable = "C#";}

Nach Ausführung der Zuweisung ersteVariable = "C#" beim Programm-lauf enthält Ihre Variable den String "C#".

Abbildung 7.2: Der Variablen »ersteVariable« wurde ein Wert zugewiesen

7 Lassen Sie sich das Ergebnis der Zuweisung zeigen, indem Sie nach der Zuweisung den Inhalt der Variablen auf den Bildschirm ausgeben:

static void Main(string[] args){ string ersteVariable; ersteVariable = "C#"; Console.WriteLine(ersteVariable);}

Um den Wert der Variablen ersteVariable auf dem Bildschirm anzuzeigen,verwenden Sie die bereits bekannte Methode WriteLine(). Als Parameterschreiben Sie den Namen Ihrer Variablen zwischen die runden Klammern. Esversteht sich von selbst, dass die Ausgabeanweisung nach der Zuweisung ste-hen muss. Der Inhalt der Variablen kann schließlich erst dann ausgegeben wer-den, wenn er vorhanden ist.

8 Fügen Sie den obligatorischen Haltebefehl hinzu:

static void Main(string[] args){ string ersteVariable; ersteVariable = "C#"; Console.WriteLine(ersteVariable); Console.ReadLine();}

9 Bringen Sie Ihr Programm zur Ausführung, z.B. mit (F5).

Danach sollten Sie die Ausgabe C# erhalten.

ersteVariable

»C#«

Page 97: Visual C# 2005 easy

96 Kapitel 7

Allerdings wirkt die bloße Anzeige des Inhalts von ersteVariable etwastrocken. Ferner erschließt sich der Sinn der Ausgabe nicht für jemanden, derkeine Kenntnis darüber hat, welche Art von Daten überhaupt angezeigt wird.Es macht folglich einen informativeren Eindruck, wenn Sie die Ausgabe desVariablenwerts mit einem erklärenden Text versehen, z.B. in der Form:

Der Inhalt der Variablen "ersteVariable" ist:

Dies erreichen Sie, indem Sie vor der Anweisung Console.WriteLine(er-steVariable); den String "Der Inhalt der Variablen \"ersteVari-able\" ist: " ausgeben.

Was tun, wenn eine Anweisung sehr lang wird?Anweisungen beanspruchen in C# mitunter sehr viel Platz im Quellcode. Diesist vor allem dann der Fall, wenn der in einer Anweisung verwendete Stringsehr lang ist:

Console.Write("Der Inhalt der Variablen \"ersteVariable\" ist: ");

Hinweis

Erinnern Sie sich? Um das Zeichen " zur Ausgabe zu bringen, müssen Sieinnerhalb der Zeichenkette einen Backslash vor jedes auszugebendedoppelte Anführungszeichen setzen, also die Form \" wählen.

Achtung

Sie dürfen innerhalb eines Strings auf keinen Fall die Taste (¢) drücken.Das mit diesem Tastendruck eingefügte Zeichen ist vom Compiler innerhalbeines Strings nicht interpretierbar. Die folgende Form ist also nicht zulässig:

Console.Write("Der Inhalt der(¢)Variablen \"ersteVariable\" ist: "); // FEHLER

Sie würden beim Kompilierungsversuch eine Fehlermeldung erhalten.Viele Editoren brechen allerdings lange Zeilen automatisch um, was aberdann in aller Regel nur eine optische Angelegenheit ist, es wird also ander Umbruchstelle kein Carriage Return eingefügt. Der Code-Editor derVisual C# Express Edition führt standardmäßig keinen Zeilenumbruchdurch, kann aber über das Kontrollkästchen Zeilenumbruch in Extras/Optionen/Text-Editor/C#/Allgemein so konfiguriert werden, dass langeZeilen optisch umbrochen werden.

Page 98: Visual C# 2005 easy

Die Zuweisung 97

Natürlich können Sie im Editor einfach in einer Zeile weiterschreiben (aller-dings wird der Quellcode dann meist schnell unübersichtlich). Die gleiche Bild-schirmausgabe lässt sich aber auch mit mehreren Anweisungen realisieren:

Console.Write("Der Inhalt der Variablen");Console.Write(" \"ersteVariable\" ist: ");

Eine andere Möglichkeit ergibt sich aus der Tatsache, dass in C# Zwischen-raumzeichen beim Kompilieren grundsätzlich keine Rolle spielen (siehe Kapi-tel 5, Abschnitt »Leerräume«).

Also können Sie unter Anwendung des Verknüpfungsoperators den String zer-legen, um so die Ausgabeanweisung auf mehrere Zeilen zu verteilen:

Console.Write("Der Inhalt der Variablen " +"\"ersteVariable\" ist: ");

Auf diese Weise ließe sich in unserem Beispiel sogar die Ausgabe des Variab-lenwerts mit einbeziehen:

Console.Write("Der Inhalt der Variablen "+ "\"ersteVariable\" ist: " + ersteVariable);

10 Fügen Sie der Ausgabe des Variablenwerts einen erklärenden Text hinzu.

Verwenden Sie dazu eine der vorgeschlagenen Techniken.

static void Main(string[] args){ string ersteVariable;

Achtung

Diese Aussage gilt natürlich nicht für Zwischenraumzeichen, welche sichinnerhalb von Strings befinden. Denken Sie daran, dass ein String einenkonstanten Wert darstellt. Der Compiler versucht grundsätzlich, jedesZeichen in einer Zeichenkette zu interpretieren. Ist dies nicht möglich –wie im Falle eines mit (¢) erzeugten Zeichens – wird er mit einer Fehler-meldung darauf aufmerksam machen.

Hinweis

Ob Sie die zweite Zeile am Zeilenanfang beginnen lassen oder wie hierbündig zur Klammer, ist dabei eine reine Geschmacksfrage.

Page 99: Visual C# 2005 easy

98 Kapitel 7

ersteVariable = "C#"; Console.Write("Der Inhalt der Variablen " +"\"ersteVariable\" ist: "); Console.WriteLine(ersteVariable); Console.ReadLine();}

11 Überzeugen Sie sich vom Ergebnis.

Abbildung 7.3: Das Beispielprogramm gibt den Inhalt der Variablen »ersteVariable« aus

Initialisieren von VariablenEs ist erlaubt, Variablen bereits im Zuge ihrer Definition einen Anfangswert zu-zuweisen. Man spricht in einem solchen Fall vom Initialisieren. So können Siez.B. die Variable ersteVariable auch in einer Anweisung definieren und mitdem String "C#" initialisieren:

static void Main(string[] args){ string ersteVariable = "C#"; Console.Write("Der Inhalt der Variablen " +"\"ersteVariable\" ist: "); Console.WriteLine(ersteVariable); Console.ReadLine();}

Auf der CD-ROM

Das Beispiel finden Sie unter Beispiele/Konsolenprogramme auf derBuch-CD (Projektname K07a).

Page 100: Visual C# 2005 easy

Unterschiedliche Bedeutung von Variablenbezeichnern im Quellcode 99

Unterschiedliche Bedeutung von Variablenbezeichnern im QuellcodeBedenken Sie, dass Sie Variablenbezeichner in drei Varianten im Quellcodeverwenden können:

• In einer Definitionsanweisung. Damit legen Sie die Variable an, das heißt,Sie reservieren Speicherplatz, den bzw. dessen Inhalt Sie ab diesem Zeit-punkt mit dem Variablenbezeichner ansprechen können.

• Auf der linken Seite einer Zuweisung. In diesem Fall bezeichnen Sie denSpeicherort an sich. Mit der Zuweisung schreiben Sie an die mit dem Vari-ablennamen bezeichnete Speicherstelle einen neuen Wert.

• An jeder anderen Stelle, an der Sie im Quellcode einen Variablenbezeich-ner notieren, sprechen Sie damit den Inhalt der Variablen (also derbezeichneten Speicherstelle) – und damit den enthaltenen Wert – an. BeimProgrammlauf geschieht Folgendes: Die Variable wird gelesen, das heißt,es wird intern zur Weiterverarbeitung eine Kopie des Variableninhaltsangefertigt. Die Variable selbst bleibt dabei unangetastet.

Ein Beispiel für die letzte Variante ist etwa die Anweisung

Console.Write("Der Inhalt der Variablen "+ "\"ersteVariable\" ist: " + ersteVariable);

Zum Zeitpunkt, zu dem diese Anweisung im Rahmen Ihres kleinen Programmszur Ausführung gelangt, enthält die Variable ersteVariable die Zeichen-kette "C#".

Bei Abarbeitung der Anweisung wird zunächst die Variable ersteVariablegelesen. Das heißt, es wird eine Kopie des in der Variablen enthaltenen Werts("C#") erzeugt. Mit dem kopierten Wert wird im nächsten Schritt die Zeichen-kette zusammengesetzt. Im Anschluss daran erfolgt die Ausgabe Der Inhaltder Variablen "ersteVariable" ist: C# auf den Bildschirm. Die Vari-able ersteVariable (deren Wert) ist dabei völlig unverändert geblieben.

Es ist nicht selten, dass ein Variablenbezeichner innerhalb einer Zuweisung inzweifacher Bedeutung auftritt. Dies wird deutlich, wenn Sie mit einer erneutenZuweisung den Inhalt Ihrer Variablen um den String-Wert "ist modern" er-gänzen:

ersteVariable = ersteVariable + " ist modern";

Hier tritt der Variablenbezeichner sowohl auf der rechten als auch auf der lin-ken Seite der Zuweisung auf. Machen Sie sich die Reihenfolge der internenSchritte deutlich:

Page 101: Visual C# 2005 easy

100 Kapitel 7

• Die Variable ersteVariable wird gelesen (kopierter Wert: "C#").

• Die beiden Strings "C#" und " ist modern" werden miteinander verket-tet.

• Nun erfolgt die Zuweisung der verknüpften Zeichenkette "C# istmodern" an die Variable ersteVariable. Die bis dahin in der Variablengespeicherte Zeichenkette ("C#") wird dabei überschrieben.

Falls Sie testen möchten, ob die Neuzuweisung das beschriebene Ergebniszeigt, hier das zugehörige Listing:

static void Main(string[] args){ string ersteVariable = "C#"; ersteVariable = ersteVariable + " ist modern"; Console.Write("Der Inhalt der Variablen " + "\"ersteVariable\" ist: "); Console.WriteLine(ersteVariable); Console.ReadLine();}

Ausgabe:

Der Inhalt der Variablen "ersteVariable" ist: C# ist modern

Beachten Sie in diesem Zusammenhang auch, dass die Abarbeitung einer Zu-weisung stets von rechts nach links erfolgt. Dies ist offensichtlich, wenn alsrechter Operand ein komplexer Ausdruck steht. Dieser muss erst ausgewertet

Hinweis

Mit jeder Neuzuweisung geht der alte Wert einer Variablen verloren.Wenn Sie also den aktuellen Wert einer Variablen berücksichtigen wol-len, müssen Sie ihn vor der Zuweisung lesen. Mit anderen Worten, Siemüssen den Variablenbezeichner in irgendeiner Form auch rechts desZuweisungsoperators verwenden.

Auf der CD-ROM

Wir beschränken uns bei der Darstellung wie gewohnt auf den Code derMain()-Methode. Das vollständige Beispiel finden Sie unter dem Pro-jektnamen K07b im Ordner Beispiele/Konsolenprogramme auf der Buch-CD.

Page 102: Visual C# 2005 easy

Notationen für Bezeichner 101

werden, bevor die Zuweisung des Berechnungsergebnisses erfolgen kann.Aber auch, falls es sich um einen einfachen Wert handelt, muss dieser vor dereigentlichen Zuweisung zumindest einmal »angefasst« werden.

Notationen für BezeichnerIn umfangreichen Quelltexten treten in der Regel eine Vielzahl von Variablen-bezeichnern auf. Dazu kommen Bezeichner für Klassen, Methoden, Felder, Ei-genschaften, eventuell Namensräume usw. Um die Lesbarkeit des Quellcodeszu verbessern, ist es sinnvoll, sich bei der Bezeichnerwahl gewissen – selbstauferlegten – Regeln zu unterwerfen:

• Verwenden Sie möglichst »sprechende« Namen. Das heißt, greifen Sie aufBezeichner zurück, die etwas über den Anwendungszweck des Elementsaussagen, z.B. der Variablen.

• Gewöhnen Sie sich an eine einheitliche Groß- und Kleinschreibung.

Das Überarbeiten eines Quelltextes gestaltet sich viel einfacher, wenn Sie esmit Variablennamen zu tun haben, die sich selbst erklären, z.B. betrag, summeund anzahl. Nichts sagende Variablenbezeichner wie a, b, c, x und y dagegenführen dazu, dass die Nachvollziehbarkeit von umfangreichen Quelltextensehr schwer wird.

Die zweite Empfehlung ergibt sich aus der Tatsache, dass C# zwischen Groß-und Kleinschreibung unterscheidet. Wenn Sie eine Variable summe wie folgtdeklarieren

double summe;

dürfen Sie später im Quellcode nicht schreiben

Console.Write(Summe); // FEHLER

Ein in der letzten Anweisung bezeichnetes Element Summe ist dem Compilernicht bekannt. Er kennt nur – weil zuvor definiert – eine Variable summe (nichtSumme).

Natürlich ist die Gefahr, dass Ihnen solche Fehler unterlaufen, bei sehr kleinenProgrammen eher gering. Wie verhält es sich aber, wenn Ihr Quellcode bei-spielsweise 50 Variablen enthält und sich über mehrere Seiten erstreckt. Ange-nommen, Sie verwenden auf Seite X eine Variable, die Sie fünf Seiten zuvordefiniert haben. Dann ist es müßig, jedes Mal nachschauen zu müssen, weilSie sich nicht sicher sind, wie Sie die Variable bei deren Definition geschriebenhaben, vor allem in puncto Groß- und Kleinschreibung. Wenn Sie sich jedochz.B. angewöhnt haben, für Bezeichner von Variablen grundsätzlich immer

Page 103: Visual C# 2005 easy

102 Kapitel 7

Kleinbuchstaben zu verwenden, dann stellt sich die Frage nach der Schreibwei-se erst gar nicht.

Die von Microsoft empfohlenen Schreibweisen für Bezeichner heißen Pascal-Casing bzw. camelCasing.

PascalCasingBeim PascalCasing wird der erste Buchstabe eines Bezeichners stets groß-,alle folgenden kleingeschrieben:

Summe, Rechteck, X, Y

Besteht ein Bezeichner aus mehreren Wörtern, so wird zusätzlich jeweils dererste Buchstabe eines Worts großgeschrieben:

FirstClass, MeineKlasse

Microsoft empfiehlt PascalCasing für die Bezeichner von Konstanten, Eigen-schaften, Methoden, Klassen und Namensräumen. Diese Elemente lernen Sieim weiteren Verlauf des Buchs noch kennen.

camelCasingBeim camelCasing wird der erste Buchstabe eines Bezeichners immer kleinge-schrieben:

summe, rechteck, x, y

Ansonsten verhält es sich wie beim PascalCasing. Besteht ein Bezeichner ausmehreren Wörtern, so wird entsprechend der erste Buchstabe jedes folgendenWorts großgeschrieben:

ersteVariable, myNumber, bigPoint

Microsoft empfiehlt camelCasing für die Bezeichner von lokalen Variablen undMethodenparametern.

Was ist das?

Alle Variablen, die im Rumpf einer Methode deklariert sind, nennt manlokale Variablen. Man sagt, sie sind lokal zu der Methode, in der sie defi-niert sind. Dies hat Einfluss auf ihren Gültigkeitsbereich. Dazu spätermehr. Vorerst haben Sie es ausschließlich mit lokalen Variablen zu tun.Auf Methodenparameter werden wir in Kapitel 13 zu sprechen kommen.

Page 104: Visual C# 2005 easy

Die Methode ReadLine() 103

Es sei hier noch erwähnt, dass es sich mit diesen Schreibweisen lediglich umEmpfehlungen handelt. Es besteht für Sie kein Zwang, sich daran zu halten.Ratsam ist es auf jeden Fall, sich hinsichtlich der Bezeichnerwahl an eine ein-heitliche Notation zu gewöhnen.

Die Methode ReadLine()Um Benutzereingaben auf der Konsole entgegenzunehmen, stellt C# dieMethode ReadLine() zur Verfügung. Diese Methode ist wie die MethodenWrite() und WriteLine() in der Klasse Console deklariert. Wenn Sie dieMethode ReadLine() verwenden, müssen Sie also schreiben

Console.ReadLine();

Wenn Sie die Anweisung so in den Quellcode schreiben, ist das zwar syntak-tisch korrekt, das heißt der Quellcode lässt sich ohne Fehlermeldung kompilie-ren. Um den Eingabebefehl jedoch wirklich sinnvoll einzusetzen, müssen Sienoch eine Kleinigkeit ergänzen. Schauen wir uns zunächst an, wieReadLine() in der obigen Form arbeitet.

1 Legen Sie in Ihrer IDE ein neues Projekt vom Typ Konsolenanwendung an.

2 Fügen Sie Ihrer Main()-Methode den Aufruf von ReadLine() hinzu:

static void Main(string[] args){ Console.ReadLine();}

3 Starten Sie mit (F5).

Sie bekommen im Konsolenfenster eine blinkende Einfügemarke zu sehen.Das Programm hält an und wartet auf eine Eingabe.

4 Geben Sie irgendetwas ein und drücken Sie (¢).

Die Einfügemarke springt in die nächste Zeile – was Sie nicht mehr mitbekom-men werden, da das Konsolenfenster sofort geschlossen und das Programmbeendet wird.

Was die Anweisung Console.ReadLine(); nach außen bewirkt, haben Sienun gesehen:

• Unterbrechung des Programmlaufs

• Blinken der Einfügemarke

Page 105: Visual C# 2005 easy

104 Kapitel 7

• Entgegennahme einer Benutzereingabe

• Setzen der Einfügemarke in die nächste Zeile

Wie ist es nun im weiteren Verlauf möglich, auf einen eingegebenen Wert zu-zugreifen? Wenn Sie die Eingabeanweisung so belassen, muss die Antwortlauten: überhaupt nicht. Die Eingabedaten sind mit der nächsten Programm-zeile für immer verloren.

Um eine Benutzereingabe weiterverarbeiten zu können, ist es notwendig, die-se fest zu speichern. Und dafür steht Ihnen schließlich der Gebrauch von Vari-ablen zur Verfügung.

Wir setzen voraus, eine string-Variable mit dem Bezeichner ein sei bereitsdefiniert. Um den Eingabewert in dieser Variablen abzulegen, schreiben Siewie folgt:

ein = Console.ReadLine();

Mit anderen Worten: Sie weisen den Rückgabewert der Methode ReadLine()der Variablen ein zu.

Hinweis

Wie bei der Methode WriteLine() können Sie die letztgenannte Wir-kung (Zeilenvorschub) von ReadLine() an dem Line im Methoden-bezeichner ablesen.

Rückgabewert: Was ist das?

Viele Methoden, z.B. ReadLine(), liefern nach Ausführung einen Wertzurück, man spricht dabei vom Rückgabewert. Es gibt aber auch Metho-den, die keinen Wert zurückgeben, etwa Write() oder WriteLine().Der Rückgabewert von ReadLine() entspricht der Benutzereingabe aufder Konsole.

Beachten Sie: • Die Verwendung des Namens einer Methode im Programmiercode

repräsentiert gleichzeitig den Rückgabewert der Methode (dies giltnatürlich nur für Methoden, welche einen Rückgabewert besitzen).Der Ausdruck Console.ReadLine() steht also gleichzeitig für denRückgabewert dieser Methode.

Page 106: Visual C# 2005 easy

Die Methode ReadLine() 105

Solange Sie den Wert einer Variablen nicht durch Neuzuweisung überschrei-ben, können Sie im weiteren Verlauf Ihres Programms darauf zugreifen. Dazuverwenden Sie den Variablenbezeichner einfach an passender Stelle, z.B. :

Console.Write("Sie haben \"" + ein + "\" eingegeben");

Ausgabe:

Sie haben "Benutzereingabe" eingegeben

Benutzereingabe steht hier für eine zuvor vom Benutzer während eines Pro-grammlaufs getätigte Eingabe.

Lassen Sie uns zur Übung ein Programm schreiben, welches den Benutzer zurEingabe seines Vornamens auffordert und diesen dann in einer Begrüßungs-formel verwendet.

5 Definieren Sie eine Variable vorname vom Datentyp string und verwenden Sie diese dazu, die Benutzereingabe festzuhalten.

static void Main(string[] args){

string vorname; vorname = Console.ReadLine();}

6 Richten Sie eine Ausgabeanweisung ein, welche den Benutzer zur Eingabe seines Vornamens auffordert.

Natürlich muss die Aufforderung vor der Eingabe stehen:

static void Main(string[] args){

string vorname; Console.Write("Sagen Sie mir Ihren Vornamen: "); vorname = Console.ReadLine();}

• Auch Rückgabewerte besitzen einen Datentyp. Der Rückgabewert derMethode ReadLine() ist vom Datentyp string. Deshalb könnenSie ihn einer string-Variablen zuweisen. Hätten Sie die Variableein etwa als int-Variable definiert, wäre die Anweisung ein =Console.ReadLine(); fehlerhaft (unerlaubter Versuch, einerint-Variablen einen Wert vom Datentyp string zuzuweisen).

In Kapitel 13 werden Sie sich mit Methoden und deren Rückgabewertengenauer befassen.

Page 107: Visual C# 2005 easy

106 Kapitel 7

Wenn Sie den Code in Ihrer IDE ausführen lassen, sollten Sie die Bildschirm-ausgabe Sagen Sie mir Ihren Vornamen: erhalten. Nach der Eingabe,die Sie mit (¢) bestätigen, bricht das Programm ab. Was noch fehlt, ist die Be-grüßungsformel.

7 Begrüßen Sie den Benutzer mit seinem zuvor eingegebenen Vornamen. An-schließend verwenden Sie ReadLine() wiederum, um das Programm anzuhalten:

static void Main(string[] args){

string vorname; Console.Write("Sagen Sie mir Ihren Vornamen: "); vorname = Console.ReadLine(); Console.WriteLine("Hallo " + vorname); Console.ReadLine();}

Tipp

An dieser Stelle sei nochmals daran erinnert: Lassen Sie sich das Ergeb-nis Ihrer Programmierarbeit auch während der Entstehungsphase IhrerProgramme in regelmäßigen Abständen anzeigen (Taste (F5)), um sovon eventuellen Fehlern frühzeitig Kenntnis zu erlangen. Diese Empfeh-lung gilt umso mehr, je weniger Programmiererfahrung Sie besitzen.

Die Vorteile: • Die Fehlersuche gestaltet sich wesentlich einfacher. Dies gilt nicht

nur für Syntaxfehler. Gerade logische Fehler bzw. deren Ursachensind in einem frühen Entwicklungsstadium viel leichter auszuma-chen.

• Es gibt Ihnen während der Programmentwicklung immer wieder dieGewissheit, »bis hier ist alles o.k.«.

Und noch ein Hinweis: Solange Sie keine Fehlermeldungen, sondern nurWarnmeldungen erhalten, wird Ihr Code erfolgreich kompiliert und aus-geführt. Um potenzielle Fehlerquellen auszuschließen, sollten Sie Warn-meldungen dennoch immer auf den Grund gehen.

Auf der CD-ROM

Das Beispiel finden Sie unter Beispiele/Konsolenprogramme auf derBuch-CD (Projektname K07c).

Page 108: Visual C# 2005 easy

Eine kleine Erfolgskontrolle 107

Die letzte Ausgabe setzt sich aus dem String "Hallo " und dem Inhalt derVariablen vorname zusammen. Letztere enthält zum Zeitpunkt des Zugriffsden zuvor eingegebenen Vornamen des Benutzers.

8 Bringen Sie Ihr Programm zur Ausführung.

Nach Programmende sollte – in Abhängigkeit Ihrer Eingabe – etwa das in derAbbildung dargestellte Ergebnis erscheinen.

Abbildung 7.4: Der eingegebene Name gelangt in Form einer Begrüßungsformel zur Ausgabe

Eine kleine Erfolgskontrolle• zahl sei eine Variable vom Datentyp int. Was bewirkt die folgende Zuwei-

sung?zahl = zahl + 3;

• Was bedeutet Initialisieren von Variablen?

• Definieren Sie eine int-Variable mit dem Bezeichner z und initialisierenSie diese mit dem Wert 0.

• Worin liegt der Fehler in folgendem Codestück?

string name;Console.Write(name);

• Erklären Sie die Funktionsweise folgender Anweisung:

Console.ReadLine();

• Ist 1A ein gültiger Bezeichner?

Page 109: Visual C# 2005 easy

Das können Sie schon:

Entwicklungsschritte zum lauffähigen C#-Programm 11

Umgang mit der Visual C# Express-IDE 36

Aufbau und grundlegende Syntax von C#-Programmen 48

Kommentare 67

Arbeiten mit Strings 75

Steuerzeichen 81

Variablen und Datentypen 87

Verarbeiten von Benutzereingaben 103

Das lernen Sie neu:

Literale und benannte Konstanten 110

Konvertieren eines Werts von einem Datentyp in einen anderen 124

Page 110: Visual C# 2005 easy

Kapitel 8

KonstantenIn diesem Kapitel lernen Sie mehr über den Umgang mit konstanten Werten. Insbesondere erfahren Sie, wie Werte eines bestimmten Da-tentyps in einen anderen Datentyp konvertiert werden können und wann dies notwendig ist. Das in diesem Kapitel erworbene Wissen bildet die Grundlage für weitere Übungen in diesem Buch.

Page 111: Visual C# 2005 easy

110 Kapitel 8

Literale»Literal« ist in der Programmierung die fachsprachliche Bezeichnung für einenkonstanten Wert bzw. für dessen Repräsentation im Quellcode. Man sprichtauch von unbenannten Konstanten – im Gegensatz zu den benannten Konstan-ten, welche wir Ihnen im nächsten Abschnitt vorstellen.

Literale lassen sich demnach wie folgt charakterisieren:

• Sie stehen im Quelltext für unveränderliche Werte, das heißt, sie repräsen-tieren diese Werte.

• Sie beanspruchen keinen benannten Speicherplatz, daher die Bezeich-nung unbenannte Konstanten.

• Sie besitzen ebenfalls einen bestimmten Datentyp.

Bis jetzt hatten Sie es ausschließlich mit string- und Integer-Konstanten zutun. string-Konstanten sind nichts anderes als Zeichenketten (Strings). Mitdiesen sind Sie ja schon hinreichend vertraut.

Integer-Konstanten haben wir bereits in Kapitel 6 (Abschnitt Zeichenketten)angesprochen, als wir zeigten, dass die Methode WriteLine() nicht nurStrings, sondern z.B. auch Integer-Werte verarbeiten kann:

Console.WriteLine(999);

Hinweis

Statt »Strings« bzw. »string-Konstanten« könnten wir natürlich ebensostring-Literale sagen (analog Integer-Literale für Integer-Konstanten).

Hinweis

Wir haben dort festgestellt, dass Zahlenkonstanten wie beispielsweise3, 47, -1 und natürlich auch 999 vom Datentyp int sind.

An anderer Stelle wurde außerdem darauf hingewiesen, dass in denÜbungen dieses Buchs nicht alle der von C# zur Verfügung gestelltenDatentypen Verwendung finden werden. Tatsächlich stellt C# noch eineReihe weiterer Datentypen zur Verarbeitung von Ganzzahlen bereit.Diese unterscheiden sich vom Datentyp int allein hinsichtlich ihres Wer-tebereichs. Ansonsten entspricht deren Handhabung der des Datentypsint.

Page 112: Visual C# 2005 easy

Literale 111

Der Datentyp einer unbenannten Konstanten ist durch ihre Schreibweise imQuellcode eindeutig festgelegt. Hierbei gelten die nachfolgend genanntenRegeln.

Literale zur Darstellung von TextwertenFolgende Regel kennen Sie bereits: Jede beliebige Folge von Zeichen, welchezwischen doppelten Anführungszeichen steht, wird vom Compiler als Zeichen-kette interpretiert – ist also vom Datentyp string.

Beispiele:

"Hallo""String\nmit\t\"Steuerzeichen\"\n""9022""a""33 + 107"

Wie Sie an dem String "9022" sehen können, gilt dies uneingeschränkt auchdann, wenn es sich ausschließlich um Ziffern handelt. Obwohl diese Zeichen-kette auch sinnvoll als numerischer Wert interpretiert werden könnte, ent-scheiden die "" über den Datentyp. Aus dem gleichen Grund handelt es sichmit "a" um eine Zeichenkette, welche eben nur ein einziges Zeichen enthält,und nicht um ein char-Literal. Desgleichen drückt "33 + 107" nicht die Dar-stellung einer mathematischen Addition aus, sondern eben einen bloßen Text-wert.

Der Datentyp char dient zur Repräsentation einzelner Zeichen. Wir haben die-sen Datentyp in Kapitel 7 bereits vorgestellt, jedoch hierfür noch kein Beispielgegeben. Das heißt, Sie haben bis jetzt weder eine Variable noch ein Literaldieses Typs verwendet.

1 Legen Sie in Ihrer IDE ein neues Projekt an.

Oberbegrifflich wird jeder Datentyp, der zur Verarbeitung von ganzenZahlen bereitsteht, als Integer-Datentyp bezeichnet. Analog spricht manauch von Integer-Werten (-Konstanten, -Literalen). 999 ist also eine Kon-stante vom Datentyp int – oder kurz: eine Integer-Konstante.

Page 113: Visual C# 2005 easy

112 Kapitel 8

2 Definieren Sie eine Variable vom Datentyp char:

static void Main(string[] args){ char ch;}

char-Literale werden im Quelltext daran erkannt, dass sie zwischen einfachenApostrophen ('...') stehen.

3 Weisen Sie der Variablen ch einen gültigen Wert zu, also z.B.

ch = 'X';

4 Geben Sie im Anschluss daran den Variablenwert mit WriteLine() auf den Bild-schirm aus und fügen Sie am Ende den obligatorischen Haltebefehl hinzu:

static void Main(string[] args){ char ch; ch = 'X'; Console.WriteLine(ch); Console.ReadLine();}

5 Testen Sie Ihr Programm.

Sie könnten dies abwechselnd mit verschiedenen Zeichen tun, indem Sie in derZuweisung ch = 'X' nacheinander verschiedene Literale verwenden.

Auf der CD-ROM

Das entsprechende Projekt finden Sie unter Beispiele/Konsolenpro-gramme auf der Buch-CD (Projektname K08a).

Hinweis

Beachten Sie, dass auch Steuerzeichen als einzelne Zeichen interpretiertwerden. Es sind daher auch Zuweisungen folgender Art möglich.

ch = '\n';

Page 114: Visual C# 2005 easy

Literale 113

Literale zur Darstellung von ganzen ZahlenEin ganzzahliges Literal besteht aus einer Folge von Ziffern, gegebenenfalls miteinem negativen Vorzeichen (-).

Es gilt die Regel: Jede Ganzzahl, welche im Wertebereich des int-Datentypsliegt, wird als von diesem Datentyp interpretiert.

Das ist nicht so selbstverständlich, wie es sich zunächst anhört. Um diesdeutlich zu machen, wollen wir Ihnen den Datentyp long vorstellen. DerWertebereich dieses Datentyps umfasst alle ganzen Zahlen von-9223372036854775808 bis 9223372036854775807 (also etwa im Bereichvon ±9 Trillionen), ist also um einiges größer als der von int. Eine Variable die-ses Typs nimmt im Arbeitsspeicher 64 Bit (8 Byte) ein.

Zur Erinnerung: Der Wertebereich des Datentyps int erstreckt sich von-2147483648 bis 2147483647 (also etwa im Bereich von ±2 Milliarden). Genauin diesem Bereich tritt also eine Überschneidung beider Wertebereiche auf(int mit long). Besitzen nun Literale wie 33, -4500, 1000000 und -11 denDatentyp int oder den Datentyp long? Denken Sie daran, dass jedem Literalgenauso wie jeder Variablen ein bestimmter Datentyp eindeutig zugeordnetist. Oben genannte Regel legt nun fest, dass ein Literal dieser Größe eben denDatentyp int aufweist.

Lassen Sie sich dies zeigen. Dazu verwenden Sie eine Methode namensGetType(). Diese liefert als Rückgabewert den Datentypnamen des Objekts,für das sie aufgerufen wird. Was dieser Satz bedeutet, werden wir nun ver-suchen zu klären.

Achtung

Beachten Sie, dass 'X' ein char-Literal, "X" jedoch ein Literal vomDatentyp string ist. Eine Zuweisung wie

char ch = "X";

ist daher nicht erlaubt.

Page 115: Visual C# 2005 easy

114 Kapitel 8

Bis jetzt haben Sie ausschließlich den Fall angetroffen, in dem Methoden unterAngabe eines Klassenbezeichners aufgerufen wurden;

Console.WriteLine("...");

oder eben

myString = Console.ReadLine();

Beide Methoden (WriteLine() sowie ReadLine()) sind in der KlasseConsole definiert, gehören also zu dieser Klasse. Bezüglich der Verwendungdieser Methoden könnte man sich auch dahingehend ausdrücken, dass dieseMethoden für die Klasse Console aufgerufen werden.

Nun ist aber auch der Fall denkbar, dass eine Methode nicht für die Klasse, inder sie definiert ist, aufgerufen wird, sondern für ein Objekt dieser Klasse.Dann wird zum Zugriff auf die Methode nicht der Klassenname, sondern einObjektname verwendet.

Nehmen wir als Beispiel eine fiktive Klasse Auto. Objekte dieser Klasse seiendie Autos MyOpel und YourVW. Die Klasse hätte unter anderem eine MethodeBeschleunigen() und eine Methode AutosZaehlen(). Letztere Methodeliefere als Rückgabewert die Anzahl aller – im Programm – existenten Autos.Dann wäre diese Methode sicher als zur Klasse selbst gehörig definiert, da sieauf alle Autos Bezug nehmen muss. Andererseits kann die MethodeBeschleunigen() nur sinnvoll eingesetzt werden, wenn sie auf einzelneObjekte der Klasse angewendet wird. Jeder Autotyp hat ja andere Beschleuni-gungswerte. Die Methode Beschleunigen() wird deshalb innerhalb derKlasse Auto entsprechend definiert sein. Die korrekten Methodenaufrufe lau-ten dann:

Auto.AutosZaehlen()

aber

Hinweis

Wenn eine Methode im Quellcode verwendet wird, spricht man auch voneinem Methodenaufruf.

string myString;myString = Console.ReadLine();

Bezüglich des Ausdrucks Console.ReadLine() können Sie alsosagen, »die Methode ReadLine() wird verwendet«, aber auch »dieMethode ReadLine() wird aufgerufen«.

Page 116: Visual C# 2005 easy

Literale 115

MyOpel.Beschleunigen()

bzw.

YourVW.Beschleunigen()

Aufrufe wie MyOpel.AutosZaehlen() oder Auto.Beschleunigen() wür-den beim Kompilierversuch Fehlermeldungen verursachen. Es gilt, eine Metho-de entweder immer mit dem Klassenbezeichner oder ausschließlich mit einemObjektnamen aufzurufen. Dies hängt von der einzelnen Methode (genauer vonderen Definition innerhalb der Klasse) ab.

Wenden wir uns wieder der Methode GetType() zu. Dass diese Methode ob-jektbezogen verwendet wird, wissen Sie bereits. Sie müssen sich also fragen,in welcher Klasse diese Methode definiert ist und wie die einzelnen Objektedieser Klasse heißen.

Nun müssen Sie wissen, dass hinter jedem elementaren Datentyp in C# eigent-lich eine Klasse steht.

Des Weiteren sind alle Literale und Variablen eines bestimmten Datentyps Ob-jekte der entsprechenden Klasse. Von daher stellt beispielsweise das Literal2003 ein Objekt der Klasse Int32 dar.

Hinsichtlich der Methode GetType() gilt: Jeder Datentyp (bzw. die Klasse,welche dahinter steht) stellt eine Methode dieses Namens – und mit ähnlicherFunktion – zur Verfügung.

Hinweis

Die elementaren Datentypen sind diejenigen, welche bis jetzt angespro-chen wurden. Sie gehören sozusagen zur Grundausstattung der Pro-grammiersprache C#. Deswegen werden sie auch Standarddatentypengenannt.

Page 117: Visual C# 2005 easy

116 Kapitel 8

Fassen wir zusammen:

• Jeder Standarddatentyp ist eigentlich eine Klasse. Die Klassennamen sindIhnen bekannt: Int32, Char, String, Double usw. Hinter dem Typ longsteht übrigens die Klasse Int64.

• Jede dieser Klassen besitzt eine eigene Methode GetType().

• Zum Zugriff auf diese Methode wird nicht der Klassenname, sondern derObjektname verwendet. Falsch wäre also Int32.GetType() // FEHLER

• Jedes Literal und jede Variable ist ein Objekt derjenigen Klasse, welchehinter dem Datentyp des Literals bzw. der Variablen steht. Das Literal 999ist demnach ein Objekt der Klasse Int32.

Wenn Sie also feststellen wollen, von welchem Datentyp das Literal 999 ist,schreiben Sie

999.GetType();

6 Fügen Sie diese Anweisung Ihrer Main()-Methode hinzu.

static void Main(string[] args){ char ch; ch = 'X'; Console.WriteLine(ch); 999.GetType(); Console.ReadLine();}

Die Methode GetType() gibt den Datentyp des Objekts zurück, für das sieaufgerufen wird. Um nun zu zeigen, welchen Datentyp das Literal 999 besitzt,müssen Sie diesen Rückgabewert auf den Bildschirm bringen. Dazu über-geben Sie ihn der Methode WriteLine().

Hinweis

Das war nun schon eine kleine Einführung in die objektorientierte Pro-grammierung, somit ein Vorgriff auf Themen, welche erst in Kapitel 14auf dem Plan stehen. Seien Sie deshalb nicht betrübt, wenn Sie nichtgleich alles verstanden haben. Die Ausführungen sind vornehmlich alsVerständnishilfe für die Verwendung der Methode GetType() – undweiterer Methoden, welche Sie demnächst kennen lernen werden –gedacht.

Page 118: Visual C# 2005 easy

Literale 117

Console.WriteLine(999.GetType());

Ein verschachtelter Methodenaufruf wie dieser mag für Sie zunächst etwas un-gewöhnlich erscheinen. Erinnern Sie sich daran, dass ein Methodenaufruf imQuelltext gleichzeitig für den Rückgabewert der Methode steht (vergleiche Ka-pitel 7, Abschnitt »Die Methode ReadLine()«). Sie dürfen also den Ausdruck999.GetType() grundsätzlich an jeder Stelle im Quellcode verwenden, an derauch ein einfacher Wert dieses Datentyps stehen kann.

Beachten Sie, dass die Abarbeitung eines verschachtelten Methodenaufrufsstets von innen nach außen erfolgt. Das bedeutet für die Anweisung Console.WriteLine(999.GetType());:

• Als Erstes kommt die Methode GetType() zur Ausführung.

• Im nächsten Schritt wird der Ausdruck 999.GetType() durch den Rück-gabewert ersetzt. Dieser wird der Methode WriteLine() übergeben.

• Zuletzt startet WriteLine() und sorgt für die Bildschirmausgabe.

7 Ergänzen Sie nun die letzte Anweisung wie beschrieben:

static void Main(string[] args){ char ch; ch = 'X'; Console.WriteLine(ch); Console.WriteLine(999.GetType()); Console.ReadLine();}

Hinweis

Der Rückgabewert der Methode GetType() ist vom Datentyp Type. Eshandelt sich also nicht um einen elementaren Datentyp. Das braucht Sieaber hier nicht zu kümmern, da die Methode WriteLine() nahezujeden Datentyp verarbeiten kann (dies gilt ebenso für die MethodeWrite()).

Page 119: Visual C# 2005 easy

118 Kapitel 8

8 Setzen Sie folgende Ausgabeanweisung davor:

Console.Write("Das Literal 999 ist vom Datentyp ");

Damit ergibt sich für die Main()-Methode folgendes Listing:

static void Main(string[] args){ char ch; ch = 'X'; Console.WriteLine(ch); Console.Write("Das Literal 999 ist vom Datentyp "); Console.WriteLine(999.GetType()); Console.ReadLine();}

9 Bringen Sie Ihr Programm zur Ausführung.

Nun können Sie den Datentyp des Literals 999 ablesen. Da die Klasse Int32im Namensraum System definiert ist, lautet die Bildschirmausgabe DasLiteral 999 ist vom Datentyp System.Int32.

Abbildung 8.1: Ausgabe des Datentyps per Methode »GetType()«

Wie Sie nun wissen, sind alle ganzzahligen Literale im Bereich von-2147483648 bis 2147483647 grundsätzlich vom Datentyp int.

Sie können jedoch durch Anhängen des Suffixes L oder l den Datentyp long(Klasse Int64) erzwingen:

long myVar;myVar = 999L;

Page 120: Visual C# 2005 easy

Literale 119

Die Literale 999l und 999L sind identisch. Hier brauchen Sie ausnahmsweiseauf Groß- und Kleinschreibung keine Rücksicht zu nehmen.

Literale zur Darstellung von Zahlen mit NachkommastellenDiese werden dargestellt wie ganzzahlige Literale zusätzlich eines Punkts zurTrennung von Vor- und Nachkommastellen. So gebildete Literale im Werte-bereich von ±5.0 * 10-324 bis ±1.7 * 10308 sind grundsätzlich vom Datentypdouble.

Beispiele:

99.9117897.56470.33-20.01.0-9033.11

Beachten Sie, dass der Punkt für den Datentyp ausschlaggebend ist. So reprä-sentiert das Literal 3.0 zwar einen ganzzahligen Wert, sein Datentyp ist jedochdouble. Folgende Initialisierung würde daher eine Fehlermeldung erzeugen.

int test = 3.0; // FEHLER

Der Grund: Es ist ein unerlaubter Versuch, einer Variablen vom Typ int einenWert vom Typ double zuzuweisen. Das Literal 3 hingegen ist vom Datentypint. Richtig ist also:

int test = 3; // OK

Hinweis

Weshalb diese Zuweisung auch ohne Anhängen eines Datentyp-Suffixesfunktioniert, werden wir weiter unten darlegen.

Page 121: Visual C# 2005 easy

120 Kapitel 8

Denken Sie daran, dass Sie im Quellcode als Trennzeichen immer den Punktverwenden müssen. Die Anzeige hingegen richtet sich nach landesspezifi-schen Einstellungen.

10 Definieren Sie eine double-Variable und weisen Sie dieser einen Wert zu.

static void Main(string[] args){ char ch = 'X'; double myDouble = 2004.99; Console.WriteLine(ch); Console.Write("Das Literal 999 ist vom Datentyp "); Console.WriteLine(999.GetType()); Console.ReadLine();}

Hinweis

Werte vom Datentyp double werden auch als Gleitkommawerte bzw.Gleitkommazahlen bezeichnet. Die Bezeichnung bezieht sich auf denEinfluss des Trennzeichens bei einer eventuellen Rundung.

So besitzt der Datentyp double eine Genauigkeit von 15-16 Stellen. Dasheißt, Rundungsfehler treten erst dann auf, wenn das Literal mehr als15 Ziffern hat. Dies ist unabhängig davon, an welcher Position sich dasTrennzeichen befindet.

Daher spielt es beispielsweise bei einem Literal wie1234567891234567.99 keine Rolle, wie viele Nachkommastellen sichhinter dem Trennzeichen befinden und wie groß deren Wert ist. Vor demPunkt befinden sich ja bereits mehr als 15 Stellen. Anders verhält es sichdagegen bei dem Literal 1.23456789123456799. Hier spielen Größeund Anzahl der Nachkommastellen sehr wohl eine Rolle. Je weiter derPunkt also nach links »gleitet«, desto größer wird seine Bedeutung fürdie Genauigkeit.

Page 122: Visual C# 2005 easy

Literale 121

11 Geben Sie den Wert von myDouble mithilfe der Methode WriteLine() aus:

static void Main(string[] args){ char ch = 'X'; double myDouble = 2004.99; Console.WriteLine(ch); Console.WriteLine(myDouble); Console.Write("Das Literal 999 ist vom Datentyp "); Console.WriteLine(999.GetType()); Console.ReadLine();}

12 Bringen Sie Ihr Programm zur Ausführung.

Die Ausgabe erfolgt mit dem Komma als Trennzeichen: 2004,99

Abbildung 8.2: Zur Ausgabe ist ein Wert vom Typ »double« hinzugekommen

Tipp

Möglicherweise wundern Sie sich darüber, weshalb wir die Definitionvon myDouble an den Anfang der Methode Main() gesetzt haben. Diesgebietet keine Vorschrift. Solange Sie Ihre Variablen definieren, bevorSie diese verwenden, ist das syntaktisch in Ordnung.

Im Sinne eines guten Programmierstils ist es jedoch empfehlenswert,alle Variablen zu Beginn eines Blocks zu definieren. Sie schaffen sichdamit gewissermaßen einen separaten Definitionsteil. Auf diese Weisekönnen Sie leichter erfassen, welche Variablen – gegebenenfalls mit wel-chen Initialisierungswerten – im Code vorkommen, welche Bezeichnerbereits verwendet wurden usw. Sie verlieren dann auch bei einer Vielzahlvon Variablen nicht so schnell den Überblick.

Page 123: Visual C# 2005 easy

122 Kapitel 8

Benannte KonstantenParadoxerweise handelt es sich bei den benannten Konstanten, mit denen wiruns hier befassen, vom Funktionsprinzip eigentlich um Variablen. Ebenso wiediese beanspruchen sie Platz im Arbeitsspeicher, müssen also vor ihrer Ver-wendung definiert werden. Allerdings dürfen sie ihren Wert nach der Definitionnicht mehr ändern, was zwingend eine Initialisierung voraussetzt.

Bei der Definition einer Konstanten gehen Sie wie folgt vor:

• Leiten Sie die Definition der Konstanten mit dem Schlüsselwort const ein.

• Initialisieren Sie die Konstante (siehe Kapitel 7, Abschnitt »Initialisierenvon Variablen«).

const int MWST = 16;

Ansonsten müssen Sie wie bei herkömmlichen Variablen den Datentyp ange-ben und einen Bezeichner wählen.

Beachten Sie, dass Konstanten allein an dem Schlüsselwort const erkanntwerden:

double myDouble = 3.14;const double PI = 3.14; // Konstante

Hinweis

Benannte Konstanten werden aus den genannten Gründen mitunter auchals »konstante Variablen« bezeichnet, auch wenn dies durch die wider-sprüchliche Aussage sprachlich recht ungeschickt formuliert ist. »Variab-len«, weil es sich um einen mit Namen ansprechbaren Speicherort handeltund »konstant«, weil der Inhalt dieses Speicherorts unveränderlich ist.

Tipp

Microsoft empfiehlt für die Notation von Konstanten PascalCasing (sieheKapitel 7, Abschnitt »PascalCasing«). Sie könnten aber auch einer gutenalten Gewohnheit seit den Zeiten der C-Programmierung folgen und kon-stante Variablen ausschließlich mit Großbuchstaben notieren. Da dannGroßbuchstaben nicht mehr als Worttrenner fungieren können, verwen-det man zur Trennung dann üblicherweise den Unterstrich (_), z.B.MWST_REDUZIERT statt MwStReduziert.

Page 124: Visual C# 2005 easy

Benannte Konstanten 123

Die Variable myDouble besitzt zwar nach ihrer Vereinbarung ebenfalls den Ini-tialisierungswert 3.14. Dieser kann jedoch im weiteren Verlauf durch Neuzu-weisungen immer wieder geändert werden.

Wenn der Programmierer dagegen im weiteren Verlauf versucht, PI einen neu-en Wert zuzuweisen, erntet er beim Kompilieren eine Fehlermeldung.

static void Main(){ double myDouble = 3.14; const double PI = 3.14; myDouble = 0.123; // OK PI = 7.77; // FEHLER}

Konstanten verwenden Sie in der Regel unter folgenden Gesichtspunkten:

• Um sicherzugehen, dass Werte auch wirklich unverändert bleiben, wenndies erforderlich ist.

• Bezeichner können so gewählt werden, dass sie selbstkommentierendsind. Dies erhöht die Lesbarkeit des Quellcodes. So besitzen benannteKonstanten wie MWST oder PI weit mehr Aussagekraft als die Literale 16bzw. 19 (in Anbetracht der Mehrwertsteuererhöhung vom 1. Januar 2007)oder 3.14.

• Eventuelle Änderungen müssen nur an einer einzigen Stelle im Quellcodeerfolgen.

Angenommen, Sie stehen vor der Aufgabe, eine Applikation für Steuererklä-rungen zu überarbeiten. Anlass sei die Erhöhung der Mehrwertsteuer von 16auf 19 Prozent. Bei Verwendung einer Konstanten müssten Sie lediglich denneuen Wert in der Definitionsanweisung austauschen (const int MWST =19;). Im weiteren Code wird schließlich nur mehr der Bezeichner MWST verwen-det. Andernfalls müssten Sie das Literal 16 an jeder Stelle im Code ändern, wasbei großen Programmen durchaus Tausende Codestellen betreffen kann, waseine enorme Fehlerquelle darstellt.

Hinweis

Wenn eine Variable neu angelegt wird, spricht man außer von »Defini-tion« auch von ihrer »Vereinbarung«. Insofern werden beide Begriffesynonym verwendet.

Page 125: Visual C# 2005 easy

124 Kapitel 8

Implizite TypumwandlungenWie Ihnen bekannt ist, gilt folgende Regel: Eine Variable kann entsprechend ih-rer Vereinbarung nur Werte eines bestimmten Datentyps aufnehmen. Daherdürfen z.B. in einer Variablen vom Datentyp int allein Werte dieses Typs abge-legt werden. Genauso haben in einer string-Variablen ausschließlich Strings(Werte vom Datentyp string) Platz.

Bei einer Zuweisung müssen Sie also grundsätzlich darauf achten, dass rechtsdes Zuweisungsoperators ein Literal bzw. ein Ausdruck vom Datentyp derVariablen steht:

double myDouble;myDouble = 3.77;myDouble = 1.3 + 0.7 + 11.3;

Beide Zuweisungen sind in Ordnung. In der ersten steht rechts vom Zuwei-sungsoperator ein Literal vom Datentyp double. In der letzten Zuweisung be-findet sich als rechter Operand ein Ausdruck, welcher nach seiner Auswertungeinen Wert dieses Datentyps ergibt (13.3).

1 Legen Sie in Ihrer IDE ein neues Projekt an und ergänzen Sie die Main()-Methode wie folgt.

static void Main(string[] args){ double myDouble; myDouble = 99; Console.WriteLine(myDouble); Console.ReadLine();}

Sehen Sie sich das obige Listing genau an. Ist Ihnen aufgefallen, dass in derZuweisung myDouble = 99; auf der rechten Seite ein Literal vom Datentypint steht, wohingegen die Variable myDouble doch vom Typ double ist. Unddennoch erhalten Sie beim Kompilieren keine Fehlermeldung.

Auf der CD- ROM

Das entsprechende Projekt finden Sie unter Beispiele/Konsolenpro-gramme auf der Buch-CD (Projektname K08b).

Page 126: Visual C# 2005 easy

Implizite Typumwandlungen 125

2 Starten Sie mit (F5).

Sie erhalten die Ausgabe 99. Wie Sie sehen, arbeitet das Programm auch hin-sichtlich der Anzeige des Variablenwerts völlig korrekt.

Nun könnte jemand auf die Idee kommen, dass sich der Typ der Variablengeändert hat. Sie natürlich nicht, weil Sie ja wissen, dass eine Variable ihrenDatentyp nach der Definition nicht mehr ändern kann.

3 Weisen Sie nach, dass die Variable myDouble nach wie vor den Datentyp double besitzt. Verwenden Sie dazu die Methode GetType():

static void Main(string[] args){ double myDouble; myDouble = 99; Console.WriteLine(myDouble); Console.WriteLine(myDouble.GetType()); Console.ReadLine();}

Wie erwartet, zeigt die Bildschirmausgabe für die Variable den Datentypdouble (Klasse Double im Namensraum System).

Wenn sich nun der Variablentyp nicht geändert hat, dann muss sich logischer-weise der Datentyp des zugewiesenen Werts gewandelt haben, bevor dieser inder Variablen gespeichert wurde. Man spricht in solchen Fällen von einer im-pliziten Typumwandlung. Das heißt, ein Wert ändert seinen Datentyp, er wirdin einen anderen Datentyp konvertiert (umgewandelt). Eine Typkonvertierungwird »implizit« genannt, wenn sie automatisch erfolgt. Das Gegenstück dazuist die explizite Typumwandlung, die der Programmierer mit Ausdrucksmittelnder Programmiersprache forcieren muss.

Page 127: Visual C# 2005 easy

126 Kapitel 8

Hier einige Regeln zur impliziten Typkonvertierung in C#:

Nicht durchgeführt werden automatische Typumwandlungen von Strings, auchwenn diese als numerische Werte interpretiert werden könnten:

int myInteger = "399"; // FEHLER

Dies gilt ebenso kategorisch für die Gegenrichtung. Eine implizite Konvertie-rung nach string wird grundsätzlich nicht unterstützt:

string myString = 399; // FEHLER

Insbesondere verweigert C# die implizite Konvertierung von numerischen Wer-ten nach bool und umgekehrt.

bool myBoolean = 1; // FEHLERint myInteger = true; // FEHLER

Die implizite Typkonvertierung funktioniert grundsätzlich nicht, wenn der Wer-tebereich des Quelldatentyps größer ist als der des Zieldatentyps. Dies trifftauch dann zu, wenn der Wert von der Größe her in den Zieldatentyp passt:

Hinweis

C# gilt als typsichere Programmiersprache. Das bedeutet, C# ist in derDurchführung automatischer Typumwandlungen sehr restriktiv. Der Vor-teil typsicherer Sprachen liegt darin, dass man sich genau Gedanken hin-sichtlich der Typen machen und in dieser Hinsicht sehr gewissenhaftarbeiten muss, wodurch Fehler häufig bereits im Vorfeld vermieden wer-den können. Allerdings kann der Programmieraufwand steigen, da dieSprache weniger Konvertierungen selbsttätig durchführt. Im Zuge einesgut durchdachten Programmcodes spricht aber nichts gegen typsichereSprachen.

Hinweis

In der Programmiersprache C++ wären beide Initialisierungen in Ord-nung. Die implizite Konvertierung erfolgt dort nach folgendem Muster: • jeder numerische Wert ungleich 0 in den booleschen Wert true, 0 in

den Wert false;• die boolesche Konstante true in den numerischen Wert 1, false in

den Wert 0.

Page 128: Visual C# 2005 easy

Implizite Typumwandlungen 127

int myInt;myInt = 5.0; // FEHLERmyInt = 99L; // FEHLER

Sowohl der Datentyp long als auch der Datentyp double haben einen größe-ren Wertebereich als int. Deshalb verweigert C# die automatische Umwand-lung, obwohl beide Werte (5 und 99) problemlos in der Zielvariablen Platzfänden.

Umgekehrt dagegen – falls der Wertebereich des Zieldatentyps größer ist – fin-det die Konvertierung statt:

long myLong = 19;double myDouble = 599;

Unter der genannten Voraussetzung steht a priori fest, dass der zugewieseneWert immer in die Zielvariable passt. Die Typsicherheit von C# bleibt somit ge-währleistet, sodass hier keine Veranlassung besteht, die Kompilierung zu ver-weigern und den Programmierer auf diese Weise auf etwaige Fehlerhinzuweisen.

Beachten Sie, dass die Literale 19 und 599 den Datentyp int besitzen (sieheAbschnitt »Literale zur Darstellung von ganzen Zahlen«). Diese müssen alsovor der eigentlichen Zuweisung erst nach int bzw. double konvertiert wer-den. Natürlich handelt es sich dabei um einen nicht wahrnehmbaren, internenZwischenschritt.

In numerischen Ausdrücken konvertiert C# nach double, sobald nur ein Ope-rand von diesem Datentyp ist:

12 + 8 + 7.0 + 3

Obiger Ausdruck ist daher wegen des Literals 7.0 vom Typ double. Sie könnendies mit der folgenden Anweisung leicht nachprüfen:

Console.WriteLine((12 + 8 + 7.0 + 3).GetType());

Der impliziten Umwandlung von char nach int liegt der Unicode zu Grunde.Das Zeichen wird in seine entsprechende Ordnungsnummer konvertiert. Fol-gendes Codefragment bewirkt daher die Ausgabe 65, da dem Zeichen 'A' imUnicode-Zeichensatz die Ordnungsnummer 65 zugeordnet ist:

int myInt = 'A'; // OKConsole.Write(myInt); // Ausgabe: 65

Allerdings funktioniert die Konvertierung nur in eine Richtung. Von int nachchar dagegen schlägt sie fehl:

char myChar = 65; // FEHLER

Page 129: Visual C# 2005 easy

128 Kapitel 8

Implizite Konvertierung im Zusammenhang mit String-VerknüpfungenWenn in einem Ausdruck X + Y allein ein Operand (X oder Y) vom Datentypstring ist, wird der andere automatisch nach string konvertiert. Dies ist in-sofern eine Besonderheit, da C# sonst keine impliziten Typumwandlungennach string unterstützt (siehe oben).

int zahl = 555;string myString = zahl; // FEHLER

aber

string myString = zahl + " ist eine Zahl"; // OK

Bei Ausführung der letzten Anweisung wird zunächst der Wert 555 (Kopie desin der Variablen zahl enthaltenen Wertes) in den String "555" konvertiert. Da-nach erfolgt die Verknüpfung, bevor der aus dieser Operation resultierendeString der Variablen myString zugewiesen wird.

Bezüglich des Plus-Zeichens (+) bedeutet dies:

• Sind beide Operanden numerischen Datentyps, wird eine arithmetischeAddition durchgeführt.

• Handelt es sich bei einem oder bei beiden Operanden um Strings, erfolgteine String-Verknüpfung.

Beachten Sie, dass sich diese Regel jeweils auf zwei benachbarte Operandenbezieht:

string myString = "012" + 3 + 4;Console.Write(myString); // Ausgabe 01234

Der Ausdruck auf der rechten Seite des Zuweisungsoperators ("012" + 3 + 4)bringt zwei Verknüpfungsoperationen mit sich. Bei Ausführung erfolgt zuerstdie Verknüpfung "012" + 3 (nach Umwandlung von 3 in "3") und im An-schluss daran die Verknüpfung "0123" + 4 (ebenfalls nach entsprechenderKonvertierung). Daher erzeugt die letzte Anweisung die Bildschirmausgabe01234, wie Sie das vielleicht erwartet haben.

Hinweis

Grundsätzlich sollten Sie sich nicht auf implizite Typumwandlungen ver-lassen, sondern möglichst versuchen, diese zu vermeiden.

Page 130: Visual C# 2005 easy

Explizite Typumwandlungen 129

Ändern wir die erste Anweisung etwas ab:

string myString = 3 + 4 + "012";Console.Write(myString); // Ausgabe 7012

Damit ergibt sich nicht etwa die Ausgabe 34012, sondern 7012. Der Grundhierfür ist, dass nach dem genannten Muster zunächst die Operation 3 + 4 zurAusführung gelangt und hier handelt es sich um eine arithmetische Addition.Beide Operanden sind schließlich vom Datentyp int. Das Resultat dieser Ope-ration ist der Wert 7. Dieser bildet nun den linken Teil der folgenden Operation(7 + "012"). Alles Weitere ist Ihnen bekannt.

Explizite TypumwandlungenIn den meisten Fällen, in denen eine implizite Typumwandlung nicht möglichist, lässt sich die gewünschte Änderung des Datentyps erzwingen. Dazu ste-hen dem Programmierer folgende Werkzeuge zur Verfügung:

• verschiedene Methoden zur Typumwandlung,

• die Cast-Operation.

UmwandlungsmethodenZunächst wollen wir Ihnen eine typische Situation zeigen, in der eine Typ-umwandlung unumgänglich ist.

1 Legen Sie ein neues Projekt an, definieren Sie in der Main()-Methode eine double-Variable und weisen Sie dieser per Benutzereingabe einen Wert zu:

static void Main(string[] args){ double ein;

Hinweis

Bei einem Ausdruck der Art A + B + C + D erfolgt die Abarbeitung von»links nach rechts« (A, B, C und D sind Platzhalter für einfache oder auchkomplexe Ausdrücke).

Durch Setzen von Klammern können Sie jedoch in diese Prioritätsreihen-folge eingreifen:

string myString = 3 + (4 + "012");Console.Write(myString); // Ausgabe 34012

Page 131: Visual C# 2005 easy

130 Kapitel 8

ein = Console.ReadLine();}

ReadLine() sorgt für die Entgegennahme einer Benutzereingabe. Der Rück-gabewert entspricht der Eingabe des Benutzers (siehe Kapitel 7, Abschnitt»Die Methode ReadLine()«).

2 Starten Sie mit (F5).

Sie erhalten die Fehlermeldung »eine implizite Konvertierung vom Typ stringin double ist nicht möglich«.

Abbildung 8.3: Der Visual C#-Compiler verweigert die Konvertierung von string nach double

Das Problem liegt darin, dass ReadLine() jede Eingabe als string-Wert zu-rückliefert, die Variable ein aber vom Typ double ist.

Hinweis

Wie alle Werte in C# besitzen natürlich auch Rückgabewerte von Metho-den einen bestimmten Datentyp.

Page 132: Visual C# 2005 easy

Explizite Typumwandlungen 131

Und da eine implizite Konvertierung von string nach double nicht möglichist, bleibt als einziger Ausweg die explizite Typumwandlung. Hierfür stellt dieKlasse Convert eine Reihe von Methoden zur Verfügung. Die wichtigsten da-von sind in der folgenden Tabelle wiedergegeben:

Tabelle 8.1: Umwandlungsmethoden der Klasse Convert

Der Aufruf der Methoden erfolgt unter Angabe des Klassenbezeichners(Convert), gefolgt von einem Punkt. Als Argument übergeben Sie den zu kon-vertierenden Wert.

Der Rückgabewert der genannten Umwandlungsmethoden entspricht danndem konvertierten Wert des Arguments.

Da Sie den Rückgabewert der Methode ReadLine() in den Typ double kon-vertieren müssen, kommt für Sie allein die Methode ToDouble() infrage. Wieformulieren Sie nun den korrekten Methodenaufruf?

Zunächst erfolgt der Zugriff auf die Methode unter Angabe des Klassen-namens:

Convert.ToDouble()

Nun müssen Sie noch das Argument zwischen die runden Klammern schrei-ben. Dabei handelt es sich natürlich um den Rückgabewert der MethodeReadLine().

Methode konvertiert Übergabewert in den Datentyp …

ToString() string

ToChar() char

ToInt32() int

ToInt64() long

ToDouble() double

ToBoolean() bool

Was ist das?

Argumente nennt man die Werte, welche einer Methode beim Aufrufübergeben werden. Bis jetzt hatten wir ausschließlich die BezeichnungParameter verwendet.

Page 133: Visual C# 2005 easy

132 Kapitel 8

Denken Sie daran, dass ein Methodenaufruf im Programmcode den Rückgabe-wert der aufgerufenen Methode repräsentiert. Was die Methode ReadLine()angeht, steht demnach der Ausdruck Console.ReadLine() für ihren Rück-gabewert und um diesen geht es schließlich. Also müssen Sie diesen Metho-denaufruf als Argument für die Methode ToDouble() verwenden.

3 Setzen Sie die Konvertierungsmethode ToDouble() wie beschrieben ein:

static void Main(string[] args){ double ein; ein = Convert.ToDouble(Console.ReadLine());}

Wie Sie sehen, haben Sie es wieder mit einem verschachtelten Methodenauf-ruf zu tun. Halten Sie sich die Einzelschritte bei Ausführung der Anweisung

ein = Convert.ToDouble(Console.ReadLine());

vor Augen:

• Zunächst kommt die innere Methode ReadLine() zum Zug. Diese bewirktdie Annahme einer Benutzereingabe.

• Danach wird der Ausdruck Console.ReadLine() durch den Rückgabe-wert der Methode (Benutzereingabe als String) ersetzt und als Argumentan die Methode ToDouble() weitergereicht.

• Diese sorgt nun für die Typumwandlung; ihr Rückgabewert ist das nachdouble konvertierte Argument (wobei es sich nach wie vor um die Benut-zereingabe handelt).

• Im letzten Schritt wird die – konvertierte – Benutzereingabe der Variablenein zugewiesen. Da nunmehr beide Datentypen übereinstimmen, hatdiese Zuweisung Erfolg.

Sie setzen dabei allerdings voraus, dass ein Benutzer beim Programmlauf auchtatsächlich einen Zahlenwert in einem zulässigen Format eingibt. Andernfallsstellt sich ein Laufzeitfehler ein, da die Konvertierung logischerweise nur dannfunktioniert, wenn sich die umzuwandelnde Zeichenkette überhaupt als Zahlinterpretieren lässt.

Hinweis

Von Programmabstürzen bleiben Sie innerhalb Ihrer IDE jedoch ver-schont, da die Visual C# 2005 Express Edition Laufzeitfehler abfängt.

Page 134: Visual C# 2005 easy

Explizite Typumwandlungen 133

Nun sollte sich Ihr Code ohne Fehlermeldung übersetzen lassen.

4 Fügen Sie zu guter Letzt eine passende Ausgabe wie folgt hinzu:

static void Main(string[] args){ double ein; ein = Convert.ToDouble(Console.ReadLine()); Console.WriteLine("Sie haben die Zahl " + ein + " eingegeben."); Console.ReadLine();}

5 Testen Sie Ihr Programm.

Nach Programmende sollte in Abhängigkeit Ihrer Eingabe etwa die in der Ab-bildung dargestellte Ausgabe zu sehen sein.

Abbildung 8.4: Der Zahlenwert der Benutzereingabe wurde in den Datentyp »double« umgewandelt

Des Weiteren besitzt in C# jeder Datentyp eine eigene Methode ToString().Diese funktioniert ähnlich wie die Umwandlungsmethoden der KlasseConvert, wird allerdings ohne Argumente und objektbezogen aufgerufen (sieheoben, Abschnitt »Literale zur Darstellung von ganzen Zahlen«). Um etwa denWert Ihrer double-Variablen ein in einen String zu konvertieren, schreiben Sie

Auf der CD-ROM

Das Beispiel finden Sie unter Beispiele/Konsolenprogramme auf derBuch-CD (Projektname K08c).

Achtung

Denken Sie bei der Eingabe daran, die Nachkommastellen mit demKomma zu trennen. (Nur im Quellcode muss der Punkt verwendet wer-den.)

Page 135: Visual C# 2005 easy

134 Kapitel 8

ein.ToString();

Alternativ dazu können Sie natürlich nach wie vor zur Konvertierung dieMethode ToString() der Klasse Convert verwenden. Dann müssen Sie denVariablenbezeichner als Argument zwischen die runden Klammern schreiben:

Convert.ToString(ein);

Es sei nochmals darauf hingewiesen, dass in beiden Fällen nicht die Variableselbst, sondern eine Kopie des in ihr enthaltenen Wertes umgewandelt wird.An welcher Stelle im Quellcode Sie diese Methoden einsetzen, ist immer vomjeweiligen Kontext abhängig.

Analog schreiben Sie z.B. (34.88).ToString() oder Convert.ToString(34.88), wenn Sie ein Literal umwandeln müssen.

Das CastingAls Alternative zu den besprochenen Umwandlungsmethoden stellt C# die sogenannte Cast-Operation zur Verfügung. Dabei schreiben Sie das Schlüssel-wort für den gewünschten Zieldatentyp in Klammern vor den zu konvertieren-den Wert:

(char) 48

Es lassen sich alle numerischen Datentypen casten – einschließlich des Daten-typs char.

Hierzu einige Beispiele:

char myChar = (char) 66;Console.Write(myChar); // Ausgabe: B

oder

Hinweis

In dem Ausdruck (34.88).ToString() ist das Setzen von Klammernin (34.88) zwar nicht zwingend notwendig. Es erhöht jedoch die Les-barkeit, da der erste Punkt als Trennzeichen eine völlig andere Bedeu-tung hat als der zweite, welcher zum Zugriff auf die MethodeToString() dient.

In ähnlichen Fällen sind Klammern jedoch mitunter erforderlich, daandernfalls ein Ausdruck vom Compiler nicht wie gewünscht interpretiertwerden kann. Es ist deshalb ratsam, sich im Zweifel für das Setzen vonKlammern zu entscheiden.

Page 136: Visual C# 2005 easy

Explizite Typumwandlungen 135

int myInt = (int) 5.0; // OK

Wie Sie sehen, funktioniert das Casting auch in Fällen, in denen keine impliziteKonvertierung möglich ist. Sie dürfen es aber auch dort anwenden, wo die Typ-umwandlung ohnehin automatisch stattfinden würde:

int myInt = (int) 'A';

Ausschlaggebendes Kriterium hierfür kann die bessere Nachvollziehbarkeitdes Quellcodes sein. Wenn der Programmierer die Konvertierung explizit fest-legt, kann man beim Lesen des Quelltextes sofort erkennen, dass diese beab-sichtigt ist. Andererseits kann man nie so ganz sicher sein, ob eine impliziteKonvertierung vom Programmautor tatsächlich so gewollt war oder auf einemVersehen beruht. Dies ist auch der Grund für die Tendenz von C#, implizite Kon-vertierungen zu verweigern.

Nicht durchführbar ist das Casting mit den Datentypen bool und string. Da-bei spielt es keine Rolle, ob diese als Quell- oder als Zieldatentypen auftreten:

int myInteger = (int) "399"; // FEHLERstring myString = (string) 2003; // FEHLERbool myBoolean = (bool) 99; // FEHLERint myInt = (int) true; // FEHLER

Hier bleibt Ihnen immer noch die Möglichkeit, sich der oben gezeigten Um-wandlungsmethoden zu bedienen, z.B.

int myInt = Convert.ToInt32(true); // OK Console.Write(myInt); // Ausgabe: 1

oder

bool myBoolean = Convert.ToBoolean(99); // OKConsole.Write(myBoolean); // Ausgabe: True

Im Einzelfall haben Sie bei verschiedenen Typumwandlungen jedoch zu berück-sichtigen, dass diese nicht immer ohne Informationsverlust vonstatten gehen.

So gehen bei der Konvertierung von double nach Integer mit Methoden derKlasse Convert etwaige Nachkommastellen verloren. Der Wert wird nach dem

Hinweis

In der Bildschirmausgabe erscheint der erste Buchstabe der booleschenKonstanten in Großbuchstaben (True bzw. False). Das ändert nichts ander Tatsache, dass Sie true und false im Quellcode stets kleinschrei-ben müssen.

Page 137: Visual C# 2005 easy

136 Kapitel 8

kaufmännischen Prinzip auf die nächstgrößere bzw. -kleinere Ganzzahl gerun-det:

int myInt = Convert.ToInt32(3.8799);Console.Write(myInt); // Ausgabe: 4

Beim Casting dagegen wird der Nachkommateil – ohne Rundung – einfach ab-geschnitten:

int myInt = (int) 3.8799;Console.Write(myInt); // Ausgabe: 3

Beachten Sie auch, dass eine Konvertierung in keinem Fall durchgeführt wer-den kann, wenn der zu konvertierende Wert in seiner Größe außerhalb desWertebereichs des Zieldatentyps liegt:

int myInt = (int) 3147483647; // FEHLER

bzw.

int myInt = Convert.ToInt32(3147483647); // FEHLER

Es macht jedoch insofern einen Unterschied, mit welchen Mitteln Sie dieseUmwandlung versuchen, als sich bei Anwendung der Methode ToInt32() derFehler erst zur Laufzeit einstellt. Beim Casting scheitert bereits der Kompilier-versuch (was einen gewissen Vorteil mit sich bringt, da ein fehlerhaftes End-produkt so gar nicht erst entstehen kann).

Umwandlungen, welche von »Write()« bzw. »WriteLine()« veranlasst werdenDie Methoden Write() bzw. WriteLine() sind so eingerichtet, dass sie ge-gebenenfalls selbstständig Konvertierungen nach string durchführen, näm-lich immer dann, wenn Sie ihnen Werte eines anderen Datentyps übergeben:

double zahl = 0.99;Console.Write(zahl);

In der letzten Anweisung wird der aus der double-Variablen zahl kopierteWert vor der Ausgabe zunächst in die Zeichenkette "0,99" konvertiert.

Diese Umwandlung ist notwendig, da Ausgaben sowie Benutzereingaben aufder Befehlszeile stets als Zeichenketten behandelt werden. Ein Datenaus-tausch mit Werten eines anderen Datentyps ist über die Konsole a priori nichtmöglich.

Beachten Sie, dass es sich hierbei nicht um eine implizite Konvertierung han-delt. Wie Sie wissen, wird eine solche (double nach string) von C# prinzipiellnicht durchgeführt. Tatsächlich handelt es sich hier um eine explizite Konver-

Page 138: Visual C# 2005 easy

Eine kleine Erfolgskontrolle 137

tierung, mit dem Unterschied, dass diese nicht vom Programmierer, sondernvon der Methode selbst angestoßen wird. (Genaueres zur Implementation vonMethoden erfahren Sie in Kapitel 13.)

Eine kleine Erfolgskontrolle• Welchen Datentyp besitzt das Literal 3?

• Nennen Sie den Datentyp des Literals 3.0.

• Der Datentyp des Literals "3" ist?

• Der Datentyp des Literals '3' ist?

• Warum verursacht folgendes Codestück beim Kompilieren eine Fehlermel-dung?

const string name = "Mustermann";Console.Write("Wie heißen Sie? ");name = Console.ReadLine();

• zahl sei eine Variable vom Typ double. Das bedeutet, sie kann aus-schließlich Werte von diesem Datentyp aufnehmen. Warum erzeugt fol-gende Zuweisung dennoch keine Fehlermeldung?

zahl = 100;

• Korrigieren Sie die/den Fehler in folgendem Codestück:

int z;Console.Write ("Geben Sie eine Zahl ein: ");z = Console.ReadLine();

• Ist folgende Variableninitialisierung korrekt?

int wert = 25.99;

Hinweis

Natürlich ist es kein Fehler, wenn Sie der Methode den Wert bereits kon-vertiert übergeben:

double zahl = 0.99;Console.Write(Convert.ToString(zahl));

bzw.

Console.Write(zahl.ToString());

Page 139: Visual C# 2005 easy

Das können Sie schon:

Entwicklungsschritte zum lauffähigen C#-Programm 11

Umgang mit der Visual C# Express-IDE 36

Aufbau und grundlegende Syntax von C#-Programmen 48

Kommentare 67

Arbeiten mit Strings 75

Steuerzeichen 81

Variablen und Datentypen 87

Verarbeiten von Benutzereingaben 103

Konstanten 109

Typkonvertierung 124

Das lernen Sie neu:

Komplexe Ausdrücke formulieren 139

Mathematische Operationen durchführen 140

Formatieren von Bildschirmausgaben 147

Page 140: Visual C# 2005 easy

Kapitel 9

RechenoperationenBisher sind wir mit der Weiterverarbeitung von Benutzereingaben sehr zurückhaltend umgegangen. Wir haben diese zwar schon in Variablen festgehalten, um sie anschließend für Bildschirmausga-ben zu verwenden, ansonsten haben wir mit diesen Daten aber kaum etwas gemacht. Das lag daran, dass uns hierzu bis jetzt nur wenig Mittel zur Verfügung standen. In diesem Kapitel lernen Sie nun das Formulieren von komplexen Ausdrücken. Sie werden so in die Lage versetzt, mit den Eingabedaten sinnvolle Operationen durchzuführen.

Page 141: Visual C# 2005 easy

140 Kapitel 9

Ausdrücke und arithmetische OperatorenJeder Teil einer Anweisung, der einen Wert repräsentiert, wird im programmier-technischen Sinn als »Ausdruck« bezeichnet. So gesehen fallen hierunter aucheinzelne Literale und Variablenbezeichner.

Komplexe Ausdrücke müssen während der Programmausführung zunächstausgewertet werden, bevor mit dem Ergebniswert weitergearbeitet werdenkann.

Wie bei Methoden spricht man auch bei Ausdrücken von Rückgabewerten.Analog die Ausdrucksweise: Ein Ausdruck gibt einen Wert zurück bzw. lieferteinen Wert.

int x;x = 17 + 3;

So ist es korrekt, wenn Sie bezüglich der letzten Anweisung sagen: »Der Aus-druck rechts des Zuweisungsoperators gibt den Wert 20 zurück«. Ein Nicht-Programmierer würde das natürlich ganz anders ausdrücken (»Der Ausdruckergibt den Wert 20«, »Das Ergebnis …«).

Hinweis

Für die Bezeichner von Variablen gilt das allerdings nur, wenn diese imLesekontext auftreten. Auf der linken Seite einer Zuweisung oder in einerDefinitionsanweisung repräsentieren sie keinen Wert, sondern den Spei-cherort selbst (siehe Kapitel 7, Abschnitt »Unterschiedliche Bedeutungvon Variablenbezeichnern im Quellcode«).

Hinweis

Diese Aussage gilt im übertragenen Sinne auch für einfache Werte (dar-gestellt durch Literale oder Variablenbezeichner), da diese zumindesteinmal »angefasst« – gelesen – werden müssen.

Page 142: Visual C# 2005 easy

Ausdrücke und arithmetische Operatoren 141

Komplexe Ausdrücke werden von Operatoren und ihren Operanden gebildet.Eine beträchtliche Bedeutung kommt dabei den arithmetischen Operatorenzu.

Den Operator zur Darstellung der mathematischen Addition kennen Sie be-reits: das Plus-Zeichen (+).

Beachten Sie, dass das Plus-Zeichen zur Darstellung zweier unterschiedlicherOperationen herangezogen wird – der mathematischen Addition sowie derStringverknüpfung. Seine Bedeutung ist also von vornherein nicht eindeutigund muss bei der Übersetzung des Quellcodes vom Compiler aus dem Kontextermittelt werden. Entscheidend hierbei ist der Datentyp der Operanden. Han-delt es sich um numerische Datentypen, repräsentiert das Plus-Zeichen diemathematische Addition. Ist nur ein Operand vom Datentyp string, wird dieStringverknüpfung durchgeführt (siehe Kapitel 8, Abschnitt »Implizite Konver-tierung im Zusammenhang mit String-Verknüpfungen«).

Der Operator für die Subtraktion (-) ist Ihnen ebenfalls aus der Mathematik ge-läufig.

Die beiden verbleibenden Symbole zur Darstellung der Grundrechenarten sindfolgende:

• für die Multiplikation der Stern: *

• für die Division der Schrägstrich (Slash): /

Hinweis

Auch ein Methodenaufruf ist nach den oben dargelegten Gesichtspunk-ten ein Ausdruck – insofern es sich um eine Methode mit Rückgabewerthandelt.

Hinweis

Das Verketten von Strings wird neben »Stringverknüpfung« auch »Kon-katenation« genannt. Analog spricht man vom »Konkatenationsopera-tor«.

Page 143: Visual C# 2005 easy

142 Kapitel 9

Der Modulo-OperatorDie Modulo-Operation gibt den Rest einer Ganzzahldivision als Wert zurück.Das bedeutet nicht, dass bei dieser Operation tatsächlich eine Division durch-geführt wird. Es wird lediglich ermittelt, wie oft der rechte Operand in dem lin-ken vollständig enthalten ist, und der verbleibende Restwert zurückgegeben.

Der Modulo-Operator wird mit dem Prozentzeichen dargestellt (%). Wie dieOperatoren für die Grundrechenarten besitzt auch der Modulo-Operator zweiOperanden.

Beispielsweise liefert der Ausdruck

8 % 5

den Rückgabewert 3, da eine Division beider Zahlen (8 geteilt durch 5) denWert 1 mit dem Rest 3 ergibt. Anders ausgedrückt: 5 ist in 8 exakt 1-mal voll-ständig enthalten, wobei ein Rest von 3 verbleibt.

Weitere Beispiele:

Console.Write(6 % 2); // Ausgabe: 0Console.Write(11 % 5); // Ausgabe: 1Console.Write(3 % 7); // Ausgabe: 3

Die letzte Anweisung erzeugt die Bildschirmausgabe 3, da 7 in 3 nullmal ent-halten ist, wobei nach wie vor ein Rest von 3 übrig bleibt.

Die Modulo-Operation wird oft angewandt, um festzustellen, ob eine Zahldurch eine andere ohne Rest teilbar ist. Mit ihrer Hilfe lässt sich auch ermitteln,ob eine – möglicherweise vom Anwender eingegebene – Zahl gerade oder un-gerade ist (eine Zahl ist dann gerade, wenn sie durch 2 ohne Rest teilbar ist).Für solche Prüfungen benötigen Sie allerdings zusätzlich die Kenntnis von Kon-trollstrukturen. Mit diesen werden Sie sich in den beiden folgenden Kapitelnbeschäftigen. Sie werden dort sowie im weiteren Verlauf noch Gelegenheithaben, die Modulo-Operation sinnvoll einzusetzen.

Hinweis

Operatoren, welche sowohl auf der linken als auch auf der rechten Seitedes Symbols Operanden erfordern, werden als »binär« bezeichnet. Zuden binären Operatoren gehört somit auch der Zuweisungsoperator. ImGegensatz dazu ist ein Operator »unär«, wenn er sich nur auf einen Ope-randen bezieht. Beispiele für unäre Operatoren werden Sie noch kennenlernen.

Page 144: Visual C# 2005 easy

Erstellen Sie ein Euro-DM-Umrechnungsprogramm 143

Nachfolgend sehen Sie eine Übersicht der arithmetischen Operatoren:

Tabelle 9.1: Arithmetische Operatoren in C#

Erstellen Sie ein Euro-DM-UmrechnungsprogrammMöglicherweise denken Sie ab und zu an die alte Währung zurück und begin-nen in Gedanken zu rechnen, welchem DM-Betrag wohl ein bestimmter Euro-Betrag entsprochen hätte. Sei es nur, um sich vor Augen zu halten, wie teuerdas Produkt, das Sie gerade im Begriff sind zu kaufen, geworden ist.

Im Folgenden erstellen Sie ein Programm, welches einen einzugebenden Euro-Betrag in DM umrechnet.

1 Legen Sie in Ihrer IDE ein neues Projekt an.

2 Definieren Sie eine double-Variable euro.

static void Main(string[] args){ double euro;}

In dieser Variablen werden Sie die Benutzereingabe speichern. Um dem Benut-zer die Möglichkeit zu geben, den Euro-Betrag mit Nachkommastellen einzu-geben, benötigen Sie eine Variable des Datentyps double.

3 Fordern Sie den Benutzer zur Eingabe eines Euro-Betrags auf:

static void Main(string[] args){ double euro; Console.Write("Umzurechnender Euro-Betrag: ");}

Operator steht für ...

+ Addition

- Subtraktion

* Multiplikation

/ Division

% Modulo (Rest einer Division)

Page 145: Visual C# 2005 easy

144 Kapitel 9

Verwenden Sie die Methode Console.Write() – anstelle vonConsole.WriteLine() –, um die Benutzereingabe in derselben Zeile folgenzu lassen.

4 Implementieren Sie eine Benutzereingabe.

Dazu rufen Sie die Methode Console.ReadLine() auf:

static void Main(string[] args){ double euro; Console.Write("Umzurechnender Euro-Betrag: "); Console.ReadLine();}

Der Rückgabewert der Methode ReadLine() soll schließlich in der Variableneuro gespeichert werden, um im Weiteren damit rechnen zu können. Da dieseraber vom Typ string ist, müssen Sie ihn zunächst in den Datentyp der Variab-len umwandeln.

5 Konvertieren Sie den Rückgabewert der Methode ReadLine() in einen double-Wert. Verwenden Sie dazu die Methode ToDouble() der Klasse Convert.

Übergeben Sie dazu den Rückgabewert – für den der Ausdruck Console.ReadLine() steht – einfach der Methode ToDouble() als Argument:

static void Main(string[] args){ double euro; Console.Write("Umzurechnender Euro-Betrag: "); Convert.ToDouble(Console.ReadLine());}

6 Weisen Sie den so konvertierten Wert der Variablen euro zu:

static void Main(string[] args){ double euro; Console.Write("Umzurechnender Euro-Betrag: "); euro = Convert.ToDouble(Console.ReadLine());}

7 Fügen Sie am Ende der Main()-Methode einen Haltebefehl hinzu.

Dies empfiehlt sich schon jetzt, damit Sie Ihr Programm auch zwischenzeitlichin Ihrer Visual C# Express-IDE testen können.

Page 146: Visual C# 2005 easy

Erstellen Sie ein Euro-DM-Umrechnungsprogramm 145

static void Main(string[] args){ double euro; Console.Write("Umzurechnender Euro-Betrag: "); euro = Convert.ToDouble(Console.ReadLine()); Console.ReadLine();}

Die Ausgabe Ihres Programms soll am Ende wie folgt aussehen:

X Euro entsprechen Y DM

Wobei X und Y natürlich als Platzhalter zu verstehen sind.

8 Setzen Sie den bekannten Teil der Ausgabe schon mal um:

static void Main(string[] args){ double euro; Console.Write("Umzurechnender Euro-Betrag: "); euro = Convert.ToDouble(Console.ReadLine()); Console.Write(euro + " Euro entsprechen "); Console.ReadLine();}

Nun müssen Sie sich um die Ausgabe des korrespondierenden DM-Betragskümmern. Der Umrechnungsfaktor beträgt 1,95583 (1 Euro entsprechen1,95583 DM). Der DM-Betrag ergibt sich folglich aus dem Ausdruck euro *1.95583.

Sie könnten nun das Ergebnis dieses Ausdrucks in einer Variablen speichernund anschließend diese Variable zur Ausgabe heranziehen:

…double dm = euro * 1.95583;…Console.Write (euro + " Euro entsprechen ");Console.WriteLine (dm + " DM.");…

Ebenso gut können Sie auf die Definition einer zusätzlichen Variablen verzich-ten und den Ausdruck, so wie er ist, für die Ausgabe verwenden.

Hinweis

In den weiteren Beispielen werden wir den obligatorischen Haltebefehlals selbstverständlich voraussetzen.

Page 147: Visual C# 2005 easy

146 Kapitel 9

9 Vervollständigen Sie die Ausgabe:

static void Main(string[] args){ double euro; Console.Write("Umzurechnender Euro-Betrag: "); euro = Convert.ToDouble(Console.ReadLine()); Console.Write(euro + " Euro entsprechen "); Console.WriteLine(euro * 1.95583 + " DM."); Console.ReadLine();}

Damit ist Ihr Umrechnungsprogramm fertig.

10 Testen Sie Ihr Programm.

Bei einer Eingabe von 27,99 erhalten Sie die in der Abbildung dargestellte Aus-gabe (wie Sie die Anzeige des Umrechnungswerts auf zwei Nachkommastellenbegrenzen können, erfahren Sie im nächsten Abschnitt).

Abbildung 9.1: Das Umrechnungsprogramm in Aktion

Eine Eingabe von 1 bewirkt die Ausgabe

1 Euro entsprechen 1,95583 DM.

Dies ist offensichtlich richtig. Insoweit arbeitet das Programm korrekt.

Bevor wir uns dem nächsten Thema zuwenden, möchten wir Sie auf eine alter-native Implementation des Umrechnungsprogramms aufmerksam machen:

• Sie weisen die Benutzereingabe ohne Konvertierung einer Variablen vomDatentyp string zu.

• Sie konvertieren den in der string-Variablen gespeicherten Wert, bevorSie ihn für die Ergebnisberechnung verwenden.

Hier das entsprechende Listing:

Auf der CD-ROM

Das Beispiel finden Sie unter Beispiele/Konsolenprogramme auf derBuch-CD (Projektname K09a).

Page 148: Visual C# 2005 easy

Formatieren von Ausgaben 147

static void Main(string[] args){ string euro; Console.Write("Umzurechnender Euro-Betrag: "); euro = Console.ReadLine(); Console.Write(euro + " Euro entsprechen "); Console.WriteLine(Convert.ToDouble(euro) * 1.95583 + " DM."); Console.ReadLine();}

Formatieren von AusgabenIm letzten Beispiel haben Sie bei der Implementation der Bildschirmausgabevon der Möglichkeit Gebrauch gemacht, Strings zusammenzusetzen. Dasheißt, Sie haben den Methoden Write() bzw. WriteLine() jeweils einen zu-sammengesetzten Ausgabe-String übergeben (wobei Sie sich zu Recht auf dieimplizite Konvertierung nach string verlassen haben, siehe Kapitel 8, Ab-schnitt »Implizite Konvertierung im Zusammenhang mit String-Verknüpfun-gen«).

Console.Write(euro + " Euro entsprechen ");Console.WriteLine(euro * 1.95583 + " DM.");

Dieses Verfahren stellt eine bequeme Möglichkeit dar, Variablenwerte und/oder Berechnungsergebnisse zusammen mit Text in einem Durchgang auszu-geben.

Alternativ gestatten es die Methoden Write() und WriteLine() innerhalbvon Ausgabe-Strings, für Werte Platzhalter zu verwenden. Die eigentlichenWerte werden durch Kommata getrennt nach dem Ausgabe-String angegeben.

Auf der CD-ROM

Das Beispiel finden Sie unter Beispiele/Konsolenprogramme auf derBuch-CD (Projektname K09b).

Hinweis

In der Programmierung gibt es in den seltensten Fällen nur eine einzigeLösung für ein Problem. In der Regel sind für die Umsetzung einer Aufga-benstellung eine Vielzahl von möglichen Implementationen denkbar.

Page 149: Visual C# 2005 easy

148 Kapitel 9

Ein Wert wird dabei wie üblich durch einen beliebigen Ausdruck repräsentiert– worunter natürlich auch reine Variablenbezeichner fallen (siehe Abschnitt»Ausdrücke und arithmetische Operatoren«).

Als Platzhalter fungieren Zahlen, welche von zwei geschweiften Klammern um-schlossen werden, z.B. {0}. Die Zahlen dienen dabei zur Indizierung der hinterdem Ausgabe-String angegebenen Werte, wobei dem ersten Wert der Index 0,dem zweiten Wert der Index 1 usw. zugeordnet ist. Wenn nur ein Wert in denAusgabe-String eingebaut werden soll, müssen Sie für diesen also den Platz-halter {0} verwenden:

double preis = 399.99;Console.Write("Die Digitalkamera kostet {0} Euro", preis);

Den Platzhalter für einen Wert setzen Sie genau an diejenige Stelle in denString, an welcher der Wert in der Ausgabe erscheinen soll. Obige Write()-Anweisung erzeugt demnach die Bildschirmausgabe

Die Digitalkamera kostet 399,99 Euro

Hier ein Beispiel für die Verwendung mehrerer Platzhalter innerhalb eines Aus-gabe-Strings:

int l = 7, b = 10, h = 9;Console.Write("Länge: {0} m, Breite: {1} m, Höhe: {2} m" , l, b, h);

Bildschirmausgabe:

Länge: 7 m, Breite: 10 m, Höhe: 9 m

Zurück zum Euro-DM-Umrechnungsprogramm des letzten Abschnitts.

Hinweis

Es ist möglich, mehrere Variablen gleichen Datentyps in einer einzigenAnweisung zu definieren. Die Variablen werden dabei durch Kommatavoneinander getrennt. Demnach werden mit der Anweisung int l =7, b = 10, h = 9; drei int-Variablen mit den Bezeichnern l, b undh sowie den Initialisierungswerten 7, 10 und 9 vereinbart.

Page 150: Visual C# 2005 easy

Formatieren von Ausgaben 149

11 Ersetzen Sie in den Ausgabestrings die Werte für Euro- und DM-Betrag mit Platzhaltern:

static void Main(string[] args){ double euro; Console.Write("Umzurechnender Euro-Betrag: "); euro = Convert.ToDouble(Console.ReadLine()); Console.Write("{0} Euro entsprechen ", euro); Console.WriteLine("{0} DM.", euro * 1.95583); Console.ReadLine();}

Platzhalter bieten den Vorteil erweiterter Formatierungsmöglichkeiten. Dieswerden Sie sich nun zunutze machen, um die Ausgabe des Umrechnungs-ergebnisses auf zwei Nachkommastellen zu begrenzen.

Die Formatierung eines in den Ausgabe-String integrierten Werts erfolgt mit-tels Angabe von Formatierungszeichen. Diese verwenden Sie innerhalb derPlatzhalter – durch einen Doppelpunkt getrennt – nach den Indizes:

Console.WriteLine("{0:F} DM.", euro * 1.95583);

Das Zeichen F bewirkt bei der Anzeige von Gleitkommawerten eine Begren-zung des Nachkommaanteils auf zwei Stellen. Sind für die Anzeige weniger alszwei Stellen notwendig, wird der Rest mit Nullen aufgefüllt.

Auf der CD-ROM

Die endgültige Version des Euro-DM-Umrechnungsprogramms finden Sieunter dem Projektnamen K09c im Ordner Beispiele/Konsolenprogrammeauf der Buch-CD.

Hinweis

Sie können auch f (kleingeschrieben) verwenden. Wie beim Datentyp-Suffix L besteht hier ausnahmsweise kein Unterschied zwischen Groß-und Kleinschreibung.

Page 151: Visual C# 2005 easy

150 Kapitel 9

Es ist auch möglich, die Anzahl der auszugebenden Nachkommastellen explizitfestzulegen. Dies geschieht durch Angabe einer entsprechenden Zahl unmit-telbar nach dem F:

Console.WriteLine("{0:F3} DM. ", euro * 1.95583);

Die Formatierung in der obigen Anweisung bewirkt somit die Anzeige von dreiNachkommastellen für das Umrechnungsergebnis. Die Formatierung {0:F0}lässt dagegen den Nachkommaanteil (einschließlich des Trennzeichens) in derAnzeige komplett verschwinden.

12 Richten Sie es ein, dass das Umrechnungsergebnis in der Anzeige immer mit zwei Nachkommastellen erscheint:

static void Main(string[] args){ double euro; Console.Write("Umzurechnender Euro-Betrag: "); euro = Convert.ToDouble(Console.ReadLine()); Console.Write("{0} Euro entsprechen ", euro); Console.WriteLine("{0:F} DM.", euro * 1.95583); Console.ReadLine();}

13 Überzeugen Sie sich vom Ergebnis.

Die Anzeige des DM-Betrags ist nun auf zwei Nachkommastellen begrenzt. Dieletzte Stelle wird dabei nach dem kaufmännischen Prinzip gerundet.

Abbildung 9.2: Das Ergebnis wird wie bei Währungsbeträgen üblich mit zwei Nachkommastellen angezeigt

Im Folgenden lernen Sie einige weitere Formatierungsmöglichkeiten kennen.

Hinweis

Da das F alleine (ohne nachfolgende Zahlenangabe) die Anzahl derNachkommastellen auf zwei begrenzt, sind die Formatierungen {0:F}und {0:F2} völlig äquivalent.

Page 152: Visual C# 2005 easy

Formatieren von Ausgaben 151

N bzw. n bewirkt eine zusätzliche Ausgabe von Tausender-Trennzeichen. An-sonsten entspricht die Formatierung der von F:

Console.Write("{0:N}", 11998.5663);

Ausgabe: 11.998,57

Console.Write("{0:N3}", 11998.5663);

Ausgabe: 11.998,566

D bzw. d plus Zahlenangabe legt für Integer-Werte eine Mindestanzahl von aus-zugebenden Stellen fest, wobei freie Stellen mit Nullen aufgefüllt werden. DieVerwendung dieses Formatzeichens ohne Zahlenangabe bleibt ohne jeglicheWirkung.

Console.Write("{0:D4}", 99);

Ausgabe: 0099

X bzw. x formatiert den angegebenen Integer-Wert als Hexadezimalzahl:

Console.Write("{0:X}", 11323);

Ausgabe: 2C3B

Console.Write("{0:X}", 30);

Ausgabe: 1E

Hinweis

Es ist ebenfalls erlaubt, die Formatierungszeichen F, f sowie N, n aufInteger-Werte anzuwenden. In diesem Fall erscheint in der Anzeige einNachkommaanteil bestehend aus lauter Nullen – so viele, wie in der For-matierung festgelegt wurden:

int z = 2007;Console.Write("{0:F4}", z);

Ausgabe: 2007,0000

Console.Write("{0:N}", z);

Ausgabe: 2.007,00

Page 153: Visual C# 2005 easy

152 Kapitel 9

Mit einer Zahlenangabe nach dem Formatzeichen können Sie wiederum dieMindestanzahl der auszugebenden Stellen bestimmen. Freie Stellen werdenmit führenden Nullen aufgefüllt:

Console.Write("{0:X8}", 11323);

Ausgabe: 00002C3B

Console.Write("{0:X4}", 30);

Ausgabe: 001E

Schreiben Sie zur Übung ein kleines Programm, welches eine einzugebendeDezimalzahl in Hexadezimalschreibweise darstellt.

1 Legen Sie in Ihrer IDE ein neues Projekt an und richten Sie in der Main()-Methode eine entsprechende Eingabeaufforderung ein:

static void Main(string[] args){ Console.Write("Geben Sie eine ganze Zahl ein: ");}

2 Definieren Sie eine int-Variable.

static void Main(string[] args){ int ein; Console.Write("Geben Sie eine ganze Zahl ein: ");}

3 Rufen Sie die Methode ReadLine() auf und weisen Sie den konvertierten Rückgabewert der Variablen zu:

static void Main(string[] args){ int ein; Console.Write("Geben Sie eine ganze Zahl ein: "); ein = Convert.ToInt32(Console.ReadLine());}

Achtung

Die Anwendung der Formatzeichen D, d sowie X, x ist nicht für Gleitkom-mawerte vorgesehen (Laufzeitfehler!).

Page 154: Visual C# 2005 easy

Formatieren von Ausgaben 153

Den Eingabewert konvertieren Sie mit der Methode ToInt32() in den Daten-typ der Variablen ein.

4 Implementieren Sie die Ausgabe des Werts in Hexadezimalform:

static void Main(string[] args){ int ein; Console.Write("Geben Sie eine ganze Zahl ein: "); ein = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("Hexadezimalzahl: {0:X}", ein); Console.ReadLine();}

5 Bringen Sie Ihr Programm zur Ausführung.

Bei Eingabe von 492 erhalten Sie für die hexadezimale Anzeige 1EC.

Abbildung 9.3: Darstellung eines Werts als Hexadezimalzahl

Für den Eingabewert 10 zeigt die Ausgabe den hexadezimalen Wert A, was aufjeden Fall richtig ist.

Auf der CD-ROM

Das Beispiel finden Sie unter Beispiele/Konsolenprogramme auf derBuch-CD (Projektname K09d).

Page 155: Visual C# 2005 easy

154 Kapitel 9

Zum Abschluss noch ein Wort zu den Platzhaltern: Diese bzw. deren Indizesdienen allein zur Identifizierung zugeordneter Werte. Ihre Nummerierung in-nerhalb eines Ausgabe-Strings muss daher nicht zwingend fortlaufend sein.Das heißt, die Reihenfolge, in der Platzhalter im Ausgabe-String stehen, mussnicht der Liste der angegebenen Werte entsprechen.

Console.Write("{2} und {1} und {0}", 3, 2, 1);

Ausgabe: 1 und 2 und 3

Dementsprechend ist es auch möglich, ein und denselben Wert an mehrerenStellen innerhalb eines Ausgabe-Strings einzubauen.

Hinweis

Unser vertrautes Dezimalsystem, dem die Basis 10 zugrunde liegt,kommt mit den Ziffern 0 bis 9 aus. Da das Hexadezimalsystem mit derBasis 16 arbeitet, sind neben den 10 Ziffern weitere 6 Zeichen zur Dar-stellung notwendig. Hierfür verwendet man die Buchstaben A bis F. Dieaufsteigende Reihenfolge der »Zahlen« im Hexadezimalsystem ist also:1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F.

Daher ist A die hexadezimale Darstellung des dezimalen Werts 10, hexa-dezimal B steht für dezimal 11 usw. und schließlich hexadezimal F fürden Dezimalwert 15. Nach F, dem letzten Ziffernzeichen, wird im Hexa-dezimalsystem wieder mit 1 angefangen und eine Null angehängt, folg-lich entspricht hexadezimal 10 dem Dezimalwert 16, hexadezimal 11dem Dezimalwert 17 usw. Die Zahlen werden also im Hexadezimalsys-tem nach dem gleichen Schema wie im Dezimalsystem gebildet, nur dasses nicht 10 Ziffern, sondern 16 gibt.

Page 156: Visual C# 2005 easy

Eine kleine Erfolgskontrolle 155

Eine kleine Erfolgskontrolle • Welchen Initialisierungswert erhält die Variable x mit der folgenden Defini-

tion?int x = 2 + 3 * 5;

• Schreiben Sie ein Programm, welches das Produkt zweier vom Benutzereinzugebender Zahlen berechnet und mit einer Genauigkeit von zweiNachkommastellen auf den Bildschirm ausgibt.

Page 157: Visual C# 2005 easy

Das können Sie schon:

Entwicklungsschritte zum lauffähigen C#-Programm 11

Umgang mit der Visual C# Express-IDE 36

Aufbau und grundlegende Syntax von C#-Programmen 48

Arbeiten mit Strings 75

Steuerzeichen 81

Variablen, Konstanten und Datentypen 87

Verarbeiten von Benutzereingaben 103

Typkonvertierung 124

Komplexe Ausdrücke 139

Arithmetische Operatoren 140

Formatieren von Bildschirmausgaben 147

Das lernen Sie neu:Einrichten von Programmverzweigungen 157

Behandlung von ungültigen Benutzereingaben 157

Formulieren von Bedingungen 158

Vergleichsoperatoren und logische Operatoren 158

Prioritätsregeln für Operatoren 162

Anhängen eines else-Zweigs 172

Die if-Anweisung 174

Vorzeitiges Abbrechen der Programmausführung 175

Das switch-Konstrukt 177

Page 158: Visual C# 2005 easy

Kapitel 10

VerzweigungenWenn nichts anderes vorgegeben ist, werden bei der Programm-ausführung alle Anweisungen so abgearbeitet, wie sie im Quellcode stehen, also von »oben nach unten«. Zur Lösung von komplexen Auf-gaben ist es jedoch vielfach erforderlich, in diesen Programmfluss einzugreifen. So etwa, wenn der weitere Ablauf von einer Entschei-dung des Benutzers abhängig gemacht werden soll. Für solche Fälle stellt C# eine Reihe von Verzweigungskonstrukten zur Verfügung, mit denen wir uns hier beschäftigen werden. Diese werden immer dann eingesetzt, wenn Anweisungen nur unter bestimmten Bedin-gungen ausgeführt werden sollen.

Page 159: Visual C# 2005 easy

158 Kapitel 10

Logische AusdrückeWie Sie bereits erfahren haben, wird jeder Teil einer Anweisung, welcher für ei-nen Wert steht, in der Programmierung als »Ausdruck« bezeichnet. Und wieSie ebenfalls wissen, besitzt jeder Ausdruck einen Rückgabewert (siehe Kapi-tel 9, Abschnitt »Ausdrücke und arithmetische Operatoren«). Damit ist letztlichder Ergebniswert gemeint, der sich nach Auswertung des Ausdrucks beim Pro-grammlauf ergibt.

Ist nun der Ergebnistyp vom Datentyp bool, handelt es sich um einen logi-schen Ausdruck. Dieser ist also ein spezieller Fall dessen, was wir bisher ge-meinhin als Ausdruck bezeichnet haben.

Für die Formulierung logischer Ausdrücke stellt C# verschiedene Vergleichsope-ratoren zur Verfügung, welche Sie der folgenden Tabelle entnehmen können.

Tabelle 10.1: Vergleichsoperatoren

Hinweis

Mit »Ergebnistyp« ist natürlich der Datentyp des Ergebniswerts (Rück-gabewerts) gemeint.

Beachten Sie, dass sich der Datentyp eines Ausdrucks immer nach demDatentyp seines Rückgabewerts richtet. Beispielsweise besitzt in demAusdruck 2.5 * 4 der linke Operand den Datentyp double, der rechteist jedoch vom Datentyp int. Da vor Auswertung eine implizite Konver-tierung des rechten Operanden nach double erfolgt (von 4 nach 4.0;siehe Kapitel 8, Abschnitt »Implizite Typumwandlungen«), wird der Aus-druck somit zu 10.0 (nicht 10) ausgewertet. Demnach weist der Aus-druck 2.5 * 4 den Datentyp double auf.

Operator Bedeutung

== gleich

!= ungleich

> größer als

>= größer als oder gleich

< kleiner als

<= kleiner als oder gleich

Page 160: Visual C# 2005 easy

Logische Ausdrücke 159

Bitte merken Sie sich:

• Ausdrücke, welche mit Vergleichsoperatoren gebildet werden, ergebennach ihrer Auswertung immer einen booleschen Wert.

• Der Wertebereich des booleschen Datentyps umfasst ausschließlich diebeiden Wahrheitswerte true und false.

Daraus folgt, dass Ausdrücke, in denen Vergleichsoperatoren vorkommen,nach Auswertung immer true (für wahr) oder false (für falsch) ergeben.

Wie werden nun boolesche Ausdrücke gebildet?

Die Vergleichsoperatoren gehören zur Gruppe der binären Operatoren. Dasheißt, sie erfordern einen linken und einen rechten Operanden. Diese werdenin Form einer logischen Aussage einander gegenübergestellt. Über die Art desVergleichs entscheidet dabei das verwendete Symbol.

Nehmen wir als einfaches Beispiel den Ausdruck 1 < 2 (»1 kleiner 2«). Dieserwird zu true ausgewertet, da es sich um eine »wahre« Aussage handelt. Eine»falsche« Aussage wie etwa 0 > 3 (»0 größer 3«) dagegen ergibt den Wertfalse.

Beides können Sie leicht nachprüfen, indem Sie sich die Ergebniswerte aufdem Bildschirm anzeigen lassen, z.B.:

Console.Write(0 > 3); // Ausgabe: False

Oder Sie weisen den Rückgabewert des Ausdrucks einer booleschen Variablenzu und benutzen diese zur Ausgabe:

bool test = 1 < 2;Console.Write(test); // Ausgabe: True

Als Operanden eines logischen Vergleichs dürfen wiederum beliebige Ausdrü-cke stehen, also z.B. auch Variablenbezeichner.

Hinweis

Für logische Ausdrücke wird wegen ihres Datentyps auch die Bezeich-nung boolescher Ausdruck verwendet.

Page 161: Visual C# 2005 easy

160 Kapitel 10

Angenommen, Sie möchten einen Ausdruck formulieren, welcher true ergibt,wenn eine int-Variable mit dem Bezeichner alter den Wert 30 hat. Dannschreiben Sie:

alter == 30

Folgender Ausdruck wird zu true ausgewertet, falls die Variable einen Wertgrößer 30 enthält, andernfalls ergibt die Auswertung false.

alter > 30

Wie verhält es sich aber, wenn Sie einen Ausdruck formulieren müssen, wel-cher nur dann true ergibt, wenn der in der Variablen alter gespeicherte Wertsich im Bereich zwischen 30 und 40 bewegt (exklusive).

Dann muss der Wert von alter größer sein als 30:

alter > 30

und er muss kleiner sein als 40:

alter < 40

Das heißt, beide Bedingungen müssen gleichzeitig erfüllt sein. Für solche Fälle– um zwei oder mehrere logische Teilausdrücke zu einem einzigen Gesamtaus-druck zusammenzufassen – stellt C# die so genannten logischen Operatorenzur Verfügung (siehe Tabelle):

Achtung

Die Rückgabewerte beider Operanden müssen im Datentyp übereinstim-men, da grundsätzlich nur Werte gleichen Datentyps miteinander vergli-chen werden können. Allerdings erfolgen gegebenenfalls impliziteTypumwandlungen nach den in Kapitel 8, Abschnitt »Implizite Typum-wandlungen« genannten Regeln.

Achtung

Denken Sie daran, beim logischen Vergleich auf Gleichheit zwei Gleich-heitszeichen zu verwenden (==). Andernfalls handelt es sich um eineZuweisung.

Page 162: Visual C# 2005 easy

Logische Ausdrücke 161

Tabelle 10.2: Logische Operatoren

Beim logischen Oder (||) reicht es aus, wenn nur einer der verknüpften Teil-ausdrücke »wahr« ist. Dann ergibt die Auswertung des logischen Gesamtaus-drucks den Wert true. Das logische Oder ist einschließend. Das heißt, derErgebniswert des gesamten Ausdrucks ist auch dann true, wenn nicht nur ei-ner, sondern beide Teilausdrücke »wahr« sind.

Umgekehrt ergibt eine Verknüpfung mit && (logisches Und) nur dann einen»wahren« Gesamtausdruck, wenn beide Teilausdrücke »wahr« sind.

Für die Umsetzung der Aufgabenstellung benötigen Sie den Operator für daslogische Und, da der in der Variablen alter enthaltene Wert nur dann zwi-schen 30 und 40 liegt, wenn beide Teilausdrücke den Wert true ergeben. Alsolautet der zusammengesetzte Ausdruck wie folgt.

alter > 30 && alter < 40

Der Operator für die Negation kehrt den Wahrheitswert eines logischen Aus-drucks um. Bei ! handelt sich um einen unären Operator, da er nur einen Ope-randen erwartet (vgl. Kapitel 9, Abschnitt »Ausdrücke und arithmetischeOperatoren«). Ein Beispiel für einen negierten logischen Ausdruck ist !false.Dieser ist mit true äquivalent, beide geben den Wert true zurück.

Statt des nahe liegenden Vergleichsoperators != wie in

alter != 30 // »alter ungleich 30«

lässt sich entsprechend – mit gleicher Wirkung – auch eine Negation verwen-den und Folgendes schreiben:

!(alter == 30) // »nicht alter gleich 30«

Operator Bedeutung

&& logisches Und

|| logisches Oder

! Negation (logische Verneinung)

Hinweis

Das Zeichen | wird mit der Tastenkombination (Strg) + (Alt) + (<)erzeugt.

Page 163: Visual C# 2005 easy

162 Kapitel 10

Prioritätsstufen von OperatorenBetrachten Sie den folgenden Ausdruck:

5 + alter * 2 < 60 && alter > 0

Bei Auswertung dieses Ausdrucks kommen mehrere Operationen zum Zuge –eine Addition, eine Multiplikation, zwei Vergleichsoperationen und eine logi-sche Verknüpfung (&&). Es muss daher irgendwie geregelt sein, in welcher Rei-henfolge diese Operationen ausgeführt werden. Zu diesem Zweck sind alleOperatoren in eine mehrstufige Prioritätsrangfolge eingeordnet. Dabei gilt:

• Operatoren mit hoher Priorität werden vor Operatoren mit niedriger Priori-tät ausgewertet.

• Operatoren mit gleicher Prioritätsstufe werden von links nach rechts aus-gewertet.

Hat ein Operator eine höhere Prioritätsstufe, so bedeutet dies also, dass diedurch ihn repräsentierte Operation zuerst ausgeführt wird, wenn er zusammenmit anderen Operatoren in einem Ausdruck bzw. in einer Anweisung auftritt.

In der folgenden Tabelle sehen Sie eine Auflistung der bis jetzt besprochenenOperatoren nach ihrer Prioritätsstufe, wobei der am weitesten oben stehendeOperator (!) die höchste Priorität besitzt. Operatoren mit gleicher Prioritäts-stufe befinden sich in einer Zeile.

Achtung

Im letzten Ausdruck ist die Klammerung zwingend notwendig, da sichder Operator ! nicht auf die int-Variable alter, sondern auf dengesamten logischen Ausdruck alter == 30 beziehen muss – genaugenommen auf dessen Rückgabewert.

Page 164: Visual C# 2005 easy

Prioritätsstufen von Operatoren 163

Tabelle 10.3: Operator-Prioritätsskala

Es ist nicht notwendig, die gesamte Rangfolge der Operatoren auswendig zukönnen. Einige Orientierungshilfen sind jedoch nützlich:

• Arithmetische Operatoren stehen in der Rangfolge weit oben.

• Wie in der Mathematik gilt: Punkt vor Strich. Das heißt, die arithmetischenOperatoren * (Multiplikation) und / (Division) binden stärker als ihre Kol-legen + (Addition) und - (Subtraktion). Hinzu gesellt sich der Modulo-Ope-rator (%), welcher dieselbe Rangstufe beansprucht wie * und /. DerAusdruck »Punkt vor Strich« kommt übrigens daher, dass die Operatorenfür die Multiplikation und Division in der Mathematik als Punkte geschrie-ben werden (».« steht für die Multiplikation und »:« für die Division). DieOperatoren für Addition (+) und Subtraktion (-) setzen sich dagegen ausStrichen zusammen.

• Der Zuweisungsoperator besitzt von allen Operatoren die niedrigstePrioritätsstufe.

• Sie können in jedem Ausdruck durch Setzen von Klammern die vorgege-bene Rangfolge ändern.

Operator Name bzw. Kategorie

! Logische Verneinung

* / % Multiplikativ

+ - Additiv

< <= > >= Relational

== != Gleichheit

&& Logisches Und

|| Logisches Oder

= Zuweisung

Tipp

Regeln Sie im Zweifel die Priorität durch Setzen von Klammern. Mitunterist dies auch im Hinblick auf eine bessere Lesbarkeit des Codes empfeh-lenswert.

Page 165: Visual C# 2005 easy

164 Kapitel 10

Bezüglich Vergleichs- und logischer Operatoren gilt:

• Die Vergleichsoperatoren besitzen eine höhere Priorität als die logischenOperatoren.

• Der Operator && (logisches Und) bindet stärker als der Operator || (logi-sches Oder).

Haben Sie bitte etwas Geduld, falls Ihnen das alles jetzt noch etwas abstrakterscheint. Sie werden im weiteren Verlauf noch ausreichend Gelegenheit ha-ben, das Formulieren von logischen Ausdrücken zu üben.

Die if-AnweisungMit dem if-Konstrukt steht dem Programmierer eine einfach zu handhabende,jedoch sehr effektive Möglichkeit zur Implementierung von Programmverzwei-gungen zur Verfügung. Die Syntax der if-Anweisung in ihrer einfachsten Formlautet

if(Bedingung) Anweisung

Die Anweisung beginnt mit dem Schlüsselwort if gefolgt von einer Bedin-gung. Eine Bedingung ist nichts anderes als ein logischer Ausdruck, der inKlammern steht und im Zusammenhang mit einer Kontrollstruktur Verwen-dung findet.

Wie Sie im Weiteren sehen werden, kommt der Bedingung bei allen Kontroll-strukturen – mit Ausnahme der switch-Anweisung – entscheidende Bedeu-tung zu.

Kontrollstruktur – was ist das?

Hierbei handelt es sich um den Oberbegriff für alle Konstrukte, welcheeine Steuerung (Kontrolle) des Programmflusses durch den Programmie-rer erlauben. Zu den Kontrollstrukturen gehören neben den Verzwei-gungskonstrukten, welche Thema dieses Kapitels sind, auch Wie-derholungskonstrukte – so genannte Schleifen. Mit Letzteren werden Siesich im nächsten Kapitel beschäftigen.

Page 166: Visual C# 2005 easy

Die if-Anweisung 165

Die nächste Anweisung im Code wird nun automatisch als zum if-Konstruktgehörig interpretiert. Alle weiteren Anweisungen werden vom Compiler wieder»normal« behandelt.

Die Funktionsweise des if-Konstrukts ist schnell erklärt. Bei Eintritt in dieseswährend des Programmlaufs wird zunächst die Bedingung geprüft.

• Ergibt die Auswertung des logischen Ausdrucks den Wert true, dann wirddie zugehörige Anweisung ausgeführt. Danach wird mit der nächstenAnweisung nach der if-Konstruktion weitergemacht.

• Ist der Ergebniswert false, wird die zum if-Konstrukt gehörige Anwei-sung ignoriert und sofort mit der Anweisung fortgefahren, welche im Codeunterhalb der if-Konstruktion steht.

Die Ausführung der zum if-Konstrukt gehörigen Anweisung ist also abhängigvon der if-Bedingung. Ist die Bedingung falsch, verhält es sich daher so, alssei das if-Konstrukt gar nicht vorhanden.

1 Betrachten Sie das folgende Listing:

static void Main(string[] args){ int zahl; Console.Write("Bitte eine Zahl eingeben: "); zahl = Convert.ToInt32(Console.ReadLine()); if(zahl > 10) Console.WriteLine("Zahl ist größer 10"); Console.WriteLine("Dieser Text wird in jedem" + " Fall ausgegeben");}

Die Eingabe des Benutzers wird in der int-Variablen zahl festgehalten. DieseVariable wird in der if-Bedingung zur Prüfung herangezogen. Die Bedingungist wahr, falls in der Variablen ein Wert größer als 10 enthalten ist (zahl > 10).Das heißt, für diesen Fall kommt die zugehörige Anweisung Console.Write-Line("Zahl ist größer 10"); zur Ausführung. Ist die zuvor eingegebeneZahl kleiner oder gleich 10, dann ergibt die Auswertung der if-Bedingung denWert false und die Anweisung des if-Konstrukts wird beim Programmlaufignoriert.

Auf der CD-ROM

Das Beispiel finden Sie unter Beispiele/Konsolenprogramme auf derBuch-CD (Projektname K10a).

Page 167: Visual C# 2005 easy

166 Kapitel 10

2 Laden Sie das Projekt K10a in Ihre Visual C# Express-IDE und führen Sie den Test für eine Eingabezahl kleiner oder gleich 10 durch.

In diesem Fall kommt allein die bedingungsunabhängige AnweisungConsole.WriteLine("Dieser Text wird in jedem Fall ausgegeben");zur Ausführung.

Abbildung 10.1: Eingabezahl kleiner oder gleich 10

3 Führen Sie den Test mit einer Eingabezahl größer als 10 durch.

Nun wird zusätzlich die Anweisung des if-Konstrukts abgearbeitet, mit demErgebnis, dass der Text Zahl ist größer 10 auf dem Bildschirm ausgege-ben wird. Die folgende – bedingungsunabhängige – Anweisung wird natürlichnach wie vor ausgeführt.

Abbildung 10.2: Eingabezahl größer als 10

Page 168: Visual C# 2005 easy

Die if-Anweisung 167

Nun ein praktisches Beispiel: Ein Käufer soll ab einer Bestellmenge von100 Stück eines bestimmten Artikels 10 % Rabatt erhalten. Der Stückpreis sei9,90 Euro.

1 Legen Sie ein neues Projekt an.

2 Definieren Sie eine Variable anzahl vom Datentyp int.

static void Main(string[] args){ int anzahl;}

In dieser Variablen werden Sie die Bestellmenge festhalten.

3 Fordern Sie den Benutzer zur Eingabe der Bestellmenge auf:

static void Main(string[] args){ int anzahl; Console.Write("Bestellmenge: ");}

Achtung

Setzen Sie kein Semikolon hinter die if-Bedingung. Dies führt in derRegel zu logischen Fehlern:

if(zahl > 10); Console.WriteLine("Zahl ist größer 10");

Ein Semikolon allein wird als Anweisung angesehen (siehe Kapitel 5,Abschnitt »Anweisungsende«). Das erste Semikolon in obigem Code-stück wird daher (als Anweisung) dem if-Konstrukt zugerechnet. Dienachfolgende Ausgabeanweisung wird nun nicht mehr als zum if-Kon-strukt gehörig interpretiert. Sie ist somit bedingungsunabhängig. Dasheißt, sie wird auf jeden Fall ausgeführt, unabhängig davon, welcherWert in zahl enthalten ist. Man kann hier davon ausgehen, dass diesvom Programmierer nicht so beabsichtigt war.

Die Visual C# Express-IDE gibt lobenswerterweise bei einer solchen Kon-struktion eine Warnung aus: »Möglicherweise falsche leere Anweisung«.Da es sich wohlgemerkt um eine Warnung und keine Fehlermeldung han-delt, lässt sich das Programm in Verbindung mit solchen Konstruktionendennoch kompilieren und ausführen.

Page 169: Visual C# 2005 easy

168 Kapitel 10

4 Richten Sie eine entsprechende Benutzereingabe ein und speichern Sie diese in der Variablen anzahl:

static void Main(string[] args){ int anzahl; Console.Write("Bestellmenge: "); anzahl = Convert.ToInt32(Console.ReadLine());}

5 Halten Sie den Gesamtpreis (ohne Berücksichtigung eines eventuellen Rabatts) in einer zusätzlichen Variablen fest.

Um den Gesamtpreis zu erhalten, müssen Sie den Stückpreis (9,90 Euro) mitder Bestellmenge multiplizieren:

static void Main(string[] args){ int anzahl; double preis; Console.Write("Bestellmenge: "); anzahl = Convert.ToInt32(Console.ReadLine()); preis = 9.9 * anzahl;}

6 Geben Sie das Ergebnis aus:

static void Main(string[] args){ int anzahl; double preis; Console.Write("Bestellmenge: "); anzahl = Convert.ToInt32(Console.ReadLine()); preis = 9.9 * anzahl; Console.WriteLine("Gesamtpreis: {0:F} Euro", preis); Console.ReadLine();}

Soweit wäre Ihr Programm bereits fertig, wenn es nicht noch die Gewährungeines zehnprozentigen Rabatts zu berücksichtigen gäbe. Um den verbilligtenGesamtpreis zu erhalten, muss dieser mit 0,9 multipliziert werden:

preis = preis * 0.9;

Page 170: Visual C# 2005 easy

Die if-Anweisung 169

7 Fügen Sie diese Anweisung unmittelbar vor der Ausgabe des Gesamtpreises in Ihren Quellcode ein:

static void Main(string[] args){ int anzahl; double preis; Console.Write("Bestellmenge: "); anzahl = Convert.ToInt32(Console.ReadLine()); preis = 9.9 * anzahl; preis = preis * 0.9; Console.WriteLine("Gesamtpreis: {0:F} Euro", preis); Console.ReadLine();}

Allerdings soll der Rabatt nur für den Fall eingeräumt werden, dass der Käufermehr als 100 Stück des besagten Artikels abnimmt. Das heißt, die eben ge-nannte Anweisung soll bedingungsabhängig ausgeführt werden (nur, »wennBestellmenge größer als 100«). Dies erreichen Sie, indem Sie die Anweisung ineine entsprechende if-Konstruktion einfassen:

if(anzahl > 100) preis = preis * 0.9;

8 Vervollständigen Sie Ihr Programm wie beschrieben:

static void Main(string[] args){ int anzahl; double preis; Console.Write("Bestellmenge: "); anzahl = Convert.ToInt32(Console.ReadLine()); preis = 9.9 * anzahl; if(anzahl > 100) preis = preis * 0.9; Console.WriteLine("Gesamtpreis: {0:F} Euro", preis); Console.ReadLine();}

9 Testen Sie Ihr Programm.

Für eine Bestellmenge, welche größer ist als 100, wird bei der Berechnung desGesamtpreises nun ein zehnprozentiger Rabatt berücksichtigt.

Page 171: Visual C# 2005 easy

170 Kapitel 10

Abbildung 10.3: Hier gewährt das Programm Rabatt, da mehr als 100 Artikel bestellt wurden

Wie verhält es sich nun, wenn Sie dem Benutzer zusätzlich die Größe desRabattbetrags mitteilen möchten, und zwar unmittelbar vor Ausgabe desGesamtbetrags?

Console.WriteLine("Sie erhalten {0:F} Euro Rabatt" , preis * 0.1);

Diese Anweisung soll natürlich auch nur dann zur Ausführung kommen, wennder Käufer tatsächlich einen Rabatt erhält, wenn also besagte Bedingung zu-trifft. Somit haben Sie es nunmehr mit zwei von derselben Bedingung abhän-gigen Anweisungen zu tun.

Statt nun für die zweite Anweisung ein neues if-Konstrukt in den Quelltext zuschreiben, fassen Sie beide Anweisungen in einer if-Konstruktion nach fol-gendem Muster zusammen:

if(Bedingung){ Anweisung(en)}

Sie können auf diese Weise beliebig viele Anweisungen unter einer bestimm-ten Bedingung zusammenfassen (was übrigens für alle Kontrollstrukturen gilt– mit Ausnahme des switch-Konstrukts).

Hinweis

Selbstverständlich ist es auch erlaubt, nur eine einzige Anweisung in {}einzuschließen. Dies bewahrt Sie davor, bei eventuellen Änderungen(falls zu ursprünglich einer bedingungsabhängigen Anweisung späternoch weitere hinzukommen) das nachträgliche Setzen von Klammern zuvergessen.

Page 172: Visual C# 2005 easy

Die if-Anweisung 171

10 Ergänzen Sie Ihr Programm wie beschrieben.

static void Main(string[] args){ int anzahl; double preis; Console.Write("Bestellmenge: "); anzahl = Convert.ToInt32(Console.ReadLine()); preis = 9.9 * anzahl; if(anzahl > 100) { preis = preis * 0.9; Console.WriteLine("Sie erhalten {0:F} Euro Rabatt" , preis * 0.1); } Console.WriteLine("Gesamtpreis: {0:F} Euro", preis); Console.ReadLine();}

11 Bringen Sie Ihr Programm zur Ausführung.

Bei einer entsprechenden Bestellmenge bekommen Sie nun den Rabattbetragausgewiesen.

Abbildung 10.4: Bei erfüllter Bedingung werden jetzt zwei Anweisungen ausgeführt

Auf der CD-ROM

Das Beispiel finden Sie unter Beispiele/Konsolenprogramme auf derBuch-CD (Projektname K10b).

Page 173: Visual C# 2005 easy

172 Kapitel 10

Die if-else-KonstruktionSie können dem if-Konstrukt bei Bedarf zusätzlich einen else-Teil hinzufü-gen. Dieser besteht aus dem Schlüsselwort else und einem zugehörigen An-weisungsblock, der nur dann ausgeführt wird, wenn die if-Bedingung denWert false ergibt. Die Syntax der if-else-Konstruktion lautet:

if (Bedingung){ // Anweisung(en)}else{ // Anweisung(en)}

Hier wird also auf jeden Fall einer der beiden Anweisungsblöcke ausgeführt.Dabei gelangen die Anweisungen des if-Teils zur Ausführung, wenn die if-Bedingung wahr ist, andernfalls die Anweisungen des else-Zweigs.

Hier eine Version des letzten Programms unter Hinzufügen eines else-Zweigs:

Hinweis

Man spricht bei Kontrollstrukturen von Anweisungen (z.B. if-Anwei-sung, switch-Anweisung), da sie im Quellcode überall dort eingesetztwerden dürfen, wo auch eine einfache Anweisung stehen darf. So gese-hen werden Kontrollstrukturen vom Compiler tatsächlich wie einfacheAnweisungen behandelt. Folgerichtig ist es auch erlaubt, sie untereinan-der beliebig zu verschachteln.

if(Bedingung1){ … if(Bedingung2) { Anweisung(en) } …}

Beachten Sie, dass dies für alle Kontrollstrukturen gilt und sich auchnicht auf ein und dieselbe Kontrollstruktur beschränkt.

Page 174: Visual C# 2005 easy

Die if-Anweisung 173

static void Main(string[] args){ int anzahl; double preis; Console.Write("Bestellmenge: "); anzahl = Convert.ToInt32(Console.ReadLine()); if(anzahl > 100) { preis = 9.9 * anzahl * 0.9; Console.WriteLine("Sie erhalten {0:F} Euro Rabatt" , preis * 0.1); } else preis = 9.9 * anzahl; Console.WriteLine("Gesamtpreis: {0:F} Euro", preis); Console.ReadLine();}

Beachten Sie:

• Die Konstruktion if else wird wie die einfache if-Konstruktion vomCompiler als Einheit betrachtet, also als eine einzige Anweisung.

• Auch im else-Zweig einer if-else-Konstruktion ist eine Schachtelungvon weiteren Kontrollstrukturen möglich.

• Ein else darf niemals alleine (ohne zugehöriges if ) im Quelltext stehen.

• Es empfiehlt sich, Anweisungen innerhalb eines Blocks einzurücken.Dadurch wird deutlich erkennbar, welcher else-Teil zu welchem if gehört(siehe Kapitel 5, Abschnitt »Programmierstil«).

• Ein else gehört jeweils zum letzten if ohne else.

Wenn Sie einen Quellcode lesen müssen, bei dem die Strukturen nichtdurch Einrückungen gekennzeichnet wurden, gehen Sie diesen von obennach unten durch, bis Sie auf das erste else treffen. Dieses rechnen Siezum letzten if. Dann verfolgen Sie den Code weiter, bis Sie das nächsteelse erreichen und ordnen dieses dem letzten if zu, das noch ohne elseist, usw.

Auf der CD-ROM

Diese Version finden Sie ebenfalls unter Beispiele/Konsolenprogrammeauf der Buch-CD (Projektname K10c).

Page 175: Visual C# 2005 easy

174 Kapitel 10

StringvergleicheMit den Operatoren == und != steht Ihnen eine einfache Möglichkeit zum Ver-gleich von Strings zur Verfügung.

Nehmen wir als Beispiel eine Kennwortabfrage. Wenn der Benutzer ein fal-sches Kennwort eingibt, soll das Programm beendet werden.

1 Legen Sie ein neues Projekt an.

2 Fordern Sie den Benutzer zur Eingabe eines Passworts auf:

static void Main(string[] args){ Console.Write("Geben Sie Ihr Kennwort ein: ");}

3 Halten Sie das eingegebene Passwort in einer string-Variablen fest;

static void Main(string[] args){ string kenn; Console.Write("Geben Sie Ihr Kennwort ein: "); kenn = Console.ReadLine();}

Beachten Sie, dass hier keine Typkonvertierung notwendig ist, da der Rück-gabewert von ReadLine() denselben Datentyp wie die Variable kenn besitzt.

Angenommen, das korrekte Passwort sei xyz. Dann müssen Sie den Wert derVariablen kenn mit dem Literal "xyz" vergleichen. Stimmen beide Werte über-ein, ist das eingegebene Kennwort richtig:

static void Main(string[] args){ string kenn; Console.Write("Geben Sie Ihr Kennwort ein: "); kenn = Console.ReadLine(); if(kenn == "xyz") Console.WriteLine("Willkommen");}

4 Prüfen Sie die Eingabe, wie es oben gezeigt wird.

Wenn das Kennwort falsch ist, soll der Benutzer eine entsprechende Mitteilungerhalten.

5 Ergänzen Sie das if-Konstrukt um einen entsprechenden else-Zweig:

Page 176: Visual C# 2005 easy

Die if-Anweisung 175

static void Main(string[] args){ string kenn; Console.Write("Geben Sie Ihr Kennwort ein: "); kenn = Console.ReadLine(); if(kenn == "xyz") Console.WriteLine("Willkommen"); else Console.WriteLine("Falsches Kennwort" + " - Das Programm wird beendet"); Console.WriteLine("...");}

Die Anweisung Console.WriteLine("..."); soll verdeutlichen, dass dasProgramm für den authentifizierten Benutzer weiterlaufen soll. Allerdings sollfür Benutzer, die ein falsches Kennwort eingegeben haben, der Programmlaufan dieser Stelle zu Ende sein. Um genau das zu erreichen, verwenden Sie denreturn-Befehl.

Sie schreiben also an der Stelle, an der die Methode unregelmäßig verlassenwerden soll, das Wort return in den Quelltext, gefolgt von einem Semikolon.Es handelt sich schließlich um eine Anweisung und wie Sie wissen, muss jedeAnweisung in C# mit einem Semikolon enden. return;

Für Ihr Programm müssen Sie nun folgende Überlegung anstellen: Für den Fall,dass der Benutzer ein falsches Kennwort eingibt, landet die Programmausfüh-rung im else-Zweig. Dort erhält er eine entsprechende Mitteilung ("FalschesKennwort") und genau danach soll für ihn die Programmausführung enden.

6 Sorgen Sie dafür, dass das Programm im else-Zweig unregelmäßig verlassen wird:

static void Main(string[] args){ string kenn;

Anweisung return – was ist das?

Die return-Anweisung bewirkt das sofortige Verlassen einer Metho-de. Anweisungen, welche in der Methode unterhalb von returnstehen, werden nicht mehr abgearbeitet. Da es sich hier um dieMethode Main() handelt, ist dies gleichbedeutend mit dem Beendendes Programms.

Page 177: Visual C# 2005 easy

176 Kapitel 10

Console.Write("Geben Sie Ihr Kennwort ein: "); kenn = Console.ReadLine(); if(kenn == "xyz") Console.WriteLine("Willkommen"); else { Console.WriteLine("Falsches Kennwort" + " - Das Programm wird beendet"); Console.ReadLine(); return; } Console.WriteLine("..."); // Hier geht's für // den authentifizierten Benutzer weiter Console.ReadLine();}

Denken Sie daran, die return-Anweisung mit der Ausgabeanweisung durchSetzen von geschweiften Klammern zu einem Block zusammenzufassen. An-dernfalls würde auch bei Eingabe des richtigen Kennworts die Programmaus-führung mit return beendet werden.

7 Testen Sie Ihr Programm.

Geben Sie einmal ein falsches und einmal das richtige Kennwort ein.

Abbildung 10.5: Das Programm wird bei falschem Kennwort durch die »return«-Anweisung beendet ...

Abbildung 10.6: ... und bei korrektem Kennwort fortgesetzt

Auf der CD-ROM

Das Beispiel finden Sie unter Beispiele/Konsolenprogramme auf derBuch-CD (Projektname K10d).

Page 178: Visual C# 2005 easy

Die switch-Anweisung 177

Die switch-AnweisungSpeziell zur Implementation von Mehrfachverzweigungen bietet C# als weitereMöglichkeit die switch-Anweisung. Zwar können Sie alle Aufgabenstellungenauch mit der if-Anweisung realisieren, für den Benutzer Ihres Programmsmacht das keinen Unterschied. Dennoch hat die switch-Anweisung ihre Exis-tenzberechtigung. Ein wesentlicher Vorteil ist ihre Übersichtlichkeit.

Bei der switch-Anweisung wird zunächst ein Ausdruck ausgewertet. Dabeiwird es sich so gut wie nie um einen booleschen Ausdruck handeln. Anhanddes Ergebniswerts wird dann entschieden, welcher Programmzweig durchlau-fen wird.

Die Syntax der switch-Anweisung lautet:

switch (Ausdruck){ case Konstante_1: Anweisung(en) break; case Konstante_2: Anweisung(en) break; … case Konstante_n: Anweisung(en) break; default: Anweisung(en) break;}

Die einzelnen Programmzweige werden jeweils mit dem Schlüsselwort caseund der Angabe eines Werts gefolgt von einem Doppelpunkt eingeleitet. Die-ser Wert muss eine Konstante sein. Es darf an dieser Stelle also kein Variablen-name stehen. Die Konstante muss vom selben Datentyp sein wie der obennach dem Schlüsselwort switch angegebene Ausdruck.

Achtung

Der Ausdruck des switch-Konstrukts muss wie die Bedingungen deranderen Kontrollstrukturen immer in Klammern stehen.

Page 179: Visual C# 2005 easy

178 Kapitel 10

Nach dem Doppelpunkt schließt sich der Anweisungsteil des entsprechendencase-Zweigs an. Die Stelle vom Schlüsselwort case bis zum Doppelpunkt(case Konstante:) definiert eine so genannte Sprungmarke. Sie wird ange-sprungen, wenn der Wert der Konstanten mit dem Ergebniswert des switch-Ausdrucks übereinstimmt.

Sobald ein Sprungziel erreicht ist, wird der zugehörige Anweisungsteil abgear-beitet. Die break-Anweisung (break;) bewirkt, dass nach Abarbeitung desangesprungenen Zweigs die switch-Konstruktion verlassen wird. Sie ist da-her in jedem Fall die zuletzt ausgeführte Anweisung im switch-Block – denFall, dass kein Programmzweig zur Ausführung gelangt, einmal ausgenom-men.

Die Angabe einer default-Marke ist optional. Stimmt keine case-Konstantemit dem Wert des switch-Ausdrucks überein, wird – soweit vorhanden – zurdefault-Marke gesprungen (ist keine default-Marke gesetzt, wird dieswitch-Anweisung unverrichteter Dinge verlassen und die Programmausfüh-rung wird mit der nächsten Anweisung nach dem switch-Konstrukt fortge-führt).

Achtung

Die break-Anweisung bewirkt das sofortige Verlassen eines switch-Konstrukts. Ihre Wirkung ist daher vergleichbar mit der von return.Allerdings beendet die return-Anweisung die ganze Methode (bzw. dasProgramm), während die Programmausführung mit dem break-Befehlunmittelbar nach dem switch-Konstrukt fortfährt.

Anders als C++ und Java schreibt C# den Gebrauch der break-Anwei-sung am Ende eines jeden Zweiges (einschließlich des letzten) zwingendvor. Andernfalls erhalten Sie eine Fehlermeldung (in C++ und Java wird,nachdem ein Sprungziel erreicht ist, mit der Programmausführung solange sequenziell weitergemacht, bis das nächste break oder das Endeder switch-Anweisung erreicht ist, ungeachtet der Tatsache, ob dabeidie Anweisungen mehrerer Zweige ausgeführt werden).

Falls erforderlich, können Sie die break-Anweisung auch an jeder ande-ren Stelle des switch-Konstrukts einsetzen (etwa in inneren if-else-Verzweigungen).

Page 180: Visual C# 2005 easy

Die switch-Anweisung 179

In der Regel wird als switch-Ausdruck der Bezeichner einer einfachen Variab-len stehen. Diese wird somit auf ihren Inhalt geprüft. Lassen Sie uns den Ab-lauf an folgendem Listing verdeutlichen:

static void Main(string[] args){ int number; number = Convert.ToInt32(Console.ReadLine()); switch(number) { case 2: Console.WriteLine("Zwei"); break; case 1: Console.WriteLine("Eins"); break; case 4: Console.WriteLine("Vier"); break; default: Console.WriteLine("Im default-Zweig"); break; } // end switch Console.WriteLine("Ausserhalb von switch");}

In obigem Programm wird eine einzugebende Ganzzahl (auf eine Eingabeauf-forderung haben wir hier verzichtet) in der Variablen number gespeichert. Die-se wird im switch-Konstrukt zur Prüfung herangezogen.

Spielen wir in Gedanken einige Varianten durch. Angenommen, die Variablenumber enthält den Wert …

… 1: Dann wird die zweite case-Marke angesprungen (case 1:), da diesecase-Konstante (1) mit dem Wert von number übereinstimmt. Die AnweisungConsole.WriteLine("Eins"); gelangt zur Ausführung, mit dem Ergebnis,dass der Text Eins auf dem Bildschirm erscheint (zusätzlich wird die Einfüge-

Hinweis

Die Anweisungsteile der einzelnen Zweige müssen nicht von geschweif-ten Klammern umschlossen sein, da sie jeweils durch eine case- oderdefault-Marke eindeutig begrenzt werden (für den Anweisungsteil desletzten Zweigs gilt die schließende geschweifte Klammer der switch-Anweisung als unterer Begrenzer).

Page 181: Visual C# 2005 easy

180 Kapitel 10

marke in die nächste Zeile gesetzt). Nun wird das switch-Konstrukt mit derbreak-Anweisung verlassen und mit der nächsten Anweisung nach demswitch-Konstrukt fortgefahren (Console.WriteLine("Ausserhalb vonswitch");).

… 77: In den case-Marken ist keine Konstante mit diesem Wert angegeben.Folglich wird zur default-Marke gesprungen. Entsprechend kommt die An-weisung Console.WriteLine("Im default-Zweig"); zur Ausführung.Der anschließende break-Befehl bewirkt das Verlassen des switch-Kon-strukts. Die Programmausführung landet bei der im Quellcode unterhalb desswitch-Konstrukts stehenden Anweisung (Console.WriteLine("Außer-halb von switch");).

… 3: Auch dieser Wert stimmt mit keiner Konstanten überein. Es erfolgt eben-falls ein Sprung zur default-Marke.

… 4: Die Anweisungen des dritten Programmzweigs kommen zum Zug (Conso-le.WriteLine("Vier"); und break;).

Beachten Sie:

• In den einzelnen case-Zweigen dürfen beliebig viele Anweisungen stehen.

• Eine Verschachtelung von weiteren Kontrollstrukturen ist ebenso möglich.

Häufig wird die switch-Anweisung zur Implementation von Menüs verwendet.Die einzelnen Menüpunkte sind dabei meist mit Zahlen oder Buchstaben ge-kennzeichnet. Um eine Aktion auszuführen, gibt der Anwender das entspre-chende Zeichen ein.

Als Beispiel soll ein kleines Rechenprogramm dienen. Dabei wird der Benutzerzur Eingabe zweier Zahlen aufgefordert und kann dann entscheiden, welcheRechenoperation mit diesen Zahlen durchgeführt wird.

1 Legen Sie ein neues Projekt an.

2 Nehmen Sie die Eingabe zweier Zahlen entgegen.

Hinweis

Wie Sie an obigem Listing erkennen können, müssen die Konstanten kei-nesfalls aufsteigend nach ihrem Wert angeordnet sein (case 2: …case 1: … case 4: …).

Page 182: Visual C# 2005 easy

Die switch-Anweisung 181

Um auch die Eingabe von Zahlen mit Nachkommastellen zu ermöglichen, müs-sen Sie Variablen vom Datentyp double verwenden, um die beiden Eingabe-zahlen festzuhalten:

static void Main(string[] args){ double zahl1, zahl2; Console.WriteLine("Geben Sie zwei Zahlen ein"); Console.Write("1. Zahl: "); zahl1 = Convert.ToDouble(Console.ReadLine()); Console.Write("2. Zahl: "); zahl2 = Convert.ToDouble(Console.ReadLine());}

3 Bringen Sie ein Menü zur Anzeige, in dem Sie den Benutzern die Grundrechenarten zur Auswahl stellen:

static void Main(string[] args){ double zahl1, zahl2; Console.WriteLine("Geben Sie zwei Zahlen ein"); Console.Write("1. Zahl: "); zahl1 = Convert.ToDouble(Console.ReadLine()); Console.Write("2. Zahl: "); zahl2 = Convert.ToDouble(Console.ReadLine()); Console.WriteLine("\n(A)ddition"); Console.WriteLine("(S)ubtraktion"); Console.WriteLine("(M)ultiplikation"); Console.WriteLine("(D)ivision\n");}

Um dem Benutzer deutlich zu machen, was er tun muss, um eine der angebo-tenen Operationen auszuwählen, wurden die dazugehörigen Anfangsbuchsta-ben jeweils in Klammern gesetzt. So wird z.B. die Addition durch Eingabe desGroßbuchstabens »A« ausgelöst (und einer Bestätigung mit (¢)). Sie benöti-gen nun eine weitere Variable vom Typ char für die Benutzerauswahl.

4 Nehmen Sie die Benutzerauswahl entgegen:

static void Main(string[] args){ double zahl1, zahl2; char c; Console.WriteLine("Geben Sie zwei Zahlen ein"); Console.Write("1. Zahl: "); zahl1 = Convert.ToDouble(Console.ReadLine()); Console.Write("2. Zahl: "); zahl2 = Convert.ToDouble(Console.ReadLine());

Page 183: Visual C# 2005 easy

182 Kapitel 10

Console.WriteLine("\n(A)ddition"); Console.WriteLine("(S)ubtraktion"); Console.WriteLine("(M)ultiplikation"); Console.WriteLine("(D)ivision\n"); Console.Write("Auswahl: "); c = Convert.ToChar(Console.ReadLine());}

5 Schauen Sie sich das Zwischenergebnis einmal an, bevor Sie weitermachen.

Das Programm endet mit der Auswahl.

Abbildung 10.7: Das Auswahlmenü erscheint nach Eingabe der beiden Zahlenwerte

An dieser Stelle muss das Programm nun in Abhängigkeit von der Benutzer-auswahl verzweigen. Zur Implementation der verschiedenen Programmzweigeverwenden Sie die switch-Anweisung. In dieser prüfen Sie den Inhalt der Va-riablen c, um zu entscheiden, welcher Anweisungsteil zur Ausführung gelangt:

switch(c){ case 'A': break; case 'S': break; case 'M': break; case 'D': break;}

Hinweis

Der Bezeichner c steht für »character«, engl. »Zeichen«. Übrigens wirdder Datentyp genauso ausgesprochen (char, sprich »character«).

Page 184: Visual C# 2005 easy

Die switch-Anweisung 183

6 Fügen Sie Ihrem Code die switch-Anweisung hinzu, wie oben dargestellt.

7 Definieren Sie eine double-Variable mit dem Bezeichner ergebnis:

static void Main(string[] args){ double zahl1, zahl2, ergebnis; char c; Console.WriteLine("Geben Sie zwei Zahlen ein"); Console.Write("1. Zahl: "); zahl1 = Convert.ToDouble(Console.ReadLine()); Console.Write("2. Zahl: "); zahl2 = Convert.ToDouble(Console.ReadLine()); Console.WriteLine("\n(A)ddition"); Console.WriteLine("(S)ubtraktion"); Console.WriteLine("(M)ultiplikation"); Console.WriteLine("(D)ivision\n"); Console.Write("Auswahl: "); c = Convert.ToChar(Console.ReadLine()); switch(c) { case 'A': break; case 'S': break; case 'M': break; case 'D': break; }}

Nun gehen Sie daran, in den einzelnen case-Zweigen die passenden Anwei-sungen einzurichten. Sie werden hier lediglich die Berechnungen durchführenund das Ergebnis in der Variablen ergebnis speichern. Am Ende des Pro-gramms, außerhalb des switch-Konstrukts, werden Sie dann den Wert derVariablen für die Ausgabe verwenden.

8 Addieren Sie im case-Zweig für die Addition beide Eingabezahlen und weisen Sie das Ergebnis der Variablen ergebnis zu:

Achtung

Da die Prüfvariable vom Datentyp char ist, müssen die case-Konstan-ten ebenfalls diesen Datentyp besitzen.

Page 185: Visual C# 2005 easy

184 Kapitel 10

static void Main(string[] args){ double zahl1, zahl2, ergebnis; char c; Console.WriteLine("Geben Sie zwei Zahlen ein"); Console.Write("1. Zahl: "); zahl1 = Convert.ToDouble(Console.ReadLine()); Console.Write("2. Zahl: "); zahl2 = Convert.ToDouble(Console.ReadLine()); Console.WriteLine("\n(A)ddition"); Console.WriteLine("(S)ubtraktion"); Console.WriteLine("(M)ultiplikation"); Console.WriteLine("(D)ivision\n"); Console.Write("Auswahl: "); c = Convert.ToChar(Console.ReadLine()); switch(c) { case 'A': ergebnis = zahl1 + zahl2; break; case 'S': break; case 'M': break; case 'D': break; }}

9 Verfahren Sie nun analog mit den anderen Programmzweigen. Sie müssen nur das entsprechende Symbol für die gewünschte Operation verwenden, also z.B. / für die Division:

static void Main(string[] args){ double zahl1, zahl2, ergebnis; char c; Console.WriteLine("Geben Sie zwei Zahlen ein"); Console.Write("1. Zahl: "); zahl1 = Convert.ToDouble(Console.ReadLine()); Console.Write("2. Zahl: "); zahl2 = Convert.ToDouble(Console.ReadLine()); Console.WriteLine("\n(A)ddition"); Console.WriteLine("(S)ubtraktion"); Console.WriteLine("(M)ultiplikation"); Console.WriteLine("(D)ivision\n"); Console.Write("Auswahl: ");

Page 186: Visual C# 2005 easy

Die switch-Anweisung 185

c = Convert.ToChar(Console.ReadLine()); switch(c) { case 'A': ergebnis = zahl1 + zahl2; break; case 'S': ergebnis = zahl1 - zahl2; break; case 'M': ergebnis = zahl1 * zahl2; break; case 'D': ergebnis = zahl1 / zahl2; break; }}

10 Bringen Sie das Berechnungsergebnis zur Anzeige:

static void Main(string[] args){ double zahl1, zahl2, ergebnis; char c; Console.WriteLine("Geben Sie zwei Zahlen ein"); Console.Write("1. Zahl: "); zahl1 = Convert.ToDouble(Console.ReadLine()); Console.Write("2. Zahl: "); zahl2 = Convert.ToDouble(Console.ReadLine()); Console.WriteLine("\n(A)ddition"); Console.WriteLine("(S)ubtraktion"); Console.WriteLine("(M)ultiplikation"); Console.WriteLine("(D)ivision\n"); Console.Write("Auswahl: "); c = Convert.ToChar(Console.ReadLine()); switch(c) { case 'A': ergebnis = zahl1 + zahl2; break; case 'S': ergebnis = zahl1 - zahl2; break; case 'M': ergebnis = zahl1 * zahl2; break; case 'D':

Page 187: Visual C# 2005 easy

186 Kapitel 10

ergebnis = zahl1 / zahl2; break; } Console.WriteLine("Ergebnis: {0:F}", ergebnis);}

Wenn Sie nun versuchen, das Programm zu kompilieren bzw. in Visual C# Ex-press auszuführen, erhalten Sie eine Fehlermeldung: »Verwendung der nichtzugewiesenen lokalen Variablen ergebnis«. Gemeint ist, dass bis zum Zeit-punkt des Lesezugriffs noch keine Wertzuweisung an die Variable ergebniserfolgt ist. Mit anderen Worten: Es handelt sich um den Versuch, eine Variablezu lesen, welche noch keinen definierten Inhalt hat. Wie Sie wissen, sind sol-che Zugriffe in C# nicht erlaubt.

Nun werden Sie einwenden, dass in den einzelnen case-Zweigen des switch-Konstrukts doch Zuweisungen an die Variable stattfinden. Dennoch sind Pro-grammläufe denkbar, in denen die Variable ohne Zuweisung bleibt, nämlich fürden Fall, dass der Benutzer ein Zeichen eingibt, welches für die Auswahl nichtvorgesehen ist (also nicht A, S, M oder D). Dann kommt kein Anweisungsteildes switch-Konstrukts zur Ausführung und daher erfolgt in diesem Fall auchkeine Zuweisung an die Variable ergebnis. Da Ihr Compiler dies erkennt, willer Sie vor unkontrollierten Zugriffen schützen. Sie könnten den Fehler nun ein-fach beheben, indem Sie die Variable mit dem Wert 0.0 initialisieren. Aller-dings erhält der Benutzer dann bei nicht vorgesehenen Eingaben für dieMenüauswahl die Ausgabe Ergebnis: 0,00, was ebenfalls nicht zufriedenstellen kann.

11 Richten Sie für nicht vorgesehene Auswahleingaben in der switch-Anweisung einen default-Zweig ein.

Am Ende des default-Zweiges beenden Sie die Ausführung der Main()-Me-thode mit return. Damit kommt die Ausgabe des Berechnungsergebnissesfür diesen Fall nicht mehr zur Ausführung:

static void Main(string[] args){ double zahl1, zahl2, ergebnis; char c; Console.WriteLine("Geben Sie zwei Zahlen ein"); Console.Write("1. Zahl: "); zahl1 = Convert.ToDouble(Console.ReadLine()); Console.Write("2. Zahl: "); zahl2 = Convert.ToDouble(Console.ReadLine()); Console.WriteLine("\n(A)ddition"); Console.WriteLine("(S)ubtraktion");

Page 188: Visual C# 2005 easy

Die switch-Anweisung 187

Console.WriteLine("(M)ultiplikation"); Console.WriteLine("(D)ivision\n"); Console.Write("Auswahl: "); c = Convert.ToChar(Console.ReadLine()); switch(c) { case 'A': ergebnis = zahl1 + zahl2; break; case 'S': ergebnis = zahl1 - zahl2; break; case 'M': ergebnis = zahl1 * zahl2; break; case 'D': ergebnis = zahl1 / zahl2; break; default: Console.WriteLine("Ungültige Auswahl " + "(A, S, M oder D)"); return; } Console.WriteLine("Ergebnis: {0:F}", ergebnis);}

Nun kann es vorkommen, dass für zwei oder mehrere Werte die gleichen Akti-onen ausgeführt werden sollen. Das erreichen Sie, indem Sie die entsprechen-den case-Marken untereinander setzen, wobei nur die letzte case-Markeeinen Anweisungsteil besitzt.

Beispielsweise bietet es sich an, das Programm bedienerfreundlicher zu ma-chen, indem neben dem Großbuchstaben auch der entsprechende Kleinbuch-stabe akzeptiert wird. Wenn Sie also möchten, dass die Addition nicht nur fürdie Eingabe A, sondern auch für die Eingabe a durchgeführt wird, dann schrei-ben Sie:

Hinweis

Da der return-Befehl bezüglich des switch-Konstrukts die gleicheWirkung besitzt, darf er anstelle von break; verwendet werden. Dassreturn; nicht nur das switch-Konstrukt, sondern die ganze Methodeverlässt, spielt insoweit keine Rolle.

Page 189: Visual C# 2005 easy

188 Kapitel 10

case 'a':case 'A': ergebnis = zahl1 + zahl2; break;

Beachten Sie, dass es sich trotz mehrerer case-Marken um jeweils nur einenProgrammzweig handelt. case-Marken dienen als Sprungziel, ansonsten wer-den sie ignoriert. Die Verwendung der break-Anweisung ist nur als letzter Be-fehl eines Anweisungsteils vorgeschrieben.

Enthält die Variable c beispielsweise den Wert 'a' (weil der Benutzer bei derAuswahl ein kleines »a« eingegeben hat), wird die zugehörige case-Marke(case 'a':) angesprungen und der nächstliegende Anweisungsteil ausge-führt. Weitere case-Marken werden dabei ignoriert. Der nächstliegende An-weisungsteil beginnt in diesem Fall unmittelbar nach der Marke case 'A':.

12 Richten Sie es ein, dass der Benutzer die von ihm gewünschte Rechenart auch durch Eingeben eines Kleinbuchstabens auswählen kann:

static void Main(string[] args){ double zahl1, zahl2, ergebnis; char c; Console.WriteLine("Geben Sie zwei Zahlen ein"); Console.Write("1. Zahl: "); zahl1 = Convert.ToDouble(Console.ReadLine()); Console.Write("2. Zahl: "); zahl2 = Convert.ToDouble(Console.ReadLine()); Console.WriteLine("\n(A)ddition"); Console.WriteLine("(S)ubtraktion"); Console.WriteLine("(M)ultiplikation"); Console.WriteLine("(D)ivision\n"); Console.Write("Auswahl: "); c = Convert.ToChar(Console.ReadLine()); switch(c) { case 'a': case 'A': ergebnis = zahl1 + zahl2; break; case 's': case 'S': ergebnis = zahl1 - zahl2; break; case 'm': case 'M': ergebnis = zahl1 * zahl2;

Page 190: Visual C# 2005 easy

Die switch-Anweisung 189

break; case 'd': case 'D': ergebnis = zahl1 / zahl2; break; default: Console.WriteLine("Ungültige Auswahl " + "(A, S, M oder D)"); Console.ReadLine(); return; } Console.WriteLine("Ergebnis: {0:F}", ergebnis); Console.ReadLine();}

13 Testen Sie Ihr Programm.

Abbildung 10.8: Bei ungültiger Auswahl wird ein entsprechender Hinweis angezeigt

Auf der CD-ROM

Das Beispiel finden Sie unter Beispiele/Konsolenprogramme auf derBuch-CD (Projektname K10e).

Page 191: Visual C# 2005 easy

190 Kapitel 10

Abbildung 10.9: Nach Auswahl einer Rechenart wird das Ergebnis angezeigt

Im Gegensatz zu den meisten anderen Programmiersprachen erlaubt C# in derswitch-Anweisung auch Stringvergleiche. Es dürfte Ihnen nun keine Schwie-rigkeiten mehr bereiten, das folgende Beispiel nachzuvollziehen:

static void Main(string[] args){ string eingabe; Console.Write("Sind Sie noch fit? "); eingabe = Console.ReadLine(); switch(eingabe) { case "ja": case "Ja": case "JA": Console.WriteLine("Das ist schön!"); break; case "nein": case "Nein": case "NEIN": Console.WriteLine("Machen Sie " + "eine kleine Pause!"); break; default: Console.Write("Ich kann Ihre Antwort "); Console.WriteLine("leider nicht verstehen.");

Tipp

Wenn Sie möchten, dass die Ausgabe mit Tausender-Trennzeichenerfolgt, dann verwenden Sie im Code das N (anstelle von F) als Formatie-rungszeichen, also {0:N}.

Page 192: Visual C# 2005 easy

Eine kleine Erfolgskontrolle 191

break; }}

Eine kleine Erfolgskontrolle• Welchen Rückgabewert liefert folgender Ausdruck?

22 == 2 * 10 || 2.3 < 2.4

• z sei eine Variable vom Datentyp int. Welche Bildschirmausgabe erzeugtfolgendes Codestück, falls z den Wert 9 enthält?if(z <= 0)Console.Write("Die Variable z besitzt ");Console.Write("den Wert " + z);

• An welcher Stelle ist in folgendem Codestück ein (logischer) Fehler zu ver-muten?if(id == 770234); Console.Write("Guten Tag Herr Müller");

• Was bewirkt die return-Anweisung?

• Fordern Sie den Benutzer auf, eine ganze Zahl einzugeben. Teilen Sie ihmanschließend mit, ob die eingegebene Zahl gerade oder ungerade war.Speichern Sie die Benutzereingabe in einer Variablen zahl vom Datentypint. Setzen Sie den Modulo-Operator (siehe Kapitel 9, Abschnitt »DerModulo-Operator«) zur Formulierung einer passenden if-Bedingung ein.

• Die Programmausführung landet in einem switch-Konstrukt mit integrier-tem default-Zweig. Ist der Fall denkbar, dass kein Anweisungsteil inner-halb des Konstrukts zur Ausführung gelangt?

Auf der CD-ROM

Das Beispiel finden Sie unter Beispiele/Konsolenprogramme auf derBuch-CD (Projektname K10f ).

Page 193: Visual C# 2005 easy

Das können Sie schon:

Aufbau und grundlegende Syntax von C#-Programmen 48

Arbeiten mit Strings 75

Steuerzeichen 81

Variablen, Konstanten und Datentypen 87

Verarbeiten von Benutzereingaben 103

Typkonvertierung 124

Komplexe Ausdrücke und arithmetische Operatoren 139

Formatieren von Bildschirmausgaben 147

Einrichten von Programmverzweigungen 157

Vergleichsoperatoren und logische Operatoren 158

Prioritätsregeln für Operatoren 162

Das lernen Sie neu:

Implementation von Wiederholungsabläufen 193

while-Schleife 194

Inkrement und Dekrement 197

do-while-Schleife 198

for-Schleife 199

Gültigkeitsbereich und Lebensdauer von Variablen 202

Im Programm Zufallszahlen erzeugen 204

Referenzvariablen 205

Page 194: Visual C# 2005 easy

Kapitel 11

Wiederholungs-anweisungenOft ist es notwendig, bestimmte Anweisungen wiederholt auszufüh-ren. Dann müssen Sie diese nicht etwa erneut in Ihren Quellcode schreiben. Dies würde in vielen Fällen auch nicht zum gewünschten Ergebnis führen, da die Anzahl der erforderlichen Wiederholungen bei der Entwicklung des Programms oft gar nicht bekannt ist. So ist es z.B. nicht vorhersehbar, ob der Benutzer beim Programmlauf eine bestimmte Aktion abbrechen oder erneut ausführen möchte. Zur Umsetzung von Wiederholungsabläufen stellt C# verschiedene Konstrukte zur Verfügung. Diese zählen wie die Verzweigungsanwei-sungen zu den Kontrollstrukturen, da sie es ermöglichen, den Pro-grammablauf zu steuern. Wiederholungsanweisungen werden wegen ihres kreisförmigen Verlaufs allgemein Schleifen genannt.

Page 195: Visual C# 2005 easy

194 Kapitel 11

Die while-SchleifeDie while-Schleife erlaubt es, in Abhängigkeit von einer Bedingung zu ent-scheiden, ob bzw. wie oft ein Anweisungsblock wiederholt ausgeführt werdensoll. Es gilt folgende Syntax:

while (Bedingung){ Anweisung(en)}

Beginnend mit dem Schlüsselwort while schließt sich eine Bedingung an.Dann folgt die Implementation des Anweisungsteils (beachten Sie die syntak-tische – und auch die funktionale – Ähnlichkeit mit der if-Anweisung).

Bei Ausführung der while-Schleife wird zunächst die Schleifenbedingung ge-prüft. Hierbei handelt es sich wie bei der if-Anweisung um einen logischenAusdruck, der »wahr« oder »falsch« sein kann. Ist er »wahr«, wird der zugehö-rige Anweisungsteil ausgeführt. Nach jedem Schleifendurchgang wird dieBedingung erneut geprüft. Der Anweisungsteil der while-Schleife wird also solange wiederholt, wie die Auswertung der Schleifenbedingung den Wert trueergibt. Andernfalls wird die Schleife verlassen und mit der Ausführung dernächsten Anweisung außerhalb der while-Schleife weitergemacht.

int number = 1;while(number < 5){ Console.WriteLine("Dies ist der " + "{0}. Schleifendurchgang", number); number = number + 1;}

Obiges Codestück erzeugt die Ausgabe

Dies ist der 1. Schleifendurchgang

Dies ist der 2. Schleifendurchgang

Dies ist der 3. Schleifendurchgang

Dies ist der 4. Schleifendurchgang

Bei Eintritt in die while-Schleife hat number den Wert 1, die Schleifenbedin-gung ist wahr und die bedingungsabhängigen Anweisungen werden ausge-führt. Zunächst wird der Text Dies ist der 1. Schleifendurchgang aufden Bildschirm ausgegeben. Danach wird der Wert von number um den Betragvon 1 erhöht. Im Anschluss daran wird die Schleifenbedingung erneut geprüft.Die Variable number hat nun den Wert 2 und die Bedingung (2 < 5) ist wie-derum wahr. Also wird der Anweisungsteil der while-Schleife erneut ausge-

Page 196: Visual C# 2005 easy

Die while-Schleife 195

führt und die Zeichenfolge Dies ist der 2. Schleifendurchgangerscheint auf dem Bildschirm. Bei jedem Schleifendurchlauf wird number um1 hochgezählt (number = number + 1;). Die Abarbeitung der Schleife setztsich nach dem gleichen Prinzip fort. Die letzte Zeichenfolge, die auf den Bild-schirm ausgegeben wird, ist Dies ist der 4. Schleifendurchgang. So-bald number den Wert 5 erreicht, wird die Schleifenbedingung (5 < 5)»falsch« und die while-Schleife verlassen.

Bei der while-Schleife kann es vorkommen, dass die zugehörigen Anweisun-gen kein einziges Mal ausgeführt werden. Das ist der Fall, wenn die erste Aus-wertung der Schleifenbedingung bereits den Wert false ergibt.

Für obiges Beispiel trifft dies zu, falls die Variable number bereits bei Schlei-feneintritt den Wert 5 oder einen höheren Wert enthält. Dann werden die An-weisungen des Schleifenrumpfs nie ausgeführt, da bereits die ersteAuswertung der Schleifenbedingung den Wert false ergibt:

int number = 5;while(number < 5){ // dieser Block wird nie erreicht! Console.WriteLine("Dies ist der " + "{0}. Schleifendurchgang", number); number = number + 1;}

Dies kann aber durchaus so beabsichtigt sein. In der Mehrzahl der Fälle wirddie Anzahl der Schleifendurchgänge (bei späteren Programmläufen) je nachVerhalten des Anwenders variieren. Das ist immer der Fall, wenn das Ergebnisder Bedingungsauswertung von einer Eingabe des Benutzers abhängt:

double number;Console.Write("Bitte positive Zahl eingeben: ");number = Convert.ToDouble(Console.ReadLine());while(number < 0){ Console.WriteLine("Sie haben eine " + "negative Zahl eingegeben."); Console.Write("Bitte positive Zahl eingeben: "); number = Convert.ToDouble(Console.ReadLine());}

Gibt der Anwender sogleich eine positive Zahl ein, dann ist die Schleifenbedin-gung (number < 0) falsch und die Anweisungen des Schleifenrumpfs werdenübersprungen. Besteht die Eingabe aber aus einem negativen Wert, dann wirddie Schleifenbedingung »wahr« und der Anwender erhält eine entsprechende

Page 197: Visual C# 2005 easy

196 Kapitel 11

Mitteilung (Console.WriteLine("Sie haben eine " + "negative Zahleingegeben.");). Nun wird er nochmals aufgefordert, eine Zahl einzugeben,bevor die Schleifenbedingung erneut geprüft wird, usw.

EndlosschleifeEinen meist unerwünschten Sonderfall stellt die so genannte Endlosschleifedar. So werden Schleifen genannt, die nie abbrechen, da die Auswertung derSchleifenbedingung stets den Wert true ergibt. Die Endlosschleife beruht inder Regel auf einem Versehen des Programmautors.

Lässt man z.B. in obigem Codestück die Eingabeanweisung des Schleifen-rumpfs weg, entsteht eine Endlosschleife, falls die Bedingung (number < 0)bei der ersten Auswertung zutrifft.

double number;Console.Write("Bitte positive Zahl eingeben: ");number = Convert.ToDouble(Console.ReadLine());while(number < 0){ Console.WriteLine("Sie haben eine " + "negative Zahl eingegeben."); Console.Write("Bitte positive Zahl eingeben: "); // number = Convert.ToDouble(Console.ReadLine());}

Die Eingabeanweisung des Schleifenrumpfs ist hier auskommentiert, also alsKommentar gekennzeichnet. Die Auswertung der Schleifenbedingung wirdnun nach jedem Schleifendurchgang true ergeben, da sich der Wert vonnumber im Schleifenrumpf nicht ändern kann.

Oder betrachten Sie das Einführungsbeispiel. Vergisst man hier, die Variablenumber hochzuzählen (number = number + 1), entsteht der gleiche Effekt:

int number = 1;while(number < 5){ Console.WriteLine("Dies ist der " + "{0}. Schleifendurchgang", number); number = number + 1; // fehlt diese Anweisung, // so entsteht eine Endlosschleife}

Page 198: Visual C# 2005 easy

Die while-Schleife 197

Inkrement- und DekrementoperatorHierbei handelt es sich um unäre Operatoren. Als Operanden kommen Variab-len numerischen Datentyps infrage. Der Inkrementoperator (++) bewirkt eineErhöhung des Werts einer Variablen um den Betrag von 1. Der Dekrementope-rator (--) verringert den Wert einer Variablen um den gleichen Betrag. Mansagt, eine Variable wird inkrementiert bzw. dekrementiert. Statt zahl = zahl+ 1; können Sie also genauso schreiben zahl++;. Analog sind die Anweisun-gen zahl = zahl - 1; und zahl--; einander gleichwertig.

Beide Operatoren gibt es nicht nur in der eben vorgestellten Postfix-Notation,sondern auch in der Präfix-Notation mit führendem Operator (++zahl bzw.--zahl). Dies macht nur einen Unterschied, falls der Ausdruck, den dieOperatoren mit ihren Variablen bilden, nicht alleine in einer Anweisung steht.Ist das der Fall, wird bei der Präfix-Notation zuerst inkrementiert bzw. dekre-mentiert, bevor weitere Operationen mit der Variablen stattfinden. Umgekehrthaben bei der Postfix-Notation andere Operationen Vorrang:

int x = 0, y = 3;x = y++; // Postfix-NotationConsole.Write(x); // Ausgabe: 3

Hier wird die Variable y erst nach der Zuweisung inkrementiert. Daher erhält xden Wert 3.

int x = 0, y = 3;x = ++y; // Präfix-NotationConsole.Write(x); // Ausgabe: 4

Achtung

Sie müssen es stets (durch geeignete Implementierung des Schleifen-rumpfs) so einrichten, dass sich die Schleifenbedingung nach einerWiederholung auch ändern kann. Diese Aussage gilt für alle Schleifen-konstrukte.

Hinweis

Im Einführungsbeispiel hätten wir also statt number = number + 1;auch kürzer number++; schreiben können.

Page 199: Visual C# 2005 easy

198 Kapitel 11

Hier wird y vor der Zuweisung inkrementiert, sodass die Variable x den Wert 4zugewiesen bekommt.

Die do-while-SchleifeWährend bei der while-Schleife die Schleifenbedingung vor jedem Durchlaufgeprüft wird, erfolgt die Prüfung bei der do-while-Schleife erst nach jedemSchleifendurchgang. Das hat zur Folge, dass die Schleife auf jeden Fall zumin-dest einmal durchlaufen wird.

do{ Anweisung(en)} while (Bedingung);

Zunächst wird der Anweisungsteil der do-while-Schleife abgearbeitet. Im An-schluss daran wird anhand der Bedingung entschieden, ob die Schleife wie-derholt werden soll.

Hier sehen Sie eine Implementation des letzten Beispiels (Eingabe einer Zahl,die positiv sein soll) in Form einer do-while-Schleife:

double number;do{ Console.Write("Bitte positive Zahl eingeben: "); number = Convert.ToDouble(Console.ReadLine()); if(number < 0) Console.WriteLine("Sie haben eine " + "negative Zahl eingegeben.");} while(number < 0);

Da der Benutzer in jedem Fall eine Zahl eingeben soll, erscheint hier der Ein-satz der do-while-Schleife gegenüber der while-Schleife eleganter, da aufeine doppelte Benutzereingabe verzichtet werden kann. Bereits die erste Ein-gabe findet im Schleifenrumpf statt. Gibt der Benutzer eine negative Zahl ein,dann wird die if-Bedingung und auch die Schleifenbedingung (number < 0)

Achtung

Die do-while-Schleife muss mit einem Semikolon abgeschlossen wer-den.

Page 200: Visual C# 2005 easy

Die for-Schleife 199

»wahr«. In diesem Fall wird die Ausgabeanweisung des if-Konstrukts ausge-führt und die do-while-Schleife erneut durchlaufen.

Die for-SchleifeDer Einsatz der for-Schleife eignet sich besonders dann, wenn die Gesamtzahlder Wiederholungen von vornherein feststeht. Folgerichtig ist die for-Schleifeals typische Zählschleife vorgesehen. Zur Syntax:

for (Initialisierung; Bedingung; Aktualisierung){ Anweisung(en)}

Der Kopf der for-Schleife präsentiert sich gegenüber den beiden anderenSchleifenarten etwas ungewöhnlich:

for (Initialisierung; Bedingung; Aktualisierung)

Hier wird eine zusätzliche Variable (Schleifenvariable oder Laufvariable ge-nannt) eingesetzt, um die Anzahl der Schleifendurchläufe zu steuern. Beach-ten Sie, dass Sie diese wie alle anderen Variablen vor Gebrauch definierenmüssen. Allerdings muss die Schleifenvariable der for-Schleife vom Datentypint sein. Es ist üblich, für die Schleifenvariable den Bezeichner i (entspre-chend j, k usw. bei verschachtelten Schleifen) und damit ausnahmsweiseeinen sehr kurzen Namen zu verwenden, absolute Pflicht ist es aber nicht.

Im Initialisierungsteil setzen Sie die Schleifenvariable auf einen Startwert (z.B.i = 0). Die Initialisierung wird nur ein Mal – bei Eintritt in die for-Schleife –ausgeführt.

Die Bedingung wird wie bei der while-Schleife vor jedem Schleifendurchlaufgeprüft. Die Anweisung(en) des Schleifenrumpfs werden so lange wiederholt,wie die Auswertung der Schleifenbedingung true ergibt. Zur Formulierung derBedingung wird folgerichtig die Schleifenvariable herangezogen (z.B. i < 5).

Tipp

Denken Sie an die Anwendung der do-while-Schleife immer dann, wenndie Anweisungen des Schleifenrumpfs zumindest ein Mal ausgeführtwerden müssen.

Page 201: Visual C# 2005 easy

200 Kapitel 11

Im Aktualisierungsteil legen Sie fest, wie sich der Wert der Schleifenvariablennach jedem Durchlauf ändern soll (z.B. i = i+1 oder kürzer i++ ). Die Aktua-lisierung erfolgt nach jedem Schleifendurchlauf. Beachten Sie, dass die Aktu-alisierungsanweisung keinesfalls mit einem Semikolon abgeschlossen werdendarf!

Beispiel:

int i;for(i = 1; i < 4; i++){ Console.WriteLine("Dies ist der " + "{0}. Schleifendurchgang", i);}

Ausgabe:

Dies ist der 1. Schleifendurchgang

Dies ist der 2. Schleifendurchgang

Dies ist der 3. Schleifendurchgang

Der Schleifenkopf ist so eingerichtet, dass die for-Schleife bei Programmaus-führung insgesamt dreimal durchlaufen wird. Bei Eintritt in die for-Schleife

Hinweis

Eigentlich lautet die allgemeine Definition des Schleifenkopfs der for-Schleife for (Anweisung; Bedingung; Anweisung). Das heißt, fürAnweisung könnte theoretisch jede beliebige Anweisung eingesetzt wer-den. Syntaktisch in Ordnung wäre sogar for (;Bedingung;) (leereAnweisungen vor und nach der Schleifenbedingung). In der Praxis spie-len solche Überlegungen jedoch in aller Regel keine Rolle.

Hinweis

Da hier der Schleifenrumpf nur eine einzige Anweisung enthält, dürfenSie die geschweiften Klammern auch weglassen:

int i;for(i = 1; i < 4; i++) Console.WriteLine("Dies ist der " + "{0}. Schleifendurchgang", i);

Page 202: Visual C# 2005 easy

Die for-Schleife 201

wird zunächst die Variable i auf den Startwert 1 gesetzt, dann wird die Bedin-gung geprüft (1 < 4) und die Schleife zum ersten Mal durchlaufen. Nach demersten Durchlauf wird i um den Betrag von 1 erhöht (i++) und die Bedingungerneut geprüft (2 < 4). Nach jedem Schleifendurchlauf wird der Wert von i um1 erhöht, sodass i nacheinander die Werte 1, 2, 3 und 4 annimmt. Nach demdritten Durchgang besitzt i den Wert 4. Nun ergibt die Bedingungsauswertung(4 < 4) den Wert false und die for-Schleife wird verlassen.

Beachten Sie:

Die Schleifenvariable der for-Schleife wird häufig – wie im Beispiel zu sehen –auch im Anweisungsteil genutzt.

for(i = 1; i < 4; i++){ Console.WriteLine("Dies ist der " + "{0}. Schleifendurchgang", i);}

Sie sollten es aber vermeiden, die Schleifenvariable im Schleifenrumpf zu ma-nipulieren.

Sie können die Schleifenvariable mit jedem beliebigen Startwert versehen,wenn Sie die Bedingung und die Aktualisierung entsprechend anpassen. Stattfor(i = 1; i < 4; i++) hätte man z.B. auch Folgendes schreiben können:

for(i = 0; i < 3; i++)

oder auch:

for(i = 3; i > 0; i--)

In der letzten Variante wird i nach jedem Schleifendurchlauf dekrementiert (i--).

Achtung

Der Wert der Schleifenvariablen sollte ausschließlich im Aktualisierungs-teil des Schleifenkopfs verändert werden. Führen Sie also im Schleifen-rumpf keine Zuweisungen an die Laufvariable durch, denn dadurchverschlechtert sich die Nachvollziehbarkeit des Quellcodes erheblich.Schließlich gibt es dann neben dem Aktualisierungsteil des Schleifen-kopfs weitere Stellen, an denen eine Aktualisierung der Laufvariablestattfindet, was eine erhöhte Anfälligkeit für logische Fehler mit sichbringt.

Page 203: Visual C# 2005 easy

202 Kapitel 11

Gültigkeitsbereich von VariablenSie dürfen die Schleifenvariable auch im Kopf der for-Schleife definieren. Die-se ist dann aber nur innerhalb der Schleifenkonstruktion gültig. Das heißt, Siekönnen außerhalb des Schleifenblocks nicht auf sie zugreifen:

for(int i = 1; i < 4; i++){ Console.WriteLine("Dies ist der " + "{0}. Schleifendurchgang", i);}// hier ist i nicht bekanntConsole.WriteLine(i); // FEHLER

Mithin ist es an der Zeit, sich über den Gültigkeitsbereich von Variablen Gedan-ken zu machen. Es gelten folgende Regeln:

• Eine Variable ist gültig in dem Block, in dem sie definiert ist, sowie in alleninneren Blöcken.

• Eine Variable darf nur innerhalb ihres Gültigkeitsbereichs verwendet wer-den. Außerhalb ihres Gültigkeitsbereichs verhält es sich so, als sei dieVariable gar nicht vorhanden.

Achtung

Allerdings müssen Sie dann auch die Anweisungen im Schleifenrumpfanpassen, wenn Sie die Laufvariable dort verwenden. Verwenden Siez.B. für die Laufvariable einen Startwert von 0 und möchten dennoch beider Ausgabe bei 1 anfangen zu zählen, gehen Sie beispielsweise so vor:

for(i = 0; i < 3; i++){ Console.WriteLine("Dies ist der " + "{0}. Schleifendurchgang", i + 1);}

Hinweis

Statt vom Gültigkeitsbereich einer Variablen spricht man auch von derenSichtbarkeit. Beide Begriffe werden synonym verwendet.

Page 204: Visual C# 2005 easy

Die for-Schleife 203

In folgendem Listing ist die Variable a innerhalb des ganzen Methodenrumpfsvon Main() gültig. Die Sichtbarkeit der Variablen b dagegen beschränkt sichauf den Schleifenrumpf der while-Schleife:

static void Main(string[] args){ int a = 0; while(a < 5) { int b = 0; b++; Console.WriteLine("Wert von b: " + b); a++; } // end while} // end Main()

Mit dem Verlassen des Blocks, in dem eine Variable definiert ist, endet in derRegel auch ihre Lebensdauer. Das heißt, der von der Variablen beanspruchteSpeicherplatz wird vom Programm wieder freigegeben.

So wird in obigem Beispiel die Variable b mit jedem Schleifendurchlauf neu an-gelegt und mit dem Wert 0 initialisiert. Daher zeigt die Ausgabe des Variablen-inhalts (Console.WriteLine("Wert von b: " + b);) stets den Wert 1,obwohl b mit jedem Schleifendurchlauf hochgezählt wird (b++;).

Auf der CD-ROM

Das Beispiel finden Sie unter Beispiele/Konsolenprogramme auf derBuch-CD (Projektname K11a).

Hinweis

Variablen, die in einem Methodenblock definiert sind, bezeichnet manals lokal (zu dieser Methode). Wenn ein Programm aus mehreren Metho-den besteht, besitzt jede Methode ihre eigenen lokalen Variablen. Diesesind in anderen Methoden nicht bekannt. Mehr dazu erfahren Sie inKapitel 13.

Page 205: Visual C# 2005 easy

204 Kapitel 11

Abbildung 11.1: Die Variable wird bei jedem Schleifendurchgang neu angelegt und initialisiert, was die Ausgabe erklärt

Zufallszahlen generierenAls Vorlauf zu weiteren Übungen erfahren Sie hier, wie Sie in Ihren Program-men Zufallszahlen erzeugen.

Dazu verwenden Sie die Methode Next() der Klasse Random. Diese Methodewird nicht mit dem Klassennamen, sondern mit einem Objektnamen aufgeru-fen. Ein Objekt der Klasse Random wird von C# jedoch nicht zur Verfügung ge-stellt. Das heißt, Sie müssen es zunächst erzeugen, bevor Sie die MethodeNext() verwenden können.

Neue Objekte einer Klasse erzeugen Sie mit dem Schlüsselwort new gefolgtvom Klassennamen. Diesem schließt sich in Klammern eine Parameterliste an:

new Random()

Beim Entstehen eines Klassenobjekts wird eine in jeder Klasse definierte spe-zielle Methode aufgerufen, der so genannte Konstruktor. Da wir den Konstruk-tor der Klasse Random ohne Parameter aufrufen, bleiben die Klammern hierleer.

Allerdings steht der Ausdruck new Random() nicht für das erzeugte Objektselbst, sondern lediglich für einen Verweis auf dieses. Um wirklich mit demneuen Objekt arbeiten zu können, benötigen Sie eine so genannte Referenz-variable, welche diesen Verweis aufnimmt.

Random zufall;

Hinweis

Berücksichtigen Sie, dass nach jedem Schleifendurchgang der zugehörigeSchleifenblock tatsächlich verlassen wird, auch im Fall einer anschließen-den Wiederholung (diese Aussage gilt für alle Schleifenarten).

Page 206: Visual C# 2005 easy

Zufallszahlen generieren 205

Bei obiger Anweisung handelt es sich um die Definition einer Referenzvariab-len. Dazu müssen Sie wissen, dass jede Klasse ein Datentyp ist. zufall ist einfrei wählbarer Bezeichner für die Referenzvariable.

Nun müssen Sie der Referenzvariablen noch den Verweis auf das Random-Objekt zuweisen:

zufall = new Random();

Im Weiteren behandeln Sie die Referenzvariable zufall so, als sei sie das Ob-jekt selbst. Um also die Methode Next() zu verwenden, schreiben Sie

zufall.Next();

Die Methode Next() bewirkt die Erzeugung einer ganzen Zufallszahl und gibtdiese als int-Wert zurück. Wenn Sie möchten, dass die Zufallszahl in einembestimmten Bereich liegt, übergeben Sie Next() zwei Werte für die Unter- undObergrenze:

zufall.Next(1, 11);

Der Wert für die Obergrenze wird von der Methode jedoch exklusiv behandelt.Das heißt, die erzeugten Zahlen liegen im Bereich Untergrenze bis Obergrenzeminus 1. Obiger Methodenaufruf bewirkt somit, dass die Zufallszahl einen derWerte von 1 bis einschließlich 10 annimmt. Sie sollten den Rückgabewert derMethode noch in einer int-Variablen festhalten:

int los;los = zufall.Next(1, 11);

Hinweis

Natürlich können Sie zufall auch gleich mit dem Verweis auf das Ran-dom-Objekt initialisieren:

Random zufall = new Random();

Hinweis

Von daher ist es auch nicht falsch zu sagen, »das Objekt zufall« bzw.die Methode Next() »des Objekts zufall«, obwohl zufall ja eigent-lich eine Referenzvariable ist (welche einen Verweis auf das wirklicheObjekt enthält).

Page 207: Visual C# 2005 easy

206 Kapitel 11

Hier ein vollständiges Beispiel zur Erzeugung und Anzeige einer Zufallszahl:

static void Main(string[] args){ int los; Random zufall = new Random(); los = zufall.Next(1, 11); Console.WriteLine("Die geloste Zahl ist " + los);}

Hier noch einmal das Wesentliche zusammengefasst:

• Die Methode Next() ist in der Klasse Random definiert und erzeugt eineZufallszahl, die als int-Wert zurückgegeben wird.

• Next() wird objektbezogen verwendet. Ein Methodenaufruf wie Random.Next(); // FEHLER

wäre also fehlerhaft.

• Der Ausdruck new Random() erzeugt ein neues Objekt der Klasse Randomund gibt einen Verweis auf dieses zurück. Das Objekt selbst befindet sichin einem separaten Teil des Arbeitsspeichers (dem so genannten Heap)und ist namenlos. Um es im Weiteren ansprechen zu können, ist es dahernotwendig, einen Verweis darauf (seine Speicheradresse) in einer Refe-renzvariablen festzuhalten.

• Nach Definition und Aufnahme eines Objektverweises wird eine Referenz-variable so verwendet, als handle es sich um das Objekt selbst.

Wertetypen und ReferenztypenIm Groben lassen sich Datentypen wie folgt in Gruppen einteilen:

• Elementare Datentypen wie int, double, char usw.

• Der Datentyp string stellt dabei einen Sonderfall dar, wie wir gleichsehen werden.

• Jeder Klassenname beschreibt ebenfalls einen Datentyp.

• Im weiteren Sinne handelt es sich bei Arrays ebenfalls um einen Datentyp.Arrays werden Sie im nächsten Kapitel kennen lernen.

Auf der CD-ROM

Das Beispiel finden Sie unter Beispiele/Konsolenprogramme auf derBuch-CD (Projektname K11b).

Page 208: Visual C# 2005 easy

Zufallszahlen generieren 207

C# unterscheidet zwischen Wertetypen und Referenztypen. Zu Letzteren gehö-ren Klassen, Arrays und der Datentyp string. Die anderen elementarenDatentypen sind Wertetypen.

Bei den Wertetypen werden die Werte in den Variablen direkt abgelegt. Variab-len eines Referenztyps erhalten lediglich einen Verweis auf ein Objekt (eine an-dere Variable), in welchem (welcher) die tatsächlichen Werte abgelegt werden.Als Beispiel für eine Variable eines Referenztyps (Random) sei hier die Variablezufall des letzten Beispiels genannt.

Obige Ausführungen sind gewissermaßen auch als Vorbereitung auf zukünfti-ge Lerninhalte (Arrays, Klassen) gedacht. Sollten Sie noch nicht alles verstan-den haben, so ist das kein Grund zur Beunruhigung. Im Allgemeinen sindReferenzvariablen nach Definition und Verweisaufnahme genauso zu behan-deln wie Variablen von Wertetypen (allerdings kann das Wissen um die ge-nannten Zusammenhänge gerade bei komplexeren Problemen sehr von Vorteilsein).

Dass Referenztypen so gesehen nichts Besonderes sind, zeigt sich schon da-rin, dass Sie bereits seit geraumer Zeit – ohne es zu wissen – mit Variableneines Referenztyps arbeiten.

Hinweis

Häufig werden vereinfachend auch die Variablen bzw. Objekte einesDatentyps als Werte- bzw. Referenztypen bezeichnet. Von daher könnteman bezüglich der Anweisung

int a = 0;

nicht nur sagen, der Datentyp der Variablen a (int) sei ein Wertetyp,sondern ebenfalls: »a ist ein Wertetyp«. Gemeint ist damit, dass a eineVariable eines Wertetyps ist.

Hinweis

»Variablen« eines Klassentyps werden Objekte genannt. Ansonsten sindVariablen und Objekte qualitativ einander ähnlich. Genaueres hierzuerfahren Sie in Kapitel 14.

Page 209: Visual C# 2005 easy

208 Kapitel 11

Es handelt sich um den Datentyp string. Wenn Sie eine Variable dieses Typsvereinbaren, schreiben Sie z.B.

string myVar;

Wenn string ein Referenztyp ist, muss myVar also eine Referenzvariable sein.Tatsächlich wird mit der Zuweisung

myVar = "C#";

zur Aufnahme der Zeichenkette "C#" ein string-Objekt auf dem Heap ange-legt und die Referenzvariable myVar erhält einen Verweis auf dieses Objekt.Das alles geschieht automatisch ohne Zutun des Programmierers. Diesbezüg-lich bildet der Datentyp string eine Ausnahme. Objekte anderer Referenz-typen müssen Sie dagegen explizit mit new erzeugen.

Wenn Sie nun eine Neuzuweisung wie z.B.

myVar = "C# ist easy";

durchführen, dann wird das alte Objekt auf dem Heap gelöscht (das heißt, derentsprechende Speicherbereich wird wieder freigegeben). Gleichzeitig wird aneiner freien Stelle auf dem Heap ein neues Objekt angelegt, welches die neue(größere) Zeichenkette aufnimmt. Die Referenzvariable myVar erhält nun ei-nen Verweis auf dieses neue Objekt.

Nun erklärt sich auch, weshalb Variablen des Datentyps string keine festeSpeichergröße beanspruchen (siehe Kapitel 7, Abschnitt »Variablendefiniti-on«). Das einzige Limit von Strings sind die Speicherressourcen des Compu-ters, auf dem das Programm läuft.

Hinweis

Der Arbeitsspeicher ist in mehrere Bereiche unterteilt. Für den Program-mierer interessant ist vor allem der so genannte Stack sowie der bereitserwähnte Heap. Wenn Speicherplatz für ein Datenobjekt in einem derBereiche reserviert wird, sagt man, das Objekt wird »auf dem Heap bzw.Stack« angelegt. Referenzvariablen werden wie die Variablen eines Wer-tetyps auf dem Stack und die tatsächlichen Objekte eines Referenztypsauf dem Heap angelegt. Beide Bereiche unterscheiden sich in der inter-nen Speicherverwaltung – worauf wir hier nicht näher eingehen wollen.

Page 210: Visual C# 2005 easy

Realisieren Sie ein Ratespiel 209

Zur Wiederholung:

• Objekte eines Referenztyps werden mit dem Schlüsselwort new erzeugt(gemeint sind nicht die Referenzvariablen, sondern die tatsächlichenObjekte). Ausnahme hierbei sind Objekte des Datentyps string. Diesewerden automatisch angelegt.

• Klassen, Arrays sowie der Datentyp string sind Referenztypen, die ande-ren Standarddatentypen sind Wertetypen. Üblicherweise bezeichnet manauch die Objekte bzw. Variablen dieser Datentypen als Referenz- bzw. Wer-tetypen.

• Eine Variable eines Wertetyps speichert den tatsächlichen Wert.

• Eine Referenzvariable speichert einen Verweis auf ein anderes Daten-objekt, in dem die Informationen abgelegt sind.

• Variablen eines Wertetyps und Referenzvariablen werden auf dem Stackangelegt.

• Das eigentliche Datenobjekt, auf das eine Referenzvariable verweist, liegtauf dem Heap.

Realisieren Sie ein RatespielErstellen Sie zur Übung folgendes Programm: Der Benutzer soll eine vom Pro-gramm zufällig erzeugte Zahl zwischen 1 und 20 erraten. Er hat hierfür drei Ver-suche. Teilen Sie ihm nach jedem erfolglosen Versuch mit, ob seine Zahl zugroß oder zu klein war.

1 Legen Sie in Ihrer Visual C# Express-IDE ein neues Projekt an.

2 Implementieren Sie die Auslosung einer Zufallszahl.

Gehen Sie so vor, wie im Abschnitt »Zufallszahlen generieren« beschrieben.Halten Sie die Zufallszahl in einer Variablen glueck fest:

static void Main(string[] args){ int glueck; Random zufallszahl = new Random(); glueck = zufallszahl.Next(1, 21);}

Page 211: Visual C# 2005 easy

210 Kapitel 11

Beachten Sie, dass die Methode Next() mit den Argumenten 1 und 21 aufge-rufen werden muss. Natürlich bringen Sie die Zufallszahl erst am Schluss zurAnzeige, da sie ja für den Benutzer während der Rateversuche nicht sichtbarsein darf.

Bemühen Sie sich zunächst um eine einfache Lösung, bevor Sie sich um Wie-derholungsabläufe kümmern. Lassen Sie also den Benutzer eine Zahl einge-ben und stellen Sie fest, ob sie mit der Zufallszahl übereinstimmt bzw. ob siekleiner oder größer ist als diese.

3 Richten Sie eine Zahleneingabe ein.

Um die Ratezahl festzuhalten, benötigen Sie eine zusätzliche Variable vomDatentyp int. Nennen Sie diese sinnigerweise tipp:

static void Main(string[] args){ int glueck, tipp; Random zufallszahl = new Random(); glueck = zufallszahl.Next(1, 21); Console.WriteLine("\nRATESPIEL 1 aus 20\n"); Console.Write("Ihr Tipp: "); tipp = Convert.ToInt32(Console.ReadLine());}

4 Vergleichen Sie den Tipp mit der Zufallszahl.

Sie müssen insgesamt drei Vergleiche anstellen, einmal auf Gleichheit (tipp== glueck) sowie größer als (tipp > glueck) und kleiner als (tipp <glueck). Dementsprechend sind drei Programmzweige einzurichten:

static void Main(string[] args){ int glueck, tipp; Random zufallszahl = new Random(); glueck = zufallszahl.Next(1, 21); Console.WriteLine("\nRATESPIEL 1 aus 20\n"); Console.Write("Ihr Tipp: "); tipp = Convert.ToInt32(Console.ReadLine()); if(tipp == glueck)

Auf der CD-ROM

Das vollständige Programm finden Sie unter Beispiele/Konsolenpro-gramme auf der Buch-CD (Projektname K11c).

Page 212: Visual C# 2005 easy

Realisieren Sie ein Ratespiel 211

Console.WriteLine("Richtig geraten!"); if(tipp > glueck) Console.WriteLine("Zu groß"); if(tipp < glueck) Console.WriteLine("Zu klein");}

Alle drei Bedingungen schließen sich gegenseitig aus. Daher ist sichergestellt,dass beim Programmlauf nur ein Zweig zur Ausführung gelangt. Beachten Sie,dass der Einsatz der switch-Anweisung hier nicht infrage kommt, da dieseausschließlich den direkten Wertevergleich unterstützt.

5 Überzeugen Sie sich vom Zwischenergebnis.

Zu Testzwecken ist es möglicherweise sinnvoll, vorübergehend eine Ausgabe-anweisung zur Anzeige der Zufallszahl in den Quellcode zu schreiben. So kön-nen Sie den Test für alle Programmzweige bequem durchführen und dieStimmigkeit der Ausgabe überprüfen:

static void Main(string[] args){ int glueck, tipp; Random zufallszahl = new Random(); glueck = zufallszahl.Next(1, 21); Console.WriteLine("\nZufallszahl: " + glueck); Console.WriteLine("\nRATESPIEL 1 aus 20\n"); Console.Write("Ihr Tipp: "); tipp = Convert.ToInt32(Console.ReadLine()); if(tipp == glueck) Console.WriteLine("Richtig geraten!"); if(tipp > glueck) Console.WriteLine("Zu groß"); if(tipp < glueck) Console.WriteLine("Zu klein");}

Page 213: Visual C# 2005 easy

212 Kapitel 11

Abbildung 11.2: Testversion des Programms, die zu ratende Zufallszahl wird zwecks Überprüfungsmöglichkeit mit angezeigt

Nun gehen Sie daran, die Wiederholungsabläufe einzurichten. Als Erstes müs-sen Sie sich überlegen, welche Anweisungen wiederholt werden sollen.

6 Fassen Sie die zu wiederholenden Anweisungen zu einem Block zusammen.

Vermutlich sind Sie zum richtigen Ergebnis gekommen: Die Wiederholungmuss mit der Eingabe des Tipps einsetzen und sich auf alle Programmzweigeerstrecken:

static void Main(string[] args){ int glueck, tipp; Random zufallszahl = new Random(); glueck = zufallszahl.Next(1, 21); Console.WriteLine("\nRATESPIEL 1 aus 20\n"); { Console.Write("Ihr Tipp: "); tipp = Convert.ToInt32(Console.ReadLine()); if(tipp == glueck) Console.WriteLine("Richtig geraten!"); if(tipp > glueck) Console.WriteLine("Zu groß");

Hinweis

Auf den Abdruck des Haltebefehls werden wir im Weiteren verzichten.Übrigens kommen Sie innerhalb Ihrer IDE auch ohne Haltebefehl aus,wenn Sie in der Menüleiste unter Debuggen den Eintrag Starten ohneDebuggen wählen (Tastenkombination (Strg) + (F5)). Dann fügt VisualC# Express für das Konsolenfenster automatisch einen Haltebefehlhinzu. Das Verwenden von Console.ReadLine() hat allerdings denVorteil, dass sich Ihre Programme (die .exe-Datei der jeweiligen Projekte)dann auch aus dem Windows-Explorer heraus starten lassen.

Page 214: Visual C# 2005 easy

Realisieren Sie ein Ratespiel 213

if(tipp < glueck) Console.WriteLine("Zu klein"); }}

Denken Sie daran, die Anweisungen innerhalb des neu entstandenen Blocksnachträglich einzurücken.

7 Verwenden Sie die for-Schleife, um den Anweisungsblock drei Mal zu wieder-holen.

Es bietet sich an, die Schleifenvariable i mit dem Startwert 1 zu versehen. Die-se gibt dann die aktuelle Wiederholungszahl wieder, was hilfreich für derenVerwendung im Schleifenrumpf ist.

static void Main(string[] args){ int glueck, tipp, i; Random zufallszahl = new Random(); glueck = zufallszahl.Next(1, 21); Console.WriteLine("\nRATESPIEL 1 aus 20\n"); for(i = 1; i < 4; i++) { Console.Write("Ihr {0}. Tipp: ", i); tipp = Convert.ToInt32(Console.ReadLine()); if(tipp == glueck) Console.WriteLine("Richtig geraten!"); if(tipp > glueck) Console.WriteLine("Zu groß"); if(tipp < glueck)

Tipp

Der Code-Editor der Visual C# 2005 Express Edition sollte nach dem Set-zen der Klammern ({ und }) die Einrückungen automatisch durchführen.Andernfalls lassen Sie Ihren Quellcode mit Bearbeiten/Erweitert/Doku-ment formatieren oder der Tastenkombination (Strg) + (E), (D) neu for-matieren (siehe Kapitel 5 unter »Hätten Sie gedacht ...«).

Hinweis

Es sei darauf hingewiesen, dass prinzipiell auch eine Umsetzung mit derwhile- oder do-while-Schleife infrage kommt.

Page 215: Visual C# 2005 easy

214 Kapitel 11

Console.WriteLine("Zu klein"); }}

Nun müssen Sie noch den Fall behandeln, dass ein Benutzer bereits vor demletzten Rateversuch die richtige Zahl tippt, im Beispiel also beim ersten oderzweiten Rateversuch. Dann muss die Schleife sofort abgebrochen werden.

Sie könnten dieses Problem nun lösen, indem Sie die Schleifenbedingung umeinen Teilausdruck ergänzen (logische Und-Verknüpfung):

for(i = 1; i < 4 && tipp != glueck; i++)

Wenn nun die zuletzt geratene Zahl (tipp) mit der Zufallszahl (glueck) über-einstimmt, dann wird die Schleife nicht mehr ausgeführt.

Es gibt allerdings eine bequemere und sicherere Lösung unter Anwendung ei-nes Befehls, der Ihnen bereits bei der switch-Anweisung begegnet ist: Mit derbreak-Anweisung können Sie nicht nur ein switch-Konstrukt, sondern auchalle Schleifenarten unregelmäßig, also vorzeitig, verlassen.

Achtung

Beachten Sie, dass Sie bei dieser Lösung die Variable tipp mit einemgeeigneten Anfangswert versehen müssen. Ansonsten ruft der ersteLesezugriff auf diese Variable (bei der Bedingungsprüfung vor dem ers-ten Schleifendurchlauf ) eine Ihnen inzwischen bekannte Fehlermeldunghervor (»Verwendung der nicht zugewiesenen lokalen Variablen tipp«).Außerdem muss der Anfangswert so gewählt werden, dass die Teilbedin-gung tipp != glueck bei der ersten Auswertung auf jeden Fall falseergibt, da in diesem Fall noch keine Benutzereingabe erfolgt ist. Sie soll-ten also einen Initialisierungswert verwenden, welcher auf keinen Fallmit einer Zufallszahl übereinstimmen kann (z.B. 0). Andernfalls kann esvorkommen, dass die Schleife kein einziges Mal ausgeführt wird. DieLösung ist daher recht anfällig für logische Fehler.

Page 216: Visual C# 2005 easy

Realisieren Sie ein Ratespiel 215

8 Beenden Sie nach einem erfolgreichen Rateversuch die for-Schleife unverzüglich:

static void Main(string[] args){ int glueck, tipp, i; Random zufallszahl = new Random(); glueck = zufallszahl.Next(1, 21); Console.WriteLine("\nRATESPIEL 1 aus 20\n"); for(i = 1; i < 4; i++) { Console.Write("Ihr {0}. Tipp: ", i); tipp = Convert.ToInt32(Console.ReadLine()); if(tipp == glueck) { Console.WriteLine("Richtig geraten!"); break; } if(tipp > glueck) Console.WriteLine("Zu groß"); if(tipp < glueck) Console.WriteLine("Zu klein"); }}

9 Tippen Sie nun selbst.

Vielleicht haben Sie Glück und treffen beim ersten oder zweiten Rateversuch.

Achtung

Der break-Befehl wird ausschließlich in Verbindung mit Schleifen oderder switch-Anweisung verwendet. Auf eine if-Anweisung entfaltetbreak keinerlei Wirkung. Im Beispiel ist also allein entscheidend, dassdie break-Anweisung innerhalb der for-Schleife steht. Allerdings ist eshier aus logischen Gründen von Bedeutung, die break-Anweisunggerade innerhalb des ersten if-Zweigs (if(tipp == glueck)) zuplatzieren.

Page 217: Visual C# 2005 easy

216 Kapitel 11

Abbildung 11.3: Das Ratespiel in Aktion mit einem Treffer beim zweiten Versuch

10 Sorgen Sie dafür, dass der Benutzer das Spiel beliebig oft wiederholen kann.

Dazu schachteln Sie eine weitere Wiederholungsanweisung um die for-Schleife. Hier bietet sich eine do-while-Schleife an. Beachten Sie, dass die An-weisung für die Erzeugung einer (neuen) Zufallszahl (glueck = zufalls-zahl.Next(1, 21);) ebenfalls von der Wiederholung umfasst sein muss.

Tipp

Es steht Ihnen frei, dem Benutzer nach drei vergeblichen Rateversuchendie Loszahl mitzuteilen. Fügen Sie die entsprechende Ausgabeanwei-sung in diesem Fall unterhalb der for-Schleife ein. Allerdings darf dieseAnweisung nur dann zur Ausführung gelangen, wenn die Bedingung(tipp != glueck) zutrifft:

} // end for if(tipp != glueck) { Console.WriteLine("Schade, die " + "Loszahl war {0}", glueck); }} // end Main()

Zusätzlich ist es jetzt notwendig, die Variable tipp mit einem Initialisie-rungswert zu versehen (z.B. 0), da Ihr Compiler ansonsten einen un-erlaubten Variablenzugriff vermutet.

Page 218: Visual C# 2005 easy

Realisieren Sie ein Ratespiel 217

static void Main(string[] args){ int glueck, tipp, i; char ch; Random zufallszahl = new Random(); do { glueck = zufallszahl.Next(1, 21); Console.WriteLine("\nRATESPIEL 1 aus 20\n"); for(i = 1; i < 4; i++) { Console.Write("Ihr {0}. Tipp: ", i); tipp = Convert.ToInt32(Console.ReadLine()); if(tipp == glueck) { Console.WriteLine("Richtig geraten!"); break; } if(tipp > glueck) Console.WriteLine("Zu groß"); if(tipp < glueck) Console.WriteLine("Zu klein"); } Console.Write("Weiterspielen? (j)a (n)ein "); ch = Convert.ToChar(Console.ReadLine()); } while(ch == 'j' || ch == 'J');}

Auf der CD-ROM

Diese Version des Programms finden Sie unter Beispiele/Konsolenpro-gramme auf der Buch-CD (Projektname K11d).

Hinweis

Bei verschachtelten Schleifenstrukturen bewirkt break; nur das Verlas-sen der inneren Schleife. In unserem Beispiel bricht zwar die for-Schleife mit dem break-Befehl ab, die Programmausführung verbleibtjedoch nach wie vor in der äußeren do-while-Schleife.

Page 219: Visual C# 2005 easy

218 Kapitel 11

Nun kann der Benutzer bei Eingabe des Zeichens j bzw. J und anschließen-dem (¢) das Spiel wiederholen.

Abbildung 11.4: Die endgültige Version des Ratespiels erlaubt es, das Spiel beliebig oft zu wiederholen

Page 220: Visual C# 2005 easy

Hätten Sie gedacht ... 219

Hätten Sie gedacht ...... dass man in früheren Programmierzeiten so genannte Warteschleifen ein-setzte, um ein Programm an bestimmten Stellen anzuhalten?

for(int i = 0; i < 1000000000; i++);

Bei den heutigen Prozessorgeschwindigkeiten haben solche Konstrukte aller-dings eher geringe Aussicht auf Erfolg. Komfortabler und genauer ist da schondie Sleep()-Methode von C#. Diese ist in der Klasse Thread im NamensraumThreading – dieser wiederum im Namensraum System – definiert. Um dieMethode ohne so genannten qualifizierten Zugriff (im vorliegenden Fall siehtdieser so aus: System.Threading.Thread.Sleep()) verwenden zu kön-nen, müssen Sie deshalb den Namensraum Threading mit der using-Direk-tive einbinden. Jetzt können Sie auf die Methode in kürzerer Schreibweisezugreifen. Beim Aufruf der Methode übergeben Sie dieser einfach die ge-wünschte Wartezeit in Millisekunden:

using System.Threading;// ...static void Main(string[] args){ // ... // Thread für 7 Sekunden anhalten Thread.Sleep(7000);

// ...}// ...

Probieren Sie doch beides mal aus! Ein kleines Beispiel mit der Sleep()-Methode finden Sie unter Beispiele/Konsolenprogramme auf der Buch-CD(Projektname K11e).

Page 221: Visual C# 2005 easy

Das können Sie schon:

Arbeiten mit Strings, Steuerzeichen 75

Variablen, Konstanten, Datentypen, Typkonvertierung 87

Verarbeiten von Benutzereingaben 103

Komplexe Ausdrücke und arithmetische Operatoren 139

Formatieren von Bildschirmausgaben 147

Einrichten von Programmverzweigungen 157

Vergleichsoperatoren und logische Operatoren 158

Prioritätsregeln für Operatoren 162

Schleifen 193

Gültigkeitsbereich und Lebensdauer von Variablen 202

Referenzvariablen 205

Das lernen Sie neu:

Verwalten größerer Datenmengen 221

Arrays definieren und initialisieren 222

Arrays mit for-Schleifen durchlaufen 224

Arrays sortieren 226

Die foreach-Schleife 227

Page 222: Visual C# 2005 easy

Kapitel 12

ArraysWenn Sie in Ihren Programmen größere Datenmengen verwalten müssen, erweist sich der ausschließliche Gebrauch von Variablen, wie Sie diese bisher verwendet haben, als sehr unhandlich. Bei 100 oder mehr Variablen verliert man im Quellcode schnell den Über-blick. Überdies müssten Sie dafür sorgen, dass sich die Variablenbe-zeichner voneinander unterscheiden. Außerdem ergibt sich in vielen Fällen erst zur Laufzeit, wie viele Datenelemente verarbeitet und ent-sprechend wie viele Variablen benötigt werden. Solche Aufgaben-stellungen sind mit gewöhnlichen Variablen nicht lösbar. Für derartige Fälle stellt C# spezielle Datenstrukturen zur Verfügung, so genannte Arrays. Diese erlauben es, eine nahezu unbegrenzte An-zahl von Werten gleichen Datentyps unter einem einzigen Bezeich-ner anzusprechen. In diesem Kapitel erfahren Sie nicht nur etwas über Arrays, sondern lernen auch eine weitere Schleifenart kennen, welche wir Ihnen bis jetzt vorenthalten haben und die in Verbindung mit Arrays gute Dienste leistet, die foreach-Schleife.

Page 223: Visual C# 2005 easy

222 Kapitel 12

Arrays definierenEin Array ist im Grunde eine Zusammenfassung von mehreren Variablen glei-chen Datentyps, welche im Speicher nebeneinander liegen. Der Name einesArrays bezeichnet dabei die Anfangsadresse des Bereichs, in dem die Datengespeichert sind.

Da es sich bei Arrays um Referenztypen handelt (siehe Kapitel 11, Abschnitt»Wertetypen und Referenztypen«), müssen Sie zunächst ein Array-Objekt an-legen. Den Verweis auf dieses weisen Sie einer Referenzvariablen zu. Mit fol-gender Anweisung vereinbaren Sie ein Array, in dem 100 Integer-Werteabgelegt werden können:

int[] myArr = new int[100];

Dabei bewirkt der Ausdruck new int[100] das Anlegen eines Arrays auf demHeap. Mit der Zahlenangabe legen Sie fest, wie viele Elemente (Variablen) dasArray haben soll.

Mit int[] myArr definieren Sie eine Referenzvariable zur Aufnahme desArray-Verweises.

Es sei hier noch einmal darauf hingewiesen, dass eine Referenzvariable nachder Zuweisung (hier: des Array-Verweises) so behandelt wird, als enthielte sie

Hinweis

Objekte auf dem Heap werden bei ihrer Vereinbarung automatisch initia-lisiert (entsprechend ihres Datentyps mit 0, 0.0 bzw. ""). Die Elementeeines Integer-Arrays besitzen also mit dessen Definition bereits denAnfangswert 0.

Achtung

Bei Angabe des Datentyps müssen Sie hinter das Schlüsselwort immerdie leeren eckigen Klammern [] setzen. Damit machen Sie deutlich,dass es sich um ein Array handelt (dass die Referenzvariable einen Ver-weis auf ein Array-Objekt aufnehmen soll);

int myVar; // Definition einer int-Variablenint[] myArr; // Definition einer Referenzvariablen // zur Aufnahme eines Array-Verweises

Page 224: Visual C# 2005 easy

Arrays definieren 223

das tatsächliche Objekt (Array). Wir werden deshalb im Folgenden so tun, alssei die Referenzvariable myArr das Objekt selbst.

Der Zugriff auf die einzelnen Array-Elemente erfolgt, indem Sie hinter den Be-zeichner des Arrays eine Indexangabe in eckige Klammern setzen. Der Indexbeginnt dabei bei 0.

Wenn Sie dem ersten Array-Element den Wert 99 zuweisen wollen, schreibenSie also

myArr[0] = 99;

und um das zweite Element mit dem Wert -29 zu versehen

myArr[1] = -29;

Um beispielsweise dem vierten Array-Element die Summe der im ersten undzweiten Element enthaltenen Werte zuzuweisen, lautet die entsprechendeZuweisung

myArr[3] = myArr[0] + myArr[1];

myArr[3] enthält danach den Wert 70.

Hinweis

Die oben genannte Vereinfachung (dass wir uns so verhalten, als hieltenwir mit der Referenzvariablen myArr das tatsächliche Objekt in Händen)wird hier in der Ausdrucksweise deutlich: »hinter den Bezeichner desArrays« müsste eigentlich lauten »hinter den Bezeichner der Referenz-variablen, welche einen Verweis auf das Array enthält«.

Achtung

Da die Indizierung bei 0 beginnt, ist der letzte gültige Index Elementzahlminus 1. Die Angabe myArr[99] stellt also den höchsten erlaubtenElementzugriff dar. Es wurde schließlich mit der Array-Definition nurPlatz für 100 Integer-Werte reserviert (welche an den Elementpositionen0 bis 99 abgelegt werden können). Der Ausdruck myArr[100] ist derVersuch, auf ein 101. Element zuzugreifen. Das Gefährliche an solchenunerlaubten Zugriffen liegt darin, dass sie vom Compiler nicht als Syn-taxfehler erkannt werden, sondern sich erst zur Laufzeit einstellen (Lauf-zeitfehler).

Page 225: Visual C# 2005 easy

224 Kapitel 12

Arrays mit der for-Schleife verwaltenArrays lassen sich bequem in for-Schleifen durchlaufen. Hierzu ein Beispiel.Der Benutzer wird dabei zur Eingabe mehrerer Zahlen aufgefordert, welche Sieanschließend in sortierter Reihenfolge ausgeben.

1 Legen Sie in Ihrer IDE ein neues Projekt an.

2 Fragen Sie den Benutzer, wie viele Werte er eingeben möchte:

static void Main(string[] args){ Console.Write("Wie viele Werte möchten" + " Sie eingeben? ");}

3 Speichern Sie die Antwort in einer int-Variablen anzahl:

static void Main(string[] args){ int anzahl; Console.Write("Wie viele Werte möchten" + " Sie eingeben? "); anzahl = Convert.ToInt32(Console.ReadLine());}

4 Definieren Sie ein Array mit anzahl Elementen.

Dabei machen Sie es sich zunutze, dass als Angabe für die Elementzahl einesArrays auch Variablenbezeichner stehen dürfen:

static void Main(string[] args){ int anzahl; Console.Write("Wie viele Werte möchten" + " Sie eingeben? "); anzahl = Convert.ToInt32(Console.ReadLine()); int[] ein = new int[anzahl];}

Nun müssen Sie dafür sorgen, dass die Benutzereingaben in dem Array einabgelegt werden.

Page 226: Visual C# 2005 easy

Arrays mit der for-Schleife verwalten 225

5 Setzen Sie eine for-Schleife auf.

Die Anzahl der Schleifendurchläufe muss der Elementzahl des Arrays entspre-chen. Es bietet sich an, die Index-Untergrenze 0 des Arrays als Startwert für dieLaufvariable zu wählen:

static void Main(string[] args){ int anzahl, i; Console.Write("Wie viele Werte möchten" + " Sie eingeben? "); anzahl = Convert.ToInt32(Console.ReadLine()); int[] ein = new int[anzahl]; for(i = 0; i < anzahl; i++) { }}

6 Nun müssen Sie das Array innerhalb der for-Schleife Element für Element durch-laufen. Verwenden Sie für die Indizierung der einzelnen Elemente die Laufvariable i:

static void Main(string[] args){ int anzahl, i; Console.Write("Wie viele Werte möchten" + " Sie eingeben? "); anzahl = Convert.ToInt32(Console.ReadLine()); int[] ein = new int[anzahl]; for(i = 0; i < anzahl; i++) { ein[i]; }}

Die Laufvariable i nimmt nun nacheinander alle ganzzahligen Werte von 0 bisanzahl - 1 an.

Hinweis

Um es noch einmal zu betonen: Genau genommen ist ein eine Referenz-variable, welche einen Verweis auf das eigentliche Array-Objekt enthält.Solche Referenzvariablen werden übrigens auch Array-Variablengenannt.

Page 227: Visual C# 2005 easy

226 Kapitel 12

7 Implementieren Sie die Eingabe der Werte und halten Sie diese im Array fest.

static void Main(string[] args){ int anzahl, i; Console.Write("Wie viele Werte möchten" + " Sie eingeben? "); anzahl = Convert.ToInt32(Console.ReadLine()); int[] ein = new int[anzahl]; for(i = 0; i < anzahl; i++) { Console.Write("{0}. Wert: ", i+1); ein[i] = Convert.ToInt32(Console.ReadLine()); }}

Nach Verlassen der for-Schleife sind die Eingabewerte im Array enthalten.Diese sollen nun vor der Ausgabe sortiert werden.

Arrays sortierenUm ein Array in aufsteigender Reihenfolge zu sortieren, verwenden Sie die Me-thode Sort() der Klasse Array. Als Parameter übergeben Sie dieser das zusortierende Array.

Um das Array ein zu sortieren, schreiben Sie also

Array.Sort(ein);

Achtung

Denken Sie daran, dass der letzte Index, für den der Anweisungsteil derfor-Schleife ausgeführt wird, anzahl - 1 (also 99 bei 100 Elementen)sein muss, was mit der Schleifenbedingung i < anzahl gewährleistetist. Wenn Sie versehentlich als Schleifenbedingung i <= anzahl wäh-len, bringt dies einen unerlaubten Array-Zugriff mit sich (z.B. ein[100]bei 100 Elementen).

Page 228: Visual C# 2005 easy

Die foreach-Schleife 227

8 Sortieren Sie die Zahlen in aufsteigender Reihenfolge:

static void Main(string[] args){ int anzahl, i; Console.Write("Wie viele Werte möchten" + " Sie eingeben? "); anzahl = Convert.ToInt32(Console.ReadLine()); int[] ein = new int[anzahl]; for(i = 0; i < anzahl; i++) { Console.Write("{0}. Wert: ", i+1); ein[i] = Convert.ToInt32(Console.ReadLine()); } Array.Sort(ein);}

Die foreach-SchleifeUm die einzelnen Werte des Arrays auszugeben, könnten Sie nun wiederumeine for-Schleife verwenden:

for(i = 0; i < anzahl; i++){ Console.Write(ein[i] + " ");}

Um ein Array im Lesezugriff zu durchlaufen, gibt es jedoch eine bequemereMöglichkeit, die foreach-Schleife:

foreach (Datentyp Bezeichner in Arrayname){ Anweisung(en)}

Hinweis

Um ein Array in absteigender Reihenfolge zu sortieren, rufen Sie imAnschluss an die Methode Sort() die Methode Reverse() auf:

Array.Reverse(ein);

Page 229: Visual C# 2005 easy

228 Kapitel 12

Bei Datentyp Bezeichner handelt es sich um die Definition einer Schleifenvari-ablen. Diese muss vom Datentyp der Array-Elemente sein. Allerdings fungiertdie Schleifenvariable nicht wie bei der for-Schleife als Zählvariable, sondernsie dient dazu, der Reihe nach die Werte des Arrays aufzunehmen. So be-kommt diese Variable nach Schleifeneintritt den Wert des ersten Elements zu-gewiesen. Nach Ausführung des Anweisungsteils erhält die Schleifenvariablefür den zweiten Durchlauf den Wert des zweiten Elements usw. Dies setzt sichso lange fort, bis das letzte Element erreicht ist. Auf diese Weise wird jedes Ar-ray-Element genau einmal »angefasst«. Dies erfolgt automatisch, ohne dassSie sich um die Indexgrenzen des Arrays kümmern müssen.

Im Schleifenblock kann die Variable dann verwendet werden. Zuweisungen andie Variable sind jedoch nicht gestattet. Das heißt, Sie können mit der fore-ach-Schleife ein Array nicht verändern, sondern nur lesend auf die Elementezugreifen.

Um die Werte Ihres Arrays auszugeben, schreiben Sie also

foreach (int x in ein){ Console.Write(x + " ");}

Achtung

Obwohl sich der Gültigkeitsbereich der Schleifenvariablen auf den Blockder foreach-Schleife beschränkt, dürfen Sie im übrigen Code derMain()-Methode keine gleichnamige Variable definieren (Syntaxfehler).

Page 230: Visual C# 2005 easy

Die foreach-Schleife 229

9 Geben Sie die sortierten Eingabezahlen aus:

static void Main(string[] args){ int anzahl, i; Console.Write("Wie viele Werte möchten" + " Sie eingeben? "); anzahl = Convert.ToInt32(Console.ReadLine()); int[] ein = new int[anzahl]; for(i = 0; i < anzahl; i++) { Console.Write("{0}. Wert: ", i+1); ein[i] = Convert.ToInt32(Console.ReadLine()); } Array.Sort(ein); Console.Write("\n Sortiert: "); foreach (int x in ein) { Console.Write(x + " "); }}

10 Testen Sie Ihr Programm.

Die eingegebenen Zahlen werden anschließend in sortierter Reihenfolge ange-zeigt.

Abbildung 12.1: Ausgabe der Werte in aufsteigender Reihenfolge

Auf der CD-ROM

Das Beispiel zu diesem Kapitel finden Sie unter Beispiele/Konsolenpro-gramme auf der Buch-CD (Projektname K12).

Page 231: Visual C# 2005 easy

230 Kapitel 12

Initialisieren von ArraysEs ist auch möglich, ein Array bereits beim Anlegen mit Werten zu versehen.Um beispielsweise ein Array yourArr mit den Werten 11, 22, 33, 44, 55 zu ini-tialisieren, schreiben Sie

int[] yourArr = {11, 22, 33, 44, 55};

Ihr Compiler erzeugt dann automatisch (ohne Angabe des Schlüsselworts new)ein Array-Objekt, dessen Elementzahl der Anzahl der angegebenen Werte ent-spricht.

Die obige Anweisung ist in ihrer Wirkung also äquivalent zu

int[] yourArr = new int[5];yourArr[0] = 11;yourArr[1] = 22;yourArr[2] = 33;yourArr[3] = 44;yourArr[4] = 55;

Im Allgemeinen wird man von dieser Möglichkeit aber nur bei kleineren Daten-mengen Gebrauch machen.

Page 232: Visual C# 2005 easy

Eine kleine Erfolgskontrolle 231

Eine kleine Erfolgskontrolle• Wo liegt der Fehler?

string[] names = new string[7];for(int i = 0; i <= 7; i++){ names[i] = Console.ReadLine();}

• Welchen Vorteil bietet die foreach-Schleife?

• Nennen Sie eine Einschränkung in Bezug auf die foreach-Schleife.

• Welche Anweisung können Sie im Quellcode verwenden, um ein Array mitdem Bezeichner myArr zu sortieren?

• Was bewirkt die folgende Anweisung?double[] numbers = {0.99, 22.3, 55.01, 17.78};

Page 233: Visual C# 2005 easy

Das können Sie schon:

Arbeiten mit Strings, Steuerzeichen 75

Variablen, Konstanten, Datentypen, Typkonvertierung 87

Verarbeiten von Benutzereingaben 103

Komplexe Ausdrücke und arithmetische Operatoren 139

Formatieren von Bildschirmausgaben 147

Programmverzweigungen und Schleifen 157

Vergleichsoperatoren und logische Operatoren 158

Prioritätsregeln für Operatoren 162

Gültigkeitsbereich und Lebensdauer von Variablen 202

Referenzvariablen 205

Arrays 221

Das lernen Sie neu:

Auslagern von Programmcode in Methoden 233

Methoden definieren und verwenden 234

Wie Methoden untereinander Informationen austauschen 238

Unterschied zwischen Wert- und Referenzübergabe 241

Rückgabewerte von Methoden festlegen 245

Page 234: Visual C# 2005 easy

Kapitel 13

MethodenBis jetzt haben Sie sich ausschließlich innerhalb der Methode »Main()« bewegt. Sie erweitern nun Ihren Aktionsradius, indem Sie eigene Methoden definieren und aufrufen. Damit lässt sich die Effizi-enz bei der Programmierung erheblich steigern. Zum einen können Sie in Ihrem Programm für mehrfach benötigte Teilaufgaben auf bereits fertige Routinen zurückgreifen. Zum anderen gestaltet sich die Codewartung einfacher. Von etwaigen nachträglich an einer Me-thode durchgeführten Verbesserungen und Korrekturen profitieren alle Teile Ihres Programms, die auf die entsprechende Methode zugreifen.

Page 235: Visual C# 2005 easy

234 Kapitel 13

Methoden definierenEine Methode kann erst dann verwendet werden, wenn sie definiert ist. DieKlassen des .NET Framework stellen Ihnen eine Vielzahl von fertigen Methodenzur Verfügung. Auf diese Methoden können Sie direkt zugreifen, also ohne die-se erst definieren zu müssen.

Sie können ebenso eigene Methoden erstellen. Zu diesem Zweck schreiben Siedie entsprechende Definition in Ihren Quellcode. Im Weiteren können Sie Ihreeigenen Methoden dann genauso verwenden wie die vordefinierten.

Eine Methodendefinition kennen Sie bereits, die der Methode Main(). Wie Siebereits im Zusammenhang mit Main() erfahren haben, besteht auch jede an-dere Methode aus einem Methodenkopf und einem Methodenrumpf. In Letzte-rem befinden sich die Anweisungen.

Beschäftigen wir uns nun damit, wie der Methodenkopf auszusehen hat. Zu-nächst benötigt jede Methode einen Bezeichner, durch den sie eindeutig iden-tifiziert werden kann. Wie Sie wissen, sind Bezeichner unter Beachtung der inKapitel 7 (Abschnitt »Variablendefinition«) genannten Regeln frei wählbar.Dies gilt natürlich auch für die Bezeichner von Methoden, mit Ausnahme vonMain(). Dieser Bezeichner ist vorgegeben, da die Methode Main() bei Pro-grammausführung den Einstiegspunkt bildet.

Wenn Sie eine Methode definieren, die eine genau festgelegte Bildschirmaus-gabe bewirken soll, dann können Sie den Methodenkopf von Main() bis aufden Bezeichner erst einmal übernehmen.

Nehmen wir eine Methode, die beim Aufruf die Ausgabe ***** erzeugt (ohneanschließenden Zeilenvorschub). Als Bezeichner für die Methode wählen wirSternAus. Dann lautet der Methodenkopf

static void SternAus()

und somit das Grundgerüst der Methodendefinition

static void SternAus(){}

Page 236: Visual C# 2005 easy

Methoden definieren 235

Genau genommen handelt es sich hier bereits um eine vollständige Methoden-definition. Allerdings bewirkt diese Methode beim Aufruf rein gar nichts. Siemüssen natürlich noch entsprechende Anweisungen in den Methodenblockschreiben. Zur Ausgabe von fünf * ist es mit der Anweisung Console.Write("*****"); getan, also

static void SternAus(){ Console.Write("*****");}

Damit ist die Definition der Methode SternAus() abgeschlossen.

1 Legen Sie ein neues Projekt an.

2 Schreiben Sie die Methodendefinition von SternAus() in die Klasse Program.

Dabei spielt es keine Rolle, ob Sie die Methode oberhalb oder unterhalb vonMain() in den Quelltext schreiben. Wichtig ist nur, dass sich die Methoden-definition im Block von Program befindet:

class Program{ static void Main(string[] args) { }

static void SternAus() { Console.Write("*****"); }}

Achtung

Verschachtelte Methodendefinitionen sind nicht erlaubt. Sie dürfen eineMethode nicht im Block einer anderen Methode definieren.

Page 237: Visual C# 2005 easy

236 Kapitel 13

Methoden verwendenWie rufen Sie die Methode SternAus() nun auf? Im Prinzip genauso wie z.B.die Methode ReadLine(), also mit dem Methodennamen gefolgt von rundenKlammern. Natürlich darf das abschließende Semikolon nicht fehlen, da essich bei einem reinen Methodenaufruf schließlich ebenfalls um eine Anwei-sung handelt:

SternAus();

Nun stellt sich grundsätzlich die Frage, wo ein Methodenaufruf im Quellcodezu notieren ist. Dabei ist zu berücksichtigen, dass die Programmausführungimmer in Main() beginnt. Wenn Sie also wollen, dass eine Methode (genauer:die Anweisungen, welche im Block der betreffenden Methode stehen) unmit-telbar nach Programmstart ausgeführt wird, dann setzen Sie den Aufruf an denAnfang von Main().

3 Rufen Sie die Methode SternAus() in Main() auf:

class Program{ static void Main(string[] args) { SternAus(); }

static void SternAus() { Console.Write("*****"); }}

4 Überzeugen Sie sich vom Ergebnis.

Auf dem Bildschirm sollte nun die Ausgabe ***** erscheinen.

Die Wirkung ist dieselbe, als ob die Anweisung Console.Write("*****");in Main() stünde. Tatsächlich geschieht Folgendes, wenn ein Methodenaufrufwährend des Programmlaufs zur Ausführung gelangt:

• Die Abarbeitung der Anweisungen der aufrufenden Methode wird vorüber-gehend angehalten.

• Es erfolgt ein Sprung in die aufgerufene Methode. Dort werden die Anwei-sungen, welche im Rumpf dieser Methode stehen, ausgeführt.

Page 238: Visual C# 2005 easy

Methoden verwenden 237

• Mit Abarbeitung der letzten Anweisung der aufgerufenen Methode wirddiese beendet. Das heißt, der Methodenblock der aufgerufenen Methodewird endgültig verlassen.

• Es erfolgt ein Rücksprung zur aufrufenden Methode an die Stelle, welchedem Methodenaufruf (gemeint ist die entsprechende Anweisung) unmit-telbar folgt.

Der Vorteil, bestimmte Anweisungen in Methoden auszulagern, ergibt sich ausder Tatsache, dass Sie die in einem Methodenblock stehenden Anweisungenbei Bedarf immer wieder zur Ausführung bringen können. Sie benötigen dafürnur eine Programmierzeile für den Methodenaufruf.

Um z.B. die Ausgabe

*****START*****

zu erzeugen, können Sie die Methode SternAus() in Main() zwei Mal ver-wenden:

static void Main(string[] args){ SternAus(); Console.WriteLine("\nSTART"); SternAus();}

Obwohl Methoden nicht innerhalb anderer Methoden definiert werden dürfen,ist es dennoch möglich, diese verschachtelt aufzurufen. Das heißt Main()könnte eine Methode A aufrufen, welche wiederum eine Methode B aufruftusw. Beachtenswert ist, dass eine solche Kette immer in der Methode Main()

Hinweis

Statt aufrufende Methode gebraucht man auch die Bezeichnung aufru-fende Umgebung oder einfach Aufrufer.

Tipp

Stellen Sie sich Methoden als eigenständige Programmteile vor, auf dieSie bei Bedarf immer wieder zurückgreifen können.

Page 239: Visual C# 2005 easy

238 Kapitel 13

in Gang gesetzt werden muss. Denn während alle anderen Methoden explizitmittels Anweisung (Methodenaufruf ) gestartet werden, geschieht dies mit derMethode Main() automatisch zu Beginn der Programmausführung.

In der Praxis wird man sich des Verfahrens, Code in Methoden auszulagern, vorallem dann bedienen, wenn es sich um fest umrissene Teilaufgaben handelt,z.B. die Durchführung komplexer Berechnungen. Auch ist davon auszugehen,dass im Methodenrumpf nicht nur eine, sondern in der Regel mehrere Anwei-sungen zusammengefasst sind.

Allerdings spielt auch die Häufigkeit des Gebrauchs eine gewisse Rolle. WennSie in Ihren Programmen häufig Sternchenreihen zur Anzeige bringen, dann istes durchaus sinnvoll, diese Ausgabe als Methode einzurichten. Vermutlichwürde Sie die Methode SternAus() in dieser Form jedoch nicht ganz zufrie-den stellen. Wenn Sie beispielsweise die Ausgabe

**********************Willkommen im Programm**********************

erzeugen möchten, dann verfügen Sie mit der Methode SternAus() nichtüber eine praxistaugliche Lösung. Diese bewirkt bekanntlich die Ausgabe vonkonstant fünf Sternchen. Sie könnten diese Methode natürlich zwei Mal ver-wenden, um z.B. zehn Sternchen auf den Bildschirm zu bringen, müssten dieAusgabe dann aber entsprechend anpassen, falls etwa 13 Sternchen er-wünscht sind. In diesem Fall wäre es effizienter, auf die Methode SternAus()zu verzichten und die Ausgabe auf herkömmliche Weise mit Write() vorzu-nehmen.

Wenn es Ihnen jedoch gelingt, die Methode SternAus() flexibel zu gestalten,dann wird sie sich für den genannten Zweck als durchaus nützlich erweisen.

ParameterübergabeBeachten Sie, dass die Methode SternAus() in der aktuellen Fassung keinerInformationen von außen bedarf. Sie »weiß« auch so, was sie zu tun hat, näm-lich genau fünf Sternchen auszugeben.

Sie werden die Methode nun aber so einrichten, dass Sie ihr beim Aufruf mit-teilen können, wie viele Sternchen sie ausgeben soll und zwar in der Weise,dass z.B. der Methodenaufruf

SternAus(10);

Page 240: Visual C# 2005 easy

Parameterübergabe 239

die Methode veranlasst, zehn Sternchen auszugeben. Dazu müssen Sie dieMethodendefinition entsprechend anpassen.

Sorgen Sie zunächst dafür, dass die Methode einen Integer-Wert aufnehmenkann. Wie Ihnen bekannt ist, benötigt man für das Festhalten eines Werts imCode eine Variable, im vorliegenden Falle eine vom Typ int. Variablen, welchebeim Methodenaufruf Übergabewerte erhalten sollen, definieren Sie im Kopfder Methode und zwar zwischen den runden Klammern. Wenn Sie für Ihre Va-riable den Bezeichner anz (steht für Anzahl der gewünschten Sternchen) wäh-len, dann sieht Ihre Methode erst einmal wie folgt aus:

static void SternAus(int anz){ Console.Write("*****");}

Einige Begriffserklärungen:

• Die Variablendefinitionen bzw. Variablen bezeichnet man als Parameterder Methode. Um sie von den Übergabewerten des Methodenaufrufs zuunterscheiden, spricht man auch von formalen Parametern.

• Die Gesamtheit der in Klammern angegebenen formalen Parameter heißtParameterliste.

• Die Werte, welche eine Methode beim Aufruf bekommt, werden Übergabe-werte, Argumente, (Übergabe-)Parameter oder präziser aktuelle Parame-ter genannt.

Allerdings nimmt die Methode SternAus() in der obigen Form den Übergabe-wert zwar entgegen, verarbeitet diesen aber nicht im Anweisungsteil. Dies er-gibt natürlich wenig Sinn.

Hinweis

Wenn Sie eine Methode so einrichten wollen, dass sie beim Aufruf meh-rere Werte erhalten soll, dann trennen Sie die formalen Parameter (Vari-ablendefinitionen) durch Kommata voneinander. Dabei dürfen dieeinzelnen Parameter auch unterschiedlichen Datentyps sein:

static void Methodenname(int a, double b, string c){ …}

Page 241: Visual C# 2005 easy

240 Kapitel 13

Sie müssen die Methode nun so einrichten, dass auch das gewünschte Ergeb-nis zustande kommt, wenn sie aufgerufen wird. Dabei sorgen Sie mit einerfor-Schleife dafür, dass die Anweisung Console.Write("*"); (Ausgabe ei-nes Sternchens) entsprechend oft wiederholt wird. Die Wiederholungszahlmuss sich dabei nach dem Übergabewert richten:

static void SternAus(int anz){ for(int i = 1; i <= anz; i++) Console.Write("*");}

Mit der Schleifenbedingung (i <= anz) und dem Startwert der Laufvariableni legen Sie fest, dass die Anweisung Console.Write("*"); genau anz Malausgeführt wird. Die Methode wird also beim Aufruf dem Übergabewert ent-sprechend viele Sternchen ausgeben.

5 Ändern Sie die Methodendefinition von SternAus() wie beschrieben und testen Sie die Methode in Main():

class Program{ static void Main(string[] args) { Console.WriteLine(); SternAus(10); Console.WriteLine("\nKapitel 13"); SternAus(10); Console.WriteLine(); for(int i = 9;i > 0; i--) { SternAus(i); Console.WriteLine(); } }

static void SternAus(int anz) { for (int i = 1; i <= anz; i++) Console.Write("*"); }}

Page 242: Visual C# 2005 easy

Parameterübergabe 241

6 Bringen Sie das Programm zur Ausführung.

Sie werden feststellen, dass die Methode SternAus() nun wie gewünscht ar-beitet. Wenn Sie die obige Main()-Methode übernommen haben (ein einfa-cherer Test hätte es natürlich auch getan), erhalten Sie die in der Abbildungdargestellte Ausgabe.

Abbildung 13.1: Aufruf der Methode »SternAus()« mit der Anzahl der auszugebenden Sternchen aus einer Schleife heraus

Call by valueBeachten Sie, dass die Methoden Main() und SternAus() zwei getrennteGültigkeitsbereiche beschreiben (siehe Kapitel 11, Abschnitt »Gültigkeitsbe-reich von Variablen«). Das heißt, lokale Variablen der einen Methode sind inder anderen nicht bekannt. Somit wäre der Fall denkbar, dass in beiden Metho-den eine Variable anz definiert ist (mit anderen Worten: ... dass jede Methodeihre eigene Variable anz besitzt).

Hinsichtlich der Lebensdauer lokaler Variablen gilt: Sobald ein Methodenblockendgültig verlassen wird, werden die lokalen Variablen dieser Methode ge-löscht (bei den formalen Parametern handelt es sich ebenfalls um lokale Vari-ablen). Die Variable anz wird also mit jedem Verlassen der MethodeSternAus() gelöscht und mit jedem Aufruf dieser Methode neu angelegt.

Auf der CD-ROM

Das Beispiel finden Sie unter Beispiele/Konsolenprogramme auf derBuch-CD (Projektname K13a).

Page 243: Visual C# 2005 easy

242 Kapitel 13

Beendet ist eine Methode, wenn die letzte Anweisung im Methodenrumpf ab-gearbeitet ist.

Halten wir noch einmal fest, was bei der obigen Parameterübergabe geschieht:

• Beim Aufruf der Methode SternAus() wird ein Integer-Wert übergeben.

• In der aufgerufenen Methode entsteht eine Variable (anz).

• Die Variable anz bekommt den Übergabewert zugewiesen.

Nun ist es möglich, dass beim Methodenaufruf als Argument ein Variablen-bezeichner auftritt, z.B. SternAus(zahl); (wobei zahl eine zuvor definierteund zugewiesene Variable vom Datentyp int sei). Dies sollte nichts Neues fürSie sein, da Sie wissen, dass überall, wo im Quellcode ein Wert stehen muss,dieser auch aus einer Variablen herausgelesen werden kann.

Lassen Sie uns nun klären, was mit einer im Aufruf bezeichneten Variablen ge-schieht, wenn der Formalparameter im Rumpf der aufgerufenen Methode ver-ändert wird. Zur Demonstration definieren wir eine Variable anz auch inMain() und verwenden diese dann beim Aufruf von SternAus().

class Program{ static void Main(string[] args) { int anz = 7; SternAus(anz); Console.WriteLine("In Main(): " + anz); }

static void SternAus(int anz) { anz = 55; Console.WriteLine("In SternAus(): " + anz); }}

Auf der CD-ROM

Das Beispiel finden Sie unter Beispiele/Konsolenprogramme auf derBuch-CD (Projektname K13b).

Page 244: Visual C# 2005 easy

Parameterübergabe 243

Nach dem weiter oben Dargelegten müsste Ihnen klar sein, dass …

• sowohl die Methode SternAus() als auch die Methode Main() eineeigene Variable anz besitzt,

• durch den Methodenaufruf SternAus(anz); die Variable anz vonMain() nicht als solche der Methode SternAus() bekannt gemacht wird.Der Methode SternAus() wird lediglich eine Kopie des in der Variablen(anz von Main()) enthaltenen Werts übergeben.

• die Zuweisung im Block von SternAus() (anz = 55;) an die Variable anzdieser Methode erfolgt, was jedoch keine Auswirkung auf die Variable anzder Methode Main() hat. Das heißt, die Variable anz der Methode Main()wird durch diese Zuweisung nicht verändert.

Wenn Sie obiges Programm kompilieren und ausführen, erhalten Sie daher diefolgende Ausgabe:

In SternAus(): 55In Main(): 7

Diese Form der Parameterübergabe wird Call by value oder schlicht Wertüber-gabe genannt.

Call by referenceBeachten Sie, dass die Form der Parameterübergabe nur relevant ist für denFall, dass …

• beim Methodenaufruf als Argument kein Literal, sondern der Bezeichnereiner Variablen verwendet wird,

• im Methodenrumpf der aufgerufenen Methode Zuweisungen an den ent-sprechenden Formalparameter erfolgen, dieser also tatsächlich verändertwird.

Wenn Sie nun beim Methodenaufruf einen Referenztyp verwenden, dann wirdein Verweis auf ein Datenobjekt übergeben. Damit wird das tatsächliche Da-tenobjekt der aufgerufenen Methode bekannt gemacht. Das bedeutet, Aufru-fer und aufgerufene Methode arbeiten mit demselben Objekt. Veränderungen,welche im Rumpf der aufgerufenen Methode stattfinden, besitzen also dauer-hafte Wirkung. Diese Art der Parameterübergabe wird Referenzübergabe bzw.Call by reference genannt.

In folgendem Beispiel werden beim Aufruf der Methode ZuNull() alle Ele-mente des Arrays myArr auf den Wert 0 gesetzt. Der Methode sind beim Aufrufentsprechend ihrer Definition zwei Argumente zu übergeben, ein Verweis aufein Array-Objekt und ein Integer-Wert, welcher für die Array-Obergrenze steht:

Page 245: Visual C# 2005 easy

244 Kapitel 13

class Program{ static void Main(string[] args) { int[] myArr = {33, 44, 55, 66, 77}; Console.Write("Vor ZuNull(): "); for(int i = 0; i < 5; i++) Console.Write(myArr[i] + " "); ZuNull(myArr, 4); Console.Write("\nNach ZuNull(): "); for(int i = 0; i < 5; i++) Console.Write(myArr[i] + " "); }

static void ZuNull(int[] arr, int ogrenze) { for(int i = 0; i <= ogrenze; i++) arr[i] = 0; }}

Ausgabe:

Vor ZuNull(): 33 44 55 66 77Nach ZuNull(): 0 0 0 0 0

Die Ausgabe beweist, dass das Array von der Methode ZuNull() nachhaltigverändert worden ist.

Wenn Sie möchten, dass auch Wertetypen per Call by reference übergebenwerden, müssen Sie in der Methodendefinition vor dem Datentyp des entspre-chenden Formalparameters und später im Aufruf das Schlüsselwort ref ange-ben:

class Program{ static void Main(string[] args) { int z1 = 109, z2 = 77;

Console.WriteLine("\nVor dem Tausch: "

Auf der CD-ROM

Das Beispiel finden Sie unter Beispiele/Konsolenprogramme auf derBuch-CD (Projektname K13c).

Page 246: Visual C# 2005 easy

Rückgabewerte von Methoden 245

+ "z1 = {0}, z2 = {1}", z1, z2); Tausche(ref z1, ref z2); Console.WriteLine("Nach dem Tausch: " + "z1 = {0}, z2 = {1}", z1, z2); }

static void Tausche(ref int a, ref int b) { int temp = a; a = b; b = temp; }}

Ausgabe:

Vor dem Tausch: z1 = 109, z2 = 77

Nach dem Tausch: z1 = 77, z2 = 109

Der Aufruf von Tausche() in Main() bewirkt hier, dass die Werte der Variab-len z1 und z2 miteinander vertauscht werden.

Rückgabewerte von MethodenMit den Methoden, die wir in diesem Kapitel definiert und verwendet haben,erfolgte die Kommunikation allenfalls in eine Richtung. Das heißt, die Metho-den wurden beim Aufruf mit Informationen versorgt, es wurden aber keine Da-ten an den Aufrufer zurückgegeben. Wie man Rückgabewerte von Methodenverarbeitet, wissen Sie bereits. Nun erfahren Sie, wie man Methoden so defi-niert, dass sie einen Rückgabewert liefern.

Folgende Methode berechnet die dritte Potenz eines zu übergebenden doub-le-Werts und gibt das Ergebnis auf den Bildschirm aus:

static void Pot3(double betrag){ Console.WriteLine(betrag * betrag * betrag);}

Auf der CD-ROM

Das Beispiel finden Sie unter Beispiele/Konsolenprogramme auf derBuch-CD (Projektname K13d).

Page 247: Visual C# 2005 easy

246 Kapitel 13

Diese Methode schränkt den Programmierer jedoch sehr ein, da jeder Aufrufautomatisch mit einer Bildschirmausgabe verbunden ist. Manchmal ist daszwar sicherlich beabsichtigt. In der Mehrzahl der Fälle wird man sich aber vondieser Methode allein das Berechnungsergebnis wünschen, ohne Bildschirm-anzeige. Andernfalls ist es nicht möglich, den Rückgabewert einer Methode ineinem komplexen Ausdruck weiterzuverarbeiten. Bei Bedarf kann der Pro-grammierer den Rückgabewert (das Berechnungsergebnis) in der aufrufendenMethode immer noch mit Write() bzw. WriteLine() zur Anzeige bringen.

Um in der Methodendefinition einen Rückgabewert festzulegen, gehen Sie wiefolgt vor:

• Schreiben Sie das Schlüsselwort für den Datentyp des Rückgabewerts vorden Bezeichner der Methode.

• Sie müssen es im Methodenrumpf so einrichten, dass die zuletzt ausge-führte Anweisung der Methode der return-Befehl ist. Hinter dem Schlüs-selwort return geben Sie den Rückgabewert an. Dieser kann durch einenbeliebigen Ausdruck des Datentyps repräsentiert werden, den Sie imMethodenkopf angegeben haben. Das heißt natürlich, dass hier auch einLiteral oder ein Variablenbezeichner stehen darf (siehe Kapitel 9, Abschnitt»Ausdrücke und arithmetische Operatoren«).

Um die Methode Pot3() mit Rückgabewert – und ohne Bildschirmausgabe –einzurichten, schreiben Sie also wie folgt:

static double Pot3(double betrag){ return betrag * betrag * betrag;}

Das Gesagte gilt allerdings nur für Methoden, welche tatsächlich einen Rück-gabewert besitzen. Für Methoden ohne Rückgabewert gilt:

• Vor dem Methodenbezeichner muss das Schlüsselwort void stehen (void,engl. leer).

• Die Verwendung des return-Befehls ist optional. Auf keinen Fall darf demSchlüsselwort return eine Wertangabe folgen (es ist also return; zuschreiben).

Hinweis

Die Bedeutung des Schlüsselworts static werden Sie im nächstenKapitel erfahren.

Page 248: Visual C# 2005 easy

Rückgabewerte von Methoden 247

Im Weiteren können Sie die Methode Pot3() verwenden wie jede andere Me-thode (mit Rückgabewert) auch. Denken Sie daran, dass ein Methodenaufrufim Code gleichzeitig für den Rückgabewert der betreffenden Methode steht(siehe Kapitel 7, Abschnitt »Die Methode ReadLine()«). Ein Aufruf der MethodePot3() repräsentiert sogar ausschließlich ihren Rückgabewert, da die Metho-de sonst keine weiteren Aktionen durchführt.

Hier ein Beispiel, in dem die Methode Pot3() verwendet wird:

class Program{ static double Pot3(double betrag) { return betrag * betrag * betrag; }

static void Main(string[] args) { double zahl, kubik; Console.Write("Eingabe: "); zahl = Convert.ToDouble(Console.ReadLine()); kubik = Pot3(zahl); Console.WriteLine("Kubikzahl: {0:N}", kubik); }}

Hinweis

Tatsächlich entsteht beim Verlassen einer Methode gegebenenfalls einetemporäre, namenlose Variable zur Aufnahme des Rückgabewerts(daher ist auch die Datentypangabe im Methodenkopf notwendig). Diesewird mit der nächsten Anweisung sofort wieder gelöscht. Um den Rück-gabewert in der aufrufenden Umgebung dauerhaft festzuhalten, müssenSie diesen daher sogleich einer Variablen zuweisen:

myDouble = Pot3(9.5);

Auf der CD-ROM

Das Beispiel finden Sie unter Beispiele/Konsolenprogramme auf derBuch-CD (Projektname K13e).

Page 249: Visual C# 2005 easy

248 Kapitel 13

Im Beispiel wird der Rückgabewert von Pot3() in der Variablen kubik gespei-chert und diese dann für die Ausgabe herangezogen. Allerdings könnten Siehier den Rückgabewert auch gleich in der Ausgabe verwenden:

Console.WriteLine("Kubikzahl: {0:N}", Pot3(zahl));

Wenn Sie beim Programmlauf z.B. 19 eingeben, erhalten Sie die Ausgabe6.859,00.

Abbildung 13.2: Berechnung der dritten Potenz über die selbst definierte Methode »Pot3()«

Hinweis

Natürlich können Sie die Methode Pot3() auch in einem komplexenAusdruck wie z.B. 2 * (Pot3(4.5) + 10) verwenden.

Page 250: Visual C# 2005 easy

Eine kleine Erfolgskontrolle 249

Eine kleine Erfolgskontrolle• Wann spricht man beim Methodenaufruf von Call by value?

• Was bedeutet Call by reference?

• Welches Schlüsselwort muss im Kopf einer Methode auf jeden Fall verwen-det werden, wenn die Methode ohne Rückgabewert definiert ist?

• Was können Sie anhand des folgenden Methodenkopfs über die Methodexy() aussagen?static int xy(double a, string b)

• Welche Ausgabe erzeugt folgendes Programm?class Program{ static void B(string myString) { Console.Write(myString); }

static void Main(string[] args) { A(); Console.WriteLine("weiter"); }

static void A() { Console.Write("Jetzt "); B("geht es "); }}

• Finden Sie den Fehler in folgender Methodendefinition:static void Quad(int a){ Console.WriteLine("Das Quadrat von {0} ist {1}" , a, a * a); return "ENDE";}

Page 251: Visual C# 2005 easy

Das können Sie schon:

Arbeiten mit Strings, Steuerzeichen 75

Variablen, Konstanten, Datentypen, Typkonvertierung 87

Verarbeiten von Benutzereingaben 103

Komplexe Ausdrücke, Operatoren, Operatorpriorität 139

Formatieren von Bildschirmausgaben 147

Programmverzweigungen und Schleifen 157

Gültigkeitsbereich und Lebensdauer von Variablen 202

Referenzvariablen 205

Arrays 221

Methoden definieren und verwenden 234

Das lernen Sie neu:

Klassen definieren 254

Im Code Objekte von Klassen erzeugen 258

Mit Objekten arbeiten 259

Konstruktoren und Destruktoren 267

Bedeutung von static-Elementen 272

Page 252: Visual C# 2005 easy

Kapitel 14

Klassen und ObjekteDas Konzept der objektorientierten Programmierung erlaubt es, Ob-jekte einer realen oder gedachten Wirklichkeit in Ihren Programmen abzubilden. Die objektorientierte Programmierung kommt der menschlichen Denkweise näher als herkömmliche Programmierung und bietet weitere Vorteile, etwa was Wartungsaufwand, Stabilität und Codetransparenz angeht. In diesem Kapitel ist es nun so weit. Jetzt dreht sich alles um Klassen und Objekte. Das Verständnis für die objektorientierte Programmierung braucht erfahrungsgemäß etwas Zeit. Nehmen Sie sich diese und lassen Sie sich bei anfänglichen Schwierigkeiten nicht entmutigen. Mit fortschreitender Übung wer-den Ihnen die Vorteile der objektorientierten Programmierung nach und nach deutlich werden.

Page 253: Visual C# 2005 easy

252 Kapitel 14

VorüberlegungenFür das Verständnis der OOP (Abkürzung für »objektorientierte Programmie-rung«) ist es sehr wichtig, zwischen Datentypen und Datenobjekten zu diffe-renzieren.

• Ein Datenobjekt (dies kann auch eine Variable sein) bezeichnet einenreservierten Platz im Arbeitsspeicher, an dem Informationen abgelegt wer-den können.

• Ein Datentyp charakterisiert ein Datenobjekt, indem er festlegt, wie vielPlatz dieses im Arbeitsspeicher beansprucht bzw. welche Art von Werten ineinem Datenobjekt dieses Typs abgelegt werden können. Ferner, und diesist für das Verständnis der OOP sehr bedeutsam, bestimmt ein Datentyp,welche Operationen sich auf Daten dieses Typs ausführen lassen.

Beispielsweise ist es möglich, Zeichenketten miteinander zu verknüpfen. An-ders sieht es in Verbindung mit Strings dagegen mit Rechenoperationen aus:Diese sind nicht zulässig. Mit anderen Worten: Die Zugehörigkeit eines Daten-objekts zu einem bestimmten Datentyp sagt aus, welche Operationen mit denDaten durchführbar sind. Mit »Daten« sind die an der Speicherstelle (demDatenobjekt) abgelegten Informationen (Werte) gemeint.

Eine Klassendefinition enthält sowohl Datenelemente als auch Methoden, diefestlegen, welche Aktionen mit diesen Datenelementen durchgeführt werdenkönnen. Die Klassendefinition beschreibt somit einen eigenen Datentyp, legtalso fest, wie sich zukünftige Objekte vom Typ dieser Klasse verhalten.

Hinweis

Die Welt der objektorientierten Programmierung und speziell die von C#und dem .NET hat ihre eigene Sprache. Datenobjekte einer Klasse wer-den nicht Variablen, sondern Objekte bzw. Instanzen dieser Klassegenannt. Dagegen bezeichnet man die in einer Klasse definierten Daten-elemente in C# als »Felder« – und nicht etwa als »Eigenschaften« wie inanderen Programmiersprachen (der Begriff Eigenschaften ist in C# fürspezielle Methoden vorgesehen).

Page 254: Visual C# 2005 easy

Vorüberlegungen 253

Eine Klassendefinition ist damit sozusagen der Bauplan für Objekte dieserKlasse, genauso wie etwa der Datentyp double die Schablone für zukünftigeVariablen dieses Typs darstellt.

Entwerfen wir gedanklich eine Klasse Rechteck. Ein Rechteck lässt sich an-hand seiner Länge und Breite für die meisten Zwecke ausreichend beschrei-ben. Also definieren wir in der Klasse ein Datenelement (ein Feld) für die Längeund eines für die Breite. Als Bezeichner für die beiden Felder wählen wirLaenge und Breite. Nun überlegen wir, welche Operationen (Methoden) dieKlasse Rechteck mit ihren Datenelementen (den Feldern) ermöglichen soll.Wir entscheiden uns für eine Operation zum Berechnen der Rechtecksflächesowie eine Operation, welche diese nicht nur berechnet, sondern auch aus-gibt. Die Methoden nennen wir BerechneFlaeche() und ZeigeFlaeche().

Somit besitzt jedes Objekt dieser Klasse (oder vereinfacht ausgedrückt: »jedesRechteck«), das Sie später im Code erzeugen, die Felder Laenge und Breitesowie die Methoden BerechneFlaeche() und ZeigeFlaeche().

Bedenken Sie, dass jedes Rechteck-Objekt seine eigenen Attribute (Felder)und gewissermaßen auch seine eigenen Methoden besitzt. So ist z.B. das eineObjekt 20 cm lang und 11 cm breit. Dann gibt die Methode ZeigeFlaeche()den Wert 220 aus. Für ein Rechteck, welches z.B. 5 cm lang und 10 cm breit ist,bringt die Methode ZeigeFlaeche() dagegen den Wert 50 zur Anzeige. Alsomuss jede Methode (hier: ZeigeFlaeche()) die speziellen Attribute (Laen-ge: 5, Breite: 10) ihres Objekts kennen.

Hinweis

Eine Klassendefinition stellt in der Regel die programmiersprachlicheWiedergabe eines realen Gebildes dar. Da die Felder die Eigenschaftenzukünftiger Objekte beschreiben, erscheint der ursprünglich in der OOPverwendete Begriff Eigenschaft bzw. Attribut für ein Datenelement tref-fender. Dies wird deutlich, wenn man sagt: »ein Objekt der KlasseRechteck besitzt die Eigenschaften Laenge und Breite«. Geht manvon der C#-Terminologie aus, so ist jedoch zumindest der Begriff Eigen-schaft in diesem Zusammenhang nur im landläufigen Sinne zu verste-hen. Im fachsprachlichen Sinne sind Eigenschaften in C# spezielleMethoden für den Zugriff auf Felder (dazu später mehr).

Page 255: Visual C# 2005 easy

254 Kapitel 14

Beachten Sie, dass die bloße Definition einer Klasse noch keinerlei Auswirkun-gen nach sich zieht. Damit steht lediglich ein neuer Datentyp zur Verfügung.Erst wenn der Programmierer im Code Objekte dieses Datentyps (der Klasse)erzeugt, können die Felder und Methoden der Klasse genutzt werden.

Nehmen wir zum Vergleich den Datentyp int. Seine bloße Existenz hat nochkeine Auswirkung auf Ihre Programme. Dies ändert sich, sobald Sie im CodeVariablen dieses Typs definieren. Dann bestimmt der Bauplan int, wie sichdiese Variablen verhalten. So kann eine Integer-Variable nur ganzzahlige Wer-te aufnehmen. Die Variable darf z.B. als Operand an einer arithmetischen Ope-ration beteiligt sein, was etwa bei einer char-Variablen nicht der Fall ist.

KlassendefinitionSie werden nun eine Klasse Rechteck, wie sie oben beschrieben ist, definie-ren.

1 Legen Sie in Ihrer IDE ein neues Projekt an.

Eine Klassendefinition wird durch das Schlüsselwort class und einen Be-zeichner für die Klasse eingeleitet. Dem schließt sich der Klassenblock an:

class Rechteck{}

2 Fügen Sie Ihrem Projekt eine neue Klasse mit dem Bezeichner Rechteck hinzu.

Sie könnten dazu nun im Code der Quelldatei Program.cs die neue Klasse ent-weder oberhalb oder unterhalb der Klasse Program aufsetzen. Übersichtlicherund bequemer ist es aber, die Klasse in eine eigene Quellcode-Datei auszula-gern. Dies lässt in der Visual C# Express-Umgebung sehr einfach mit demMenübefehl Projekt/Klasse hinzufügen... durchführen. Wählen Sie im folgen-den Dialog unter Vorlagen: die Option Klasse, geben Sie in das untere Textfeldfür den Namen der Klasse Rechteck ein und klicken Sie dann auf Hinzufügen.

Page 256: Visual C# 2005 easy

Klassendefinition 255

Abbildung 14.1: Hinzufügen einer neuen Klasse

Daraufhin wird im Projektmappen-Explorer der Eintrag für die neue Quellcode-Datei Rechteck.cs hinzugefügt.

Abbildung 14.2: Visual C# Express nimmt Ihnen viel Arbeit ab, wenn Sie den Code für eine neue Klasse in eine separate Datei auslagern

3 Definieren Sie in der Klasse Rechteck die Felder Laenge und Breite.

Tipp

Um eine Datei im Code-Editor zu bearbeiten, klicken Sie den entspre-chenden Eintrag im Projektmappen-Explorer doppelt an oder benutzenSie die Reiter in der oberen Leiste (im Beispiel »Rechteck.cs« und »Pro-gram.cs«), um zwischen den Dateien zu wechseln.

Page 257: Visual C# 2005 easy

256 Kapitel 14

Schreiben Sie dazu zwei Variablendefinitionen in den Block Ihrer neuen Klasse(Sie können daraus schließen, dass es sich bei den Feldern einer Klasse imGrunde um nichts anderes handelt als um Variablen). Damit besitzen IhreRechtecke die Eigenschaften Länge und Breite:

class Rechteck{ public double Laenge; public double Breite;}

Das Schlüsselwort public vor der Datentypangabe ist für den direkten Zugriffauf die Datenelemente notwendig. Direkter Zugriff bedeutet, dass Objekteeiner Klasse ihre öffentlichen (public) Datenelemente unmittelbar anspre-chen können. Das Gegenstück zu public ist private. Auf ein private-Ele-ment einer Klasse kann von Klassenobjekten nicht auf direktem Wegezugegriffen werden. Dies ist auch die Voreinstellung. Das heißt, wenn Sie denZugriffsspezifizierer (public bzw. private) bei der Definition eines Feldesweglassen, gilt dieses als private. Diese Aussagen gelten nicht nur für dieDatenelemente einer Klasse, sondern auch für deren Methoden.

4 Richten Sie in der Klasse die Methoden BerechneFlaeche() und ZeigeFlaeche() ein.

Dabei soll die Methode BerechneFlaeche() die Rechtecksfläche als Rückga-bewert liefern, während die Methode ZeigeFlaeche() die Rechtecksflächenur ausgeben soll:

class Rechteck{ public double Laenge; public double Breite;

public double BerechneFlaeche() {return Laenge * Breite;}

public void ZeigeFlaeche() { Console.Write("Rechtecksfläche: "); Console.WriteLine(Laenge * Breite); }}

Page 258: Visual C# 2005 easy

Klassendefinition 257

Die Methode BerechneFlaeche() liefert die Rechtecksfläche als Rückgabe-wert. Die Methode ZeigeFlaeche() bringt diesen zur Anzeige. Diese Metho-de ist jedoch in ihrer Verwendung sehr einschränkend und wird daher wohlnicht so häufig von Klassenobjekten in Anspruch genommen werden. Von die-sem Gesichtspunkt aus gehört BerechneFlaeche() eher zur minimalenGrundausstattung einer Klasse Rechteck, die Methode ZeigeFlaeche() isteher als komfortabler Zusatz anzusehen. Berücksichtigen Sie aber, dass eskeinen Schaden macht, Elemente in die Klasse zu integrieren, auch wenn da-von auszugehen ist, dass diese später nur wenig gebraucht werden. Objekteder Klasse werden sowieso nur auf diejenigen Elemente zugreifen, welche zumaktuellen Zeitpunkt tatsächlich benötigt werden. Und wenn Sie die Klasse in ei-nem anderen Programm verwenden, sind Sie vielleicht froh, wenn Ihnen dieeine oder andere Methode zur Verfügung steht.

Machen Sie sich auch deutlich, dass Sie sich um die Klasse selbst, wenn sieeinmal eingerichtet ist, nicht mehr kümmern müssen. Genauso wenig, wie Siesich z.B. Gedanken machen, wie die vordefinierte Klasse Console eingerichtetist. Sie verwenden einfach deren Methoden (Write(), WriteLine(), Read-Line()) und fahren damit sehr bequem. Ebenso verhält es sich mit selbst de-finierten Klassen. Sind diese einmal implementiert, stellen sie für denProgrammierer einfach eine willkommene Hilfe bzw. Erweiterung seiner Mög-lichkeiten dar.

Betrachten Sie nun die beiden Methoden ZeigeFlaeche() und Berechne-Flaeche(). Fällt Ihnen etwas auf? Warum dürfen diese Methoden die DatenLaenge und Breite im Rumpf verwenden, ohne diese Informationen über dieParameterliste auszutauschen?

Die Antwort: Jede Methode einer Klasse kennt ihre Datenelemente. Dabeispielt es keine Rolle, ob die Attribute als private oder public gekennzeich-net sind.

Tipp

Es widerspricht keinem guten Programmierstil, kleinere Methoden – wiehier BerechneFlaeche() – in Kompaktform zu notieren.

Page 259: Visual C# 2005 easy

258 Kapitel 14

Objekte erzeugenBetrachten wir die Definition der Klasse Rechteck fürs Erste als abgeschlos-sen. Um die Features der Klasse verwenden zu können, müssen Sie nun darangehen, ein Objekt dieses Klassentyps (ein Rechteck) zu erzeugen. Wie Sie wis-sen, werden Klassenobjekte mit dem new-Operator erzeugt. Zusätzlich benöti-gen Sie eine Referenzvariable zur Aufnahme des Objektverweises.

5 Erzeugen Sie in der Methode Main() ein Rechteck-Objekt:

static void Main(string[] args){ Rechteck myRec = new Rechteck();}

Nun ist im Code ein Rechteck namens myRec existent und Sie können die Ele-mente seiner Klasse nutzen. Für den Zugriff verwenden Sie den Punkt als Zu-griffsoperator, wie Sie das bisher getan haben, um die Elemente vordefinierterKlassen anzusprechen.

6 Setzen Sie Ihr Rechteck auf eine Länge von 5 und eine Breite von 4 (cm):

static void Main(string[] args){ Rechteck myRec = new Rechteck(); myRec.Laenge = 5.0; myRec.Breite = 4.0;}

Hinweis

Es ist auch möglich, Felder sofort mit eigenen Werten zu initialisieren.

class Rechteck{ public double Laenge = 1.0; public double Breite = 1.0; …}

Damit hat jedes Rechteck mit seiner Instanzierung eine Länge von 1 undeine Breite von 1 (wenn man im Code Klassenobjekte erzeugt, sprichtman vom Instanzieren, analog bezeichnet man Klassenobjekte auch alsInstanzen einer Klasse).

Page 260: Visual C# 2005 easy

Klassendefinition 259

7 Geben Sie nun mit der Methode ZeigeFlaeche() die Rechtecksfläche aus:

static void Main(string[] args){ Rechteck myRec = new Rechteck(); myRec.Laenge = 5.0; myRec.Breite = 4.0; myRec.ZeigeFlaeche();}

8 Testen Sie Ihr Programm.

Sie sollten die Ausgabe Rechtecksfläche: 20 erhalten.

ZugriffsspezifiziererEs steht dem Entwickler einer Klasse grundsätzlich frei, für welche Klassenele-mente er den direkten Zugriff von außen erlauben möchte. Das Konzept der ob-jektorientierten Programmierung verfolgt jedoch im Allgemeinen das Ziel,Klassen mit einer gewissen Intelligenz auszustatten, sodass Fehlbedienungenbei der Verwendung der Klasse reduziert werden. Ebenso soll der Code stabillaufen und plausible Ergebnisse produzieren.

So wie die Klasse Rechteck derzeit eingerichtet ist, wäre z.B. der Fall denkbar,dass jemand, der in seinem Programm die Klasse Rechteck verwendet, denAttributen Laenge und Breite im Code aus Versehen negative Werte zuweist.Um die Benutzer Ihrer Klasse – also Sie selbst oder andere Programmierer, dieIhre Klasse in ihren Programmen verwenden – vor solchen Fehlern zu bewah-ren, liegt es nahe, Felder dieser Art als private zu definieren und für den Zu-griff entsprechende Methoden einzurichten. Im Anweisungsteil dieserMethoden nehmen Sie dann gewisse Prüfungen und gegebenenfalls Korrektu-ren vor. Im konkreten Beispiel verhindern Sie die Zuweisung negativer Wertean die Felder Laenge und Breite.

Auf der CD-ROM

Das Beispiel finden Sie unter Beispiele/Konsolenprogramme auf derBuch-CD (Projektname K14a).

Page 261: Visual C# 2005 easy

260 Kapitel 14

9 Versehen Sie die Felder Laenge und Breite Ihrer Rechteck-Klasse mit dem Zugriffsspezifizierer private:

class Rechteck{ private double laenge; private double breite;

public double BerechneFlaeche() {return laenge * breite;}

public void ZeigeFlaeche() { Console.Write("Rechtecksfläche: "); Console.WriteLine(laenge * breite); }}

Nun ist der direkte Zugriff auf die Felder laenge und breite nicht mehr mög-lich:

Rechteck myRec = new Rechteck();myRec.laenge = 9.5; // FEHLER

Sie wollen den Zugriff auf diese Attribute jedoch nicht generell verhindern,sondern nur kontrollieren. Dazu könnten Sie für den Zugriff auf das Feld laen-ge zwei public-Methoden GetLaenge() und SetLaenge() einrichten. Da-bei muss der Rückgabewert der Get-Methode dem Wert des Feldes laengeentsprechen.

class Rechteck{ private double laenge; private double breite;

public double GetLaenge() { return laenge; }

Hinweis

Microsoft empfiehlt für die Notation von private-Feldern camelCasing,für die Notation von public-Feldern PascalCasing, daher die geänderteGroß- und Kleinschreibung im Listing.

Page 262: Visual C# 2005 easy

Hätten Sie gedacht ... 261

public void SetLaenge(double l) { if(l > 0) laenge = l; }

public double BerechneFlaeche() {return laenge * breite;}

public void ZeigeFlaeche() { Console.Write("Rechtecksfläche: "); Console.WriteLine(laenge * breite); }}

Die Zuweisung im Methodenblock von SetLaenge() findet nur statt, wenn derübergebene Wert größer als 0 ist. Andernfalls zieht ein Aufruf dieser Methodekeine Veränderung an dem Attribut laenge nach sich. Damit ist sichergestellt,dass laenge niemals einen negativen Wert annimmt. Beachten Sie, dass dieMethode SetLaenge() keinen Rückgabewert benötigt. Alle Datenelemente(hier laenge) sind schließlich innerhalb einer Klasse bekannt und für denLesezugriff von außen steht jetzt die Methode GetLaenge() zur Verfügung.

Hinsichtlich des Feldes breite würden Sie mit entsprechenden MethodenGetBreite() und SetBreite() ebenso verfahren:

class Rechteck{ private double laenge; private double breite;

public double GetLaenge() { return laenge; }

public void SetLaenge(double l) { if(l > 0) laenge = l; }

public double GetBreite() { return breite;

Page 263: Visual C# 2005 easy

262 Kapitel 14

}

public void SetBreite(double b) { if(b > 0) breite = b; }

public double BerechneFlaeche() {return laenge * breite;}

public void ZeigeFlaeche() { Console.Write("Rechtecksfläche: "); Console.WriteLine(laenge * breite); }}

In Main() müssten Sie dann allerdings statt des direkten Zugriffs

myRec.laenge = 5.0;myRec.breite = 4.0;

die entsprechenden Methoden aufrufen:

myRec.SetLaenge(5.0);myRec.SetBreite(4.0);

Spezielle Methoden von C# – die EigenschaftenDie gezeigte Vorgehensweise entspricht der anderer objektorientierter Pro-grammiersprachen und ist an und für sich völlig in Ordnung. Für jedes Feldexistiert eine Methode zum Lesen und eine für den Schreibzugriff. Letzterer er-folgt dann über einen Methodenaufruf in der Form Objekt.SetMethode(Argu-ment), wobei der neue Wert als Argument übergeben wird.

Allerdings sieht C# für den kontrollierten Zugriff auf Felder so genannte Eigen-schaften vor. Tatsächlich handelt es sich dabei um spezielle Methoden. DerVorteil liegt darin, dass der Zugriff über eine Eigenschaft von der Syntax her ge-nauso aussieht wie der direkte Zugriff auf ein Feld.

Das Grundgerüst einer Eigenschaft gleicht der Definition eines Feldes plusAnweisungsblock. Natürlich sollte eine Eigenschaft public sein:

public double Laenge{}

Page 264: Visual C# 2005 easy

Klassendefinition 263

Eigenschaften bestehen eigentlich aus zwei Methoden, einer Get-Methodezum Lesen und einer Set-Methode zum Setzen von Werten. Die Definition ge-staltet sich wie folgt:

public double Laenge{ get { } set { }}

Im Getter verfahren Sie nun wie bekannt, Sie geben einfach den Feldwert her-aus. Allein der Setter besitzt eine Besonderheit. Hier verwenden Sie den vor-definierten Parameter value, der den zuzuweisenden Wert enthält. Für dieEigenschaft Laenge prüfen Sie natürlich zunächst, ob value positiv ist, bevorSie die Zuweisung an das Feld laenge durchführen:

public double Laenge{ get { return laenge; } set { if(value > 0) laenge = value; }}

Hinweis

Get- und Set-Methoden werden auch kurz Getter bzw. Setter genannt.

Page 265: Visual C# 2005 easy

264 Kapitel 14

10 Richten Sie in der Klasse Rechteck die Eigenschaften Laenge und Breite ein. Verhindern Sie die Zuweisung von negativen Werten an die Felder laenge und breite. Initialisieren Sie die Felder außerdem mit dem Wert 1.0:

class Rechteck{ private double laenge = 1.0; private double breite = 1.0;

public double Laenge { get {return laenge;} set { if(value > 0) laenge = value;} }

public double Breite { get {return breite;} set { if(value > 0) breite = value;} }

public double BerechneFlaeche() {return laenge * breite;}

public void ZeigeFlaeche() { Console.Write("Rechtecksfläche: "); Console.WriteLine(laenge * breite); }}

Tipp

Für Eigenschaften empfiehlt sich oft eine Kompaktschreibweise. Dasausschlaggebende Kriterium bleibt nach wie vor die Übersichtlichkeitdes Codes.

Page 266: Visual C# 2005 easy

Klassendefinition 265

Hinweis

Natürlich könnten Sie es sich innerhalb der Klasse nun aussuchen, obSie in den Methoden BerechneFlaeche() und ZeigeFlaeche() –und eventuell in weiteren Methoden, die Sie später noch einrichten wer-den – die Felder laenge und breite oder die Eigenschaften Laengeund Breite verwenden. In der folgenden Klassendefinition wurde aufletztere Möglichkeit zurückgegriffen:

class Rechteck{ private double laenge = 1.0; private double breite = 1.0;

public double Laenge { get {return laenge;} set { if(value > 0) laenge = value;} }

public double Breite { get {return breite;} set { if(value > 0) breite = value;} }

public double BerechneFlaeche() {return Laenge * Breite;}

public void ZeigeFlaeche() { Console.Write("Rechtecksfläche: "); Console.WriteLine(Laenge * Breite); }}

Allerdings ist es in der Definition einer Klasse durchaus üblich, in denjeweiligen Methoden die Felder direkt anzusprechen. Als Entwicklereiner Klasse bewegen Sie sich ja auf sicherem Terrain.

Page 267: Visual C# 2005 easy

266 Kapitel 14

Beachten Sie, dass sich in Main() nichts geändert hat. Für Programmierer, dieIhre Klasse verwenden, präsentieren sich Laenge und Breite wie Felder:

myRec.Laenge = 5.0;myRec.Breite = 4.0;

11 Bringen Sie Ihr Programm zur Ausführung.

Sie sollten die gleiche Ausgabe erhalten wie zuvor.

Abbildung 14.3: Die Klasse bietet die gleiche Funktionalität wie vorher, kommt aber nun dem Ideal objektorientierter Programmierung von C# erheblich näher

Tipp

Bei der Implementation Ihrer Klassen können Sie sich als Richtschnurvon einem Grundprinzip der OOP leiten lassen, alle Datenelemente, wel-che nach außen zugänglich sein sollen, als private zu definieren undfür den Zugriff entsprechende öffentliche Methoden zur Verfügung zustellen.

»Nach außen zugänglich« bedeutet natürlich, zugreifbar aus einer ande-ren Klasse heraus (indem in dieser Objekte instanziert werden, welchedann in irgendeiner Form auf die Daten zugreifen – direkt oder über eineMethode). Es kommt aber auch vor, dass ein Feld ausschließlich für denklasseninternen Gebrauch (in anderen Methoden derselben Klasse) vor-gesehen ist. Dann darf seine Information (gemeint ist der Wert des Fel-des) in keiner Weise nach außen zugänglich sein (weder direkt noch aufdem Umweg über eine eigens hierfür implementierte Methode).

Auf der CD-ROM

Die so erweiterte Version des Beispiels finden Sie unter dem Projekt-namen K14b im Ordner Beispiele/Konsolenprogramme auf der Buch-CD.

Page 268: Visual C# 2005 easy

Klassendefinition 267

Natürlich steht es Ihnen frei, Ihre Rechteck-Klasse mit anderen Anweisungenzu testen. Versuchen Sie es doch einmal mit negativen Zuweisungen an Laen-ge und Breite:

static void Main(string[] args){ Rechteck myRec = new Rechteck(); myRec.Laenge = -11.0; myRec.Breite = - 7.8; myRec.ZeigeFlaeche();}

Ausgabe:

Rechtecksfläche: 1

Da die Zuweisungen negativer Werte erfolglos bleiben, zeigt die Ausgabe derRechtecksfläche den Wert 1, was dem Produkt der Initialisierungswerte vonlaenge und breite entspricht.

Konstruktoren und DestruktorenWir haben an anderer Stelle bereits erwähnt, dass beim Instanzieren einesKlassenobjekts eine besondere Methode aufgerufen wird, der so genannteKonstruktor. Dies gilt auch für den Fall, dass in der Klasse nicht explizit ein Kon-struktor definiert ist. Dann wird Ihrer Klasse automatisch ein Standardkon-struktor hinzugefügt. Dieser ist parameterlos und führt auch keinerleiAktionen durch. In der Regel werden Sie aber einen eigenen Konstruktor ein-richten.

Auf der CD-ROM

Das Beispiel finden Sie unter dem Projektnamen K14c im Ordner Bei-spiele/Konsolenprogramme auf der Buch-CD.

Hinweis

Die Bereitstellung eines Standardkonstruktors ist aus Gründen notwen-dig, die in der Sprache C# bzw. dem .NET verankert sind. Ansonstenwürde der Ausdruck new Rechteck() wegen der Klammern eine Feh-lermeldung erzeugen.

Page 269: Visual C# 2005 easy

268 Kapitel 14

Wie sieht nun die Definition eines Konstruktors aus? Ein Konstruktor besitzt ei-nen Anweisungsblock und eine Parameterliste wie jede andere Methode. Wasihn von normalen Methoden unterscheidet, ist Folgendes:

• Der Name des Konstruktors entspricht dem Namen der Klasse.

• Ein Konstruktor besitzt keinen Rückgabewert (auch nicht void).

Beachten Sie außerdem, dass ein Konstruktor immer von außen zugänglich,also public, sein muss.

Um in der Klasse Rechteck einen selbst definierten Standardkonstruktor ein-zurichten, schreiben Sie also

public Rechteck(){}

Statt die Felder der Klasse bei der Definition zu initialisieren, werden Sie diesenun im Konstruktor mit Anfangswerten versehen. Dies erfüllt denselbenZweck, da ein Konstruktor ja für jedes Objekt bei seiner Instanzierung zur Aus-führung kommt.

12 Richten Sie in Ihrer Rechteck-Klasse einen parameterlosen Konstruktor ein, der die Datenfelder mit dem Wert 1.0 initialisiert:

class Rechteck{ private double laenge; private double breite;

public Rechteck() { laenge = 1.0; breite = 1.0; }

public double Laenge { get {return laenge;} set { if(value > 0) laenge = value;} }

public double Breite { get {return breite;} set {

Page 270: Visual C# 2005 easy

Klassendefinition 269

if(value > 0) breite = value;} }

public double BerechneFlaeche() {return laenge * breite;}

public void ZeigeFlaeche() { Console.Write("Rechtecksfläche: "); Console.WriteLine(laenge * breite); }}

Das Gegenstück zum Konstruktor ist der Destruktor. Das ist eine Methode,welche zur Ausführung gelangt, wenn ein Objekt wieder gelöscht wird. Das istder Fall, wenn keine Referenzvariable mehr auf das Objekt verweist (weil derBlock, in dem die Referenzvariable definiert ist, verlassen wird und somit de-ren Lebensdauer endet).

Es sei darauf hingewiesen, dass sowohl der Konstruktor als auch der Destruk-tor für jedes Objekt nur ein einziges Mal zur Ausführung gelangt. Die Aufrufebeider Methoden erfolgen automatisch. Sie dürfen keine der beiden Methodenexplizit durch Programmierbefehle verwenden.

Ein Destruktor ist immer parameterlos und er besitzt auch keinen Rückgabe-wert. Der Name der Destruktormethode entspricht analog zum Konstruktordem Klassennamen, wird aber mit einer einleitenden Tilde (~) versehen. Die

Hinweis

Es ist auch der Fall möglich, dass mehrere Referenzvariablen mit ein unddemselben Objekt verbunden sind. In der Regel wird in Ihren Program-men aber nur eine Referenzvariable auf ein bestimmtes Objekt verwei-sen. Sobald deren Lebensdauer endet, räumt die Speicherverwaltungdes .NET das Objekt auf dem Heap, mit dem die Referenzvariable ver-bunden ist, automatisch auf. Man spricht in diesem Zusammenhang vomGarbage Collector, was so viel wie Müllabfuhr heißt.

Allerdings geht das Freigeben des Speichers (das Entfernen des Objekts)und damit der Aufruf des zugehörigen Destruktors meist nicht synchronmit dem Ungültigwerden der entsprechenden Referenzvariable einher.Der Garbage Collector wartet stattdessen einen »passenden« Zeitpunktab.

Page 271: Visual C# 2005 easy

270 Kapitel 14

Tilde geben Sie mit (Alt_Gr)+(+) ein. Die Definition des Destruktors erfolgtalso bezogen auf die Beispielklasse nach folgendem Schema:

~Rechteck(){ // ...}

Dem Destruktor kommt wegen des Garbage Collectors in der Praxis nur einegeringe Bedeutung zu, sodass Sie in Ihren Programmen in der Regel auf dieDefinition eines eigenen Destruktors verzichten werden.

Überladen von MethodenWie Sie wissen, müssen Bezeichner innerhalb eines Gültigkeitsbereichs ein-deutig sein. Eine Ausnahme von dieser Regel existiert in Bezug auf das Über-laden von Methoden. Das Wort »Überladen« bezieht sich eigentlich auf denBezeichner der Methode. Dieser wird gegebenenfalls überladen, da es möglichist, mehrere Methoden gleichen Namens zu definieren. Voraussetzung hierfürist, dass sich die Methoden in Anzahl und/oder Datentyp und/oder Reihenfol-ge der Parameter unterscheiden.

Sie werden von dieser Möglichkeit nun Gebrauch machen, um für die Instan-zierung von Rechteck-Objekten alternativ einen zweiten Konstruktor zur Ver-fügung zu stellen.

Hinweis

Beispielsweise gehört es zu den Aufgaben eines C++-Programmierers,Objekte vom Heap wieder zu entfernen (den Speicherplatz wieder freizu-geben). Gewöhnlich werden die dafür notwendigen Anweisungen dannim Destruktor eingerichtet.

Hinweis

Da Bezeichner und Parameterliste zusammen eine Methode eindeutigidentifizieren, spricht man von der Signatur einer Methode.

Page 272: Visual C# 2005 easy

Klassendefinition 271

13 Definieren Sie in der Klasse Rechteck einen Konstruktor, dem beim Aufruf Werte für Länge und Breite übergeben werden:

class Rechteck{ private double laenge; private double breite;

public Rechteck() { laenge = 1.0; breite = 1.0; }

public Rechteck(double l, double b) { laenge = l; breite = b; }

public double Laenge { get {return laenge;} set { if(value > 0) laenge = value;} }

public double Breite { get {return breite;} set { if(value > 0) breite = value;} }

public double BerechneFlaeche() {return laenge * breite;}

public void ZeigeFlaeche() { Console.Write("Rechtecksfläche: "); Console.WriteLine(laenge * breite); }}

Page 273: Visual C# 2005 easy

272 Kapitel 14

Nun besitzt die Klasse Rechteck neben einem Standardkonstruktor einenKonstruktor, dem Werte für Länge und Breite zu übergeben sind. Sie können essich nun aussuchen, welchen Konstruktor Sie beim Instanzieren von Rechteck-Objekten verwenden. Ihr Compiler erkennt anhand des Aufrufs, welcher Kon-struktor gemeint ist. Also

Rechteck myRec = new Rechteck();

oder

Rechteck yourRec = new Rechteck(5.0, 2.5);

Im ersten Fall wird der Standardkonstruktor verwendet, im zweiten Fall der an-dere. Nur dieser ist in der Lage, die Werte 5.0 und 2.5 entgegenzunehmen.

Statische KlassenelementeWie Sie bereits in Kapitel 8 (Abschnitt »Literale zur Darstellung von ganzenZahlen«) erfahren haben, gibt es sowohl Methoden, die sich auf ein Objekt be-ziehen, als auch Methoden, welche sich auf die Klasse selbst beziehen, in dersie definiert sind. Die einen werden mit dem Objektnamen, die anderen mitdem Klassennamen aufgerufen. Zu den Methoden, die auf die Klasse ange-wendet werden, gehören beispielsweise die Methoden Write(), Write-Line(), ReadLine(), aber auch etwa die Umwandlungsmethoden der KlasseConvert (siehe Kapitel 8, Abschnitt »Umwandlungsmethoden«). Solche Me-thoden werden »statisch« genannt. Es gibt nicht nur statische Methoden, son-dern auch statische Datenelemente.

Wenn Sie in Ihren Klassen statische Elemente (Methoden oder Felder) einrich-ten, verwenden Sie das Schlüsselwort static. Dieses wird vor dem Datentypangegeben. Ein Beispiel ist die Methode Main():

static void Main()

Zur Demonstration soll die Klasse Rechteck nun so erweitert werden, dass siedie Anzahl der im Programm instanzierten Rechtecke festhält.

Hinweis

Die Methode Main() muss statisch sein, da sie vom Betriebssystemansonsten nicht aufgerufen werden kann.

Page 274: Visual C# 2005 easy

Statische Klassenelemente 273

14 Definieren Sie zu diesem Zweck ein privates statisches Feld anzahl und ver-sehen Sie es mit dem Anfangswert 0:

class Rechteck{ private double laenge; private double breite; private static int anzahl = 0;

public Rechteck() { laenge = 1.0; breite = 1.0; }

public Rechteck(double l, double b) { laenge = l; breite = b; }

public double Laenge { get {return laenge;} set { if(value > 0) laenge = value;} }

public double Breite { get {return breite;} set { if(value > 0) breite = value;} }

public double BerechneFlaeche() {return laenge * breite;}

public void ZeigeFlaeche() { Console.Write("Rechtecksfläche: "); Console.WriteLine(laenge * breite); }}

Page 275: Visual C# 2005 easy

274 Kapitel 14

Nun müssen Sie dafür sorgen, dass der Wert von anzahl um eins hochgezähltwird, wenn ein neues Rechteck-Objekt im Code entsteht.

15 Inkrementieren Sie das Feld anzahl in den beiden Konstruktormethoden:

class Rechteck{ private double laenge; private double breite; private static int anzahl = 0;

public Rechteck() { laenge = 1.0; breite = 1.0; anzahl++; }

public Rechteck(double l, double b) { laenge = l; breite = b; anzahl++; }

public double Laenge { get {return laenge;} set { if(value > 0) laenge = value;} }

public double Breite { get {return breite;} set { if(value > 0) breite = value;} }

public double BerechneFlaeche() {return laenge * breite;}

public void ZeigeFlaeche() { Console.Write("Rechtecksfläche: ");

Page 276: Visual C# 2005 easy

Statische Klassenelemente 275

Console.WriteLine(laenge * breite); }}

Damit haben Sie sichergestellt, dass anzahl immer die aktuelle Anzahl der in-stanzierten Objekte enthält.

16 Richten Sie zum Zugriff auf das Feld anzahl eine statische Eigenschaft Anzahl ein.

Natürlich darf anzahl nur gelesen, nicht aber von außerhalb der Klasse verän-dert werden. Das erreichen Sie, indem Sie den Setter bei der Definition einfachweglassen:

class Rechteck{ private double laenge; private double breite; private static int anzahl = 0;

public Rechteck() { laenge = 1.0; breite = 1.0; anzahl++; }

public Rechteck(double l, double b) { laenge = l; breite = b; anzahl++; }

public double Laenge { get {return laenge;} set { if(value > 0) laenge = value;} }

public double Breite { get {return breite;} set { if(value > 0)

Page 277: Visual C# 2005 easy

276 Kapitel 14

breite = value;} }

public static int Anzahl { get {return anzahl;} }

public double BerechneFlaeche() {return laenge * breite;}

public void ZeigeFlaeche() { Console.Write("Rechtecksfläche: "); Console.WriteLine(laenge * breite); }}

Nun überzeugen Sie sich davon, dass anzahl korrekt funktioniert.

17 Erzeugen Sie dazu in Main() zwei weitere Rechtecke. Zur Kontrolle geben Sie vorher und nachher den aktuellen Wert von anzahl aus.

static void Main(string[] args){ Rechteck myRec = new Rechteck(); myRec.Laenge = 5.0; myRec.Breite = 4.0; myRec.ZeigeFlaeche(); Console.WriteLine("Anzahl der Rechtecke: {0}" , Rechteck.Anzahl); Rechteck yourRec = new Rechteck(); Rechteck herRec = new Rechteck(); Console.WriteLine("Anzahl der Rechtecke: {0}" , Rechteck.Anzahl);}

18 Starten Sie Ihr Programm mit (F5) bzw. (Strg) + (F5).

Die ausgegebenen Werte für „Anzahl“ sollten jeweils der aktuellen Anzahl derinstanzierten Rechteck-Objekte entsprechen, also 1 und 3.

Page 278: Visual C# 2005 easy

Namensräume 277

Abbildung 14.4: Die Beispielklasse wurde um eine statische Eigenschaft erweitert, welche die Anzahl der momentan existierenden Objekte der Klasse darstellt

NamensräumeZum Abschluss wollen wir uns noch in aller Kürze mit den Namensräumen(engl. »namespaces«) beschäftigen. Ein Namensraum beschreibt einen klas-senübergreifenden Gültigkeitsbereich. Das heißt, in einem Namensraum kön-nen mehrere Klassen zusammengefasst werden. Dabei müssen die Bezeichnerfür die Klassen nur innerhalb ein und desselben Namensraums eindeutig sein.

Beispielsweise haben Sie den vordefinierten Namensraum System von Anfangan verwendet. Dieser wurde mit der Zeile using System; in Ihre Programmeeingebunden. In diesem Namensraum sind z.B. alle Datentypen definiert, dieSie verwendet haben, sowie die Klassen Console und Convert.

Ohne die Direktive using System; müssten Sie beispielsweise jeden Zugriffauf die Methode WriteLine() der Klasse Console (im Namensraum System)qualifiziert vornehmen, was folgendermaßen aussieht:

System.Console.WriteLine();

Die Definition eines Namensraums wird durch das Schlüsselwort namespaceeingeleitet:

namespace Neu{}

Neu ist hier der Bezeichner für den Namensraum. Im zugehörigen Block stehendann die Klassendefinitionen. Die Verwendung von selbst definierten Namens-räumen ist nicht vorgeschrieben und im Allgemeinen nur bei sehr umfangrei-chen Programmen sinnvoll.

Auf der CD-ROM

Das komplette Beispiel finden Sie unter dem Projektnamen K14d im Ord-ner Beispiele/Konsolenprogramme auf der Buch-CD.

Page 279: Visual C# 2005 easy

278 Kapitel 14

Hinweis

Namensräume dürfen auch verschachtelt definiert werden. Beim Zugriffwerden die Namensräume verschiedener Ebenen wie gewohnt durcheinen Punkt getrennt. Außerdem ist es möglich, Namensräume übermehrere Dateien hinweg zu definieren. Wenn Sie Ihre Rechteck-Klasse ineine separate Datei ausgelagert haben, können Sie z.B. feststellen, dassVisual C# Express beide Klassen (Program und Rechteck) auf dieseWeise in einem Namensraum zusammengefasst hat.

Page 280: Visual C# 2005 easy

Eine kleine Erfolgskontrolle 279

Eine kleine Erfolgskontrolle• Was ist ein Konstruktor?

• Was ist ein Standardkonstruktor?

• Fügen Sie Ihrer Klasse Rechteck eine nicht statische public-Methodehinzu, welche zwei Rechtecke miteinander vergleicht. Die Methode solltrue zurückgeben, falls beide Rechtecke deckungsgleich sind (also diegleiche Länge und Breite besitzen), ansonsten false. Nennen Sie dieMethode Vergleiche().

• Formulieren Sie eine if-Bedingung zum Vergleich zweier Rechtecke a undb. Benutzen Sie dazu die eben erstellte Methode Vergleiche().

• Welche Datenelemente würden Sie in einer Minimaldefinition einer KlasseKonto einrichten, welche ein Kundenkonto einer Bank repräsentierensoll?

• Eröffnen Sie mit dieser fiktiven Klasse ein neues Konto. Instanzieren Siealso ein Objekt der Klasse Konto (unter Verwendung des Standardkon-struktors der Klasse) und nennen Sie die Referenzvariable meinKonto.

Page 281: Visual C# 2005 easy

Das können Sie schon:

Arbeiten mit Strings, Steuerzeichen 75

Variablen, Konstanten, Datentypen, Typkonvertierung 87

Verarbeiten von Benutzereingaben 103

Komplexe Ausdrücke, Operatoren, Operatorpriorität 139

Programmverzweigungen und Schleifen 157

Gültigkeitsbereich und Lebensdauer von Variablen 202

Arrays, Referenzvariablen 205

Methoden definieren und verwenden 234

Klassen definieren 254

Mit Objekten arbeiten 259

Das lernen Sie neu:

Entwickeln von GUI-Programmen 281

Windows Forms 282

Spezielle Features der Visual C# Express Edition 283

Toolbox und Eigenschaftenfenster 284

Steuerelemente mit Ereignissen verbinden 293

Page 282: Visual C# 2005 easy

Kapitel 15

Windows-Anwendungen entwickelnHier erfahren Sie, wie Sie mit der Visual C# 2005 Express Edition Win-dows-Anwendungen erstellen – also Applikationen mit GUI-Elemen-ten, etwa Fenstern, Schaltflächen, Menüs usw., wie Sie diese z.B. von den Microsoft Office-Produkten her kennen. Vermutlich werden Sie angenehm überrascht sein, wie einfach es ist, Programme mit einer grafischen Benutzeroberfläche zu versehen – das inzwischen erwor-bene Programmier-Know-How vorausgesetzt. Sie werden im Folgen-den ein Lottospiel entwickeln, wobei Sie Ihre bisher erworbenen Programmierkenntnisse zum Einsatz bringen.

Page 283: Visual C# 2005 easy

282 Kapitel 15

Der Windows Forms-DesignerIn der Visual C# 2005 Express Edition bilden Formulare die Basis jeder GUI-An-wendung – daher auch der Name Windows Forms (engl. »form« = »Formular«).Formulare sind nichts anderes als Fenster, worunter auch Zusatzfenster wieDialogfelder fallen. Auf einer Form platzieren Sie die benötigten Steuerelemen-te (Textfelder, Schaltflächen, Dialogfelder usw.), welche in ihrer Gesamtheitschließlich das Aussehen Ihrer Anwendung bestimmen. Zu diesem Zweck stelltIhnen Visual C# Express eine Vielzahl von Hilfsmitteln zur Verfügung, unter an-derem eine Palette von fertigen Steuerelementen, mit denen Sie auch bei derEntwicklung professioneller Applikationen auskommen sollten.

Die vordefinierte Funktionalität der eingefügten Steuerelemente führt in Ver-bindung mit dem von Ihnen zu entwickelnden Code in der Regel verhältnis-mäßig schnell zu den gewünschten Lösungen.

1 Legen Sie in Ihrer Visual C# Express-IDE ein neues Projekt an. Wählen Sie als Pro-jektvorlage Windows-Anwendung.

Hinweis

Hinter jedem Steuerelement steht eine Klasse des .NET Framework.Sobald Sie Ihrer Form ein Steuerelement hinzufügen, generiert Visual C#Express im Hintergrund den benötigten Code (z.B. Instanzieren einesObjekts der betreffenden Klasse).

Hinweis

Was hier über die Visual C# 2005 Express Edition gesagt wird, gilt imWesentlichen auch für Visual Studio .NET. Falls Sie sich also irgendwanndie »große« Version von Visual Studio zulegen sollten, werden Sie durchIhre Erfahrungen mit der Visual C# 2005 Express Edition bestens vorbe-reitet sein.

Page 284: Visual C# 2005 easy

Der Windows Forms-Designer 283

Abbildung 15.1: Auswahl der Projektvorlage »Windows-Anwendung«

Visual C# Express erzeugt daraufhin unter anderem den Code für das Haupt-formular. Die Oberfläche Ihrer IDE sollte sich nun wie in der Abbildung 15.2 zusehen präsentieren.

Abbildung 15.2: Toolbox, Windows Forms-Designer, Projektmappen-Explorer und Eigenschaftenfenster

Page 285: Visual C# 2005 easy

284 Kapitel 15

Die Toolbox (links im Bild) und das Eigenschaftenfenster (rechts, unterhalb desProjektmappen-Explorers) können Sie gegebenenfalls im Menü mit Ansicht/Toolbox bzw. Ansicht/Eigenschaftenfenster (oder Klick auf die entsprechendenSymbole in der Symbolleiste) einblenden.

Bei der Windows Form, wie sie in der Entwurfsansicht zu sehen ist, handelt essich um eine visuelle Darstellung des Fensters, wie es beim Starten der Anwen-dung erscheint. Der entsprechende Code, den Visual C# Express generiert hat,befindet sich in den Dateien Form1.cs und Form1.Designer.cs. Letztere Datei iststandardmäßig nicht sichtbar, kann aber zur Anzeige gebracht werden, indemim Projektmappen-Explorer der Ast bei Form1.cs durch Klicken auf das Plus-Symbol (+) geöffnet wird. Diese Aufteilung in zwei Dateien hat den Sinn, dassder automatisch generierte Code vom selbst entwickelten Code getrennt wird,was für mehr Übersicht sorgt. Entsprechend ist die Datei Form1.cs fast leer. DieEntwicklung findet dort statt, gegebenenfalls in weiteren Formularen, wennvorhanden, außerdem und vor allem in der Klasse Program.cs sowie in weite-ren Klassendateien, die einem Projekt hinzugefügt werden.

In der Toolbox besorgen Sie sich nun die passenden Steuerelemente. Für IhrLottoprogramm benötigen Sie sechs Textfelder zum Anzeigen der Zahlen undeinen Button.

2 Fügen Sie Ihrem Formular ein Textfeld hinzu.

Erweitern Sie gegebenenfalls die Kategorie Alle Windows Forms in der Toolboxund klicken Sie auf den Eintrag TextBox. Danach klicken Sie auf die gewünsch-te Stelle in Ihrem Formular, woraufhin das Textfeld auf dem Formular abgelegtwird. Die Position kann durch Ziehen des Steuerelements noch nachträglichgeändert werden.

Hinweis

Um gegebenenfalls von der Codeansicht in die Entwurfsansicht des For-mulars Form1.cs zu gelangen, klicken Sie im Projektmappen-Explorerdoppelt auf den Eintrag Form1.cs oder Sie klicken mit der rechten Maus-taste darauf und wählen im Kontextmenü den Eintrag Ansicht-Designer.

Page 286: Visual C# 2005 easy

Der Windows Forms-Designer 285

Jedes Steuerelement – auch das Formular selbst – besitzt bestimmte Eigen-schaften. Um diese zu ändern, wählen Sie dieses mit einem Mausklick aus undbegeben sich in das Eigenschaftenfenster. Dort können Sie zwischen derEigenschaften-Ansicht und der Ereignis-Ansicht wählen.

Abbildung 15.3: Eigenschaften-Ansicht des Eigenschaftenfensters

Klicken Sie dazu auf das entsprechende Symbol in der oberen Symbolleistedes Eigenschaftenfensters. In der Eigenschaften-Ansicht sehen Sie in der lin-ken Spalte den Namen der jeweiligen Eigenschaft und in der rechten den dazu-gehörigen aktuellen Wert, den Sie dort auch neu setzen können. Der untereTeil des Eigenschaftenfensters zeigt eine Beschreibung der betreffendenEigenschaft.

Hinweis

Ebenso können Sie ein Steuerelement bei gedrückter Maustaste von derToolbox auf das Formular ziehen.

Page 287: Visual C# 2005 easy

286 Kapitel 15

3 Ändern Sie den Wert für die Eigenschaft Text des Formulars zu »Ihre Lottozahlen«.

Klicken Sie dazu im Windows Forms-Designer Ihr Formular an, lassen Sie sichim Eigenschaftenfenster die Eigenschaften-Ansicht anzeigen und setzen Siedie Einfügemarke in die rechte Spalte neben Text. Dort löschen Sie den vor-handenen Eintrag »Form1« und tippen »Ihre Lottozahlen« ein. Damit legen Sieden Text für die Titelleiste des Formulars fest.

4 Setzen Sie den Wert für die Breite des Textfeldes auf 35 Pixel.

Erweitern Sie dazu im Eigenschaftenfenster die Eigenschaft Size, nachdemSie das Textfeld in der Entwurfsansicht ausgewählt haben. Belassen Sie es fürHeight bei dem Wert 20 und geben Sie für Width den Wert 35 an.

5 Setzen Sie das Attribut Size der Font-Eigenschaft auf den Wert 12.

Damit legen Sie für die Darstellung der Lottozahlen eine Schriftgröße von 12 ptfest. Die Eigenschaft Font besteht wie die Eigenschaft Size aus mehreren At-tributen. Zusammengesetzte Eigenschaften werden im Eigenschaftenfensterin einer Strukturansicht angezeigt, erkennbar an dem vorangestellten Plus-Zeichen (+). Um die Werte einzelner Attribute zu ändern, erweitern Sie den Ein-trag für die Eigenschaft, indem Sie darauf doppelklicken und verfahren dannwie gerade bei dem Width-Attribut von Size.

Bei vielen Eigenschaften, so auch bei der Font-Eigenschaft, kann das Setzender Attributwerte alternativ über einen Dialog erfolgen, was sehr praktisch ist,um mehrere Attribute in einem Durchgang zu ändern. In diesem Fall wird in derrechten Spalte ein mit Auslassungspunkten beschrifteter Button (»...«) ange-boten. Klicken Sie diesen entsprechend an.

Hinweis

Denken Sie daran, dass jedes Steuerelement eine Instanz der betreffen-den Steuerelement-Klasse ist. Wenn Sie bestimmte Eigenschaften (dasWort ist hier im üblichen Sinne gebraucht) ändern, rufen Sie praktischdie entsprechenden Methoden (Eigenschaften, siehe Kapitel 14,Abschnitt »Spezielle Methoden von C# – die Eigenschaften«) auf, welchedann wiederum die entsprechenden Felder ändern, das heißt derenWerte (das bedeutet, Visual C# Express erzeugt im Hintergrund den ent-sprechenden Code für Sie ).

Page 288: Visual C# 2005 easy

Der Windows Forms-Designer 287

Abbildung 15.4: Der Dialog zum Ändern der Eigenschaft »Font«. Er entspricht dem Dialog aus Textverarbeitungsprogrammen zur Anbringung zeichenorientierter Formatierungen

6 Setzen Sie die Anchor-Eigenschaft auf None.

Dies ist notwendig, damit die Textfelder später beim Vergrößern des Anwen-dungsfensters zentriert bleiben. Klicken Sie im Eigenschaftenfenster in derSpalte neben Anchor auf das Dreiecksymbol und dann jeweils ein Mal auf diegrauen Balken, bis kein grauer Balken mehr vorhanden ist.

7 Setzen Sie die TextAlign-Eigenschaft auf Center, damit die Zahl später im Feld zentriert dargestellt wird.

8 Kopieren Sie das vorhandene Textfeld fünf Mal.

Dazu wählen Sie es aus, kopieren Sie es mit (Strg) + (C) in die Zwischenabla-ge (oder wählen Sie den Menübefehl Bearbeiten/Kopieren) und fügen Sie esdann fünf Mal in Ihr Formular ein ((Strg) + (V) oder Bearbeiten/Einfügen).

9 Ordnen Sie die sechs Textfelder so an, dass sie mittig in einer Reihe nebeneinander liegen.

Die Namen der Textfelder sollten von links nach rechts textBox1, textBox2,... textBox6 lauten. Ziehen Sie also zuerst das textBox1-Textfeld nach links,platzieren dann das textBox2-Textfeld daneben usw.

Page 289: Visual C# 2005 easy

288 Kapitel 15

Lassen Sie sich beim Ausrichten der Textfelder von den Ausrichtungslinien un-terstützen, den so genannten SnapLines. Außerdem bestätigen Sie zur Aus-richtung die Möglichkeit, die Textfelder (und andere Steuerelemente)auszuwählen und dann die passenden Optionen im Menü Format aufzurufen.Gleichen Sie dabei die horizontalen Abstände zwischen den Rändern der ein-zelnen Textboxen an (Format/Horizontaler Abstand/Angleichen) und zentrierenSie diese auf dem Formular (mit Format/Auf Formular zentrieren/Horizontalund Format/Auf Formular zentrieren/Vertikal).

10 Fügen Sie Ihrem Formular ein Button-Steuerelement hinzu.

11 Ändern Sie die Text-Eigenschaft des Buttons zu »Lottozahlen auslosen«.

12 Setzen Sie die Anchor-Eigenschaft auf None.

13 Legen Sie für den Text des Buttons eine 10-Punkt-Schrift fest und passen Sie die Größe des Buttons an.

Hinweis

Sie finden den Namen eines Steuerelements in der zweite Spalte imEigenschaftenfenster neben dem eingeklammerten Eintrag (Name). WieSie sich vermutlich denken können, handelt es sich dabei um denBezeichner der Referenzvariablen des betreffenden Steuerelements. Mitdiesem werden Sie im Code auch auf die Text-Eigenschaft der einzelnenTextfelder zugreifen (die, wie zu erwarten, den angezeigten Text des Text-felds repräsentiert).

Hinweis

Um zuverlässig mehrere Steuerelemente gleichzeitig zu markieren,erweitern Sie in der Toolbox den Eintrag Alle Windows Forms und klickenauf Zeiger. Dann klicken Sie in der Entwurfsansicht das erste Steuerele-ment und – bei gedrückter (Strg)-Taste – nacheinander die anderen anoder Sie wählen im Menü Bearbeiten/Alle Auswählen, sofern es sich umgleichartige Steuerelemente handelt. Des Weiteren besteht die Möglich-keit, bei gedrückter Maustaste einen Auswahlrahmen aufzuziehen,wodurch alle auf diese Weise erfassten Steuerelemente markiert wer-den.

Page 290: Visual C# 2005 easy

Der Windows Forms-Designer 289

Setzen Sie z.B. hierfür das Width-Attribut der Size-Eigenschaft auf den Wert160 und Height auf 30.

14 Platzieren Sie den Button mittig über die Textfelder.

Damit ist das Design Ihrer Anwendung im Wesentlichen fertig. Drücken Sie die(F5)-Taste und sehen Sie sich das Ergebnis an.

Abbildung 15.5: Das fertige Formular bei gestartetem Programm

Es steht Ihnen natürlich frei, weitere Verbesserungen wie z.B. farbliche Hervor-hebungen (Form-, Button- oder TextBox-Eigenschaften ForeColor bzw.BackColor) hinzuzufügen. Es sei Ihnen an dieser Stelle empfohlen, möglichstviel auszuprobieren, um Ihre IDE noch besser kennen zu lernen.

Tipp

Um Größe bzw. Position eines Steuerelements zu ändern, können Sieauch mit gedrückter (ª)- bzw. (Strg)-Taste und den Pfeiltasten arbei-ten. Ebenso kann die Größe des Buttons durch Ziehen der Anfasser (denQuadraten an den Begrenzungen des Steuerelements) bei gedrückterMaustaste geändert werden.

Page 291: Visual C# 2005 easy

290 Kapitel 15

Weitere SteuerelementeDie Visual C# 2005 Express Edition stellt Ihnen als Entwickler von Windows-An-wendungen eine Reihe von Steuerelementen zur Auswahl, wie Sie diese alsAnwender im Umgang mit professionellen Programmen gewöhnt sind. In derfolgenden Tabelle sehen Sie eine Liste derjenigen Steuerelemente, die Sie ver-mutlich in der nächsten Zeit häufig verwenden werden:

Tabelle 15.1: Steuerelemente mit Beschreibung

RadioButton- und CheckBox-Steuerelemente besitzen eine ähnliche Funktion.Beide stellen Auswahlmöglichkeiten bereit, die ein Benutzer durch Anklickenaktivieren oder deaktivieren kann. Während sich die Optionsfelder eines Radio-Button-Steuerelements jedoch gegenseitig ausschließen – das heißt von meh-reren vorhandenen Optionen kann vom Benutzer jeweils nur eine ausgewähltwerden –, können gleichzeitig mehrere CheckBoxen (Kontrollkästchen) akti-viert sein.

Tipp

Falls Ihnen die Größe des Formulars nicht zusagt, können Sie diese ana-log zu Steuerelementen durch Ziehen eines der Anfasser bei gedrückterMaustaste ändern. Vergessen Sie nicht, das Formular zunächst miteinem Klick auszuwählen.

Steuerelement Beschreibung

Label Beschreibungstext, in der Regel als Beschriftung für andere Steuer-elemente gedacht

TextBox Textfeld zur Eingabe von Text

RichTextBox Textfeld mit umfangreichen Formatierungsmöglichkeiten

Button Schaltfläche zum Anklicken

RadioButton Optionsschaltfläche, die aktiviert oder deaktiviert werden kann

CheckBox Kontrollkästchen, das aktiviert oder deaktiviert werden kann

MenuStrip Zeigt eine obere Menüleiste in bekannter Form, auch kaskadiert, an

ToolTip QuickInfo für andere Steuerelemente

Page 292: Visual C# 2005 easy

Der Windows Forms-Designer 291

Mit einem MenuStrip richten Sie am oberen Rand einer Form ein Standard-menü ein. Zum Hinzufügen eines MenuStrip-Steuerelements in Ihr Formulargehen Sie in bekannter Weise vor. Ziehen Sie also das Steuerelement auf dasFormular oder klicken Sie je ein Mal in der Toolbox auf das MenuStrip-Symbolbzw. den Text MenuStrip und danach an eine beliebige Position innerhalb desFormulars. Danach erscheint im unteren Bereich, dem so genannten Kompo-nentenfach, des Entwurfsfensters ein Eintrag für das MenuStrip-Steuerele-ment (das Komponentenfach dient zur Aufbewahrung von Steuerelementen,die zur Laufzeit entweder nicht sichtbar sind, z.B. eines Timers, oder die einenfesten Platz haben, wie es bei einem Standardmenü der Fall ist; das Kompo-nentenfach ist entsprechend nur im Entwurfsmodus, nicht aber zur Laufzeitsichtbar).

Nach Ablegen des MenuStrip-Steuerelements auf dem Formular wird Ihnenoben in der Menüleiste für die erste Auswahlmöglichkeit ein Textfeld angebo-ten (klicken Sie gegebenenfalls das MenuStrip-Steuerelement im Komponen-tenfach an, falls diese Anzeige inzwischen nicht mehr sichtbar ist). Sie könnensogleich mit der Eingabe des Textes für die erste Auswahlmöglichkeit begin-nen (Sie müssen dazu ausdrücklich nicht in die Menüleiste klicken, es genügttatsächlich, wenn das MenuStrip-Steuerelement aktiv ist. Mit dem ersten Tas-tendruck wird die Einfügemarke in ein dann sichtbares Textfeld der Menüleistegesetzt). Beenden Sie die Eingabe mit (¢). Danach erscheint rechts davon einweiteres Textfeld für die nächste Auswahlmöglichkeit und unterhalb davon einTextfeld für Auswahlmöglichkeiten der zweiten Ebene – vergleichbar z.B. mitden Menüauswahlen Datei oder Bearbeiten (für die erste Ebene) bzw. Bearbei-ten/Kopieren (zweite Ebene), wie sie in fast jedem Windows-Programm vorhan-den sind. Durch Drücken von (¢) werden Ihnen jeweils neue leere Felder zumErstellen weiterer Auswahlmöglichkeiten angeboten. Sobald Sie das Menüvollständig aufgefüllt haben, entziehen Sie dem MenuStrip-Steuerelementden Fokus, indem Sie mit der Maus einfach in einen anderen Bereich des For-mulars klicken.

Hinweis

Mehrere RadioButton-Steuerelemente eines Formulars oder in einem sogenannten Panel (einem weiteren Steuerelement) zusammengefassteRadioButton-Steuerelemente bilden eine Gruppe. Wenn ein Benutzer einOptionsfeld innerhalb einer Gruppe aktiviert, werden die anderen Opti-onsfelder automatisch deaktiviert.

Page 293: Visual C# 2005 easy

292 Kapitel 15

Ein ToolTip-Steuerelement können Sie fast jedem beliebigen anderen Steuer-element zuordnen. Es zeigt eine QuickInfo an, wenn ein Benutzer den Mauszei-ger auf das betreffende Steuerelement bewegt und ein paar Augenblickewartet.

Wenn Sie Ihrer Form ein ToolTip-Element aus der Toolbox hinzufügen, er-scheint wie beim MenuStrip-Steuerelement ein entsprechendes Symbol imKomponentenfach. Um nun für ein Steuerelement des Formulars eine Quick-Info festzulegen, gehen Sie wie folgt vor:

• Wählen Sie das Steuerelement – beispielsweise den Button Ihres Lottopro-gramms – aus, welches Sie mit der QuickInfo verbinden möchten.

• Legen Sie im Eigenschaftenfenster für den Wert ToolTip auf toolTip1einen passenden Text fest. Dieser erscheint dann als QuickInfo, wenn einBenutzer den Mauszeiger auf dem Steuerelement positioniert.

• Mit der Eigenschaft ToolTipTitle des ToolTip-Elements können Siezusätzlich den Titel der QuickInfo bestimmen.

Daneben sei noch das Web-Browser-Steuerelement zum Anzeigen von Web-seiten erwähnt, welches in den Beispielen Webbrowser_1 und Webbrowser_2Verwendung findet (siehe unter Hätten Sie gedacht ... am Schluss des Kapi-tels).

Hinweis

Um ein MenuStrip-Steuerelement nachträglich weiter zu bearbeiten, kli-cken Sie das Steuerelement im Komponentenfach an oder klicken in dieobere Menüleiste. Um einem bestimmten Menüeintrag weitere Unterein-träge hinzuzufügen, klicken Sie auf den Eintrag der übergeordnetenEbene. Mit (Entf) lassen sich Menüeinträge nachträglich entfernen.

Hinweis

Wenn Sie ein ToolTip-Element in Ihrer Form ablegen, wird allen sich dortbefindlichen Steuerelementen – auch dem Formular selbst – eine Eigen-schaft ToolTip auf Name_des_Tooltip_Elementes hinzugefügt. Umfür ein bestimmtes Steuerelement eine QuickInfo einzurichten, müssenSie dieser Eigenschaft im Eigenschaftenfenster lediglich einen Wertzuweisen. Sie benötigen also keinesfalls für jedes Steuerelement eineigenes ToolTip-Element.

Page 294: Visual C# 2005 easy

Steuerelemente mit Code verbinden – Ereignisbehandlungsroutinen 293

Steuerelemente mit Code verbinden – EreignisbehandlungsroutinenUm auf unser Lottoprogramm zurückzukommen: Jedem Steuerelement sindeine Reihe von Ereignissen zugeordnet, die beim Programmlauf je nach Benut-zerverhalten ausgelöst werden. Für jedes dieser Ereignisse steht eine Metho-de bereit, die dann ausgeführt wird, wenn das Ereignis beim Programmlaufauftritt.

Klickt der Benutzer beispielsweise auf eine Schaltfläche, so löst er damit derenClick-Ereignis aus und die zugehörige Click()-Methode wird ausgeführt. FallsSie für diese Methode Code hinterlegt haben, geschieht etwas, ansonstenbleibt der Anweisungsteil der Methode leer und das Ereignis hat keine weitereAuswirkung.

Die Ereignisse für ein bestimmtes Steuerelement können Sie sich im Eigen-schaftenfenster anzeigen lassen, indem Sie dort in die Ereignis-Ansicht wech-seln (Klick auf das Blitz-Symbol). Sobald Sie die Einfügemarke auf einbestimmtes Ereignis setzen, erhalten Sie unten im Eigenschaftenfenster eineBeschreibung, wann dieses Ereignis ausgelöst wird.

In Ihrem Programm sollen nun sechs Lottozahlen ausgelost und in die Textfel-der geschrieben werden, wenn ein Benutzer auf die Schaltfläche klickt. Siemüssen also Ihre Schaltfläche mit dem Click-Ereignis verbinden, indem Sie fürdie zugehörige Methode den passenden Code hinterlegen.

Hinweis

Methoden, die auf ein Ereignis reagieren, werden auch Ereignis- oderEventhandler genannt.

Hinweis

Für einige Aktionen erzeugt Visual C# Express den passenden Code auchautomatisch, z.B. für den Schließen-Button in der rechten oberen Eckeeines Formulars.

Page 295: Visual C# 2005 easy

294 Kapitel 15

15 Führen Sie in der Entwurfsansicht einen Doppelklick auf die Schaltfläche aus.

Damit wechseln Sie in das Code-Fenster, wo Ihnen das Grundgerüst der Metho-de button1_Click() bereits zur Verfügung steht.

Nun sind Ihre Programmierkenntnisse gefragt. Zunächst müssen Sie dafür sor-gen, dass im Programm sechs Zufallszahlen ausgelost und festgehalten wer-den. Im Hinblick auf weitere Zugriffe mittels einer for-Schleife bietet sich fürdas Speichern der Zahlen ein Array an.

16 Definieren Sie in der Methode button1_Click() ein Array zur Aufnahme von sechs Integer-Zahlen:

private void button1_Click(object sender, EventArgs e){ int[] lottozahlen = new int[6];}

17 Erzeugen Sie sechs Zufallszahlen im Bereich von 1 bis 49 und halten Sie diese in den Elementen des Arrays fest. Verwenden Sie zum einfachen Zugriff auf die Array-Elemente die Laufvariable einer for-Schleife:

private void button1_Click(object sender, EventArgs e){ int i; int[] lottozahlen = new int[6]; Random zufallszahl = new Random(); for (i = 0; i < 6; i++) { lottozahlen[i] = zufallszahl.Next(1, 50); }}

Hinweis

Jedes Steuerelement besitzt ein Standardereignis. Für eine Schaltflächeist das z.B. das Click-Ereignis, für ein Textfeld ist es z.B. das TextChan-ged-Ereignis – Letzteres tritt ein, sobald sich der Wert eines Textfeldesändert. Um für Standardereignisse eine vordefinierte – zunächst leere –Methode anzulegen, genügt der gerade erwähnte Doppelklick auf dasjeweilige Steuerelement. Für die anderen Ereignisse legen Sie die ent-sprechenden (ebenso zunächst leeren) Methoden an, indem Sie imEigenschaftenfenster den Ereignisnamen doppelt anklicken (auch eineMethode für das Standardereignis kann so alternativ angelegt werden).

Page 296: Visual C# 2005 easy

Steuerelemente mit Code verbinden – Ereignisbehandlungsroutinen 295

18 Sortieren Sie das Array:

private void button1_Click(object sender, EventArgs e){ int i; int[] lottozahlen = new int[6]; Random zufallszahl = new Random(); for (i = 0; i < 6; i++) { lottozahlen[i] = zufallszahl.Next(1, 50); } Array.Sort(lottozahlen);}

Nun müssen Sie den Fall behandeln, dass Zahlen doppelt ausgelost werden.Lösungsvorschlag: Sie untersuchen zunächst das sortierte Array auf doppelteZahlen, indem Sie jeweils zwei Nachbarn miteinander vergleichen. Ist das derFall, so führen Sie die Auslosung nochmals durch. Dies wiederholen Sie so lan-ge, bis eine Auslosung keine doppelten Zahlen enthält.

Hinweis

Der vorgeschlagene Lösungsweg ist sicher nicht der eleganteste, abergedanklich leicht nachvollziehbar und einfach zu realisieren. Daher solldiesem hier der Vorzug gegeben werden. Zwar kann es zu Wiederholun-gen der entsprechenden Anweisungen für die Auslosung während desProgrammlaufs kommen, was aber keine merkliche Verschlechterung derPerformance Ihrer Anwendung nach sich zieht. (Es steht Ihnen natürlichfrei, später eine raffiniertere Lösung zu entwickeln, es ist sogar eine guteÜbung.)

Page 297: Visual C# 2005 easy

296 Kapitel 15

19 Untersuchen Sie das sortierte Array auf doppelte Zahlen. Falls doppelte Zahlen vorkommen, setzen Sie eine Variable mit dem Bezeichner doppelt auf den Wert 1:

private void button1_Click(object sender, EventArgs e){ int i, doppelt = 0; int[] lottozahlen = new int[6]; Random zufallszahl = new Random(); for (i = 0; i < 6; i++) { lottozahlen[i] = zufallszahl.Next(1, 50); } Array.Sort(lottozahlen); for (i = 0; i < 5; i++) { if (lottozahlen[i] == lottozahlen[i+1]) doppelt = 1; }}

20 Wiederholen Sie die Auslosung für den Fall, dass im Array doppelte Werte ent-halten sind.

Denken Sie daran, doppelt bei Schleifenbeginn wieder auf 0 zu setzen. An-dernfalls produzieren Sie eine Endlosschleife, falls in der ersten Auslosungdoppelte Werte enthalten sind:

private void button1_Click(object sender, EventArgs e){ int i, doppelt = 0; int[] lottozahlen = new int[6]; Random zufallszahl = new Random(); do { doppelt = 0; for (i = 0; i < 6; i++) { lottozahlen[i] = zufallszahl.Next(1, 50); } Array.Sort(lottozahlen); for (i = 0; i < 5; i++) { if (lottozahlen[i] == lottozahlen[i+1]) doppelt = 1; } } while (doppelt == 1);}

Page 298: Visual C# 2005 easy

Steuerelemente mit Code verbinden – Ereignisbehandlungsroutinen 297

Nun können Sie die sechs Lottozahlen in aufsteigend sortierter Reihenfolge indie Textfelder schreiben. Für den Zugriff auf die Textfelder verwenden Sie in be-kannter Weise den Objektnamen plus Punktoperator plus Name der Eigen-schaft. Allerdings müssen Sie die Integer-Zahlen noch in einen Stringumwandeln (Methode ToString()), bevor Sie diese der Text-Eigenschaft zu-weisen.

Tipp

IntelliSense hilft Ihnen auch beim Einfügen von Codeausschnitten, wobeies unterscheidet, ob Sie ein Codestück nur einfügen oder von einemanderen umschließen lassen wollen. Klicken Sie mit der rechten Maus-taste in das Editorfenster und wählen Sie im Kontextmenü Ausschnitteinfügen... bzw. Umschliessen mit... (Tastenkombination (Strg) + (K),(X) bzw. (Strg) + (K), (S)). Beide Befehle sind auch über das MenüBearbeiten/IntelliSense erreichbar. Um z.B. das Codestück mit der Aus-losung, Sortierung und Prüfung wie oben mit der do-while-Schleife zuumgeben, markieren Sie es und verwenden den Befehl Umschließenmit.... Dann bekommen Sie eine Auswahlliste angeboten, in der Sie fürdie do-while-Schleife den Eintrag do selektieren.

Abbildung 15.6: IntelliSense hilft beim Erzeugen von Konstrukten und kann dabei auch bereits vorhandene Codeteile einbeziehen, sodass sich z.B. vor-handene Anweisungen in eine for-Schleife einbetten lassen

Um die Schleife hinzuzufügen, klicken Sie doppelt auf den Eintrag oderdrücken Sie (¢). Danach müssen Sie lediglich noch die Bedingung derdo-while-Schleife anpassen.

Page 299: Visual C# 2005 easy

298 Kapitel 15

21 Schreiben Sie die Lottozahlen in die Textfelder:

private void button1_Click(object sender, EventArgs e){ int i, doppelt = 0; int[] lottozahlen = new int[6]; Random zufallszahl = new Random(); do { doppelt = 0; for (i = 0; i < 6; i++) { lottozahlen[i] = zufallszahl.Next(1, 50); } Array.Sort(lottozahlen); for (i = 0; i < 5; i++) { if (lottozahlen[i] == lottozahlen[i+1]) doppelt = 1; } } while (doppelt == 1); textBox1.Text = lottozahlen[0].ToString(); textBox2.Text = lottozahlen[1].ToString(); textBox3.Text = lottozahlen[2].ToString(); textBox4.Text = lottozahlen[3].ToString(); textBox5.Text = lottozahlen[4].ToString(); textBox6.Text = lottozahlen[5].ToString();}

22 Starten Sie Ihre Applikation und betätigen Sie die Schaltfläche »Lottozahlen auslosen«.

In den Textfeldern sollten Sie die ausgelosten Zahlen in aufsteigender Reihen-folge zu sehen bekommen.

Auf der CD-ROM

Das Projekt finden Sie unter Beispiele/Windows-Programme auf derBuch-CD (Projektname Lottospiel).

Page 300: Visual C# 2005 easy

Hätten Sie gedacht ... 299

Abbildung 15.7: Das Lottoprogramm in Aktion

In der Tabelle sehen Sie eine Übersicht der Standardereignisse für die oben ge-nannten Steuerelemente nebst Beschreibung:

Tabelle 15.2: Die wichtigsten Steuerelemente und die dazugehörigen Standardereignisse

Steuerelement Standardereignis Beschreibung

Label Click Tritt ein, wenn ein Benutzer das Label anklickt

TextBox TextChanged Tritt mit jeder Änderung des enthaltenen Textes ein

RichTextBox TextChanged

Button Click Tritt ein, wenn ein Benutzer den Button anklickt

RadioButton CheckedChanged Tritt ein, wenn sich der Wert der Checked-Eigenschaft ändert

CheckBox CheckedChanged

MenuStrip ItemClicked Tritt ein, sobald ein Benutzer auf einen Menü-eintrag klickt

ToolTip Popup Tritt unmittelbar vor dem Anzeigen der Quick-Info ein

Page 301: Visual C# 2005 easy

300 Kapitel 15

Die Checked-Eigenschaft von RadioButton- und CheckBox-Steuerelementenbesitzt den Wert true, wenn das jeweilige Steuerelement aktiviert ist, andern-falls false (Anzeige True bzw. False im Eigenschaftenfenster). Deren Wertändert sich also, wenn ein Benutzer die entsprechende Option aktiviert bzw. –bei RadioButtons durch Auswahl einer anderen Option – wieder deaktiviert.

Die Methode »Show()« der Klasse »MessageBox«Eine beliebte Variante, um sich schnell anzeigen zu lassen, wann genau ein be-stimmtes Ereignis eintritt, liegt darin, für den jeweiligen Eventhandler Codezum Anzeigen eines Meldungsfensters zu hinterlegen. Nicht nur dazu solltenSie die Methode Show() der Klasse MessageBox (Namensraum System.Win-dows.Forms) kennen. Sie ist gewissermaßen das Pendant der Windows Formszu den Ausgabemethoden Write() und WriteLine() der Console-Klasse.

Der Methode Show() der Klasse MessageBox erzeugt ein Meldungsfenster,das standardmäßig ohne Titel und mit einer OK-Schaltfläche erscheint.

Hinweis

Wenn Sie Ihre Konsolenprogramme mit Windows Forms umsetzen, soll-ten Sie daran denken, die Console.WriteLine()- bzw. Con-sole.Write()-Methoden mit entsprechenden Aufrufen vonMessageBox.Show() zu ersetzen, da die Methoden der Console-Klasse in diesem Zusammenhang nicht verwendet werden können.

Hinweis

Beides – den Text der Titelzeile sowie Anzahl und Art der Schaltflächen –können Sie nach Bedarf ändern, indem Sie Show() beim Aufruf entspre-chende Argumente übergeben. Die Methode ist mehrfach überladen.Eine Beschreibung können Sie in der Online-Hilfe Ihrer Visual C#Express-IDE unter der URL ms-help://MS.VSExpressCC.v80/MS.NETFramework.v20.de/cpref17/html/O_T_System_Windows_Forms_MessageBox_Show.htm abrufen (Such-begriff MessageBox.Show-Methode eingeben, dann aus den Such-ergebnissen den obersten Eintrag auswählen).

Page 302: Visual C# 2005 easy

Steuerelemente mit Code verbinden – Ereignisbehandlungsroutinen 301

Falls Sie z.B. für das Ereignis Popup Ihres ToolTip-Steuerelements – sofern vor-handen – ein Meldungsfenster anzeigen möchten, klicken Sie doppelt auf dasentsprechende Symbol im Komponentenfach des Entwurfsfensters und fügendem Eventhandler den Methodenaufruf MessageBox.Show() hinzu. Dabeiübergeben Sie der Methode den passenden Text für das Meldungsfenster.

private void toolTip1_Popup(object sender, PopupEventArgs e){ MessageBox.Show("Sie haben gerade das " + "Popup-Ereignis des ToolTips ausgelöst");}

Abbildung 15.8: Mithilfe der Methode »Show()« der Klasse MessageBox lassen sich auf einfache Weise Meldungsfenster anzeigen

Hinweis

Visual C# Express bindet beim Anlegen einer Form automatisch denNamensraum System.Windows.Forms ein, wovon Sie sich in derCode-Ansicht der Quelldatei für Ihr Formular (Form1.cs) überzeugen kön-nen.

using System.Windows.Forms;

Page 303: Visual C# 2005 easy

302 Kapitel 15

Hätten Sie gedacht ...... dass es mit der Visual C# 2005 Express Edition nur weniger – in der Minimal-ausstattung sogar nur einer einzigen – Programmierzeilen bedarf, um eineneigenen Web-Browser zu »entwickeln«? Die Lösung können Sie in der Online-Hilfe Ihrer IDE unter der folgenden URL abrufen: ms-help://MS.VSExpressCC.v80/MS.NETFramework.v20.de/dv_csexpresscon/html/250618a0-c5f5-4c68-86bf-4fb970220992.htm.

Abbildung 15.9: Ihr eigener Web-Browser

Auf der CD-ROM

Das nachgebildete Beispiel finden Sie unter dem ProjektnamenWebbrowser_2 im Ordner Beispiele/Windows-Programme auf der Buch-CD. Die »einzeilige« Version eines Web-Browsers befindet sich alsWebbrowser_1 im gleichen Ordner. Anders als in Webbrowser_2 könnenSie in diesem Browser jede beliebige URL eingeben.

Page 304: Visual C# 2005 easy

303

Anhang – Antworten

Antworten zu Kapitel 1• Was ist ein Compiler?

Ein Compiler ist ein Softwareprogramm, welches den Quellcode übersetztund ihn damit praktisch in seine endgültige – ausführbare – Form bringt.

• Worin unterscheiden sich Hochsprachen von maschinennahen Sprachen?

Zur Übersetzung eines in einer Hochsprache geschriebenen Quellcodessind im Allgemeinen mehr interne Übersetzungsschritte notwendig als beimaschinennahen Sprachen. Dagegen bieten Hochsprachen gegenübermaschinennahen Sprachen im Allgemeinen den Vorteil der besseren Les-barkeit. Auch sind Hochsprachen meist weniger komplex und entspre-chend einfacher zu erlernen.

• Was ist eine IDE?

IDE ist die Abkürzung für »Integrated Development Environment«, was»integrierte Entwicklungsumgebung« heißt. Dies ist eine Software, in deralle Werkzeuge zur Programmentwicklung unter einer Benutzeroberflächezusammengefasst sind.

Antworten zu Kapitel 2• Was bedeutet der Begriff »Laufzeitumgebung«?

Wenn ein Programm eine bestimmte Software (abgesehen vom Betriebs-system) benötigt, damit es ausgeführt werden kann, spricht man von einerLaufzeitumgebung.

• Was hat es mit dem IL-Code auf sich?

IL-Code ist die Abkürzung für »Intermediate Language Code«. Dieser bildetgewissermaßen das Endprodukt der C#-Programmierung, ist aber ohneweitere Übersetzung nicht lauffähig. Es handelt sich also um eine Art Zwi-schencode. Tatsächlich wird der IL-Code mitunter auch als Zwischencodebezeichnet (engl. intermediate – dazwischen liegend).

• Welcher Compiler erzeugt aus dem Quellcode den IL-Code?

Dafür ist der C#-eigene Compiler zuständig, der unter der ausführbarenDatei csc.exe zu finden ist. Dieser Compiler ist ebenfalls Bestandteil des.NET Framework.

Page 305: Visual C# 2005 easy

304 Anhang – Antworten

• Welche Rolle spielt der Compiler des .NET Framework bei der Ausführungvon C#-Programmen?

Der Just-in-Time-Compiler des .NET Framework übersetzt beim Programm-lauf den IL-Code des C#-Programms in spezifischen Maschinencode, dendas jeweilige Betriebssystem verarbeiten kann.

• Wie lautet eine zusammenfassende Beschreibung der Bedeutung des .NETFramework für die Ausführung von C#-Programmen?

Das .NET Framework bildet die Laufzeitumgebung für C#-Programme.

Antworten zu Kapitel 4• Nennen Sie eine Anweisung, welche die Bildschirmausgabe ***** ein-

schließlich einer Zeilenschaltung bewirkt.

Die Anweisung Console.WriteLine("*****"); bewirkt die Ausgabe***** und setzt anschließend die Einfügemarke in die nächste Zeile.

• Woran erkennt der Compiler den Anfang und das Ende eines Methoden-rumpfes?

An den geschweiften Klammern, { kennzeichnet den Anfang, } das Ende.

• Welche Anweisung wird beim Programmlauf als Erstes abgearbeitet?

Da die Programmausführung immer in Main() beginnt, handelt es sich umdie erste Anweisung in dieser Methode, mit anderen Worten um die Anwei-sung, welche im Methodenrumpf von Main() am weitesten oben steht.

• Wie wird die Definition einer Klasse eingeleitet?

Mit dem Schlüsselwort class.

• Nennen Sie in hierarchisch aufsteigender Reihenfolge drei Bausteine einesC#-Programms.

Anweisung, Methode, Klasse.

Antworten zu Kapitel 6• Welche Bildschirmausgabe erzeugt folgende Anweisung?

Console.Write(11 + 22 + "33");

Die Anweisung bewirkt die Ausgabe 3333. Zunächst erfolgt die mathema-tische Addition zwischen den Operanden 11 und 22 zu 33. An diesesErgebnis wird dann der String "33" angehängt.

• Schreiben Sie ein Programm, welches folgende Ausgabe erzeugt:

Das Newline-Zeichen wird mit "\n" dargestellt

Page 306: Visual C# 2005 easy

Anhang – Antworten 305

Hier die Main()-Methode:

static void Main(string[] args){ Console.Write("Das Newline-Zeichen wird " + "mit \"\\n\" dargestellt"); Console.ReadLine();}

Antworten zu Kapitel 7• zahl sei eine Variable vom Datentyp int. Was bewirkt die folgende Zuwei-

sung?

zahl = zahl + 3;

Die Zuweisung bewirkt eine Erhöhung des bisherigen Variablenwerts umden Wert 3.

• Was bedeutet Initialisieren von Variablen?

Eine Variable wird initialisiert, wenn sie bereits bei ihrer Definition miteinem Anfangswert versehen wird.

• Definieren Sie eine int-Variable mit dem Bezeichner z und initialisierenSie diese mit dem Wert 0.

int z = 0;

• Worin liegt der Fehler in folgendem Codestück?

string name;Console.Write(name);

Der Lesezugriff auf eine Variable, welche noch keinen kontrollierten Wertenthält, ist in C# nicht erlaubt. Das bedeutet, zwischen Definition und Aus-gabeanweisung muss auf jeden Fall eine Wertzuweisung an die Variablename erfolgen.

• Erklären Sie die Funktionsweise folgender Anweisung:

Console.ReadLine();

Die Anweisung bewirkt die Entgegennahme einer Benutzereingabe (ein-schließlich eines Zeilenvorschubs), ohne diese in einer Variablen zu spei-chern. Der Einsatz von ReadLine() in dieser Form ist z.B. als Haltebefehlgeeignet.

• Ist 1A ein gültiger Bezeichner?

Nein, da das erste Zeichen eines Bezeichners keine Ziffer sein darf.

Page 307: Visual C# 2005 easy

306 Anhang – Antworten

Antworten zu Kapitel 8• Welchen Datentyp besitzt das Literal 3?

Das Literal 3 ist vom Datentyp int.

• Nennen Sie den Datentyp des Literals 3.0.

Datentyp: double

• Der Datentyp des Literals "3" ist?

string

• Der Datentyp des Literals '3'ist?char

• Warum verursacht folgendes Codestück beim Kompilieren eine Fehlermel-dung? const string name = "Mustermann";Console.Write("Wie heißen Sie? ");name = Console.ReadLine();

Da die Variable name mit dem Schlüsselwort const definiert ist, darf ihrWert im weiteren Code nicht mehr verändert werden. Die Anweisung name= Console.ReadLine(); ruft daher eine Fehlermeldung hervor.

• zahl sei eine Variable vom Typ double. Das bedeutet, sie kann aus-schließlich Werte von diesem Datentyp aufnehmen. Warum erzeugt fol-gende Zuweisung dennoch keine Fehlermeldung?

zahl = 100;

Das Literal 100 ist zwar vom Datentyp int, vor der eigentlichen Zuweisungerfolgt jedoch eine implizite Konvertierung in den Datentyp der Variablen(double).

• Korrigieren Sie die/den Fehler in folgendem Codestück:

int z;Console.Write ("Geben Sie eine Zahl ein: ");z = Console.ReadLine();

Da der Rückgabewert der Methode ReadLine() vom Datentyp stringist, muss dieser erst explizit umgewandelt werden, bevor er einer int-Vari-ablen zugewiesen werden kann. Eine implizite Konvertierung von stringnach int erfolgt nicht. Die Lösung lautet also int z;Console.Write ("Geben Sie hier eine Zahl ein: ");z = Convert.ToInt32(Console.ReadLine());

Page 308: Visual C# 2005 easy

Anhang – Antworten 307

• Ist folgende Variableninitialisierung korrekt?int wert = 25.99;

Nein, da C# implizite Konvertierungen von double nach int grundsätzlichnicht durchführt.

Antworten zu Kapitel 9• Welchen Initialisierungswert erhält die Variable x mit der folgenden Defini-

tion?int x = 2 + 3 * 5;

Die Variable erhält den Wert 17 (nicht 25), da wie in der Mathematik»Punkt vor Strich« gilt. Im Ausdruck rechts des Zuweisungsoperators wirddaher die Multiplikation 3 * 5 vor der Addition ausgeführt.

• Schreiben Sie ein Programm, welches das Produkt zweier vom Benutzereinzugebender Zahlen berechnet und mit einer Genauigkeit von zweiNachkommastellen auf den Bildschirm ausgibt.

Eine Lösung könnte wie folgt aussehen:

static void Main(string[] args){ double z_1, z_2; Console.Write("Erste Zahl: "); z_1 = Convert.ToDouble(Console.ReadLine()); Console.Write("Zweite Zahl: "); z_2 = Convert.ToDouble(Console.ReadLine()); Console.WriteLine("{0} * {1} = {2:F}" , z_1, z_2, z_1 * z_2); Console.ReadLine();}

Das entsprechende Projekt finden Sie unter Beispiele/Konsolenpro-gramme auf der Buch-CD (Projektname K09e).

Antworten zu Kapitel 10• Welchen Rückgabewert liefert folgender Ausdruck?

22 == 2 * 10 || 2.3 < 2.4

Der linke Teilausdruck wird zu false ausgewertet, der rechte zu true(false || true). Somit ist der Ergebniswert des Gesamtausdrucksebenfalls true (bei einer logischen Oder-Verknüpfung ist der Gesamtaus-druck »wahr«, wenn mindestens ein Teilausdruck »wahr« ist).

Page 309: Visual C# 2005 easy

308 Anhang – Antworten

• z sei eine Variable vom Datentyp int. Welche Bildschirmausgabe erzeugtfolgendes Codestück, falls z den Wert 9 enthält?if(z <= 0)Console.Write("Die Variable z besitzt");Console.Write("den Wert " + z);

Ausgabe: den Wert 9

Da die Auswertung der if-Bedingung false ergibt (9 ist nicht kleiner odergleich 0), wird die erste Ausgabeanweisung übersprungen. Die Belanglo-sigkeit des Ausgabetexts und das Nichteinrücken der zum if-Konstruktgehörigen Anweisung dienten hier allein dem Zweck, Sie zu irritieren.Lesbarer ist natürlich

if(z <= 0) Console.Write("Die Variable z besitzt ");Console.Write("den Wert " + z);

Allerdings war die Intention des Programmierers wahrscheinlich eineandere und er wollte beide Ausgabezeilen vom Ergebnis der Bedingungabhängig machen. Dann müssen diese allerdings in einen Block gesetztwerden:

if(z <= 0){ Console.Write("Die Variable z besitzt "); Console.Write("den Wert " + z);}

• An welcher Stelle ist in folgendem Codestück ein (logischer) Fehler zu ver-muten?

if(id == 770234); Console.Write("Guten Tag Herr Müller");

Es ist anzunehmen, dass die Ausgabeanweisung nur für den Fall zur Aus-führung gelangen soll, dass die Variable id den Wert 770234 besitzt. Tat-sächlich wird diese Anweisung jedoch unabhängig von einer Bedingung injedem Fall abgearbeitet. Der Grund: Nicht die Ausgabeanweisung, sonderndie leere Anweisung (;) wird dem if-Konstrukt zugerechnet. Da eine leereAnweisung keinerlei Wirkung entfaltet, ist das if-Konstrukt if(id ==770234); eigentlich überflüssig. Somit kann davon ausgegangen werden,dass es sich bei dem ersten Semikolon um ein Versehen des Programm-autors handelt.

Page 310: Visual C# 2005 easy

Anhang – Antworten 309

• Was bewirkt die return-Anweisung?

Die return-Anweisung hat das unverzügliche Verlassen einer Methodezur Folge. Da Sie sich bis auf Weiteres ausschließlich innerhalb derMethode Main() befinden, ist dies gleichbedeutend mit dem Ende derProgrammausführung.

• Fordern Sie den Benutzer auf, eine ganze Zahl einzugeben. Teilen Sie ihmanschließend mit, ob die eingegebene Zahl gerade oder ungerade war.Speichern Sie die Benutzereingabe in einer Variablen zahl vom Datentypint. Setzen Sie den Modulo-Operator (siehe Kapitel 9, Abschnitt »DerModulo-Operator«) zur Formulierung einer passenden if-Bedingung ein.

Eine Zahl ist gerade, wenn sie durch 2 ohne Rest teilbar ist. Daher müssenSie den Ausdruck zahl % 2 mit dem Wert 0 vergleichen, um festzustellen,ob die Eingabezahl gerade ist:static void Main(string[] args){ int zahl; Console.Write("Geben Sie eine ganze Zahl ein: "); zahl = Convert.ToInt32(Console.ReadLine()); if(zahl % 2 == 0) Console.WriteLine("Die Zahl ist gerade"); else Console.WriteLine("Die Zahl ist ungerade"); Console.ReadLine();}

Das entsprechende Projekt finden Sie unter Beispiele/Konsolenpro-gramme auf der Buch-CD (Projektname K10g).

• Die Programmausführung landet in einem switch-Konstrukt mit integrier-tem default-Zweig. Ist der Fall denkbar, dass kein Anweisungsteil inner-halb des Konstrukts zur Ausführung gelangt?

Nein. Sollte keine der angegebenen case-Konstanten mit dem Wert desswitch-Ausdrucks übereinstimmen, kommt der Anweisungsteil derdefault-Marke zur Ausführung.

Page 311: Visual C# 2005 easy

310 Anhang – Antworten

Antworten zu Kapitel 12• Wo liegt der Fehler?

string[] names = new string[7];for(int i = 0; i <= 7; i++){ names[i] = Console.ReadLine();}

Die Schleifenbedingung (i <= 7) ist Ursache für einen unerlaubten Array-Zugriff. Da der Schleifenblock für den Wert 7 von i zur Ausführung gelangt,resultiert daraus der Zugriff names[7]. Das Array ist jedoch für 7 Elementedefiniert, das letzte Element wird also mit names[6] angesprochen, da dieZählung bei Arrays stets bei 0 beginnt. Richtig müsste die Schleifenbedin-gung lauten: i < 7 oder i <= 6.

• Welchen Vorteil bietet die foreach-Schleife?

Die Array-Grenzen werden automatisch erkannt. Der Programmierer brauchtsich daher nicht um diese zu kümmern.

• Nennen Sie eine Einschränkung in Bezug auf die foreach-Schleife.

Mit der foreach-Schleife ist es nicht möglich, ein Array zu verändern. Sieist ausschließlich für den Lesezugriff vorgesehen.

• Welche Anweisung können Sie im Quellcode verwenden, um ein Array mitdem Bezeichner myArr zu sortieren?

Verwenden Sie dazu die Methode Sort() der Klasse Array. Der Metho-denaufruf lautet: Array.Sort(myArr);

• Was bewirkt die folgende Anweisung?

double[] numbers = {0.99, 22.3, 55.01, 17.78};

Es handelt sich um Definition und Initialisierung eines Arrays mit vier Ele-menten. Das Array-Objekt wird auf dem Heap angelegt. Die in Klammernstehenden Werte werden den Elementen des Arrays in der angegebenenReihenfolge zugewiesen. Die Referenzvariable numbers erhält einen Ver-weis auf das Array-Objekt.

Page 312: Visual C# 2005 easy

Anhang – Antworten 311

Antworten zu Kapitel 13• Wann spricht man beim Methodenaufruf von Call by value?

Wenn der aufgerufenen Methode ein reiner Wert übergeben wird.

• Was bedeutet Call by reference?

Hierbei wird der aufgerufenen Methode ein Datenobjekt mittels eines Ver-weises bekannt gemacht. Mit anderen Worten: Die Methode erhält keineneinfachen Wert, sondern den Verweis auf ein Datenobjekt. Es handelt sichalso um eine Referenzübergabe.

• Welches Schlüsselwort muss im Kopf einer Methode auf jeden Fall verwen-det werden, wenn die Methode ohne Rückgabewert definiert ist?

void

• Was können Sie anhand des folgenden Methodenkopfs über die Methodexy() aussagen?

static int xy(double a, string b)

Die Methode xy() erwartet beim Aufruf zwei Argumente, eines vomDatentyp double, das zweite vom Datentyp string. Zudem besitzt dieMethode einen Rückgabewert (Datentyp int). Die genaue Wirkungsweiseder Methode ließe sich natürlich nur dem Anweisungsteil entnehmen.

• Welche Ausgabe erzeugt folgendes Programm?

class Program{ static void B(string myString) { Console.Write(myString); }

static void Main(string[] args) { A(); Console.WriteLine("weiter"); }

static void A() { Console.Write("Jetzt "); B("geht es "); }}Die Ausgabe lautet: Jetzt geht es weiter

Page 313: Visual C# 2005 easy

312 Anhang – Antworten

Main() ruft die Methode A() auf, diese wiederum die Methode B() mitdem Argument "geht es ". Nachdem die Anweisung von B() ausgeführtist, erfolgt der Rücksprung nach A(). Nach Beenden von A() landet derProgrammlauf schließlich wieder in Main(). Die Reihenfolge, in der dieMethodendefinitionen innerhalb der Klasse stehen, ist dabei nicht vonBedeutung.

Das entsprechende Projekt finden Sie unter Beispiele/Konsolenpro-gramme auf der Buch-CD (Projektname K13f ).

• Finden Sie den Fehler in folgender Methodendefinition:

static void Quad(int a){ Console.WriteLine("Das Quadrat von {0} ist {1}" , a, a * a); return "ENDE";}Da die Methode im Kopf als void, also ohne Rückgabewert, festgelegt ist,darf die return-Anweisung nur ohne Wertangabe verwendet werden(return;). Allerdings wird die Methode mit Erreichen der schließendengeschweiften Klammer } ohnehin verlassen, sodass der Einsatz desreturn-Befehls an dieser Stelle überflüssig ist. Denken Sie aber daran,dass bei Methoden, welche mit Rückgabewert definiert sind, der Gebrauchvon return (mit Wertangabe) zwingend vorgeschrieben ist.

Antworten zu Kapitel 14• Was ist ein Konstruktor?

Ein Konstruktor ist eine Methode, welche automatisch beim Instanziereneines Objekts aufgerufen wird.

• Was ist ein Standardkonstruktor?

Hierbei handelt es sich um einen parameterlosen Konstruktor.

• Fügen Sie Ihrer Klasse Rechteck eine nicht statische public-Methodehinzu, welche zwei Rechtecke miteinander vergleicht. Die Methode solltrue zurückgeben, falls beide Rechtecke deckungsgleich sind (also diegleiche Länge und Breite besitzen), ansonsten false. Nennen Sie dieMethode Vergleiche().

Das Rechteck, für das die Methode Vergleiche() aktuell aufgerufenwird, ist der Methode bekannt. Jedoch benötigt Vergleiche() einenParameter zur Übergabe eines Verweises auf das zu vergleichende Recht-eck.

Page 314: Visual C# 2005 easy

Anhang – Antworten 313

public bool Vergleiche(Rechteck zwei){ if(laenge == zwei.laenge && breite == zwei.breite) return true; else return false;}

Der direkte Zugriff auf Länge und Breite des übergebenen Rechtecks(zwei.laenge bzw. zwei.breite) ist hier erlaubt, da beide Objekte sichin derselben Klasse befinden. Möglicherweise haben Sie die entsprechen-den Eigenschaften verwendet (zwei.Laenge bzw. zwei.Breite), wasebenfalls korrekt ist.

• Formulieren Sie eine if-Bedingung zum Vergleich zweier Rechtecke a undb. Benutzen Sie dazu die eben erstellte Methode Vergleiche().

Diese sieht wie folgt dargestellt aus. Dabei spielt es keine Rolle, für wel-ches Rechteck Sie die Methode aufrufen, sodass sowohl

if(a.Vergleiche(b))

als auch Folgendes möglich ist:

if(b.Vergleiche(a))

• Welche Datenelemente würden Sie in einer Minimaldefinition einer KlasseKonto einrichten, welche ein Kundenkonto einer Bank repräsentierensoll?

Die Klasse Konto sollte auf jeden Fall Datenelemente für Kontostandsowie Kontonummer und Name (bzw. zwei Felder für Vor- und Nachname)des Kontoinhabers besitzen. Zu überlegen wären Felder für Kreditrahmenund Identifikationsnummer (PIN).

• Eröffnen Sie mit dieser fiktiven Klasse ein neues Konto. Instanzieren Siealso ein Objekt der Klasse Konto (unter Verwendung des Standardkon-struktors der Klasse) und nennen Sie die Referenzvariable meinKonto.

Die Anweisung lautet

Konto meinKonto = new Konto();

Page 315: Visual C# 2005 easy
Page 316: Visual C# 2005 easy

315

Glossar

Argumente

Informationen, die beim Aufruf einer →Methode an diese übergeben werden.Argumente stehen nach dem Methodennamen zwischen zwei runden Klam-mern, wobei die einzelnen Argumente durch Kommata (,) voneinander ge-trennt werden. Weitere Bezeichnungen für Argumente sind Übergabewerte,Übergabeparameter bzw. aktuelle →Parameter oder einfach Parameter.

Array

Datenstruktur, in der mehrere Werte gleichen Datentyps zusammengefasstund unter einem einzigen Namen mittels Indexangabe ansprechbar sind.

Ausdruck

Jeder Teil einer Anweisung, der für einen Wert steht (das gilt mitunter auch fürdie ganze Anweisung). Komplexe Ausdrücke setzen sich in der Regel aus Lite-ralen, →Variablen, Operatoren und auch Aufrufen von →Methoden (für derenRückgabewerte) zusammen.

Block

Alle Anweisungen, welche zwischen einer öffnenden und der schließenden ge-schweiften Klammer gleicher Ordnung stehen ({…}).

Compiler

Software zum Übersetzen des Quellcodes, bei herkömmlichen Programmier-sprachen in Maschinencode. Der Compiler von C# erzeugt einen maschinen-unabhängigen Zwischencode, den so genannten Intermediate Language Code(IL-Code).

Debugger

Programm, das bei der Anwendungsentwicklung für die Fehlersuche einge-setzt wird. Die Visual C# 2005 Express Edition beinhaltet auch einen integrier-ten Debugger.

Dekrementieren

Vermindern des Werts einer →Variablen um den Betrag eins.

Page 317: Visual C# 2005 easy

316 Glossar

Destruktor

Gegenstück zum →Konstruktor. Die Destruktor-Methode (→Methode) wirdaufgerufen, wenn ein Objekt (→Instanz) gelöscht wird. Der Definition einesDekonstruktors kommt in C# eine nur geringe Bedeutung zu.

Eigenschaften

Spezielle →Methoden, die den Zugriff auf →Felder mit der gewohnten Syntaxgestatten. Ein Programmierer, der eine →Klasse verwendet, wendet den Be-zeichner für eine Eigenschaft im Code praktisch genauso an, als greife er aufein public-Feld zu. Tatsächlich wird bei Ausführung jedoch die entsprechendeMethode – eben die Eigenschaft – aufgerufen.

Ereignisse

Zustandsänderungen, auf die Steuerelement-Objekte (→Steuerelement) undauch Formulare reagieren. Jedem Steuerelement-Objekt und auch einem For-mular sind spezifische Ereignisse zugeordnet, welche beim Programmlaufdann gegebenenfalls durch ein bestimmtes Benutzerverhalten – z.B. einenMausklick auf eine Schaltfläche – oder andere Ursachen (z.B. abgelaufene Zeitbei einem Timer) ausgelöst werden.

Eventhandler

Spezielle →Methoden, die immer dann ausgeführt werden, wenn ein Steuer-element-Objekt (→Steuerelement) ein bestimmtes →Ereignis meldet. Manspricht auch von Ereignisbehandlungsroutinen oder Ereignishandlern.

Felder

In C# die Datenelemente einer →Klasse. Praktisch handelt es sich dabei um→Variablen, die innerhalb einer Klasse definiert sind. Jedes Objekt erhält beiseiner Instanzierung (→Instanz) eine Kopie jedes in der Klasse definierten Fel-des, sodass später die aktuell in den Feldern gespeicherten Werte den Zustandeines bestimmten Objekts ausmachen. Für den Zugriff auf die Felder einerKlasse sieht C# spezielle →Methoden vor – die so genannten →Eigenschaften.

IDE

Abkürzung für »Integrated Development Environment« (integrierte Entwick-lungsumgebung). Software, in welcher alle notwendigen Programmierwerk-zeuge unter einer Benutzeroberfläche zusammengefasst sind.

Page 318: Visual C# 2005 easy

Glossar 317

Inkrementieren

Erhöhen des Werts einer →Variablen um den Betrag eins.

Instanzen (von Klassen)

Auch »Objekt (einer Klasse)« genannt. Ein Element im Arbeitsspeicher, das ge-wissermaßen die reale, »lebendige« und tatsächlich nutzbare Umsetzung ei-ner →Klasse darstellt. Während die Klasse mehr einen abstrakten Bauplandarstellt, der das Wesen späterer nutzbarer Elemente (also Objekte) be-schreibt, ist ein Objekt etwas Greifbares, das →Methoden und →Eigenschaf-ten zur Verfügung stellt und über eigene Datenspeicherbereiche verfügt. DasErzeugen eines Objekts unter Vorlage einer Klasse wird als »Instanzieren« be-zeichnet. Ein Objekt wird meist an tatsächlich existierende Dinge angelehnt.Beispielsweise könnte ein Objekt einer Klasse namens »Konto« ein Konto miteiner bestimmten Kontonummer darstellen. Das Objekt enthält dann nicht nurdie aktuellen Daten über das Konto, sondern stellt auch Methoden zum Um-gang des Kontos zur Verfügung. Die gespeicherten Daten des Objekts sindspezifisch, die Methoden sind bei jedem Objekt gleich.

Man kann Objekte auch gewissermaßen als »→Variablen« eines Klassentypssehen. Genau genommen steht in C# bzw. dem .NET hinter jedem Datenobjekteine Klasse. Datenobjekte elementarer Datentypen wie int werden dennochals Variablen bezeichnet.

Kapselung

In der objektorientierten Programmierung die Bezeichnung für das Prinzip,den inneren Aufbau einer →Klasse nach außen hin zu verbergen. Die Benut-zung der Klasse erfolgt dabei allein über genau definierte Schnittstellen, in derRegel über öffentliche →Methoden (wozu in C# auch die →Eigenschaften alsspezielle Methoden gehören). Solange diese Schnittstellen – z.B. Signaturoder Rückgabewert von public-Methoden – nicht geändert werden, habenÄnderungen innerhalb der Klasse keinerlei Auswirkungen auf Programme, wel-che die Klasse verwenden. Dadurch können die Wartungsarbeiten am Codesolcher Programmen reduziert werden, was eines der hauptsächlichen Zieleder Kapselung ist. Aber auch der Aspekt, dass der Programmierer keine Kennt-nisse darüber haben muss, wie die Klasse intern arbeitet, geht mit der Kapse-lung einher. Der Programmierer nutzt die Klasse einfach und verlässt sichdarauf, dass diese das durchführt, für was sie bestimmt wurde. Details dertechnischen Umsetzung bleiben im Verborgenen und auf Funktionalitäten,welche negativen Einfluss auf das Verhalten der Klasse haben könnten, etwabei Fehlanwendung durch den Programmierer, hat der Programmier erst gar

Page 319: Visual C# 2005 easy

318 Glossar

keinen Zugriff. Damit bieten Klassen im Allgemeinen eine höhere Stabilität undFehlertoleranz, als wenn auf herkömmliche Weise, also nicht objektorientiertprogrammiert werden würde.

Klassen

Eine Art Schablone, die einen eigenen Datentyp beschreibt. Eine Klasse ist so-zusagen der abstrakte Bauplan für künftige »→Variablen« – Objekte oder →In-stanzen genannt – dieser Klasse (dieses Typs). Die Objekte vereinen Daten mitihrer Funktionalität. Letztere wird durch die in der jeweiligen Klasse definierten→Methoden bestimmt.

Konkatenation

Aneinanderhängen von Zeichenketten mittels des Operators »+« (Konkatena-tionsoperator).

Konstruktor

Spezielle →Methode, die beim Erzeugen eines Objekts (→Instanz) einer→Klasse aufgerufen wird. Die Konstruktormethode kommt also für jedes Ob-jekt genau ein Mal zur Ausführung.

Laufzeitumgebung

Eine bestimmte Software (»Umgebung«), die ein Programm benötigt, damit esausgeführt werden kann. Die Laufzeitumgebung für C#-Programme bildet das.NET Framework.

Literal

Steht im Quelltext für einen unveränderlichen Wert.

Namensräume

Übergreifender Gültigkeitsbereich, mit dem sich mehrere →Klassen zusam-menfassen lassen. Dabei müssen die Bezeichner der Klassen nur in ein unddemselben Namensraum eindeutig sein. Es ist also der Fall möglich, dass zweiverschiedene Klassen denselben Namen tragen, vorausgesetzt, die Klassensind in verschiedenen Namensräumen definiert.

.NET Framework

Bildet die →Laufzeitumgebung für C#-Programme.

Page 320: Visual C# 2005 easy

Glossar 319

Objekte (von Klassen)

→Instanzen einer →Klasse.

Parameter

Lokale →Variablen einer →Methode, die beim Aufruf mit den übergebenenWerten (→Argumenten) initialisiert werden. In der Definition einer Methodestehen die Parameter innerhalb der runden Klammern unmittelbar nach demBezeichner für die Methode.

Standardkonstruktor

Parameterloser (→Parameter) →Konstruktor.

Statische Klassenelemente

Beziehen sich nicht auf eine →Instanz der →Klasse, sondern auf die Klasseselbst. Folgerichtig erfolgt der Zugriff auf statische →Methoden sowie stati-sche Datenelemente nicht mit dem Objekt-, sondern mit dem Klassennamen.Der aktuelle Wert eines statischen Datenelements ist für alle erzeugten Instan-zen einer Klasse gleich.

Steuerelemente

Komponenten von grafischen Benutzeroberflächen, z.B. Schaltflächen, Menü-leisten, Kontrollkästchen, Textfelder usw.

System

Vordefinierter →Namensraum, in dem eine Reihe von wichtigen →Klassen de-finiert sind (z.B. die Klasse Console sowie die Klassen für die grundlegendenDatentypen). In den Beispielprogrammen ist der Namensraum System mit derAnweisung using System; eingebunden und damit sind die darin definiertenKlassen mit ihren →Methoden verfügbar.

Variable

Benannter Ort im Arbeitsspeicher, an dem Werte abgelegt, gelesen und auchverändert werden können.

Windows-Programme

Anwendungen, die eine grafische Benutzeroberfläche (engl. »Graphical UserInterface«, daher auch GUI-Programme genannt) zur Verfügung stellen.

Page 321: Visual C# 2005 easy

320 Glossar

Zugriffsspezifizierer

Angaben in der Klassendefinition, die den Zugriff von →Instanzen einer→Klasse auf deren Elemente (→Felder, →Eigenschaften und →Methoden) re-geln. Elemente können auf diese Weise sowohl als öffentlich (public) alsauch als nicht öffentlich (private) deklariert werden. Bei nicht öffentlichenElementen ist kein Zugriff von außerhalb der Klasse möglich. Falls für ein Ele-ment der Klasse nichts explizit festgelegt wurde, gilt die Voreinstellung pri-vate.

Page 322: Visual C# 2005 easy

321

Liebe Leserin, lieber Leser,herzlichen Glückwunsch, Sie haben es geschafft. Visual C# 2005 ist Ihnen nunvertraut. Ist es Ihnen nicht viel leichter gefallen, als Sie am Anfang dachten?Genau das ist das Ziel unserer Bücher aus der easy-Reihe. Sie sollen helfen, er-folgreich die ersten Schritte zu gehen, und den Leser auf keinen Fall mit unver-ständlichem Fachchinesisch überhäufen.

Als Lektorin hoffe ich, dass Sie durch das Buch die richtige Unterstützung be-kommen haben. Denn für Ihre Zufriedenheit stehen alle Beteiligten mit ihremNamen: der Verlag, die Autoren, die Druckerei.

Aber niemand ist perfekt. Wenn Sie Anregungen zum Buch und zum Konzepthaben: Schreiben Sie uns. Und wenn Sie uns kritisieren wollen: Kritisieren Sieuns.

Ich verspreche Ihnen, dass Sie Antwort erhalten.

Denn nur durch Sie werden wir noch besser.

Ich freue mich auf Ihr Schreiben!

Brigitte Alexandra Bauer-SchiewekLektorin Markt + TechnikPearson Education Deutschland GmbHMartin-Kollar-Str. 10-1281829 München

E-Mail: [email protected]: http://www.mut.de

Page 323: Visual C# 2005 easy
Page 324: Visual C# 2005 easy

Stichwortverzeichnis 323

Stichwortverzeichnis

<Operator 158

!Operator 161

!=Operator 158, 174

%Modulo-Operator 143

&&Operator 161, 164

*Operator 143

*/Kommentarzeichen 67

.exe-Dateien 13, 14, 57

.NET Framework 12, 18, 22, 23, 24, 25, 26, 57, 89, 90, 234, 267, 282

Installation 27.NET Framework 2.0

Beta-Versionen 27.NET siehe .NET Framework/

Operator 143/*

Kommentarzeichen 67//

Kommentarzeichen 51, 67==

Operator 158, 160, 174>

Operator 158>=

Operator 158||

Operator 161, 164

A\a

Steuerzeichen 83Addition

arithmetische 143, 163mathematische 93, 111

Additionsoperator 80

AnchorEigenschaft 287, 288

Anweisungleere 61

Anweisungen 12, 48, 49, 63, 96, 234Anweisungsende 61, 62, 65args 50Argumente 131, 239Array

Klasse 226Array-Objekt 222, 225, 230Arrays 206, 220, 221, 222, 223, 224

definieren von 222initialisieren von 230sortieren von 226, 295

ASCII-Zeichen 91Assembler 16Assemblies 57Attribute

von Eigenschaften 286Aufruf

von Methoden 76, 114Aufrufer 237Ausdrücke

komplexe 140, 141logische 158, 159, 160

Ausgabemethoden 300Ausrichten

von Textfeldern 288

B\b

Steuerzeichen 83BackColor

Eigenschaft 289Backspace

Steuerzeichen 83Basic

Programmiersprache 53Befehle siehe AnweisungenBenutzereingaben

implementieren von 143, 144verarbeiten von 86, 88, 103

Page 325: Visual C# 2005 easy

324 Stichwortverzeichnis

Bezeichner 54, 56, 60, 64, 88, 234, 270für Klassen 277von Variablen 99, 101, 140, 148

BezeichnerwahlRegeln 88, 89, 101, 103

binVerzeichnis 57

Blitz-Symboldes Eigenschaftenfensters 293

Blöcke 62, 63Blockstruktur

verschachtelte 62bool

Datentyp 90, 91Boolean

Klasse 90break 178, 188Button

Steuerelement 288, 290, 299byte

Datentyp 89, 90

CC

Programmiersprache 16, 22, 48, 53, 122C#-Compiler 22, 25C#-Programme

Aufbau 48, 49, 50, 51, 52C++

Programmiersprache 16, 50, 53, 126, 178Call by reference 243Call by value 241camelCasing 102, 260Carriage Return

Steuerzeichen 83case

Schlüsselwort 177case-Konstante 178case-Marke 179case-Zweig(e) 178, 186Casting siehe Cast-OperationCast-Operation 129, 134, 135Char

Klasse 90, 116char

Datentyp 90, 91, 111

char-Literale 113CheckBox

Steuerelement 290, 299, 300Checked

Eigenschaft 299, 300CheckedChanged

Ereignis 299class

Schlüsselwort 53, 54, 254Click

Ereignis 293, 294, 299Click()

Methode 293Cobol 16, 53Codeansicht 284Codeausschnitte

einfügen 297umschließen 297

Compiler 14, 17, 18, 25, 48, 51, 78, 80, 97, 111, 141, 165, 172, 173, 186, 230

ConsoleKlasse 40, 77, 78, 79, 103, 114, 277

Console.ReadLine() 17, 40, 48, 103, 104, 105, 114, 132, 144

Console.Write() 13, 49, 76, 77, 78, 79, 104, 136, 300

Console.WriteLine() 17, 39, 48, 49, 63, 76, 77, 78, 79, 95, 104, 136, 300

constSchlüsselwort 122

contents.htmDatei 27

ConvertKlasse 131, 133, 135, 277

csc.exe 25

DD

Formatierungszeichen 151, 152d

Formatierungszeichen 151, 152Datei

ausführbare 13binärkodiert 16

Datenelemente 252, 256, 257statische 272

Page 326: Visual C# 2005 easy

Stichwortverzeichnis 325

Datentyp(en) 60, 61, 78, 86, 87, 88, 89, 90, 206

boolescher 89, 91elementare 115, 206

Datenverbindungen 44Debug

Verzeichnis 57default

Marke 178, 179Zweig 186

Dekrementoperator 197Designer siehe EntwurfsfensterDestruktoren 267, 269Division

arithmetische 143, 163Double

Klasse 90, 116double

Datentyp 90, 119, 127do-while-Schleife 198, 199, 297

EEigenschaften

Ansicht 285spezielle Methoden 252, 262, 264, 286zusammengesetzte 286

Eigenschaftenfenster 45, 284, 285, 286, 293, 294, 300

else-Zweig 172, 173Endlosschleife(n) 196, 296Entwurfsansicht 284, 288Entwurfsfenster 291, 301Ereignis-Ansicht 285, 293Ereignisbehandlungsroutinen 293Ereignishandler 293Ereignisse 293, 294

Beschreibung 293Escape-Sequenzen 83Eventhandler siehe Ereignishandlerexplizite Typumwandlung siehe Typ-

umwandlung explizite

FF

Formatierungszeichen 149, 150, 151

\fFormatierungszeichen 149, 151Steuerzeichen 83

false 91, 126, 159, 160Fehler

logische 71Fehlerliste 41Fehlermeldungen

beim Kompilieren 96, 97, 106, 115, 130, 178

Felder 101, 252, 253, 254, 256, 259, 262, 265, 286

initialisieren von 258statische 272

FontEigenschaft 286

foreach-Schleife 227, 228ForeColor

Eigenschaft 289Form 282, 291, 292Form1.cs 284, 301Form1.Designer.cs

Datei 284Formalparameter siehe Parameter formaleFormat

Menü 288Formatierung

des Quelltextes 72von Bildschirmausgaben 147, 148, 149,

150, 151Formatierungszeichen 149Formatzeichen siehe FormatierungszeichenFormfeed

Steuerzeichen 83Formular 282, 284, 285, 286, 291, 292, 293Formulargröße 290for-Schleife 199, 200, 224, 225, 227, 294Funktionen 53

GGarbage Collector 269Get-Methoden 263Getter 263GetType()

Methode 113, 115, 116

Page 327: Visual C# 2005 easy

326 Stichwortverzeichnis

Gleitkommawerte 120, 149, 152Gleitkommazahlen 120Graphical User Interface 37Gruppe

von Steuerelementen 291GUI siehe Graphical User InterfaceGültigkeitsbereich 270, 277

von Schleifenvariablen 228von Variablen 102, 202, 203

HHeap 222, 269Height

Attribut 286, 289Hexadezimalsystem 154Hochsprachen 16

IIDE 18, 44, 289if 164, 165, 166, 167if-else 172, 173, 178IL-Code siehe Intermediate Language Codeimplizite Typumwandlung siehe Typ-

umwandlung impliziteInitialisierung

von Arrays 230von Konstanten 122von Variablen 98

Inkrementoperator 197Instanzen

von Klassen 252, 258, 286Instanzieren

von Objekten 258, 267, 270int 60

Datentyp 78, 89, 90, 110, 113, 118, 254Int32

Klasse 90, 116, 118Int64

Klasse 116, 118Integer 78

Arrays 222Datentyp 111Konstanten 110Literale 110Werte 111, 151

Integrated Development Environment siehe IDE

Integrierte Entwicklungsumgebung siehe IDE

IntelliSense 41, 297Intermediate Language Code 22, 25, 26, 57ItemClicked

Ereignis 299

JJava 16, 23, 50, 178Java Virtual Machine 23, 24JIT Compiler Manager 26JITter siehe Just-in-Time-CompilerJust-in-Time-Compiler 26JVM siehe Java Virtual Machine

KKlasse

Definition 53, 54Klassen 52, 53, 63, 114, 250, 251, 252,

253, 277Definition 254vordefinierte 77

Kommandozeile 50Kommentare 67Kommentarzeichen 51, 67Kompilieren 13, 14, 15, 18, 36, 51, 56, 64, 97

von C#-Programmen 22, 25Komponentenfach 291Konsole(n) 36, 37, 78, 103, 104

Anwendung 38Fenster 40Programme 36, 37, 42

Konstante(n) 108, 109, 110, 111benannte 110, 122, 123boolesche 126unbenannte 110

Datentyp 111Konstruktor

Definition 268Konstruktoren 267Kontrollkästchen 290Kontrollstrukturen 63, 91, 172Konvertierung siehe Typumwandlung

Page 328: Visual C# 2005 easy

Stichwortverzeichnis 327

LL

Datentyp-Suffix 118l

Datentyp-Suffix 118Label

Steuerelement 290, 299Laufvariable 199, 201, 202Laufzeitfehler 71, 132, 152, 223Laufzeitumgebung 24Laufzeitverhalten

von Programmen 24Lebensdauer 269

von lokalen Variablen 241von Variablen 203

Leerzeichen 60Linux

Betriebssystem 17Literale 110, 111, 112, 113, 115, 119, 127

ganzzahlige 118Lizenzbedingungen

Visual C# 2005 Express EditionInstallation 28

logische Verneinung siehe Negation logische

longDatentyp 113, 116, 118, 127

MMain()

Methode 39, 50, 51, 52, 54, 55, 56, 62, 63, 175, 234, 236, 238, 272

Maschinencode 14, 17, 22, 26Maschinensprache 14, 26Meldungsfenster 300MenuStrip

Steuerelement 290, 291, 292, 299MessageBox

Klasse 300, 301MessageBox.Show() 300, 301Methode(n) 49, 53, 63, 232, 233, 234, 237,

241, 245, 252, 253, 254, 256aufgerufene 236aufrufende 236, 237Definition von 234, 235

statische 272überladen (von) 79, 270vordefinierte 234

Methodenaufruf 239Methodenblock 62, 63Methodendefinition siehe Methoden

Definition vonMethodenkopf 50, 52, 234Methodenparameter siehe ParameterMethodenrumpf 50, 51, 62, 234Microsoft SQL Server 2005 27Modulo

Operation 143, 163Operator 142

MSDN Express Library 29MSDN Online 29Multiplikation

arithmetische 143, 163

NN

Formatierungszeichen 151\n

Steuerungszeichen 83Formatierungszeichen 151

NamensraumDefinition 277, 278

Namensräume 55, 101, 277, 278selbst definierte 277

namespaceSchlüsselwort 277

namespaces siehe NamensräumeNegation

logische 161new 208

Operator 258Schlüsselwort 204, 230

NewlineSteuerzeichen 83

Next Generation Windows Services 25Next()

Methode 205, 206NGWS siehe Next Generation

Windows Services

Page 329: Visual C# 2005 easy

328 Stichwortverzeichnis

Notationvon Bezeichnern 101, 102, 103von private-Feldern 260von public-Feldern 260

Notepad 12

OObjekte

instanzieren 258von Klassen 114, 115, 207, 250, 251,

252, 253objektorientierte Programmierung 52, 252Oder

logisches 161, 164OOP siehe objektorientierte

ProgrammierungOperanden 141, 142, 158, 159Operationen 89

arithmetische 143Operator(en) 60, 64

arithmetische 140, 141, 142, 163logische 160, 161unäre 142, 161

Optionsfelder 290

PParameter 50, 76, 79, 102, 226

aktuelle 239der Main()-Methode 56formale 239, 241von Methoden 131, 239

Parameterliste 204, 239, 268, 270Parameterübergabe 238, 242, 243Pascal 16, 53PascalCasing 102, 122, 260Platzhalter 147, 148, 154Popup

Ereignis 299, 301Portierbarkeit 22Position

von Steuerelementen 289Postfix-Notation 197Präfix-Notation 197Prioritätsskala

von Operatoren 163

Prioritätsstufenvon Operatoren 162, 164

privateZugriffsspezifizierer 256, 257, 259

ProgramKlasse 39, 40, 54, 56, 63

Program.csDatei 44

Programm 15Programmdatei 13, 14, 57Programmentwicklung 12Programmiersprachen

case-sensitive 77objektorientierte 53, 262typsichere 126

Programmierstil 66, 67Programmierung

objektorientierte 116, 252Programmverzweigung 25Projektmappen 39, 43, 44Projektmappen-Explorer 44, 45, 255, 284Projektmappenverzeichnis 42Projektordner 57Projektvorlagen 38Prozessor 14, 51public

Zugriffsspezifizierer 256, 257Punktoperator 77, 297

QQuellcode 12, 13, 14, 15, 16, 17, 18, 22, 36,

48, 55, 62, 64Quellcode-Datei 24Quelltext siehe QuellcodeQuickInfo 290, 292, 299

R\r

Steuerzeichen 83RadioButton(s)

Steuerelement 290, 291, 299, 300Random

Klasse 204ReadLine()

Methode siehe Console.ReadLine()

Page 330: Visual C# 2005 easy

Stichwortverzeichnis 329

readme.htmDatei 27

Referenztypen 206, 207, 222Referenzübergabe siehe Call by referenceReferenzvariablen 205, 222, 269, 288return

Anweisung 175, 187Befehl 246

Reverse()Methode 227

RichTextBoxSteuerelement 290, 299

Rückgabewertder Methode ReadLine() 104von Ausdrücken 158, 159von Methoden 104, 105, 117, 131, 245,

246Runtime Environment siehe Laufzeit-

umgebung

SSchaltfläche

Steuerelement 293Schleifen 192, 193, 194, 195Schleifenvariable 199, 201, 202, 213, 228Schlüsselwörter 41, 53, 60, 64, 88, 90, 91Seitenvorschub

Steuerzeichen 83Semikolon

Anweisungsende 61, 62, 65Service Pack 26Set-Methoden 263Setter 263setup.exe

Installationsdatei 27Show()

Methode 300, 301Signatur

von Methoden 270Size

Eigenschaft 286, 289Sleep()

Methode 219SnapLines 288

Sort()Methode 226, 227

Speicherbedarfvon Datentypen 89

Speicherverwaltungdes .NET Framework 269

Standardanwendungstypen 38Standarddatentypen 115, 116Standardereignisse 299

von Steuerelementen 294Standardkonstruktor 267

selbst definierter 268Standardmenü

einrichten 291static 52, 53

Schlüsselwort 246, 272Statische Klassenelemente 272Steuerelemente 282, 284, 285, 288, 290,

293, 299Namen von 288

Steuerelement-Klassen 286Steuerzeichen 81, 82, 83, 84, 112String

Klasse 90, 116string

Datentyp 78, 79, 89, 90, 105, 111, 128, 206

Stringkonstanten 78string-Konstanten 110string-Literale 110Strings 60, 78, 89, 97, 110, 124, 147, 252Stringvergleiche 174Stringverknüpfung 79, 80, 93, 128Subtraktion

arithmetische 143, 163switch 172, 177, 178, 187switch-Ausdruck 178, 179Syntaxfehler 49, 71, 223Syntaxregeln 48, 58, 59, 60, 61, 62System

Namensraum 55, 118, 125, 219, 277System.Windows.Forms

Namensraum 300, 301

Page 331: Visual C# 2005 easy

330 Stichwortverzeichnis

T\t

Steuerzeichen 83Text

Eigenschaft 286, 288, 297TextAlign

Eigenschaft 287Textbausteine 60, 61, 64TextBox

Steuerelement 284, 290, 299TextChanged

Ereignis 294, 299Thread

Klasse 219Threading

Namensraum 219ToBoolean()

Methode 131ToChar()

Methode 131ToDouble()

Methode 131, 132, 144ToInt32()

Methode 131ToInt64()

Methode 131Token siehe TextbausteineToolbox 45, 284, 291ToolTip

Steuerelement 290, 292, 299, 301ToolTip auf ToolTip1

Eigenschaft 292ToolTipTitle

Eigenschaft 292ToString()

Methode 131, 133, 297Trennzeichen 61true 91, 126, 159, 160, 161Type

Datentyp 117Typkonvertierung siehe TypumwandlungTypsicherheit

von C# 127

Typumwandlung 174automatische siehe Typumwandlung

impliziteexplizite 125, 129, 130, 131, 132, 133implizite 124, 125, 126, 127, 128, 158

UÜberladen

von Methoden 270Und

logisches 161, 164Unicode 91, 127Unix

Betriebssystem 17using

Schlüsselwort 55using System 55, 277using-Direktive 219

V\v

Steuerzeichen 83value 263Variablen 60, 80, 86, 87, 88, 89, 92, 93, 98,

100, 101, 104, 105, 107, 115, 197Definition von siehe Variablendefinitionlokale 102, 203, 241

Variablenbezeichner siehe Bezeichner von Variablen

Variablendefinition 88, 90, 91, 92, 93, 148Vereinbarung

von Variablen 123Vergleichsoperatoren 158, 159Verknüpfung

von Strings siehe Stringverknüpfungvon Zeichenketten siehe String-

verknüpfungVerknüpfungsoperator 79, 80, 97Verzweigungen 156, 157, 158, 159, 160Video-Animationen

von Microsoft 45Visual Basic 18Visual C# 2005 Express Edition 18, 36, 37,

38, 39, 40, 45, 57, 290Code-Editor 41

Page 332: Visual C# 2005 easy

Stichwortverzeichnis 331

Formatierungseinstellungen 72Hilfe 45Installation 26, 27, 28, 29, 30, 31, 33

Systemvoraussetzungen 27Online-Hilfe 300, 302Projekte 37, 38, 39, 40, 41, 42, 43

Visual C# Express siehe Visual C# 2005 Express Edition

Visual Studio 72Visual Studio .NET 18, 282Visual Studio 2005 26, 27void 52, 53, 64

Schlüsselwort 246

WWahrheitswerte 89, 91Warnmeldungen

beim Kompilieren 106Warteschleifen 219Web-Browser

erstellen 302WebBrowser

Steuerelement 292Wert

konstante 60Werte

konstante 60, 78, 110kontrollierte 93

Wertebereichdes Datentyps char 91des Datentyps double 90des Datentyps int 78, 90, 113des Datentyps long 113von Datentypen 89

Wertetypen 206, 207Wertübergabe siehe Call by valuewhile-Schleife 194, 195Width

Attribut 286, 289Wiederholungsanweisungen 192, 193,

194, 195Windows 2000

Betriebssystem 26Windows Forms 282, 284, 300Windows Forms-Designer 282, 286

Windows Server 2003Betriebssystem 26

Windows XPBetriebssystem 26

Windows-Anwendungen 280, 281, 282, 284Windows-Programme 42Windows-Programmierung 37Write()

Methode siehe Console.Write()WriteLine()

Methode siehe Console.WriteLine()

XX

Formatierungszeichen 151, 152x

Formatierungszeichen 151, 152

ZZählvariable 228Zeichenkette(n) 60, 78, 80, 89, 110, 252

Konstanten 78leere 81

Zufallszahlen 204Zugriffsspezifizierer 259Zuweisung 93, 94, 95, 124Zuweisungsoperator 60, 61, 93, 94, 100,

124, 163Zwischencode 22, 26, 57Zwischenraumzeichen 64, 97

Page 333: Visual C# 2005 easy

Häufig verwendete Steuerelemente

Steuerelemente und die dazugehörigen Standardereignisse

Arithmetische Operationen

Wichtige Datentypen

Steuerelement BeschreibungLabel Beschreibungstext, in der Regel als Beschriftung für andere Steuer-

elemente gedachtTextBox Textfeld zur Eingabe von TextRichTextBox Textfeld mit umfangreichen FormatierungsmöglichkeitenButton Schaltfläche zum AnklickenRadioButton Optionsschaltfläche, die aktiviert oder deaktiviert werden kannCheckBox Kontrollkästchen, das aktiviert oder deaktiviert werden kannMenuStrip Zeigt eine obere Menüleiste in bekannter Form, auch kaskadiert, anToolTip QuickInfo für andere Steuerelemente

Steuerelement Standardereignis BeschreibungLabel Click Tritt ein, wenn ein Benutzer das Label anklicktTextBox TextChanged Tritt mit jeder Änderung des enthaltenen Texts einRichTextBox TextChanged Tritt mit jeder Änderung des enthaltenen Texts einButton Click Tritt ein, wenn ein Benutzer den Button anklicktRadioButton CheckedChanged Tritt ein, wenn sich der Wert der Checked-Eigen-

schaft ändertCheckBox CheckedChanged Tritt ein, wenn sich der Wert der Checked-Eigen-

schaft ändertMenuStrip ItemClicked Tritt ein, sobald ein Benutzer auf einen Menü-

eintrag klicktToolTip Popup Tritt unmittelbar vor dem Anzeigen der QuickInfo

ein

Operator steht für ...+ Addition- Subtraktion* Multiplikation/ Division% Modulo (Rest einer Division)

Alias Größe Datentypint 32 Bit Int32 double 64 Bit Double char 16 Bit Char string 16 Bit pro Zeichen String bool 1 Bit Boolean

Page 334: Visual C# 2005 easy

Vergleichsoperatoren

Logische Operatoren

Syntax der switch-Anweisungswitch (Ausdruck){ case Konstante_1: Anweisung(en) break; case Konstante_2: Anweisung(en) break; … case Konstante_n: Anweisung(en) break; default: Anweisung(en) break;}

Beispiel for-Schleifeint i;for (i = 1; i < 5; i++){ Console.WriteLine("{0}. Zeile", i);}

Operator Bedeutung== gleich!= ungleich> größer als>= größer als oder gleich< kleiner als<= kleiner als oder gleich

Operator Bedeutung&& logisches Und|| logisches Oder! Negation (logische Verneinung)

Page 335: Visual C# 2005 easy

Copyright Daten, Texte, Design und Grafiken dieses eBooks, sowie die eventuell angebotenen

eBook-Zusatzdaten sind urheberrechtlich geschützt. Dieses eBook stellen wir lediglich als persönliche Einzelplatz-Lizenz zur Verfügung!

Jede andere Verwendung dieses eBooks oder zugehöriger Materialien und Informationen, einschliesslich

• der Reproduktion,

• der Weitergabe,

• des Weitervertriebs,

• der Platzierung im Internet, in Intranets, in Extranets,

• der Veränderung,

• des Weiterverkaufs

• und der Veröffentlichung

bedarf der schriftlichen Genehmigung des Verlags. Insbesondere ist die Entfernung oder Änderung des vom Verlag vergebenen

Passwortschutzes ausdrücklich untersagt!

Bei Fragen zu diesem Thema wenden Sie sich bitte an: [email protected]

Zusatzdaten Möglicherweise liegt dem gedruckten Buch eine CD-ROM mit Zusatzdaten bei. Die

Zurverfügungstellung dieser Daten auf unseren Websites ist eine freiwillige Leistung des Verlags. Der Rechtsweg ist ausgeschlossen.

Hinweis Dieses und viele weitere eBooks können Sie rund um die Uhr

und legal auf unserer Website

http://www.informit.de

herunterladen