~~SLIDYSHOW~~
| Datentyp | Bezeichnung | Beispiel |
|---|---|---|
| Ganze Zahlen | integer | 1911 oder -1911 |
| Dezimalzahl | float | 19.11 oder -19.11 |
| Dezimalzahl | double | 19.11 oder -19.11 |
| Zeichenketten | string | „Kette von Zeichen“ oder 'Kette von Zeichen' |
| Felder (ein- oder mehrdimensional) | array | („Frankfurt“, „Berlin“, „Zürich“) |
| Objekte | object | Verweis auf eine bestimmte Variable |
| Wahrheitswert | bool | true oder false |
| Zeichen | char | a, b, c, 1, 2, 3 |
Mithilfe von if - Verzweigungen wird eine Bedingung überprüft, und wenn diese zutrifft, ein Block von Anweisungen ausgeführt.
if (Bedingung 1) { Anweisungsblock 1; } else if (Bedingung 2) { Anweisungsblock 2; } else { Anweisungsblock 3; }
Wenn ein Anweisungsblock aus nur 1er Anweisung besteht, kann man auf die geschwungenen Klammern verzichten.
if (alter<18) {ShowMessage("Du bist noch minderjährig");} else if (alter<=50) {ShowMessage("Du bist noch nicht allzu alt");} else {ShowMessage("Du bist schon so gut wie tot")}
In den Bedingungen können verschiedene Vergleichsoperatoren verwendet werden:
| Operator | Name |
|---|---|
| < | kleiner |
| <= | kleiner oder gleich |
| == | gleich |
| >= | größer oder gleich |
| > | größer |
| != | ungleich |
Vergleiche können auch miteinander verknüpft werden:
| Veknüpfung | Art |
|---|---|
| && | und |
| || | oder |
Wenn eine Auswahl aus mehreren Varianten möglich ist, kann anstelle der if-Verzweigung die switch-Anweisung verwendet werden. Es handelt sich hierbei um eine Mehrfachauswahl.
switch(Note) { case 1: ShowMessage("Sehr Gut"); break; case 2: ShowMessage("Gut"); break; case 3: ShowMessage("Befriedigend"); break; case 4: ShowMessage("Genügend"); break; case 5: ShowMessage("Nicht Genügend"); break; default: ShowMessage("Diese Note gibt es nicht"); break; }
switch(Note) { case 1: case 2: case 3: case 4: ShowMessage("Positiv"); break; case 5: ShowMessage("Negativ");break; }
In der while-Schleife bestimmt die Laufbedingung - das ist der Ausdruck in der Klammer nach while - wielange die folgende Anweisung wiederholt wird. Der Wert des Ausdrucks wird vor der Abarbeitung der Anweisung überprüft. Daher kann es auch vorkommen, dass eine Schleife überhaupt nicht durchlaufen wird. Gleich zu Beginn wird das erste mal überprüft, ob der Ausdruck in der Klammer 'true' oder 'false' zurückliefert, bei 'true' werden die folgenden Anweisungen ausgeführt, bei 'false' wird die Klammer gleich übersprungen. Nach jedem Durchlauf wird der Ausdruck erneut überpfrüft.
while(Ausdruck) //Schleifeneintrittsbedingung Anweisung; while(Ausdruck){ //Schleifeneintrittsbedingung Anweisung1; Anweisung2; ...; }
Die do-while-Schleife unterscheidet sich von der while-Schleife nur dadurch, dass immer erst am Ende jedes Durchlaufs der Ausdruck überprüft wird anstatt zu Beginn. Darum wird die Schleife auch mindestens 1x durchlaufen.
do Anweisung; while(Ausdruck); //Schleifenaustrittsbedingung do { Anweisung1; Anweisung2; ...; } while(Ausdruck); //Schleifenaustrittsbedingung
Die for-Schleife eignet sich besonders gut, wenn schon im Voraus die gewünschte Anzahl der Durchläufe feststeht, da die Anzahl der Schleifendurchläufe mit einer Laufvariable mitgezählt werden.
for([Initialisierung];[Bedingungsausdruck];[Aktualisierung]) { Anweisung1; Anweisung2; ...; }
Initialisierung: Hier steht die Anweisung, die vor der zu wiederholenden Anweisung auszuführen ist. Der Laufvariable wird ein Wert zugewiesen.
Bedingungsausdruck: Hier steht die Abbruchsbedingung, die jedesmal vor Betreten der Schleife überprüft wird.
Aktualisierung: Der Wert der Laufvariable wird aktualisiert, z.B. i+ +, i–, i=i+5, usw.
Aufgabe: Würfelsimulation
Entwickle eine Würfelsimulation, die es erlaubt 10 mal zu würfeln. Die Wurfergebnisse sollen dabei über den Zufallsgenerator erzeugt werden und in einem Integer-Array abgespeichert werden. Ergänze das Programm derart, dass der Mittelwert der 10 Würfe berechnet wird und die Anzahl jener Würfe ermittel wird, die über dem Mittelwert liegen.
Eine Datenstruktur ist ein mathematisches Objekt zur Speicherung von zusammengehörigen Daten. Sie organisiert die Daten und stellt Algorithmen zur Datenverwaltung zur Verfügung. Weil die Daten in einer bestimmten Art und Weise miteinander verknüpft werden, um einen möglichst einfachen Zugang zu ermöglichen, spricht man von einer Struktur.
Grundlegende Funktionen einer Datenstruktur sind z.B. das Hinzufügen und das Löschen von Informationen. Dabei muss man natürlich beachten, dass gleiche Funktionen bei verschiedenen Datenstrukturen unterschiedlich effizient und komplex zu programmieren sind. Bestimmte Strukturen benötigen mehr Speicherplatz für die gleichen Daten als andere, bringen dafür aber wiederum Vorteile in anderen Bereichen mit sich. Darum muss man, bevor man sich für eine Datenstruktur entscheidet, deren Vor- und Nachteile kennen und diese in dem jeweiligen konkreten Fall gegeneinander abwägen. Ziel ist es natürlich, durch die geeignete und richtige Wahl einer Struktur Zeit und Speicherplatz zu sparen und möglichst effektiv mit den Daten arbeiten zu können.
Das Array ist die einfachste verwendete Datenstruktur. Es werden hierbei mehrere Variablen vom selben Datentyp gespeichert. Ein Zugriff auf die einzelnen Elemente wird über einen Index möglich. Grundsätzlich gibt es zwei Typen von Arrays:
Arrays können außerdem bis zu 60 Dimensionen haben, meistens werden aber nicht mehr als drei oder vier gebraucht.
Ein eindimensionales Array ist im Grunde eine Kette (Spalte oder auch Zeile) von Elementen mit fortlaufendem Index von 0 beginnend.
Für eine Deklaration eines eindimensionalen Arrays wird zuerst der Datentyp, dann der Name des Arrays und zum Schluss die gewünschte Anzahl der Elemente in eckigen Klammern angegeben. Die Anzahl der Elemente muss immer eine Konstante sein und kann weder durch eine Varible festgelegt sein, noch während der Laufzeit geändert werden.
Ein Beispiel:
int k[4]; // erzeugt ein Array vom Datentyp Integer mit Platz für vier Variablen
Um einem bestehenden Array Werte zuzuweisen oder bereits zugewiesene Werte zu ändern, müssen der Arrayname mit dem Index des zu Bearbeitenden Elements in eckigen Klammern und nach einem = der neue Wert dieses Elements eingegeben werden. Der Index des ersten Elements lautet immer 0, daher ist der letzte Index, die bei der Deklaration angegebene Anzahl der Elemente - 1.
Fortsetzung des Beispiels:
k[0]=1; k[1]=2; k[2]=3; // den Elementen werden Werte zugewiesen k[3]=4;
Da es mit zunehmender Anzahl von Elementen immer unpraktischer wird den Elementen einzeln Werte zuzuweisen, kann man mithilfe einer for-Schleife reichlich Zeit und Platz sparen.
Wertzuweisung:
int i[20]; //Deklaration eines eindimensionalen Arrays mit 20 Elementen. int y=1; for (int j=0;j<20;j++) { i[j]=y; //Array i wird der Reihe nach mit den Zahlen 1 - 20 gefüllt. y++; }
Oder:
int i[20]; for (int j=0;j<20;j++) { i[j]=StrToInt(InputBox("Wertzuweisung","Wert für das "+IntToStr(j)+". Element:", ""); }
Natürlich können die Werte des Arrays ganz normal mit z.B. i[3] einzeln ausgegeben werden, um den ganzen Array zu durchlaufen und die Werte nacheinander auszugeben kann aber wieder eine for-Schleife zuhilfe genommen werden.
Im Beispiel werden die Werte des Arrays in eine Memobox übertragen.
for (int j=0; j<20; j++) { Memo1->Lines->Add(i[j]); }
Bei einem mehrdimensionalen Array können Werte nicht nur einer Dimension (Zeile), sondern mehreren übergeben werden. Ein mehrdiemensionales Array ist im Aufbau mit einer Matrix zu vergleichen. Es besitz Spalten und Zeilen durch die die Koordinate des Werts bestimmt wird.
Im Allgemeinen ändert sich bei der Deklaration eines mehrdimensionalen Arrays im Gegensatz zu der eines eindimensionalen Arrays nicht viel. Es werden ledigleich mehrere eckige Klammern mit den Anzahlen für Spalten und Zeilen verwendet.
int k[3][6]; //Zweidimensionales Array mit 3 Spalten und 6 Zeilen -> 18 Elemente
Wie auch bei einem eindimensionalen Array können Werte einfach über die entsprechenden Indizes geändert werden.
k[2][3]=5; k[1][1]=13;
Da das aber meistens zu zeitaufwändig ist, kann man sich diesmal mit 2 ineinander veschachtelten for-Schleifen helfen:
for(int i=0; i<3; i++) { for(int j=0; j<6; j++) { k[i][j]=StrToInt(InputBox("Wertzuweisung","Wert für das Element der "+IntToStr(i)+". Spalte und "+IntToStr(j)". Zeile:",""); } }
Die Ausgabe kann analog dazu so aussehen:
for(int i=0; i<3; i++) { for(int j=0; j<6; j++) { Memo1->Lines->Add(k[i][j]); } }
Oft ist es sinnvoll, nicht nur wie in einem Array Daten desselben Datentyps zusammenzufassen, sondern auch Daten verschiedener Datentypen.
Eine mit dem Schlüsselwert struct definierte Klasse ist ein Datentyp, der auch als Struktur bezeichnet wird. Die wie Variablen zwischen den geschweiften Klammern aufgeführten Elemente einer solchen Klasse werden auch als Datenelemente bezeichnet.
Beispiel: Uhrzeit Die Uhrzeit besteht aus drei Werten: Stunde, Minute und Sekunde. Eine solche Uhrzeit kann durch die Klasse CZeit mit den Datenelementen Stunde, Minute und Sekunde dargestellt werden:
struct CZeit { int Stunde; int Minute; int Sekunde; };
Um von diesem neuen Datentyp eine Variable zu erhalten kann man sie wie gewohnt definieren:
CZeit t; //Die Variable t ist vom Datentyp CZeit
Oder man gibt noch vor dem Semikolon, das die Klassendefinition abschließt eine Variable ein:
struct CZeit { int Stunde; int Minute; int Sekunde; } t; // Die Variable t ist vom Datentyp CZeit
Benötigt man nur eine Variable vom neuen Datentyp, muss man keinen Namen dafür angeben:
struct // Dieser Datentyp hat keinen eigenen Namen. { int Stunde; int Minute; int Sekunde; } t; // Der Datentyp von t hat keinen Namen
Natürlich kann man Strukturen auch verschachteln. Wenn man sich eine Tabelle vorstellt, in der sich alle Schüler einer Klasse mit Name, Geburtsdatum, Telefonnummer, usw. eintragen, kann man aus einer Zeile dieser Tabelle auch eine Struktur erstellen:
struct Schüler { AnsiString Name; struct { int Tag; int Monat; int Jahr; } Geburtsdatum; int Telefonnummer; }s; //Die Variable s ist vom Datentyp Schüler
Man kann die Elemente der vorhin definierten Variable s folgendermaßen ansprechen:
s.Name; s.Telefonnummer; s.Geburtsdatum.Tag; s.Geburtsdatum.Monat;
Mit struct können nur Datenelemente zusammengefasst werden. Eine Funktion, die zu einer Klasse gehört, wird als Elementfunktion (Methode) bezeichnet. Mit class können auch Elementfunktionen in eine Klasse eingebunden werden.
Eine Elementfunktion kann innerhalb oder außerhalb der Klasse definiert werden. Wenn sie außerhalb der Klasse definiert wird, gibt man vor ihrem Namen den Namen der Klasse und den Bereichsoperator „::“ an. Sie muss dann zuvor in der Klasse durch die Angabe ihres Prototyps deklariert werden.
Ein Konstruktor ist eine Elementfunktion der Klasse, die dadurch charakterisiert ist, dass sie denselben Namen wie die Klasse hat. Er darf keinen Rückgabetyp haben (auch nicht void). Eine Klasse kann mehrere Konstruktoren haben. Diese müssen sich dann wie alle anderen überladenen Funktionen durch hinreichend verschiedene Parameter unterscheiden. Die Parameter können auch Default-Argumente haben.
class Bruch { double zaehler, nenner; Bruch(double zaehler_) { zaehler=zaehler_; nenner=1; } Bruch(double zaehler_, double nenner_) { zaehler=zaehler_; nenner=nenner_; } };
Wenn ich dann eine Variable vom Typ Bruch mit nur einem Parameter definiere, wird der nenner automatisch 1 gesetzt, da ich vermutlich eine ganze Zahl haben wollte.
Bruch a(2); // a=2/1 Bruch b(3,2); // b=3/2
Die beiden Konstruktoren können auch durch einen einzigen mit einem Default-Argument ersetzt werden:
class Bruch { double zaehler, nenner; Bruch(zaehler_, nenner_=1) { zaehler=zaehler_; nenner=nenner_; } };
weitere Datenstrukturen:
→ dynamische Strukturen (Sebastian)
Mit den Zugriffsrechten private, protected und public kann man für jedes Klassenelement explizit festlegen, ob man über ein Objekt darauf zugreifen kann.
Diese Spezifizierer definieren ab ihrer Angabe einen Abschnitt mit Zugriffsrechten, die für alle folgenden Elemente bis zum nächsten solchen Spezifizierer oder bis zum Ende der Klasse gelten. Ein Element aus einem private, protected oder public Abschnitt heißt auch private, protected oder public Element.
Ohne die Angabe eines Zugriffsrechts sind alle Elemente einer mit class definierten Klasse private, während alle Elemente einer mit struct definierten Klasse public sind. Dieses voreingestellte Zugriffsrechte ist der einzige Unterschied zwischen einer mit class und einer mit struct definierten Klasse.
Funktionen sind eigenständige Programmteile, die vom Skript beliebig oft aufgerufen und abgearbeitet werden können. Funktionen beinhalten Anweisungen, die innerhalb des Programms mehrmals benötigt werden. Anstatt die Anweisungen mehrfach im Programm zu codieren, wird die entsprechende Funktion aufgerufen, die die gewünschten Anweisungen durchführt.
Vorteile von Funktionen:
Zuerst wird - wie bei Variablen auch - der Typ der Funktion angegeben - bei einer Funktion ist damit der Rückgabetyp gemeint. Dieser kann z.B. int sein, das heißt dann, dass das return am Ende der Funktion einen Integer-Wert zurückgeben wird. Ein besonderer Rückgabetyp ist void , der besagt, dass kein Wert zurückgegeben wird.
Danach folgt der Name der Funktion mit direkt anschließenden Klammern. Diese stellen die Liste der Übergabewerte - der Parameter - dar.
Zuletzt folgt der Anweisungsteil in geschwungener Klammern. In ihm steht, was diese Funktion machen soll.
int summe() { int i=5; int j=3; int sum; sum=5+3; return sum; }
Die Parameter der Funktionen dienen dazu, Werte an Funktionen durchzureichen. Diese Möglichkeit macht die Arbeit mit Funktionen um ein Vielfaches flexibler. Um aus der aufgerufenen Funktion auf die Werte des Aufrufers zuzugreifen, könnten man natürlich auch globale Variablen verwenden. Durch die Parameter wird aber offen dokumentiert, welche Informationen eine Funktion von außen bekommt.
int summe(int i, int j) { int sum; sum=i+j; return sum; }
Es gibt jedoch auch viele Probleme, bei denen die Ausführung des Unterprogramms Ergebnisse liefert, die später im Hauptprogramm verwendet werden müssen. Dazu dienen sogenannte Ein/Ausgabeparameter. Diese Parameter werden mit einem &-Zeichen gekennzeichnet.
void summe(int i, int j, int &sum) { sum=i+j; }
Mit dem MainMenu besteht die Möglichkeit ein typisches Windows-Menü zu erstellen. Mit einem Doppelklick auf das Symbol öffnet sich ein neues Fenster. Wenn man auf eines der Vierecke klickt, kann man indem man die „Caption“ von diesem ändert, die einzelnen Menüpunkte erstellen.
Mit einem Doppelklick auf das PopupMenu-Symbol, öffnet sich ein Fenster, um die Menüpunkte festzulegen. Allerdings ist es dann nicht, wie das MainMenu, fix im Formular vorzufinden. Um es während der Laufzeit öffnen zu lassen, muss ich es z.B. bei einem Klick auf einen Button aufrufen. Aufrufen kannst du es mit: PopupMenu1→Popup(), wobei die Klammer 2 Integer-Werte verlangt. Dies ist der Ort am Bildschirm, an dem sich das Popup-Menü öffnen wird. Mit PopupMenu1→Popup(Form1→Left+Button1→Left+6,Form1→Top+Button1→Top+55) öffnet sich das Popup-Fenster z.B. unter Button1.
OnClick - einfacher Klick auf das Element (Die Maustaste muss auf dem Element betätigt und auch wieder ausgelassen werden)
OnKeyDown - drücken einer Taste, wenn das Element ausgewählt ist
OnKeyPress - drücken einer Taste, wenn das Element ausgewählt ist, mit dem Unterschied zu OnKeyDown, dass hier nur „printable keys“ funktionieren
OnKeyUp - auslassen einer Taste, wenn das Element ausgewählt ist
OnMouseActivate - Wird ausgelöst, wenn der Benutzer über einem Steuerelement eine Maustaste drückt und das übergeordnete Formular nicht aktiv ist.
OnMouseDown - Maustaste wird auf dem Element betätigt
OnMouseEnter - wenn sich der Mauszeiger über das Steuerelement bewegt
OnMouseLeave - wenn sich der Mauszeiger vom Steuerelement wegbewegt
OnMouseMove - wenn sich der Mauszeiger über dem Element bewegt
OnMouseUp - wenn sich der Mauszeiger über dem Steuerelement befindet, wenn die Maustaste gedrückt wird; wird allerdings erst ausgelöst, wenn Maustaste ausgelassen wird