Schleifen --> verwirrt

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.
Rawi
Beiträge: 14
Registriert: Sa 31. Mär 2018, 17:39

Schleifen --> verwirrt

Beitrag von Rawi »

Hi,
mir sind bisher immer die while- und die for-Schleife bekannt gewesen.
Nun habe ich neulich einige Begriffe wie Repeat-Schleife, kopfabweisende Schleife und fußabweisende Schleife. Sind das andere Begriffe für die beiden Schleifen oder völlig andere Schleifen?
Kennt ihr vielleicht eine gute Übersicht dazu?

Und nur so nebenbei: Was sind denn ordinale Schritte? Ich habe das im Zusammenhang mit Schleifen gelesen, aber irgendwie ist mir nicht ganz klar, was das sein soll...

Vielen Dank

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Schleifen --> verwirrt

Beitrag von m.fuchs »

Rawi hat geschrieben:Nun habe ich neulich einige Begriffe wie Repeat-Schleife, kopfabweisende Schleife und fußabweisende Schleife. Sind das andere Begriffe für die beiden Schleifen oder völlig andere Schleifen?

Als abweisend kenne ich gar keine, sondern nur als kopf- und fußgesteuert. Aber egal.

while..do ist eine kopfgesteuerte Schleife.

Code: Alles auswählen

while X > 15 do begin
  (* ... *)
end;

Es wird bereits im Kopf der Schleife (also oben) geprüft ob die Bedingung stimmt. Stimmt sie vor dem Betreten der Schleife schon nicht, wird die Schleife überhaupt nicht ausgeführt.

repeat...until ist eine fußgesteuerte Schleife.

Code: Alles auswählen

repeat
  (* ... *)
until X <= 15;

Es wird erst im Fuß der Schleife (also unten) geprüft ob die Abbruchbedingung stimmt. Das heißt die Schleife wird mindestens einmal ausgeführt.

Rawi hat geschrieben:Kennt ihr vielleicht eine gute Übersicht dazu?


https://de.wikipedia.org/wiki/Schleife_(Programmierung)

Rawi hat geschrieben:Was sind denn ordinale Schritte?

Das sagt mir gar nichts. Hast du einen Link zu dem Dokument wo du es gelesen hast?
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Schleifen --> verwirrt

Beitrag von Socke »

m.fuchs hat geschrieben:
Rawi hat geschrieben:Was sind denn ordinale Schritte?

Das sagt mir gar nichts. Hast du einen Link zu dem Dokument wo du es gelesen hast?


Eine Datentyp ist ordinal, wenn man seine Werte abzählen kann (siehe Wikipedia: Ordinalzahl). Dazu gehören in Pascal Ganzzahlen, Buchstaben (Char, man kann das Alphabet durchzählen) und Boolean. Die Schritteweite in einer for .. do Schleife ist in Pascal immer 1. In anderen Programmiersprachen kann man das für jede Schleife angeben.

In diesem Beispiel hätten wir eine ordinale Schrittweite von 10:

Code: Alles auswählen

var i: Integer = 0;
begin
  while i < 50 do
    inc(i, 10);
end;


Natürlich kann man auch Schleifen ganz ohne ordinale Schritte schreiben:

Code: Alles auswählen

begin
  while not WorkDone do
    WorkSomething();
end;
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Rawi
Beiträge: 14
Registriert: Sa 31. Mär 2018, 17:39

Re: Schleifen --> verwirrt

Beitrag von Rawi »

m.fuchs hat geschrieben:Das sagt mir gar nichts. Hast du einen Link zu dem Dokument wo du es gelesen hast?


Also ich hab beim raussuchen nochmal nachgelesen und hatte mich falsch erinnert. Es wurde von ordinalen Werten in Schleifen gesprochen. Ist dir das vllt. geläufig?

Rawi
Beiträge: 14
Registriert: Sa 31. Mär 2018, 17:39

Re: Schleifen --> verwirrt

Beitrag von Rawi »

Socke hat geschrieben:
m.fuchs hat geschrieben:
Rawi hat geschrieben:Was sind denn ordinale Schritte?

Das sagt mir gar nichts. Hast du einen Link zu dem Dokument wo du es gelesen hast?


