Autor Beitrag
Arakis
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 344



BeitragVerfasst: Mi 12.06.02 17:43 
Einführung in Delphi -- TEIL 1 --

(* getestet und entworfen unter Delphi 6, verfasst von Addy *)

Dieses Tutorial ist dafür gedacht, Anfängern einen Einstieg in Delphi zu bieten.
Grundsätzlich gilt: Wenn du nach diesem Tutorial Gefallen an Delphi gefunden hast, solltest du ein Buch darüber kaufen. 100 Mark für eine 1000-Seiten-Lektüre sind durchaus gerechtfertigt und gut angelegt.

Jetzt geht's endlich los:
Starte Delphi. Wenn du Delphi nach dem Installieren die ersten Male aufrufst, erscheint ein Fenster, um dich zu registrieren. Wenn du dich registriert hast (oder es auf später verschoben hast), erscheint gegebenenfalls noch ein "Delphi-Direct"-Fenster, das du wegklicken kannst.
Auf dem Monitor sollten jetzt (mindestens) 4 Fenster erscheinen (nach dem 4. musst du etwas suchen, es ist in der Mitte hinter einem anderen versteckt):

1. Das Hauptfenster
Es ist das lange Fenster am oberen Rand des Bildschirms. Hier kannst du deine Programme laden, starten, kontrollieren, testen und visuell gestalten.

2 Der Objektinspektor
Das Fenster links (in Version 6 ist es das untere Fenster, das obere wird vorerst nicht besprochen), es bietet Kontrolle über die Komponenten eines Formulars, womit wir schon zu

3. kommen. Das Formular stellt ein Windows-Fenster dar (ach nee), das du mit Buttons, Labels, Menüs und vielem mehr schmücken kannst.

4. Das Quellcode-Fenster
Hier definierst du das Verhalten deiner Anwendung zur Laufzeit (Laufzeit = Zeit der Ausführung der Anwendung).

Sollte der Objektinspektor nicht zu sehen sein, holst du ihn mit F11 wieder nach oben. Wenn das Formular oder das Quellcode-Fenster fehlen, markierst du im Menü Ansicht/Units "Unit 1" und klickst auf OK. Wenn das nicht klappt ist kein Projekt (so heißt eine Anwendung oder DLL, die unter Delphi gestaltet wird) geladen. Um eines zu laden, klickst du auf Datei/Neu und wählst Anwendung aus, oder öffnest ein Projekt (Datei/öffnen). Delphi-Projekte haben .dpr als Erweiterung.
Klicke nun auf "Alles speichern" im Hauptfenster und speichere die Anwendung am besten in einem eigenen Ordner; akzeptiere vorerst die vorgeschlagenen Dateinamen.

Tipp: Mit F12 kann man zwischen dem Formular und der dazugehörigen Quellcodedatei ("Unit" genannt, doch später mehr dazu) wechseln.


Wir fangen mit einer einfachen Anwendung an. Der Anwender soll die Möglichkeit haben, einen Text sowie einen Standarttext anzugeben, und den Text zu löschen. Der Text wird auf Knopfdruck als Nachricht ausgegeben. Ferner kann der Anwender wählen, ob er die Nachricht anzeigen kann.

Zuerst brauchen wir ein "Edit-Feld". Edit-Felder sind die (meist) weißen Kasten, in denen Text eingegeben wird, die aber rechts keinen Pfeil nach unten haben, um aus einer Anzahl anderer Texte zu wählen.
In Delphi gibt es im Hauptfenster die "Komponentenpalette" im unteren linken Bereich. Sie besteht aus Registerkarten wie z.B. "Standart", "Zusätzlich" u.a. Der Umfang hängt von deiner Delphi-Version und -Edition ab. Bringe die Registerkarte "Standart" in den Vordergrund.
Auf ihr befindet sich das Edit-Feld. Es sieht aus wie ein echtes, nur kleiner, und es enthält die Buchstaben "ab". Wenn du mit der Maus über dem Edit-Feld bleibst, wird "Edit" als Beschreibung angezeigt. Klicke darauf, um es auszuwählen, und danach in das Formular an der Stelle, wo es platziert werden soll, um es abzulegen.
Das Edit-Feld erhält eine Standartgröße. Wenn du die Größe eine Steuerelements (so heißen die Dinger auf der Komponentenpalette) während des Einfügens ändern willst, musst du auf die Form klicken, die Maus gedrückt halten und ziehen. Wenn das Steuerelement die gewünschte Größe hat, lässt du los.
Wenn du die Größe zu einer beliebigen Zeit ändern willst, musst du das Steuerelement markieren (d.h. auf es klicken) und an den Rändern ziehen (genau wie bei Fenstern). Mit dem Formular geht das genauso.

Nun plazieren wir links neben das Edit-Feld ein "Label". Labels befinden sich auf der Standart-Seite der Komponentenpalette und sind durch ein schwarzes "A" dargestellt. Sie dienen lediglich zur Informationsanzeige und können vom Anwender nicht verändert werden. Jedoch können sie auf Mausklicks reagieren.
Unter das Edit-Feld kommen nun zwei "Buttons". Ein Button (Schaltfläche, Knopf) ist durch ein schwarzes "OK" auf einer kleinen Schaltfläche, also so ein Ding, auf das man klicken kann, und das dann gedrückt aussieht :wink:, gekennzeichnet. Rechts neben dem Edit-Feld und unten links kommen nun zwei weitere Buttons.
Unter die Buttons kommt nun noch eine "CheckBox". Eine CheckBox ist ein weißes Kästchen, das mit einem Häkchen versehen werden kann.

