Skocz do zawartości
Bula i spula

[delphi] Dlaczego źle Działa Ten Kalkulator?

Rekomendowane odpowiedzi

Witam!

 

Postanowiłęm sobie stworzyć kalkulator.

Najpierw stworzyłem najprostszy z numerami, +, -, *, /, %, ^2 i ^3 i jednym wyświetlaczem.

I postanowiłem dla ćwiczenia zrobić taki kalkulator z tablicami. chociaż ten sam efekt można by uzyskać i bez nich. Najpierw spójrzcie w kod:

 

unit Unit1;interfaceuses  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  Dialogs, StdCtrls;type  TForm1 = class(TForm)	ce: TButton;	zglos: TButton;	off: TButton;	plus: TButton;	minus: TButton;	razy: TButton;	podzielic: TButton;	procent: TButton;	potega2: TButton;	potega3: TButton;	plusminus: TButton;	rownasie: TButton;	koma: TButton;	num0: TButton;	num1: TButton;	num2: TButton;	num4: TButton;	num3: TButton;	num5: TButton;	num6: TButton;	num7: TButton;	num8: TButton;	num9: TButton;	wyswietlacz1: TEdit;	wyswietlacz2: TEdit;	wyswietlacz3: TEdit;	pr1: TRadioButton;	pr2: TRadioButton;	pr3: TRadioButton;	pr4: TRadioButton;	pr5: TRadioButton;	pr6: TRadioButton;	pr7: TRadioButton;	pr8: TRadioButton;	pr0: TRadioButton;	okreslone: TCheckBox;	miejsce: TLabel;	przecinku: TLabel;	procedure ceClick(Sender: TObject);	procedure zglosClick(Sender: TObject);	procedure offClick(Sender: TObject);	procedure num0Click(Sender: TObject);	procedure num1Click(Sender: TObject);	procedure num2Click(Sender: TObject);	procedure num3Click(Sender: TObject);	procedure num4Click(Sender: TObject);	procedure num5Click(Sender: TObject);	procedure num6Click(Sender: TObject);	procedure num7Click(Sender: TObject);	procedure num8Click(Sender: TObject);	procedure num9Click(Sender: TObject);	procedure komaClick(Sender: TObject);	procedure plusClick(Sender: TObject);	procedure minusClick(Sender: TObject);	procedure razyClick(Sender: TObject);	procedure podzielicClick(Sender: TObject);	procedure potega2Click(Sender: TObject);	procedure potega3Click(Sender: TObject);	procedure plusminusClick(Sender: TObject);		procedure rownasieClick(Sender: TObject);	procedure okresloneClick(Sender: TObject);	procedure pr1Click(Sender: TObject);	procedure pr2Click(Sender: TObject);	procedure pr3Click(Sender: TObject);	procedure pr4Click(Sender: TObject);	procedure pr5Click(Sender: TObject);	procedure pr6Click(Sender: TObject);	procedure pr7Click(Sender: TObject);	procedure pr8Click(Sender: TObject);	procedure pr0Click(Sender: TObject);  private	{ Private declarations }  public	{ Public declarations }  end;var  Form1: TForm1;  glowna:double;  liczby:array [1..50] of double;  dzialanie: array [1..50] of string;  ilosc:byte;  wynik:string;implementation{$R *.dfm}procedure TForm1.offClick(Sender: TObject); begin	halt;  end;procedure TForm1.ceClick(Sender: TObject);  var p:byte;  begin	wyswietlacz1.text:='0';	wyswietlacz2.Text:='';	wyswietlacz3.Text:='';	ilosc:=0;	for p:=0 to 50 do liczby[p]:=0;	for p:=0 to 50 do dzialanie[p]:='';  end;procedure TForm1.num1Click(Sender: TObject);  begin	  if wyswietlacz2.text='=' then		begin		  wyswietlacz1.Text:='1';		  wyswietlacz3.Text:='';		  wyswietlacz2.Text:='';		end;	  if wyswietlacz1.text='0'		then wyswietlacz1.Text:='1'		else wyswietlacz1.text:=wyswietlacz1.Text+'1';  end;procedure TForm1.num2Click(Sender: TObject);  begin	if wyswietlacz2.text='=' then	  begin		wyswietlacz3.Text:='';		wyswietlacz1.Text:='1';		wyswietlacz2.Text:='';	  end;	if wyswietlacz1.text='0'	  then wyswietlacz1.Text:='2'	  else wyswietlacz1.text:=wyswietlacz1.Text+'2';  end;procedure TForm1.num3Click(Sender: TObject);  begin	if wyswietlacz2.text='=' then	  begin		wyswietlacz3.Text:='';		wyswietlacz1.Text:='1';		wyswietlacz2.Text:='';	  end;	if wyswietlacz1.text='0'	  then wyswietlacz1.Text:='3'	  else wyswietlacz1.text:=wyswietlacz1.Text+'3';  end;procedure TForm1.num4Click(Sender: TObject);  begin	if wyswietlacz2.text='=' then	  begin		wyswietlacz3.Text:='';		wyswietlacz1.Text:='1';		wyswietlacz2.Text:='';	  end;	if wyswietlacz1.text='0'	  then wyswietlacz1.Text:='4'	  else wyswietlacz1.text:=wyswietlacz1.Text+'4';  end;procedure TForm1.num5Click(Sender: TObject);  begin	if wyswietlacz2.text='=' then	  begin		wyswietlacz3.Text:='';		wyswietlacz1.Text:='1';		wyswietlacz2.Text:='';	  end;	if wyswietlacz1.text='0'	  then wyswietlacz1.Text:='5'	  else wyswietlacz1.text:=wyswietlacz1.Text+'5';  end;procedure TForm1.num6Click(Sender: TObject);  begin	if wyswietlacz2.text='=' then	  begin		wyswietlacz3.Text:='';		wyswietlacz1.Text:='1';		wyswietlacz2.Text:='';	  end;	if wyswietlacz1.text='0'	then wyswietlacz1.Text:='6'	else wyswietlacz1.text:=wyswietlacz1.Text+'6';  end;procedure TForm1.num7Click(Sender: TObject);  begin	if wyswietlacz2.text='='	  then		begin		  wyswietlacz3.Text:='';		  wyswietlacz1.Text:='1';		  wyswietlacz2.Text:='';		end;	if wyswietlacz1.text='0'	then wyswietlacz1.Text:='7'	else wyswietlacz1.text:=wyswietlacz1.Text+'7';  end;procedure TForm1.num8Click(Sender: TObject);  begin	if wyswietlacz2.text='='	  then		begin		  wyswietlacz3.Text:='';		  wyswietlacz1.Text:='1';		  wyswietlacz2.Text:='';		end;	if wyswietlacz1.text='0'	  then wyswietlacz1.Text:='8'	  else wyswietlacz1.text:=wyswietlacz1.Text+'8';  end;procedure TForm1.num9Click(Sender: TObject);  begin	if wyswietlacz2.text='='	  then		begin		  wyswietlacz3.Text:='';		  wyswietlacz1.Text:='1';		  wyswietlacz2.Text:='';		end;	if wyswietlacz1.text='0'	  then wyswietlacz1.Text:='9'	  else wyswietlacz1.text:=wyswietlacz1.Text+'9';  end;procedure TForm1.num0Click(Sender: TObject);  begin	if wyswietlacz2.text='='	  then		begin		  wyswietlacz3.Text:='';		  wyswietlacz1.Text:='1';		  wyswietlacz2.Text:='';		end;	if wyswietlacz1.text='0'	  then	  else wyswietlacz1.text:=wyswietlacz1.Text+'0';  end;procedure TForm1.komaClick(Sender: TObject);  begin	if wyswietlacz1.text=''	  then wyswietlacz1.Text:='0,'	  else wyswietlacz1.text:=wyswietlacz1.Text+',';  end;procedure TForm1.plusClick(Sender: TObject);begin  if ilosc=0 then	begin	  ilosc:=ilosc+1;	  glowna:=strtofloat(wyswietlacz1.text);	end  else	begin	  ilosc:=ilosc+1;	  liczby[ilosc]:=strtofloat(wyswietlacz1.text);	  dzialanie[ilosc]:='dodac';	end;  wyswietlacz1.Text:='';  wyswietlacz2.Text:='+';  wyswietlacz3.Text:=floattostr(glowna);end;procedure TForm1.minusClick(Sender: TObject);begin  if ilosc=0 then	begin	  ilosc:=1;	  glowna:=strtofloat(wyswietlacz1.text);	  dzialanie[ilosc]:='odjac';	end  else	begin	  ilosc:=ilosc+1;	  liczby[ilosc]:=strtofloat(wyswietlacz1.text);	  dzialanie[ilosc]:='odjac';	end;  wyswietlacz1.Text:='';  wyswietlacz2.Text:='-';  wyswietlacz3.Text:=floattostr(glowna);end;procedure TForm1.razyClick(Sender: TObject);begin  if ilosc=0 then	begin	  ilosc:=1;	  glowna:=strtofloat(wyswietlacz1.text);	  dzialanie[ilosc]:='razy';	end  else	begin	  ilosc:=ilosc+1;	  liczby[ilosc]:=strtofloat(wyswietlacz1.text);	  dzialanie[ilosc]:='razy';	end;  wyswietlacz1.Text:='';  wyswietlacz2.Text:='*';  wyswietlacz3.text:=floattostr(glowna);end;procedure TForm1.podzielicClick(Sender: TObject);begin  if ilosc=0 then	begin	  ilosc:=1;	  glowna:=strtofloat(wyswietlacz1.text);	  dzialanie[ilosc]:='podzielic';	end  else	begin	  ilosc:=ilosc+1;	  liczby[ilosc]:=strtofloat(wyswietlacz1.text);	  dzialanie[ilosc]:='podzielic';	end;  wyswietlacz1.Text:='';  wyswietlacz2.Text:='/';  wyswietlacz3.Text:=floattostr(glowna);end;procedure TForm1.potega2Click(Sender: TObject);  var	e:double;  begin	wyswietlacz3.text:=wyswietlacz1.Text;	e:=strtofloat(wyswietlacz1.Text);	e:=e*e;	wyswietlacz1.text:=floattostr(e);	wyswietlacz2.Text:='^2';  end;procedure TForm1.potega3Click(Sender: TObject);  var	e:double;  begin	e:=strtofloat(wyswietlacz1.Text);	e:=e*e*e;	wyswietlacz1.text:=floattostr(e);	wyswietlacz2.Text:='^3';  end;procedure TForm1.plusminusClick(Sender: TObject);  var	p:double;  begin	p:=strtofloat(wyswietlacz1.Text);	p:=0-p;	wyswietlacz1.Text:=floattostr(p);	wyswietlacz2.Text:='+/-';  end;procedure TForm1.rownasieClick(Sender: TObject);  var	p:byte;  begin	ilosc:=ilosc+1;	p:=0;	for p:=0 to 50 do	  begin		if dzialanie[p]='dodac'		  then			begin			  glowna:=glowna+liczby[p];			end;	  end;	for p:=0 to 50 do	  begin		if dzialanie[p]='odjac'		  then			begin			  glowna:=glowna-liczby[p];			end;	  end;	for p:=0 to 50 do	  begin		if dzialanie[p]='razy'		  then			begin			  glowna:=glowna*liczby[p];			end;	  end;	for p:=0 to 50 do	  begin		if dzialanie[p]='podzielic'		  then			begin			  glowna:=glowna/liczby[p];			end;	  end;	wynik:=floattostr(glowna);	wyswietlacz1.text:=wynik;	wyswietlacz2.text:='=';  end;procedure TForm1.okresloneClick(Sender: TObject);beginif okreslone.checked=true then  begin	pr0.Visible:=true;	pr1.Visible:=true;	pr2.Visible:=true;	pr3.Visible:=true;	pr4.Visible:=true;	pr5.Visible:=true;	pr6.Visible:=true;	pr7.Visible:=true;	pr8.Visible:=true;  endelse  begin	pr0.Visible:=false;	pr1.Visible:=false;	pr2.Visible:=false;	pr3.Visible:=false;	pr4.Visible:=false;	pr5.Visible:=false;	pr6.Visible:=false;	pr7.Visible:=false;	pr8.Visible:=false;  end;end;procedure TForm1.pr1Click(Sender: TObject);  var	c:string;  begin	c:=floattostrf(glowna, ffFixed, 25, 1);	wyswietlacz1.Text:=c;  end;procedure TForm1.pr2Click(Sender: TObject);  var	c:string;  begin	c:=floattostrf(glowna, ffFixed, 25, 2);	wyswietlacz1.Text:=c;  end;procedure TForm1.pr3Click(Sender: TObject);  var	c:string;  begin	c:=floattostrf(glowna, ffFixed, 25, 3);	wyswietlacz1.Text:=c;  end;procedure TForm1.pr4Click(Sender: TObject);  var	c:string;  begin	c:=floattostrf(glowna, ffFixed, 25, 4);	wyswietlacz1.Text:=c;  end;procedure TForm1.pr5Click(Sender: TObject);  var	c:string;  begin	c:=floattostrf(glowna, ffFixed, 25, 5);	wyswietlacz1.Text:=c;  end;procedure TForm1.pr6Click(Sender: TObject);  var	c:string;  begin	c:=floattostrf(glowna, ffFixed, 25, 6);	wyswietlacz1.Text:=c;  end;procedure TForm1.pr7Click(Sender: TObject);  var	c:string;  begin	c:=floattostrf(glowna, ffFixed, 25, 7);	wyswietlacz1.Text:=c;  end;procedure TForm1.pr8Click(Sender: TObject);  var	c:string;  begin	c:=floattostrf(glowna, ffFixed, 25, 8);	wyswietlacz1.Text:=c;  end;procedure TForm1.pr0Click(Sender: TObject);  var	c:string;  begin	c:=floattostrf(glowna, ffFixed, 25, 0);	wyswietlacz1.Text:=c;  end;procedure TForm1.zglosClick(Sender: TObject);  begin	showmessage('W tym programie nie ma błędów!!! Musiałes cos przeoczyc lub źle zrozumiec!!!');  end;end

