Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Zuweisung für FOR-Schleifenvariablen wird nicht akzeptiert (https://www.delphipraxis.net/66964-zuweisung-fuer-schleifenvariablen-wird-nicht-akzeptiert.html)

Alexander Roth 7. Apr 2006 07:56


Zuweisung für FOR-Schleifenvariablen wird nicht akzeptiert
 
Hallo,


der Fehler wird gemeldet:
Zitat:

[Fehler] Unit1.pas(1642): Anweisung für FOR-Schleifenvariablen 'la'
[Fehler] Unit1.pas(1643): Anweisung für FOR-Schleifenvariablen 'lb'
[Fehler] Unit1.pas(1644): Anweisung für FOR-Schleifenvariablen 'lc'
Und zwar bei diesem Code:
Delphi-Quellcode:
  for la:=0 to max.a do
    for lb:=-max.b to max.b do
      for lc:=-max.c to max.c do
      begin
//jetzt kommt viel blabla
        //aussenwelt
        if (maxlauf>5000)or (i mod 10=0 ) then // keine Sorge der kommt da manchmal rein
        begin
          application.ProcessMessages;
          if stop then
          begin
            la:=max.a;
            lb:=max.b;
            lc:=max.c;
          end;
          label2.Caption:=inttostr(maxformel-i);
        end;
//jetzt kommt viel blabla
      end;
Wieso hat der damit ein Problem dass ich den Schleifenvariablen etwas zuweisen will? Wage glaube ich dass das früher immer geklappt hat?
Rot makieren tut er das da:
Delphi-Quellcode:
            la:=max.a;

Angel4585 7. Apr 2006 08:00

Re: Zuweisung für FOR-Schleifenvariablen wird nicht akzeptie
 
versuchs doch einfach mit "break", du willst ja wie ich das sehe "nur" die Schleifen beenden oder?

Sharky 7. Apr 2006 08:01

Re: Zuweisung für FOR-Schleifenvariablen wird nicht akzeptie
 
Hai Alexander,

den Laufvariablen einer FOR-Schleife kannst Du nichts zuweisen. Diese werden quasi vom Compiler "wegoptimiert".
Genauso kannst Du nach der FOR-Schleife nicht auf die Variablen zugreifen. Genauer gesagt haben sie nach der Schleife keinen definierten Wert. Das war aber imho schon immer so.

Klaus01 7. Apr 2006 08:01

Re: Zuweisung für FOR-Schleifenvariablen wird nicht akzeptie
 
kann es sein, das es ein Problem damit hat,
dass Du die Schleifenvariablen der FOR Schleife
in der Schleife veränderst.

Da wäre dann wenn ein while oder repeat Schleife besser.

Delphi-Quellcode:
  la:=0;
  while la < max.a do
    begin
      lb:=-max.b;
      while lb < max.b do
        begin
          lc:=-max.c;
          while lc < max.c do
            begin
             //jetzt kommt viel blabla
            //aussenwelt
            if (maxlauf>5000)or (i mod 10=0 ) then // keine Sorge der kommt da manchmal rein
              begin
                application.ProcessMessages;
                if stop then
                  begin
                    la:=max.a;
                    lb:=max.b;
                    lc:=max.c;
                  end;
                label2.Caption:=inttostr(maxformel-i);
             end;
             inc(lc);
           end; /while lc
           inc(lb);
         end; //while lb
         inc(la);
       end; // while la
     //jetzt kommt viel blabla
so ähnlich stelle ich mir das vor.
Ich mag das mit break nicht.

Grüße
Klaus

Alexander Roth 7. Apr 2006 08:04

Re: Zuweisung für FOR-Schleifenvariablen wird nicht akzeptie
 
Zitat:

Zitat von Angel4585
versuchs doch einfach mit "break", du willst ja wie ich das sehe "nur" die Schleifen beenden oder?

break beendet doch nur die Innerste. Oder?
Hatte es nämlich damit ausprobiert.


Zitat:

Zitat von Klaus01
Da wäre dann wenn ein while oder repeat Schleife besser.

Unpraktisch.

Dann bleibt mir wohl nichts anderes übrig als in jede for schleife die break variante einzubauen.
Also ungefähr so
Delphi-Quellcode:
  for la:=0 to max.a do
  begin
    for lb:=-max.b to max.b do
    begin
      for lc:=-max.c to max.c do
      begin
//jetzt kommt viel blabla
        //aussenwelt
        if (maxlauf>5000)or (i mod 10=0 ) then // keine Sorge der kommt da manchmal rein
        begin
          application.ProcessMessages;
          if stop then
            break;
          label2.Caption:=inttostr(maxformel-i);
        end;
//jetzt kommt viel blabla
      end;
      if stop then
        break;
    end;
    if stop then
      break;
  end;
Falls ich was falsch eingerückt haben sollte. Bitte entschuldigt. Hier ist es mit den Leerzeichen kompliziert einzurücken.

Angel4585 7. Apr 2006 08:11

Re: Zuweisung für FOR-Schleifenvariablen wird nicht akzeptie
 
Also wenn nach der Schleife nixmehr kommt würd ich ein exit empfehlen.

Alexander Roth 7. Apr 2006 08:13

Re: Zuweisung für FOR-Schleifenvariablen wird nicht akzeptie
 
Da kommt noch verdammt viel wichtiges. :???:
Deswegen so umständlich. :roll:

NicoDE 7. Apr 2006 08:17

Re: Zuweisung für FOR-Schleifenvariablen wird nicht akzeptie
 
Es gibt mehrere Möglichkeiten die Schleife zu verlassen.
Hier nur ein paar Möglichkeiten...

Abfrage in jeder Schleife:
Delphi-Quellcode:
begin
  for LoopX := 1 to 1000 do
  begin
    for LoopY := 1 to 1000 do
    begin
      for LoopZ := 1 to 1000 do
      begin
        Application.ProcessMessages();
        if Stop then
          Break;
        //...
      end;
      if Stop then
        Break;
      //...
    end;
    if Stop then
      Break;
    //...
  end;
  //...
end;
Label um alle Schleifen direkt zu verlassen (manche mögen kein 'goto'):
Delphi-Quellcode:
label
  LoopEnd;
begin
  for LoopX := 1 to 1000 do
  begin
    for LoopY := 1 to 1000 do
    begin
      for LoopZ := 1 to 1000 do
      begin
        Application.ProcessMessages();
        if Stop then
          goto LoopEnd;
        //...
      end;
      //...
    end;
    //...
  end;
LoopEnd:
  //...
end;
Mit Exit die Funktion verlassen (Code nach 'finally' wird nicht ausgeführt):
Delphi-Quellcode:
begin
  try
    for LoopX := 1 to 1000 do
    begin
      for LoopY := 1 to 1000 do
      begin
        for LoopZ := 1 to 1000 do
        begin
          Application.ProcessMessages();
          if Stop then
            Exit;

          //...
        end;
        //...
      end;
      //...
    end;
  finally
    //...
  end;
end;
...hat alles seine Vor- und Nachteile.

Angel4585 7. Apr 2006 08:18

Re: Zuweisung für FOR-Schleifenvariablen wird nicht akzeptie
 
dann mach doch ne Funktion/prozedur aus dem Abschnitt! So etwa:

Delphi-Quellcode:

procedure DeineMainPrc;

  procedure InMainproc(var x,y,a,z,b,c : integer);
  begin
  for i:= x to y do
    for j:= a to z do
      for k := b to c do
        begin
        if stop then
          exit;
        end;
  end;

begin

InMainProc(x1,x2,x3,x4,x5,x6)

end;
Naja weist schon was ich mein oder?

sakura 7. Apr 2006 08:26

Re: Zuweisung für FOR-Schleifenvariablen wird nicht akzeptie
 
Exit zählt i.A. zu den Jump-Befehlen und wird oft in die Kategorie "GoTo" geworfen. Und da gehört es auch hin, es ist einer der Befehle, die zu unleserlichem Spaghetti-Code führen und nur mit Bedacht, besser aber nie, genutzt werden sollten.

Das dreifache Break, wie von NicoDE gezeigt, ist hier der sauberste Lösungsweg.

...:cat:...

NicoDE 7. Apr 2006 08:31

Re: Zuweisung für FOR-Schleifenvariablen wird nicht akzeptie
 
Zitat:

Zitat von sakura
Das dreifache Break, wie von NicoDE gezeigt, ist hier der sauberste Lösungsweg.

Das hängt, meiner Meinung nach, vom jeweiligen Code ab...
Um die drei Schleifen zu verlassen, würde ich Goto einsetzen (für mich einer der wenigen sinnvollen Einsatzmöglichkeiten dieses Sprachelements).

Robert Marquardt 7. Apr 2006 08:34

Re: Zuweisung für FOR-Schleifenvariablen wird nicht akzeptie
 
Huh?
Exit, Break und Continue sind der saubere Ersatz fuer goto. Alle drei sind notwendig, aber sollten sparsam eingesetzt werden.
In diesem Fall ist Exit die sauberste Moeglichkeit aus der innersten Schleife auszubrechen.
Am lesbarsten ist es nur die Schleifen in eine lokale Prozedur zu extrahieren. Der Vorschlag mit try finally ist nicht so leicht zu durchschauen.
Es ist auch der effizienteste Weg. Dreifaches Break heisst zwei zusaetzliche Tests.

negaH 7. Apr 2006 09:02

Re: Zuweisung für FOR-Schleifenvariablen wird nicht akzeptie
 
Da die Möglichkeit besteht diese Schleifen durch bedingte Schleifen wie "while do" und "repeat until" zu ersetzen sind es diese Sprachkonstrukte die am saubersten sind.

Die Feststellung sie wären "unpraktisch" glaube ich einfach nicht, eher vermute ich das das Problem konzeptionell vom Programmierer falsch angegangen wurde !

Gruß Hagen

Alexander Roth 7. Apr 2006 09:19

Re: Zuweisung für FOR-Schleifenvariablen wird nicht akzeptie
 
Zitat:

Zitat von negaH
Die Feststellung sie wären "unpraktisch" glaube ich einfach nicht, eher vermute ich das das Problem konzeptionell vom Programmierer falsch angegangen wurde !

Also hör mal! Das kann man auch netter ausdrücken.

Ausserdem ist es auch viel Geschacksache ob, man jetzt For Schleifen mir break, oder while schleife mit dem Zuweisen der laufvariablen löst.

Ich glaub jetzt auch langsam, dass while schleifen da etwas kürzer wären.

Tschüss

Danke für eure Hilfe

himitsu 7. Apr 2006 10:08

Re: Zuweisung für FOR-Schleifenvariablen wird nicht akzeptie
 
Ich glaub hier könnte man auch mal wieder das nette goto anwenden :mrgreen:
Delphi-Quellcode:
for la:=0 to max.a do
  for lb:=-max.b to max.b do
    for lc:=-max.c to max.c do
    begin
//jetzt kommt viel blabla
      //aussenwelt
      if (maxlauf>5000)or (i mod 10=0 ) then
      begin
        application.ProcessMessages;
        if stop then goto abc;
        label2.Caption:=inttostr(maxformel-i);
      end;
//jetzt kommt viel blabla
    end;
abc:
Zitat:

Zitat von Sharky
den Laufvariablen einer FOR-Schleife kannst Du nichts zuweisen. Diese werden quasi vom Compiler "wegoptimiert".

Das entspricht nicht ganz der Wahrheit, es gibt zwar einen Weg solche Variablen zu ändern, aber viele würden es bestimmt nicht als "sauber" ansehn, :roll:
drumm laß ich dat ma mit dem Beispielcode ... will ja keine "schlechten" Praktiken verbreiten ^^

Khabarakh 7. Apr 2006 10:23

Re: Zuweisung für FOR-Schleifenvariablen wird nicht akzeptie
 
Zitat:

Zitat von Alexander Roth
Zitat:

Zitat von negaH
Die Feststellung sie wären "unpraktisch" glaube ich einfach nicht, eher vermute ich das das Problem konzeptionell vom Programmierer falsch angegangen wurde !

Also hör mal! Das kann man auch netter ausdrücken.

Ich finde Hagens Beitrag in keinster Weise unfreundlich. Ich kann mir ebenfalls durchaus vorstellen, dass sich das Problem vielleicht vom Konzept her anders lösen lassen könnte.

alzaimar 7. Apr 2006 10:53

Re: Zuweisung für FOR-Schleifenvariablen wird nicht akzeptie
 
Hi,

Die While-Schleifenlösung ist zwar vom Sprachkonzept her die sauberste, aber in der Realität grauenvoll.

Delphi-Quellcode:
i:=0;
While (i<m) and Not AbortedByInnerCode Do Begin
  j := 0;
  While (j<n) and Not AbortedByInnerCode Do Begin
    k := 0;
     While (k < r) and Not AbortedByInnerCode Do Begin
       l := 0;
       While (l < p) and Not AbortedByInnerCode Do Begin
         If DoSomeThing = DoesNotWork Then
           AbortedByInnerCode := True;
         l := l + 1;
       End;
       k := k + 1;
     End;
     j := j + 1;
  End;
  i := i + 1;
End;
Äh.. sauber? :shock:

Hier die Goto-Version: Ich finde das besser, weil es lesbarer und *kein* Spaghetticode ist. Denn nicht jedes Goto macht aus Code gleich eine Frickelschusterei. Goto ist ein legitimer Befehl, der -richtig (und damit sparsam!) dosiert- den Code übersichtlicher macht.
Delphi-Quellcode:
For i:=0 t o m-1 do
  For j:=0 to n-1 do
    For k:=0 to r-1 do
     For l:=0 to p-1 do
       If DoSomeThing = DoesnotWork Then
          Goto ExitLoop;

ExitLoop:
Mal ehrlich: Was ist übersichtlicher?
Ich würde allerdings eine lokale Prozedur verwenden:
Delphi-Quellcode:
Procedure OuterProc;
Var
  m,n,o,p : Integer;

  Procedure InnerLoop;
  Var
    i,j,k,l : Integer;
 
  Begin
    For i:=0 t o n-1 do
      For j:=0 to m-1 do
        For k:=0 to o-1 do
          For l:=0 to p-1 do
            If DoSomeThing = DoesnotWork Then
              Exit;
  End;

Begin
  ...
  InnerLoop;
  ...
End;
Damit sind die Goto-Ablehner zufriedengestellt. Ach so, die lokale Prozedur bekommt natürlich einen aussagekräftigen Namen. Denn eigentlich ist es ein 'ausführbarer Kommentar'.

Unabhängig davon, ob 4 verschachtelte Schleifen nicht vielleicht ein falsches Konzept/Algorithmus implizieren, ist die Beendigung aus dem inneren von Schleifen eine generelle Frage, die ich, einmal beantwortet, konsistent und konsequent durch den Code ziehen würde. Also
Entweder IMMER
- mit While-Schleifen arbeiten und einen Flag mitschleppen, ODER
- mit Goto arbeiten, ODER
- mit lokalen Prozeduren und Exit.

Ach, eins noch: Eine andere (sinnvolle) Verwendung für das GOTO fällt mir übrigens nicht ein, Euch etwa?

negaH 7. Apr 2006 12:35

Re: Zuweisung für FOR-Schleifenvariablen wird nicht akzeptie
 
Hi

die Schleifen laufen

Delphi-Quellcode:
for i := 0 to m-1 do
  for j := 0 to n-1 do
    for k := 0 to r-1 do
      for l := 0 to p-1 do
von 0 bis m * n * r * p -1, meiner Meinung nach reicht eventuell auch nur eine Schleife aus.

@Alexander: Ja man könnte es auch "höflicher" ausdrücken:

Lieber Alexander, könnte es unter Umständen, ich meine ja nur, vielleicht wäre es sinnvoll dein Problem mal im Gesamtkontext zu erläutern, weil es könnte ja durchaus die klitzekleine Möglichkeit bestehen, das man auf diese vielen Schleifen verzichten kann ?

Ändert nichts an der Sache, ich finde meine erste Aussage nicht falsch, noch beleidigend, sondern leider allzuoft eine Tatsache. Also wozu um den heisen Brei reden.

Erkläre doch mal dein gesamtes Verfahren.

Ansonsten stimme ich Alzaimar zu wenn er den Vorschlag macht mit Exit in einer nested Funktion zu arbeiten. Das ist besser als ein verschachteltes Break/Continue da es dort öfters Probleme gibt beim Verständis wohin nun "ge-breakt"/"ge-continued" wird. Besonders bei Sprachübergreifender Betrachtungsweise stellt sich nämlich heraus das Break/Continue abhängig von der Sprache unterschiedlich arbeiten. Das kann bei Exit/Return() (und meinetwegen auch einem GOTO zu einem LABEL) etc. nicht passieren.


Gruß Hagen


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:06 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz