Autor Beitrag
MK777
Hält's aus hier
Beiträge: 2



BeitragVerfasst: Sa 06.11.10 00:22 
Hallo, ich schreibe am nächsten Montag eine Kursarbeit in Informatik. Leider verstehe ich manche Sachen nicht ganz und hoffe, dass ihr mir helfen könnt.

1.) Wenn ich eine Prozedur oder Funktion programmieren möchte, muss ich dabei betsimmte Variablen aus dem Hauptprogramm "importieren" (damit meine ich die erste Zeile der Prozedur).
Bei einer Variable gibt es zwei Möglichkeiteb:
ausblenden Delphi-Quelltext
1:
procedure bsp(x: integer);					

und
ausblenden Delphi-Quelltext
1:
procedure bsp(var x: integer);					

Wo ist der Unterschied?

Bei zwei Variablen gibt es jedoch vier Möglichkeiten:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure bsp(x: integer; y: integer);

procedure bsp(x: integer; var y: integer);

procedure bsp(x,y: integer);

procedure bsp(x: integer);
var y: integer;


Kann mir jemand den Unterschied erklären und wie sich jeweils die einzelnen Konstellationen auf die Prozedur auswirken?


Des Weiteren habe ich hier einen Ausschnitt aus einem Programm, dass aus einem Wort ein Palindrom erstellt:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
var eingabe, ausgabe: string;

procedure mach_es(position: integer);
var buchstabe: char;
begin
  buchstabe := eingabe[position];
  ausgeben := ausgabe + buchstabe;
  if position < length(eingabe)
  then mach_es(position + 1);
  ausgabe := ausgabe + buchstabe;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  label2.caption := ' ':
  eingabe := Form1.Edit1.Text;
  ausgabe := ' ';
  mach_es(1);
  label2.caption := ausgabe;
end;


Sobald die Prozedur "mach_es" aufgerufen wird, bekommt die Variable "position" den Wert 1.
Doch dann steht da "buchstabe := eingabe[position];". Ich habe keine Ahnung was hier passiert. :shock: Was bedeuten die eckigen Klammern?
Ich würde mich freuen, wenn mir jemand das Programm in einfachen Schritten erklären könnte.
Leider bin totaler Anfänger und blicke noch bie vielen Sachen nicht so richtig durch. :oops:
Bitte um Hilfe. Vielen Dank im Voraus für die Mühe.

Moderiert von user profile iconMartok: Delphi-Tags gesetzt
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Sa 06.11.10 01:38 
Bitte immer nur eine Frage pro Thread. Ich beantworte daher hier nur die erste. Es wird sonst zu unübersichtlich. Auch solltest Du für Code-Abschnitte den Delphi-Tag nutzen, da es dadurch wesentlich lesbarer wird.

Okay. Zu den Variablen sollte man wissen, dass Du in deinen Beispielen gerade Variablen (lokale, globale) und Parameter durcheinander gehauen hast. Während Variablen Werte speichern, werden mit Parametern Werte an andere Programmteile übergeben, damit diese etwas mit diesen anstellen können. Etwa so wie das x bei einer quadratischen Funktion f(x)=x^2-1 an die Funktion f übergeben wird.

Je nach Notationsort legst Du in deinem Programm einen Parameter oder eine Variable an:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
unit Foo;

interface

{...}

var
    InterfaceGlobal: Integer;

{...}

implementation

{...}

var
    ImplementationGlobal: Integer;

{...}

procedure Bar(StdParameter:Integer; const ConstParameter: integer; var VarParameter: Integer; out OutParameter: Integer);
var
    LocalVariable: Integer;
begin
    LocalVariable := StdParameter + ConstParameter;
    StdParameter := StdParameter + 1;
    VarParameter := StdParameter + VarParameter;
    OutParameter := VarParameter + LocalVariable;
end;

{...}

end.