Eine Datentyp ist ordinal, wenn man seine Werte abzählen kann (siehe Wikipedia: Ordinalzahl). Dazu gehören in Pascal Ganzzahlen, Buchstaben (Char, man kann das Alphabet durchzählen) und Boolean. Die Schritteweite in einer for .. do Schleife ist in Pascal immer 1. In anderen Programmiersprachen kann man das für jede Schleife angeben.

In diesem Beispiel hätten wir eine ordinale Schrittweite von 10:

Code: Alles auswählen

var i: Integer = 0;
begin
  while i < 50 do
    inc(i, 10);
end;


Natürlich kann man auch Schleifen ganz ohne ordinale Schritte schreiben:

Code: Alles auswählen

begin
  while not WorkDone do
    WorkSomething();
end;


Danke, das hab ich jetzt verstanden. :)

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Schleifen --> verwirrt

Beitrag von siro »

Buchstaben haben zum Beispiel auch eine Ordinalzahl, das ist quasi die Position innerhalb der Ascii-Tabelle,
so wäre eine solche Schleife auch möglich:

Code: Alles auswählen

procedure Test;
var i,x:Integer;
var s:string;
begin
  x:=0;
  s:='';
 
  for i:=ord('A') to ord('Z') do begin    // identisch zu for i:=65 to 90 do begin
    inc(x);
    s:=s+chr(i);
  end;
 
  Writeln(s);                  // Ausgabe: ABCDEFGHIJKLMNOPQRSTUVWXYZ
  Writeln(IntToStr(x));        // Ausgabe: 26
end;             
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Schleifen --> verwirrt

Beitrag von m.fuchs »

Was man aber kürzer und übersichtlicher heutzutage so machen würde:

Code: Alles auswählen

procedure Test;
var
  x: Integer = 0;
  c: Char;
  s: String = '';
begin
  for c in ['A'..'Z'] do begin
    inc(x);
    s := s + c;
  end;
  Writeln(s);
  Writeln(IntToStr(x));
end;
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Schleifen --> verwirrt

Beitrag von Mathias »

Es geht auch ohne ord.

Code: Alles auswählen

var
  c: char;
begin
  for c := 'a' to 'z' do begin
    WriteLn(c);
  end;


Es gehen auch lustige Sachen.

Code: Alles auswählen

var
  c: char;
begin
  forin['a'..'z', 'A'..'Z'] do begin
    WriteLn(c);
  end;
 


Diese beiden Schleifen sind nicht gleich, die erste Variante verbraucht weniger Speicher, das es eine reine Zähl schleife ist, bei der 2. Variante, wie eine Array durchgezählt, möglicherweise, ist dies auch langsamer.

Code: Alles auswählen

  for:= 'a' to 'z' do
  forin['a'..'z'] do
 
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Schleifen --> verwirrt

Beitrag von siro »

Mathias seine lustige Variante hab ich grad mal probiert und bin erstaunt über die Sortierung:
Beides Mal identisch: Großbuchstaben zuerst

Code: Alles auswählen

 
procedure TForm1.FormCreate(Sender: TObject);
var c:char;
var s1,s2:string;
begin
  forin['A'..'Z', 'a'..'z'] do begin
    s1:=s1+c;
  end;
  label1.caption:=s1;   // ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
 
  forin['a'..'z', 'A'..'Z'] do begin
    s2:=s2+c;
  end;
  label2.caption:=s2;  // ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
end;       
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Schleifen --> verwirrt

Beitrag von Mathias »

Mathias seine lustige Variante hab ich grad mal probiert und bin erstaunt über die Sortierung:
Beides Mal identisch: Großbuchstaben zuerst


Ich habe noch was probiert, wen man es so macht, hat man gar keine Ausgabe.
Dafür habe ich bei Length 26 und i hat 676. Somit läuft die Schleife 676mal durch.

Code: Alles auswählen

var
  a:array ['a'..'z', 'A'..'Z'] of Char;
 
begin
  s2 := '';
  i := 0;
  for c in a do begin
    Inc(i);
    s2 := s2 + c;
  end;
  WriteLn('Länge: ', Length(a));
  WriteLn('i:     ', i);
  WriteLn(s2);


Jetzt weis ich warum, a ist eine 2D-Array.
Aber irgendwie ist es trotzdem merkwürdig.