(bajery typu wyswietlacz3 jeszcze nieskończone)

No i sami zobazcie jak on działa:

2+2=2

2+2+2=6

2+2+2+2=8

2*2=2

2*2*2=8

2*2*2*2=16

itd.

 

Gdzie popełniłem błąd??

Pomóżcie, bo głowięsięnad tym od przedwczoraj, próbowałem róznych drobnych zmian, ale nie przyniosło to porządanego efektu. Sam nie wiem co jest nie tak.

 

Link do źródeł i skompilowanego programu.

 

Z góry dziękuję za pomoc

Pozdrawiam

Bula i spula

 

edit1/Nie działał link, ale już go poprawiłem.

Edytowane przez Bula i spula

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

proponuję nauczyć sie debugowania programów... Jest tam w delfim takie coś jak PRACA KROKOWA programu. Uruchamiasz program i wtedy lecisz linijka po linijce... po najechaniu kursorem myszki na zmienną widzisz jej aktualną wartość... i patrzysz kro po kroku jak sie zmienia ta zmienna wcześniej wyliczając sobie ją w pamięci...

 

W pracy krokowej masz dwa rodzaje kroków.. step in i step over... Step in powoduje że jeśli nacisjniesz ten przycisk ( lub klawisz F7 chyba) to jeśli w aktualnej linijce masz odwólanie do funkcji to zostaniesz przeniesiony do ciała tej funkcji (w edytorze kodu). Jeśli dasz setp over to funkcja (procedura) sie wykona w tle i zwróci tylko to co ma zwrócić...

 

