Help to implement the following function of the calculator: the calculation of the "chain" of operations. For example, when you press the keys in the following order: 5 - 1 = = = final result is 2. I also got only a chain of this type: 5 * = = = (instead of 5 and the "*" sign there may be other valid numbers and operation signs ). I enclose the procedure code, which is triggered by pressing the "=" key:

 procedure TFrm.BtnRsltClick(Sender: TObject); begin if err then exit; if (oper = ' ') then begin res := op1; EdtNmbr.Text := FloatToStr(res); exit; end; if edit then begin TryStrToFloat(EdtNmbr.Text, op2); if i = 1 then res := Calculation(op1, op2, oper); end else begin if (op_m <> op1) or (oper_m <> oper) then i := 1; if i = 1 then begin op_m := op1; oper_m := oper; res := op1; end; res := Calculation(res, op1, oper); inc(i); end; EdtNmbr.Text := FloatToStr(res); edit := false; end; ` 

The idea of ​​the code is this: there is a boolean edit variable that is responsible for the edit field. If true, then when pressing numbers we add a number at the end, if false, then we completely replace the text with a number. Using it, I determine whether the chain of calculations has started or not (when you press the operation key, it (variable) becomes a lie so that the second operand does not merge with the second). Then there is a variable of integer type i - from it I determine which operation is on the account: if the first, then I memorize the operation and the operand. The next time you press the "=" key, a check is performed: if the operand and the operation coincide with the previous ones, the "chain" began. If something has changed, then this is another “chain” of calculations, therefore we reset i . This code works only for the chain with the first operand and sign. And how to make it work for two operands?

    2 answers 2

    If your calculator represents something more serious than working with two values, then use the reverse Polish entry. Having written down the expression in it, there will no longer be a problem to find the terminating element of the expression and do the repeat operation.

      I got such a calculator:

      First we declare the global variables in the var section.

        First, Second: Extended; Operation, OldOperation: Char; WasCount, Selected, Count, Counted: Boolean; 

      Then we declare 2 procedures in the private section:

        private { private declarations } Procedure AddDigit(Sender: TObject); // для добавления цифры Procedure SelectOperation(Sender: TObject); // для выбора операции 

      Let's write their code. Add a number to Edit:

       procedure TCalculatorForm.AddDigit(Sender: TObject); begin If (EditCalc.Text='0') Then If ((Sender As TButton).Caption=DecimalSeparator) Then Begin If (Selected) Then Begin EditCalc.Text:='0,'; Selected:=False; End Else EditCalc.Text:=EditCalc.Text+DecimalSeparator; (Sender As TButton).Enabled:=False; End Else EditCalc.Text:=(Sender As TButton).Caption Else If (((Sender As TButton).Caption=DecimalSeparator)) Then Begin If (Selected) Then Begin EditCalc.Text:=(Sender As TButton).Caption; Selected:=False; End Else EditCalc.Text:=EditCalc.Text+(Sender As TButton).Caption; (Sender As TButton).Enabled:=False; End Else If (Selected) Then Begin EditCalc.Text:=(Sender As TButton).Caption; Selected:=False; End Else EditCalc.Text:=EditCalc.Text+(Sender As TButton).Caption; end; 

      Choose an action:

       procedure TCalculatorForm.SelectOperation(Sender: TObject); Var StrText: String; begin If (Selected) Then Exit; If Not(ButtonDot.Enabled) Then ButtonDot.Enabled:=True; If (Counted) Then Begin Operation:=(Sender As TButton).Caption[1]; Selected:=True; Counted:=False; Exit; End; If (Count) Then Begin Second:=StrToFloat(EditCalc.Text); If (WasCount) Then Begin OldOperation:=Operation; Operation:=(Sender As TButton).Caption[1]; Case OldOperation Of '+': First:=First+Second; '-': First:=First-Second; '*': First:=First*Second; '/': First:=First/Second; End; End Else Begin Case Operation Of '+': First:=First+Second; '-': First:=First-Second; '*': First:=First*Second; '/': First:=First/Second; End; WasCount:=True; Operation:=(Sender As TButton).Caption[1]; End; EditCalc.Text:=FloatToStr(First); EditCalc.Repaint; Selected:=True; End Else Begin Operation:=(Sender As TButton).Caption[1]; StrText:=EditCalc.Text; EditCalc.Text:=''; EditCalc.Repaint; Sleep(200); EditCalc.Text:=StrText; EditCalc.Repaint; First:=StrToFloat(EditCalc.Text); Selected:=True; Count:=True; WasCount:=False; End; end; 

      Create an OnCreate handler for the form to set flag values.

       procedure TCalculatorForm.FormCreate(Sender: TObject); begin Counted:=False; // равно ещё не нажимали WasCount:=False; // первое действие ещё не выбрано {ставим разделитель: точка или запятая - это зависит от настроек системы, поэтому используем переменную DecimalSeparator (объявлять не надо!)} ButtonDot.Caption:=DecimalSeparator; end; 

      Now let's connect our procedures with buttons. To do this, on one of the buttons, add a number (or a separator) to write it in the OnClick event and pass this event to the other buttons. For example, for a button that adds 0:

       procedure TCalculatorForm.Button0Click(Sender: TObject); begin AddDigit(Sender); end; 

      We do the same with all buttons for actions (+, -, *, /). I chose a plus:

       procedure TCalculatorForm.ButtonPlusClick(Sender: TObject); begin SelectOperation(Sender); end; 

      Handler for the equal button:

       procedure TCalculatorForm.ButtonResultClick(Sender: TObject); begin If Not (Counted) Then Begin Second:=StrToFloat(EditCalc.Text); Counted:=True; End; Case Operation Of '+': First:=First+Second; '-': First:=First-Second; '*': First:=First*Second; '/': First:=First/Second; End; EditCalc.Text:=FloatToStr(First); EditCalc.Repaint; If (Selected) Then Selected:=False; end; 

      And finally, the handler for the reset button:

       procedure TCalculatorForm.ButtonCeClick(Sender: TObject); begin EditCalc.Text:='0'; If Not(ButtonDot.Enabled) Then ButtonDot.Enabled:=True; First:=0; Second:=0; If (WasCount) Then WasCount:=False; If (Selected) Then Selected:=False; If (Counted) Then Counted:=False; If (Count) Then Count:=False; end;