|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Что-то вроде калькулятора
Доходит только до Numbera и выводит тупо число((Что не так?
Код:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; Label1: TLabel; Label2: TLabel; Button1: TButton; Edit4: TEdit; procedure Edit1Change(Sender: TObject); procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; S:string; P:integer; implementation uses Math; {$R *.dfm} procedure TForm1.Edit1Change(Sender: TObject); begin S:=Edit1.Text; end; function IsDigit(Ch: Char): Boolean; begin IsDigit := Ch in ['0'..'9']; end; function IsSeparator(Ch: Char): Boolean; begin IsSeparator := Ch='.'; end; // Проверка символа на соответствие <Sign> function IsSign(Ch: Char): Boolean; begin IsSign := (Ch = '+') or (Ch = '-'); end; function IsExponent(Ch: Char): Boolean; begin IsExponent:= (Ch = 'E') or (Ch = 'e'); end; function Number( var P: Integer): Extended; var InitPos: Integer; begin // InitPos для передачи в StrToFloat InitPos := P; if (P <= Length(S)) and IsSign(S[P]) then Inc(P); if (P > Length(S)) or not IsDigit(S[P]) then ShowMessage( 'Ожидается цифра ' + IntToStr(P)); repeat Inc(P); until (P > Length(S)) or not IsDigit(S[P]); if (P <= Length(S)) and IsSeparator(S[P]) then begin Inc(P); if (P > Length(S)) or not IsDigit(S[P]) then ShowMessage( 'Ожидается цифра в позиции ' + IntToStr(P)); repeat Inc(P); until (P > Length(S)) or not IsDigit(S[P]); end; if (P <= Length(S)) and IsExponent(S[P]) then begin Inc(P); if P > Length(S) then ShowMessage('Неожиданный конец строки'); if IsSign(S[P]) then Number(S[P]) and Inc(P); if (P > Length(S)) or not IsDigit(S[P]) then ShowMessage( 'Ожидается цифра в позиции ' + IntToStr(P)); repeat Inc(P); until (P > Length(S)) or not IsDigit(S[P]); end; Number := StrToFloat(Copy(S, InitPos,P-InitPos)); end; function Expr(var P: Integer): Extended; forward; function Factor(var P: Integer): Extended;//проверяем введенные символы begin if P > Length(S) then ShowMessage('Неожиданный конец строки'); case S[P] of '+': begin Inc(P); Factor := Factor( P); ShowMessage('положительной число'); end; '-': begin Inc(P); Factor := -Factor(P); end; '(': begin Inc(P); Factor := Expr( P); if (P > Length(S)) or (S[P] <> ')') then ShowMessage( ' ")" ? ' + IntToStr(P)); Inc(P); end; '0'..'9': Factor:= Number(P); else ShowMessage( 'конец строки? ' + IntToStr(P)); end; end; function Term(var P: Integer): Extended; var OpSymb: Char; begin Term := Factor( P); while (P <= Length(S)) and IsSign(S[P]) do //проверяем приоритет операторов * или / begin OpSymb := S[P]; Inc(P); case OpSymb of '*': Term := Term(P) * Factor( P); '/': Term := Term(P) / Factor( P); end; end; end; function Expr(var P: Integer): Extended; var OpSymb: Char; begin Expr := Term( P); while (P <= Length(S)) and IsSign(S[P]) do begin OpSymb := S[P]; Inc(P); case OpSymb of '+': Expr := Expr(P) + Term( P); '-': Expr := Expr(P) - Term( P); end; end; end; function Func(const FuncName: string; var P:Integer): Extended; var Arg: Extended; begin Arg := Expr(P); if AnsiCompareText(FuncName, 'sin') = 0 then Func := Sin(Arg) else if AnsiCompareText(FuncName, 'cos') = 0 then Func := Cos(Arg) else if AnsiCompareText(FuncName, 'ln') = 0 then Func := Ln(Arg) else if AnsiCompareText(FuncName, 'log2') = 0 then Func := Log2(Arg) else if AnsiCompareText(FuncName, 'log10') = 0 then Func := Log10(Arg) else if AnsiCompareText(FuncName, 'tg') = 0 then Func := Tan(Arg) else if AnsiCompareText(FuncName, 'ctag') = 0 then Func :=Cotan(Arg) else if AnsiCompareText(FuncName, 'arccos') = 0 then Func :=ArcCos(Arg) else if AnsiCompareText(FuncName, 'arcsin') = 0 then Func :=ArcSin(Arg) else if AnsiCompareText(FuncName, 'arctg') = 0 then Func :=ArcTanh(Arg) else if AnsiCompareText(FuncName, 'arccot') = 0 then Func :=ArcCot(Arg) else if AnsiCompareText(FuncName, 'ctag') = 0 then else ShowMessage('Неизвестная функция ' + FuncName); end; function Identifier(var P: Integer): Extended; var InitP: Integer; IDStr, VarValue1,VarValue2: string; begin InitP := P; Inc(P); if S[P] = ('x') then VarValue1 := Form1.Edit2.Text; Identifier:= StrToInt( VarValue1); if S[P] = ('t') then VarValue2 :=Form1.Edit3.Text; Identifier:= StrToInt(VarValue2); end; function Base(var P: Integer): Extended; begin if P > Length(S) then ShowMessage('неожиданный конец строки'); //определяем основание case S[P] of '(': // выражение в скобках begin Inc(P); Base := Expr( P); // если скобка закрыта if (P > Length(S)) or (S[P] <> ')') then ShowMessage( 'ожидается ")" в позиции ' + IntToStr(P)); Inc(P); end; '0'..'9': // число Base := Number(P); 'x','t', 'X','T', '_': //переменные Base := Identifier(P); else ShowMessage( 'Некорректный символ в позиции ' + IntToStr(P)); end; end; function Factor1(var P: Integer): Extended; begin if P > Length(S) then ShowMessage('Неожиданный конец строки'); case S[P] of '+': begin Inc(P); Factor1 := Factor( P); end; '-': begin Inc(P); Factor1 := -Factor( P); end; else begin Factor1 := Base( P); if (P <= Length(S)) and (S[P] = '^') then begin Inc(P); Factor1 := Power(Result, Factor( P)); end; end; end; end; procedure TForm1.Button1Click(Sender: TObject); begin S:=Edit1.Text; P:=1; Edit4.Text:= FloatToStr(Expr(P)); end; end. Последний раз редактировалось Крамер, 16.04.2013 в 20:09. |
#2
|
||||
|
||||
На первый взгляд - в функции Number P задан как var, а тут видна попытка передачи константного (менять нельзя) значения - Number(S[P]), да и Р: интеджер, а S[P] это чарка, несовпадение типов. Нужно заВарить отдельную переменную для передачи в функцию, ну и с приведением к типу разобраться. напр
Код:
var ds: integer; begin ds:=StrToInt(s[p]); Number(ds); ... end; Я не понял Вашего вопроса, но всё же Вам на него отвечу! |