InterfaceGlobal: Globale Variable, die auch in fremden Units überall sichtbar ist, wenn diese Unit eingebunden wird
ImplementationGlobal: Überall in der aktuellen Unit sichtbar
LocalVariable: Nur innerhalb von Bar sichtbar.

Zu den Parameter-Typen (Nicht wundern, dass Du viele noch nicht kennen wirst):
StdParameter: Veränderbar, aber Änderungen nur lokal in Bar sichtbar
ConstParameter: Konstant und Wert auch in Bar nicht veränderbar
VarParameter: Wie Std, jedoch werden Änderungen auch außerhalb von Bar sichtbar
OutParameter: Wie Var, jedoch ist der Wert bei Betreten von Bar undefiniert.

Allgemein gilt aber, unabhängig davon, was Du für einen Parameter hast, dass dieser immer nur innerhalb von der Prozedur oder Funktion gültig ist, wo dieser definiert wurde, bzw. in untergeordneten Prozeduren/Funktionen (das hat was mit der Syntax zu tun und ist hier nicht weiter wichtig, ggf. vgl. Scoping).

HTH.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Tranx
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 648
Erhaltene Danke: 85

WIN 2000, WIN XP
D5 Prof
BeitragVerfasst: Sa 06.11.10 07:22 
Ich versuche es mit der zweiten Frage. Zum Ersten, bitten einen Quelltext immer mit den reservierten Worten {delphi} ... {/delphi} (in eckigen Klammern!) eingrenzen. Dann ist der Quelltext besser vom restlichen Text zu unterscheiden:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
var 
  eingabe, ausgabe: string;

procedure mach_es(position: integer);
var 
  buchstabe: char;
begin
  buchstabe := eingabe[position];
  ausgeben := ausgabe + buchstabe; // ??? was soll diese Zeile. Die Variable Ausgeben ist nirgendwo definiert!
  if position < length(eingabe) then 
    mach_es(position + 1);
  ausgabe := ausgabe + buchstabe; // wahrscheinlich ist die o.a. Zeile mit ausgeben falsch!!
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  label2.caption := ' ';  // irrtümlich stand hier ein Doppelpunkt
  eingabe := Edit1.Text;  // Bezug auf das Formular ist überflüssig, da schon in der Prozedur erfolgt
  ausgabe := ' '
  mach_es(1);
  label2.caption := ausgabe;
end;


Also das Programm ruft beim Click auf den Button die Prozedur mach_es auf, welche dann sich selber solange wieder aufruft, bis der Parameter die Länge des im Editfeld angegebenen Textes erreicht hat. Das nennt man rekursive Prozeduraufrufe.
Wie das Programm das Ganze abarbeitet, kannst Du am Besten daran sehen, wenn Du in dem Programm einen Haltepunkt setzt. Und zwar in der Zeile "Ausgabe :=". Das Programm behält die Informationen für die Variable Buchstabe (lokale Variable der Prozedur mach_es) bei jedem Aufruf bei. Und gibt diese Variable am Ende der Bedingung - Position = Length(Eingabe) - der Reihe nach wieder aus. Das Ergebnis ist dann der in umgekehrter Reihenfolge erzeugte Text im Editfeld.

Ein weiteres Beispiel für rekursive Prozeduraufrufe ist die Auflistung von Dateien in Unterverzeichnissen. Das läuft nach dem gleichen Muster ab.

Für solche rekursiven Prozeduraufrufe gibt es allerdings eine große Gefahr, nämlich wenn die Abbruchbedingung nie erreicht wird. Dann wird das Programm irgendwann einmal mit einen Stackoverflow abbrechen oder im Nirwana verschwinden, weil es ja nie endet. Schließlich muss ja jeder Prozeduraufruf mindestens seine Variablen zwischenspeichern.

Die eckigen Klammern sind zur Unterscheidung zwischen Indices und Prozedurparametern.

