ZmienneCzęść NR.1Witam w nowym cyklu w którym szybko będę omawiał składnie języka C#, Java bez zbędnego opisu. Typ wartościowy i typ referencyjny? Nie będzie takich opisów bo mówimy tutaj o składni języka. . Zauważyłem, że 70% ruchu na moje stronie dotyczy wpisów z C# dla początkujących więc kto wie może to nie jest taki głupi pomysł.

Obliczyłem, że ten cykl zajmie 27 wpisów, ale przy dobrym planie powinien zakończyć ten cykl.

Typy danych

W C# proste typy składają się czterech typów liczb całkowitych ze znakiem, z czterech typów bez znaku, z 3 typów zmienno przecinkowych oraz z typu chart i bool.

TypRozmiar(bity)Opis
sbyte8-128 do 127
short16od -32 768 do 32 767.
int32od -2,147,483,648 do 2 147 483 647
long64–9, 223, 372, 036, 854, 775 808 do 9,223,372,036,854,775,807
byte8Od 0 do 256
ushort160 do 65 535.
uint320 do 4 294 967 295
ulong640 do 18,446,744,073,709,551,615. Jedna z najlepszych możliwości do przechowywania dużych pozytywnych liczb całkowitych.
float32Liczby zmiennoprzecinkowe.
double64Liczby zmiennoprzecinkowe.
decimal128Większa precyzja, ale mniejszy zakres. Wykorzystywany w aplikacjach finansowych
char16Znaki unicode
bool4Wartości logiczne

Oprócz strigów, klas i kolekcji, każdy typ został przedstawiony do tej tabelce. Oto tabelka prostych typów w Javie.

TypRozmiar(bity)Opis
byte8-128 do 127
short16od -32 768 do 32 767
int32od -2,147,483,648 do 2,147,483,647
long64od -9,223,372,036,854,775,808 do +9,223,372,036,854,775,807.
float32Liczby zmiennoprzecinkowe.
double64Liczby zmiennoprzecinkowe.
chart16Znaki unicode
boolean1Wartości logiczne

Podstawową różnica jaką widzimy w tej tabelce to zachowanie typu prostego: byte. Java nie ma także typów ograniczonych do liczb pozytywnych.

Deklaracje

Brak różnic w deklaracji typów.

W C# i Javie zmienna musi być najpierw utworzona przed jej użyciem. Aby zadeklarować zmienną zaczynasz od deklaracji typu a później od jej nazwy. Nazwa zmiennej nie może zaczynać się od cyfry bądź znaku specjalnego. Zmienna też nie może się nazywać jak słowa kluczowe występujące w C# i w Javie.

int myVariable;

Przypisania

Brak różnic jeśli o przypisania.

Przypisujemy wartość zmiennej używając znaku równa się “=”. Jest on operatorem przypisania. Zmienna wtedy jest zainicjalizowana.

int myVariable = 121;

Oczywiście deklaracja i przypisanie może być połączona do wspólnego wrażenia.

myVariable = 11;

Możemy definiować wiele zmiennych tego samego typu oddzielając je przecinkami.

int a = 10, b = 20, c;

Gdy zmienna jest zdefiniowana (zadeklarowana i uzupełniona wartością) możemy się do niej odwoływać używając jej nazwy.

System.out.print(myVariable);
Console.WriteLine(myVariable);

Całkowite typy

