Addition wird nicht ausgeführt

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Weizenbaum
Beiträge: 28
Registriert: Mi 24. Aug 2016, 09:00

Addition wird nicht ausgeführt

Beitrag von Weizenbaum »

Hallo zusammen,
habe eine Methode wo 2 Zahlen von einer Funktion zurückgegeben werden, welche Zufallszahlen zurückgibt. Diese sollen dann in der Methode addiert werden. Die Variable die das Ergebnis erhalten soll, behielt jedoch ihren alten wert. Ich führte dann weiter oben zum Testen ein paar Additionen aus, welche auch zu einen Ergebnis führten. Also mußte der Fehler entweder auf der Random-Funktion basieren oder auf etwas anderem.
Beim näheren hinsehen erkannte ich in der Assembleransicht, daß zwar ein mov und ein add - Befehl ausgeführt wird und das Ergebnis steht dann auch in EAX, jedoch wird dies nicht in iSumme gespeichert.

Hier der Quelltext der Methode, die zwei Zufallszahlen addieren soll.

Code: Alles auswählen

 
// Öffentliche Methode, um die Testreihe zu starten
procedure TForm1.ButtonTestlaufStartenClick(Sender: TObject);
var
  iZahl1, iZahl2, iSumme: integer;
begin
  iSumme:= 0;
  iSumme:= 3+5;
  iZahl1:= 7;
  iZahl2:= 7;
  iSumme:= iZahl1 + iZahl2;
  iZahl1:= GetRand(0, 1, 100);
  iZahl2:= GetRand(0, 1, 100);
  iSumme:= iZahl1 + iZahl2;  // Ergebnis wird nicht in iSumme gespeichert
end;
 


Hier noch der Quelltext, wo die Zufallszahlen generiert und zurückgegeben werden.

Code: Alles auswählen

 
// Öffentliche Funktion, um Zufallszahlen innerhalb eines über die Parameter fest-
// gelegten Bereichs zu erzeugen und zurückzugeben.
function TForm1.GetRand(iParamNoNum, iParamUnder, iParamUpper: integer
  ): integer;
var
  iASC: integer;
begin
  repeat
//    iASC:= Random(iParamUnder) + (iParamUpper - iParamUnder);
    iASC:= Random(iParamUpper);
  until (iASC > iParamUnder) and (iASC < iParamUpper)
        and (iASC <> iParamNoNum);
  result:= iASC;
end;
 


Nun ist die Frage, warum das Ergebnis nicht in iSumme gespeichert wird. Der Compiler scheint am Ende der Methode den Befehl nicht vollständig zu übersetzen.

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Addition wird nicht ausgeführt

Beitrag von wp_xyz »

Ich könnte mir durchaus vorstellen, dass die letzte Zeile (iSumme := iZahl1 + iZahl2) tatsächlich nicht berechnet wird, denn das Ergebnis geht in eine lokale Variable, hinter der Zeile ist die Methode zu Ende. Die Variable verschwindet dann im Nirvana. Das heißt, das Ergebnis kann nicht weiterverwendet werden. Wieso es dann berechnen?

Setze ein Label auf dein Formular und schreibe als letzte Zeile "Label1.Caption := IntToStr(iSumme)". Dann wirst du sehen, dass sich die Anzeige mit jedem Button-Click ändert. Denn nun wird das Ergebnis weiterverwendet.

Oder mache iSumme zu einer globalen Variablen, dann kann der Compiler nicht wissen, dass mit iSumme nichts mehr passiert. Auch hier ändert sich im Debugger der Wert von iSumme mit jedem Button-Click.

Weizenbaum
Beiträge: 28
Registriert: Mi 24. Aug 2016, 09:00

Re: Addition wird nicht ausgeführt

Beitrag von Weizenbaum »

Ja in dieser Hinsicht übersetzt der Compiler richtig, ist ja eine lokale Variable. Bei folgenden Quelltext ist jetzt auch die mov, add, mov Sequenz vorhanden, da die Methode weitere Befehle nach der Addition enthält.

Code: Alles auswählen

 
// Öffentliche Methode, um die Testreihe zu starten
procedure TForm1.ButtonTestlaufStartenClick(Sender: TObject);
var
  iVersuche, iCount, iZahl1, iZahl2, iSumme: integer;
  acMsg: AnsiString;
begin
  if EditAnzahl.Text = '' then
  begin
    acMsg := 'Die Anzahl der Durchläufe fehlt.';
    MessageDlg(acMsg, mtError, [mbOk], 0);
    EditAnzahl.SetFocus;
    exit;
  end;
 
  iVersuche:= StrToInt(EditAnzahl.Text);
  for iCount:= 1 to iVersuche do
  begin
    iZahl1:= GetRand(0, 1, 100);
    iZahl2:= GetRand(0, 1, 100);
    iSumme:= iZahl1 + iZahl2;
    if Testreihe(iZahl1, iZahl2, iSumme) = false then
    begin
      acMsg := 'Fehler bei: ' + IntToStr(iZahl1) + ' + ' + IntToStr(iZahl2);
      MessageDlg(acMsg, mtError, [mbOk], 0);
      exit;
    end;
  end;
end;
 

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

Re: Addition wird nicht ausgeführt

Beitrag von Mathias »

Du könntest im ersten Beispiel folgenden Kompilerschalter zu verwenden, dann sollte der Compiler nichts mehr optimieren.

Code: Alles auswählen

{$O-}
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Antworten