C# Programmieren: für Einsteiger: Der leichte Weg zum C#-Experten! (Visual Studio 2019) (Einfach Programmieren lernen 5) 9783966450010

"Wenn es darum geht, mit welcher Sprache ein hoffnungsvoller Programmiernovize den Anfang machen sollte, ist C# nic

1,064 172 5MB

German Pages 334 [353] Year 2019

Report DMCA / Copyright

DOWNLOAD FILE

Polecaj historie

C# Programmieren: für Einsteiger: Der leichte Weg zum C#-Experten! (Visual Studio 2019) (Einfach Programmieren lernen 5)
 9783966450010

Table of contents :
Cover
Title
Copyright
Table Of Contents
1 Einleitung
1.1 C#: Eine Programmiersprache mit vielfältigen Anwendu ngsmöglichkeiten
1.2 Die Entwicklungsgeschichte von C#
1.3 C# und .NET Framework
1.4 Vom Code zum fertigen Programm: die Kompilierung
2 Visual Studio: die passende IDE für die Entwicklung mit C#
2.1 Visual Studio installieren
2.2 Ein neues Projekt mit Visual Studio erstellen
3 Das erste Programm in C#
3.1 Eine Ausgabe mit C# erzeugen
3.2 So ist ein C#-Programm aufgebaut
3.3 Den Programmcode kompilieren und ausführen
3.4 Kommentare erleichtern das Verständnis des Codes
3.5 Übungsaufgabe: Das erste Programm erweitern
4 Variablen
4.1 Die Verwendung von Variablen in der Informatik
4.2 Variablentypen: wichtig für das Programmieren in C#
4.3 Variablen in C# verwenden
4.4 Berechnungen mit arithmetischen Operatoren durchführen
4.5 Eingaben des Anwenders in einer Variablen aufnehmen
4.6 Übungsaufgabe: Programme mit Variablen erstellen
5 Datenstrukturen in C#
5.1 Arrays für eine feste Anzahl an Werten
5.2 Mehrdimensionale Arrays
5.3 Listen für eine variable Anzahl an Werten
5.4 Listen für identische Datentypen
5.5 Listen für unterschiedliche Datentypen
5.6 Übungsaufgabe: mit Datenstrukturen arbeiten
6 If-Abfragen: mehrere Alternativen in das Programm einfügen
6.1 Der Aufbau der if-Abfrage
6.2 Vergleichsoperatoren
6.3 Logische Operatoren
6.4 Weitere Optionen zur if- Abfrage hinzufügen
6.5 Übungsaufgabe: Programme mit Verzweigungen erstellen
7 Schleifen: Befehle automatisch wiederholen lassen
7.1 Den Ablauf mit einer while-Schleife steuern
7.2 Do-while-Schleife: die fußgesteuerte Alternative
7.3 Die for-Schleife für eine feste Anzahl an Wiederholungen
7.4 Foreach-Schleifen für Arrays und andere Datenstrukturen
7.5 Übungsaufgabe: eigene Schleifen erstellen
8 Grundzüge der objektorientierten Programmierung in C#
8.1 Was bedeutet objektorientierte Programmierung?
8.2 Die Klasse: grundlegende Struktur für objektorientierte Programme
8.3 Ein Objekt als Instanz einer Klasse erzeugen
8.4 Übungsaufgabe: objektorientierte Programme schreiben
9 Methoden in C# verwenden
9.1 Welche Vorteile bieten Methoden?
9.2 Der Aufbau einer Methode in C#
9.3 Methoden mit Übergabewerten
9.4 Methoden mit Rückgabewerten
9.5 Funktionen und Methoden: Worin bestehen die Unterschiede?
9.6 Methoden wie klassische Funktionen verwenden
9.7 Übungsaufgabe: Methoden im Programm verwenden
10 Weiterführende Prinzipien der objektorientierten Programmierung
10.1 Konstruktoren für die Instanziierung der Objekte verwenden
10.2 Daten kapseln: besserer Schutz für die Attribute der Objekte
10.3 Vererbung: Klassen von anderen Klassen ableiten
10.4 Klassen in Module auslagern
10.5 Übungsaufgabe: fortgeschrittene objektorientierte Programme
11 Vorgefertigte Funktionen im Programm verwenden
11.1 Eine Übersicht über die verschiedenen Möglichkeiten
11.2 Eine vorgefertigte Funktion im Programm verwenden
11.3 Übungsaufgaben: passende Funktionen für das Programm suchen
12 Fehler im Programm beseitigen
12.1 Syntax-, Laufzeit- und Semantikfehler: Worin bestehen die Unterschiede?
12.2 Syntaxfehler beheben
12.3 Ausnahmen für Laufzeitfehler erstellen
12.4 Semantikfehler durch das Debugging finden
13 Daten dauerhaft abspeichern
13.1 Verschiedene Möglichkeiten für die Datenspeicherung
13.2 Was ist eine Datenbank?
13.3 Verschiedene Organisationsformen für Datenbanken
13.4 Ein passendes Datenbankmanagementsystem für C#-Programme
13.5 SQL-Befehle: wichtig für die Arbeit mit Datenbanken
13.6 Eine Datenbank erzeugen
13.7 Tabellen, Spalten und Felder erstellen
13.8 Werte aus der Tabelle auslesen und verändern
13.9 Eine Verbindung zwischen dem Programm und der Datenbank herstellen
13.10 SQL-Befehle im Programm verwenden
13.11 #0220;bungsaufgabe: Daten in Datenbanken speichern
14 GUI: moderne Programme mit einzelnen Fenstern erstellen
14.1 Verschiedene Techniken für die Erstellung von User Interfaces
14.2 Das erste Fenster mit WPF erstellen
14.3 Buttons im Fenster verwenden
14.4 Ein neues Fenster öffnen
14.5 Inhalte in einem Fenster dynamisch anzeigen lassen
14.6 Übungsaufgabe: ein kleines Quiz erstellen
15 Anwendungsbeispiel: ein kleines Spiel programmieren
15.1 Das Hauptfenster gestalten
15.2 Das Spiel beginnen
15.3 Das Spielfeld aktualisieren
15.4 Einen Zug durchführen
15.5 Den Spielstand speichern und laden
15.6 Überblick: Alle Klassen und Dateien des Spiels
16 Ausblick: die Programmierkenntnisse weiter ausbauen

Citation preview

C# Programmieren für Einsteiger Michael Bonacina.

2. Auflage: Februar 2019 © dieser Ausgabe 2019 by BMU Media GmbH ISBN 978-3-96645-001-0

Herausgegeben durch: BMU Media GmbH Hornissenweg 4 84034 Landshut

C# Programmieren für Einsteiger

Inhaltsverzeichnis 1 Einleitung 1.1 C#: Eine Programmiersprache mit vielfältigen Anwendu ngsmöglichkeiten 1.2 Die Entwicklungsgeschichte von C# 1.3 C# und .NET Framework 1.4 Vom Code zum fertigen Programm: die Kompilierung

2 Visual Studio: die passende IDE für die Entwicklung mit C# 2.1 Visual Studio installieren 2.2 Ein neues Projekt mit Visual Studio erstellen

3 Das erste Programm in C# 3.1 Eine Ausgabe mit C# erzeugen 3.2 So ist ein C#-Programm aufgebaut 3.3 Den Programmcode kompilieren und ausführen 3.4 Kommentare erleichtern das Verständnis des Codes 3.5 Übungsaufgabe: Das erste Programm erweitern

4 Variablen

4.1 Die Verwendung von Variablen in der Informatik 4.2 Variablentypen: wichtig für das Programmieren in C# 4.3 Variablen in C# verwenden 4.4 Berechnungen mit arithmetischen Operatoren durchführen 4.5 Eingaben des Anwenders in einer Variablen aufnehmen 4.6 Übungsaufgabe: Programme mit Variablen erstellen

5 Datenstrukturen in C# 5.1 Arrays für eine feste Anzahl an Werten 5.2 Mehrdimensionale Arrays 5.3 Listen für eine variable Anzahl an Werten 5.4 Listen für identische Datentypen 5.5 Listen für unterschiedliche Datentypen 5.6 Übungsaufgabe: mit Datenstrukturen arbeiten

6 If-Abfragen: mehrere Alternativen in das Programm einfügen 6.1 Der Aufbau der if-Abfrage 6.2 Vergleichsoperatoren 6.3 Logische Operatoren 6.4 Weitere Optionen zur if- Abfrage hinzufügen 6.5 Übungsaufgabe: Programme mit Verzweigungen erstellen

7 Schleifen: Befehle automatisch wiederholen lassen 7.1 Den Ablauf mit einer while-Schleife steuern 7.2 Do-while-Schleife: die fußgesteuerte Alternative 7.3 Die for-Schleife für eine feste Anzahl an Wiederholungen

7.4 Foreach-Schleifen für Arrays und andere Datenstrukturen 7.5 Übungsaufgabe: eigene Schleifen erstellen

8 Grundzüge der objektorientierten Programmierung in C# 8.1 Was bedeutet objektorientierte Programmierung? 8.2 Die Klasse: grundlegende Struktur für objektorientierte Programme 8.3 Ein Objekt als Instanz einer Klasse erzeugen 8.4 Übungsaufgabe: objektorientierte Programme schreiben

9 Methoden in C# verwenden 9.1 Welche Vorteile bieten Methoden? 9.2 Der Aufbau einer Methode in C# 9.3 Methoden mit Übergabewerten 9.4 Methoden mit Rückgabewerten 9.5 Funktionen und Methoden: Worin bestehen die Unterschiede? 9.6 Methoden wie klassische Funktionen verwenden 9.7 Übungsaufgabe: Methoden im Programm verwenden

10 Weiterführende Prinzipien der objektorientierten Programmierung 10.1 Konstruktoren für die Instanziierung der Objekte verwenden 10.2 Daten kapseln: besserer Schutz für die Attribute der Objekte 10.3 Vererbung: Klassen von anderen Klassen ableiten 10.4 Klassen in Module auslagern 10.5 Übungsaufgabe: fortgeschrittene objektorientierte Programme

11 Vorgefertigte Funktionen im Programm verwenden

11.1 Eine Übersicht über die verschiedenen Möglichkeiten 11.2 Eine vorgefertigte Funktion im Programm verwenden 11.3 Übungsaufgaben: passende Funktionen für das Programm suchen

12 Fehler im Programm beseitigen 12.1 Syntax-, Laufzeit- und Semantikfehler: Worin bestehen die Unterschiede? 12.2 Syntaxfehler beheben 12.3 Ausnahmen für Laufzeitfehler erstellen 12.4 Semantikfehler durch das Debugging finden

13 Daten dauerhaft abspeichern 13.1 Verschiedene Möglichkeiten für die Datenspeicherung 13.2 Was ist eine Datenbank? 13.3 Verschiedene Organisationsformen für Datenbanken 13.4 Ein passendes Datenbankmanagementsystem für C#-Programme 13.5 SQL-Befehle: wichtig für die Arbeit mit Datenbanken 13.6 Eine Datenbank erzeugen 13.7 Tabellen, Spalten und Felder erstellen 13.8 Werte aus der Tabelle auslesen und verändern 13.9 Eine Verbindung zwischen dem Programm und der Datenbank herstellen 13.10 SQL-Befehle im Programm verwenden 13.11 #0220;bungsaufgabe: Daten in Datenbanken speichern

14 GUI: moderne Programme mit einzelnen Fenstern erstellen

14.1 Verschiedene Techniken für die Erstellung von User Interfaces 14.2 Das erste Fenster mit WPF erstellen 14.3 Buttons im Fenster verwenden 14.4 Ein neues Fenster öffnen 14.5 Inhalte in einem Fenster dynamisch anzeigen lassen 14.6 Übungsaufgabe: ein kleines Quiz erstellen

15 Anwendungsbeispiel: ein kleines Spiel programmieren 15.1 Das Hauptfenster gestalten 15.2 Das Spiel beginnen 15.3 Das Spielfeld aktualisieren 15.4 Einen Zug durchführen 15.5 Den Spielstand speichern und laden 15.6 Überblick: Alle Klassen und Dateien des Spiels

16 Ausblick: die Programmierkenntnisse weiter ausbauen

Alle Programmcodes aus diesem Buch sind als PDF zum Download verfügbar. Dadurch müssen Sie sie nicht abtippen: https://bmu-verlag.de/books/cs-programmieren/

Außerdem erhalten Sie die eBook Ausgabe zum Buch im PDF Format kostenlos auf unserer Website:

https://bmu-verlag.de/books/cs-programmieren/ Downloadcode: siehe Kapitel 16

Kapitel 1

Einleitung Eine Programmiersprache zu erlernen, mag eine große Herausforderung darstellen. Wenn man sich jedoch darauf einlässt, dann stellt man in der Regel fest, dass die ersten Schritte nicht allzu schwer sind. Wer sich dieser Aufgabe stellt, profitiert von enormen Vorteilen. Programmierkenntnisse sind beispielsweise bei der Suche nach einer Arbeitsstelle sehr hilfreich. Die Digitalisierung schreitet stetig voran und immer mehr Arbeitgeber benötigen Fachkräfte, die in der Lage dazu sind, Computerprogramme zu erstellen. Doch selbst Arbeitnehmer, die nicht direkt als Programmierer tätig sind, profitieren stark von diesen Kenntnissen. Wer gut programmieren kann, versteht die Prozesse und Abläufe der Digitalisierung deutlich besser und kann dadurch besser zum Wachstum des Unternehmens beitragen. Die Mühe, die es mit sich bringt, eine Programmiersprache zu erlernen, macht sich daher durch eine deutliche Verbesserung der Karrierechancen schnell bezahlt. Um das Programmieren zu erlernen, ist es zunächst notwendig, eine Programmiersprache auszuwählen. Dafür gibt es viele verschiedene Möglichkeiten. Dieses Buch befasst sich mit der Programmiersprache C# (was als C Sharp ausgesprochen wird). Diese stellt eine ausgezeichnete Wahl dar, um das Programmieren von Grund auf zu erlernen. Die folgenden Abschnitte stellen vor, was C# auszeichnet und welche Unterschiede zu anderen Programmiersprachen bestehen.

1.1

C#: Eine Programmiersprache mit vielfältigen Anwendu ngsmöglichkeiten

Einer der großen Vorteile von C# besteht darin, dass sich diese Programmiersprache für sehr viele verschiedene Anwendungen eignet. Hierbei handelt es sich um eine General Purpose Language – auf Deutsch um

eine Allzweck- oder eine Mehrzweck Programmiersprache. Das bedeutet, dass sich damit ganz unterschiedliche Probleme lösen lassen – von Anwenderprogrammen und Web-Applikationen bis hin zur Hardwareprogrammierung. Darüber hinaus ist es möglich, mit C# Programme für verschiedene Plattformen zu gestalten. Da diese Programmiersprache von Microsoft entwickelt wurde, kommt sie zwar vorwiegend in einer Windows-Umgebung zum Einsatz. Mittlerweile bestehen jedoch auch zahlreiche Möglichkeiten, um mit C# Programme für Computer zu schreiben, die die Betriebssysteme macOS oder Linux verwenden. Selbst für mobile Endgeräte, die mit den Betriebssystemen Android oder iOS arbeiten, lassen sich mit C# Programme gestalten. Auch dieser Aspekt trägt dazu bei, dass C# sich universell einsetzen lässt. Schließlich unterstützt C# viele verschiedene Programmierparadigmen. Es ist damit möglich, sowohl imperative als auch deklarative Programme zu erstellen. C# bietet eine volle Unterstützung für die objektorientierte Programmierung und lässt auch eine funktionale Programmierung zu. Anfänger werden sicherlich nicht wissen, was hinter all diesen Ausdrücken steckt. Das ist im Moment auch noch nicht von Bedeutung. Wichtig ist es lediglich, zu wissen, dass es sich bei C# um eine Multiparadigmensprache handelt. Das erlaubt es dem Programmierer später, sich auf eine bestimmte Programmiertechnik zu spezialisieren oder das verwendete Paradigma individuell an die Aufgaben anzupassen. Zusammenfassend lässt sich sagen, dass sich C# beinahe für jede Aufgabe im Bereich der Programmierung eignet. Das ist für den Anfänger sehr vorteilhaft. Auf diese Weise kann er zunächst die grundlegenden Programmiertechniken erlernen. Später ist es möglich, sich auf jeden beliebigen Bereich zu spezialisieren, ohne die Programmiersprache zu wechseln.

1.2

Die Entwicklungsgeschichte von C#

Die Entwicklung von C# hat ihren Ursprung in den letzten Jahren des vergangenen Jahrhunderts. Die Sprache steht in engem Zusammenhang mit der Entwicklung des .NET-Frameworks. Dabei handelt es sich um eine Plattform, die unter anderem aus einer Laufzeitumgebung für die Ausführung von Anwenderprogrammen besteht. Darüber hinaus sind viele weitere Bestandteile enthalten, die es erlauben, Programme für diese Umgebung zu entwickeln. Microsoft verwendeten zuvor andere Techniken für diese Aufgaben. Diese waren jedoch bereits in die Jahre gekommen und entsprachen nicht mehr dem Stand der Technik. Daher entschloss sich der Softwarekonzern aus den USA dazu, ein modernes System zu entwerfen. Das führte dazu, dass er mit der Entwicklung des .NET-Frameworks begann. Dabei kam es zu einem weiteren Problem. Microsoft verwendete bis zu diesem Zeitpunkt vorwiegend die Programmiersprache Java für die Entwicklung von Anwendungsprogrammen. Dieses System stammte jedoch ursprünglich vom Unternehmen Sun Microsystems. Microsoft adaptierte diese Programmiersprache und erweiterte sie anhand der eigenen Bedürfnisse. Damit waren die Entwickler bei Sun jedoch nicht einverstanden und strebten daher ein Gerichtsverfahren an. Das führte dazu, dass sich Microsoft dazu entschloss, für das .NET-Framework eine neue Programmiersprache zu entwickeln. Die Arbeit an diesem Projekt begann im Januar 1999 unter Leitung des bekannten Informatikers Anders Hejlsberg. Es erhielt zunächst den Namen Cool – als Abkürzung für C-like Object Oriented Language. Daran wird bereits deutlich, an welchen Grundsätzen sich C# orientierte. Zum einen sollte eine Programmiersprache entstehen, die auf der Syntax von C basiert. C war zu diesem Zeitpunkt noch eine der am häufigsten verwendeten Programmiersprachen. Darüber hinaus sollte die neue Sprache objektorientiert sein. Dabei handelt es sich um eines der wichtigsten Konzepte der modernen Informatik. Die Grundlagen der objektorientierten Programmierung werden auch später in diesem Buch noch behandelt. Auf diese Weise entstand eine neue Programmiersprache, deren Aufbau vielen Programmierern der damaligen Zeit aufgrund der Ähnlichkeit zu C bereits

bekannt vorkam. Dennoch setzte sie alle Anforderungen an eine moderne Sprache um. Die Vorstellung der Programmiersprache fand 2001 statt. Microsoft verabschiedete sich jedoch kurz vor der Präsentation von der Bezeichnung Cool, da bereits andere Unternehmen diese Markenbezeichnung nutzten. Daher wählte es die Bezeichnung C#. Das Rautensymbol leitet sich vom Kreuzzeichen aus der Notenschrift ab. Dieses steht für die Erhöhung um einen Halbton. Das soll symbolisieren, dass es sich bei C# um eine geringfügige Weiterentwicklung von C handelt. Die erste Version wies jedoch sehr starke Ähnlichkeiten zur Programmiersprache Java auf. Doch auch Einflüsse anderer Sprachen waren bemerkbar – beispielsweise von C++, Haskell oder Delphi (das ebenfalls von Anders Hejlsberg entwickelt wurde). Die starke Ähnlichkeit zu Java wurde erst 2005 mit der Vorstellung von C# 2.0 aufgehoben.

1.3

C# und .NET Framework

Wie bereits aus dem vorherigen Abschnitt hervorgeht, besteht ein enger Zusammenhang zwischen C# und dem .NET Framework. Daher ist es sinnvoll, kurz vorzustellen, was das .NET Framework überhaupt ist und welcher Art die Verbindung zur Programmiersprache C# ist. Das .NET Framework entstand zu Beginn des neuen Jahrtausends. Die erste Version erschien 2002. Dabei handelt es sich um ein Framework, das es ermöglicht, Anwenderprogramme zu entwickeln und auszuführen. Da der Softwarekonzern Microsoft für dessen Entwicklung verantwortlich war, liegt es auf der Hand, dass diese Software für die Verwendung unter dem Betriebssystem Windows vorgesehen ist. Das .NET Framework besteht zum einen aus einer Laufzeitumgebung. Dabei handelt es sich um ein Programm, das die Ausführung eines Anwenderprogramms ermöglicht. Um ein Programm auf einem Computer auszuführen, ist es notwendig, die einzelnen Kommandos, die in Textform vorliegen, in die Maschinensprache zu übersetzen. Diese Übersetzung wird als Kompilierung bezeichnet. Bei der Ausführung eines Programms in C#

handelt es sich jedoch um einen zweistufigen Prozess. Zunächst kommt es zur Übersetzung in eine Zwischensprache. Diese weist zwar bereits große Ähnlichkeiten zur Maschinensprache auf, doch ist sie noch unabhängig von der Architektur des Rechners und vom verwendeten Betriebssystem. Erst bei der Ausführung wird diese Zwischensprache in die eigentliche Maschinensprache übersetzt. Diese Aufgabe übernimmt die Laufzeitumgebung. Darüber hinaus enthält das .NET Framework Programmierschnittstellen, Klassenbibliotheken und anderen Werkzeugen, die das Programmieren einfacher gestalten. Außerdem ist eine Entwicklungsumgebung im .NET Framework inbegriffen. Dabei handelt es sich um ein Programm, das alle notwendigen Werkzeuge zum Programmieren bereitstellt. Es besteht aus einer Oberfläche, in die der Programmierer seinen Code direkt einfügen kann. Des Weiteren sind jedoch noch viele weitere Werkzeuge enthalten – beispielsweise um Fehler im Programmcode zu beseitigen oder um fertige Codebausteine anhand einer grafischen Benutzeroberfläche einzufügen. Der Name dieser Entwicklungsumgebung lautet Visual Studio. Das .NET Framework ist ausschließlich für das Betriebssystem Windows erhältlich. Da dieses für die Entwicklung und die Ausführung von C#Programmen ursprünglich notwendig war, kam diese Programmiersprache zu Beginn fast ausschließlich für die Programmierung unter Windows zum Einsatz. Mittlerweile gibt es jedoch auch Alternativen für andere Betriebssysteme. Daher ist es inzwischen möglich, mit C# Programme für Linux, macOS und für weitere Plattformen zu erstellen.

1.4

Vom Code Kompilierung

zum

fertigen

Programm:

die

Bereits im vorherigen Abschnitt wurde kurz angesprochen, dass es für die Ausführung eines Programms notwendig ist, dieses in die Maschinensprache zu übersetzen. Dieser Prozess ist für die Erstellung des Programms von enormer Bedeutung. Daher soll er an dieser Stelle etwas ausführlicher vorgestellt werden.

Wenn ein Computer ein Programm ausführt, sendet er ein Kommando aus einzelnen Bits an den Prozessor. Jeder dieser Befehle hat eine bestimmte Ausgabe des Prozessors zur Folge. Sie werden als Maschinensprache bezeichnet. Ein ausführbares Programm besteht aus einer festen Abfolge dieser Befehle in Maschinensprache. Wenn man jedoch eine gewöhnliche Programmiersprache betrachtet, ist diese ganz anders aufgebaut. Sie besteht aus Zahlen und aus bestimmten Schlüsselbegriffen. Bevor es möglich ist, das Programm auszuführen, ist es notwendig, es in die Maschinensprache zu übersetzen. Dafür gibt es grundsätzlich zwei Alternativen. Zum einen ist es möglich, diese Übersetzung ein einziges Mal vorzunehmen und auf diese Weise ein ausführbares Programm zu erzeugen. Dieser Vorgang wird als Kompilierung bezeichnet. Eine andere Vorgehensweise besteht darin, die Übersetzung jedes Mal aufs Neue vorzunehmen. Diese Methode wird als Interpretierung bezeichnet. Dabei entsteht kein ausführbares Programm. Der Code lässt sich nur mithilfe eines speziellen Übersetzungsprogramms – der als Interpreter bezeichnet wird – ausführen. Beide Möglichkeiten bieten einige Vor- und Nachteile. Kompilierte Programme arbeiten beispielsweise sehr effizient. Wenn der Code bereits in Maschinensprache vorliegt, dann begünstigt das eine schnelle Ausführung. Allerdings lassen sich die Programme nicht auf andere Rechnerarchitekturen oder Betriebssysteme übertragen. Interpretierte Programme arbeiten etwas ineffizienter, da bei jeder Ausführung eine erneute Übersetzung notwendig ist. Allerdings sind sie deutlich unabhängiger. Sie lassen sich auf jedem Computer ausführen, der über einen entsprechenden Interpreter verfügt. C# verwendet hierbei eine Zwischenlösung. Zunächst ist es notwendig, das Programm zu kompilieren. Dabei entsteht jedoch noch keine Maschinensprache, sondern eine Zwischensprache. Für die Ausführung ist dann die .NET Laufzeitumgebung notwendig. Dabei handelt es sich um einen Interpreter, der das Programm während der Laufzeit in die Maschinensprache überträgt. Da bei der Erstellung der Zwischensprache jedoch bereits zahlreiche Arbeitsschritte abgeschlossen wurden, verläuft dieser Prozess deutlich schneller als bei gewöhnlichen interpretierten Sprachen. Das führt zu

einer effizienten Ausführung und ermöglicht es dennoch, die Programme auf unterschiedlichen Architekturen auszuführen – vorausgesetzt sie verfügen über die .NET Laufzeitumgebung. Auf diese Weise verbindet C# die Vorteile beider Methoden.

Kapitel 2

Visual Studio: die passende IDE für die Entwicklung mit C# Um ein Computerprogramm zu erzeugen und auszuführen, sind drei Schritte notwendig: 1.

das Programm schreiben

