Prezentowane materiały są przeznaczone dla uczniów szkół ponadgimnazjalnych. Autor artykułu: mgr Jerzy Wałaszek, wersja1.0 |
©2011 mgr
Jerzy Wałaszek
|
a b + oznacza a + b
a b * oznacza a * b
Na dzisiejszych zajęciach zaprogramujemy prosty kalkulator działający w ONP. Dane wprowadzane do kalkulatora będą przechowywane na stosie pięcio-elementowym. Działania będą zawsze wykonywane na elementach znajdujących się na szczycie stosu.
Utwórz na swoim dysku twardym odpowiedni katalog dla projektu. My kolejne projekty zapisujemy w numerowanych katalogach: 001, 002, itd. Dzięki temu pliki nigdy się nie mieszają.
Uruchom środowisko Borland C++ Builder 6 Personal. Projekt zapisz w utworzonym wcześniej katalogu za pomocą opcji menu:
Pierwszy zapisywany jest plik modułu. Pozostaw jego nazwę niezmienioną: Unit1. Drugi plik jest plikiem projektu. Tutaj zmień nazwę na rpncalc. Jeśli wykonałeś poprawnie tę operację, to w katalogu projektu powinny znaleźć się następujące pliki:
rpncalc.bpr | - | plik zawiera informacje dotyczące projektu |
rpncacl.cpp | - | plik programu projektu |
rpncalc.res | - | tzw. plik zasobów projektu |
Unit1.cpp | - | plik modułu obsługującego okno główne |
Unit1.dfm | - | plik definiujący parametry użytych komponentów w oknie głównym |
Unit1.h | - | plik nagłówkowy modułu |
W oknie Object Inspector znajdują się własności okna programu. Będziemy je zmieniać, idąc od góry na dół.
BorderIcons→biMaximize = false
Parametr ten powoduje wyłączenie przycisku maksymalizacji. Użytkownik
będzie mógł jedynie zminimalizować lub zamknąć okno kalkulatora.
BorderStyle = bsSingle
Rozmiarów okna użytkownik nie będzie mógł zmieniać.
Caption = Kalkulator ONP
Tytuł okna programu
Name = frmCalc
Pod taką nazwą będzie widoczny w programie egzemplarz klasy naszego
okna. Umawiamy się, że pierwsze trzy literki nazwy zawsze określają
rodzaj obiektu - dzięki temu szybko znajdziemy go na liście w oknie
Object TreeView - frm to Form, czyli okno.
Position = poDesktopCenter
Po uruchomieniu programu nasze okno pojawi się na środku pulpitu.
Na tak przygotowanym oknie umieścimy teraz komponent etykiety - Label. Etykiety pozwalają wyświetlać dowolny tekst. Kliknij dwukrotnie w ikonę A na pasku narzędziowym komponentów. Następnie w Object Inspector ustawiamy własności etykiety:
Autosize = false
Etykieta nie będzie się automatycznie dostosowywała do szerokości
zawartego w niej tekstu.
Left = 8
Pozycja lewej krawędzi etykiety na obszarze okna.
Top = 8
Pozycja górnej krawędzi etykiety na obszarze okna.
Width = 249
Szerokość etykiety
Kliknij raz myszką w etykietę, aby ją wybrać, a następnie skopiuj do schowka za pomocą klawiszy Ctrl+C. Teraz wklej cztery razy etykietę ze schowka do okienka. W efekcie na oknie będzie się znajdowało 5 etykiet. Ustaw je jedna pod drugą za pomocą myszki:
Wybierz myszką ostatnią etykietę u dołu i zmień w oknie Object Inspector jej własność Name na lblS0 (lbl oznacza Label, czyli etykietę). Idąc w górę nazwij kolejne etykiety lblS1...lblS4. Przy najwyższej etykiecie napis zmieni się na lblS4 - nie przejmuj się tym, tak ma być.
Etykiety te będą nam służyły jako prosty stos. Będziemy w nich przechowywać liczby w postaci napisów.
Pod etykietami umieść komponent Edit, powiększając go na odpowiednią szerokość. Umożliwia on wprowadzanie tekstu. Jego własność Name ustaw na edtInput (edt oznacza Edit).
Teraz umieść w oknie komponent przycisku - Button. Pomniejsz go myszką na szerokość Width = 35 (gdy skalujesz komponent, to w żółtym prostokącie pokazywane są jego aktualne wymiary). Tak przygotowany przycisk skopiuj do schowka (Ctrl+C), a następnie wklej 9 razy - w oknie powinno pojawić się 10 przycisków. Umieść je w dwóch rzędach pod komponentem edtInput. W pierwszym rzędzie 6 przycisków (ostatni przycisk możesz trochę poszerzyć, aby zgrał się z komponentem edtInput), w drugim 4:
Pozmieniaj własności Caption przycisków (na przycisku minus umieszczamy 3 minusy, ponieważ jeden jest zbyt mało widoczny):
Teraz odpowiednio zmienimy własności Name każdego z przycisków:
(btn oznacza Button, czyli przycisk).
Funkcje przycisków będą następujące:
btnCLR | - | zeruje cały kalkulator, umieszcza 0 we wszystkich elementach stosu, czyści tekst w edtInput. |
btnADD | - | dodaje dwa ostatnie elementy stosu |
btnSUB | - | odejmuje dwa ostatnie elementy stosu |
btnMUL | - | mnoży dwa ostatnie elementy stosu |
btnDIV | - | dzieli dwa ostatnie elementy stosu |
btnENT | - | przepisuje liczbę z edtInput na stos |
btnDEL | - | usuwa ze stosu ostatni element |
btnDUP | - | kopiuje na stos ostatni element |
btnEX | - | zamienia miejscami dwa ostatnie elementy na stosie |
btnSQR | - | oblicza pierwiastek kwadratowy z ostatniego elementu stosu |
Dopasuj rozmiary okna programu:
Kliknij myszką przycisk btnENT i ustaw jego własność Default na true. Spowoduje to, iż przycisk ten będzie automatycznie aktywowany za każdym razem, gdy naciśniesz klawisz Enter. Zwróć uwagę, że przycisk ten jest rysowany w oknie w czarnym prostokącie:
Skompiluj i uruchom aplikację. Interfejs jest gotowy, teraz zaprogramujemy jego obsługę.
Uwaga. Przy tworzeniu funkcji obsługujących zdarzenia należy korzystać z opcji środowiska Borland C++ Builder, a nie wpisywać kod ręcznie.
Na początek zaprogramujemy zdarzenie kliknięcia przycisku btnCLR. Funkcję obsługi tego zdarzenia tworzysz szybko klikając dwukrotnie myszką w przycisk C. Środowisko przenosi cię do edytora kodu programu, gdzie powinieneś zobaczyć pustą funkcję:
//--------------------------------------------------------------------------- void __fastcall TfrmCalc::btnCLRClick(TObject *Sender) { } //---------------------------------------------------------------------------
Funkcja ta została utworzona w pliku modułu Unit1.cpp. Jest to funkcja składowa klasy TfrmCalc, czyli naszego okna. Wpisz do niej następujący kod:
//--------------------------------------------------------------------------- void __fastcall TfrmCalc::btnCLRClick(TObject *Sender) { lblS0->Caption = "0"; // zerujemy kolejne elementy stosu lblS1->Caption = "0"; lblS2->Caption = "0"; lblS3->Caption = "0"; lblS4->Caption = "0"; edtInput->Text = ""; // czyścimy wiersz wejścia } //---------------------------------------------------------------------------
Dostęp do tekstu wyświetlanego przez etykiety uzyskujemy poprzez ich własności Caption. Wiersz edycji jest dostępny poprzez własność Text. Jeśli teraz skompilujesz i uruchomisz aplikację, to po kliknięciu w przycisk C nastąpi wyzerowanie kalkulatora:
Jednakże efekt ten chcielibyśmy uzyskać od razu na początku programu, aby kalkulator startował od tego stanu. Zamknij aplikację i przejdź do okna interfejsu (jeśli nie jest widoczne, wciśnij klawisz F12, który przełącza pomiędzy edytorem kodu a oknem interfejsu). Kliknij myszką w obszar niezajęty przez komponenty, aby w Object Inspector dostać własności okna (możesz również wybrać obiekt frmCalc w oknie Object TreeView). Teraz przejdź na zakładkę Events (zdarzenia) i wyszukaj zdarzenia o nazwie onCreate. Zdarzenie to pojawia się, gdy dany obiekt jest tworzony, czyli, w przypadku okna głównego, na początku działania aplikacji. Kliknij raz w zdarzenie onCreate, aby je wybrać, następnie kliknij strzałeczkę w dół, aby rozwinąć listę zdefiniowanych już funkcji obsługi zdarzeń. Na liście tej powinna występować funkcja btnCLRClick, która obsługuje kliknięcie przycisku C. Wybierz ją dla zdarzenia onCreate okna.
Co zrobiliśmy? Kazaliśmy, aby zdarzenie onCreate dla okna aplikacji obsługiwała funkcja kliknięcia przycisku C. W ten sposób wykorzystujemy już wcześniej utworzony kod do nowych zadań. Gdy teraz skompilujesz i uruchomisz program, kalkulator wystartuje w stanie wyzerowanym, jakbyś kliknął przycisk C.
Kolejną czynnością będzie utworzenie dwóch funkcji usługowych, które obsługują stos:
push(v) | - | przesuwa zawartość stosu w górę, a v umieszcza na spodzie. |
pop() | - | pobiera spód stosu i przemieszcza jego zawartość w dół |
Funkcje te nie obsługują zdarzeń, jednakże muszą posiadać dostęp do komponentów lblS0...lblS4. Dlatego będą funkcjami składowymi klasy naszego okna. Najpierw w definicji klasy umieścimy informację, że klasa takie funkcje posiada. Przejdź do edytora kodu (klawisz F12) i naciśnij Ctrl+F6. Zostaniesz przeniesiony do pliku nagłówkowego Unit1.h. W pliku tym znajduje się definicja klasy okna:
class TfrmCalc : public TForm { __published: // IDE-managed Components TLabel *lblS4; TLabel *lblS3; TLabel *lblS2; TLabel *lblS1; TLabel *lblS0; TEdit *edtInput; TButton *btnSQR; TButton *btnEX; TButton *btnDUP; TButton *btnDEL; TButton *btnENT; TButton *btnDIV; TButton *btnMUL; TButton *btnSUB; TButton *btnADD; TButton *btnCLR; void __fastcall btnCLRClick(TObject *Sender); private: // User declarations public: // User declarations __fastcall TfrmCalc(TComponent* Owner); };
W definicji tej mamy trzy bloki: __published, private i public. Nasze definicje dopisujemy ręcznie w bloku public:
class TfrmCalc : public TForm { __published: // IDE-managed Components TLabel *lblS4; TLabel *lblS3; TLabel *lblS2; TLabel *lblS1; TLabel *lblS0; TEdit *edtInput; TButton *btnSQR; TButton *btnEX; TButton *btnDUP; TButton *btnDEL; TButton *btnENT; TButton *btnDIV; TButton *btnMUL; TButton *btnSUB; TButton *btnADD; TButton *btnCLR; void __fastcall btnCLRClick(TObject *Sender); private: // User declarations public: // User declarations __fastcall TfrmCalc(TComponent* Owner); double pop(); // pobiera daną ze stosu void push(double v); // umieszcza daną na stosie };
Gdy wpiszesz prototypy funkcji pop() i push() do definicji klasy TfrmCalc, naciśnij Ctrl+F6, aby powrócić do modułu Unit1.cpp. Teraz na końcu pliku dopisz ręcznie definicje tych funkcji:
double TfrmCalc::pop() { double v; v = StrToFloat(lblS0->Caption); // odczytujemy ostatni element lblS0->Caption = lblS1->Caption; // przesuwamy stos w dół lblS1->Caption = lblS2->Caption; lblS2->Caption = lblS3->Caption; lblS3->Caption = lblS4->Caption; lblS4->Caption = "0"; // ostatni element stosu zerujemy return v; // zwracamy odczytany element } //--------------------------------------------------------------------------- void TfrmCalc::push(double v) { lblS4->Caption = lblS3->Caption; // przesuwamy stos w górę lblS3->Caption = lblS2->Caption; lblS2->Caption = lblS1->Caption; lblS1->Caption = lblS0->Caption; lblS0->Caption = FloatToStr(v); // wartość v zapisujemy na spodzie stosu } //---------------------------------------------------------------------------
Teraz dodamy obsługę przycisku ENT. W tym celu kliknij go dwukrotnie myszką, aby środowisko utworzyło dla niego funkcję obsługującą kliknięcie. Do funkcji tej wpisz kod:
//--------------------------------------------------------------------------- void __fastcall TfrmCalc::btnENTClick(TObject *Sender) { if(edtInput->Text != "") { push(StrToFloat(edtInput->Text)); // przesyłamy liczbę na stos edtInput->Text = ""; // czyścimy wiersz wejścia } } //---------------------------------------------------------------------------
Jeśli skompilujesz i uruchomisz aplikację, to będziesz już mógł wprowadzać na stos liczby:
Zwróć uwagę, że w naszym kalkulatorze stos może przechowywać tylko pięć liczb w etykietach. Jeśli wprowadzisz więcej, to górna liczba będzie utracona.
W podobny sposób tworzysz pozostałe funkcje obsługi kliknięć przycisków. Poniżej podajemy ich kody, jednakże pamiętaj, aby funkcję utworzyć za pomocą mechanizmów środowiska (klikając dwukrotnie w przycisk lub w odpowiednie zdarzenie na zakładce Events w oknie Object Inspector dla danego komponentu). Do edytora przepisujesz tylko treść funkcji. Zwracam na to uwagę, ponieważ uczniowie często zapominają o tej "drobnostce", a później programu nie daje się uruchomić.
//--------------------------------------------------------------------------- void __fastcall TfrmCalc::btnADDClick(TObject *Sender) { push(pop()+pop()); } //---------------------------------------------------------------------------
//--------------------------------------------------------------------------- void __fastcall TfrmCalc::btnSUBClick(TObject *Sender) { push(-pop()+pop()); } //---------------------------------------------------------------------------
//--------------------------------------------------------------------------- void __fastcall TfrmCalc::btnMULClick(TObject *Sender) { push(pop()*pop()); } //---------------------------------------------------------------------------
//--------------------------------------------------------------------------- void __fastcall TfrmCalc::btnDIVClick(TObject *Sender) { push(1/pop()*pop()); } //---------------------------------------------------------------------------
//--------------------------------------------------------------------------- void __fastcall TfrmCalc::btnDELClick(TObject *Sender) { pop(); } //---------------------------------------------------------------------------
//--------------------------------------------------------------------------- void __fastcall TfrmCalc::btnDUPClick(TObject *Sender) { double v = pop(); push(v); push(v); } //---------------------------------------------------------------------------
//--------------------------------------------------------------------------- void __fastcall TfrmCalc::btnEXClick(TObject *Sender) { double x,y; x = pop(); y = pop(); push(x); push(y); } //---------------------------------------------------------------------------
Tutaj na początku pliku Unit1.cpp musisz dołączyć plik nagłówkowy z definicjami funkcji matematycznych za pomocą polecenia #include <math.h>
//--------------------------------------------------------------------------- void __fastcall TfrmCalc::btnSQRClick(TObject *Sender) { push(sqrt(pop())); } //---------------------------------------------------------------------------
Skompiluj i uruchom aplikację. Kalkulator jest gotowy, miłej zabawy. Dla prostoty kodu nie obsługujemy ewentualnych błędów, które mogą się pojawić przy współpracy z użytkownikiem.
W ramach ćwiczeń możesz pododawać do niego różnych funkcji matematycznych, np. SIN, COS, TAN, LN, EXP, itp.
I Liceum Ogólnokształcące |
Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl
W artykułach serwisu są używane cookies. Jeśli nie chcesz ich otrzymywać,
zablokuj je w swojej przeglądarce.
Informacje dodatkowe