In diesem Kapitel erarbeiten wir die Grundlagen der Programmierung mit Hilfe der integrierten Entwicklungsumgebung Microsoft Visual Studio 2005 und der .NET-Technologie von Microsoft. Als Programmiersprache verwenden wir Visual C#. In diesem Kapitel beschäftigen wir uns mit ● der Erstellung von eigenen Programmen mit Hilfe des .NET-Frameworks, ● der Verwendung von Variablen, Konstanten und Datentypen, ● den verschiedenen Arraytypen und dem Einsatz von Arrays, ● Verzweigungen und Schleifen sowie der Behandlung von Laufzeitfehlern und ● der Verwendung von Prozeduren und Funktionen. be 1 Programmieren mit Visual C# Lerneinheit 2: Verzweigungen und Arrays ro Lerneinheit 1: Erste Schritte in .NET Lernen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 if-Verzweigung . . . . . . . . . . . . . . . . . . . 2 switch-Verzweigung . . . . . . . . . . . . . . . 3 Arrays und Collections . . . . . . . . . . . . . . 4 Zufallszahlen . . . . . . . . . . . . . . . . . . . . . . Üben . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Sichern . . . . . . . . . . . . . . . . . . . . . . . . . . . . Wissen . . . . . . . . . . . . . . . . . . . . . . . . . . . . sep Lernen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 1 Visual Studio 2005 . . . . . . . . . . . . . . . . . . 2 2 Das .NET-Framework . . . . . . . . . . . . . . . . 3 3 Das erste Programm . . . . . . . . . . . . . . . . 5 4 Werte und Typen . . . . . . . . . . . . . . . . . . . 8 Üben . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 Sichern . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 Wissen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 Lerneinheit 3: Schleifen und Zuweisungsoperatoren Le Lernen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Zählerschleifen . . . . . . . . . . . . . . . . . . . . 2 Bedingte Schleifen . . . . . . . . . . . . . . . . . 3 Zuweisungsoperatoren . . . . . . . . . . . . . 4 Gültigkeitsbereich von Variablen . . . . . . Üben . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Sichern . . . . . . . . . . . . . . . . . . . . . . . . . . . Wissen . . . . . . . . . . . . . . . . . . . . . . . . . . . . Lerneinheit 4: Windows-Formulare und Controls 24 24 25 27 28 29 30 30 Lerneinheit 5: Fehlerbehandlung, Methoden und Strukturen Lernen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Fehlerbehandlung . . . . . . . . . . . . . . . . . 2 Prozeduren und Funktionen . . . . . . . . . 3 Enumerationen . . . . . . . . . . . . . . . . . . . . 4 Strukturen . . . . . . . . . . . . . . . . . . . . . . . . Üben . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Sichern . . . . . . . . . . . . . . . . . . . . . . . . . . . . Wissen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 40 42 47 47 48 49 50 Kapitelrückblick . . . . . . . . . . . . . . . . . . . . . 52 Softwareentwicklung 13 13 16 17 20 21 22 22 Lernen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 WinForm-Controls . . . . . . . . . . . . . . . . . 2 Eventhandler . . . . . . . . . . . . . . . . . . . . . . 3 Formularklasse . . . . . . . . . . . . . . . . . . . . . 4 Zugriffsmodifizierer . . . . . . . . . . . . . . . . Üben . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Sichern . . . . . . . . . . . . . . . . . . . . . . . . . . . Wissen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 32 34 35 35 36 38 38 Ich bin Ms. Check! Ich kenne mich sehr gut aus und habe auf jede Frage eine verständliche Antwort. Ich bin Mr. What! Ich kenne mich ganz gut aus, habe aber immer wieder einige Zwischenfragen … 1 Programmieren mit Visual C# Lerneinheit 1: Erste Schritte in .NET Lernen Üben Sichern Wissen Lerneinheit 1 Erste Schritte in .NET Alle SbX-Inhalte zu dieser Lerneinheit findest du unter der ID: 1139. In dieser Lerneinheit erkunden wir die integrierte Entwicklungsumgebung Visual Studio 2005 und schreiben damit unser erstes Programm. Wir arbeiten mit Variablen und Konstanten und lernen die unterschiedlichen Datentypen kennen. Wir lernen, wofür wir das .NET-Framework benutzen können und was sich hinter Abkürzungen wie CLR oder CIL verbirgt. Wir beschäftigen uns mit IDE Integrated Development Environment Debugging Fehlersuche in Programmen Die integrierte Entwicklungsumgebung Um ein Computerprogramm erstellen zu können, benötigen wir im Grunde zwei Dinge: 1 Einen Texteditor, um den Sourcecode in einer Programmiersprache wie Visual Basic, C++, C# oder Java zu schreiben, und 2 einen Compiler, der diese Programmiersprache in Maschinensprache übersetzt. Das Ergebnis liegt dann als ausführbare Programmdatei mit der Endung .exe vor. sep Ein Compiler ist ein Programm, das den Sourcecode in Maschinensprache übersetzt. 1 Visual Studio 2005 Eine integrierte Entwicklungsumgebung (IDE) ermöglicht durch die Unterstützung mittels zahlreicher Assistenten und Debugging-Werkzeuge eine raschere Programmierung. Wir benutzen für unsere Arbeit Microsoft Visual Studio 2005. Le Sourcecode wird eine Textdatei genannt, die ein Computerprogramm in einer Programmiersprache enthält. ro Lernen be ● der integrierten Entwicklungsumgebung Visual Studio 2005, ● dem .NET-2.0-Framework, der CLR und der CIL, ● dem ersten Programm in C# sowie mit ● Variablen, Konstanten und ihren Datentypen. Controls Menü- und Symbolleisten Projektfenster Form-/CodeAnsicht Eigenschaftenfenster Fehlerliste Diese Abbildung findest du in der PowerPointPräsentation unter der ID: 1151. Abb.: Integrierte Entwicklungsumgebung Microsoft Visual Studio 2005 Softwareentwicklung Visual Studio 2005 bietet eine einheitliche Oberfläche für die Entwicklung von Programmen in verschiedenen Programmiersprachen an. Wir beschränken uns im Rahmen dieses Buches auf die Standardsprache für objektorientierte .NET-Programme: Visual C#. .NET-Programmiersprachen Programmiersprachen in Visual Studio 2005 1 Visual Basic VB.NET ist als Einsteigersprache nach wie vor sehr beliebt, da viele Programmierer bereits über Basic-Kenntnisse verfügen, z.B. in VBA, das als Programmiersprache in Microsoft Office zur Verfügung steht. 2 Visual C# be 3 Visual J# J# (gesprochen „tschej: scha:p“) ist eine von Microsoft entwickelte Java-Sprache. J#-Programme laufen nicht mit der Java-Virtual-Machine von Sun, sondern mit dem .NET-Framework von Microsoft. ro Anders Hejlsberg entwickelte die Sprachen Turbo Pascal und Delphi für die Firma Borland, wechselte 1992 zu Microsoft und war dort für die Entwicklung von C# zuständig. C# (gesprochen „si: scha:p“) ist eng verwandt mit den Sprachen C++ und Java, jedoch teilweise einfacher in der Handhabung. C# wurde von Mircosoft völlig neu entwickelt und 2003 von der ISO (International Organization for Standardization) standardisiert. C# gilt als die Standardsprache für die Programmierung mit .NET. 4 Visual C++ sep Bjarne Stroustrup entwickelte 1979 die Sprache C++ bei AT&T. Die Programmiersprache C++ wurde 1979 von Bjarne Stroustrup entwickelt und 1982 um objektorientierte Konzepte erweitert. Mit Visual C++ lassen sich maschinennahe Anwendungen, z.B. Treiber oder Betriebssystemkomponenten, erstellen. Sehen wir uns nun an, was sich hinter der .NET-Strategie von Microsoft verbirgt und wie .NETProgramme arbeiten. Weiters werfen wir einen Blick auf den Aufbau des .NET-Frameworks. 2 Das .NET-Framework Basis für moderne Softwareentwicklung Das .NET-Framework 3.0 wird mit Windows Vista ausgeliefert und enthält das .NET-Framework 2.0 sowie WinFX. Le Ende der 1990er Jahre sah Microsoft seine Marktposition durch den Konkurrenten Sun mit der damals bei Softwareentwicklern beliebten Programmiersprache Java arg bedroht und wollte einen Gegenpol etablieren. Im Juni 2000 stellte Microsoft erstmals seine .NET-Vision vor. Im Jänner 2002 wurde .NET 1.0 gemeinsam mit Visual Studio 2002 gelauncht. Die überarbeitete Version 1.1 erschien gemeinsam mit Visual Studio 2003 ein Jahr später. Die Weiterentwicklung zu .NET 2.0 und Visual Studio 2005 war eng an die Entwicklung des SQL-Datenbankservers 2005 gekoppelt. Beide Produkte wurden im November 2005 eingeführt. Die .NET-Technologie ist für Microsoft eine sehr wichtige Kerntechnologie, auf der alle Softwareprodukte zukünftig basieren sollen. Produkte, die diese Technologie verwenden, sind z.B. Windows-Server-2003, SQL-Server 2005 und Windows Vista. Was ist ein Framework? Moderne Softwareentwicklung erfolgt objektorientiert unter Verwendung fertiger Softwarekomponenten mit Hilfe eines Frameworks, wie zum Beispiel mittels .NET-Framework oder Java. Eine Klasse ist eine wichtige Basis für objektorientiertes Programmieren (siehe Kapitel 2). Softwareentwicklung Ein Framework enthält Softwarekomponenten in Form von Klassenbibliotheken. Damit ist es möglich, vorhandene Funktionen für eigene Programme zu nutzen. Die bekanntesten Frameworks sind das .NET-Framework von Microsoft sowie Java 5 von Sun. 1 Programmieren mit Visual C# Lerneinheit 1: Erste Schritte in .NET Lernen Üben Sichern Wissen Schichten des .NET-Frameworks Webservice WebForms WinForms ASP.NET Plattformunabhängig sind Java und .NET durch CLR und JIT-Compiler. Data- und XML-Klassen (ADO.NET) be Basisklassen Common Language Runtime Abb.: Schichten des .NET-Frameworks von Microsoft ro Diese Abbildung findest du in der PowerPointPräsentation unter der ID: 1151. 1 .NET fungiert als Erweiterung bzw. Teil des Betriebssystems Das .NET-Framework kann bei Microsoft kostenlos bezogen werden. Ein .NET-Programm liegt in einem Zwischencode, der Common Intermediate Language (CIL), vor. Programme werden durch einen Compiler in den CIL-Code übersetzt und werden somit zu EXE- oder DLL-Dateien, können jedoch ohne das .NET-Framework nicht ausgeführt werden. Die Ausführung der Programme übernimmt ein JIT-Compiler, der Bestandteil der Common Language Runtime ist. sep Der JIT-Compiler heißt bei Java Virtual Machine (VM). 2 Common Language Runtime (CLR) 3 Just-in-time-Compiler (JIT) Der CIL-Code muss für den jeweiligen Mikroprozessor während der Laufzeit des Programmes in Maschinensprache übersetzt werden. Für jedes Betriebssystem wird daher ein JIT-Compiler benötigt. Microsoft liefert den JIT-Compiler als Bestandteil der CLR. Für Linux ist seit 2004 eine CLR mit JIT-Compiler unter dem Namen „Mono“ verfügbar. Le Zwischencode Was bei .NET als CIL bezeichnet wird, heißt bei Java Bytecode. Das Prinzip ist jedoch ähnlich. ADO.NET bezeichnet jene Klassen in der FCL, die für Datenbankzugriffe und XML zuständig sind. 4 Framework Class Library (FCL) Extensible Markup Language (XML) ist ein standardisiertes, sich selbst beschreibendes Datenformat unter Verwendung von Tags. 5 Benutzerschnittstellen Mr. What und Ms. Check Das gesamte Framework wurde objektorientiert entwickelt. Das hat zur Folge, dass unsere Programme ebenfalls objektorientiert sind. Das Framework gliedert sich in Basisklassen und spezielle Klassen für den Datenzugriff, die unter dem Begriff ADO.NET zusammengefasst werden. .NET-Anwendungen können für Windows (WinForms) und einen Webbrowser (WebForms) entwickelt werden. Auch mobile Geräte, wie Smartphones und PDAs, werden unterstützt. Web-Services ermöglichen den Zugriff auf Datenbanken über das Internet, wobei als Datenaustauschformat XML benutzt wird. Was ist ein Compiler? Was ist ein JIT-Compiler? Ein Compiler übersetzt den Sourcecode einer höheren Programmiersprache wie C++ in Maschinensprache. Ein JIT-Compiler übersetzt den Sourcecode von VB.NET, C# oder Java in einen Zwischencode (CIL, Bytecode). Softwareentwicklung 3 Das erste Programm Anwendung zur Uhrzeitausgabe Wer programmiert, hat gelernt, genau zu arbeiten und auf Kleinigkeiten zu achten. Dennoch machen alle Programmierer Fehler. Auch wir werden Fehler machen. Aber lassen wir uns nicht entmutigen! Programmieren ist eine feine Sache, auch wenn aller Anfang schwer ist. Beachte Programmieren heißt „Fehler machen“. Der gute Programmierer unterscheidet sich vom schlechten dadurch, dass er seine Fehler rascher findet. be Wir erstellen ein neues Projekt, wählen die Programmiersprache Visual C#, klicken auf Windows-Anwendung, geben als Projektname „cs_Uhrzeit“ ein und wählen den Projektordner. www.wissenistmanz.at ro Das C#-Lehrbeispiel für Visual Studio 2005 findest du unter der ID: 1151. sep Windows-Anwendung Name „cs_Uhrzeit“ Diese Abbildung findest du in der PowerPointPräsentation unter der ID: 1151. Projektordner Abb.: Erstellung der C#-Windowsanwendung cs_Uhrzeit Le Aus der Toolbox erstellen wir eine Befehlsschaltfläche, der wir im Eigenschaftenfenster den Text „Uhrzeit“ als Beschriftung und „btUhrzeit“ als Name zuweisen. Eigenschaftenfenster Button = Befehlsschaltfläche Befehlsschaltfläche Diese Abbildung findest du in der PowerPointPräsentation unter der ID: 1151. Softwareentwicklung Abb.: Erstellung des Dialogfensters 1 Programmieren mit Visual C# Lerneinheit 1: Erste Schritte in .NET Lernen Üben Sichern Wissen Eventhandler für den Uhrzeit-Button L 1: using using using using using using using Der Eventhandler wird beim Klicken der Befehlsschaltfläche btUhrzeit aufgerufen. Kommentare in C#: // bewirkt einen einzeiligen Kommentar, /* ... */ bewirkt einen mehrzeiligen Kommentar. namespace cs_Uhrzeit { public partial class Form1 : Form { public Form1() { InitializeComponent(); } ro C# ist case sensitive, d.h., die Groß-/Kleinschreibung wird in C# genau unterschieden. System; System.Collections.Generic; System.ComponentModel; System.Data; System.Drawing; System.Text; System.Windows.Forms; be Nachdem die Befehlsschaltfläche btUhrzeit im Formular positioniert und die Eigenschaften Text und Name dafür festgelegt wurden, erstellen wir mit einem Doppelklick auf den Button einen Eventhandler. Ein Eventhandler ist ein Programm, das beim Auftreten eines bestimmten Ereignisses abläuft. Für das Klicken des Uhrzeit-Buttons wird ein Eventhandler erstellt. private void btUhrzeit_Click(object sender, EventArgs e) { } } // Ausgabe der aktuellen Uhrzeit MessageBox.Show( "Es ist jetzt " + DateTime.Now.Hour + " Uhr und " + DateTime.Now.Minute + " Minuten"); } sep Eventhandler = Ereignisprozedur Mr. What und Ms. Check Le Der Befehl MessageBox.Show() gibt den übergebenen Text in einer Messagebox am Bildschirm aus. Mit DateTime.Now.Hour bzw. DateTime.Now.Minute werden die Stunde bzw. Minute der aktuellen Uhrzeit abgefragt. Was bedeutet using? Was ist ein namespace? Der Tipptext zeigt die Namensraum-Verortung der Klasse MessageBox im Framework an. namespace bedeutet Namensraum und ermöglicht die eindeutige Zuordnung von Frameworkklassen und -funktionen ähnlich einer Festplatte, die mit Hilfe von Ordnern strukturiert wird. Was bedeutet class? Was bedeuten die geschweiften Klammern {}? Was bedeutet ein Strichpunkt am Ende einer Zeile? Mit using kann ein Namensraum des Frameworks in das Programm eingebunden werden, wodurch wir uns Schreibarbeit ersparen. Statt System.Windows.Forms.MessageBox.Show schreiben wir nur MessageBox.Show. class bedeutet Klasse. Eine Klasse ist ein eigenständiger Programmteil, der Daten und die zugehörige Programmlogik (Code) enthält. Die geschweiften Klammern {} sind Blöcke, die zusammengehörigen Code enthalten. Jeder Befehl muss mit einem Strichpunkt abgeschlossen werden. Daher ist es in C# zulässig, an beliebiger Stelle Leerzeichen oder Zeilensprünge zu setzen. Softwareentwicklung Compilieren und Ausführen Programm compilieren und ausführen Programm ausführen: mit F5 oder Strg Nachdem wir nun unser erstes Programm geschrieben haben, interessiert uns natürlich das Ergebnis. Um das Programm im Debugging-Modus, d.h. im Modus mit Fehlerüberwachung, zu starten, drücken wir F5 oder wir klicken auf den grünen Start-Knopf in der Symbolleiste. Mit Strg F5 starten wir das Programm ohne Debugging. Bei Konsolenanwendungen ist dieser Modus praktisch, da das Konsolenprogramm auf einen beliebigen Tastendruck wartet, bevor es beendet wird. F5 L 2: Abb.: cs_Uhrzeit-Programm ro be Nachdem wir unser Programm ausgeführt haben, wird das Formular Form1 mit der Befehlsschaltfläche btUhrzeit und der Beschriftung „Uhrzeit“ auf dem Bildschirm angezeigt. Sobald wir auf den Button klicken, wird der Eventhandler ausgeführt, der die Messagebox mit der Uhrzeit ausgibt. Ü 1: Le Eine Übersicht der wichtigsten WinFormControls findest du in Lerneinheit 4 in diesem Kapitel. sep Im folgenden Übungsbeispiel erstellen wir eine Uhr mit automatischer Zeitanzeige und grafischer Darstellung der Sekunden. ProgressBar Label Timer In einer Windows-Anwendung erstellen wir ein Label mit dem Text „Uhrzeit:“ und dem Namen lblUhrzeit sowie einen Progressbar mit dem Maximum 60 und dem TabIndex 1 zur Darstellung der Sekunden. Wir ziehen ein Timer-Control in das Formular und ändern die Eigenschaft Enabled auf True. Damit wird alle 100 Millisekunden der Programmcode im Eventhandler des Timer-Controls aufgerufen. Mittels Doppelklick auf das Timer-Control erstellen wir den Eventhandler. Abb.: Automatische Zeitanzeige mit Sekundendarstellung private void timer1_Tick(object sender, EventArgs e) Das Timer-Control aktualisiert den Progressbar alle 100 Millisekunden. Softwareentwicklung { } Sekunde.Value = DateTime.Now.Second; lblUhrzeit.Text = "Uhrzeit: " + DateTime.Now.Hour + " Uhr und " + DateTime.Now.Minute + " Minuten"; 1 Programmieren mit Visual C# Lerneinheit 1: Erste Schritte in .NET Lernen Üben Sichern Wissen Sehen wir uns nun an, wie wir in unseren Programmen Variablen und Konstanten verwenden können und welche Datentypen es für diese im Framework gibt. 4 Werte und Typen Variablen, Konstanten und Datentypen Nahezu jedes Programm muss Werte speichern, um Berechnungen auszuführen und Eingaben von Benutzern abzulegen, um andere Eingaben oder gespeicherte Daten zu vergleichen oder um Eingaben in einer Datenbank oder Datei abzuspeichern. Variablen 1 Eine Variable ermöglicht das Speichern von Werten, die sich jedoch im Programmverlauf ändern können. be SbX Eine Abbildung dazu findest du in der PowerPoint-Präsentation unter der ID: 1151. Wir definieren die Variable Marke, um die Marke eines Autos zu speichern (z.B. „BMW“). Wird ein anderes Auto bearbeitet, kann diese Variable eine andere Marke aufnehmen (z.B. „Volvo“). Konstanten ro 2 Eine Konstante ermöglicht das einmalige Speichern eines Wertes. Der Inhalt einer Konstanten darf im Programmverlauf nicht geändert werden. Wir definieren z.B. eine Konstante für das Serviceintervall. Im Lauf des Programms darf sich die Konstante Intervall nicht mehr ändern. Datentypen 3 Jede Variable oder Konstante muss einem Datentyp entsprechen. sep Common Type System (CTS) Die Datentypen für alle .NET-Sprachen sind im gemeinsamen Typsystem des Frameworks definiert. Die Variable Marke wird Text aufnehmen, daher weisen wir ihr den Datentyp String zu. Die Konstante Intervall wird eine Zahl ohne Nachkommastellen sein, daher weisen wir ihr den Datetyp Int32 zu. Wir erzeugen eine Variable Marke vom Typ String sowie eine Konstante intervall vom Typ Decimal. Die Initialisierung weist einer Variablen oder Konstanten einen Wert zu. Beachte Eine Variable oder Konstante steht immer links vom zugewiesenen Wert. Le Die Deklaration erzeugt eine Variable oder Konstante von einem bestimmten Datentyp. L 3: // Deklaration der Variablen marke und der Konstanten intervall String marke; const Int32 intervall = 30000; // Initialisierung der Variablen marke marke = "BMW"; // Überschreiben der Variablen marke marke = "Mercedes"; Einer Zahl vom Typ Decimal wird ein M, einer Zahl vom Typ Float ein F nachgestellt. Das Programm erzeugt die Variable Marke und die Konstante Intervall. Beiden werden Werte zugewiesen. Der Variablen Marke kann mehrmals ein Wert zugewiesen werden. Softwareentwicklung Datentypen Jede Variable und Konstante muss einem Datentyp zugeordnet sein. Alle .NET-Sprachen verwenden ein gemeinsames Typsystem aus der Klassenbibliothek. Da viele Programmierer an die Begriffe aus der jeweiligen Sprache gewöhnt sind, hat Microsoft für die Datentypen aus der CLR Aliasnamen definiert. Die folgende Tabelle zeigt diese Datentypen aus dem Framework mit ihren CLR-Namen sowie den C#-Aliasnamen und die Wertebereiche. SByte sbyte –128 bis 127 Byte byte 0 bis 255 Int16 short –32.768 bis 32.767 UInt16 ushort 0 bis 65.535 Int32 int –2.147.483.648 bis 2.147.483.647 UInt32 uint 0 bis 4.294.967.295 Int64 long –263 bis 263 – 1 UInt64 ulong 0 bis 264 – 1 Single float ±3,4*1038 Double double ±1,7*10308 Decimal decimal ±7,9*1028 Boolean bool True/False Char char Unicode-Zeichen String string Unicode-Zeichenfolge Ein Stack speichert Datenobjekte in einem Stapel nach dem Last-in-/First-outPrinzip. Wertetypen Ein Heap speichert große Mengen von Datenobjekten in einem Baum. Verweistypen be Wertebereich ro Diese Tabelle findest du in der PowerPointPräsentation unter der ID: 1151. C#-Alias Ein Wertetyp wird im Stack gespeichert. SByte, Byte, Int16, UInt16, Int32, UInt32, Int64 und UInt64 sind ganzzahlige Wertetypen. Single, Double und Decimal sind Fließkomma-Wertetypen. Boolean ist ein Wertetyp, der nur die beiden Zustände Wahr und Falsch kennt. sep SbX CLR-Datentyp Ein Verweistyp wird im Heap gespeichert. Char und String sind Verweistypen. Sie werden für die Darstellung von Zeichen verwendet. Anders als in Java kann in C# mit Strings, die Verweistypen sind, so umgegangen werden, als wären es Wertetypen. Le Welche Probleme beim Arbeiten mit Datentypen auftreten können, zeigt folgendes Beispiel: L 4: // Deklaration und Initialisierung der Variablen int tankinhalt = 55; decimal verbrauch = 7.5M; –> Fehler! Mr. What und Ms. Check Casting ist eine explizite Typkonvertierung unter Akzeptanz eines möglichen Verlustes an Genauigkeit. Softwareentwicklung // 200 km Fahren und benzinvorrat berechnen double benzinvorrat = tankinhalt – 200 * verbrauch / 100; MessageBox.Show("Benzinvorrat: " + benzinvorrat); Warum erhalte ich bei diesem Beispiel einen Fehler mit dem Hinweis auf eine nicht durchführbare, implizite Konvertierung? Was ist das? Bei der Berechnung des Benzinvorrats könnte aufgrund des verwendeten Datentyps Double Genauigkeit verlorengehen, denn in der Berechnung kommt der noch genauere Datentyp Decimal vor. Deshalb ist eine automatische Typkonvertierung hier nicht möglich und wir müssen dem Compiler mitteilen, dass wir den Datentyp Double haben wollen. Wir nennen dies Casting. Die Lösung lautet dann: double benzinvorrat = (double)(tankinhalt – 200 * verbrauch / 100); 1 Programmieren mit Visual C# Lerneinheit 1: Erste Schritte in .NET Lernen Üben Sichern Wissen Typkonvertierung In C# gilt generell eine strenge Typkonvertierung. Folgende Methoden zur Typkonvertierung sind vorgesehen: Die explizite Konvertierung ermöglicht die Umwandlung in jeden beliebigen Datentyp, z.B. intzahl = Convert. ToInt32("41.75"), intzahl enthält 41. 1 Casting ermöglicht die Konvertierung innerhalb einer Typenfamilie. Mittels Casting können wir z.B. eine Variable vom Typ Decimal in den Zieltyp Int32 oder Single umwandeln, da es sich in allen Fällen um Zahlen handelt. Wir können aber einen String oder Boolean nicht in eine Zahl umwandeln, also z.B. nicht String zu Byte casten. 2 Explizite Konvertierung Die Konvertierung mit der Methode Convert.To kann auch dann eingesetzt werden, wenn die Variablen unterschiedlichen Typenfamilien angehören. So kann z.B. mit Convert. ToString(intzahl) eine Zahl vom Typ Int32 in einen String umgewandelt werden. Eine andere Form für diese Umwandlung wäre intzahl.ToString(). be Casting wandelt Typen innerhalb der gleichen Typenfamilie um, z.B. i = (int) d, wobei i vom Typ int und d vom Typ double ist. Ü 2: Welche Formen der Konvertierung sind bei den folgenden Variablen möglich? Typ <– Typ implizit decimal <– int byte <– int float <– double string <– byte Convert.To... sep double <– decimal Casting ro Weitere Informationen zur Datenkonvertierung findest du in der Linkliste unter der ID: 1151. decimal <– double byte <– bool char <– int Übungsbeispiele Le Üben Ü 3: Für folgende Variablen soll der geeignete Datentyp gefunden werden. Die korrekte Deklaration und Initialisierung der Variablen ist in C# darzustellen. Variable Name für den Wert Max Muster. Variable Gehalt für den Wert 1897,67. Variable Alter für den Wert 45. 10 Softwareentwicklung Variable Verheiratet für den Wert ja. Variable Geschlecht für den Wert männlich. Ü 4: Finde den Fehler im Programmteil: be int zahl1 = 30; string zahl2 = 16; MessageBox.Show("Ergebnis: " + Convert.ToString(zahl1 + zahl2)); Zusätzlich zu diesen Übungen findest du in SbX eine Internetaufgabe. Sichern ro ID: 1153 sep In dieser Lerneinheit haben wir die ersten Schritte des Programmierens und die Elemente des Microsoft .NET-Frameworks kennengelernt. Eine integrierte Entwicklungsumgebung ermöglicht das rasche und einfache Entwickeln von Software in einer Programmiersprache mit Hilfe von vorgefertigten Werkzeugen. .NET-Framework Das Microsoft .NET-Framework besteht aus der Common Language Runtime, dem Common Type System, der Framework Class Library (Basis-, Data- und XML-Klassen) sowie WinForms, WebForms und WebServices. CLR, CIL und JIT Die Common Language Runtime stellt den JIT-Compiler zur Verfügung, der die Zwischensprache (Common Intermediate Language) in die Maschinensprache des Prozessors übersetzt. VB, C#, J#, C++ Die durch Visual Studio 2005 unterstützten Programmiersprachen sind objektorientierte Sprachen, die das .NET-Framework und seine Klassen nutzen. Die Standardsprache für die .NET-Programmierung ist Visual C#. Variable Eine Variable speichert einen Wert als Werte- oder Verweistyp. Ihr Wert kann während eines Programmablaufs jederzeit verändert werden. Konstante Eine Konstante ähnelt einer Variablen. Jedoch darf ein Wert nur einmal zugewiesen und anschließend nur noch gelesen werden. Datentypen Datentypen, z.B. String, Int32 und Double, sind im Common Type System (CTS) des .NETFrameworks festgelegt und gelten für alle .NET-Sprachen gleichermaßen. Typkonvertierung In C# gilt eine strenge Verwendung von Typkonvertierungen, was den Einsatz von Casting und expliziter Konvertierung erforderlich macht. Le IDE Zusätzlich zu dieser Zusammenfassung findest du in SbX eine Bildschirmpräsentation. ID: 1156 Softwareentwicklung 11 1 Programmieren mit Visual C# Lerneinheit 1: Erste Schritte in .NET Lernen Üben Sichern Wissen Wissen Wiederholungsfragen und -aufgaben 1.Was ist eine integrierte Entwicklungsumgebung? 2.Beschreibe den Aufbau des .NET-Frameworks und nenne seine Bestandteile! 3.Welche Aufgabe erfüllt ein JIT-Compiler? 4.Welche Gemeinsamkeiten haben Java und C#? 6.Erkläre die Begriffe ADO.NET und ASP.NET! be 5.Was versteht man unter dem Begriff Framework-Class-Library? 7.Was versteht man unter einem Namensraum (Namespace)? 8.Erkläre den Unterschied zwischen Variablen und Konstanten! ro 9.Nenne mindestens fünf verschiedene Datentypen des .NET-Common-Type-Systems! 10.Erkläre die Begriffe Stack und Heap im Zusammenhang mit Werte- und Verweistypen! 11.Welche Datentypen sind Verweistypen? sep 12.Was versteht man unter impliziter Konvertierung und wann wird sie angewendet? 13.Erkläre den Begriff Casting anhand eines selbst gewählten Beispiels! 14.Nenne ein selbst gewähltes Beispiel für explizite Konvertierung, bei dem weder implizite Konvertierung noch Casting funktionieren! Zusätzlich zu diesen Aufgaben findest du in SbX Drag&Drop-Aufgaben. ID: 1157 Le Lerncheck Ich kann jetzt … w ... eine integrierte Entwicklungsumgebung und das .NET-Framework benutzen. w ... die Begriffe CLR, CTS, FCL, CIL und JIT-Compiler erklären. w ... einfache Windows-Programme mit C# erstellen. w ... Variablen und Konstanten sowie deren Datentypen und die Möglichkeiten der Typkonvertierung verwenden. In der folgenden Lerneinheit lernen wir weitere Elemente der Programmiersprache C#, wie Verzweigungen, Arrays sowie die Erzeugung von Zufallszahlen, kennen. 12 Softwareentwicklung Lerneinheit 2 Verzweigungen und Arrays Alle SbX-Inhalte zu dieser Lerneinheit findest du unter der ID: 1158. In dieser Lerneinheit erweitern wir unser Wissen um wichtige Basiskonzepte der Programmierung. Verzweigungen (if und switch) werden in nahezu jedem Programm benötigt. Danach sehen wir uns an, wie wir mit Arrays in einer Variablen mehrere Werte speichern und Zufallszahlen berechnen können. Wir beschäftigen uns mit be ● der if-Verzweigung und ihrer Verwendung, ● der switch-Verzweigung, ● Arrays zum Speichern mehrerer Werte in einer Variablen und ● der Berechnung von Zufallszahlen. 1 if-Verzweigung ro Lernen Sein oder nicht sein, das ist hier die Frage. Die if-Verzweigung kennen wir bereits aus Excel in Form der Wenn-Funktion. Die if-Anweisung bewirkt Alternativen, die von einer Bedingung abhängen. Die Bedingung ist ein logischer Ausdruck, der wahr (true) oder falsch (false) sein kann. Wenn bei einem Auto der Benzinvorrat unter 10 % des Tankvolumens sinkt, sollte bald getankt werden, da bereits die Reserve erreicht ist. Andernfalls muss nicht getankt werden. Eine Verzweigung würde sich wie folgt darstellen lassen: Le Beachte sep In einem Programm sind oft Bedingungen zu prüfen, von denen der weitere Programmablauf abhängt. if() Diese Abbildung findest du in der PowerPointPräsentation unter der ID: 1159. Softwareentwicklung Benzinvorrat < 10 % true false Demnächst muss getankt werden. Tanken ist noch nicht notwendig. Abb.: if-Verzweigung am Beispiel der Tankanzeige eines Autos 13 1 Programmieren mit Visual C# Lerneinheit 2: Verzweigungen und Arrays Lernen Üben Sichern Wissen Sehen wir uns nun das Beispiel aus der Abbildung als Programmteil an. Wir ergänzen aber noch eine weitere Bedingung: Wenn der Tankvorrat erschöpft ist, darf das Auto nicht mehr fahren. if-Verzweigung Auf if folgt die Bedingung in runden Klammern, auf else dürfen keine runden Klammern folgen. be Die if-Verzweigung besteht aus maximal zwei Schlüsselwörtern: if und else. L 1: // Benzinvorrat auf Reserve prüfen if (benzinvorrat == 0) Anweisung MessageBox.Show("Der Tank ist leer."); else if (benzinvorrat / tankinhalt * 100 <= 10) { MessageBox.Show("Bitte demnächst tanken!"); Block MessageBox.Show("Sie sind auf Reserve."); } else MessageBox.Show("Benzinvorrat: " + benzinvorrat); Auf eine if- bzw. else-Anweisung muss entweder ein Befehl mit Strichpunkt oder eine Blockanweisung folgen. Le sep Beachte ro Einem if oder else folgt ein Befehl, der mit einem Strichpunkt zu beenden ist. Sollen wie in Lehrbeispiel L 1 mehrere Befehle zu einem if- oder else-Zweig gehören, müssen diese Befehle in einem Block mit geschwungenen Klammern { ... } eingeschlossen sein. Bei der Programmierung soll der Inhalt einer if-Verzweigung erst später erstellt werden. Sehen wir uns an, wie wir dies mit Hilfe von Kommentaren berücksichtigen können: -> Fehler! Auf if und else muss eine Anweisung oder ein Block folgen! Mr. What und Ms. Check L 2: // Kommentare in if-Anweisungen if (benzinvorrat == 0) Falsch, Anweisung oder Block fehlt. // später else { // später Richtig } Warum wird bei einem Vergleich ein doppeltes Gleichheitszeichen „==“ verwendet? C# unterscheidet Zuweisungsoperatoren, das einfache Gleichheitszeichen, und Vergleichsoperatoren, das doppelte Gleichheitszeichen. Warum gibt es in C# kein ElseIf wie in VB? In C# benötigen wir kein ElseIf. Schachteln wir eine weitere if-Anweisung in einen vorangehenden elseZweig, so erzielen wir den gleichen Effekt. 14 Softwareentwicklung Vergleichsoperatoren und logische Operatoren Um eine if-Anweisung erstellen zu können, benötigen wir eine Bedingung. Diese Bedingung ist ein Vergleich, der mittels Vergleichsoperatoren formuliert wird. Bedeutung Bedeutung Logischer Operator gleich == NOT ! kleiner < AND & bzw. && kleiner oder gleich <= OR größer > XOR größer oder gleich >= ungleich != | bzw. || ^ be Bei & und | werden beide logischen Ausdrücke geprüft, bei && und || erfolgt die Überprüfung beider Ausdrücke nur dann, wenn nach Prüfung des ersten Ausdrucks noch kein eindeutiges Ergebnis feststeht. Vergleichsoperator Das Ergebnis einer Bedingung, die mit Hilfe eines Vergleichsoperators gebildet wird, ist entweder true oder false. Zwei Bedingungen können mit einem logischen Operator verknüpft werden. Die folgende Tabelle enthält die Ergebnisse der logischen Operatoren: Die Ergebnisse für & bzw. | gelten für && bzw. || sinngemäß. Ergebnis Ausdruck true & true true true | true true & false false true | false false & true false false & false false Ergebnis Ausdruck Ergebnis true true ^ true false true true ^ false true false | true true false ^ true true false | false false false ^ false false ro Ausdruck Le sep Sehen wir uns dazu folgende Beispiele an: Ü 1: Was ist an den folgenden Beispielen falsch? if (vmax < 50 && vmax > 80) {...} Wo stecken die Fehler? if (vmax >= 40 || vmax <= 40) {...} if (! vmax = 50) {...} Ü 2: Wie lauten die Verzweigungen in C#, 1.wenn das Gewicht kleiner als 50 kg ist? 2.wenn das Gewicht größer als 100 kg ist? 3.wenn das Gewicht größer als 60 kg und die Größe kleiner/gleich 160 cm ist? 4.wenn das Gewicht kleiner als 70 kg oder die Größe größer als 150 cm ist? 5.wenn das Gewicht nicht genau 75 kg ist? 6.wenn es sich beim Geschlecht einer Person nicht um einen Mann handelt? 7.wenn das Alter einer Person genau 30 Jahre beträgt? 8.Die Person ist ein Arbeiter, Angestellter oder Lehrling. Für Arbeiter beginnt der Dienst um 7 Uhr, für Angestellte um 8 Uhr und für Lehrlinge um 8.30 Uhr. Beachte Softwareentwicklung Der logische XOR-Operator ^ kann im Gegensatz zu Excel, VBA oder VB.NET nicht zur Berechnung von Potenzen verwendet werden, dafür gibt es die Methode Math.Pow(). 15 1 Programmieren mit Visual C# Lerneinheit 2: Verzweigungen und Arrays Lernen Üben Sichern Wissen Neben der if-Verzweigung gibt es noch eine weitere Verzweigung, die vor allem für Variablen benutzt wird, die verschiedene Ausprägungen annehmen können. Diese Verzweigung sehen wir uns nun genauer an. 2 switch-Verzweigung Mehrfachverzweigung für eine Variable be Das folgende Beispiel berechnet die LKW-Maut auf österreichischen Autobahnen in Abhängigkeit von der Achszahl der LKW. switch() = 2-achsig 3-achsig andere 0,130 EUR 0,182 EUR 0,273 EUR sep Maut je km Diese Abbildung findest du in der PowerPointPräsentation unter der ID: 1159. ro LKWAchszahl? Abb.: switch-Verzweigung am Beispiel der LKW-Maut in Abhängigkeit von der Achszahl Die Variable Achszahl wird hinsichtlich ihres Wertes abgefragt. Bei zweiachsigen LKWs beträgt die Maut 13 Cent, bei dreiachsigen 18,2 Cent und bei allen anderen LKWs 27,3 Cent pro Kilometer. Die Switch-Verzweigung besteht aus den Schlüsselwörtern switch, case, default und break. Jeder case- bzw. default-Block muss mit break beendet werden. Die switch-Anweisung unterscheidet für jeden Fall (case) einen Wert. Le Beachte L 3: // LKW Maut switch (achszahl) { case 2: maut = 0.13; break; case 3: maut = 0.182; break; default: maut = 0.273; break; } Nahezu jedes Programm muss in Variablen oder Konstanten Werte speichern, damit Berechnungen ausführen und diese Werte ausgeben oder abspeichern. Häufig werden diese Funktionen für viele gleichartige Variablen benötigt, z.B. in einer Liste oder in einer Datenbank. Sehen wir uns an, wie wir mehrere gleichartige Variablen bequem verwalten können. 16 Softwareentwicklung 3 Arrays und Collections Containervariablen für viele Werte Das Array hat z.B. den Namen Garage und enthält die Werte „Audi“, „BMW“, „Porsche“ usw. Um die Werte im Array zu speichern, erhält jeder Wert eine fortlaufende Indexnummer. Der Index beginnt immer bei 0. Abb.: Ein Array ist ein Container für viele Werte. be Diese Abbildung findest du in der PowerPointPräsentation unter der ID: 1159. Oft benötigt ein Programm mehrere gleichartige Variablen. Zum Beispiel parken in einer Parkgarage verschiedene Autos unterschiedlicher Automarken. Es wäre wenig komfortabel, wenn wir hierfür viele Einzelvariablen vom Typ String anlegen würden. StattEin Array funktioniert wie dessen erzeugen wir ein eine Parkgarage. Jeder StellArray vom Typ String platz beherbergt ein anderes und legen die benötigte Auto. Anzahl der Werte fest. Arrays verwenden L 4: // Parkgarage mit einem Array string[] garage = new string[3]; garage[0] = "Audi A4"; garage[1] = "BMW 320d"; garage[2] = "Mercedes E230"; sep Zur Deklaration des Arrays wird in C# die Anzahl der Werte angegeben. ro Im folgenden Beispiel werden in einem Array drei Autos mit Marke und Type gespeichert. Das oben dargestellte Array kann alternativ auch direkt bei der Deklaration initialisiert werden: Le L 5: // Deklaration und Initialisierung eines Arrays string[] garage = { "Audi A4", "BMW 320d", "Mercedes E230" }; Wollen wir z.B. den Wert „BMW 320d“ ausgeben, können wir diesen Wert über seine Indexnummer 1 ansprechen: mittels garage[1]. Für Arrays gibt es einige Framework-Funktionen, die wir nutzen können. Häufig benutzte Funktionen sind das Sortieren und das Suchen. Die Funktion Array.BinarySearch() verlangt nach einem sortiert vorliegenden Array. L 6: // Array sortieren Array.Sort(garage); // Arrayeintrag finden if (Array.BinarySearch(garage, "BMW 320d") >= 0) {...} Die Verwendung des Arrays Garage wäre für eine Parkgarage mit mehreren Ebenen etwas umständlich. Sehen wir uns an, wie wir das Konzept der Arrays erweitern können, um damit auch mehrstöckige Parkgaragen verwalten zu können. Softwareentwicklung 17 1 Programmieren mit Visual C# Lerneinheit 2: Verzweigungen und Arrays Lernen Üben Sichern Wissen Arraytypen Wir unterscheiden eindimensionale, zweidimensionale und verschachtelte Jagged Arrays: Arraytypen Zweidimensionales Array Garage mit einer Ebene Garage mit mehreren Ebenen Abb.: Arraytypen 1 Eindimensionale Arrays Jagged Array be Diese Abbildung findest du in der PowerPointPräsentation unter der ID: 1159. Eindimensionales Array Mehrere Garagen ro Ein Jagged Array bezeichnet ein Array in einem Array. Die einfachste Form eines Arrays ist die eindimensionale. Die Parkplätze einer Garagenebene können in einem solchen Arraytyp verwaltet werden. 2 Zweidimensionale Arrays 3 Jagged Arrays sep Mit einem zweidimensionalen Array können mehrere Ebenen einer Garage verwaltet werden. Alle Ebenen haben die gleiche Anzahl an Garagenplätzen. Ein Jagged Array ist ein Array innerhalb eines Arrays, also ein verschachteltes Array. Mit diesem Arraytyp können wir z.B. mehrere Garagen mit unterschiedlich vielen Ebenen verwalten. Le L 7: // Parkgarage mit mehreren Ebenen (zweidimensionales Array) string[,] garage = new string[3, 20]; garage[0, 0] = "BMW"; // erster Parkplatz auf Ebene 1 garage[1, 5] = "Ferrari"; // Parkplatz 6 auf Ebene 2 garage[2, 19] = "Mini Cooper"; // letzter Parkplatz auf Ebene 3 Über die beiden Indizes werden die Ebene bzw. der Parkplatz der jeweiligen Reihe referenziert. Mr. What und Ms. Check Kann ich in einem zweidimensionalen Array auch Werte mit verschiedenen Datentypen speichern? Nein, sämtliche Werte in einem Array müssen demselben Datentyp angehören. Du kannst aber Objekte in einem Array speichern, die ihrerseits Variablen verschiedener Datentypen (Eigenschaften) beinhalten. Das folgende Lehrbeispiel L 8 zeigt die Verwendung eines Jagged Arrays. 18 Softwareentwicklung Der Deklaration des Jagged Arrays folgen die SubarrayDeklarationen. L 8: // Deklaration des Jagged Arrays string[][,] garage = new string[2][,]; // Garage garage[0] // Garage garage[1] 0 = 1 = hat new hat new 2 Ebenen à 20 Parkplätze string[2, 20]; 3 Ebenen à 32 Parkplätze string[3, 32]; // Parkplatzbelegung in Garage 1 garage[1][0, 0] = "Aston Martin"; garage[1][2, 31] = "Porsche"; Kann ich auch ein Array unbestimmter Größe erstellen? Ja, mit der Klasse ArrayList lassen sich flexible Arrays erstellen, die während der Laufzeit ihre Größe ändern können. ro Mr. What und Ms. Check be // Parkplatzbelegung in Garage 0 garage[0][0, 0] = "Nissan"; garage[0][1, 19] = "Toyota"; Collections Der Namensraum System.Collections wird eingebunden, um mit ArrayList arbeiten zu können. Mit einer ArrayList aus dem Namensraum System.Collections können wir zur Laufzeit eines Programmes die Dimensionierung des Arrays ändern. ArrayList bietet uns Methoden zum Hinzufügen und Entfernen von Listeneinträgen an, sodass wir eine Liste dynamisch aufbauen können, ohne die Dimensionierung bei der Erstellung der ArrayList angeben zu müssen. Le Die Klasse ArrayList werden wir in Kapitel 2 häufiger verwenden. sep Mit den bislang besprochenen Arraytypen können wir zwar unterschiedlich strukturierte Listen erzeugen, aber deren Dimensionierung muss zum Zeitpunkt der Programmerstellung bereits bekannt sein. Zum Einlesen von Daten aus einer Datenbank sind diese fixen Arraytypen daher nicht geeignet. L 9: // Einbinden des Collections-Namespaces using System.Collections; // Deklaration einer ArrayList ArrayList garage = new ArrayList(); // Hinzufügen von Einträgen garage.Add("BMW"); garage.Add("Aston Martin"); Mit Reverse wird die Reihenfolge der ArrayList-Elemente umgekehrt. Jede ArrayList bietet die String-Konvertierung als Methode an. Softwareentwicklung // ArrayList sortieren garage.Sort(); garage.Reverse(); // Entfernen von Einträgen garage.Remove("BMW"); // Auslesen von ArrayList-Einträgen MessageBox.Show("Parkplatz 0: " + garage[0].ToString() ); 19 1 Programmieren mit Visual C# Lerneinheit 2: Verzweigungen und Arrays Lernen Üben Sichern Wissen 4 Zufallszahlen Für Simulationen unentbehrlich In Simulationsprogrammen oder Spielen werden Zufallszahlen benötigt, um eine nicht vorhersehbare Spielsituation zu schaffen. Die Klasse System.Random 1 Das Framework stellt zur Erzeugung von Zufallszahlen die Klasse System.Random zur Verfügung. Wir benutzen die Klasse System.Random, um neue Zufallszahlen zu erzeugen. Damit wir dies tun können, müssen wir zuvor die Klasse Random in ein Objekt vom Typ Random instanzieren. Was das genau bedeutet, lernen wir in Kapitel 2. be Klasse, Objekt und Methode sind Begriffe der objektorientierten Programmierung und werden in Kapitel 2 genauer besprochen. 2 Die Methode Next() erzeugt eine Zufallszahl vom Typ Integer. NextDouble() erzeugt eine Zufallszahl zwischen 0 und 1 vom Typ Double. Nachdem wir ein Zufallszahlenobjekt instanziert (erzeugt) haben, können wir das Objekt verwenden und eine Zufallszahl mit der Methode Next(von, bis) ermitteln. Die Parameter von und bis stehen für den gewünschten Wertebereich, in dem sich die erzeugte Zufallszahl befinden soll. Die Variable index enthält die Zufallszahl zwischen 0 und 3. sep rnd.Next(0, anzahl) ermittelt eine Zufallszahl zwischen 0 und 3. Die obere Grenze von 4 wird nicht erreicht. L 10: // Zufallszahlengenerator erzeugen Random rnd = new Random(); // Array marke erzeugen string[] marke = { "Jeep", "Audi", "Ferrari", "Mini" }; // marke.Length liefert die Anzahl der Arrayelemente, also 4 int anzahl = marke.Length; // index enthält eine Zufallszahl zwischen 0 und 3 int index = rnd.Next(0, anzahl); // Welches Auto parkt ein? MessageBox.Show("Ein " + marke[index] + " hat in der Garage eingeparkt."); Le Mit new wird ein Objekt rnd aus der Klasse Random erzeugt. ro Der folgende Beispielcode simuliert die zufällige Auswahl eines Autos für das Einparken in der Parkgarage. Das Lehrbeispiel L 10 veranschaulicht die Verwendung einer Zufallszahl zur Auswahl eines zufälligen Arrayeintrages. Der Vorteil der dargestellten Lösung liegt in ihrer Flexibilität, wie das nächste Übungsbeispiel demonstriert. Ü 3: Ergänze das Array marke aus dem Lehrbeispiel L 10 um die Automarken Opel, Ford, Nissan, Toyota und Mitsubishi. Was muss im Programmcode angepasst werden, damit das Programm mit dieser Veränderung fehlerfrei läuft? 20 Softwareentwicklung Üben Übungsbeispiele Ü 4: Wettervorhersage Eine Windows-Anwendung soll anhand von Zufallszahlen eine Wettervorhersage für den nächsten Tag treffen. Die Ausgabe erfolgt in einer Messagebox. Vorhersage Variable wetter 1 Bewölkt, großteils sonnig 2 Trüb und nebelig 3 Regnerisch und trüb 4 Starker Regen möglich 5 ro Wolkenloser Himmel Ü 5: Wahrsagen be 1.Wir deklarieren die Variable wetter vom Datentyp Byte. 2.Wir weisen der Variablen wetter eine Zufallszahl im Wertebereich 1 bis 5 zu. 3.In einer switch-Verzweigung (C#) prüfen wir, welche Zufallszahl ermittelt wurde. Folgende Wettervorhersagen sind möglich: Berechne in einer Windows-Anwendung eine Zufallszahl zwischen 1 und 5 und gib – abhängig von dieser Zufallszahl – einen der folgenden Texte in einer Messagebox aus: Ü 6: Notenberechnung sep 1.Die nächste Woche verläuft sehr positiv. Du findest die große Liebe deines Lebens. 2.Achte auf dein Zeitgefühl, sonst kommst du zu einem wichtigen Termin zu spät. 3.Die Arbeit geht dir nächste Woche leicht von der Hand und du wirst sehr erfolgreich sein. 4.In den nächsten Tagen wirst du vor einer schweren Prüfung stehen. Aber keine Angst, du wirst dein Können unter Beweis stellen. 5.Nächste Woche wird dir etwas gelingen, was du schon seit langem anstrebst. Die Eingabe der Punkte erfolgt in einem TextBox-Control in der Eigenschaft Text, die den Datentyp String hat. Le Eine Windows-Anwendung soll die Schularbeitsnote berechnen, wobei die erreichbare Maximalpunkteanzahl und die tatsächlich erreichte Punkteanzahl vom Benutzer in Textboxen eingegeben werden. Auf Basis der berechneten Prozentwerte wird die Note ausgegeben. Notenschema: Note Prozentsatz Sehr Gut > 90 % Gut > 80 % Befriedigend > 65 % Genügend > 50 % Nicht Genügend >0% Der berechnete Prozentsatz soll vom Datentyp Decimal sein und auf zwei Dezimalstellen gerundet in einer Messagebox ausgegeben werden. Hinweis: Zur Rundung von Werten wird die Frameworkfunktion Math.Round(zahl, stellen) verwendet. Die Variable ergebnis wird z.B. mit Math.Round(ergebnis, 2) auf zwei Stellen gerundet. Zusätzlich zu diesen Übungen findest du in SbX eine Internetaufgabe. ID: 1160 Softwareentwicklung 21 1 Programmieren mit Visual C# Lerneinheit 2: Verzweigungen und Arrays Lernen Üben Sichern Wissen Sichern In dieser Lerneinheit haben wir uns mit Verzweigungen, Vergleichsoperatoren, Arrays und Zufallszahlen beschäftigt. Eine Verzweigung ermöglicht die Entscheidung zwischen zwei Alternativen anhand einer Bedingung, deren Ergebnis richtig (true) oder falsch (false) ist. if und else Die if-Anweisung enthält eine oder mehrere Bedingungen. Sie gliedert sich in einen Wennund einen Dann-Teil. Der Dann-Teil kann eine weitere if-Anweisung enthalten. Der letzte else-Teil fängt alle weiteren, bisher nicht überprüften Bedingungen ab. Vergleichsoperatoren Mit Vergleichsoperatoren, wie gleich, kleiner, größer und ungleich, kann eine Bedingung für eine if-Verzweigung formuliert werden. Weiters können mit den logischen Operatoren &, &&, |, || und ^ mehrere Bedingungen zu einem logischen Gesamtergebnis kombiniert werden. switch Die switch-Anweisung unterscheidet sich von if dadurch, dass sie auf die Überprüfung des Wertes nur einer Variablen abzielt. Die Variable wird auf einen vorkommenden Wert geprüft. Arrays Arrays sind Containervariablen, die unter einem Namen mehrere Werte enthalten. Bei der Deklaration von eindimensionalen, zweidimensionalen und Jagged Arrays muss deren Größe angegeben werden, ArrayList ermöglicht die Verwendung dynamischer Arrays (Collections). Um einen bestimmten Wert im Array anzusprechen, wird ein Index benutzt. Zufallszahl Eine Zufallszahl wird über die Klasse System.Random in einem Zufallszahlenobjekt mit der Methode Next() erzeugt. sep ro be Verzweigung Zusätzlich zu dieser Zusammenfassung findest du in SbX eine Bildschirmpräsentation. ID: 1161 Le Wissen Wiederholungsfragen und -aufgaben 1.Welche Schlüsselwörter können für die if-Anweisung benutzt werden? 2.Was ist eine verschachtelte if-Anweisung? 3.Erkläre den Unterschied zwischen einem Zuweisungs- und einem Vergleichsoperator! 4.Erkläre den Unterschied zwischen &, | und ^ anhand eines selbst gewählten Beispiels! 5.Wie könnte die Bedingung if(wetter != "Regen") mit einem Gleichheitsoperator formuliert werden, sodass Sinn und Ergebnis erhalten bleiben? 6.Erkläre die Anwendung der switch-Verzweigung anhand eines geeigneten, selbst gewählten Beispiels in C#! 7.Welche Schlüsselwörter gehören zur switch-Anweisung? 8.Mit welchem Befehl werden in einer switch-Anweisung alle verbleibenden Alternativen abgefangen? 22 Softwareentwicklung 9.Erkläre die Verwendung eines ein- und eines zweidimensionalen Arrays anhand selbst gewählter Beispiele! 10.Würdest du der Aussage „Ein Array speichert mehrere Datentypen in einer Variablen.“ zustimmen? Wenn nicht, formuliere die Aussage so um, dass sie richtig ist! 11.Wie lautet die Anweisung zum Sortieren der Elemente in einer ArrayList? 12.In welcher Form muss ein Array vorliegen, damit Array.BinarySearch() angewendet werden kann? 13.System.Random ist eine Framework-Klasse. Was ist darunter zu verstehen? be 14.Welche Schritte sind nötig, um eine Zufallszahl zu erzeugen? Zusätzlich zu diesen Aufgaben findest du in SbX ein Quiz. ID: 1162 Ich kann jetzt … ro Lerncheck w ... if-Verzweigungen einschließlich der Operatoren verwenden. w ... switch-Verzweigungen einsetzen. w ... den Aufbau sowie die Verwendung von Arrays und Collections beschreiben. sep w ... Zufallszahlen erzeugen und verwenden. Le In der folgenden Lerneinheit erarbeiten wir weitere Elemente der Programmiersprache C#, wie Zählerschleifen, bedingte Schleifen und Zuweisungsoperatoren. Softwareentwicklung 23 1 Programmieren mit Visual C# Lerneinheit 2: Verzweigungen und Arrays Lernen Üben Sichern Wissen Lerneinheit 3 Schleifen und Zuweisungsoperatoren In dieser Lerneinheit befassen wir uns mit den verschiedenen Formen von Schleifen. Wir beschäftigen uns mit ● den Zählerschleifen for und foreach, ● den kopf- und fußgesteuerten bedingten Schleifen while und do/while sowie ● den Zuweisungsoperatoren. be Alle SbX-Inhalte zu dieser Lerneinheit findest du unter der ID: 1163. Eine animierte Grafik zur for-Schleife findest du in der PowerPointPräsentation unter der ID: 1164. 1 Zählerschleifen Iteration mit for und foreach Mit Schleifen können wir Wiederholungen in unsere Programme einbauen, z.B. kann eine Parkhaus-Anwendung in einer Schleife das Ein- und Ausparken vieler Autos simulieren. Schleifen kommen in Programmen sehr häufig vor und sind ein wichtiges Basiskonzept der Programmierung. sep Iteration = Wiederholung ro Lernen for- und foreach-Schleifen for zählt vom Startwert bis zum Endwert. 1 Die for-Schleife zählt von einem Startwert bis zu einem Endwert. Sie durchläuft einen Anweisungsblock für jeden gezählten Wert. foreach liefert jeden Wert des angegebenen Arrays. 2 Die foreach-Schleife durchläuft einen Anweisungsblock für jeden Wert eines Arrays oder einer Collection, z.B. einer ArrayList. Le Wollen wir eine bestimmte Operation zehnmal ausführen, so lassen wir eine For-Schleife von 1 bis 10 zählen. Die Schleifenvariable erhält den Wert 1 im ersten Durchlauf, den Wert 2 im zweiten Durchlauf usw. bis zum Wert 10 im zehnten Durchlauf. Haben wir ein Array, das aus tausend Zufallszahlen besteht, so wird die foreach-Schleife tausendmal durchlaufen. Die Schleifenvariable erhält den jeweiligen Wert des Arrays. Das folgende Lehrbeispiel ermittelt bei tausend Einparkvorgängen, wie oft ein BMW in das Parkhaus eingefahren ist. L 1: Random rnd = new Random(); string[] marke = { "Audi", "BMW", "Opel", "Porsche", "Fiat" }; int anzahl = 0; Zählvariable vom Typ int Die Schleifenvariable i läuft von 0 bis 999. 24 for (int i = 0; i < 1000; i++) { if( marke[rnd.Next(0, marke.Length)] == "BMW" ) anzahl++; } MessageBox.Show("Von 1000 Autos waren " + anzahl + " BWMs."); Softwareentwicklung Bei der for-Schleife wird eine Laufbedingung angegeben. Im Lehrbeispiel L 1 beginnt die Schleifenvariable i bei 0. Mit dem Operator ++ wird die Variable i bei jedem Schleifendurchlauf um 1 erhöht (inkrementiert). Diese Operation wird so lange ausgeführt, wie die Schleifenvariable i der Laufbedingung i < 1000 entspricht. Das Lehrbeispiel L 2 speichert die zufällig gewählten Automarken im Array garage und durchsucht dieses anschließend mit Hilfe einer foreach-Schleife. L 2: Random rnd = new Random(); string[] marke = { "Audi", "BMW", "Opel", "Porsche", "Fiat" }; int anzahl = 0; string[] garage = new string[1000]; be for (int i = 0; i < 1000; i++) { garage[i] = marke[rnd.Next(0, marke.Length)]; } Array vom Typ string ro Mr. What und Ms. Check foreach(string auto in garage) { if(auto == "BMW") Schleifenvariable vom Typ string anzahl++; } MessageBox.Show("Von 1000 Autos waren " + anzahl + " BWMs."); Worin unterscheiden sich for und foreach? sep Die Variable garage ist ein Array, auto hat den Datentyp des Arrays und erhält in jedem Schleifendurchlauf den Wert des nächsten Arrayelementes. Die for-Schleife zählt von einem Wert bis zu einem anderen Wert. Dadurch wird die Anzahl der Schleifendurchläufe festgelegt. Mit foreach können alle Werte eines Arrays ausgelesen werden. Le 2 Bedingte Schleifen Iteration mit while und do So lange die Laufbedingung true ist, wird die Schleife durchlaufen. Beachte Der Durchlauf einer bedingten Schleife ist von der Laufbedingung abhängig, die wie die ifVerzweigung als Ergebnis true oder false liefert. Bedingte Schleifen werden je nachdem, ob die Schleifenbedingung im Kopf- oder im Fußteil der Schleife vorkommt, in kopf- und fußgesteuerte Schleifen unterteilt. Wenn innerhalb einer bedingten Schleife die Laufbedingung niemals false ist, liegt eine Endlosschleife vor. Diese kann nur durch einen Programmabbruch mittels Taskmanager beendet werden. Endlosschleifen werden vom Compiler nicht erkannt. Sie treten erst während der Laufzeit auf. Wir sehen uns nun den Unterschied zwischen kopf- und fußgesteuerten Schleifen genauer an. Anhand des Parkhaus-Lehrbeispiels erarbeiten wir die Umsetzung in C#. Softwareentwicklung 25 1 Programmieren mit Visual C# Lerneinheit 3: Schleifen und Zuweisungsoperatoren Lernen Üben Sichern Wissen Kopf- und fußgesteuerte bedingte Schleifen Komplizierte Laufbedingungen bei Schleifen führen häufig zu Denkfehlern und damit zu falschen Schleifendurchläufen. Nur wenn die Laufbedingung am Beginn der Schleife true ergibt, wird eine while-Schleife ausgeführt. Wenn die Laufbedingung bereits zu Beginn false liefert, wird die whileSchleife nie ausgeführt. 2 do/while ist eine fußgesteuerte Schleife. Die Laufbedingung wird am Ende der do-Schleife nach der Anweisung while angegeben. Eine do-/while-Schleife wird auf jeden Fall zumindest einmal durchlaufen, da die Prüfung der Bedingung erst am Ende der Schleife erfolgt. be Eine Abbildung zu den Schleifen findest du in der PowerPointPräsentation unter der ID: 1164. 1 while ist eine kopfgesteuerte Schleife. Die Laufbedingung wird am Beginn der Schleife angegeben. Die beiden folgenden Lehrbeispiele ermitteln aus einer Reihe zufällig einfahrender Autos in ein Parkhaus, das wievielte ein Porsche ist. while ( marke[rnd.Next(0, marke.Length)] != "Porsche" ) { kopfgesteuerte Schleife anzahl++; } MessageBox.Show("Das " + anzahl + ". Auto war ein Porsche."); sep while-Schleife mit Laufbedingung am Anfang ro L 3: Random rnd = new Random(); string[] marke = { "Audi", "BMW", "Opel", "Porsche", "Fiat" }; int anzahl = 1; L 4: Random rnd = new Random(); string[] marke = { "Audi", "BMW", "Opel", "Porsche", "Fiat" }; int anzahl = 0; string auto; Mr. What und Ms. Check do fußgesteuerte Schleife { auto = marke[rnd.Next(0, marke.Length)]; anzahl++; } while (auto != "Porsche"); MessageBox.Show("Das " + anzahl + ". Auto war ein Porsche."); Le do-/while-Schleife mit Laufbedingung am Ende Was ist eine Laufbedingung? Eine Bedingung, die erfüllt sein muss, damit eine bedingte Schleife durchlaufen wird. Worin unterscheiden sich die while- und die do-/while-Schleife? 26 Die Schleifenbedingung muss zutreffen, damit die whileSchleife ausgeführt werden kann. Bei do/while wird die Schleife zumindest einmal durchlaufen, selbst wenn die Bedingung false liefert, da diese erst am Schleifenfuß geprüft wird. Softwareentwicklung In den Lehrbeispielen zu den Schleifen haben wir bereits gesehen, dass Schleifenvariablen (Zähler) in for-Schleifen um den Wert 1 erhöht werden müssen. Wir nennen diesen Vorgang Inkrementieren. 3 Zuweisungsoperatoren Inkrement- und Dekrementoperatoren In den Lehrbeispielen zu den Schleifen haben wir den Zuweisungsoperator ++ verwendet, z.B. zur Erhöhung der Schleifenvariablen i im Lehrbeispiel L 1: i++. Zuweisungsoperator ändere v in wert v = wert; erhöhe v um wert v += wert; vermindere v um wert v -= wert; multipliziere v mit wert v *= wert; dividiere v durch wert v /= wert; füge den String str an v an v += str; ro Auswirkung auf die Variable v be Welche wichtigen Zuweisungsoperatoren gibt es? Präfix- und Postfix-Operatoren Darüber hinaus gibt es in C# noch weitere Operatoren, die vor bzw. nach einer Variablen benutzt werden können. Postfix-Inkrement: Zuerst wird x an y zugewiesen, danach wird x erhöht. L 5: Inkrement-Operatoren x = 1; y = ++x; // Ergebnis: x = 2 und y = 2 x = 1; y = x++; // Ergebnis: x = 2 und y = 1 Le Präfix-Inkrement: Zuerst wird x erhöht, danach wird das Ergebnis an y zugewiesen. sep Inkrement-Operator ++ Der Inkrement-Operator ++ erhöht eine Variable um den Wert 1. Dekrement-Operator -Der Dekrement-Operator -- vermindert den Wert einer Variablen um 1. Präfix-Dekrement: Zuerst wird x vermindert, dann wird das Ergebnis an y zugewiesen. Postfix-Dekrement: Zuerst wird x an y zugewiesen, danach wird x vermindert. Softwareentwicklung L 6: Dekrement-Operatoren x = 2; y = --x; // Ergebnis: x = 1 und y = 1 x = 2; y = x--; // Ergebnis: x = 1 und y = 2 27 1 Programmieren mit Visual C# Lerneinheit 3: Schleifen und Zuweisungsoperatoren Lernen Üben Sichern Wissen Ü 1: int benzinvorrat = 10; int liter = 5; Welchen Wert haben benzinvorrat und liter nach der folgenden Codezeile? =+ liter; == liter; += liter; = ++liter; = liter++; -= ++liter; be a) benzinvorrat b) benzinvorrat c) benzinvorrat d) benzinvorrat e) benzinvorrat f) benzinvorrat 4 Gültigkeitsbereich von Variablen Die Lebensdauer von Variablen Sehen wir uns das folgende Lehrbeispiel an und finden wir gemeinsam heraus, warum es nicht funktioniert! sep –> Fehler! ro Die Variable i wird in der Schleife deklariert und gilt daher nur innerhalb der Schleife. L 7: for (int i = 1; i <= 10; i++) { Die Variable i ist // do something hier unbekannt! } MessageBox.Show(i.ToString()); Eine Variable existiert, wo sie erzeugt wird. Anders gesagt: Variablen leben nur in ihrem Umfeld. Deklarieren wir eine Variable in einer Schleife, wie z.B. for(), dann lebt diese Variable auch nur innerhalb dieser Anweisung. Sobald der Anweisungsblock zu Ende ist, wird die Variable gelöscht und sie ist nicht mehr gültig. Das Lehrbeispiel L 8 löst das Problem, indem die Variable i nicht innerhalb, sondern vor der for-Schleife deklariert wird: Le Die Variable i wird vor der Schleife deklariert und gilt daher auch nach Beendigung der Schleife. L 8: int i; for (i = 1; i <= 10; i++) { Die Variable i ist // do something hier gültig! } MessageBox.Show(i.ToString()); Prozedurvariablen Variablen können auch in Prozeduren, z.B. innerhalb von Ereignisprozeduren (Eventhandlern), erzeugt werden. Sie gelten nur innerhalb jener Prozedur, in der sie deklariert wurden. Eine andere Prozedur kann auf sie nicht zugreifen. Variablen, die auf Prozedurebene erzeugt werden, nennen wir Prozedurvariablen. Eine Prozedurvariable ist immer eine private Variable der Prozedur und daher für eine andere Prozedur unsichtbar. Klassenvariablen Wenn eine Variable auf Klassenebene erzeugt wird, nennen wir sie eine Klassenvariable. Klassenvariablen sind immer für alle Prozeduren einer Klasse gültig. 28 Softwareentwicklung Die Prozedurvariable zwsumme gilt innerhalb des Eventhandlers button1_Click. Mit jedem Buttonklick wird zwsumme neu erzeugt und auf 0 gesetzt. Hier stirbt die Prozedurvariable zwsumme. private void button1_Click(object sender, EventArgs e) { int zwsumme = 0; // Prozedurvariable zwsumme for (int i = 1; i <= 10; i++) // Schleifenvariable i { zwsumme += i; } summe += zwsumme; MessageBox.Show("Summe: " + summe); } } be Die Klassenvariable summe gilt für alle Prozeduren der Klasse. L 9: public partial class Form1 : Form { int summe = 0; // Klassenvariable summe Üben Ü 2: Bei einem Würfelspiel gewinnt jeder den zehnfachen Einsatz, der einen Sechser-Pasch würfelt (zwei Sechser). Bei allen anderen Kombinationen ist der Einsatz verloren. Ermittle für 1000 Würfe die Anzahl der Sechser-Paschs und gib diese in einer Messagebox aus. sep Übungsbeispiele ro Die Verwendung von Klassenvariablen sehen wir uns in der nächsten Lerneinheit genauer an. Le Ü 3: In einer Windows-Form erstellst du zwei Buttons, einen mit der Beschriftung „Ziehen“ und einen mit der Beschriftung „Sehen“. Bei jedem Ziehen erhältst du eine Karte mit einem zufälligen Zahlenwert zwischen 2 und 11 zu deinen bisher gezogenen Karten, ebenso dein imaginärer Gegenspieler (das Computerprogramm). Sobald du auf den Button Sehen klickst, werden die Zahlenwerte der Karten beider Spieler addiert und als Summen in einer Messagebox ausgegeben. Wenn du weniger als 21 hast, hast du gewonnen, andernfalls dein Gegenspieler. Ü 4: Der indische König Sher Kahn versprach, dem Mathematiker Buddhiram, der das Schachspiel erfunden haben soll, einen Wunsch zu erfüllen. Buddhiram antwortete: „Herr, ich möchte auf dem ersten Quadrat des Schachbretts ein Reiskorn haben.“ „Ein gewöhnliches Reiskorn?“, der König traute seinen Ohren nicht. „Ja, Herr, ein Reiskorn auf dem ersten Feld, zwei auf dem zweiten, vier auf dem dritten, acht auf dem vierten, sechzehn auf dem fünften ...“ „Es reicht“, rief der König verärgert. Du sollst deine Reiskörner für alle 64 Quadrate des Schachbretts haben, so wie du es wünschst. Buddhiram lächelte und ging hinaus. (Quelle: Wolfgang Appell) Erstelle eine Windows-Anwendung und berechne, ohne Anwendung der Potenzrechnung, mit einer bedingten Schleife die Anzahl der Reiskörner auf allen Feldern des Schachbrettes. Wie viel Reis bekam Buddhiram für jedes Feld des Schachbrettes? Zusätzlich zu diesen Übungen findest du in SbX Internetaufgaben. ID: 1165 Softwareentwicklung 29 1 Programmieren mit Visual C# Lerneinheit 3: Schleifen und Zuweisungsoperatoren Lernen Üben Sichern Wissen Sichern In dieser Lerneinheit haben wir das Konzept der Zählerschleifen und der bedingten Schleifen mit ihren Operatoren erarbeitet. Die for-Schleife gehört zur Kategorie der Zählerschleifen. Im Kopf der for-Schleife wird ein Zählerbereich definiert. Die for-Schleife zählt mit einer Schleifenvariablen vom Beginn bis zum Ende des angegebenen Bereichs. foreach-Schleife Die foreach-Schleife gehört zur Kategorie der Zählerschleifen. Sie wird im Zusammenhang mit Arrays verwendet, um jeden Wert einer Arrayvariablen in der Schleife zu repräsentieren. while-Schleife Die while-Schleife ist eine kopfgesteuerte bedingte Schleife. Solange die Bedingung im Schleifenkopf erfüllt (true) ist, wird die Schleife durchlaufen. Daraus ergibt sich die Gefahr einer Endlosschleife, wenn die Schleifenbedingung nie false wird. do-/whileSchleife Die do-/while-Schleife ist eine fußgesteuerte bedingte Schleife. Sie wird auf jeden Fall einmal durchlaufen, da die Schleifenbedingung erst am Schleifenende geprüft wird. Solange die Schleifenbedingung erfüllt ist, wird die Schleife wiederholt. Daraus ergibt sich die Gefahr einer Endlosschleife, wenn die Schleifenbedingung nie false wird. Zuweisungsoperatoren Mit Zuweisungsoperatoren können Wertzuweisungen verkürzt geschrieben werden. Häufig werden die Inkrement- und Dekrementoperatoren +=, –=, *= und /= sowie die Präfix- und Postfixoperatoren ++ und -- verwendet. ro be for-Schleife sep Zusätzlich zu dieser Zusammenfassung findest du in SbX eine Bildschirmpräsentation. ID: 1166 Wissen Le Wiederholungsfragen und -aufgaben 1.Erkläre den Unterschied zwischen einer for- und einer foreach-Schleife! 2.Mit welcher Schleife können alle Werte eines Arrays ausgelesen werden, wenn die Anzahl der Arrayelemente unbekannt ist? 3.Erkläre den Unterschied zwischen der while- und der do-/while-Schleife! 4.Welches Ergebnis liefert die Zuweisung a += 5, wenn a zuvor den Wert 10 hatte? 5.Welches Ergebnis liefert die Zuweisung a*= 5, wenn a zuvor den Wert 10 hatte? 6.Die Variable text enthält den String „Guten Morgen“ und soll um den Vornamen (Variable vorname) und den Zunamen (Variable zuname) des Benutzers ergänzt werden. Wie lautet die Zuweisung an die Variable text, wenn mit einem Operator gearbeitet werden soll? 7.Welchen Wert hat die Variable b nach dem folgenden Programmcode? int b = 5; b += ++b + b; Zusätzlich zu diesen Aufgaben findest du in SbX ein Quiz. ID: 1167 30 Softwareentwicklung Lerncheck Ich kann jetzt … w ... die Zählerschleifen for und foreach verwenden. w ... die bedingten Schleifen while und do/while anwenden. w ... die Zuweisungsoperatoren +=, –=, *= und /= nutzen. w ... die Präfix- und Postfix-Operatoren ++ und -- richtig einsetzen. Le sep ro be In der nächsten Lerneinheit sehen wir uns an, wie wir mit Hilfe verschiedener Controls Windows-Anwendungen erstellen können. Softwareentwicklung 31 1 Programmieren mit Visual C# Lerneinheit 3: Schleifen und Zuweisungsoperatoren Lernen Üben Sichern Wissen Lerneinheit 4 Windows-Formulare und Controls Alle SbX-Inhalte zu dieser Lerneinheit findest du unter der ID: 1168. In dieser Lerneinheit sehen wir uns an, wie wir mit Hilfe verschiedener Controls Windows-Formulare erstellen können. Wir beschäftigen uns mit Lernen 1 WinForm-Controls ro Windows-Formulare erstellen be ● häufig gebräuchlichen WinForm-Controls für die Ein- und Ausgabe, ● der Gültigkeit von Variablen sowie ● der Erstellung von Ereignisprozeduren. In dieser Lerneinheit konzentrieren wir uns auf die Erstellung von Windows-Formularen mit Hilfe von Standardcontrols, wie z.B. Label, Textbox, Radiobutton oder Combobox. Die folgende Tabelle gibt einen Überblick, welche Controls zu welchem Zweck eingesetzt werden können. Panel Symbol Anwendung sep Control Wert Anordnung und Strukturierung von Controls GroupBox CheckBox RadioButton Label TextBox Mehrere Auswahloptionen aktivierbar Checked Eine Auswahloption aktivierbar Checked Beschriftung, Ausgabe von Zeichen Text Ein-/Ausgabe von Zeichen Text Liste (Collection) mit einer Auswahlmöglichkeit Text Le ComboBox Gruppierung von Checkboxes oder Radiobuttons ProgressBar Fortschrittsanzeige Value DateTimePicker Auswahl eines Datums mittels Kalender Value TrackBar Wert von/bis festlegen Value PictureBox Darstellung eines Bildes Button Befehlsschaltfläche, Aktion Timer Programmcode nach Zeitintervall ausführen Für jedes Control können wir Eigenschaften festlegen, indem wir diese im PropertiesFenster eingeben oder über den Programmcode zuweisen. Die abgebildete Tabelle enthält in der Spalte Wert jene Properties, die den Wert des Controls enthalten, z.B. die Eigenschaft Text bei einem Label oder einer Textbox. Auf die Eigenschaften eines Controls können wir vom Programmcode aus mittels Controlname, gefolgt von einem Punkt und dem Propertynamen zugreifen, z.B. textbox1.Text, label1.Text oder progressbar1.Value. Beachte 32 Die Eigenschaften von Controls können wie Variablen verwendet werden. Jede Eigenschaft eines Controls hat einen bestimmten Datentyp. Softwareentwicklung Die folgende Abbildung zeigt die Verwendung einiger Controls für ein Eingabeformular. Label Textbox DateTimePicker Panel Combobox be Groupbox Picturebox Button Abb.: Beispiel für ein Eingabeformular ro Diese Abbildung findest du in der PowerPointPräsentation unter der ID: 1169. sep Ü 1: Erstelle das abgebildete Formular in einer neuen Windows-Anwendung und verwende sinnvolle Namen für die Controls, z.B. txtVorname oder radioWeiblich. a) Erstelle einen Eventhandler für den Speichern-Button, der eine Messagebox mit den Inhalten der Controls Vorname- und Zuname-Textbox, Geburtsdatum-DateTimePicker, Familienstand-Combobox sowie Geschlecht- und Hobbys-Groupbox ausgibt! b)Erstelle einen Eventhandler für den Abbrechen-Button, der die Inhalte der Textboxen Vor- und Zuname löscht sowie die beiden Hobby-Checkboxen deaktiviert. Gültigkeit von Klassenvariablen Variablen und Prozeduren sind Bestandteile einer Klasse. Prozeduren werden auch als Methoden bezeichnet. Eine Klassenvariable ist in der gesamten Klasse und damit in allen Prozeduren einer Klasse gültig. Die Gültigkeit einer Prozedurvariablen endet mit dem Ende der Prozedur. Diese Abbildungen findest du in der PowerPoint-Präsentation unter der ID: 1169. Softwareentwicklung Wie wir in der letzten Lerneinheit gesehen haben, müssen Variablen immer dort deklariert werden, wo sie gültig sein sollen. Anders gesagt: Variablen leben nur in ihrem Umfeld. Deklarieren wir eine Variable in einem Eventhandler, dann lebt diese Variable auch nur innerhalb dieser Prozedur. Sobald die Prozedur zu Ende ist, ist die Variable nicht mehr gültig. Die folgende Abbildung verdeutlicht die Gültigkeit von Klassen- und Prozedurvariablen. Le Eine Klasse wird mit dem Schlüsselwort class deklariert. public partial class Form1 : Form { Klassenvariable string vorname; Prozedurvariable public Form1() { gehalt wird double gehalt = 2500; erzeugt vorname = "Hans"; InitializeComponent(); gehalt stirbt } vorname gilt in der gesamten Klasse, somit auch in allen Prozeduren und Eventhandlern. void Eventhandler() { vorname = "Alex"; } } Abb.: Variablen und ihre Gültigkeit auf Klassen- und Prozedurebene 33 1 Programmieren mit Visual C# Lerneinheit 4: Windows-Formulare und Controls Lernen Üben Mr. What und Ms. Check Sichern Wissen Kann eine Prozedur auf Klassenvariablen aus anderen Klassen zugreifen? Klassenvariablen gelten zwar für die ganze Klasse, z.B. ein bestimmtes Windows-Formular, aber nicht darüber hinaus. Klassenvariablen sind private Variablen der Klasse. Aber sie können über einen Zugriffsmodifizierer eine erweiterte Gültigkeit erhalten, z.B. mittels public. 2 Eventhandler be Auf Ereignisse reagieren Wenn wir auf ein beliebiges Control doppelklicken, erhalten wir einen StandardEventhandler für das Control, z.B. bei einem Button einen Click-Eventhandler oder bei einer Textbox einen TextChanged-Eventhandler. Darstellung der Events für ein Control Beachte Bei den Eigenschaften zu einem Control können wir zwischen Properties und Events umschalten. ro Properties Wir können auch Eventhandler erzeugen, die auf andere Ereignisse eines Controls reagieren, z.B. wenn die Maus über das Control bewegt wird, ohne dass die Maustaste gedrückt wird. Mehrere Eventhandler für ein Control können nebeneinander existieren. Sobald ein bestimmtes Event eintritt, wird die entsprechende Eventhandler-Prozedur aufgerufen und der darin enthaltene Programmcode ausgeführt. sep Events Das Lehrbeispiel L 1 zeigt die Verwendung der Eventhandler MouseMove und MouseLeave zur Anzeige eines Tipp-Textes in einem Label. Le L 1: private void button1_Click(object sender, EventArgs e) { int summe = 0; for (int i = 1; i <= 10; i++) { summe += i; } MessageBox.Show("Summe: " + summe); } Wenn der Benutzer die Maus über den Button bewegt, wird der TippText angezeigt. 34 private void button1_MouseMove(object sender, MouseEventArgs e) { // Zeigt den Tipp-Text im Label an labelTipp.Text = "Berechnet die Summe!"; } private void button1_MouseLeave(object sender, EventArgs e) { // Entfernt den Tipp-Text aus dem Label labelTipp.Text = ""; } Softwareentwicklung 3 Formularklasse Container für Controls und Eventhandler Die Klasse Form ist in der Framework Class Library (FCL) im Namensraum System. Windows.Forms festgelegt. Dieser Namensraum wurde mit using eingebunden, weshalb wir nur Form schreiben. Nachdem wir uns etwas genauer mit den Eventhandler-Prozeduren beschäftigt haben, widmen wir uns jetzt ihrem Umfeld, der Formularklasse. Alle Eventhandler eines Formulars werden in der Formularklasse festgelegt. Die Klasse hat den Namen des Formulars – wenn wir ihn nicht ändern, ist er Form1. Jede Formularklasse wird vom Standardformular Form abgeleitet. Das Standardformular Form vererbt seine Funktionalität an unser Formular, z.B. Form1, was durch einen Doppelpunkt symbolisiert wird. Die Klasse Form1 wird mit class Form1 : Form eingeleitet, das bedeutet Form1 erbt von Form. Partielle Klasse be Eine Formularklasse ist eine partielle Klasse, sie wird als partial class deklariert. Eine partielle Klasse ist ein Teil einer Klasse, der restliche Teil der Klasse befindet sich in einer anderen Quelltextdatei. Partielle Klassen tragen zu mehr Übersichtlichkeit bei den Formularklassen bei. Um den bislang verborgenen Teil der Formularklasse Form1 zu sehen, doppelklicken wir auf die Datei Form1.Designer.cs im Solutionexplorer. Die Designerdatei hat denselben Namen wie die partielle Formularklasse. Die Controls des Formulars werden in der Methode InitializeComponent als Objekte mit ihren Eigenschaften erzeugt. ro Die Datei Form1. Designer.cs enthält den zweiten Teil der partiellen Formularklasse Form1. In Kapitel 2 werden wir uns mit der objektorientierten Programmierung, z.B. Klassen, Objekten und Vererbung, intensiv beschäftigen. 4 Zugriffsmodifizierer sep Private und öffentliche Klassenelemente Betreffend die Gültigkeit von Variablen haben wir bereits erfahren, dass diese immer privat innerhalb eines Kontextes gültig sind, z.B. innerhalb einer Klasse, einer Prozedur oder einer Schleife. In diesen Fällen wird automatisch der Zugriffsmodifizierer private verwendet. Für Klassenelemente, z.B. Klassenvariablen und Eventhandler, darf ein Zugriffsmodifizierer explizit angegeben werden – falls dies unterbleibt, wird automatisch private angenommen. Le Das folgende Lehrbeispiel zeigt eine Formularklasse mit ihren Bestandteilen und deren Zugriffsmodifizierern. L 2: Formularklasse public partial class Form1 : Form { private double gehalt; // private Klassenvariable public int persNr; // öffentliche Klassenvariable public Form1() Formularkonstruktor { InitializeComponent(); Dieser Prozeduraufruf erzeugt die Formularelemente im Formular. } } Weitere Zugriffsmodifizierer sind protected und internal. Softwareentwicklung private void button1_Click(object sender, EventArgs e) { Eventhandler } Die Formularklasse und der Formularkonstruktor sind immer public, alle anderen Elemente einer Klasse sind private, wenn sie von anderen Klassen nicht benötigt werden. Die Variable persNr wurde als öffentliche Variable deklariert, d.h., dass andere Klassen auf diese Variable zugreifen können. Mit der Variable gehalt ist dies nicht möglich, sie ist privat. 35 1 Programmieren mit Visual C# Lerneinheit 4: Windows-Formulare und Controls Lernen Üben Beachte Sichern Wissen Zugriffsmodifizierer dürfen nur für Klassenelemente, z.B. Klassenvariablen, Formularkonstruktor und Eventhandler, verwendet werden. Formularklasse öffentliche Klassenvariablen Formularklasse private Klassenvariablen Abb.: Klassenvariablen und ihre Zugriffsmodifizierer ro Diese Abbildung findest du in der Power-PointPräsentation unter der ID: 1169. be Programmklasse static class Program { static void Main() { // ... Application.Run (new Form1()); } } Visual C# ist eine vollständig objektorientierte Programmiersprache. In Kapitel 2 werden wir uns mit den Konzepten und der Verwendung der objektorientierten Programmierung genauer beschäftigen. Wann verwende ich öffentliche Klassenvariablen? Im Rahmen der OOP wirst du das Konzept der Zugriffsmethoden kennenlernen, die du anstatt einer öffentlichen Klassenvariablen (Eigenschaft) einsetzen wirst. Variablen sind immer in eine Klasse bzw. ein Objekt eingekapselt und dürfen von außen nicht direkt veränderbar oder lesbar sein. Le Mr. What und Ms. Check Um robuste Anwendungen erstellen zu können, ist es sehr wichtig, dass Variablen und Prozeduren nur dort gültig sind, wo dies erforderlich ist. Andernfalls könnten z.B. die Werte von Variablen irrtümlich verändert werden, was zu undefinierten Programmzuständen führen kann. Ein Hacker penetriert z.B. absichtlich ein Programm, sodass dieses einen Laufzeitfehler verursacht und dadurch eine Sicherheitslücke entsteht. Viele Würmer nutzen solche Exploits für ihre Angriffe. sep Exploit = Computerprogramm, das Fehlfunktionen eines anderen Programmes ausnutzt. Üben Übungsbeispiele 36 Ü 2: Erstelle eine Windows-Anwendung mit einem Formular zur Eingabe der Schüler/innen einer Klasse gemäß der folgenden Abbildung. Das Formular soll folgende Controls enthalten: Überschriftenlabel, Panel, Beschriftungen der Controls, Textboxen für Vorname und Zuname, Combobox für die Auswahl der Klasse und einen DateTimePicker für das Geburtsdatum. Softwareentwicklung ro be Erstelle für den Neu-Button im Formular einen Eventhandler, der die Inhalte der Textboxen entfernt, das Geburtsdatum auf den 1. Jänner 1980 setzt und das Häkchen bei der Checkbox Aufstiegsberechtigt deaktiviert. Ü 3: sep Erstelle eine neue Windows-Anwendung wie abgebildet. Die drei Textboxen heißen txtMinuten, txtSekunden und txtHundertstel. Der Button erhält den Namen btStart. Außerdem benötigst du für das Formular das TimerControl timer1 mit einem Intervall von 33 ms. Deklariere die private Klassenvariable startzeit vom Typ DateTime. Le Erstelle einen Eventhandler für das Klicken des Start-Buttons. Wenn der Timer nicht läuft, also timer1.Enabled nicht true ist, weise der Klassenvariablen startzeit die aktuelle Systemzeit zu, schalte den Timer ein und ändere den Button-Text auf „Stopp“. Falls der Timer läuft, schalte ihn ab und ändere den Button-Text auf „Start“. Erstelle den Eventhandler für das Timer-Control timer1. Deklariere die Prozedurvariable zeit vom Typ TimeSpan und weise ihr die Differenz zwischen DateTime.Now und dem Inhalt der Variablen startzeit zu. Weise den Textboxen die Inhalte von zeit.Minutes, zeit.Seconds und zeit.Milliseconds / 10 zu. Stelle die Hundertstel als ganze Zahl dar. Beachte die erforderliche Konvertierung für die Darstellung in den Textboxen. Zusätzlich zu diesen Übungen findest du in SbX Internetaufgaben. ID: 1170 Softwareentwicklung 37 1 Programmieren mit Visual C# Lerneinheit 4: Windows-Formulare und Controls Lernen Üben Sichern Wissen Sichern In dieser Lerneinheit haben wir uns mit der Erstellung von Windows-Formularen, Eventhandlern und der Gültigkeit von Klassenvariablen beschäftigt. Controls sind Formularelemente, die Ereignisse auslösen können und zur Ein- bzw. Ausgabe von Daten dienen. Eventhandler Ein Eventhandler ist eine Ereignisprozedur, die aufgerufen wird, sobald ein bestimmtes Ereignis eintritt, z.B. das Klicken auf einen Button. Der in der Ereignisprozedur hinterlegte Programmcode wird ausgeführt, nachdem das Ereignis aufgetreten ist. Zugriffsmodifizierer Für Klassen und deren Bestandteile, wie z.B. Variablen und Eventhandler, können die Zugriffsmodifizierer private und public verwendet werden. Weitere Zugriffsmodifizierer sind protected und internal. Klassenvariable Eine Klassenvariable ist für alle Elemente einer Klasse gültig, z.B. für alle Eventhandler. Klassenvariablen können als private oder öffentliche Variablen deklariert werden. Prozedurvariable Eine Prozedurvariable wird innerhalb einer Prozedur erzeugt und ist nur innerhalb dieser Prozedur bekannt und gültig. Die Prozedurvariable stirbt mit dem Ende der Prozedur und wird mit jedem Aufruf der Prozedur wieder neu erzeugt. Formularklasse Die Klasse eines Windows-Formulars ist eine partielle Klasse (partial class). Sie besteht aus einem Designerteil, der die Formularobjekte erzeugt und festlegt, sowie dem Teil, der die Eventhandler beinhaltet. Alle Formularklassen erben ihre Grundfunktionalität von der Basisklasse System.Windows.Forms.Form aus der Framework Class Library (FCL). sep ro be Controls Zusätzlich zu dieser Zusammenfassung findest du in SbX eine Bildschirmpräsentation. ID: 1171 Le Wissen Wiederholungsfragen und -aufgaben 1.Wie lauten die Eigenschaften einer Textbox, eines Progressbars bzw. einer Checkbox, um deren Werte abzufragen bzw. zu verändern? 2.Erkläre die Begriffe Event und Eventhandler! 3.Kann eine Prozedurvariable mittels public-Zugriffsmodifizierer für andere Prozeduren gültig sein? Begründe deine Antwort! 4.Warum sollten Klassenvariablen immer privat deklariert werden? 5.Wie gelangt man zum verborgenen Teil einer Formularklasse? 6.Was bedeutet partial class? 7.Wofür steht der Doppelpunkt in der Klassendeklaration class Form1 : Form? Zusätzlich zu diesen Aufgaben findest du in SbX ein Quiz. ID: 1172 38 Softwareentwicklung Lerncheck Ich kann jetzt … w ... Windows-Anwendungen mit partiellen Formularklassen verwenden. w ... Formulare mit verschiedenen Controls erstellen. w ... private sowie öffentliche Klassenvariablen und -prozeduren deklarieren. w ... Eventhandler für unterschiedliche Events eines Controls schreiben. w ... partielle Formularklassen verwenden. Le sep ro be In der nächsten Lerneinheit sehen wir uns an, wie wir Laufzeitfehler behandeln und Programme mit Hilfe von Prozeduren und Funktionen effizienter erstellen können. Außerdem lernen wir die Verwendung von Enumerationen und Strukturen kennen. Softwareentwicklung 39 1 Programmieren mit Visual C# Lerneinheit 4: Windows-Formulare und Controls Lernen Üben Sichern Wissen Lerneinheit 5 Fehlerbehandlung, Methoden und Strukturen Alle SbX-Inhalte zu dieser Lerneinheit findest du unter der ID: 1173. In dieser Lerneinheit erarbeiten wir die Behandlung von Laufzeitfehlern sowie das Auslagern von Programmcodes in wiederverwendbare Methoden. Wir beschäftigen uns mit 1 Fehlerbehandlung ro Lernen be ● dem Auftreten von Programmfehlern und deren Korrektur, ● der Behandlung von Laufzeitfehlern mittels try-catch-finally, ● dem Auslagern von Codes in wiederverwendbare Prozeduren und Funktionen sowie ● der Verwendung von Enumerationen und Strukturen. Syntax- und Laufzeitfehler Eine Abbildung zu diesem Programm findest du in der Power-PointPräsentation unter der ID: 1174. sep Laufzeitfehler werden vom Compiler nicht erkannt und treten erst während des Betriebes auf. Wie schon in der ersten Lerneinheit erwähnt, passieren beim Programmieren oft Fehler. Sie entstehen z.B., wenn ein Befehl oder Variablenname falsch geschrieben wird. Solche Fehler sind kein großes Problem, denn sie werden vom Compiler erkannt, bevor das Programm an den Benutzer ausgeliefert wird. Ein Programm kann erst dann vom Compiler vollständig übersetzt werden, wenn keine Syntaxfehler mehr auftreten. Problematischer sind Fehler, die nur unter ganz bestimmten Umständen während des Betriebes eines Programmes auftreten. Solche Fehler werden Laufzeitfehler genannt. Ein Laufzeitfehler tritt z.B. bei zahl = 50 / a auf, wenn die Variable a den Wert 0 hat. Ein Benutzer soll in eine Textbox eine Zahl zwischen 0 und 36 eingeben. Was passiert, wenn der Benutzer die Zahl 37 eingibt? Wir könnten diesen Fall mit einer if-Verzweigung abfragen und nur die Zahlen 0 bis 36 zulassen: Le Syntaxfehler werden durch falsche Anwendung von Befehlen oder falsch geschriebene Befehle verursacht. L 1: int zahl = Convert.ToInt32(txtEingabe.Text); if (zahl < 0 || zahl > 36) MessageBox.Show("Eingabe ungültig. Bitte wiederholen."); Was passiert aber, wenn der Benutzer keine Zahl, sondern gar nichts, einen Buchstaben oder ein Sonderzeichen eingibt? Dann würde Convert.ToInt32 einen Laufzeitfehler verursachen. Behandlung von Laufzeitfehlern mittels try-catch-finally try-catch-finally ermöglicht die Behandlung von Laufzeitfehlern. 40 1 Wenn der erfolgreiche Ausgang einer Operation ungewiss ist, sollte diese Operation in einen try-Block geschrieben werden. Zum Beispiel wollen wir eine Division durchführen, aber wir sind uns nicht sicher, dass der Divisor ungleich 0 ist. Softwareentwicklung 2 Im Fall eines Fehlers können wir in einem dem try-Block folgenden catch-Block das Auftreten eines bestimmten Fehlers überprüfen und darauf reagieren. Wenn der Divisor 0 ist, so ist z.B. dem Benutzer eine Fehlermeldung auszugeben oder der Benutzer hat die Eingabe mit einem gültigen Wert zu wiederholen. 3 In einem finally-Block können Operationen angegeben werden, die, egal ob Fehler auftreten oder nicht, auf jeden Fall ausgeführt werden sollen. Steht im try-Block das Öffnen einer Datenbankverbindung, so muss diese im finally-Block auf jeden Fall geschlossen werden, egal ob die Datenbank erfolgreich geöffnet werden kann und Daten gelesen werden oder ob ein Fehler auftritt. Falls der Benutzer keine Zahl eingibt, folgt ein Hinweis. be L 2: try { if (Convert.ToInt32(txtTipp.Text) == zahl) { MessageBox.Show("Hurra, das ist richtig."); panelSpielfeld.Visible = false; } else if (Convert.ToInt32(txtTipp.Text) < zahl) MessageBox.Show("Die gesuchte Zahl ist größer."); else MessageBox.Show("Die gesuchte Zahl ist kleiner."); } ro Im try-Block wird ein Vergleich von zwei vermeintlichen Zahlen vorgenommen. Wie wir mittels try-catch-finally einen möglichen Laufzeitfehler behandeln können, zeigt das folgende Lehrbeispiel L 2. Wenn der Benutzer bei einem Zahlen-Ratespiel in die Textbox txtTipp statt einer Zahl einen Buchstaben eingibt, wird der Laufzeitfehler durch den catchBlock abgefangen und entsprechend behandelt. sep Das Zahlen-Ratespiel findest du als Download unter der ID: 1174. catch (Exception exp) { MessageBox.Show("Ungültige Eingabe."); } Mr. What und Ms. Check Le finally { txtVersuche.Text = Convert.ToString( Convert.ToInt32(txtVersuche.Text) + 1); } Warum sollte ich das mögliche Auftreten von Laufzeitfehlern speziell berücksichtigen? Falls ein Laufzeitfehler in einem Programm auftritt, so wird das Programm beendet und der Benutzer erhält eine ihm relativ wenig sagende Fehlermeldung. Wann tritt ein Laufzeitfehler auf? Ein Laufzeitfehler tritt bei einem Programmfehler auf, der zum Zeitpunkt des Compilierens nicht vorhersehbar war. Kann ich das Auftreten von Laufzeitfehlern verhindern? Softwareentwicklung Nein. Wir können auftretende Laufzeitfehler nur abfangen und behandeln. Wenn wir z.B. durch das Ergebnis einer Berechnung dividieren, so ist der Ausgang vom Ergebnis der vorhergehenden Berechnung abhängig. Das kann funktionieren oder auch nicht. 41 1 Programmieren mit Visual C# Lerneinheit 5: Fehlerbehandlung, Methoden und Strukturen Lernen Üben Sichern Wissen Sehen wir uns nun an, wie wir leichter lesbare Programme schreiben und deren Bestandteile für andere Programme nutzen können. 2 Prozeduren und Funktionen Wiederverwendbare Programmteile Prozeduren und Funktionen sind wichtige Bestandteile von Programmen. Sie verbessern die Übersichtlichkeit und erleichtern die Programmierung. Prozeduren und Funktionen sind Anweisungsblöcke, die unter einem Namen beliebig oft angesprochen und ausgeführt werden können. Dadurch kann ein Codeblock in einem Programm öfter verwendet werden, ohne dass der Block kopiert werden muss. Eine erforderliche Änderung muss nur einmal durchgeführt werden. be Prozeduren und Funktionen werden als Methoden bezeichnet. Prozedur Hauptprogramm Funktion eb Funktionsaufruf Prozeduraufruf void erzeugt eine Prozedur ohne Rückgabewert. double ist der Datentyp des Rückgabewertes der Funktion. return liefert das Ergebnis an den aufrufenden Code. 42 1 Eine Prozedur ist ein Anweisungsblock, der eine bestimmte Aktion ausführt. Prozeduren haben wir bereits in Form der Eventhandler bei Windows-Anwendungen kennengelernt. Eine Prozedur führt ihren Code aus, wenn sie aufgerufen wird. Im Fall des Eventhandlers ist der Aufruf ein Event, wie z.B. der Click auf einen Button. 2 Eine Funktion ist ein Anweisungsblock, der eine bestimmte Aktion ausführt und ein Ergebnis an den aufrufenden Code übermittelt. Wir wollen beispielsweise die Reichweite eines Autos mit dem jeweils aktuellen Benzinvorrat auf Basis des durchschnittlichen Verbrauches berechnen. Die Funktion Reichweite() liefert das gewünschte Ergebnis. Le Math.Pow() ist eine Funktion aus dem Framework, die das Ergebnis einer Potenzrechnung liefert. return ergebnis; Abb.: Verwendung einer Prozedur und einer Funktion Methoden Eventhandler sind Prozeduren, die wir bereits kennengelernt haben. nis sep Diese Abbildung findest du in der PowerPointPräsentation unter der ID: 1174. ro Erg L 3: private void button1_Click(object sender, EventArgs e) { double reichweite = Reichweite(34.4, 7.5); ReichweiteAusgabe(reichweite); } Parameter private void ReichweiteAusgabe(double reichweite) { MessageBox.Show("Reichweite: " + reichweite); } private double Reichweite(double benzinvorrat, double verbrauch) { // Reichweite auf Ganze gerundet zurückliefern return Math.Round(benzinvorrat / (verbrauch / 100), 2); } Softwareentwicklung Der Unterschied zwischen einer Prozedur und einer Funktion besteht darin, dass die Funktion ein Ergebnis liefert, während die Prozedur dies nicht tut. Das folgende Lehrbeispiel zeigt den Aufruf der Prozedur und der Funktion in einer einzigen Codezeile: Das Funktionsergebnis ist der Parameterwert für die Prozedur. L 4: private void button1_Click(object sender, EventArgs e) { ReichweiteAusgabe( Reichweite(34.4, 7.5) ); } be private void ReichweiteAusgabe(double reichweite) { MessageBox.Show("Reichweite: " + reichweite); } ro private double Reichweite(double benzinvorrat, double verbrauch) { // Reichweite auf Ganze gerundet zurückliefern return Math.Round(benzinvorrat / (verbrauch / 100), 2); } Wir können uns eine Funktion im Prinzip wie eine Variable vorstellen, deren Inhalt bei jedem Funktionsaufruf neu berechnet wird. Das Ergebnis des Funktionsaufrufes ist die Reichweite. Dieses Ergebnis dient gleichzeitig als Parameter für die Prozedur ReichweiteAusgabe. Sofern in der Funktion ein Laufzeitfehler auftritt, wird dieser mittels try-catch abgefangen. Die Reichweite-Funktion hat noch eine Schwäche: Aufgrund eines Eingabefehlers des Benutzers könnte der Wert der Variablen verbrauch 0 sein. In diesem Fall würde ein Laufzeitfehler beim Aufruf der Funktion auftreten. Sehen wir uns an, wie wir die Funktion Reichweite() verbessern können, sodass dieses Problem nicht mehr auftreten kann. L 5: private void button1_Click(object sender, EventArgs e) { try { ReichweiteAusgabe( Reichweite(34.4, 7.5) ); } catch (Exception exp) { MessageBox.Show(exp.Message); } } Le Die Behandlung von Laufzeitfehlern muss innerhalb der Prozedur oder Funktion erfolgen. sep Fehlerbehandlung in Methoden private void ReichweiteAusgabe(double reichweite) { MessageBox.Show("Reichweite: " + reichweite); } Mittels throw new Exception wird ein Laufzeitfehler erzeugt, wenn eine Operation nicht erlaubt ist. Softwareentwicklung private double Reichweite(double benzinvorrat, double verbrauch) { if (verbrauch > 0) return Math.Round(benzinvorrat / (verbrauch / 100), 2); else throw new Exception("Ungültiger Verbrauch!"); } 43 1 Programmieren mit Visual C# Lerneinheit 5: Fehlerbehandlung, Methoden und Strukturen Lernen Üben Prozeduren und Funktionen sollten möglichst unabhängig vom aufrufenden Code sein. Sichern Wissen Um eine Prozedur bzw. Funktion möglichst unabhängig von der Gültigkeit der übergebenen Parameter zu machen, sollte mittels throw new Exception("Fehlertext") innerhalb der Prozedur bzw. Funktion ein Laufzeitfehler erzeugt werden, der im aufrufenden Programmcode durch einen try-catch-Block abgefangen wird. Hauptprogramm Funktion eitLaufzler feh throw new Exception("Fehler"); be Diese Abbildung findest du in der PowerPointPräsentation unter der ID: 1174. try { Funktionsaufruf } catch (Exception exp) { MessageBox( exp.Message); } Abb.: Eine Funktion gibt die Fehlermeldung an das Hauptprogramm weiter Warum sollte ich in einer Prozedur keine Messagebox mit dem Fehlertext ausgeben? Wenn die Prozeduren und Funktionen nur einen Laufzeitfehler erzeugen, ohne diesen auszugeben, kannst du diese Programmteile für Konsolen-, Windows- und Web-Anwendungen verwenden. Die Ausgabe des Fehlers erfolgt im Hauptprogramm. Le Mr. What und Ms. Check In einer Prozedur oder Funktion sollte keine Fehlermeldung ausgegeben werden, sondern ein Ausnahmefehler erzeugt werden. sep Beachte ro Das Hauptprogramm ruft eine Funktion auf, die aufgrund ungültiger Werte einen Ausnahmefehler Exception erzeugt. Der erzeugte Fehler mit dem Fehlertext wird an den aufrufenden Code übergeben und dort vom catch-Block aufgefangen. Die Eigenschaft Message des Exception-Objektes exp enthält den Fehlertext „Fehler“. Übergabetypen Die Übergabe von Parametern kann auf zwei verschiedene Arten erfolgen: Werte- und Verweistypen Wertetypen-Parameter sind Kopien der Variablen des aufrufenden Programmcodes. 1 Ein Wertetyp-Parameter erzeugt eine Kopie des übergebenen Wertes. VerweistypenParameter zeigen auf die Originalvariablen des aufrufenden Programmcodes. 2 Ein Verweistyp-Parameter zeigt auf den Wert im Hauptprogramm. 44 Hierbei wird eine Kopie des Wertes der Variablen vom aufrufenden Code an die Prozedur bzw. Funktion übergeben. In unserem Reichweite-Beispiel werden also Kopien der Werte von benzinvorrat und verbrauch an die Funktion übergeben. Hier wird der Verweis auf den Wert der Variablen des aufrufenden Codes übergeben. Wir können uns das wie einen Hyperlink auf die Speicherstelle der Variablen des Hauptprogramms vorstellen. Würde z.B. die Funktion Reichweite die Variable benzinvorrat ändern, so würde diese Änderung auch für die Variable des Hauptprogrammes gelten. Die Änderung greift in das Hauptprogramm durch. Bei einer Wertetyp-Übergabe würde das nicht passieren, da der Wert als Kopie in einer separaten, nur für die Prozedur oder Funktion sichtbaren Variablen gespeichert ist. Softwareentwicklung Beachte Überlicherweise verwenden wir Parameter als Wertetypen. Das folgende Lehrbeispiel L 6 zeigt die unterschiedlichen Auswirkungen der Verwendung von Werte- und Verweistypenparametern. L 6: private void button1_Click(object sender, EventArgs e) { double benzinvorrat = 50, verbrauch = 5; // benzinvorrat wird als Verweistyp übergeben Fahren(200, ref benzinvorrat, verbrauch); be } Verweistyp // Funktion mit Wertetyp-Parametern double Fahren(int km, double benzinvorrat, double verbrauch) { return benzinvorrat – km * verbrauch / 100; } ro Der Verweistyp zeigt auf die Variable des Hauptprogrammes und verändert diese. // Funktionsaufruf mit Wertetyp-Parametern benzinvorrat = Fahren(200, benzinvorrat, verbrauch); // Prozedur mit Verweistyp-Parameter void Fahren(int km, ref double benzinvorrat, double verbrauch) { benzinvorrat –= km * verbrauch / 100; } sep Ein VerweistypParameter wird mit einem vorangestellten ref gekennzeichnet. Der Eventhandler erzeugt die privaten Variablen benzinvorrat und verbrauch. Beide Variablen sind weder der Prozedur Fahren noch der Funktion Fahren bekannt, also im Eventhandler eingekapselt. Le Die Funktion Fahren erhält für ihre private Funktionsvariable benzinvorrat eine Kopie des Wertes der Eventhandler-Variablen benzinvorrat. Es gibt nun zwei benzinvorrat-Variablen, beide enthalten den Wert 50. Die Funktionsvariable benzinvorrat wird um den Verbrauch von zehn Litern verringert. Das Ergebnis von 40 Litern wird an den Eventhandler zurückgeliefert und überschreibt dort den Wert der Eventhandler-Variablen benzinvorrat mit 40. Die Prozedur Fahren erhält statt einer Kopie des Wertes 40 einen Verweis auf die Eventhandler-Variable benzinvorrat, die den Wert 40 enthält. Bei der Prozedurvariablen benzinvorrat handelt es sich zwar um eine private Variable, aber sie greift auf die Eventhandler-Variable durch und verändert diese. Mr. What und Ms. Check Warum darf ich eine Prozedur und eine Funktion mit demselben Namen verwenden? Beim sogenannten Überladen (engl. Overload) von Prozeduren bzw. Funktionen müssen unterschiedliche Typen bei den Parametern verwendet werden. Im Lehrbeispiel L 6 sind zwar die Datentypen ident, aber bei der Prozedur wurde ein Verweistyp benutzt. Das genügt dem Compiler für die Unterscheidung der beiden Methoden. Methoden, das sind Prozeduren und Funktionen, sind eine sehr wichtige Grundlage für die objektorientierte Programmierung. Softwareentwicklung 45 1 Programmieren mit Visual C# Lerneinheit 5: Fehlerbehandlung, Methoden und Strukturen Lernen Üben Sichern Wissen Überladen von Methoden In einer Klasse darf es mehrere Prozeduren und Funktionen mit demselben Namen geben, wenn sich diese anhand der Parameter klar unterscheiden lassen. Damit ist aber keineswegs der Name der Parameter gemeint, sondern der Daten- bzw. Übergabetyp. 1 Überladene Prozeduren und Funktionen müssen unterschiedliche Parametertypen aufweisen, entweder verschiedene Daten- oder unterschiedliche Übergabetypen. Überladene Parameter können sich in ihrer Anzahl, in ihrem Datentyp, in ihrem Übergabetyp oder in der Reihenfolge der Datentypen – bei sonst gleichen Typen – unterscheiden. 2 Beim Überladen spielt der Rückgabe-Datentyp keine Rolle bei der Unterscheidung. be Das Überladen ist für Prozeduren und Funktionen zulässig, wie wir im Lehrbeispiel L 6 bereits gesehen haben. Aber egal ob eine Prozedur oder Funktion überladen wird, müssen sich die Parametertypen unterscheiden. Das Lehrbeispiel L 7 zeigt die mehrfach überladene Deklaration einer Fahren-Prozedur. ro L 7: // Überladene Fahren-Methode private int Fahren() { } private void Fahren(int km) { } sep Unterschiedliche Rückgabetypen sind für das Überladen nicht relevant! private void Fahren(int km, ref double verbrauch) { } Le private void Fahren(int km, double verbrauch) { } private void Fahren(double verbrauch, int km) { } Mr. What und Ms. Check Wie kann ich beliebig viele Werte an eine Prozedur oder Funktion übergeben? Eine einfache Lösung stellt params dar, z.B. private void Fahren(double verbrauch, params int[] km). Die Variable km ist ein Array und kann mit einer foreach-Schleife durchlaufen werden. Um das Auto mehrmals hintereinander fahren zu lassen, rufst du die Prozedur z.B. mittels Fahren(7.5, 200, 150, 180, 70); auf. Im letzten Abschnitt in dieser Lerneinheit beschäftigen wir uns mit zwei verschiedenen Möglichkeiten zur typsicheren Speicherung von Daten, den Enumerationen und den Strukturen. 46 Softwareentwicklung 3 Enumerationen Aufzählungen L 8: public partial class Form1 : Form { // Enumeration definieren public enum Geschlecht { Mann, Frau } be Eine Enumeration enthält eine vollständige Aufzählung von konstanten Werten. Enumerationen können entweder als Teil einer Klasse oder eines Namensraumes deklariert werden. ro private void button1_Click(object sender, EventArgs e) { // Enumeration verwenden Geschlecht geschlecht = Geschlecht.Frau; MessageBox.Show("Geschlecht: " + geschlecht); } } Wofür kann ich Enumerationen sinnvoll einsetzen? Enumerationen erlauben nur die Zuweisung der vordefinierten Werte. Damit kannst du hundertprozentig ausschließen, dass eine Variable einen anderen Wert annehmen kann, als einen von dir gewünschten. Le Mr. What und Ms. Check sep Die Enumeration Geschlecht erlaubt nur die Ausprägungen Mann und Frau. Im Eventhandler wird die Variable geschlecht vom Typ der Enumeration Geschlecht deklariert. Für die Zuweisung wird der Name der Enumeration, gefolgt von einem Punkt und der Ausprägung, verwendet. 4 Strukturen Container für Werte Mit einer Struktur lassen sich Variablen unterschiedlicher Datentypen zusammenfassen. L 9: // Struktur definieren public struct Schueler { public string name; public Geschlecht geschlecht; public int jahrgang; // Enumeration aus L 8 public void Aufsteigen() { jahrgang++; } } Softwareentwicklung 47 1 Programmieren mit Visual C# Lerneinheit 5: Fehlerbehandlung, Methoden und Strukturen Lernen Üben Sichern Wissen private void button1_Click(object sender, EventArgs e) { // Objekt erzeugen Schueler s = new Schueler(); // Eigenschaften zuweisen s.name = "Adam Herbert"; s.geschlecht = Geschlecht.Mann; s.jahrgang = 3; // Methodenaufruf s.Aufsteigen(); be MessageBox.Show("Schüler: " + s.name + ", " + s.geschlecht + ", " + s.jahrgang); } Eine Struktur enthält Eigenschaften mit unterschiedlichen Datentypen, ähnlich einem Datensatz in einer Tabelle einer Datenbank. Außerdem kann eine Struktur Methoden enthalten, die auf die Eigenschaften der Struktur zugreifen und diese verändern. ro Um die Struktur Schueler auf eine neue Variable s anwenden zu können, muss das Objekt mit dem Konstruktor new Schueler() von der Struktur abgeleitet werden. Dieser Vorgang wird als Instanzierung bezeichnet. Wo darf ich Strukturen deklarieren? Strukturen kannst du entweder im Namensraum, also auf Klassenebene, oder innerhalb einer Klasse festlegen. Innerhalb von Prozeduren und Funktionen ist die Deklaration von Strukturen nicht zulässig. Le Mr. What und Ms. Check sep Eine Struktur ist einer Klasse sehr ähnlich. Strukturen sind jedoch Werttypen, Klassen dagegen Verweistypen. Außerdem unterstützen Strukturen keine Vererbung. Mit der Erstellung und Verwendung von Klassen beschäftigen wir uns im nächsten Kapitel. Vieles davon trifft auch auf Strukturen zu, weshalb wir uns an dieser Stelle nicht näher mit den Strukturen auseinandersetzen wollen. Üben Übungsbeispiele Ü 1: Ergänze die Laufzeitfehlerbehandlung im folgenden Programm: int dividend, divisor; dividend = Convert.ToInt32(txtDividend.Text); divisor = Convert.ToInt32(txtDivisor.Text); MessageBox.Show( "Quotient = " + (dividend / divisor) ); Ü 2: Ergänze die Laufzeitfehlerbehandlung im folgenden Programm: int alter = Convert.ToInt32(txtAlter.Text); MessageBox.Show("Alter: " + alter); 48 Softwareentwicklung Ü 3: Ergänze die Laufzeitfehlerbehandlung im folgenden Programm: private int Alter(DateTime gebdatum) { TimeSpan alter = DateTime.Now – gebdatum; return alter.Years; } private void button1_Click(object sender, EventArgs e) { MessageBox.Show("Alter: " + Alter( Convert.ToDateTime(txtGebDatum.Text) ) ); } be Ü 4: Ein Hauptprogramm beinhaltet die Variable benzinvorrat vom Typ Double. a) Codiere die Prozedur Tanken zum Volltanken der Autos. Der maximale Tankinhalt wird als Werttyp-Parameter, der Benzinvorrat als Verweistyp-Parameter übergeben. b) Codiere eine überladene Funktion zum Auftanken der Autos. Übergib als Werttyp-Parameter den maximalen Tankinhalt, die getankte Menge und den Benzinvorrat. ro Beachte bei der Fehlerbehandlung, dass der Tank nicht überfüllt werden darf! Die beiden Methoden sollen anwendungsunabhängig eingesetzt werden können. Ü 5: Erstelle die Struktur Auto mit folgenden Eigenschaften: Marke, PS und Farbe. Als Farben dürfen nur Rot, Blau, Grün und Schwarz möglich sein. Erstelle für die Farben daher eine Enumeration und verwende sie für die Struktur. sep Instanziere ein Autoobjekt und weise die folgenden Werte zu: Audi A3, 150 PS, Rot. Zusätzlich zu diesen Übungen findest du in SbX Internetaufgaben. ID: 1175 Le Sichern In dieser Lerneinheit haben wir die Behandlung von Laufzeitfehlern, den Einsatz von Prozeduren und Funktionen sowie Enumerationen und Strukturen besprochen. Syntaxfehler Syntaxfehler werden zur Compilierzeit erkannt und in der Fehlerliste angezeigt. Ein Programm kann nur dann erfolgreich compiliert werden, wenn es keine Syntaxfehler enthält. Laufzeitfehler Laufzeitfehler (Exceptions) werden zur Compilierzeit nicht erkannt. Sie treten erst während der Programmausführung unter bestimmten Umständen auf. Laufzeitfehler werden z.B. von ungültigen Werten in Berechnungen verursacht. try-catch-finally Laufzeitfehler können mit einem try-Block abgefangen und in einem catch-Block behandelt werden. Der finally-Block enthält jene Anweisungen, die auf jeden Fall, egal ob ein Fehler auftritt oder nicht, ausgeführt werden sollen. throw new Exception Mit dem Befehl throw new Exception() wird ein Laufzeitfehler ausgelöst. Dies ist z.B. innerhalb von Prozeduren oder Funktionen sinnvoll, um dem aufrufenden Code einen Fehler zu signalisieren. Der aufrufende Code muss die Prozedur bzw. Funktion in einem try-Block aufgerufen haben, da andernfalls das Programm mit dem Fehler beendet wird. Softwareentwicklung 49 1 Programmieren mit Visual C# Lerneinheit 5: Fehlerbehandlung, Methoden und Strukturen Lernen Üben Sichern Wissen Prozedur Prozeduren sind Programmteile, die beliebig oft aufgerufen werden können und keinen Rückgabewert an den aufrufenden Code liefern. Funktion Funktionen sind Programmteile, die beliebig oft aufgerufen werden können und einen Rückgabewert an den aufrufenden Code liefern. Methode Prozeduren und Funktionen werden allgemein als Methoden bezeichnet. An Prozeduren und Funktionen können Parameter als Werte- oder Verweistypen übergeben werden. Die Übergabe von Parametern ermöglicht die Unabhängigkeit der Prozedur bzw. Funktion von den Variablen des aufrufenden Programmcodes. Überladen Die Definition mehrerer gleichnamiger Methoden wird als Überladen bezeichnet. Die überladenen Methoden müssen sich durch die Daten- bzw. Übergabetypen ihrer Parameter unterscheiden. Enumeration Eine Enumeration ermöglicht die Festlegung von konstanten Werten in Form einer Aufzählung. Enumerationen können auf Klassenebene und innerhalb von Klassen deklariert werden. Struktur Eine Struktur ist ein Container für Variablen mit verschiedenen Datentypen sowie für Methoden, die zur Veränderung dieser Variablen dienen. Strukturen sind Klassen sehr ähnlich. Sie können auf Klassenebene und innerhalb von Klassen deklariert werden. ro be Parameter Zusätzlich zu dieser Zusammenfassung findest du in SbX eine Bildschirmpräsentation. ID: 1176 sep Wissen Wiederholungsfragen und -aufgaben 1. Erkläre den Unterschied zwischen Syntax- und Laufzeitfehlern! 2. Warum können Laufzeitfehler niemals gänzlich ausgeschlossen werden? Le 3. Erkläre den Aufbau von try-catch-finally! 4. Nenne ein Beispiel, bei dem vom Programmierer mittels throw new Exception ein Laufzeitfehler bewusst erzeugt wird! 5. Erkläre den Unterschied zwischen einer Prozedur und einer Funktion! 6. Warum sollten Prozeduren und Funktionen von den Variablen des aufrufenden Programmcodes unabhängig sein? 7. Erkläre den Unterschied zwischen Werte- und Verweistypen-Parametern! 8. Was passiert, wenn eine Funktion keinen Rückgabewert hat? 9. Wie kann ein Laufzeitfehler in einer Prozedur oder Funktion an den aufrufenden Code weitergereicht werden? Erkläre den Vorgang anhand eines selbst gewählten Beispiels! 10. Worauf muss beim Überladen von Methoden geachtet werden? 11. Erkläre den Unterschied zwischen einer Enumeration und einer Struktur! Zusätzlich zu diesen Aufgaben findest du in SbX ein Quiz. ID: 1177 50 Softwareentwicklung Lerncheck Ich kann jetzt … w... Compilier- und Laufzeitfehler sowie deren Konsequenzen unterscheiden. w... Laufzeitfehler mittels try-catch-finally behandeln. w... von der Möglichkeit der Weiterreichung von Laufzeitfehlern von einer Prozedur oder Funktion an den aufrufenden Programmcode Gebrauch machen. w... Prozeduren und Funktionen mit Parametern verwenden und überladen. w... Werte- und Verweistypen-Parameter unterscheiden. w... Enumerationen und Strukturen verwenden. Le sep ro be In diesem Kapitel haben wir uns die Grundlagen der .NET-Programmierung erarbeitet. Wir haben gelernt, wie ein Computerprogramm in Visual C# erstellt wird und welche Kontrollstrukturen dafür benutzt werden. Softwareentwicklung 51 1 Programmieren mit Visual C# Lerneinheit 5: Fehlerbehandlung, Methoden und Strukturen Lernen Üben Sichern Wissen Kapitelrückblick In diesem Kapitel haben wir gelernt, wie ein Computerprogramm mit Hilfe der Programmiersprache Visual C# erstellt wird. Was genau sollte ich nun eigentlich wissen? be Anhand des Lernchecks hier am Kapitelende kannst du leicht überprüfen, ob du wirklich alles verstanden hast! Lerncheck Ich kann jetzt … ro w ... den Begriff „Integrierte Entwicklungsumgebung“ erklären und eine .NET-Programmiersprache anwenden. w ... den Aufbau und die Grundelemente eines Programms erklären. w ... Datentypen wie z.B. bool, byte, int, long, float, double, decimal und string auf Variablen, Konstanten und Arrays anwenden. w ... ein Programm erstellen, compilieren und ausführen. sep w ... Verzweigungen in einem eigenen Programm sinnvoll einsetzen. w ... Arrays und Collections beschreiben und in einem Programm verwenden. w ... die Begriffe WinForm, Control sowie Eventhandler und deren Zusammenwirken erklären. w ... den Ablauf einer for- und einer foreach-Schleife beschreiben. w ... den Unterschied zwischen kopf- und fußgesteuerten bedingten Schleifen erklären. w ... in meinen Programmen Laufzeitfehler vermeiden. w ... Prozeduren und Funktionen sowie Enumerationen und Strukturen einsetzen. Le Zusätzlich findest du in SbX eine Bildschirmpräsentation zu diesem Kapitel. ID: 1200 Im nächsten Kapitel bauen wir auf den erarbeiteten Grundlagen auf. Wir beschäftigen uns mit den Konzepten der objektorientierten Programmierung und sehen uns an, wie Programme nach diesen Regeln erstellt werden. 52 Softwareentwicklung