Jest jeszcze cos takiego jak breakpointy... Umieszczasz to w podejrzanym miejscu w kodzie... najczęściej przydaje się w większych programach uruchamaisz program normalnie a jeśli dotrez on do tej linii w kodzie to sie zatrzyma i będziesz mógł dalej robić pracę krokowa..

 

Przy odrobinie logiki, inteligencji i sprytu jaki odróżnia programistę od zwykłych ludzi :D powinieneś to szybko opanować i stosować.. To bardzo ułatwia debugowanie programów...

 

W C++ Builderze jest jeszcze codeguard... przydaje się zwłaszcza gdy sa problemy ze wskaźnikami, tablicami etc.. ale to już inna bajka :)

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Link już funkcjonuje. A możesz mi PelzaK wytłumaczyć jak używać tego step over, i jak się tworzy te breakpointy, bo ja jakoś nie potrafię. Mam delphi 7. No i naciskam run->step over i co dalej??

 

edit1/Ahaś, udało mi się utworzyć breakpoint i dojść do niego za pomocą step over. Tylko jak wyświetlić te zmienne?? Podejrzewam, że może coś przy tych pętelkach w procedure rownasie pokręciłem i tam utworzyłem ten punkt, tylko jak mam po każdym przejściu pętli śledzić te zmienne??

 