2. das Programm kompilieren (in die C#-Zwischensprache vorübersetzen) 3. das Programm ausführen Für jeden dieser Schritte sind passende Hilfsmittel erforderlich. Für die erste Aufgabe kommt ein Texteditor zum Einsatz. Dabei handelt es sich um ein Programm, das die Eingabe von Text ermöglicht. Im Gegensatz zu gewöhnlichen Textverarbeitungsprogrammen wie Word speichern Texteditoren die Inhalte jedoch als reinen Text ab – ohne weitere Formatierungen. Das ist erforderlich, damit der Compiler die Inhalte später versteht. Darüber hinaus ermöglicht es der Texteditor, ein passendes Dateiformat für C# zu wählen. Wenn man den Code mit einem gewöhnlichen Textverarbeitungsprogramm erstellt, ist es später nicht möglich, das Programm auszuführen. Daher ist es notwendig, über einen geeigneten Texteditor zu verfügen. Die meisten Betriebssysteme enthalten bereits eine entsprechende Software. Unter Windows steht beispielsweise der Microsoft Editor – auch als Notepad bekannt – zur Verfügung. Mit diesem ist das Programmieren zwar grundsätzlich möglich, doch bietet er nur einen minimalen Funktionsumfang. Daher ist es ratsam, einen etwas leistungsfähigeren Texteditor zu verwenden.

Der zweite Schritt besteht in der Kompilierung. Diese ist erforderlich, um aus dem Quellcode ein lauffähiges Programm zu erzeugen. Auch hierfür ist eine passende Software notwendig. Diese wird als Compiler bezeichnet. Sie übersetzt den Programmcode in die C#- Zwischensprache. Daher ist es notwendig, einen Compiler zu installieren, bevor man mit dem Programmieren beginnen kann. Für die Ausführung des Programms ist schließlich die .NETLaufzeitumgebung erforderlich. Dieser Punkt spielt jedoch für die meisten Leser keine große Rolle: Die .NETLaufzeitumgebung ist bereits standardmäßig auf allen neueren Windows-Rechnern installiert. Lediglich Anwender, die ein anderes Betriebssystem verwenden, sollten überprüfen, ob eine entsprechende Software vorhanden ist. Es ist möglich, den C#-Compiler und den Texteditor einzeln zu installieren. Allerdings gibt es auch eine praktische Möglichkeit, die bereits beide Bestandteile enthält: Visual Studio von Microsoft. Hierbei handelt es sich um eine integrierte Entwicklungsumgebung (Integrated Development Environment – IDE). Das bietet nicht nur den Vorteil, dass man dabei nur ein einziges Programm installieren muss. Darüber hinaus enthält die IDE noch viele weitere nützliche Funktionen für die Programmierung. Visual Studio und C# stammen beide von Microsoft und sind daher perfekt aufeinander abgestimmt. Daher eignet sich die Software hervorragend für die Arbeit mit dieser Programmiersprache. Ein weiterer Vorteil besteht darin, dass sie in der Community-Edition kostenlos zur Verfügung steht. Die folgenden Absätze stellen einige nützliche Funktionen von Visual Studio vor. Die IDE erzeugt beim Eingeben des Programmcodes eine automatische Syntaxhervorhebung. Das bedeutet, dass bestimmte Befehle farblich im Quellcode gekennzeichnet werden. Das sorgt für eine deutlich übersichtlichere Gestaltungsweise und macht es einfacher, den erzeugten Code zu verstehen und darin nach Fehlern zu suchen. Außerdem ist es möglich, einzelne Programmteile, die einen in sich geschlossenen Block darstellen, einzuklappen. Das ist insbesondere bei längeren Programmen sinnvoll, um die Übersichtlichkeit zu verbessern. Bei Bedarf ist es jedoch jederzeit möglich, die entsprechenden Stellen wieder auszuklappen, um die Details zu betrachten. Die Software erzeugt außerdem automatische

Einrückungen, um zusammengehörige Programmteile zu kennzeichnen. Auch das trägt zu einer übersichtlichen Gestaltungsweise bei. Schließlich bietet die IDE die Möglichkeit zur Autovervollständigung der Befehle. Wenn man die ersten Buchstaben eines Kommandos eingibt, präsentiert die Software mehrere passende Möglichkeiten. Diese kann man dann mit der Maus oder mit den Pfeiltasten auswählen und in das Programm einfügen. Das ermöglicht eine sehr effiziente Arbeitsweise.

Screenshot 1 Der Programmcode mit Syntaxhervorhebung Die bisher beschriebenen Vorteile beziehen sich nicht ausschließlich auf integrierte Entwicklungsumgebungen wie Visual Studio. Auch die meisten Texteditoren bieten die entsprechenden Möglichkeiten an. Allerdings gibt es dabei auch Ausnahmen wie den Microsoft Editor, der diese Funktionen nicht enthält. Eine IDE wie Visual Studio bietet jedoch noch einige weitere Vorteile. Dazu zählt, dass diese Software die Funktionen eines Texteditors und des Compilers miteinander vereint. Wenn man diese Programme einzeln installiert, ist es für jeden Kompilierungsprozess notwendig, das Fenster zu wechseln. Da es während der Testphase notwendig ist, das Programm sehr oft zu kompilieren, um zu überprüfen, ob es alle Anforderungen erfüllt, geht dabei viel Zeit verloren. Visual Studio präsentiert jedoch beide Funktionen im gleichen Fenster. Obwohl die Zeitersparnis bei jeder einzelnen Kompilierung nur wenige Sekunden beträgt, erhöht sich in der Summe die Effizienz beim Programmieren dadurch erheblich. Darüber hinaus ist es bei einem herkömmlichen Compiler notwendig, den Befehl für die Kompilierung von Hand einzutippen. Auch das nimmt einige zusätzliche Sekunden in

Anspruch. Bei Visual Studio reicht hierfür hingegen ein einziger Mausklick aus. Visual Studio bietet außerdem noch viele weitere Zusatzfunktionen. Diese sind zwar für Anfänger meistens von geringer Bedeutung. Wenn man jedoch fortgeschrittenere Programme erstellt, können sie sehr hilfreich sein. Ein Beispiel hierfür ist die Debugging-Funktion. Diese ermöglicht es, die Ausführung des Programms in einzelne Abschnitte zu zerlegen und dabei die Werte aller Variablen zu betrachten. Das ist sehr hilfreich, wenn man auf der Suche nach einem Fehler im Programm ist. Darüber hinaus ermöglicht es die IDE, vorgefertigte Programmbausteine in den Code einzufügen oder diesen anhand einer grafischen Benutzeroberfläche zu erstellen. Das sorgt bei fortgeschrittenen Programmen für eine einfache und effiziente Gestaltungsweise. Aufgrund dieser vielfältigen Vorteile ist die Verwendung von Visual Studio für das Programmieren mit C# sehr zu empfehlen.

2.1

Visual Studio installieren

Bevor man damit beginnt, in C# zu programmieren, ist es daher notwendig, Visual Studio von Microsoft auf dem eigenen Rechner zu installieren. Am sinnvollsten ist es, die Software direkt auf der Homepage des Herstellers herunterzuladen: https://visualstudio.microsoft.com/de/vs/whatsnew/ Diese Seite bietet einen Überblick über die Funktionen des Programms und einen Link zum Download der aktuellen Version. Dieses Buch verwendet Visual Studio 2019. Diese ist am 2. April 2019 erschienen. Dabei handelt es sich zum Zeitpunkt der Erstellung um die aktuelle Version. Wenn es in der Zwischenzeit in diesem Bereich jedoch zu einer Neuerscheinung gekommen sein sollte, stellt das ebenfalls kein Problem dar. In der Regel werden die grundlegenden Funktionen dabei beibehalten. Es kann jedoch vorkommen, dass es hinsichtlich der grafischen Darstellung einige Unterschiede zu den im Buch abgebildeten Screenshots gibt.

Die Version 2019 zeichnet sich durch einige bedeutende Neuerungen gegenüber der Vorgängerversion aus. Unter anderem überarbeitete Microsoft das Debugging – eine Funktion zum Aufspüren von Fehlern im Programm. Diese bietet nun einige praktische neue Möglichkeiten. Auch der Dialog zum Öffnen eines neuen Projekts wurde überarbeitet. Von besonderer Bedeutung ist außerdem der sogenannte Intellicode. Damit bezeichnet Microsoft eine Eingabehilfe, die auf künstlicher Intelligenz beruht. Diese gibt dem Anwender Tipps für das Erstellen des Programms und berücksichtigt dabei Vorschläge der Community. Auch die Möglichkeit für die RemoteZusammenarbeit über das Internet wurden verbessert. Wenn wir die Seite aufrufen und mit der Maus über den Download-Button fahren, klappt sich ein Menü auf, das die drei verschiedenen Editionen von Visual Studio anzeigt: Community, Professional und Enterprise. Für diesen Kurs kommt die Community Edition zum Einsatz. Dabei handelt es sich um das einzige der drei Angebote, das kostenfrei erhältlich ist. Die beiden anderen Versionen können nur gegen Bezahlung einer Lizenz verwendet werden. Doch bietet auch die Gratis-Ausführung alle für dieses Buch erforderliche Funktionen und ist für Anfänger vollkommen ausreichend.

Screenshot 2 Die Downloadseite von Visual Studio Wenn man nach dem Download die Datei anklickt, öffnet sich automatisch der Installations-Assistent. Dieser lädt alle weiteren Dateien herunter und führt den Anwender durch das Setup.

Während der Installation ist es notwendig, vorzugeben, welche Konfiguration gewählt werden soll. Dabei erscheint ein Auswahlfenster mit mehreren Optionen. Für die Bearbeitung der Aufgaben in diesem Buch ist es wichtig, den Bereich .NET-Desktopentwicklung auszuwählen. Alle übrigen Auswahlmöglichkeiten sind für andere Programmiersprachen bestimmt und kommen daher für die Projekte in diesem Buch nicht zum Einsatz. Daher ist es nicht erforderlich, sie zu installieren.

Screenshot 3 Die .NET-Desktopanwendungen für die Installation auswählen Nun muss man nur noch rechts unten auf die Schaltfläche „Installieren“ klicken. Daraufhin beginnt der eigentliche Installationsprozess, der einige Minuten in Anspruch nehmen kann. Sobald dieser beendet ist, ist das Programm jedoch bereits einsatzbereit.

2.2

Ein neues Projekt mit Visual Studio erstellen

Nun ist es bereits möglich, ein neues Projekt mit Visual Studio zu erstellen. Dabei soll zunächst lediglich die Funktionsweise der IDE vorgestellt werden, ohne dabei ein Programm zu erzeugen. Dieser Schritt folgt dann im nächsten Kapitel. Wenn man Visual Studio nach der Installation das erste Mal öffnet, kommt es nochmals zu einer Wartezeit. Dabei wird die IDE auf die Nutzung

vorbereitet. Daraufhin öffnet sich ein Fenster mit mehreren Auswahloptionen. Unten rechts befindet sich die Schaltfläche “Neues Projekt erstellen…”. Diese muss angeklickt werden, um das erste Programm zu gestalten.

Screenshot 4 Das Fenster beim Beginn eines neuen Projekts Daraufhin öffnet sich ein neues Fenster. Hier ist es notwendig, die KonsolenApp auszuwählen.

Screenshot 5 Die Erzeugung einer Konsolen-App Nachdem man auf „Weiter“ geklickt hat, öffnet sich ein neues Fenster. Hier ist es möglich, einen Namen für das neue Projekt anzugeben. In diesem Beispiel soll es Erstes_Projekt heißen. Beim Speicherort ist es sinnvoll, die Standardeinstellungen zu übernehmen. Wenn man nun den Erstellen-Button anklickt, erzeugt Visual Studio die Grundlagen für das erste Programm, das im Rahmen dieses Kurses erstellt werden soll. Daraufhin ruft die Software das eigentliche Hauptfenster auf. Hier erscheint ein Bereich, der bereits einige Codezeilen enthält. Dabei handelt es sich um die grundlegenden Strukturen, die für jedes Programm in C# notwendig sind. Diese haben jedoch keinerlei Funktion. Das Programm lässt sich zwar ausführen, doch passiert dabei zunächst einmal überhaupt nichts. Allerdings sind nun alle Vorbereitungen abgeschlossen, um im nächsten Kapitel mit dem ersten eigenen Programm zu beginnen.

Screenshot 6 Das Fenster für die Bearbeitung des Programmcodes mit den grundlegenden Strukturelementen.

Kapitel 3

Das erste Programm in C# Nachdem alle Vorbereitungen abgeschlossen sind, ist es an der Zeit, das erste eigene Programm zu erstellen. Dabei handelt es sich um eine sogenannte Konsolenanwendung. Das bedeutet, dass die Ausführung auf der Programmkonsole beruht. Dabei handelt es sich um eine Funktion, die in jedes Betriebssystem bereits integriert ist. Sie ermöglicht es, schriftliche Kommandos einzugeben. Unter Windows trägt das entsprechende Programm den Namen Eingabeaufforderung. Unter Linux ist es unter der Bezeichnung Terminal verfügbar. Konsolen-Anwendungen sind nur in Verbindung mit einem derartigen Programm ausführbar. Die Konsole kann nur Schrift ausgeben und schriftliche Eingaben entgegennehmen. Eine Konsolenanwendung entspricht daher nicht dem Bild eines modernen Computerprogramms, das über Fenster verfügt und mit der Maus gesteuert wird. Dennoch soll mit dieser Art von Programmen begonnen werden. Der Grund dafür liegt darin, dass sie deutlich einfacher aufgebaut sind. Daher eignen sie sich gut für Anfänger. Erst im weiteren Verlauf dieses Buchs werden dann Programme vorgestellt, die auf Fenstern basieren.

3.1

Eine Ausgabe mit C# erzeugen

Das erste Programm soll eine ganz einfache Aufgabe erfüllen: Es soll einen Text in der Konsole ausgeben. Diese Art von Programm wird auch als HalloWelt-Programm bezeichnet. Der Grund dafür liegt darin, dass der erste Schritt beim Erlernen einer Programmiersprache fast immer darin besteht, eine einfache Textausgabe zu erzeugen. In vielen Lehrbüchern ist es üblich, hierfür den Text “Hallo Welt!” beziehungsweise auf Englisch “Hello World!”

auszugeben. An dieser Stelle soll das erste Programm jedoch eine Begrüßung zu unserem Kurs erzeugen: “Willkommen zum C#-Kurs!”. Um das Programm zu schreiben, ist es notwendig, Visual Studio zu öffnen und das Projekt auszuwählen, das bereits im vorherigen Kapitel erstellt wurde. Dabei wurde bereits automatisch etwas Code erzeugt. Das ist sehr hilfreich, da auf diese Weise der Einstieg leichter fällt. Allerdings ist es wichtig, genau darauf zu achten, den eigenen Code an der richtigen Stelle einzufügen. Die bereits vorhandenen Befehle stellen lediglich den Rahmen dar und haben keine Funktion. Sie sind aber für die Ausführung des Programms zwingend notwendig. Der Einstieg erfolgt in Zeile 12 – nach der sich öffnenden geschweiften Klammer. Der Inhalt des neuen Programms steht stets innerhalb der geschweiften Klammer, die in der folgenden Zeile geschlossen wird. Wenn man mit der Maus hinter die Klammer in Zeile 12 klickt, ist es sinnvoll, erst einmal die Enter-Taste zu betätigen. So entsteht eine neue Zeile für den Code, den man einfügen will. Dabei kann man bereits eine wichtige Funktion der IDE beobachten: die automatische Einrückung. Der Cursor blinkt nach dieser Aktion noch weiter eingerückt als in der vorherigen Zeile. Der Inhalt der Klammer stellt einen abgeschlossenen Block dar, der eine bestimmte Funktion ausführt. Die IDE macht das deutlich, indem sie den Inhalt automatisch einrückt. An dieser Stelle soll nun der erste Befehl eingefügt werden: Console.WriteLine(“Willkommen zum C#-Kurs!”);

Screenshot 7 Es ist wichtig, den Befehl an der richtigen Stelle einzufügen. Dieser Befehl sorgt dafür, dass das Programm die entsprechende Begrüßung über die Konsole ausgibt. Für den Anfänger wirkt diese Ansammlung einzelner Begriffe jedoch recht kompliziert, sodass diese nun Schritt für Schritt erklärt werden sollen. An erster Stelle steht dabei der Ausdruck Console. Dieser sagt aus, dass sich der folgende Befehl auf die Konsole bezieht – also dass der Text hier ausgegeben wird. Der zweite Teil des Befehls ist der Begriff WriteLine. Dabei handelt es sich um einen Schreib-Befehl, der den entsprechenden Text ausgibt. Darüber hinaus erzeugt er anschließend einen Zeilenumbruch. Alternativ wäre es auch möglich, den einfachen Write- Befehl zu verwenden, der keinen Zeilenumbruch erzeugt. Der Inhalt der Ausgabe muss stets in einer runden Klammer und in Anführungszeichen stehen. Dabei ist es wichtig, zu beachten, dass es sich hierbei nicht um die deutschen Anführungszeichen handelt, sondern um das sogenannte Kodierungszeichen. Wenn man den Code direkt über Visual Studio eingibt, wählt die IDE automatisch das passende Zeichen aus. Wenn man jedoch auf die Idee kommt, den Code zunächst mit einem Textverarbeitungsprogramm zu erstellen und ihn dann in den Texteditor kopiert, kann das zu Problemen führen.

3.2

So ist ein C#-Programm aufgebaut

Im vorherigen Abschnitt wurde nur die Funktionsweise des Schreib-Befehls erklärt, der in den vorgefertigten Programmcode eingefügt wurde. Um die Funktionsweise von C# zu verstehen, ist es jedoch sinnvoll, auch den Code zu betrachten, den Visual Studio automatisch eingefügt hat. Dabei ist es jedoch nicht notwendig, jedes einzelne Detail zu verstehen. Die meisten Befehle werden im weiteren Verlauf des Buchs noch etwas ausführlicher behandelt.

An erster Stelle steht das Kommando using System; Dieses ist erforderlich, um die Befehle, die in der Bibliothek System enthalten sind, im Programm zu verwenden. C# beinhaltet sehr viele Kommandos. Diese sind jedoch nicht direkt verfügbar, sondern in sogenannten Bibliotheken abgespeichert. Wenn man sie verwenden will, dann ist es notwendig, die entsprechende Bibliothek einzubinden. Der WriteLine-Befehl ist beispielsweise in der Bibliothek System enthalten. Daher ist er nur verfügbar, wenn man diese zu Beginn in das Programm einbindet. Danach folgen weitere Befehle für den Import von Bibliotheken. Diese sind für das erste Programm jedoch nicht notwendig, sodass es möglich ist, sie zu löschen, um den Code übersichtlicher zu gestalten. Anschließend steht das Kommando namespace Erstes_Projekt. Mit C# kann man Funktionen und Objekte erzeugen und diesen einen eigenen Namen geben. Dabei ist es möglich, dass es zu Überschneidungen mit vorgefertigten Funktionen kommt. Um dabei eine eindeutige Zuordnung zu gewährleisten, arbeitet C# mit Namensräumen. Innerhalb eines Namensraums darf jede Bezeichnung nur einmal vorkommen. Vor Beginn des Programms ist es notwendig anzugeben, welcher Namensraum verwendet werden soll. Dabei belassen wir es bei der Standardangabe – der Verwendung unseres eigenen Namensraums, der die Bezeichnung Erstes_Projekt trägt. Danach folgt eine geschweifte Klammer, die deutlich macht, dass nun der eigentliche Inhalt des Programms beginnt. In der nächsten Zeile steht der Begriff class Program. Dieser erzeugt eine neue Klasse mit der Bezeichnung Program. Eine Klasse ist das grundlegende Element in der objektorientierten Programmierung. Sie gibt die grundlegenden Strukturen für ein Objekt vor und ermöglicht es, verschiedene Aktionen damit durchzuführen. Die Programmiersprache C# legt viel Wert auf die objektorientierte Programmierung. Das hat zur Folge, dass jedes einzelne Programm die Grundzüge dieses Paradigmas beachten muss. Daher muss jedes Programm als Klasse aufgebaut sein. Deshalb ist es notwendig, es zu Beginn entsprechend zu kennzeichnen und der Klasse einen passenden Namen zu geben. Dieser ist eigentlich frei wählbar. Es ist jedoch sinnvoll, es bei der

Standard-Bezeichnung Program zu belassen. Der Inhalt der Klasse steht wiederum in einer geschweiften Klammer. Eine ausführliche Erklärung zu Klassen und Objekten folgt im Kapitel 8. Danach folgt der Ausdruck static void Main (string[] args). Dieser ist insbesondere für Anfänger schwer zu verstehen. Er ist jedoch von großer Bedeutung, da er den Einstiegspunkt für das Programm darstellt. Wenn man es ausführt, beginnt es stets an dieser Stelle. Dass es sich hierbei um die Hauptfunktion des Programms handelt, wird am Begriff Main deutlich. Davor stehen die Begriffe static und void. Diese legen einige grundlegende Eigenschaften der Hauptfunktion fest. Die genaue Bedeutung zu erklären, ist jedoch nicht möglich, ohne tiefer auf den Aufbau einer Funktion einzugehen. Daher wird die entsprechende Erklärung im Kapitel 8 nachgereicht, das sich mit diesem Thema beschäftigt. Zum Abschluss dieser Codezeile steht eine Klammer mit dem Inhalt string[] args. Es ist möglich, dem Programm bereits bei dessen Aufruf bestimmte Werte zu übergeben, die Einfluss auf den Ablauf haben. Die Angaben in der Klammer sind erforderlich, um diese Werte innerhalb des Programms aufzunehmen. Obwohl bei diesem Programm keine Übergabe von Werten stattfindet, ist es notwendig, diese Angaben einzufügen. An dieser Stelle ist es sicherlich schwierig, die genaue Funktionsweise der genannten Befehle zu verstehen. Das stellt jedoch kein Problem dar. Wichtig ist es lediglich, darauf zu achten, dass jeder einzelne von ihnen für ein C#Programm notwendig ist. Wenn man einmal ein Programm mit einem gewöhnlichen Texteditor erstellt, der diesen Code nicht automatisch einfügt, müssen all diese Kommandos von Hand geschrieben werden.

3.3

Den Programmcode kompilieren und ausführen

Das erste Programm ist zwar bereits fertiggestellt und seine Funktionsweise ist erklärt, allerdings wurde es noch nicht ausgeführt. Daher war es bislang nicht möglich, zu überprüfen, welche Auswirkungen es hat.

Bevor man ein C#-Programm ausführen kann, ist es notwendig, es zu kompilieren. Visual Studio macht diese Aufgabe jedoch ganz einfach, indem die IDE die Kompilierung und die Ausführung des Programms in einer Schaltfläche zusammenfasst. Hierfür ist es lediglich notwendig, in der Menüleiste den Punkt Debuggen auszuwählen und daraufhin “Starten ohne Debugging” auszuwählen.

Screenshot 8 Das Programm kompilieren und ausführen Alternativ dazu ist es möglich, den Shortcut Strg + F5 zu verwenden. Auf diese Weise lässt sich das Programm in Sekundenbruchteilen ausführen. Daraufhin öffnet sich die Konsole. Es erscheint der Text, der über den WriteLine-Befehl eingegeben wurde. Danach wird automatisch die Zeile “Drücken Sie eine beliebige Taste . . . “ eingefügt. Wenn man dieser Aufforderung folgt und eine Taste drückt, schließt sich die Konsole wieder.

Screenshot 9 Die Ausgabe der Begrüßung über die Konsole Eine weitere Möglichkeit besteht darin, den grünen Pfeil in der Werkzeugleiste mit der Aufschrift Starten anzuklicken. Dieser kompiliert das Programm ebenfalls und führt es aus. Allerdings schließt sich die Konsole dabei sofort wieder, sodass es nicht möglich ist, das Ergebnis zu betrachten. Die Ausgabe in der Konsole ist nicht der einzige Effekt, der durch die Kompilierung des Programms zu beobachten ist. Darüber hinaus ist es sinnvoll, sich einmal das Verzeichnis anzuschauen, in dem Visual Studio das Projekt abgespeichert hat. Wenn man sich nun durch die Unterverzeichnisse Erstes_Projekt, bin und Debug klickt, entdeckt man eine neue Datei mit dem Namen Erstes_Projekt.exe. Dabei handelt es sich um eine ausführbare Datei, die durch die Kompilierung entstanden ist. Wenn man diese anklickt, öffnet sich ebenfalls kurz die Konsole und zeigt den entsprechenden Text an. Da sie sich jedoch bereits nach Sekundenbruchteilen wieder schließt, ist das kaum zu erkennen. Dennoch ist es wichtig, zu beachten, dass bei jedem Kompilierungs-Prozess eine ausführbare Datei entsteht.

3.4

Kommentare erleichtern das Verständnis des Codes

Wenn man den Programmcode betrachtet, ist es manchmal schwer, zu verstehen, welche Funktionen dieser ausführt. Das ist bereits nicht ganz

einfach, wenn man ein eigenes Programm nach einiger Zeit nochmals anschaut. Besonders schwierig ist es, wenn man den Code eines anderen Programmierers liest. Es gibt jedoch ein praktisches Hilfsmittel, das das Verständnis erleichtert: Kommentare. Dabei handelt es sich um einfachen Text, der keinerlei Auswirkungen auf den Ablauf des Programms hat. Er dient lediglich dazu, die Funktionsweise zu erläutern und auf diese Weise das Verständnis zu erleichtern. Um deutlich zu machen, dass es sich bei den entsprechenden Textpassagen um Kommentare handelt, die das Programm nicht beeinflussen sollen, ist es notwendig, sie zu kennzeichnen. Für einzeilige Kommentare kommt dafür der doppelte Schrägstrich zum Einsatz (//). Darüber hinaus besteht die Möglichkeit, mehrzeilige Kommentarblöcke einzufügen. Dabei wird der Beginn durch die Symbole /* und das Ende durch die Symbole */ gekennzeichnet. Der folgende Programmcode enthält beide Arten von Kommentaren: using System; namespace Erstes_Projekt { class Program { static void Main(string[] args) { //Dieser Befehl gibt eine Begrüßung aus Console.WriteLine(“Willkommen zum C#-Kurs!”); /* An dieser Stelle ist das Programm bereits beendet. Die Konsole wird daraufhin geschlossen. */ } } }

Bei einem derart einfachen Programm, ist es sicherlich auch ohne Kommentare möglich, die Funktionsweise zu verstehen. Allerdings ist es sinnvoll, sich diese Vorgehensweise von Beginn an anzugewöhnen. So ist sichergestellt, dass man später bei komplizierteren Programmen die Kommentare automatisch einfügt. Kommentare sind auch bei der Erstellung eines Programms sehr hilfreich. Wenn man später beispielsweise eine Funktion verwenden will, ist es üblich, zunächst das Hauptprogramm zu schreiben, das diese aufruft. Solange die Funktion noch nicht erstellt ist, lässt sich das Programm jedoch noch nicht ausführen. Um es dennoch auszuprobieren, ist es sinnvoll, den Aufruf der Funktion als Kommentar zu kennzeichnen. So stört er den Ablauf des Programms nicht. Es ist aber dennoch erkenntlich, an welcher Stelle die Funktion später stehen soll. Diese Praxis wird als Auskommentieren bezeichnet.

3.5

Übungsaufgabe: Das erste Programm erweitern

Am Ende der meisten Kapitel steht eine kleine Übungsaufgabe. Diese hat den Zweck, das Erlernte in die Praxis umzusetzen. Auf diese Weise verstärkt sie den Lerneffekt und sorgt für etwas Praxiserfahrung. Sie bezieht sich dabei in erster Linie auf die Inhalte, die im entsprechenden Kapitel vermittelt wurden. Doch auch die Kenntnisse aus den vorherigen Abschnitten werden dabei als gegeben vorausgesetzt. Sollten einmal neue Befehle für die Bearbeitung notwendig sein, werden diese kurz erläutert. Danach folgt eine Musterlösung für die entsprechenden Aufgaben. Es wird jedoch dringend empfohlen, zunächst selbst zu probieren, ein entsprechendes Programm zu erstellen – selbst wenn das beim ersten Anlauf nicht gelingen sollte. Die Lösung dient in erster Linie zum Abgleich mit den eigenen Ergebnissen. Erst wenn das Programm auch nach mehreren Versuchen seine Funktion nicht erfüllt, ist es sinnvoll, hier nachzuschauen. Beim Erstellen eines Programms gibt es meistens viele verschiedene Lösungswege. Das bedeutet, dass es sich bei der Musterlösung nicht um die einzige Möglichkeit handelt. Wenn das eigene Programm ausführbar ist und

alle Anforderungen erfüllt, dann stellt es ebenfalls eine richtige Lösung dar, auch wenn es von der Musterlösung abweicht. Da in diesem Kapitel nur ein einziger Befehl vorgestellt wurde, ist die erste Übungsaufgabe selbstverständlich sehr einfach. Sie dient in diesem Fall lediglich der Wiederholung und der Vertiefung der erworbenen Kenntnisse. 1. Erstellen Sie ein Programm, das eine weitere Zeile zur Ausgabe hinzufügt, die auf den Inhalt des Kurses eingeht. 2. Fügen Sie auch für diese zweite Zeile einen passenden Kommentar ein.

Lösungen: 1. using System; namespace Erstes_Projekt { class Program { static void Main(string[] args) { //Dieser Befehl gibt eine Begrüßung aus Console.WriteLine(“Willkommen zum C#-Kurs!”); Console.WriteLine(“Hier lernen Sie, Programme mit C# zu erstellen.”); } } }

2. using System; namespace Erstes_Projekt {

class Program { static void Main(string[] args) { //Dieser Befehl gibt eine Begrüßung aus Console.WriteLine(“Willkommen zum C#-Kurs!”); //Diese Ausgabe geht auf die Inhalte ein. Console.WriteLine(“Hier lernen Sie, Programme mit C# zu erstellen.”); } } }

Alle Programmcodes aus diesem Buch sind als PDF zum Download verfügbar. Dadurch müssen Sie sie nicht abtippen: https://bmu-verlag.de/books/cs-programmieren/

Außerdem erhalten Sie die eBook Ausgabe zum Buch im PDF Format kostenlos auf unserer Website:

https://bmu-verlag.de/books/cs-programmieren/ Downloadcode: siehe Kapitel 16

Kapitel 4

Variablen Um einen einfachen Text zu erstellen, ist es sicherlich nicht notwendig, ein eigenes Computerprogramm zu schreiben. Dafür könnte man auch bereits vorhandene Softwareprodukte verwenden. Die Aufgabe eines Computerprogramms besteht vielmehr darin, verschiedene Werte aufzunehmen, zu speichern und Berechnungen damit durchzuführen. Für diese Aufgabe sind Variablen notwendig. Sie stellen einen sehr wichtigen Teil der Programmierung dar und kommen in fast allen Programmen zum Einsatz. Ein Programm ohne Variablen kann lediglich einem starren Ablauf folgen und stets die gleichen Berechnungen durchführen. Die folgenden Abschnitte stellen vor, was Variablen sind, welche Bedeutung sie in der Informatik haben und wie sie in C# zu verwenden sind.

4.1

Die Verwendung von Variablen in der Informatik

Variablen kennen die meisten Leser wahrscheinlich bereits aus dem Mathematikunterricht in der Schule. Dabei ist es jedoch wichtig, zu beachten, dass die Bedeutung dieses Begriffs in der Mathematik und in der Informatik nicht vollkommen identisch ist. In der Mathematik ist die Variable eine Leerstelle. Sie steht als Platzhalter für eine Zahl, die an dieser Stelle eingefügt werden kann. In vielen logischen Ausdrücken kann die Variable nur einen ganz spezifischen Wert annehmen. Wenn man an dieser Stelle eine andere Zahl einfügen würde, wäre der Ausdruck nicht mehr korrekt. In vielen Formeln kann man den Wert der Variablen hingegen frei wählen. Entsprechend der Zahl, die man an dieser Stelle einsetzt, verändert sich das Ergebnis der Formel.

In der Informatik handelt es sich bei einer Variablen hingegen um einen Behälter, der einen Wert aufnehmen kann. Man kann sich die Variable wie ein Fach in einem Regal vorstellen. Darin kann man unterschiedliche Gegenstände aufbewahren. Im Regal kann man beispielsweise Aktenordner, CDs oder Bücher ablegen. Analog dazu kann eine Variable Zahlen, Buchstaben oder ganze Wörter und Sätze speichern. Wenn man einen Gegenstand aus dem Regal holen will, ist es notwendig, zu wissen, wo er sich befindet. Dabei wäre es möglich, in jedem einzelnen Fach nachzuschauen, bis man ihn findet. Einfacher wäre es jedoch, gleich zu Beginn ein Beschriftungssystem einzuführen. Wenn man beispielsweise an jedem einzelnen Fach ein Schildchen mit einem Buchstaben anbringt, ist es ganz einfach, den Inhalt zu finden. Wenn man sich notiert, dass die Bücher im Fach A, die Aktenordner im Fach B und die CDs im Fach C liegen, dann reicht anschließend ein kurzer Blick aus, um den richtigen Inhalt zu finden. Bei Variablen ist diese “Beschriftung” zwingend notwendig. Der Zugriff auf den Inhalt einer Variablen ist nur über deren Namen möglich. Daher muss man ihr zu Beginn stets einen Namen geben. Dafür kann man nicht nur einzelne Buchstaben, sondern auch Wörter und Zahlen verwenden. Dieser Name muss eindeutig sein. Das bedeutet, dass es nicht erlaubt ist, gleiche Bezeichnungen für unterschiedliche Variablen zu verwenden. Wenn man ein Regalsystem verwendet, dann ist es möglich, verschiedene Gegenstände daraus zu entnehmen oder neue Objekte hinzuzufügen. Wenn in einem Regalfach beispielsweise zuvor drei Bücher gelegen haben, ist es möglich, zwei weitere hinzuzufügen – vorausgesetzt der Platz reicht hierfür aus. Außerdem kann man ein Buch daraus entnehmen. Auch bei Variablen ist es möglich, derartige Änderungen vorzunehmen. Wenn analog zum vorherigen Beispiel die Zahl 3 in der Variablen abgespeichert ist, kann man zu diesem Wert die Zahl 2 addieren, sodass der neue Wert 5 beträgt. Allerdings gibt es bei C# genau wie bei einigen anderen Programmiersprachen einen wichtigen Unterschied zu diesem Modell. Während es bei einem Regal möglich wäre, die Bücher zu entnehmen und durch Aktenordner zu ersetzen, ist es bei Variablen in C# nicht möglich, den

grundsätzlichen Typ zu ändern. Das bedeutet, dass eine Variable, die für die Speicherung einer ganzen Zahl verwendet wurde, anschließend nicht für Buchstaben oder Fließkommazahlen zum Einsatz kommen kann. Der Datentyp ist hierbei unveränderlich. Das Beispiel des Regals diente der Veranschaulichung der Funktion der Variablen. Aus technischer Sicht sind die Prozesse bei der Verwendung von Variablen jedoch sehr ähnlich. Anstelle des Regals steht hier der Arbeitsspeicher. Dieser lässt sich analog zu den Regalfächern in viele kleine Abschnitte unterteilen. In diesen Abschnitten kann das Programm dann einen Wert abspeichern. Um später wieder darauf zuzugreifen, muss es jedoch genau wissen, wo sich der entsprechende Wert befindet. Aus diesem Grund sind die einzelnen Speicherplätze des Arbeitsspeichers durchnummeriert. Ein direkter Zugriff über diese Nummer ist in C# jedoch nur eingeschränkt möglich. Außerdem erfordert dies fortgeschrittene Programmierkenntnisse. Anstatt dessen kommt der Variablennamen zum Einsatz. Das Programm hinterlegt, welcher Variablenname mit welchem Speicherort verknüpft ist. Wenn man die Variable später im Programm aufruft, ermittelt dieses zunächst den konkreten Ort und ruft daraufhin den hier hinterlegten Wert ab.

4.2

Variablentypen: wichtig für das Programmieren in C#

Bei Variablen in der Informatik ist es nicht nur notwendig, dass diese über einen eindeutigen Namen verfügen. Darüber hinaus ist es erforderlich, dass sie einen bestimmten Typ haben. Der Variablentyp gibt an, ob es sich bei einem Wert um eine Zahl, um einen Buchstaben oder um einen Wahrheitswert handelt. Diese Angabe ist aus mehreren Gründen sehr wichtig. Zum einen ist sie erforderlich, um den konkreten Speicherort zu bestimmen. Wie im vorherigen Abschnitt erklärt wurde, hinterlegt das Programm den mit dem entsprechenden Variablennamen verbundenen Speicherort. Dabei handelt es sich jedoch nur um den Startpunkt. Es ist nicht angegeben, wie lang der Eintrag ist. Dabei kann es jedoch erhebliche Unterschiede geben. Kleine

Zahlen haben beispielsweise eine Länge von nur einem Byte. Wenn man eine derartige Zahl im Programm abruft, muss das Programm die Informationen auslesen, die im auf den Startpunkt folgenden Byte stehen. Längere Zahlen benötigen hingen zwei, vier oder sogar acht Bytes. Daher ist es notwendig, einen deutlich längeren Speicherbereich auszulesen. Jeder Variablentyp hat eine spezifische Länge. Diese Information ist notwendig, um zusammen mit dem Startpunkt den genauen Speicherort zu definieren. Der Variablentyp ist außerdem für die Auswertung der abgespeicherten Informationen sehr wichtig. Der Arbeitsspeicher kennt nur binäre Informationen – also einzelne Bits, die entweder den Wert 0 oder 1 annehmen können. Wenn man nun einen Wert abspeichert, ist es notwendig, ihn in binäre Informationen umzuwandeln. Die Systeme, die dafür zum Einsatz kommen, unterscheiden sich jedoch – je nachdem, ob es sich um eine ganze Zahl, eine Fließkommazahl oder um einen Buchstaben handelt. Dabei kann es auch zu Überschneidungen kommen. Das bedeutet, dass die gleiche Bitfolge unterschiedliche Werte darstellen kann – je nachdem, um welchen Datentyp es sich dabei handelt. Um den Inhalt zu verarbeiten, muss das Programm daher wissen, wie es die Binärinformationen interpretieren soll. Diese Information ist ebenfalls im Variablentyp enthalten. C# zeichnet sich durch eine strenge Typisierung aus. Bei manchen Programmiersprachen ist es nicht notwendig, einen Variablentyp vorzugeben. Das Programm erledigt das automatisch, wenn man der Variablen einen Wert zuweist. Bei C# ist das jedoch nicht möglich. Hier muss jeder Variablen vor der Verwendung ein fester Typ zugewiesen werden. Dieser ist nachträglich nicht veränderbar. C# kennt eine große Anzahl an verschiedenen Variablentypen. Diese unterscheiden sich zum einen hinsichtlich ihrer grundsätzlichen Art – beispielsweise ob es sich um einen Buchstaben, um eine Ganzzahl, um eine Fließkommazahl oder um einen Wahrheitswert handelt. Darüber hinaus kann sich die Größe dabei unterscheiden. Die folgende Tabelle gibt einen Überblick über die wichtigsten Variablentypen und ihre Länge: Ganze Zahlen mit Vorzeichen:

sbyte:

von -128 bis 127 (1 Byte)

short:

von -32.768 bis 32.767 (2 Bytes)

von -2.147.438.648 bis 2.147.438.647 (4 Bytes)

int:

von -9.223.372.036.854.775.808 bis 9.223.372.036.854.775.807 (8

long:

Bytes) Ganze Zahlen ohne Vorzeichen: 0 bis 255 (1 Byte)

byte:

0 bis 65.535 (2 Byte)

ushort:

0 bis 4.294.967.295 (4 Bytes)

uint:

0 bis 18.446.744.073.709.551.615 (8 Bytes)

ulong:

Fließkommazahlen: von 1,5 x 10-45 bis 3,4 x 1038, 7 Nachkommastellen (4 Bytes)

float: double:

von 5.0 x 10-324 bis 1,7 x 10308, 15 Nachkommastellen (8 Bytes)

Zeichen: char:

Unicode-Zeichen (2 Bytes)

Wahrheitswerte: bool: True

oder False (1 Byte)

Neben diesen einfachen Datentypen gibt es auch zusammengesetzte Strukturen unterschiedlicher Art. Sehr wichtig sind beispielsweise Zeichenketten. Diese bestehen aus einer Aneinanderreihung einzelner Buchstaben oder anderer Symbole. Wenn man Wörter oder längere Texte in einer Variablen abspeichern will, muss man diese daher als Zeichenkette deklarieren. Dafür ist die Bezeichnung string notwendig.

Außerdem gibt es Listen und andere Objekte, die mehrere Werte enthalten. Diese zusammengesetzten Datenstrukturen werden in einem späteren Kapitel detailliert vorgestellt.

4.3

Variablen in C# verwenden

Nachdem nun die Eigenschaften der Variablen in der Theorie vorgestellt wurden, ist es an der Zeit, dieses Wissen in der Praxis anzuwenden. Wenn man in C# eine Variable verwenden will, muss man sie zunächst deklarieren. Das bedeutet, dass man ihren Typ angibt und ihr einen eindeutigen Namen gibt. Dafür ist es zunächst notwendig, in der Tabelle aus dem vorherigen Abschnitt den gewünschten Variablentyp zu wählen und diesen in das Programm zu schreiben. Danach folgt ein Name, der weitestgehend frei gewählt werden kann. Zum Schluss steht ein Semikolon. Wenn man beispielsweise eine Ganzzahl mit einer Länge von 4 Bytes mit dem Namen meineVariable festlegen will, dann ist dafür folgender Befehl notwendig: int meineVariable;

Für die Auswahl des Variablennamens sind einige Regeln zu beachten. Für diesen Bezeichner kommen grundsätzlich Buchstaben, Zahlen und der Unterstrich infrage. Dabei ist es jedoch wichtig, darauf zu achten, dass am Anfang des Variablennamens keine Zahl stehen darf. Der Unterstrich ist an erster Stelle zwar erlaubt, doch ist dies nicht zu empfehlen. Zum einen ist dieser manchmal nur schwer zu erkennen. Zum anderen verwenden einige Programmierer den Unterstrich am Anfang einer Bezeichnung für Kommandos mit einer speziellen Bedeutung. Daher ist es sinnvoll, den Variablennamen stets mit einem Buchstaben zu beginnen. Umlaute und andere spezielle Buchstaben sind zwar erlaubt, doch ist es nicht üblich, diese beim Programmieren zu verwenden. Es ist empfehlenswert, sprechende Namen für die Variablen zu verwenden. Das macht bereits auf den ersten Blick deutlich, wofür sie stehen. Dadurch wird es einfacher, den Programmcode zu verstehen. Eine umstrittene Frage stellt es dabei dar, ob die Bezeichnungen in deutscher oder in englischer Sprache zu verwenden sind. Hierbei gibt es unterschiedliche Auffassungen.

Auf der einen Seite gibt es viele Programmierer, die bei international tätigen Unternehmen angestellt sind. Hier wird in der Regel gefordert, englische Bezeichnungen zu verwenden. Auf der anderen Seite erleichtern deutsche Variablennamen zumindest zu Beginn das Verständnis. Aus diesem Grund verwendet dieses Buch Variablennamen in deutscher Sprache. Darüber hinaus ist es wichtig, dass jede Bezeichnung einmalig ist. Das bedeutet, dass es nicht erlaubt ist, den gleichen Namen für unterschiedliche Variablen zu verwenden. Außerdem gibt es noch weitere Elemente, denen der Programmierer einen Namen geben muss. Beispiele hierfür sind Klassen und Methoden, die im weiteren Verlauf des Buchs vorgestellt werden. Auch hierbei sind keine Überschneidungen bei der Namensgebung erlaubt. Nachdem die Variable deklariert ist, ist es notwendig, ihr einen Wert zuzuweisen. Das geschieht mit dem Zuweisungsoperator. Dieser verwendet als Symbol das Gleichheitszeichen (=). Danach kann man der Variablen jeden beliebigen Wert zuweisen, der ihrem Typ entspricht. Da die oben deklarierte Variable vom Typ int ist, kommen in diesem Beispiel ausschließlich ganze Zahlen infrage. Nach dem Befehl muss wieder ein Semikolon stehen. Um der Variablen meineVariable den Wert 5 zuzuweisen, wäre dementsprechend folgender Befehl notwendig: meineVariable = 5;

Da die Deklarierung und die Initialisierung einer Variablen häufig direkt aufeinanderfolgen, bietet C# auch die Möglichkeit, diese beiden Befehle in einer Zeile zusammenzufassen. Um die Variable zu deklarieren und ihr gleich den gewünschten Wert zuzuweisen, ist folgender Code erforderlich: int meineVariable = 5;

Der Zugriff auf die Variable erfolgt über ihren Namen. Wenn man etwa den Wert der Variablen meineVariable in einem WriteLine-Befehl ausgeben will, ist das mit folgendem Befehl möglich: Console.WriteLine(meineVariable);

Dabei ist es wichtig, darauf zu achten, dass der Variablennamen hierbei nicht in Anführungszeichen stehen darf. Das würde dazu führen, dass das Programm den Namen der Variablen ausgibt und nicht deren Inhalt. Mit diesen Informationen ist es bereits möglich, ein kleines Programm zu schreiben, das eine Variable bestimmt, ihr einen Wert zuweist und diesen dann ausgibt: using System; namespace Variablen { class Program { static void Main(string[] args) { int meineVariable; meineVariable = 5; Console.WriteLine(meineVariable); } } }

4.4

Berechnungen mit arithmetischen Operatoren durchführen

Variablen dienen nicht nur dazu, bestimmte Werte aufzunehmen. Sie haben auch eine wichtige Bedeutung, um Berechnungen innerhalb des Programms durchzuführen. Hierfür sind ebenfalls passende Operatoren notwendig. Die Gruppe, die der Durchführung mathematischer Berechnungen dient, trägt die Bezeichnung arithmetische Operatoren. Häufig verwenden die arithmetischen Operatoren die gleichen Zeichen, die in der Mathematik für die entsprechende Aufgabe zum Einsatz kommen. Für Additionen kommt etwa das Pluszeichen (+) und für Subtraktionen das

Minuszeichen (-) zum Einsatz. Das ist jedoch nicht immer der Fall. Die Multiplikation verwendet das Sternsymbol (*) und die Division den Schrägstrich (/). Hinzu kommt der Modulo-Operator, der dem Prozentzeichen (%) entspricht. Dieser gibt den Rest an, der bei der Division der entsprechenden Zahlen entsteht. Arithmetische Operatoren lassen sich entweder auf Variablen oder auf Zahlen anwenden. Demnach sind alle drei folgenden Ausdrücke erlaubt – vorausgesetzt die Variablen a und b wurden zuvor deklariert und initialisiert: a + b a + 5 3 + 5

Bei diesen Ausdrücken handelt es sich jedoch noch nicht um vollständige Befehle. Deshalb steht hier auch noch kein Semikolon nach dem Kommando. Um sie zu vervollständigen, muss das Programm wissen, was mit dem Ergebnis der Berechnung passieren soll. Häufig wird dieses in einer anderen Variablen gespeichert. Diese nimmt dann automatisch den neuen Wert an. Dafür muss sie bereits deklariert sein. Eine vorherige Initialisierung ist in diesem Fall jedoch nicht zwingend notwendig. Wenn man beispielsweise der Variablen b den Wert aus der Multiplikation der Variablen a und der Zahl 5 zuweisen will, ist dafür folgender Ausdruck notwendig: b = a * 5;

Allerdings gibt es noch eine weitere Möglichkeit. Es ist auch erlaubt, das Ergebnis direkt in einem anderen Befehl zu verwenden. Dann wird es jedoch nicht dauerhaft abgespeichert. Wenn man es lediglich über die Konsole ausgeben will, ist das mit folgendem Kommando möglich: Console.WriteLine(a * 5);

Arithmetische Operatoren erlauben auch rekursive Ausdrücke. Das bedeutet, dass die Variable, in der das Ergebnis gespeichert wird, auch für die Berechnung zum Einsatz kommt. Ein Beispiel für einen derartigen Ausdruck wäre a = a * 3;

Das bedeutet, dass der bisherige Wert von a mit dem Faktor 3 multipliziert wird. Das Ergebnis dieser Berechnung wird dann wieder in der Variablen a gespeichert. Wenn der Wert von class a vor diesem Ausdruck 5 beträgt, wird er durch die Berechnung verdreifacht, sodass er danach bei 15 liegt. In sehr vielen Programmen ist es notwendig, den Wert einer Variablen um 1 zu erhöhen. Mit den bisherigen Kenntnissen lässt sich dafür bereits ein passender rekursiver Ausdruck erzeugen: a = a +1;

Da dieser Befehl jedoch sehr häufig vorkommt, gibt es dafür in C# – genau wie in vielen weiteren Programmiersprachen – eine Kurzform: a ++;

Diese hat genau den gleichen Effekt. Analog dazu ist es auch möglich, den Wert der Variablen um 1 zu verringern. Dafür kommt folgender Ausdruck zum Einsatz: a --;

Zum Schluss soll noch ein kleines Beispielprogramm stehen, das einige Variablen deklariert, Berechnungen mit ihnen durchführt und die Ergebnisse anschließend ausgibt. using System; namespace Variablen { class Program { static void Main(string[] args) { int a = 5; int b = 3; Console.WriteLine(“Das Ergebnis aus 5 + 3 beträgt “ + (a + b));

Console.WriteLine(“Das Ergebnis aus 5 * 3 beträgt “ + (a * b)); Console.WriteLine(“Das Ergebnis aus 5 - 3 beträgt “ + (a b)); Console.WriteLine(“Das Ergebnis aus 5 / 3 beträgt “ + (a / b)); Console.WriteLine(“Das Ergebnis aus 5 % 3 beträgt “ + (a % b)); a = b * 7; Console.WriteLine(“Der neue Wert der Variablen a beträgt “ + a); b++; Console.WriteLine(“Nach der Erhöhung um 1 beträgt der Wert von b “ + b); } } }

Screenshot 10 Die Ausgabe der Berechnungen Anmerkung: Bei den bisherigen WriteLine-Befehlen haben wir entweder nur Text oder nur eine Variable verwendet. In diesem Beispiel werden erstmals beide Elemente in einem Befehl zusammengefasst. Dafür ist es notwendig, sie mit dem Pluszeichen zu verbinden. Auf diese Weise lassen

sich beliebig viele Textbausteine und Variablen zusammenfügen. Wenn es sich bei einem der Bestandteile um einen Rechenausdruck handelt, der aus mehreren Variablen oder Zahlen besteht, ist es notwendig, diesen in Klammern zusammenzufassen. Darüber hinaus ist es wichtig, sich nochmals das Ergebnis der Division anzuschauen. Das Programm gibt hier den Wert 1 aus. Das wirkt auf den ersten Blick jedoch erstaunlich. Wenn man 5 durch 3 teilt, könnte man als Ergebnis 1,66667 erwarten. Wenn es jedoch zu einer Division von zwei Integer-Werten kommt, führt C# stets die sogenannte Integer-Division durch. Das bedeutet, dass die Ausgabe immer aus einem ganzzahligen Wert besteht. Den Rest (der in der folgenden Zeile mit dem Modulo-Operator abgerufen wird) gibt das Programm nicht aus. Es ist jedoch auch möglich, das Ergebnis als Kommazahl ausgeben zu lassen. Dafür ist es notwendig, eine der beiden Variablen als Fließkommazahl (double) zu deklarieren. Anstatt dessen wäre es in diesem Fall auch möglich, eine float-Variable zu verwenden. Das kann jedoch Probleme mit sich bringen, wenn man dieser einen Wert mit einer Nachkommastelle zuweist. Zahlen mit Nachkommastellen interpretiert C# automatisch als double-Variable. Float-Werte müssen gesondert gekennzeichnet werden. Aus diesem Grund ist es empfehlenswert, sich von Anfang an die Verwendung von double-Variablen anzugewöhnen. Dabei gilt es außerdem zu beachten, dass hierbei entsprechend der englischen Schreibweise ein Punkt zum Einsatz kommt, um die Nachkommastellen abzutrennen.

4.5

Eingaben des Anwenders in einer Variablen aufnehmen

Die bisherigen Programme laufen alle stets nach dem gleichen Muster ab. Sie arbeiten mit fest vorgegebenen Werten und liefern stets das gleiche Ergebnis. In den meisten Fällen ist jedoch eine Interaktion mit dem Anwender gewünscht. Es soll möglich sein, dass dieser selbst bestimmte Werte eingeben kann. Das Programm soll diese dann aufnehmen und verarbeiten.

Dafür sind ebenfalls Variablen notwendig. Diese ermöglichen es, die Nutzereingaben abzuspeichern. Zu diesem Zweck kommt der ReadLine-Befehl zum Einsatz. Dieser wird per Zuweisungsoperator einer Variablen zugewiesen. Das führt dazu, dass diese den Wert annimmt, den der Nutzer eingibt. Dazu ist es notwendig, die Variable zu deklarieren. Das kann man entweder bereits zuvor erledigen oder direkt in der gleichen Befehlszeile. Nach dem ReadLine-Befehl folgen eine leere Klammer und das Semikolon. Das folgende Beispielprogramm soll den Anwender dazu auffordern, seinen Namen einzugeben. Da es sich hierbei um eine Zeichenkette handelt, ist dafür eine string-Variable notwendig. Demnach kommen für die Deklarierung der Variablen und für die Aufnahme des Werts folgende Möglichkeiten infrage: string anwender; anwender = Console.ReadLine();

oder string anwender = Console.ReadLine();

Wenn man nun noch die Eingabeaufforderung und eine personalisierte Begrüßung ausgibt, ergibt sich daraus folgendes Programm: using System; namespace Variablen { class Program { static void Main(string[] args) { Console.Write(“Geben Sie bitte Ihren Namen ein: “); string anwender = Console.ReadLine(); Console.WriteLine(“Herzlich willkommen, “ + anwender + “!”);

} } }

Screenshot 11 Die Ausgabe des Programms Anmerkung: In diesem Programm kommt der einfache Write-Befehl zum Einsatz. Dieser erzeugt im Gegensatz zum WriteLine-Befehl keinen Zeilenumbruch. Daher kann der Anwender seinen Namen direkt in der gleichen Zeile eingeben. Im nächsten Beispiel soll der Anwender eine Zahl eingeben. Das Programm soll daraufhin den doppelten Wert dieser Eingabe berechnen und über die Konsole ausgeben. Wenn man dabei nach dem bisherigen Muster vorgeht, wären dafür folgende Befehle notwendig: Console.Write(“Geben Sie bitte eine Zahl ein: “); int zahl = Console.ReadLine(); Console.WriteLine(“Doppelter Wert: “ + (zahl * 2));

Wenn man diesen Code jedoch in das Programm einfügt und es daraufhin ausführt, erscheint folgende Fehlermeldung:

Screenshot 12 Die Fehlermeldung Das Programm gibt dabei diesen Text aus: “Der Typ “string” kann nicht implizit in “int” konvertiert werden.” Daraus lässt sich bereits schließen, dass es sich hierbei um ein Problem mit den Variablentypen handelt. Der Grund dafür besteht darin, dass der ReadLine-Befehl stets eine Zeichenkette erzeugt. Diese kann man jedoch nicht einfach einer integer-Variablen zuweisen – selbst wenn es sich dabei um Ziffern handelt. Daher ist es zunächst notwendig, den string-Wert in einen integer-Wert umzuwandeln. Das erfolgt mit dem Befehl Parse. Diesem wird der Variablentyp, in den der Wert umgewandelt werden soll, mit einem Punkt getrennt vorangestellt. Der Parse-Befehl muss dem ReadLine-Befehl vorangestellt werden, der wiederum in Klammern steht: int zahl = int.Parse(Console.ReadLine());

Dabei sei jedoch gleich angemerkt, dass es sich hierbei nicht um die beste Lösung für dieses Problem handelt. Der Grund dafür liegt in erster Linie darin, dass es hierbei zu einem sofortigen Abbruch des Programms kommt, wenn der Anwender keine Zahl, sondern einen Buchstaben eingibt. Für den Anfang reicht diese Funktionsweise jedoch aus. Später werden noch etwas elegantere Möglichkeiten für die Eingabe von Werten durch den Anwender vorgestellt. Dafür sind jedoch weitere Kenntnisse für die Steuerung des Programms notwendig. Das vollständige Programm sieht dann folgendermaßen aus: using System; namespace Variablen { class Program

{ static void Main(string[] args) { Console.Write(“Geben Sie bitte eine Zahl ein: “); int zahl = int.Parse(Console.ReadLine()); Console.WriteLine(“Doppelter Wert: “ + (zahl * 2)); } } }

Es wäre auch möglich, den Eingabewert in eine Fließkommazahl zu überführen. Dazu ist es nicht nur notwendig, die Deklaration der Variablen entsprechend abzuändern, sondern auch den Parse-Befehl: double zahl = double.Parse(Console.ReadLine());

4.6

Übungsaufgabe: erstellen

Programme

mit

Variablen

1. Erstellen Sie ein Programm, das jeweils eine int-, eine double und eine string-Variable enthält. Multiplizieren Sie die Werte der int- und der double-Variablen und speichern Sie den Wert in einer neuen Variablen. Wählen Sie hierfür einen passenden Typ. Geben Sie anschließend das Ergebnis zusammen mit der string-Variablen aus. 2. Schreiben Sie ein Programm, das vom Anwender zwei Werte abfragt. Berechnen Sie daraufhin das Ergebnis aus allen vier Grundrechenarten für die beiden Werte. Geben Sie bei der Ausgabe den entsprechenden Term und das Ergebnis an. Das Programm soll es dem Anwender erlauben, Kommazahlen einzugeben.

Lösungen: 1. using System;

namespace Variablen { class Program { static void Main(string[] args) { int ganzzahl = 2; double kommazahl = 5.6; string zeichenkette = “Ergebnis: “; double ergebnis = ganzzahl * kommazahl; Console.WriteLine(zeichenkette + ergebnis); } } }

Screenshot 13 Die Ausgabe zu Aufgabe 1

2. using System; namespace Variablen { class Program

{ static void Main(string[] args) { Console.Write(“Geben Sie bitte die erste Zahl ein: “); double zahl1 = double.Parse(Console.ReadLine()); Console.Write(“Geben Sie bitte die zweite Zahl ein: “); double zahl2 = double.Parse(Console.ReadLine()); Console.WriteLine(zahl1 + “ + “ + zahl2 + “ = “ + (zahl1 + zahl2)); Console.WriteLine(zahl1 + “ - “ + zahl2 + “ = “ + (zahl1 - zahl2)); Console.WriteLine(zahl1 + “ * “ + zahl2 + “ = “ + (zahl1 * zahl2)); Console.WriteLine(zahl1 + “ / “ + zahl2 + “ = “ + (zahl1 / zahl2)); } } }

Screenshot 14 Die Ausgabe der Berechnungen

Alle Programmcodes aus diesem Buch sind als PDF zum Download verfügbar. Dadurch müssen Sie sie nicht abtippen: https://bmu-verlag.de/books/cs-programmieren/

Außerdem erhalten Sie die eBook Ausgabe zum Buch im PDF Format kostenlos auf unserer Website:

https://bmu-verlag.de/books/cs-programmieren/ Downloadcode: siehe Kapitel 16

Kapitel 5

Datenstrukturen in C# Es kommt häufig vor, dass ein Programm nicht nur einen einzelnen Wert verarbeiten soll, sondern eine größere Menge zusammengehöriger Daten. Als Beispiel hierfür kann man sich einen Händler vorstellen, der sein Sortiment verwaltet. Zu diesem Zweck will er die Preise der einzelnen Angebote festhalten. In diesem Fall wäre es selbstverständlich möglich, für jeden einzelnen Preis eine eigene Variable zu deklarieren. Das ist jedoch aus mehreren Gründen nicht zu empfehlen. Wenn man für viele gleichartige Werte einzelne Variablen verwendet, entsteht beim Programmieren ein enormer Arbeitsaufwand. Man müsste sich dabei für jeden Wert einen eigenen Namen überlegen und diesen in das Programm eintippen. Darüber hinaus entstehen Probleme, wenn es zu einer Änderung im Sortiment kommt. In diesem Fall wäre es notwendig, Variablen zu entfernen oder hinzuzufügen, um die Funktionsweise wiederherzustellen. Darüber hinaus würde das Programm auf diese Weise ausgesprochen unübersichtlich. Von besonderer Bedeutung ist es jedoch, dass die Verwendung einzelner Variablen eine automatische Bearbeitung der Daten erschwert. In einem späteren Kapitel werden beispielsweise Schleifen vorgestellt, die die gleiche Aktion auf viele verschiedene Werte anwenden können. Das ist für die Erstellung effizienter Programme unverzichtbar. Bei den einzelnen Durchläufen der Schleifen ist es jedoch nicht möglich, den Variablennamen zu ändern. Das macht die Verwendung unmöglich, wenn man jeden Wert in einer eigenen Variablen abspeichert. Wenn man im Alltag mehrere ähnliche Werte zusammenfasst, ist es üblich, hierfür Listen oder Tabellen zu verwenden. C# bietet hierfür ganz ähnliche

Möglichkeiten an. Das erlaubt es, zusammengehörige Daten auch zusammenhängend abzuspeichern. Diese Gebilde, die aus mehreren einzelnen Werten bestehen, werden in der Informatik als Datenstrukturen bezeichnet. Der Zugriff findet dabei in der Regel über eine Indexnummer statt. Da sich deren Wert innerhalb einer Schleife einfach verändern lässt, bietet sich diese Organisationsform hervorragend für die automatische Bearbeitung größerer Datenbestände an. Das folgende Kapitel stellt mehrere Datenstrukturen vor.

5.1

Arrays für eine feste Anzahl an Werten

Eine der häufigsten Datenstrukturen, die in C# Verwendung finden, ist das Array. In deutschsprachigen Lehrbüchern findet sich dafür auch die Bezeichnung Datenfelder. Arrays kann man sich ähnlich wie eine Liste vorstellen. Sie bestehen aus einer linearen Abfolge einzelner Felder. In jedes dieser Felder kann man einen bestimmten Wert eintragen. Bei diesem Vergleich ist jedoch Vorsicht geboten. Der Grund dafür liegt darin, dass C# neben Arrays auch die Verwendung von Listen ermöglicht. Diese haben etwas andere Eigenschaften. Aus diesem Grund ist es wichtig, die beiden Begriffe strikt voneinander zu trennen. Eine der wesentlichen Eigenschaften eines Arrays besteht darin, dass sich darin nur Werte des gleichen Datentyps abspeichern lassen. Es ist nicht möglich, ganze Zahlen, Fließkommazahlen und Zeichenketten darin zu vermischen. Jedes Array unterstützt genau einen Datentyp. Dieser muss bei der Deklarierung angegeben werden und ist nicht veränderlich. Eine weitere Eigenheit dieser Datenstruktur besteht darin, dass sie stets eine feste Größe hat. Bereits zum Zeitpunkt, zu dem das Array erstellt wird, ist es notwendig, die gewünschte Länge festzulegen. Dieser Wert lässt sich später nicht mehr verändern. Das stellt einen wesentlichen Unterschied zur Liste dar, die in einem der folgenden Abschnitte vorgestellt wird. Genau wie bei einer Variablen ist es bei der Verwendung eines Arrays notwendig, dieses vor der ersten Verwendung zu deklarieren. Dabei ist es

notwendig, den gewünschten Datentyp anzugeben. Um deutlich zu machen, dass es sich hierbei um ein Array und nicht um eine gewöhnliche Variable handelt, folgt nach dem Datentyp eine eckige Klammer, die jedoch leer bleibt. Danach ist es erforderlich, einen Namen für das Array anzugeben. Bei der Auswahl des Namens gelten die gleichen Regeln wie bei Variablen. Wenn man beispielsweise ein Array aus ganzen Zahlen benötigt, kann man es mit folgendem Befehl deklarieren: int[] meinArray;

Wenn man andere Datentypen im Array speichern will, kann man an dieser Stelle auch andere Variablentypen einfügen – beispielsweise double, char oder string. Danach ist es notwendig, das Array zu initialisieren. Dabei gibt es jedoch einen erheblichen Unterschied zur Verwendung gewöhnlicher Variablen. Bei diesen ist es notwendig, bereits einen konkreten Wert vorzugeben. Bei einem Array ist es lediglich erforderlich, dessen Länge anzugeben. Konkrete Werte müssen hingegen nicht eingefügt werden. Die Felder erhalten dabei automatisch einen Standard-Wert. Bei Zahlen beträgt dieser 0, bei Zeichenketten ein leeres Feld. Folgender Befehl dient der Initialisierung: meinArray = new int[4];

Dieser erzeugt ein Array mit vier Feldern. Für die Initialisierung des Arrays ist der Schlüsselbegriff new notwendig. Das liegt daran, dass C# das Array wie ein Objekt behandelt. In Kapitel 8 wird ausführlich vorgestellt, was Objekte in der Informatik sind. An dieser Stelle ist es lediglich wichtig, zu wissen, dass man diese mit dem Begriff new erzeugt. Danach folgt die Angabe, um welchen Objekttyp es sich dabei handelt. In diesem Fall soll ein Array aus vier Feldern für ganze Zahlen entstehen. Daher muss wieder der Variablentyp und danach in einer eckigen Klammer die Anzahl der gewünschten Felder stehen. Auch bei Arrays ist es möglich, die Deklarierung und die Initialisierung in einem Befehl zusammenzufassen: int[] meinArray = new int[4];

Nun kann man den einzelnen Feldern des Array bestimmte Werte zuweisen. Dafür ist es notwendig, zunächst den Namen des Array anzugeben. Außerdem muss der Programmierer deutlich machen, in welches Feld der Wert eingetragen werden soll. Dazu dient die Indexnummer. Diese muss in einer eckigen Klammer nach dem Namen des Arrays stehen. Dabei handelt es sich stets um eine ganze Zahl. Es ist wichtig, dabei darauf zu achten, dass der Index stets mit 0 beginnt. Das Array aus unserem Beispiel, das aus vier Feldern besteht, hat demnach die Indexnummern 0 bis 3. Die Zuweisung von Werten erfolgt wie bei gewöhnlichen Variablen über den Zuweisungsoperator. Auch um Berechnungen durchzuführen, die Werte auszugeben oder um sie zu verändern, gelten ebenfalls die gleichen Regeln wie bei Variablen. Der einzige Unterschied besteht darin, dass man dabei stets die Indexnummer angeben muss. Wenn man beispielsweise dem ersten Feld einen Wert zuweisen und diesen daraufhin über die Console ausgeben will, wären folgende Befehle notwendig: meinArray[0] = 5; Console.WriteLine (meinArray[0]);

Sollte man bereits bei der Erstellung des Arrays genau wissen, welche Werte er aufnehmen soll, dann ist es auch möglich, diese direkt bei der Initialisierung einzufügen. Dazu ist es notwendig, die Werte in eine geschweifte Klammer zu schreiben und hinter der eckigen Klammer einzufügen. Die einzelnen Einträge werden durch Kommas getrennt. Wenn man das Array beispielsweise mit den Werten 5, 7, 9 und 10 initialisieren will, ist dafür folgender Befehl notwendig: int[] meinArray = new int[4] {5, 7, 9, 10};

Zum Abschluss soll noch ein kleines Beispielprogramm entstehen. Dieses nimmt das Thema aus der Einleitung zu diesem Kapitel auf. Es erstellt ein Array mit den Preisen von vier Produkten. Anschließend gibt es diese aus, nimmt eine Änderung an einem Eintrag vor und gibt den Wert erneut aus. using System; namespace Variablen

{ class Program { static void Main(string[] args) { double[] Preisliste = new double[4] {2.99, 8.49,          6.29, 10.99 }; Console.WriteLine(“Preis Produkt 1: “ +        Preisliste[0]); Console.WriteLine(“Preis Produkt 2: “ +        Preisliste[1]); Console.WriteLine(“Preis Produkt 3: “ +        Preisliste[2]); Console.WriteLine(“Preis Produkt 4: “ +        Preisliste[3]); Preisliste[1] = 7.99; Console.WriteLine(“Neuer Preis Produkt 2: “ +        Preisliste[1]); } } }

Screenshot 15 Die Ausgabe der Arrayfelder

5.2

Mehrdimensionale Arrays

Im Alltag kommen nicht nur Listen zum Einsatz, sondern häufig auch Tabellen. Diese ermöglichen es, in den verschiedenen Spalten unterschiedliche Werte zu einem Gegenstand abzuspeichern. Um beim Beispiel aus dem vorherigen Abschnitt zu bleiben: Wenn der Händler nicht nur den Preis, sondern auch die Artikelnummer und die Anzahl der im Lager verfügbaren Artikel aufnehmen will, kann er dafür eine Tabelle erstellen. Für jede dieser Angaben wird eine eigene Spalte erzeugt. C# bietet eine Möglichkeit, um eine derartige Organisationsform umzusetzen: mehrdimensionale Arrays. Das bedeutet, dass sich in jedem Arrayfeld mehrere Werte befinden. Ein zweidimensionales Array entspricht einer Tabelle. Darüber hinaus ist es möglich, noch beliebig viele weitere Dimensionen hinzuzufügen. Allerdings wird das Programm bei einer derartigen Struktur etwas unübersichtlich. Außerdemm besteht hierbei keine vergleichbare Struktur in der analogen Welt. Daher beschränken sich die meisten Programmierer auf zwei oder höchstens drei Dimensionen. Bereits bei der Deklarierung muss angegeben werden, wie viele Dimensionen das Array enthalten soll. Für jede weitere Dimension, die über das eindimensionale Array hinausgeht, muss zu diesem Zweck ein Komma in der eckigen Klammer stehen. Für ein zweidimensionales Array wäre demnach ein Komma notwendig, für ein dreidimensionales Array zwei Kommas. Bei der Initialisierung ist es notwendig, in der eckigen Klammer zunächst die Anzahl der Felder in der übergeordneten Dimension anzugeben. Nach einem Komma folgt dann die Anzahl der Felder, die es in der untergeordneten Dimension aufweisen soll. Um ein zweidimensionales Array zu deklarieren und zu initialisieren, bestehen demnach folgende zwei Möglichkeiten: int[,] meinArray; meinArray = new int[4,3];

oder: int[,] meinArray = new int[4,3];

Auch hierbei ist es möglich, den Arrayfeldern direkt Werte zuzuweisen. Dafür kommt wieder eine geschweifte Klammer zum Einsatz. Die Werte der weiteren Dimensionen müssen dabei jedoch jeweils in einer weiteren geschweiften Klammer stehen. Wenn man beispielsweise zu vier Produkten jeweils die Artikelnummer, den Preis und die vorhandene Stückzahl eintragen will, dann kann man dafür folgenden Befehl verwenden: double[,] Artikel = new double[4,3] {{1001, 2.99, 23},{1003, 8.49, 42},{1004, 6.29, 61},{1007, 10.99, 15}};

Dieser Ausdruck ist jedoch bereits sehr unübersichtlich. Daher kann es in diesem Fall sinnvoller sein, die entsprechenden Werte einzeln einzugeben. Um auf die Inhalte zuzugreifen, ist es notwendig, in der eckigen Klammer zunächst die Position in der ersten Dimension und daraufhin die Position der zweiten Dimension anzugeben. Um den Preis des dritten Produkts abzurufen, wäre beispielsweise folgender Ausdruck erforderlich: Artikel[2,1]

Wenn man sich die Deklarierung dieses Arrays genau betrachtet, dann fällt auf, dass dieser den Variablentyp double verwendet. Dieser ist jedoch eigentlich nur für den Preis sinnvoll. Für die Artikelnummer und für die Anzahl wären hingegen ganze Zahlen besser. Mehrdimensionale Arrays müssen jedoch immer den gleichen Datentyp verwenden. In diesem Fall können wir uns damit behelfen, für alle Variablen einen double-Wert zu verwenden. Das ist für die Anzahl und für die Artikelnummer zwar nicht ideal, aber dennoch möglich. Wenn jedoch zusätzlich auch noch eine Produktbezeichnung eingefügt werden soll, entstehen weitere Schwierigkeiten. In diesem Fall wäre es notwendig, alle Werte als string abzuspeichern. Wenn danach eine Berechnung mit den Zahlen stattfinden soll, wäre es notwendig, diese zunächst umzuformen. Das würde das Programm ausgesprochen kompliziert machen. Aus diesem Grund ist es sinnvoll, Arrays nur dann zu verwenden, wenn alle Werte dem gleichen Datentyp entsprechen.

5.3

Listen für eine variable Anzahl an Werten

Arrays haben den Vorteil, dass sie sehr effizient sind. Wenn sehr große Datenmengen bearbeitet werden sollen, ist es daher sinnvoll, Arrays dafür zu verwenden. Das führt zu einem geringen Rechenaufwand und daher zu einer schnellen Ausführung. Diesem Vorteil steht jedoch ein erheblicher Nachteil gegenüber: Bei einem Array ist die Anzahl der Felder stets konstant. Bei vielen Programmen hängt die Anzahl der Werte, die abgespeichert werden sollen, jedoch von den Eingaben des Anwenders ab. Es ist zwar möglich, die Länge des Arrays erst bei der Ausführung festzulegen und dabei die Eingaben des Anwenders zu berücksichtigen. Doch gibt es auch längere Programme, bei denen es möglich ist, dass später noch weitere Elemente hinzukommen. Wenn das Array einmal definiert ist, dann ist es nicht mehr möglich, die Anzahl der Felder zu verändern. Eine Lösung kann es darstellen, ein sehr großes Array zu definieren, in dem zunächst einige Felder leer bleiben. Das schafft zusätzliche Kapazitäten, um später weitere Werte einzufügen. Das stellt jedoch keine sinnvolle Vorgehensweise dar. Zum einen reduzieren die zusätzlichen Felder die Effizienz, was einen der wesentlichen Vorteile des Arrays zunichte macht. Zum anderen ist es häufig möglich, dass zu einem gewissen Zeitpunkt die Anzahl der Werte die Größe des Arrays dennoch übersteigt. Das führt zu einem Fehler des Programms. Aus diesem Grund ist es sinnvoll, eine andere Datenstruktur zu wählen, wenn die Anzahl der Einträge zunächst unbekannt ist. Hierfür bieten sich Listen an. Diese haben keine feste Länge. Es ist daher jederzeit möglich, weitere Elemente hinzuzufügen. C# unterstützt unterschiedliche Arten von Listen. Diese unterscheiden sich in erster Linie darin, ob sie sich nur für einen einheitlichen Datentyp eignen oder ob es möglich ist, Werte mit unterschiedlichen Typen darin abzuspeichern.

5.4

Listen für identische Datentypen

Häufig soll die Liste nur Daten des gleichen Typs aufnehmen. In diesem Fall ist es sinnvoll, den Datentyp List zu verwenden. Dieser bietet die Möglichkeit, immer weitere Daten hinzuzufügen – selbst wenn die Länge der Liste zu Beginn noch nicht bekannt ist. Bei der Verwendung dieser Liste gilt es zu beachten, dass diese nicht in den Standard-Befehlen von C# enthalten ist. Daher müssen die entsprechenden Funktionen zunächst importiert werden. Dazu ist es notwendig, folgende Zeile oben im Programm einzufügen – direkt unterhalb des Befehls using System: using System.Collections.Generic;

Um eine Liste dieses Typs zu erzeugen, ist es zunächst erforderlich, den Schlüsselbegriff List in das Programm zu schreiben. Danach steht in spitzen Klammern der gewünschte Datentyp. Nun folgt der Name, der wie bei Variablen und Arrays frei gewählt werden kann. Für die Initialisierung ist es dann notwendig, diesem Begriff mit dem Zuweisungsoperator eine neue Liste zuzuweisen. Um diese zu erzeugen, dient wieder der Schlüsselbegriff new. Danach folgen nochmals der Ausdruck List und die Angabe des Datentyps in einer spitzen Klammer. Anschließend steht eine runde Klammer, die jedoch leer bleibt. Um eine neue Liste für integer-Werte zu erstellen, ist demnach dieser Ausdruck notwendig: List meineListe = new List();

Auf diese Weise entsteht zunächst eine Liste mit dem Namen meineListe. Um diese mit Inhalten zu füllen, ist es notwendig, den Add-Befehl anzuwenden. Zu diesem Zweck wird zunächst der Name der Liste angegeben. Danach folgen ein Punkt und und der Ausdruck Add. Anschließend steht in einer Klammer der Wert, der eingefügt werden soll. Dabei ist es möglich, direkt eine Zahl anzugeben oder eine Variable zu nutzen. Wenn man der Liste beispielsweise den Wert 5 hinzufügen will, ist dafür folgender Befehl notwendig: meineListe.Add(5);

Indem man diesen Befehl wiederholt, kann man beliebig viele weitere Elemente hinzufügen. Um auf ein Element der Liste zuzugreifen, ist es notwendig, dessen Indexnummer in einer eckigen Klammer anzugeben – genau wie bei Arrays. Auch hierbei beginnt der Index stets mit der Zahl 0. Die Abfolge entspricht dabei der Reihenfolge, in der die Werte eingegeben wurden. Um Inhalte aus der Liste zu entfernen, bestehen zwei Möglichkeiten. Zum einen lässt sich das zu löschende Element über die Index-Nummer bestimmen. Hierzu kommt der Befehl RemoveAt zum Einsatz. Um das erste Element einer Liste zu löschen, dient beispielsweise folgender Befehl: meineListe.RemoveAt(0);

Wenn in der entsprechenden Liste bereits mehrere Einträge vorhande sind, werden die folgenden Elemente alle um einen Schritt nach vorne verschoben. Eine weitere Möglichkeit besteht darin, den Remove-Befehl zu verwenden. Dieser nutzt den Inhalt als Kriterium für die Löschung. Wenn beispielsweise der Befehl meineListe.Remove(5) eingegeben wird, dann geht das Programm die komplette Liste durch, bis es den Eintrag mit dem Wert 5 gefunden hat. Diesen löscht es dann. Sollte der Wert nicht in der Liste vorkommen, führt es keine Aktion durch. Wenn er mehrmals vorhanden ist, wird nur der erste Eintrag gelöscht. Die übrigen Listenfelder mit dem identischen Wert bleiben erhalten. Ein weiterer wichtiger Befehl für den Umgang mit Listen ist das Kommando Count. Dieses wird ebenfalls nach einem Punkt an den Namen der Liste angehängt. Dieses Kommando gibt die Länge der Liste zurück. Dieser Wert lässt sich in einer Variablen speichern oder wie im folgenden Beispiel direkt über den WriteLine-Befehl ausgeben: Console.WriteLine(meineListe.Count);

Zum Abschluss folgt ein Beispielprogramm, das eine Liste erstellt, und danach verschiedene Operationen mit ihr durchführt. using System;

using System.Collections.Generic; namespace Variablen { class Program { static void Main(string[] args) { List meineListe = new List(); meineListe.Add(5); meineListe.Add(12); meineListe.Add(14); Console.WriteLine(“Wert 1: “ + meineListe[0]); Console.WriteLine(“Wert 2: “ + meineListe[1]); Console.WriteLine(“Wert 3: “ + meineListe[2]); Console.WriteLine(“Länge: “ + meineListe.Count); meineListe.Remove(12); meineListe[0] = 7; Console.WriteLine(“Nach der Veränderung:”); Console.WriteLine(“Wert 1: “ + meineListe[0]); Console.WriteLine(“Wert 2: “ + meineListe[1]); Console.WriteLine(“Neue Länge: “ +        meineListe.Count); } } }

Screenshot 16 die Ausgabe der Elemente der Liste Es gibt noch viele weitere Kommandos, die für die Arbeit mit Listen nützlich sind. Die hier vorgestellten Befehle stellen jedoch die Grundlage hierfür dar und ermöglichen bereits viele Anwendungen. Wenn im späteren Verlauf dieses Buchs weitere Befehle für die Arbeit mit Listen notwendig sind, werden diese im entsprechenden Kontext vorgestellt.

5.5

Listen für unterschiedliche Datentypen

In manchen Fällen ist es erwünscht, dass eine Liste nicht nur gleichartige Elemente aufnehmen kann, sondern auch verschiedene Datentypen. Im letzten Beispiel in Kapitel 5.2. kamen beispielsweise int- und double-Werte gemeinsam zum Einsatz. C# bietet auch eine Datenstruktur, die sich für ganz verschiedene Werte anbietet. Dabei handelt es sich um die ArrayList. Um dieses zu verwenden, ist zunächst folgender Import-Befehl notwendig: using System.Collections;

Danach ist es notwendig, die ArrayList zu deklarieren und zu initialisieren. Die Vorgehensweise ist dabei beinahe identisch wie bei der Verwendung der Datenstruktur List. Es ist lediglich notwendig, den Schlüsselbegriff

anzupassen und die Typbezeichnung in den eckigen Klammern zu entfernen. Daraus ergibt sich folgender Befehl: ArrayList meineListe = new ArrayList();

Die Befehle Add, RemoveAt, Remove und Count werden bei der ArrayList auf genau die gleiche Weise angewendet wie bei List. Der einzige Unterschied besteht darin, dass es beim Add-Befehl möglich ist, Werte jedes beliebigen Datentyps einzufügen. Daher ist es nicht notwendig, alle einzelnen Kommandos nochmals explizit zu erläutern. Anstatt dessen soll die Verwendung in einem Beispielprogramm verdeutlicht werden: using System; using System.Collections; namespace Variablen { class Program { static void Main(string[] args) { ArrayList meineListe = new ArrayList(); meineListe.Add(24); meineListe.Add(“Hallo”); meineListe.Add(true); meineListe.Add(3.44); Console.WriteLine(“Wert 1: “ + meineListe[0]); Console.WriteLine(“Wert 2: “ + meineListe[1]); Console.WriteLine(“Wert 3: “ + meineListe[2]); Console.WriteLine(“Wert 4: “ + meineListe[3]); meineListe.RemoveAt(2); meineListe.Remove(“Hallo”); Console.WriteLine(“Länge: “ + meineListe.Count); } } }

Screenshot 17 Die Ausgabe des Programms Die Datenstruktur ArrayList ist deutlich älter als die im vorherigen Abschnitt vorgestellte List. Früher kam sie sehr häufig zum Einsatz. Mittlerweile rät Microsoft jedoch von der Verwendung ab. Der Grund dafür liegt zum einen darin, dass diese Struktur äußerst ineffizient arbeitet. Daher hat sie bei größeren Datenmengen lange Wartezeiten zur Folge. Zum anderen kann es zu Fehlern führen, wenn man nicht weiß, welche Datentypen in der Liste an welcher Position enthalten sind. Aus diesem Grund ist es sinnvoll, wenn möglich auf die Verwendung zu verzichten. Diese Struktur wird an dieser Stelle in erster Linie deshalb vorgestellt, weil sie in vielen älteren Programmen noch zu finden ist. Vorerst bietet sie auch den Vorteil, dass man darin verschiedene Datentypen abspeichern kann. Doch gibt es hierfür auch eine sinnvollere Lösung: die Verwendung von Objekten. Diese Alternative wird später in diesem Buch vorgestellt.

5.6

Übungsaufgabe: mit Datenstrukturen arbeiten

1. Erstellen Sie ein Programm, das eine Datenstruktur mit drei integerWerten beinhaltet. Geben Sie dafür beliebige Zahlen ein und erhöhen Sie diese dann jeweils um 1. Geben Sie anschließend die Ergebnisse aus. Wählen Sie dafür eine passende Datenstruktur.

2. Erstellen Sie ein Programm, das eine Datenstruktur aus drei beliebigen Worten enthält. Es soll möglich sein, diese später noch zu erweitern. Geben Sie anschließend die Zahl der Einträge über die Konsole aus. Wählen Sie dafür eine passende Datenstruktur. 3. Wählen Sie abschließend eine Datenstruktur aus, die es ermöglicht, eine Zahl, ein Wort und eine boolesche Variable aufzunehmen. Löschen Sie daraus den Eintrag mit dem Wort und geben Sie die übrigen Inhalte aus.

Lösungen: 1. using System; namespace Variablen { class Program { static void Main(string[] args) { int[] meinArray = new int[3] { 3, 23, 12 }; meinArray[0]++; meinArray[1]++; meinArray[2]++; Console.WriteLine(“Wert 1: “ + meinArray[0]); Console.WriteLine(“Wert 1: “ + meinArray[1]); Console.WriteLine(“Wert 2: “ + meinArray[2]); } } }

Screenshot 18 Das Programm mit einem Array

2. using System; using System.Collections.Generic; namespace Variablen { class Program { static void Main(string[] args) { List meineListe = new List(); meineListe.Add(“Haus”); meineListe.Add(“Baum”); meineListe.Add(“Blume”); Console.WriteLine(“Anzahl der Listenelemente: “ +     meineListe.Count); } } }

Screenshot 19 Die Verwendung einer Liste

3. using System; using System.Collections; namespace Variablen { class Program { static void Main(string[] args) { ArrayList meineArrayList = new ArrayList(); meineArrayList.Add(6); meineArrayList.Add(“Haus”); meineArrayList.Add(false); meineArrayList.Remove(“Haus”); Console.WriteLine(“Element 1: “ + meineArrayList[0]); Console.WriteLine(“Element 2: “ +        meineArrayList[1]); } } }

Screenshot 20 Die Verwendung der ArrayList

Alle Programmcodes aus diesem Buch sind als PDF zum Download verfügbar. Dadurch müssen Sie sie nicht abtippen: https://bmu-verlag.de/books/cs-programmieren/

Außerdem erhalten Sie die eBook Ausgabe zum Buch im PDF Format kostenlos auf unserer Website:

https://bmu-verlag.de/books/cs-programmieren/ Downloadcode: siehe Kapitel 16

Kapitel 6

If-Abfragen: mehrere Alternativen in das Programm einfügen Eine der grundsätzlichen Eigenschaften eines Computerprogramms besteht darin, dass es nicht immer auf die gleiche Weise ausgeführt wird. Anstatt dessen ist der Ablauf von verschiedenen Variablen abhängig. Je nachdem, welchen Wert diese haben, führt es unterschiedliche Befehle aus oder wiederholt einen bestimmten Abschnitt mehrere Male. Um dieses Verhalten festzulegen, kommt die Ablaufsteuerung zum Einsatz. Eines der zentralen Elemente der Ablaufsteuerung ist die Verzweigung. Das bedeutet, dass das Programm zwei unterschiedliche Wege aufweist. Diese zeichnen sich jeweils durch verschiedene Befehle aus. In Abhängigkeit von den Werten der Variablen wählt das Programm dann die eine oder die andere Möglichkeit aus. Für diese Verzweigungen kommen if-Abfragen zum Einsatz.

6.1

Der Aufbau der if-Abfrage

Bei einer Verzweigung ist es notwendig, eine Entscheidung über den einzuschlagenden Weg zu treffen. Diese Entscheidung trifft das Programm jedoch nicht willkürlich. Anstatt dessen ist es notwendig, eine konkrete Bedingung dafür anzugeben. Diese steht daher stets am Anfang einer Verzweigung.

Wenn man in der Alltagssprache eine Bedingung formuliert, dann kommt dafür in der Regel der Ausdruck “wenn” zum Einsatz. Zum Beispiel: “Wenn es regnet, nehme ich den Regenschirm mit.” In der englischen Sprache lautet dieser Begriff “if”. C# verwendet wie fast alle übrigen Programmiersprachen genau diesen Ausdruck für eine Verzweigung im Programm. Nach diesem Schlüsselbegriff folgt die Aufstellung der Bedingung. Daraufhin ist eine geschweifte Klammer notwendig. Darin stehen alle Befehle, die das Programm ausführen soll, wenn die Bedingung erfüllt ist. Daraus ergibt sich der folgende strukturelle Aufbau der if-Abfrage: if (Bedingung) { Befehl 1; Befehl 2; Befehl 3; . . . Befehl n; }

Mit diesen Kenntnissen lässt sich bereits eine erste Verzweigung erstellen. Allerdings wurde bislang noch nicht erklärt, wie die Bedingungen für die ifAbfrage aufzustellen sind. Das folgt in den nächsten Abschnitten. Um die eben vorgestellte Struktur dennoch bereits jetzt in der Praxis anzuwenden, soll kurz die einfachste Möglichkeit hierfür erklärt werden: die Verwendung einer booleschen Variablen. Diese kann entweder den Wert true oder false haben. Ist der Wert true, ist die Bedingung erfüllt. Wurde er hingegen auf false gesetzt, führt das Programm die entsprechenden Befehle nicht aus. Um eine boolesche Variable als Bedingung zu verwenden, ist es lediglich notwendig, deren Namen in die Klammer zu schreiben. Das folgende Programm enthält zwei Verzweigungen. Bei der ersten von ihnen ist die Bedingung erfüllt, bei der zweiten hingegen nicht. Daher werden nur die Befehle in der ersten if-Abfrage ausgeführt.

using System; namespace if_abfrage { class Program { static void Main(string[] args) { bool bedingung1 = true; bool bedingung2 = false; if (bedingung1) { Console.WriteLine(“Bedingung 1 trifft zu.”); } if (bedingung2) { Console.WriteLine(“Bedingung 2 trifft zu.”); } } } }

Screenshot 21 Das Programm führt nur die Befehle der ersten Abfrage aus.

if-

6.2

Vergleichsoperatoren

Die Bedingung spielt für jede if-Abfrage eine zentrale Rolle. Bislang wurde hierfür nur eine sehr einfache Möglichkeit vorgestellt: die Verwendung boolescher Variablen. Das bedeutet jedoch, dass man hierbei den Wert schon im Vorfeld vorgeben muss. Das Ziel der Verzweigung ist es hingegen, während der Ausführung den Ablauf anzupassen – häufig in Abhängigkeit von den Eingaben des Anwenders. Hierfür sind Vergleiche notwendig. Diese machen es möglich, den Wert einer Variablen mit einem bestimmten Sollwert zu vergleichen. Hierfür finden Vergleichsoperatoren Verwendung. Sehr häufig ist es notwendig, zu überprüfen, ob eine Variable den gleichen Wert aufweist wie eine andere. Zu diesem Zweck kommt das doppelte Gleichheitszeichen zum Einsatz. Die doppelte Verwendung dieses Symbols ist notwendig, um Verwechslungen mit dem Zuweisungsoperator zu vermeiden. Sind die Werte gleich, ist die Bedingung erfüllt. Das soll gleich in einem Beispielprogramm vorgestellt werden. Dieses stellt dem Anwender eine einfache Rechenaufgabe und fordert ihn dazu auf, das Ergebnis einzugeben. Wenn er die Aufgabe richtig gelöst hat, gibt es eine Erfolgsmeldung aus. using System; namespace if_abfrage { class Program { static void Main(string[] args) { Console.Write(“Was ist das Ergebnis aus 2+4? “); int ergebnis = int.Parse(Console.ReadLine()); if (ergebnis == 6) { Console.WriteLine(“Sie haben die Aufgabe richtig gelöst.”); } }

} }

Wenn man das Programm ausführt und über die Konsole den Wert 6 eingibt, dann erscheint die Meldung, dass die Aufgabe richtig gelöst wurde. Wenn man jedoch einmal einen anderen Wert eingibt, dann erscheint überhaupt keine Ausgabe. Es wäre jedoch sinnvoll, auch in diesem Fall eine passende Nachricht auszugeben. Das wird nun durch das Einfügen weiterer ifAbfragen mit anderen Vergleichsoperatoren nachgeholt. using System; namespace if_abfrage { class Program { static void Main(string[] args) { Console.Write(“Was ist das Ergebnis aus 2+4? “); int ergebnis = int.Parse(Console.ReadLine()); if (ergebnis == 6) { Console.WriteLine(“Sie haben die Aufgabe    richtig gelöst.”); } if (ergebnis < 6) { Console.WriteLine(“Sie haben die Aufgabe    nicht richtig gelöst.”); } if (ergebnis > 6) { Console.WriteLine(“Sie haben die Aufgabe    nicht richtig gelöst.”); } }

} }

Wenn man das falsche Ergebnis eingibt, dann ist der Wert entweder größer oder kleiner als die korrekte Lösung. Diese Eigenschaft macht sich das Programm zunutze, indem es für jede dieser beiden Optionen eine weitere ifAbfrage erstellt. Dafür kommen das Größer- und das Kleinerzeichen (> und = und