Addition wird nicht ausgeführt

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut

Addition wird nicht ausgeführt

Beitragvon Weizenbaum » 14. Jan 2018, 13:36 Addition wird nicht ausgeführt

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.
Weizenbaum
 
Beiträge: 8
Registriert: 24. Aug 2016, 08:00

Beitragvon wp_xyz » 14. Jan 2018, 14:22 Re: Addition wird nicht ausgeführt

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.
wp_xyz
 
Beiträge: 2645
Registriert: 8. Apr 2011, 08:01

Beitragvon Weizenbaum » 14. Jan 2018, 14:33 Re: Addition wird nicht ausgeführt

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;
 
Weizenbaum
 
Beiträge: 8
Registriert: 24. Aug 2016, 08:00

Beitragvon Mathias » 14. Jan 2018, 15:50 Re: Addition wird nicht ausgeführt

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 gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 4327
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

• Themenende •

Zurück zu Freepascal



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 5 Gäste

cron
porpoises-institution
accuracy-worried