Opowieść o programowaniu w Adzie



Pobieranie 0.69 Mb.
Strona2/16
Data28.04.2016
Rozmiar0.69 Mb.
1   2   3   4   5   6   7   8   9   ...   16

Trochę matematyki


Wróćmy do programu pr3. Od dłuższego czasu wspominamy o liczbach typu integer. Skąd jednak wiemy, że działamy na liczbach jakiegoś typu i jakie to powoduje konsekwencje?

Za pomocą linii


a,b : integer;
umieszczonej w części deklaracyjnej programu zadeklarowaliśmy zmienne o nazwach a i a jako będące typu integer. Deklaracja zmiennych powoduje dla każdej zmiennej zarezerwowanie w pamięci komputera obszaru o ściśle określonym, wymaganym dla danego typu rozmiarze. Zmiennym tym nadajemy następnie konkretne wartości, które podajemy w trakcie wykonywania instrukcji int_io.get(nazwa_zmiennej). Liczby te nie mogą zawierać kropki dziesiętnej, dozwolony jest natomiast znak podkreślenia w roli separatora (5_345_566 jest bardziej czytelne niż 5345566). Na podanych liczbach wykonujemy działania: + (dodawanie), - (odejmowanie), * (mnożenie), / (dzielenie), ** (potęgowanie), abs (wartość bezwzględna), rem i mod. Możemy stosować także jednoargumentowe operatory + i - dające liczbę o określonym znaku. Wynik działań na liczbach typu integer jest również tego samego typu. Zauważmy, że dzieje się tak nawet w przypadku dzielenia. Jest to w tym wypadku dzielenie całkowite (np. 5/2 daje wynik 2). Operacje rem i mod dają w wyniku liczby spełniające odpowiednio równości:
A = (A/B)*B + ( A rem B )
( |A rem B| < |B|, A rem B ma ten sam znak, co A)
oraz
A = B * N + ( A mod B ) dla pewnego N całkowitego
( |A mod B| < |B|, A mod B ma ten sam znak, co B).
Operacja rem (od remainder) to reszta z dzielenia, operacja mod (czyt. modulo) jest podobna. Oto przykładowe wyniki działań:
i j i rem j i mod j
12 5 2 2
12 -5 2 -3
-12 5 -2 3
-12 -5 -2 -2
Jak widać, jeśli A i B są tych samych znaków, to wyniki operacji rem i mod są takie same (reszta z dzielenia |A| przez |B|, ze znakiem takim, jak A i B). Różnica występuje dopiero dla argumentów przeciwnych znaków. Wówczas wynik działania jest różnicą między liczbą A a sąsiadującą z nią wielokrotnością B, przy czym wielokrotność tę wybieramy dla mod bardziej "na zewnątrz", czyli dalej od zera, a dla rem - bliżej zera.
W przypadku zapisywania bardziej złożonych wyrażeń kolejność działań (ich priorytet) jest następująca: najpierw abs i **, następnie *, /, rem i mod, a na końcu + i -. Tworząc wyrażenia możemy również używać nawiasów "(" i ")" , czyli okrągłych.
Jeżeli potrzebne są nam ułamki, musimy użyć typu float (zmiennoprzecinkowego). Liczby tego typu posiadają kropkę dziesiętną. (7.1, -12.34, 4.0). Mogą być również zapisywane w postaci wykładniczej, np. -1.35330E+02 czy 4.23567E-04, co oznacza -135.33 i 0.000423567 (litera E - duża lub mała - i następująca po niej liczba są odpowiednikiem pomnożenia przez 10 podniesione do potęgi liczba_napisana_po_E ). Na liczbach typu float wykonujemy takie same działania, jak na liczbach całkowitych. Zabronione jest jednak używanie ich jako wykładnika potęgi. Napisanie
3.2 ** 1.1
spowoduje zgłoszenie błędu (zob. jednak podrozdział Funkcje matematyczne).
W celu wykonywania operacji wejścia/wyjścia na liczbach typu float musimy, podobnie jak w poprzednim przypadku, skonkretyzować odpowiedni pakiet:
package float_io is new ada.text_io.float_io(float);
lub użyć pakietu ada.float_text_io.
Ada nie pozwala na łączenie w jednym wyrażeniu różnych typów. Napisanie np.
1.2 + 4.0 * 2 + 7
spowoduje zgłoszenie błędu, gdyż mnożymy i sumujemy ze sobą liczby typów float i integer. Prawidłowy zapis tego wyrażenia ma postać:
1.2 + 4.0 * 2.0 + 7.0
Problem łączenia różnych typów w jednym wyrażeniu możemy rozwiązać również tak, jak w poniższym programie:
-- program demonstrujacy konwersje typow

-- i konkretyzacje pakietow potrzebnych do operacji

-- wejscia/wyjscia dla liczb typu float i integer
with ada.text_io;

use ada.text_io;


procedure pr5 is
package int_io is new ada.text_io.integer_io(integer);
package flt_io is new ada.text_io.float_io(float);
x,y:integer;

z,wynik:float;

begin