Z góry dziękuję za pomoc

Pozdrawiam

Bula i spula

Edytowane przez Bula i spula

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

za kazdym wykonaniem polecenia STEP over komputer przetwarza kolejną linię w kodzie.. W delphi z tego co pamietam po najechaniu na zmiennąpojawiał sie hint (dymek) z jej wartością. Jeśli nie to gdzieś w menu VIEW powinny być debug tools/winowds i/lub tam coś takeigo jak show variables, evaluateuate variable etc... wtedy powinny Ci sie pokazwyać na bierząco w tym oknie wszystkie zmienne dostępne w danym bloku programu. Dokładnie Ci nie powiem bo nie używam delphi od 5 lat :)

 

Co do break pointów.. to stawiasz je tam gdzie wydaje Ci się że może sie coś chrzanić... i uruchamiasz normalnie program... Który zatrzyma się dopiero jak wejdzie na breakpointa.. Breakpointy są po to abyś nie musiał lecieć step overem przez pare tysiecy linii kodu zanim dotrzesz w miejsce w które chcesz :)

 

I jeśli debugujesz pętle to tak.. stawiasz breakpointa przed pętla (może być na for....) i uruchamiasz program.. Wprowadzasz se liczby do wymozenia... np 2 x 2 i = ... wtedy jak program dojrdzie do pętli na której jest breakpoint to sie zatrzyma (pauza) i jesteś w trybie pracy krokowej.. Sprawdzasz czy wpisane wartości do wymnozenia napewno są takei jak podałeś... rpzed wejsciem w pętle.. i stepujesz... monitorując jak sie zmieniają zmienne...

 