Soweit, so gut. Jetzt stehen aber auf den Buttons so hässliche Beschriftungen wie "Button1" oder im Edit-Feld "Edit1". Das hätten wir auch früher ändern können, aber das hätte wohl etwas Verwirrung gestiftet.
Markiere deshalb den Label (durch einfaches Klicken) und suche im Objektinspektor in der Registerkarte "Eigenschaften" auf der linken Seite die Eigenschaft "Caption". Ändere den dazugehörigen Wert auf der rechten Seite in "Nachricht:" (ohne Anführungszeichen).
Den Rest habe ich in einer Tabelle dargestellt. Um herauszufinden, welches Steuerelement gemeint ist, fährst du mit der Maus über ein "verdächtiges" :wink: Steuerelement. Dann werden einige Infos über die Komponente (anderer Ausdruck für Steuerelement) angezeigt, u.a. der Name (Button1: TButton...). Sollte dies nicht der Fall sein, steht der Name der Komponente in der Eigenschaft "Name" (logisch, oder :wink:) im Objektinspektor.

Hinweiß:
Die Eigenschaft "Name" darf nicht verwechselt werden mit "Caption" (Aufschrift, Beschriftung). Bevor Caption von dir geändert wird, wirken sich Änderungen von Name auch auf Caption aus, was ganz praktisch sein kann, aber nicht so gelassen werden sollte. Wenn ein Button "LoadImgBtn" heißt, soll die Aufschrift ja auch nicht "LoadImgBtn" heißen, sondern "Bild laden"


ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
  Komponente  |  Eigenschaft  |  Neuer Wert
  -----------------------------------------
  Edit1          Text            Geben Sie hier eine Nachricht ein
  Button1        Caption         Standart-Nachricht  
  Button2        Caption         Nachricht löschen
  Button3        Caption         Nachricht ausgeben
  Button4        Caption         Beenden
  CheckBox1      Caption         Nachrichten anzeigen erlaubt
                 Checked         True
  Form1          Caption         Nachrichten anzeigen


Form1 ist das Formular und wird ausgewählt, wenn man auf die graue Fläche des Formulars klickt.
Du musst evt. die Buttons, das Edit-Feld und die CheckBox etwas verlängern, damit alles zu sehen ist. Beim Label ist das (normalerweiße, lässt sich ändern) nicht nötig, er vergrößert sich automatisch.
Um ein Steuerelement auszuwählen würde es auch genügen, wenn man im Objektinspektor oben eine Komponente wählt.


So, nicht schlecht. Ohne eine Zeile Quelltext haben wir jetzt eine lauffähige Windows-Anwendung erschaffen. Starte jetzt das Programm mit F9, einem Klick auf den grünen Pfeil im Hauptfenster oder dem Befehl Start im Menü Start.
Das Programm wird compiliert (d.h. in eine für den Computer verständliche Sprache, Assembler-Bytecode, übersetzt) und gelinkt (also zusammengesetzt). Das Programm funktioniert aber nicht, die Buttons lassen sich zwar drücken, im Edit-Feld kann etwas eingegeben werden, die Größe des Fensters kann geändert werden usw., aber unser Programm macht noch nicht das, was wir uns gewünscht haben. Also müssen wir doch etwas Code einfügen, das wird auch immer so bleiben, bis Computer intelligenter sind als Menschen, und das wird (hoffentlich) noch etwas dauern.

Dazu eine kleine Einleitung in die Windows-Programmierung (interessant vor allem für umsteigende DOS-Entwickler):
Unter DOS musste die Anwendung selbst überprüfen, ob eine Taste gedrückt wurde, mit der Maus geklickt usw. Die Anwendung war das einzige Programm, das lief.
Windows umgibt eine Anwendung wie ein Mantel, und nicht das eigene Programm muss auf Mausklicks getestet, sondern Windows übernimmt das. Was passiert jetzt, wenn mit der Maus auf deine Anwendung geklickt wird?
Windows fängt den Mausklick ab und wertet aus, auf welches Fenster geklickt wurde. Nun wird eine Nachricht an das Programm, oder besser gesagt, das Fenster, geschickt, in der der Nachrichten-Typ (in diesem Fall also Mausklick links), einige andere Werte, die von der Nachricht abhängen (in diesem Fall u.a. die Mausposition in Fensterkoordinaten), die Zeit und die Maus-Cursorposition in Bildschirmkoordinaten angegeben werden.
Diese Nachricht wird an das Ende eine Nachrichtenschleife ("Message-Queue") gehängt, von deren Anfang immer eine Nachricht abgepflückt und ausgewertet wird. Dieses Prinzip, das spätere Nachrichten später behandelt werden, nennt man "lilo" (last in, last out).
Wenn die Nachricht verarbeitet wurde, wird die nächste Nachricht von der Schleife genommen und verarbeitet, bis eine bestimmte Nachricht ("WM_QUIT") gesendet wird, die das Programm dazu veranlässt, dass es beendet.
Diese Nachrichten werden auch als Ereignisse bezeichnet, daher ist Windows (und Windows-Programme) "Ereignis-orientiert".

Soviel zur Theorie. Du wirst den letzten Absatz für den Anfang getrost vergessen können, da uns Delphi das alles abnimmt. Alles was du noch tun musst, ist den Code zu definieren, der ausgeführt wird, wenn z.B. ein Button gedrückt wird. Das wäre beispielsweiße so:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
procedure TForm1.Button4Click(Sender: TObject);
begin
  ShowMessage('Button4 wurde gedrückt, Programm wird beendet');
  Application.Terminate;
end;


(Das musst du noch nicht verstehen, behalten oder eintippen, das kommt noch)
Und wie reagiert man jetzt auf so ein Ereignis? Mit Hilfe von Delphi ganz einfach: Markiere Button3 und wechsle im Objektinspektor in die Registerkarte "Ereignisse". Suche dort das Ereignis "OnClick" und doppelklicke in die rechte Spalte. Delphi wechselt nun in das Quellcode-Fenster und legt eine "Prozedur" an (was das ist, kommt später). Das sollte jetzt so aussehen:

ausblenden Delphi-Quelltext
1:
2:
3:
procedure TForm1.Button3Click(Sender: TObject);
begin
end;


