ArytmetykaCzęść NR.2W tej części kursu pokażę podstawy tworzenia aplikacji z interface-m graficznym. Po dłuższym namyśleniu się jednak postanowiłem, by była to aplikacja WPF , będzie też mowa o Windows Forms..
Stworzymy banalny program dodający,odejmujący, mnożący i dzielący zawartość z dwóch pól tekstowych i wyświetlający wynik w tym trzecim.
Mając taki program łatwo się zapoznamy z modelem zdarzeniowym w C#.
Najpierw jednak trochę teorii, co do pisania zmiennych.
Bez tego napisanie tego programu nie ma sensu.
Używanie identyfikatorów
Identyfikatory to nazwy elementów w naszym programie jak zmienne, klasy , metody i przestrzenie nazw. Trzeba przestrzegać pewnych zasad, co do nazw elementów.
- Nazwa musi zaczynać się od litery bądź podkreślenia
- Nazwa może składać się tylko z litery, cyfry i znaku podkreślenia.
- Nazwa nie może być taka sama jak nazwy kluczowych elementów w języku C#.
Czyli zmienne takie są poprawne:
- X
- _delta
- wynik2
A takie nie są:
- procent%
- 2wynik
- email@
- abstract (słowo kluczowe)
Wielkość znaków ma też znaczenie. Zmienne “MojGra” i “mojGra” są traktowane jako dwie oddzielne nazwy. W nazwach lepiej nie korzystać z polskich znaków i lepiej się przyzwyczajać do nazywania ich po angielsku. To ,że ja tego nie robię teraz wnika z tego ,że upraszczam ten kurs do bólu.
Pomimo iż możemy tworzyć różne zmienne zgodnie z tymi zasadami trzeba też pamiętać o pewnych rekomendacjach:
- Zmienna nie powinna się zaczynać od podkreślenia.
- Nie powinno się posiadać różnych zmiennych, których różnica polega na wielkości liter.
- W nazwie, które zawiera wiele słów jak np. “graKomputerowa” każdy nowy wyraz powinien zaczynać się wielką literą
- Zmienne nie powinny zawierać w sobie informacji o swoim typie . To można zobaczyć w Visual Studio.
To tylko przykładowe rekomendacje. O tym, jak pisać czysty kod według określonych zasad można napisać książkę, która i tak nie zawsze może być zgodna z rzeczywistością.
Identyfikatory kluczowe
Język C# jak każdy inny język programowania posiada w sobie specjalne identyfikatory, których nie możesz użyć do własnych celów. Te słowa kluczowe informują kompilator o pętlach, warunkach , typach wartości i tak dalej. Oto lista tych słów kluczowych. Zauważ , że w Visual Studio podkreśla te słowa kluczowe na niebiesko.
abstract | else | is | struck |
as | enum | lock | switch |
base | event | long | this |
bool | explicit | namespace | throw |
break | extern | new | protected |
byte | false | null | readonly |
case | finally | object | ref |
catch | fixed | operator | return |
char | float | out | unchecked |
checked | for | override | unsafe |
class | foreach | params | unshort |
const | goto | private | using |
continue | if | sbyte | virtual |
decimal | implicit | sealed | void |
default | in | short | volatile |
delegate | int | sizeof | while |
do | interface | stackalloc | true |
double | internal | static | try |
typeof | uint | ulong |
Dużo ich nieprawdaż ,ale niektóre z nich nie są stosowane jak np. goto. Zapamiętanie ich wszystkich jest bezcelowe . Na razie bądź ich tylko świadom.
Język C# posiada także identyfikatory specjalne, które mogą być zapisane w postaci zmiennych . Aby uniknąć zakłopotania w przyszłości lepiej ich unikać.
dynamic | group | let | select | var |
from | into | orderby | set | where |
get | join | partical | value | yield |
Identyfikatory te pojawiły się wraz z rozwojem języka ,więc aby nagle stare programy z takim zmiennymi jak “dynamic” nie przestały działać jest to dozwolone. Taka jest moja teoria. zapewne się mylę. Nigdzie tego nie wyczytałem.
Używanie i Deklaracja zmiennych
Zadanie zmiennych jest przetrzymywanie wartości niekoniecznie liczbowych. Przykładowo X w matematyce może referować się do jednej zmiennej we wzorze. Niczym w zadaniu matematycznym zapisujemy dane pod odpowiednimi nazwami i obliczamy wynik za pomocą odpowiedniego wzoru.
W C# zmienne mogą przechowywać wiele wartości liczbowych w zależności od ich zakresu i potrzeb.
Przy deklaracji zmiennej musimy określić typ danej, jaką ona ją przechowuje. Przykładowo ludzki wiek jest liczbą całkowitą więc w takiej zmiennej ona powinna być przechowywana. Tak jak każde stwierdzenie i to musi się kończyć średnikiem.
Aby zmienić wartość zadeklarowanej zmiennej wystarczy już tylko przyrównać do danej wartości. Wracając do kodu z poprzedniego ćwiczenia w konsoli możemy tą zmienną wyświetlić w ten sposób.
int wiek = 22;
wiek = 23;
Console.WriteLine(wiek);
Typy zmiennych liczbowych
Tak jak napisałem wcześniej C# oferuje kilka typów liczbowych w zależności od potrzeby i zakresu liczbowego. Oto ich tabelka.
Typ danych | Opis | Rozmiar | Zakres | Użycie |
int | Liczby całkowite | 32 | -2^31 do 2^31 - 1 | int x = 22; |
long | Duże liczby | 64 | -2^63 do 2^62 - 1 | long wynik = 22L; |
float | Liczby z ułamkami | 32 | +-1.5 * 10^45 do -+3.4 * 10^38 | float y = 0.42F |
double | Liczby z ułamkami, większa dokładność | 64 | -+5.0 * 10^-324 do –+1.7 * 10^308 | double fizyka; |
decimal | Typ do obliczania wartości pieniężnych | 128 | 28-29 cyfr | decimal moneta; |
Zwróć uwagę na inne zapisy liczbowe w kolumnie użycie. W ten sposób zmienna jest zgodna z danym typem. Jeśli przy zapisie 0.42 zapomnisz o literce F wartość będzie traktowana jak typ double. Nie rozwali to programu ,ale wykona się rzutowanie na inny typ.
C# oferuje dużo więcej zmiennych liczbowych jak np. single czy uint. Ale w dzisiejszych czasach programista raczej nie musi się martwić ,że jedna zmienna liczbowa ma większy zakres liczbowy niż powinna mieć. Nie żyjemy w latach 80 i to nie jest Pascal gdzie program mieścił się na dyskietce i mieliśmy dostęp do kilkobitowej pamięci ram.
Oczywiście, jeśli wiemy ,że będziemy przechowywać zmienną całkowitą nieprzekraczającą np. liczbę 100. To wybierzemy int ,a nie jego mniejszych braci. Przynajmniej takie jest moje zdanie, ponieważ kod jest bardziej czytelny.
Poza typami liczbowymi w C# spotkasz się nieraz z takimi zmiennymi:
Typ danych | Opis | Rozmiar | Zakres | Użycie |
string | Przechowuje ciąg znaków | 32 | ---------- | string napis; napis = “Cezary”; |
char | Znak | 16 | od 0 do 2^16 - 1 | char małpa; małpa = ‘@’; |
bool | Wartość logiczna | 8 | True albo False | bool zrobione’ zrobione = false; |
Nie przypisana zmienna
Kiedy deklarujesz zmienną w programie zawiera ona w sobie nie określoną wartość. C# i Visual Studio nie pozwoli ci na wykonanie takiego kodu.
int x;
Console.WriteLine(x);
Co można zobaczyć na takim błędzie.
Dla każdej zmiennej musisz podać do niej wartość, zanim będziesz chciał ją odczytać.
Używanie operacji arytmetycznych
C# wspiera podstawowe operacje arytmetyczne, które każdy poznał w klasie podstawowej. Dodawanie (+) . Odejmowanie (-) . Mnożenie (*) . Dzielenie (/)
double x;
x = 0.001 * 1000;
Analogicznie do tego przykładu mogą być wykonane pozostałe operacje.
Operacje i typy
Dla napisów, czyli typu “string” można wykonać tylko operacje dodawania. Operacja ta łączy dwa łańcuchy znaków. Pozostałe operacje arytmetycznie nie mogą być wykonane z resztą co one by robiły.
string napis = "Zdzisław" + "Bohater" + "Galaktyki";
W przypadku, gdybyśmy chcieli dodać dwie cyfry, które są napisami. Możemy skorzystać z metody konwertujące je na dane liczby. Trzeba być jednak ostrożnym, gdyż, gdy napis rzeczywiście nie jest liczbą to wyskoczy nam błąd w czasie wykonywania się tego fragmentu kodu. Oto jak ten fragment kodu wygląda. Lepiej go zapamiętam konwertowanie zmiennych liczbowych do napisów i odwrotnie w C# jest na porządku dziennym;
int y = int.Parse("1") + int.Parse("2");
string n = y.ToString();
Typy zmiennych liczbowych też są ważne. Przyjrzyj się poniższym operacjom:
double a = 3 / 2; //1
double b = 3.0 / 2.0; //1.5
double c = 3 / 2.0; //1.5
Pierwsza operacja zwróci liczbę całkowitą “1”, ponieważ dzielenie wykonało się na dwóch liczbach całkowitych. Wynik równa się 1, pomimo iż zmienna “a” była przygotowana na wartość ułamkową, ponieważ jest typem double. Ale tak naprawdę wynik działania z liczby całkowitej został przekonwertowany na double.
Druga operacja zwróci “1.5”, ponieważ obie liczby są typami double wynik też jest tym typem.
Trzecia operacja, która zawiera dwa typy mieszane int i double . Co w takim razie zrobi kompilator. Kompilator znajdzie niezgodność i przekonwertuje wartość int na double przed operacją dzielenia ,więc w tym wypadku wynik też wynosi 1.5. Jednak, pomimo iż ten sposób działa, lepiej nie przemęczać kompilatora taką brudną praktyką. Zwłaszcza że z punktu widzenia programisty do końca nie wiadomo, co się dzieje w tym kodzie przed kompilacją.
Inne operacje
C# wspiera też inne operacje jak dzielenie modulo.
Dzielenie modulo zwraca resztę z dzielenia. Normalnie, jeśli dzielmy liczby może wychodzić nam ułamek , dzielenie modulo właśnie pokazuje jaka liczba będzie po przycinku. Jeżeli wynikiem dzielenia jest liczba całkowita np: 4/2=2, to wynikiem dzielenia modulo jest 0 (4%2=0). W ten sposób można badać parzystość liczby.
int m = 5 % 3; // 2
Wartość nieskończone
Zapewne się zastanawiasz jaka wartość powinna się pojawić przy dzieleniu przez zero. Skoro w matematyce ta operacja jest nie dozwolona ,a niektórzy twierdzą ,że próba złamania tej zasady grozi zawaleniem się wszechświata z ograniczeniem do jednej galaktyki
Bezpośredni zapis dzielenia przez zero nie przejdzie przez kompilator C#. Więc by wykonać tą błędną operacje trzeba użyć dodatkowych zmiennych pomocniczych.
double z = 0;
double d = 5 / z;
Operacja ta dla typu double i float zwraca nieskończoność . Ta wartość jest poza zakresem typów: int,long i decimal. Operacja dzielenia przez zero dla nich skutkuję błędem programu. Ale dla typu double i float istnieje specjalna wartość właśnie reprezentująca nieskończoność.
Chociaż warto zaznaczyć ,że dzielenie przez zero liczby zero powinno zwrócić akurat zero. W C# ta operacja zwraca wartość “NaN”, czyli dana wartość nie jest liczbą . Ale w każdym innym wypadku dzielenie przez zero zwraca nieskończoność.
Jakakolwiek operacja na wartości “NaN” będzie zwracać NaN.
Przy nieskończoności jedna operacja może zwrócić zero i jest to pomnożenie nieskończoności przez zero.
Wartość double i float mają też wartości specjalne jak nieskończoność dodatnia i nieskończoność ujemna. Te wartości pojawiają się, gdy wynik naszej operacji arytmetycznej wyszedł poza zakres.
Kolejność wykonywania działań
Ostatnio na Internecie pojawiło się równanie 6 / 2(1+2) = ? z małą pułapką, ponieważ Google sugerowało wynik 1.
Oczywiście kolejność wykonywania działań jest następująca: dzielnie, mnożenie, dodawanie, odejmowanie.Wynik tego równania to 9;
A jaka kolejność jest w C#. Wykonajmy te równanie w C#. Bez zaskoczenia wynik to 9. C# też przestrzega kolejności działań.
Tak jak w matematyce by dostosować kolejność działań do naszych potrzeb możemy używać tylko nawiasów zwykłych() . Nawiasy kwadratowych [] i klamrowe {} w C# mają swoje specjalne miejsce.
Inkrementacja i dekrementacja
Zwiększanie wartości o jeden w programowaniu jest na porządku dziennym , a w niektórych algorytmach niezbędne. Oczywiście by nie pisać w kodzie x = x + 1; możemy użyć operatora ++ do zmiennej w ten właśnie sposób.
W podobny sposób można wykonać dekrementacje za pomocą operatora “—".
int odliczanie = 0;
odliczanie++;
odliczanie--;
Operator – i ++ są operatorami jednoargumentowymi, czyli potrzebują tylko jednej zmiennej do działania.
Prefiks i sufiks
…albo po angielsku prefix i postfix. Akurat oficjalnego tłumaczenie postfix nie mogłem znaleźć nawet tutaj.
Operacja inkrementacji bądź dekrementacji może zajść w określonej kolejności. Na przykład chcemy najpierw wyświetlić obecną zawartość po czym zmniejszyć ją o jeden, albo od razu zmniejszyć zmienną i ją wyświetlić. Oba przypadki są pokazane w kodzie.
int odliczanie2 = 10;
Console.WriteLine(odliczanie2--); //10 postfix (sufiks)
Console.WriteLine(--odliczanie2); //8 prefiks
W wyrażeniu doliczanie2-- zmienna jest odczytywana najpierw ,dekrementacja zachodzi później. W wyrażeniu drugim wyrażenie operacja zachodzi najpierw więc mam wynik po operacji.
W programowaniu dla konsystencji wszyscy się trzymają pierwszej metody. W ten sposób wszyscy wiedzą co się dzieje w kodzie. A jedna linijka więcej w kodzie dużo nie zmienia.
Uuuf tyle
Teraz gdy masz wiedzę na temat zmiennych i deklarowania ich, jest sens pokazania , jak napisać prostą aplikacje graficzną w WPF i Windows Forms.