Sicher hast Du schon mal was von Arrays gehört. Das sind Speicherbereiche, welche mit gleichen Variablentypen belegt sind, wo einzelne Variablen dann über Indices angesprochen werden. z.B. die Monate des Jahres:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
Var
  Monat : Array[1..12of string =
    ('JAN','FEB','MRZ','APR','MAI','JUN','JUL','AUG','SEP','OKT','NOV','DEZ');
  AktuellerMonat : string;
  i : integer;
begin
  AktuellerMonat := Monat[3]; // dann ist AktuellerMonat = 'MRZ'
  for i := 1 to 12 do WriteLn(Monat[i]);
end;


Vorteil dabei ist, Du kannst den Speicherbereich mit den Daten beliebig ansprechen, indem Du den Index benutzt (Wie die Seiten eines Buches). Siehe das kleine Beispiel.
Die Daten im Array können im Übrigen jede x-beliebige - im Programm definierte! - Struktur haben.
z.B.:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
type
  Adresse = Record
    Vorname, Name : string[50];
    Strasse : string[90];
    PLZ : string[5];
    Ort : string[90];
    Geburtstag : TDateTime;
  end;

var
  Kunde : Array [1..200of Adresse;


Dann kannst Du mit dem Index i (Kunde[i]) den i-ten Kunden direkt ansprechen. Vorausgesetzt, Du hast da etwas eingegeben. Für eine Datenbank allerdings ist dieses Verfahren nicht geeignet, nur so im Voraus, weil ja nur 200 Kunden möglich sind.

Die Eckigen Klammern bei string[90] sind hier keine Indices, sonder Speicherbegrenzungen. Das heißt, für PLZ sind maximal 5 Zeichen möglich, für Ort maximal 90 usw. Der Typ TDateTime ist speziell für Datums- und Zeitangaben gedacht. Schau hier einfach mal in der Delphi-Hilfe nach.

_________________
Toleranz ist eine Grundvoraussetzung für das Leben.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19314
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 06.11.10 08:09 
user profile iconTranx hat folgendes geschrieben Zum zitierten Posting springen:
Ich versuche es mit der zweiten Frage.
Und damit ist das Chaos perfekt. :roll: :autsch:

Aber nachdem du jetzt gleich mit Arrays mit Records und Strings darin losgelegt hast :shock: (was vermutlich einige Wochen im Kursablauf vorgreift), schreibe ich dann trotzdem kurz etwas dazu. Denn hier ging es ja eigentlich nur um Strings und den Zugriff auf die Buchstaben darin.
user profile iconMK777 hat folgendes geschrieben Zum zitierten Posting springen:
Doch dann steht da "buchstabe := eingabe[position];". Ich habe keine Ahnung was hier passiert. :shock: Was bedeuten die eckigen Klammern?
Auf diese Weise greifst du auf den Buchstaben Nummer Position in eingabe zu.
Wenn in eingabe der Text "ABC" steht, bekommst du in eingabe[1] das A, in eingabe[2] das B und in eingabe[3] das C. Auf diese Weise kannst du auf die einzelnen Buchstaben zugreifen und hier umgekehrt wieder zusammenbauen.

Mehr zum oben genannten Debugger steht hier:
www.delphi-treff.de/...s-delphi-7/debugger/
MK777 Threadstarter
Hält's aus hier
Beiträge: 2



BeitragVerfasst: Sa 06.11.10 15:39 
Vielen Dank für die ausführlichen Antworten. Ich weiss zwar was Arrays sind, aber ich war verwirrt, da es nirgendwo definiert ist (sprich "array[1..x] of string...").
Außerdem habe ich nicht gewusst, dass man damit einzelne Buchstaben auslesen kann. Jetzt habe ich endlich das Programm verstanden.
PS: Sorry, dass ich den Delphi-Tag nicht benutzt habe. Ich wusste nicht wie es geht, werde es mir aber für die Zukunft merken.