Wenn du eine Prozedur hast, die leer ist (so wie diese), und dann auf "Speichern" klickst, wird diese Prozedur gelöscht, was sehr praktisch ist aber auch nerven kann. Sollte dir das versehentlich passieren, legst du einfach eine neue Prozedur an (auf dem gleichen Weg).
Jetzt muss diese Prozedur mit Code gefüllt werden. Das geht mit . . . der Tastatur :wink:. Und zwar wird der Code zwischen "begin" und "end;" geschrieben. Das sieht danach so aus:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.Button3Click(Sender: TObject);
begin
  MessageDlg(Edit1.Text, mtInformation, [mbOK], 0);
end;


Genauso legen wir für Button1 eine OnClick-Prozedur an. Der Code:

ausblenden Delphi-Quelltext
1:
Edit1.Text := 'Hallo Welt';					


(war ja nicht anders zu erwarten :wink:)
Und Button2:

ausblenden Delphi-Quelltext
1:
Edit1.Text := '';					


Für Button4:

ausblenden Delphi-Quelltext
1:
Application.Terminate					


Und ebenfalls OnClick für CheckBox1:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
if CheckBox1.Checked then
begin
  Button1.Enabled := true;
  Button2.Enabled := true;
  Button3.Enabled := true;
  Edit1.Enabled := true;
end
else
begin  
  Button1.Enabled := false;
  Button2.Enabled := false;
  Button3.Enabled := false;
  Edit1.Enabled := false;
end;


Bei erneutem Starten wirst du feststellen, das es so klappt wie wir uns das vorgestellt haben (außer du hast was falsch gemacht).
Ein paar kleine Schönheitsfehler sind noch drin, wie z.B. das Icon oben links, aber das kommt erst später.
Den Code musst du noch nicht verstehen, das lernst du später.

So weit, so gut. Wer Fragen hat, kann die gerne posten :P

Bis dann
user defined image

_________________
Mit dem Computer löst man Probleme, die man ohne ihn nicht hätte.
Entwickler von SpaceTrek: The New Empire - Siehe Hompage!
Arakis Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 344



BeitragVerfasst: Sa 29.06.02 00:42 
Titel: TEIL 2: Variablen und einfache Operationen 1
Einführung in Delphi -- TEIL 2: Variablen und einfache Operationen 1 --

Heute lernen wir, was Variablen sind, wie man sie benutzt und anlegt.

Also was ist eine Variable?
Wenn du in Mathe etwas aufgepasst hast, hast du sicher schon von Variablen gehört. Diese hießen dann meistens "x", "y", "z", "a", "b", "c" oder "n".
Wenn eine Variable "deklariert" wird (d.h. wenn Delphi gesagt wird, dass der Bezeichner "EineVariable" eine Variable ist und auch als solche behandelt werden soll), wird Platz im Arbeitsspeicher reserviert, soviel, wie gebraucht wird. Für eine Variable, die ganze Zahlen von -2147483648 bis +2147483647 aufnehmen kann, werden 4 Byte gebraucht (also garnichts im Vergleich zu den über 64 MegaByte heutiger Computer).
Und da haben wir auch schon das erste Problem: in einer Programmiersprache wie Delphi oder C(++) musst du vorher wissen, welche Aufgaben deine Variable übernehmen soll (zwei Auswege lernst du später kennen). Du musst also wissen, welchen Wertebereich deine Variable haben soll, und ob sie mit Dezimalzahlen umgehen kann. sollte letzteres zutreffen, musst du dir Gedanken machen, wie genau sie sein soll.

Das klingt jetzt sehr kompliziert und aufwendig, aber mit etwas Übung (und einer sauberen Vorstellung, wofür die Variable da ist), weiß man im vorraus, welcher (Variablen)Type der richtige ist.

Mit den bisher vorgestellten Typen können wir aber nur mit Zahlen umgehen. Was, wenn wir einzelne Buchstaben oder ganze Ketten ("Strings") davon speichern und bearbeiten wollen?
Dafür sind die Typen "Char" und "String" da. Ersteres kann je einen Buchstaben speichern, während zweiteres beliebig viele davon hintereinander darstellen kann.