Und dies spuckt 676mal '0' aus.

Code: Alles auswählen

  for c in a do begin
    Write(byte(c): 4);
  end;
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Schleifen --> verwirrt

Beitrag von Warf »

Über ranges kann man nunmal auch statische arrays definieren, daher hast du ein 26*26 Felder 2D array. Ein wenig verwirrend, vor allem da ich kein fan der range array definierung bin. Ich finde das C system mit nur anzahl an elementen dafür immer 0 basiert deutlich besser

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Schleifen --> verwirrt

Beitrag von Socke »

Hier wird nur ein 2-dimensionaler Array definiert, dieser hat 26*26 Elemente. Über den Inhalt des Arrays macht dein Code keine Aussage.

Code: Alles auswählen

var
  a:array ['a'..'z', 'A'..'Z'] of Char;


Hier definiert ['A'..'Z', 'a'..'z'] ein Set of Char; dabei wird die mögliche Wertemenge von allen möglichen Zeichen (Char) auf die angegebenen Zeichen festgelegt.

Code: Alles auswählen

forin ['A'..'Z', 'a'..'z'] do begin
    s1:=s1+c;
  end;

Es wäre also identisch mit:

Code: Alles auswählen

var
  c: Char;
  s: set of Char;
  s1: String;
begin
  s := ['A'..'Z', 'a'..'z'];
  for c in s do begin
    s1 := s1 + c;
  end;
end;

Die Elemente eines Sets sind immer ordinal (so ist ein Set definiert) und damit in einer Reihenfolge abzählbar. Bei Set of Char wird die Reihenfolge entsprechend der Codepoints der einzelnen Buchstaben festgelegt, bei Zahlen entsprechend durch ihren Zahlwert.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

mischi
Beiträge: 206
Registriert: Di 10. Nov 2009, 18:49
OS, Lazarus, FPC: macOS, 10.13, lazarus 1.8.x, fpc 3.0.x
CPU-Target: 32Bit/64bit

Re: Schleifen --> verwirrt

Beitrag von mischi »

Warf hat geschrieben:Über ranges kann man nunmal auch statische arrays definieren, daher hast du ein 26*26 Felder 2D array. Ein wenig verwirrend, vor allem da ich kein fan der range array definierung bin. Ich finde das C system mit nur anzahl an elementen dafür immer 0 basiert deutlich besser

Es hindert dich doch nichts daran, deine Arrays mit 0 .. n-1 zu deklarieren. Das ist doch nur etwas mehr Schreibarbeit bei der Deklaration. Die Flexibilität von Pascal Arrays hat einige Vorteile. In Fortran beginnen alle Arrays mit dem Index 1 und das ist in einigen Fällen praktischer. Durch seine Flexibilität kann ich also in Pascal Code aus C UND Fortran direkt übernehmen, ohne dass ich etwas mit den Laufvariablen und Grenzen machen muss. Manchmal kommen einem auch Real-World Probleme auf den Tisch, bei denen weder bei 0 noch bei 1 angefangen wird zu zählen, sondern bei irgendeiner anderen Zahl. Ich habe immer wieder die Erfahrung gemacht, dass es überraschend häufig zu Fehlern kommt, wenn man das umsetzen muss, obwohl man denkt, dass es doch nicht so schwierig sein kann, eine Eins oder einen anderen Wert abzuziehen.
MiSchi macht die fink-Pakete

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Schleifen --> verwirrt

Beitrag von Mathias »

Das Realzahlenproblem kann msn mit einer while do Schleife umgehen.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Schleifen --> verwirrt

Beitrag von m.fuchs »

Mathias hat geschrieben:Das Realzahlenproblem kann msn mit einer while do Schleife umgehen.

Jetzt musste ich erst einmal einen Moment nachdenken was du meinst. Du beziehst dich auf die Real-World Probleme nicht auf Realzahlen.

Klar kann man das in einer while..do-Schleife lösen, man kann auch komplett auf for..to..do verzichten. Man könnte auch label, goto und if verwenden um das alles abzubilden.
Die Frage ist nur Warum?

Was ich eher schmerzlich vermisse ist die Möglichkeit bei einem dynamischen Array den Startindex zu setzen.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Antworten