Przy liczbach 2 x 2 to będziesz miał niewiele iteracji więc to jeszzce żaden problem... a w krótką chwile zdiagnozujesz w czym problem.

 

Pomyśl że ja muszę np diagnozować pętle wielokrotne z mnóstwem wywoływanych funkcji i z iteracjami po kilkadziesiąt... Ale zazwyczaj wystarczy preśledzieć 2..3 iteracje żeby wychwycić gdzie jest błąd...

 

Jak nie to jest też możliwość uaktywnienia break pointa po iluś tam przejsciach... np w pętli.. 10x breakpoint nie zatrzymuje a 11 raz zatrzyma wykonywanie programu

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Udało się! Ciężko mi wytłumaczyć co było źle... Tak jakby jak się nacisnęło np. 1+1, to on to zapisywał jako liczby[1]:=1, działanie[1]:='dodac' i liczby[2]:=1. A przy równaniu liczył:

procedure TForm1.rownasieClick(Sender: TObject);  var	p:byte;  begin	ilosc:=ilosc+1;	p:=0;	for p:=0 to 50 do	  begin		if dzialanie[p]='dodac'		  then			begin			  glowna:=glowna+liczby[p];			end;	  end;	for p:=0 to 50 do	  begin		if dzialanie[p]='odjac'		  then			begin			  glowna:=glowna-liczby[p];			end;	  end;	for p:=0 to 50 do	  begin		if dzialanie[p]='razy'		  then			begin			  glowna:=glowna*liczby[p];			end;	  end;	for p:=0 to 50 do	  begin		if dzialanie[p]='podzielic'		  then			begin			  glowna:=glowna/liczby[p];			end;	  end;	wynik:=floattostr(glowna);	wyswietlacz1.text:=wynik;	wyswietlacz2.text:='=';  end;

tj.

jeśli dzialanie[1] (nie wiem dlaczego, ale jak jest for x:=0 to liczy od jeden, for x:=1 to od dwóch itd.) = dodawanie to wynik:=wynik+liczba[1] i koniec, bo nie było wprowadzonej dzialanie[2], więc wychodzi 0+liczba[1], a miało być liczba[1]+liczba[2]. rozwiązaniem okazało się na początku procedury rownasię wpisać wynik (w programie nazwa zmiennej glowna):=liczba[1], a w rownasie rozpocząć liczenie od dwóch (tj. for p:=1):

jeśli działanie[2(p)-1]='dodawanie' to wynik (już z liczbą[1], którą wprowadziłem na początku procedury):=wynik+liczba[2] i to samo z mnożeniem, dzieleniem itd. Dziękuję wszystkim za wskazówki, a w szczególności PeŁzakowi, który mnie przy okazji nauczył bardzo przydatnego stepowania, tworzenia breakpointów itp.

 

p.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.

Gość
Dodaj odpowiedź do tematu...

×   Wklejono zawartość z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Odnośnik został automatycznie osadzony.   Przywróć wyświetlanie jako odnośnik

×   Przywrócono poprzednią zawartość.   Wyczyść edytor

×   Nie możesz bezpośrednio wkleić grafiki. Dodaj lub załącz grafiki z adresu URL.

Ładowanie


×
×
  • Dodaj nową pozycję...