Hinweiß:
Als ich von "Buchstaben" redete, so meinte ich das, was man sich unter einem "Buchstaben" vorstellt, aber auch "Text-Zahlen" wie "5" und andere Zeichen wie "!", "(", "^", "°" oder das Anführungszeichen selbst (") u.v.m. Auch das Leerzeichen oder die "neue Zeile"-Zeichen gehören dazu. Deshalb werde ich in Zukunft nicht mehr "Buchstabe", sondern "Zeichen" (=Character) sagen


Wenn man Zahlen auch in Strings und Chars speichern kann, warum gibt es dann die Variablen-Typen, die ich oben beschrieben habe? Schließlich kann ein String über 2 Milliarden Zeichen aufnehmen (wenn genug Speicher und Geduld des Benutzers vorhanden sind :wink:), man könnte also auch ohne Probleme die Zahlen "5346823168321654684321684654131" oder "14684321.54687654*10^4684321" darstellen (123*10^5 schreibt man in Programmiersprachen als 123E5).
Ich würde jetzt gerne sagen: "Ganz einfach...". Aber so einfach ist es für einen Anfänger wohl garnicht.
Alle Variablen werden als Zahl gespeichert, eine Variable der Größe 1 Byte kann Zahlenwerte von 0 bis 255 annehmen. Oder von -128 bis 127. Es kommt also auf die Interpretation an. Ein Char (das 1 Byte belegt), kann 256 verschiedene Zeichen (oder besser gesagt: Zustände) annehmen (aber immer nur eines angenommen haben). Es wird aber genauso gespeichert wie der Delphi-Datentyp "Byte" (der, genau, 1 Byte belegt).
Wie weiß der Computer jetzt, ob er den Speicher, der von der Variable belegt ist, als Zahl von -128 bis 127, als Zahl von 0 bis 255 oder als Zeichen, das u.a. Buchstaben annehmen kann, behandeln soll? Die Antwort lautet schlicht und einfach: Gar nicht. Denn das sagt ihm das Programm, etwa so (stark vereinfacht :wink:):


ausblenden Quelltext
1:
Nimm den Speicher an dieser und jener Stelleund addiere 5 zu ihm, und zwar so,  als ob es eine Zahl wäre, die von -128 bis 127 reicht.Nimm jetzt den Speicher von hier und dort,betrachte ihn als Gleitkommazahl mit doppelter Genauigkeit  und multipliziere ihn mit 10.Lade jetzt nochmal den Speicher von dieser und jener Stelle,betrachte ihn als Zahl von -128 bis 127und subtrahiere ihn von dem Speicher von hier und dort,  den du als Gleitkommazahl mit doppelter Genauigkeit bearbeitest.Speichere das Ergebnis hier und dort als Gleitkommazahl mit der höchsten Genauigkeit.					



Naja, so ähnlich zumindest :wink:
Hinweiß für C(++)-Programmierer:
Object-Pascal, worauf Delphi aufbaut, ist viel strenger "getypt" als C oder C++. Ein "Byte" kann nur Zahlen von 0 bis 255 aufnehmen, für Zeichen wird der Typ "Char" benötigt.
Genauso stehts um boolesche Werte (wahr oder falsch), die Integer (= "ganze Zahl") sind. In Delphi gibt es dafür den Typ "Boolean", der nur die Werte "true" (wahr) und "false" (falsch) annehmen kann. In Delphi liefert ein Wahrheitsausdruck, wie z.B. x = 5 (enthält die Variable x den Wert 5 ?) oder Count < x (ist die Variable Count kleiner als die Variable x ?), einen booleschen Wert, in C(++) einen Ganzzahl-Wert.


Weitere einfache Datentypen:
Wenn man nur zwei Möglichkeiten speichern möchte (also "ja" oder "nein"), nimmt man den Typ "Boolean". Er ist standartmäßig ein Byte groß. Auch wenn in Delphi die möglichen Werte für diesen Typ auf zwei begrenzt sind ("true", wahr oder "false", falsch), kann er doch 256 verschiedene Werte annehmen. True entspricht nämlich 1 und false 0.
Was, wenn ich aber einer booleschen Variable 2 zuweisen will? Ganz einfach: das geht nicht (direkt). Auch wenn man der Variable 1 zuweisen will, meckert Delphi, den der Typ Boolean darf nur die Werte true und false annehmen.
Was aber jetzt, wenn ich auf einen indirekten Weg einer Boolean-Variable den Wert 2 oder 198 zugewiesen habe? Kein Grund zur Panik: Der Computer behandelt eigentlich nur 0 als false, alles andere, also von 1 bis irgendwas, wird wie true behandelt.

Zur Bennenung von Variablen:
Variablen müssen mit einem Buchstaben ("a" bis "z", "A" bis "Z") oder einem Unterstrich ("_") beginnen, danach dürfen aber Buchstaben, Unterstriche und Ziffern folgen, jedoch keine Leerzeichen und keine Sonderzeichen, wie "ä", "ß", "!", "+" oder ",".
Hier einige Beispiele für gültige Variablennamen:
abc123
_3
_a3a__g
MeinHausMeinAutoMeinBoot
lkfhjglekrjhfv
________
IchBinUeber3MeterGross

Und hier ein paar ungültige Namen:
3ksjbhf (fängt mit einer Zahl an)
_ß_ (Sonderzeichen)
kjdfv e (Leerzeichen)
Hallöchen (Sonderzeichen)
décider (Sonderzeichen)

Desweiteren unterscheidet Delphi nicht zwischen Groß- und Kleinschreibung. Die folgenden Variablennamen sind also identisch (für Delphi):
Kamel
kAMEL
KaMeL
kameL

Auch müssen Variablen nicht englische (oder überhaupt sinnvolle) Namen haben. Allerdings sind alle Delphi-Befehle englisch, und wenn dazwischen "AnzahlderBratwuerste" steht, sieht das nicht sehr elegant aus.

Wenn Variablennamen zu lang sind, sollte man sie abkürzen:
HasSystemBeenShutdownByUserOrByProgram könnte dann zu ShutdownUserProg, aber besser nicht zu HSBSBUOBP werden, in einer Woche wüsstest du dann nicht mehr, was gemeint ist, andere Programmierer schon garnicht.
Deshalb immer aussagekräftige Namen verwenden, keine kryptischen Abkürzungen.


So, genug Theorie.
Lege ein neues Projekt an und speichere es. Dann platzierst du zwei Edit-Felder und einen Button.
Der Button soll den Namen ("Name"-Eigenschaft) "TransferBtn" (natürlich ohne die Anführungszeichen) haben. Das erste Edit-Feld nennst du "SourceEdit" und das zweite "DestEdit". Weitere Werte:


ausblenden Quelltext
1:
2:
3:
4:
5:
6:
Komponente  |  Eigenschaft  |  Neuer Wert
-----------------------------------------
SourceEdit    Text            'Schreiben sie hier was rein.'    (die Apostrophe natürlich wieder weglassen,    sie dienen zur Kennzeichnung eines Strings)
DestEdit      Text            ''
              ReadOnly        True
TransferBtn   Caption         'Transfer'


Nun legst du eine OnClick-Prozedur für den Button an und schreibst zwischen "procedure TForm1.TransferBtnClick(Sender: TObject);" und dem "begin" folgendes:


ausblenden Quelltext
1:
var  Temp: string;					



Was bedeutet das?
Das var sagt Delphi, dass jetzt eine oder mehrere Variablen deklariert werden.
"Temp" ist der Name der Variable, der Doppelpunkt danach besagt: "Diese Variable ist von dem Typ, der jetzt folgt."
"string" ist der Typ, den die Variable haben soll, also eine beliebig lange Kette von beliebigen Zeichen.
Das Semikolon (Strichpunkt) bedeutet, dass die Deklaration dieser Variable erstmal beendet ist.
Man hätte auch


ausblenden Quelltext
1:
var   Temp            :string;					



schreiben können, da Delphi "Whitespace-Zeichen" (also Leerzeichen, Zeilenumbrüche, Tabulatoren) weitgehend ignoriert.
Das hingegen wäre unzulässig:

ausblenden Quelltext
1:
varTemp: string;					



da Delphi nicht weiß, das "var" nicht zur Variable gehören soll, sondern eine Variablendeklaration einleitet soll. So wäre es wieder korrekt:

ausblenden Quelltext
1:
var varTemp: string;					


Man kann auch mehrere Variablen gleichen Typs auf einmal deklarieren:


ausblenden Quelltext
1:
var  Temp, NochEinString: string;					


Zwischen "begin" und "end" kommt jetzt folgender Code:


ausblenden Quelltext
1:
Temp := SourceEdit.Text;Temp := Temp + '; nächster Text: ';DestEdit.Text := DestEdit.Text + Temp;					


In der ersten Zeile wird Temp der Text, der in SourceEdit steht, zugewiesen, d.h. Temp hat jetzt genau den gleichen Wert wie die Text-Eigenschaft von SourceEdit, die ebenfalls ein String ist.
Danach wird an den Wert von Temp der String '; nächster Text: ' gehängt, und das Ergebnis an Temp zugewiesen.
Zuletzt wird an die Text-Eigenschaft von DestEdit Temp angehängt und das Ergebnis DestEdit.Text zugewiesen.

Das ganze hätte man auch so (ohne Variable) machen können, allerdings hättet ihr dann ja nichts gelernt:


ausblenden Quelltext
1:
Destedit.Text := DestEdit.Text + SourceEdit.Text + '; nächster Text: ';					


So, jetzt zerlegen wir mal den obigen Code:
Das Zuweisungszeichen := weist der Variable (ist eigentlich keine richtige Variable, aber das ist eine andere Geschichte) der linken Seite den Wert der rechten Seite zu. Und zwar wird erst der rechte Ausdruck ausgewertet und dann erst der linken Seite zugewiesen.
Auf der linken Seite darf kein konstanter Ausdruck stehen:
5 := Variable;
ist nicht zulässig, denn 5 kann man nichts zuweisen (logisch, oder?).

Auf der linken Seite muss also etwas stehen, dem etwas zugewiesen werden kann, ein sog. "Links-Wert" (oder L-Wert).
Rechts kann entweder ein konstanter Ausdruck (z.B. "5", "3 * 4", "1 + 2") oder ein L-Wert stehen. Auch komplexere Ausdrücke wie
5 * Number1 + Number2 - (2 / Number3)
sind R(echts)-Werte, aber keine L-Werte.

Hinweiß:
5
ANumber
EineZahl + 5
(4 * 3) / 7
5 = x
Count < x
und vieles mehr, das du später kennenlernen wirst, werden "Ausdrücke" genannt.
Ausdrücke sind also Kombinationen aus Zahlen und Zeichen, die einen Wert, egal welchen Typs, ergeben. Dieser Wert kann konstant (z.B. 5 * 3) oder variabel (z.B. Count + 4) sein.


Der Punkt . trennt das Objekt (was ein Objekt ist kommt später. Stell es dir einfach als das Edit-Feld vor, das es ja auch ist, mit dem etwas machen kann und das Eigenschaften hat) SourceEdit von seiner Eigenschaft Text.
SourceEdit.Text
lässt sich etwa so ausdrücken:


ausblenden Quelltext
1:
Nimm vom Edit-Feld "SourceEdit" die Eigenschaft "Text"					


Das Semikolon ; bedeutet Delphi, das diese Anweisung beendet ist und eine nächste folgt.
Wenn man also zwei Anweisungen hat,
x := 5 * 3
und
y := 10 - z
dann werden sie so geschrieben:


ausblenden Quelltext
1:
x := 5 * 3;y := 10 - z;					


Die Apostrophe ' beginnen und beenden den String, so wie in C die Anführungszeichen.
Wenn man also den String Hallo Welt! für Delphi als String kennzeichnen will, schreibt man das so:


ausblenden Quelltext
1:
'Hallo Welt!'					


Und wenn man ein Apostroph wie in Wie geht's einfügen will? Na probiers mal mit:


ausblenden Quelltext
1:
'''					



Geht nicht - Delphi meckert rum.
Die Erklärung: der erste Apostroph eröffnet den String, soviel ist klar. Jetzt müsste man allerdings wissen, dass Delphi zwei Apostrophe hintereinander in einem bereits eröffneten String als ein Apostroph interpretiert.
Also so kann man ein Apostroph darstellen: mit zwei Apostrophen hintereinander.
Und warum meckert Delphi jetzt? Dafür müsste man noch wissen, dass in Delphi ein String nicht über das Zeilenende hinausgehen darf, folgende Anweisung ist daher ungültig:

ausblenden Quelltext
1:
StringVar := 'HalloWelt!'					


Jetzt haben wir aber Temp + '; nächster Text: ' stehen, werden jetzt zwei Strings addiert oder was?
Natürlich steht das Plus normalerweiße für eine Addition oder als Vorzeichen, aber im Zusammenhang mit Strings bedeutet es, dass der zweite String an den ersten gehängt wird, also ; nächster Text: hinter Temp.
Und so kann man auch einen String über das Zeilenende hinaus deklarieren:


ausblenden Quelltext
1:
StringVar := 'Hallo ' +'Welt!'					


Einen Zeilenumbruch erhält man trotzdem nicht, das geht so:


ausblenden Quelltext
1:
StringVar := 'Dies ist die erste Zeile.' + #13#10 + 'Und das die nächste.' +  #13#10 + 'Diese hier ist die letzte.'					



Indem man #13#10 an den String hängt, bewirkt man einen Zeilenumbruch.
Hinweis:
Das #xxx, wenn es sich nicht in einem String befindet, bewirkt, das ein Char mit dem Charcode xxx eingefügt wird.
Man könnte auch Buchstaben als Charcode eingeben, A wäre #65, B #66 usw. Da dies aber viel unübersichtlicher und länger ist, schreibt man stattdessen 'A' oder 'B'.


In der dritten Zeile kommt nichts neues, nur soviel: zu der Text-Eigenschaft von DestEdit wird Temp hinzugefügt und der resultierende String an die Text-Eigenschaft von DestEdit zugewiesen.


So, das wars fürs erste mit Variablen im allgemeinen und Strings im speziellen.
Ihr solltet jetzt wissen, was ein String ist, wozu er gut ist und wie man ihn deklariert, eine Wert zuweist und einen String anfügt.

Glaubt jetzt bloß nicht, das wäre alles, was es zu Strings zu sagen gibt. :wink:

Bis dann
user defined image

_________________
Mit dem Computer löst man Probleme, die man ohne ihn nicht hätte.
Entwickler von SpaceTrek: The New Empire - Siehe Hompage!
Arakis Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 344



BeitragVerfasst: So 28.07.02 18:23 
Titel: TEIL 3: Variablen und einfache Operationen 2
Einführung in Delphi -- TEIL 3: Variablen und einfache Operationen 2 --

Heute erkläre ich euch Ganzzahlen und Wahrheitswerte.

Im letzten Teil habt ihr Strings kennen gelernt, heute lernt ihr einen (bzw. mehrere) Typ kennen, mit denen Rechenoperation möglich sind, und einen, mit dem man Wahrheitswerte (wahr, falsch) speichern kann.


Es gibt mehrere Ganzzahltypen, hier eine Zusammenfassung der Wertebereiche:


ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
  Name      |  Größe  |  Wertebereich
---------------------------------------
  ShortInt     1 Byte    -128 bis 127
  Byte         1 Byte    0 bis 255
  SmallInt     2 Byte    -32768 bis 32767
  Word         2 Byte    0 bis 65536
  LongInt      4 Byte    -2147483648 bis 2147483647
  LongWord     4 Byte    0 bis 4294967295
  Integer      4 Byte    -2147483648 bis 2147483647
  Cardinal     4 Byte    0 bis 4294967295
  Int64        8 Byte    -2^63 (-9.22*10^18) bis 2^63 - 1 (9.22*10^18)



Es ist dir sicher aufgefallen, das LongInt den gleichen Wertebereich wie Integer und LongWord den gleichen wie Cardinal hat. Warum gibt es dann aber zwei gleiche Datentypen?
Wenn jetzt eine Delphi-Version für einen 64-Bit-Prozessor herauskommt (die dann Anwendungen speziell für 64-Bit erzeugt), wird Integer als 8-Byte-Zahl mit Vorzeichen (also wie Int64) und Cardinal als 8-Byte-Zahl ohne Vorzeichen behandelt. LongInt und LongWord werden aber weiterhin 4 Byte haben. Dies ist jetzt kein Grund, nur noch LongInt/-Word zu nehmen, selbst für den Fall, das du deine Anwendung auf ein 64-Bit-System importieren willst, musst du nur in folgenden Fällen bei 4-Byte bleiben:
- Deine Anwendung ist speziell auf 4-Byte abgestimmt (was man möglichst vermeiden sollte)
- Deine Anwendung öffnet Dateien, die mit einer 4-Byte-Anwendung gespeichert wurden

Man stellt sich beim Variablendeklarieren die Frage, welchen (Ganzzahl)Datentyp man denn benutzt. Dazu kann ich nur sagen:
- Wenn aus symbolischen Gründen (z.B. RGB-Farbwerte) oder wenn es sein muss -> bestimmter Datentyp (bei RGB-Farbwerten Byte)
- Wenn aus symbolischen Gründen nur Zahlen größer 0 möglich sein dürfen -> Cardinal
- Wenn Integer und Cardinal zu klein sind -> Int64
- In allen anderen Fällen -> Integer

Das hat natürlich auch Grenzen. Wenn ein Gitter (Feld, dazu mehr später) mit einer Größe von 1024 * 1024 benutzt wird, jedes Gitterfeld aber nur 200 verschiedene Werte annehmen muss, ist es nicht gerechtfertigt, Integer zu nehmen und 4 MB zu belegen, sondern es sollte Byte (oder ShortInt) benutzt und nur 1 MB belegt werden.
Ansonsten kann aber getrost Integer genommen werden, da, wie schon erwähnt, 4 Byte bei 64 MB RAM nicht ins Gewicht fallen und, wichtiger, 32-Bit-Werte auf einer 32-Bit-CPU am schnellsten verarbeitet werden.


Jetzt probieren wir das Ganze mal aus.
Neues Projekt, speichern, ein Button und ein Edit-Feld.

In die OnClick-Ereignis-Prozedur von Button1 kommt folgendes (zwischen procedure und begin):


ausblenden Quelltext
1:
var  Number: Integer					


und nach begin

ausblenden Quelltext
1:
2:
  Number := 5;
  Edit1.Text := Number;


Durch einen Druck auf F9 starten wir jetzt die Anwendung - geht aber nicht, Compiler-Fehler. Der Grund?
Die Text-Eigenschaft von Edit1 ist vom Typ String, Number aber Integer. Diese beiden Typen kann man nicht ohne weiteres kombinieren oder zuweisen.
Der Ausweg ist einfach: Delphi wird mit einer Funktion IntToStr (was eine Funtion ist, kommt später) geliefert, die einen Ganzzahl-Ausdruck entgegennimmt und einen String zurückliefert. Du musst die zweite Zeile also durch

ausblenden Quelltext
1:
Edit1.Text := IntToStr(Number);					


ersetzen und es wird gehen.
Um einen Integer (wenn ich Integer sage, meine ich meistens Ganzzahlen) aus einem String zu bekommen, benutzt man folgendes:

ausblenden Quelltext
1:
2:
Number := StrToInt(EinString);
Number1 := StrToInt('-654');


Wenn der String keine richtige Ganzzahl (wie z.B. '548.4' oder '10E5') enthält, tritt eine Fehlermeldung auf. Gegenmaßnahmen werden wir später kennen lernen.
Operationen mit Integern gehen wie gewohnt:
Addition:


ausblenden Quelltext
1:
2:
3:
Number1 := Number + 5;
Number := 5 + Number1;
Number3 := Number1 + Number2 + 548617;


Subtraktion:

ausblenden Quelltext
1:
2:
3:
Number := 5 - 3;
Number1 := Number - Number1;
Number2 := 7654 - Number875;


Multiplikation:

ausblenden Quelltext
1:
2:
3:
Number := Number * 8;
Number := Number * Number1;
Number3 := 898 * 65;


Die Integer-Division ist etwas anders:

ausblenden Quelltext
1:
2:
3:
Number := 5 div 2;
Number := Number1 div Number;
Number5 := 2 div Number4;


Die Ganzzahl-Division funktioniert so, wie man es in der Grundschule lernt, mit Rest. 11 durch 4 ergibt also 2 Rest 3. Den Rest einer Division bekommt man so heraus:

ausblenden Quelltext
1:
2:
3:
Number := 11 mod 4;
Number1 := 5 mod Number;
Number5 := Number1 mod Number;

Hinweiß:
Delphi wertet Ganzzahl-Ausdrücke wie in der Mathematik aus, also Punkt-vor-Strich, Klammern, von rechts nach links. Der folgende Ausdruck ergibt also, wie erwartet, 22:
5 * 4 + 20 div (9 + 10) + 20 mod (9 + 10)

Delphi wertet konstante Ausdrücke, wie der darüber liegende, beim Compilieren aus und ersetzt sie durch ihren Wert, also in diesem Fall 22.
Folgender Ausdruck ist kein konstanter Ausdruck:
EineVariable + 4 * 3
da der Wert von EineVariable zur Compilierzeit noch nicht bekannt ist. Jedoch ist 4 * 3 konstant und wird durch 12 ersetzt.



Man kann (Ganz)Zahlen auch als Hexadezimalzahlen ausdrücken. Für alle, die nicht wissen, was das ist:

Unser normales Zahlensystem basiert auf der Zahl 10. Das Hexadezimalsystem basiert aber auf 16. Da es aber nur 10 Ziffern (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) gibt, braucht man noch 6 Buchstaben (a, b, c, d, e, f, werden meistens großgeschrieben).
Wie rechnet man nun eine Hexadezimalzahl in eine Dezimalzahl um?
Die Zahl lautet C6. Die zweite Stelle von rechts ("Sechzehner") hat (dezimal) den Wert 16^1. An dieser Stelle steht nun ein C, also wird der Wert der Stelle mit (dezimal) 12 multipliziert.
Die erste Stelle ("Einer") hat den Wert 16^0 (also 1, nicht 0). An dieser stelle steht eine 6, also wird der Wert mit 6 multipliziert.
Der Term für diese Zahl:
12 * 16^1 + 6 * 16^0 = 198
Und noch ein Beispiel: FFA9
Term:
15 * 16^3 + 15 * 16^2 + 10 * 16^1 + 9 * 16^0 = 65449

Von dezimal nach hexadezimal geht es etwas anders:
Wie nehmen wieder die Zahl 198 und machen es wie beim schriftlichen Dividieren (kann das noch irgendeiner ). Also, wie oft passt 16^2 rein? Garnicht. 16^1 passt 12 mal rein, also schreiben wir ein C (den 12 dezimal entspricht C hexadezimal) und subtrahieren 12 * 16^1 von 198, das ergibt 6. Wie oft geht 16^0 in 6? Richtig, sechsmal, also schreiben wir eine 6 => C6.
Noch ein Beispiel: 5199
16^3 passt einmal, 16^2 viermal, 16^1 auch viermal und 16^0 15mal => 144F

Solltest du das immer noch nicht verstanden haben: Der Windows-Rechner rechnet auch dezimal in hexadezimal um und umgekehrt.

Und so sieht eine Hexadezimal-Zahl in Delphi aus:


ausblenden Quelltext
1:
aInteger := $F173C2;					


Also das Dollarzeichen $ und dahinter die Hex-Ziffern.
Wahrheitswerte sind Ausdrücke, die entweder wahr (true) wie 5 > 4 oder falsch (false) wie 5 < 4 sein können.
Ein Wahrheitswert ist vom Typ Boolean, der 1 Byte groß ist und dem nur die Werte false und true zugewiesen werden können (mehr dazu kam schon in Teil 2).

Beispiele für einen Wahrheitswert:


ausblenden Quelltext
1:
2:
3:
eineBooleanVar := 5 > 4;
eineBooleanVar := Count <= 4;
eineBooleanVar := eineAndereBooleanVar = 5;


Als Vergleichsoperatoren gibt es < (kleiner als), > (größer als), <= (kleiner/gleich als), >= (größer/gleich als), = (gleichgroß wie) und <> (ungleich).
Ausdrücke mit Vergleichsoperatoren liefern einen booleschen Wert zurück.
Links und rechts der Operatoren müssen entweder Ganzzahlen, Gleitkomma-Zahlen oder Strings stehen. Von der letzten Möglichkeit rate ich ab, da es bessere und elegantere Wege dafür gibt. Beispielsweiße wäre 'A' kleiner als 'a' - Auslegungssache.
Es ist nicht erlaubt, wie in Mathe mehrere Vergleichsoperatoren hintereinanderzustellen:

ausblenden Quelltext
1:
ErgebnisIstInLoesungsmenge := 5 < x < 10;					

Wenn man jetzt aber zwei boolesche Werte vergleichen will, z.B. ob beide oder nur einer true ist?
Dazu gibt es die Operatoren and, or, xor, not.
Beispiele:


ausblenden Quelltext
1:
2:
3:
4:
eineBooleanVar := (4 > 3) and IsBigger;
eineBooleanVar := eineAndereBooleanVar or ((Count > 5) and (Count < 10));
eineBooleanVar := IsBigger xor true;
eineBooleanVar := not eineBooleanVar;


Was bewirken jetzt diese Operatoren?
And überprüft, ob die Ausdrücke auf beiden Seiten true ergeben und gibt in diesem Fall true zurück, ansonsten false. Die folgende Tabelle veranschaulicht die Möglichkeiten:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
  Links  |  Rechts  | Ergebnis
  ----------------------------
  true      true      true
  true      false     false
  false     true      false
  false     false     false

Or liefert nur true zurück, wenn auf einer oder auf beiden Seiten true (oder ein wahrer Ausdruck) steht:


ausblenden Quelltext
1:
2:
3:
4:
5:
6:
  Links  |  Rechts  | Ergebnis
  ----------------------------
  true      true      true
  true      false     true
  false     true      true
  false     false     false

Xor ergibt nur true, wenn auf genau einer Seite true (oder ein wahrer Ausdruck) steht:


ausblenden Quelltext
1:
2:
3:
4:
5:
6:
  Links  |  Rechts  | Ergebnis
  ----------------------------
  true      true      false
  true      false     true
  false     true      true
  false     false     false

Und not vertauscht einfach die Werte, aus true wird false und umgekehrt:


ausblenden Quelltext
1:
2:
3:
4:
  Rechts  | Ergebnis
  ----------------------------
  false     true
  true      false

So können wir jetzt auch das Problem 5 < x < 10 lösen:


ausblenden Quelltext
1:
ErgebnisIstInLoesungsmenge := (5 < x) and (x < 10);					


Du wirst schon sehr bald die Ausführung von Code von einer Bedingung abhängig machen wollen. Dafür gibt es die if-Bedingungen.
Die Syntax (Syntax = grundsätzlicher Aufbau):


if Wahrheitsausdruck then
begin

Code, der ausgeführt wird, wenn Wahrheitsausdruck true ergibt
end;


Das begin und end; wird nur gebraucht, wenn mehrere Befehle ausgeführt werden sollen:


ausblenden Quelltext
1:
2:
3:
4:
if (5 > Count) then
begin  Var1 := true;
  Var2 := false;
end;


Hier wird es nicht gebraucht:

ausblenden Quelltext
1:
if (Size < 7) then  Var1 := true;					

Wenn man für den Fall, dass der Ausdruck zwischen if und then false ergibt, ebenfalls Code ausführen soll, benutzt man else:


ausblenden Quelltext
1:
2:
if (5 < Count) then  Var1 := true
else  Var2 := false;

Die Regeln für begin und end sind die gleichen wie nach if.

Achtung:
Vor else darf kein Semikolon sein
.

Wenn der Code-Teil hinter if leer sein soll, gibt es zwei Möglichkeiten:
1. symbolische Variante:


ausblenden Quelltext
1:
2:
if (Zahl < 5) then
else  Var2 := true;

2. normale Variante:


ausblenden Quelltext
1:
if (Zahl < 5) = false then  Var2 := true;					

oder
ausblenden Quelltext
1:
if not (Zahl < 5) then  Var2 := true;					


Es gibt von Delphi keine direkte Funktion, um einen Boolean in einen String umzuwandeln, das kannst du mittlerweile aber selbst:


ausblenden Quelltext
1:
2:
if BoolVar then  StringVar := 'true'
else  StringVar := 'false';


Und von String in Boolean:

ausblenden Quelltext
1:
2:
if StringVar = 'true' then  BoolVar := true
else  BoolVar := false;


Wenn StringVar jetzt aber 'True' oder 'TRUE' ist, kommt trotzdem false raus, denn 'true' ist für Delphi definitiv nicht gleich 'True'. Ich erwähnte vorhin, für Delphi gäbe es keinen Unterschied zwischen Kamel und kAMEl. Das stimmt aber nur soweit es die Bezeichner (wie z.B. Variablen) angeht. Denn Strings werden Zeichen für Zeichen verglichen, und 'A' ist im Speicher nicht das gleiche wie 'a' (das ist auch gut so :D ). Es gibt jedoch Funktionen, die zwei Strings, ohne auf Groß/Kleinschreibung zu achten, vergleichen.
Hier ein Ausweg:

ausblenden Quelltext
1:
2:
if AnsiUpperCase(StringVar) = 'TRUE' then  BoolVar := true
else  BoolVar := false;


So, ich denke, das reicht erstmal zu Ganzzahlen und booleschen Werten. In Teil 4 erwarten euch Gleitkommazahlen.

Bis dann
user defined image

_________________
Mit dem Computer löst man Probleme, die man ohne ihn nicht hätte.
Entwickler von SpaceTrek: The New Empire - Siehe Hompage!
Sana
Hält's aus hier
Beiträge: 11



BeitragVerfasst: Mo 22.11.04 15:49 
eine frage

das was für delphi 6 gilt gilt das auch für delphi 5??? oda ist es unterscheidlich

bybe bye
Udontknow
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2596

Win7
D2006 WIN32, .NET (C#)
BeitragVerfasst: Mo 22.11.04 15:55 
Die hier vermittelten Grundlagen dürften eigentlich 1:1 auch für Delphi 5 übernommen werden können.

Cu,
Udontknow
Benutzername
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 210

Win XP Pro
Delphi 7 PE, D2005 Prof. SSL
BeitragVerfasst: Mo 22.11.04 15:59 
StandarD ;-)
Sana
Hält's aus hier
Beiträge: 11



BeitragVerfasst: Mo 22.11.04 20:30 
gzut dann lern ich mal ein nbisschen von hier tschüss
j-a-n@gmx.de
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 84


Delphi 7
BeitragVerfasst: Do 09.12.04 11:04 
Titel: Inhaltsverzeichnis?
Klasse Tutorial, vielen Dank für Deine Mühe.
Aber ein Inhaltsverzeichnis wäre schon ne Erleichterung.
DieRuekkehr
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 30

win xp

BeitragVerfasst: Mi 02.02.05 16:08 
gehts auch noch weiter? oder sind nur diese 3 projecte beschrieben?

hoffe es kommen immer wieder neue rein!!

Danke für eure mühe!
F34r0fTh3D4rk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5284
Erhaltene Danke: 27

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: Mi 02.02.05 16:20 
da kriegt wohl jemand net genug.

jetzt wo ichs sehe nettes tutorial, ist auch mal zur auffrischung ganz gut, vor allem das mit den hex zahlen, da wusste ich auch noch nicht so recht bescheid, aber das immer rechnen lassen ^^