W Javie mamy 4 typy liczb całkowitych. Przetrzymują one różne wielkości danych. Aby nie komplikować sobie życia najlepiej trzymać się typów: int i long. Chyba, że twój kod robi coś na z niższym poziomie (tryb unsafe w C#).

sbyte sbyte8 = 2; // -128 to +127
short short16 = 1; // -32768 to +32767
int int32 = 0; // -2^31 to +2^31-1
long long64 = -1; // -2^63 to +2^63-1
byte b8 = 2; // -128 to +127
short s16= 1; // -32768 to +32767
int i32 = 0; // -2^31 to +2^31-1
long long64 = -1; // -2^63 to +2^63-1

C# są również typy, które przechowują tylko wartości dodatnie.

W dodatku do standardowej notacji. Liczby całkowite mogą być przypisane przy użyciu notacji hexadecymalnej. Pamiętaj, że jednej z rozmów o pracę miałem takie pytanie.

int hex = 0xF; // hexadecimal (base 16) 15
int number = 0xFFAA11; //16755217
int n1 = 0x100; //256
int hex = 0xF; // hexadecimal (base 16) 15
int number = 0xFFAA11; //16755217
int n1 = 0x100; //256

W C# w całkowitych typach gdy przekroczymy ich wartość maksymalne bądź minimalne otrzymamy wyjątek “Overflow Exception”.

image

Chyba, że w projekcie zaznaczyliśmy opcję “unsinged integers” bądź używamy słowa kluczowe “Checked”, “Unchecked”.

image

Więcej informacji tego typu w tym kursie.

W Javie występuje podobny wyjątek, ale w zależności od frameworka wyjątek zostanie wyrzucony lub zmienne całkowite będą miały przepełnioną wartość. Na co warto uważać.

Zmienne całkowite są także otwarte na wyjątek związany z dzieleniem przez zero.

image

Ten problem oczywiście jest także i w Javie.

image

Typy Zmiennoprzecinkowe

Typy zmiennoprzecinkowe potrafią przetrzymywać liczby ułamkowe z różną precyzją. Stałe liczby ułamkowe są przetrzymywane w C# jako typ double. Dlatego by się odnieść do typu “float” musimy dodać do liczby symbol “F” by skonwertować ją na typ float. To samo dotyczy typu decimal gdzie musimy użyć znaku “M”.

float f = 3.14F; // 7 precyzja w cyfrach
double d = 3.14; // 15-16 precyzja w cyfrach
decimal md = 3.14M; // 28-29 precyzja w cyfrach

W Javie jest podobnie. Jedyna różnica polega na braku typu decimal.

double d = 3.14;
float f = 1.11F;

W Javie tak samo jak w C# stałe zmienno przecinkowe są zawsze przetrzymywane jako typ double.

Przy próbie przypisania wartości double do typu float kompilator zgłosi błąd.

image

Ten problem oczywiście rozwiązujemy przy użyciu specjalnych literałów opisanych wyżej.

image

Przy próbie dodawania typu float i double kompilator zgłosi błąd gdyż double ma większą precyzje.

image

W takim wypadku najlepiej konwertować typy używając jawnego rzutowania. Rzutowanie to określamy poprzez napisanie w nawiasach potrzebnego nam typu przed zmienną. O to przykład.

float dd = 3.333F;
double aa = 1.1111111111111;
float re = dd + (float)aa;

Warto także pamiętać o precyzji typów. Typ float nie może przetrzymywać więcej niż 7 znaków. Wyrażenie poniżej zostanie zaokrąglone. To, że możesz zapisać taką wartość nie znaczy, że taka wartość będzie przekazana.

float fff = 1.1111111111111111111111111111F;
float ffff = 0.444444444444444444444444444F;
float fffff = 0.33333333333333333333333333F;
Console.WriteLine(fff);
Console.WriteLine(ffff);
Console.WriteLine(fffff);

image

float fff = 1.1111111111111111111111111111F;
float ffff = 0.444444444444444444444444444F;
float fffff = 0.33333333333333333333333333F;
System.out.println(fff);
System.out.println(ffff);
System.out.println(fffff);

image

Jak widać kompilator C# trochę ma inną interpretacje zaokrąglania wartości jeśli mamy dużo miejsc po przecinku. W prostszych przypadkach działa tak jak się tego spodziewałem.

image

Dobry pomysł na wpis bo liczby zmiennoprzecinkowe nie działają tak jakbyśmy chcieli i jak widać nie działają tak samo w Javie i w C#.

Liczby zmienno przecinkowe mogą być także przypisywane przy użyciu notacji wykładniczej.

double d = 3e6; // 3*10^6 = 3.000.000
double d = 3e2; // 300

W przypadku przekroczenia maksymalnych i minimalnych wartości w typach zmienno przecinkowych C# i Java nada takiej zmiennej wartość specjalną jak: nieskończoność i minus nieskończoność.

float f1 = 10000000000F;
f1 = f1 * f1 * f1 * f1;
float f2 = -10000000000F;
f2 = f2 * f2 * f2 * -f2;
System.out.println(f1);
System.out.println(f2);

image

image

W trakcie operacji dzielenia przez zero otrzymamy nieskończoność. Prawie każda operacja zwiększająca wartość lub zmniejszająca wartości nieskończoną da nieskończoność. Gdy spróbujemy podzielić zero przez zero lub nieskończoność przez nieskończoność to otrzymamy wartość specjalną “NaN” określającą brak zapisu matematycznego na takie wyrażenie. Nan nie jest także liczbą więc dzielnie zero przez NaN da NaN.

image

double z = 0;
double zer = 1 / z; //Infinity
double infinity  = zer + 1;
double nan = zer / zer;
double what_ok = nan / nan;
double what_what = 0 / nan;
double what_k = infinity / infinity;
System.out.println(zer); //Infinity
System.out.println(infinity); //Infinity
System.out.println(nan); //NaN
System.out.println(what_ok); //NaN
System.out.println(what_what); //NaN
System.out.println(what_k); //NaN

Typ znaku

Typ “char” zawiera w sobie pojedynczy znak “Unicode”. Przypisujemy typ chart używając pojedynczego apostrofu. W Javie i w C# możemy użyć specjalnego wyrażenia hexadecymalnego, który pozwala na uzyskanie dostępu do wszystkich znaków unicode nawet tych których nie możemy zapisać na klawiaturze.

image

Typ logiczny

Typ “bool” przetrzymuje wartości logiczne. Wartości są reprezentowane przez słowa kluczowe “true”, “false”. Działa on tak samo w Javie i C#. Jedyna różnica polega na tym, że w Javie mamy typ “boolean” , a nie “bool”.

Zasięg zmiennych

Zasięg zmiennej referuje się do bloków kodu wewnątrz nawiasów klamrowych. Przykładowo zmienna zadeklarowana wewnątrz metody może być użyta tylko w tej metodzie. Po zakończeniu metody zmienna ta zostanie zniszczona. Mechanizm zasięgu zmiennych w C# i Javie jest taki sam.

public class Test {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        
        int local; // lokalna zmienna

    }
}

Anonimowe bloki

C# i Java oferują anonimowe bloki. Możesz zadeklarować anonimowe bloki używając nawiasów klamrowych bez podawania ich nazw (bloki if/else/metody).

public class Test {
    public static void main(String[] args) {
        
        // Anonimowy blok kodu
        {
        int localVar = 10;
        }
        // zminna nie jest dostępna

    }
}

Nie mają one praktycznego użytku gdyż kod zawsze lepiej wydzielić na oddzielną metodę.