put("Podaj pierwsza liczbe calkowita :");



int_io.get(x);

put("Podaj druga liczbe calkowita :");

int_io.get(y);

new_line;

put("Podaj liczbe rzeczywista :");

flt_io.get(z);

new_line(4);

wynik:=float(x)*float(y)*z;

put("Oto iloczyn tych trzech liczb : ");

flt_io.put(wynik,fore=>4,aft=>5,exp=>0);

end pr5;
Powyższy przykład ilustruje sposób dokonywania konwersji typów - zamiany danych pewnego typu na inny typ instrukcją postaci
typ_żądany ( wartość_zamieniana )
np.

integer (5.0) -- daje 5

float (5) -- daje 5.0

integer (4.1) -- daje 4

integer(4.6) -- daje 5

Zwróćmy jeszcze uwagę na postać instrukcji put. Dla liczb typu float może on przybrać postać

put (liczba, fore => ilość_cyfr_przed_kropką

aft => ilość_cyfr_po_kropce,

exp => ilość_cyfr_w_wykładniku );
Nadanie parametrowi exp wartości 0 powoduje, iż liczby są wyprowadzane nie w postaci wykładniczej, lecz w "zwykłej", jako ułamek dziesiętny.
Jak sama nazwa wskazuje, zmienna może zmieniać swoją wartość w trakcie wykonywania programu. Konkretną wartość możemy jej nadać wykonując instrukcję
get (nazwa_zmiennej)
lub stosując instrukcję podstawienia := , tak jak to widzimy w programach pr3 i pr4. Na przykład
w programie pr4 mamy linię
wynik:=float(x)*float(y)*z;
gdzie za pomocą instrukcji := zmiennej wynik nadajemy wartość obliczoną po prawej stronie. Ponadto jeśli potrzebujemy nadać naszej zmiennej wartość początkową, możemy to uczynić już w części deklaracyjnej programu, równocześnie z deklaracją zmiennej, pisząc
nazwa_zmiennej : typ := wartość;
czyli np.
x : float := 12.1;.
Oto program przykładowy:
-- przyklad, w ktorym nadajemy zmiennej

-- wartosc poczatkowa

-- obliczenie wagi zaladowanego samochodu
with ada.text_io;

use ada.text_io;


procedure pr6 is
package int_io is new ada.text_io.integer_io(integer);

use int_io;

masa_samochodu:integer:=520;

waga_osob,waga_bagazu:integer;

begin

put("Obliczamy mase zaladowanego 'malucha'...");



new_line(2);

put("Podaj mase pasazerow - zaokraglona

do pelnych kilogramow ");

get(waga_osob);

new_line;

put("Podaj mase wlozonego bagazu,

takze w pelnych kilogramach ");

get(waga_bagazu);

masa_samochodu:=masa_samochodu+waga_osob+waga_bagazu;

new_line(3);

put("Zaladowany 'maluch' wazy ");

put(masa_samochodu,0);

put(" kilogramow");

end pr6;
Oprócz zmiennych - zmieniających swoją wartość - możemy deklarować także stałe, które


nie mogą zmieniać swej wartości podczas podczas wykonywania programu. Stałej nadajemy wartość już w momencie jej deklarowania:
nazwa_stałej : constant typ := wartość_stałej ;
np.

y : constant integer:=12;


Ponieważ, jak wiemy, stała nie zmienia swojej wartości podczas działania programu, nie może występować z lewej strony instrukcji podstawienia. Użycie stałej ilustruje następujący przykład:
-- program demonstrujacy uzycie stalych
with ada.text_io;

use ada.text_io;


procedure pr7 is
package flt_io is new ada.text_io.float_io(float);

use flt_io;

procent_podatku : constant float:=0.21;

procent_premii : constant float:=0.20;

premia,placa,podatek,do_wyplaty:float;
begin

put("Podaj place zasadnicza brutto : ");

get(placa);

new_line(3);

put_line(" WYPLATA");

new_line;

premia:=placa*procent_premii;

podatek:=procent_podatku*(placa+premia);

do_wyplaty:=placa+premia-podatek;

put(" placa zasadnicza : ");

put(placa,fore=>5,aft=>2,exp=>0);

new_line;

put(" premia : ");

put(premia,fore=>5,aft=>2,exp=>0);

new_line;

put(" potracony podatek : ");

put(podatek,fore=>5,aft=>2,exp=>0);

new_line;

new_line;

put(" do wyplaty : ");

put(do_wyplaty,fore=>5,aft=>2,exp=>0);

end pr7;


Można by postawić pytanie, po co deklarować stałe, jeżeli można po prostu w odpowiednim miejscu
w programie pomnożyć przez 0.21 czy 0.20 - i już. Oczywiście - można, jednak stosowanie stałych ułatwia na przykład wprowadzanie zmian w razie konieczności modyfikacji programu - przerabiamy wtedy tylko część deklaracyjną, nie musząc przeglądać całej treści.

1   2   3   4   5   6   7   8   9   ...   16


©absta.pl 2016
wyślij wiadomość

    Strona główna