01. Zmienne, stałe, wyrażenia i odstępy w C# 2.0

01. Zmienne, stałe, wyrażenia i odstępy w C# 2.0

Autor: Paweł Kruczkowski

Opublikowano: 9/26/2006, 12:00 AM

Liczba odsłon: 128332

Każdy kto rozpoczynał naukę programowania w jakimkolwiek języku (nie tylko w języku obiektowym jakim jest C#), na samym jej początku zetknął się z definicją zmiennych czy stałych, bez których nasz program nie może „żyć”. Nauka ich deklarowania to pierwsze kroki każdego programisty. Niniejszy artykuł pokaże nam w jaki sposób te pierwsze kroki postawić. Wprowadzimy sobie kilka pojęć: obok wspomnianych stałych czy zmiennych, postaram się pokrótce wytłumaczyć istotę wyliczeń czy prawidłowo zdefiniowanych wyrażeń używanych w C# 2.0.

Postawmy więc pierwszy krok i wprowadźmy prawidłową definicję zmiennej. Otóż jest ona obszarem pamięci o pewnym, określonym typie. Zmienne w programie mają określone wartości, które oczywiście mogą ulegać zmianom. Definiowanie zmiennych jest bardzo prostą czynnością: podajemy typ zmiennej oraz nadajemy jej nazwę. Zmienne możemy inicjalizować (prawidłowo stworzyć) w dowolnym miejscu naszego programu i przypisywać jej wartość w dowolnym momencie. Poniższy przykład przedstawia inicjalizację zmiennej oraz przypisanie jej pewnej wartości:

class Program
{
static void Main(string[] args)
{
int mojaZmienna = 21;
System.Console.WriteLine("Zainicjalizowaliśmy zmienną mojaZmienna o wartości: {0}", mojaZmienna);
mojaZmienna = 99;
System.Console.WriteLine("Po przypisaniu mojaZmienna ma wartość równą: {0}", mojaZmienna);
}
}

Otrzymamy następujący wynik:

W powyższym przykładzie zainicjalizowaliśmy zmienną: mojaZmienna za pomocą liczby 21. Następnie tę zmienną wyświetlamy. Jak wspomniałem wyżej w dowolnym momencie możemy przypisać zainicjalizowanej zmiennej wartość (w naszym przykładzie jest to liczba 99, którą wyświetlimy na ekranie naszej konsoli).
Powyższy programik napiszmy troszeczkę inaczej:

class Program
{
static void Main(string[] args)
{
int mojaZmienna;
System.Console.WriteLine("Zainicjalizowaliśmy zmienną mojaZmienna o wartości: {0}", mojaZmienna);
mojaZmienna = 99;
System.Console.WriteLine("Po przypisaniu mojaZmienna ma wartość równą: {0}", mojaZmienna);
}

}

Po skompilowaniu otrzymamy następujący komunikat:

Powyższy przykład przedstawia niedozwoloną sytuację do jakiej w języku C# nie możemy doprowadzić. A mianowicie, próbujemy użyć niezainicjalizowanej zmiennej, o czym mówi nam powyższy komunikat z błędem. Aby temu odpowiednio zaradzić musimy przyswoić sobie raz na zawsze regułę: przed użyciem zmiennej musimy ją zainicjalizować, bądź musimy przypisać jej wartość. Takie bowiem wymagania ma język C#. Innymi słowy, kompilator sprawdza, czy danej zmiennej przed jej użyciem została przypisana określona wartość. Jeśli nie została to nasz kompilator zgłosi błąd, jaki widzimy powyżej.
Zmodyfikujmy jeszcze nasz programik w następujący sposób:

class Program
{
static void Main(string[] args)
{
int mojaZmienna;
mojaZmienna = 21;
System.Console.WriteLine("Po przypisaniu mojaZmienna ma wartość: {0}", mojaZmienna);
mojaZmienna = 99;
System.Console.WriteLine("Po ponownym przypisaniu, mojaZmienna ma wartość: {0}", mojaZmienna);
}

}

Otrzymamy identyczny wynik jak w przykladzie pierwszym:

Jaki wniosek z powyższego przykładu? Bardzo prosty: oczywiście, że w języku C# używanie niezainicjalizowanych zmiennych jest sytuacją niedozwoloną, ale używanie niezainicjalizowanych zmiennych z przypisanymi im wartościami przed ich użyciem jest już jak najbardziej prawidłowe i dozwolone co ukazuje właśnie powyższy przykład.

Teraz przejdźmy do drugiego pojęcia jakim są stałe w C# 2.0. Jak się możemy domyślać, stała to taka wartość w programie, która nie może zostać w żaden sposób zmieniona po jej zainicjalizowaniu. Używanie stałych powoduje, że nasz program staje się bardziej przejrzysty. Wyobraźmy sobie program symulujący pewien eksperyment matematyczny, w którym będą potrzebne 2 zmienne reprezentujące odpowiednio: liczbę ¶ oraz liczbę e jako podstawę logarytmu naturalnego. Jak wiadomo liczby te są stałymi matematycznymi, więc najlepiej używać ich w naszym programie jako właśnie stałe.

W języku C# 2.0 mamy 3 rodzaje stałych:

  • literały,
  • stałe symboliczne oraz
  • wyliczenia.
  • W następującym przypisaniu:
    x = 21;
    liczba 21 jest nazywana literałem. Jak byśmy się nie starali to i tak nigdy nam się nie uda przypisać nowej wartości do liczby 21 (wartością liczby 21 jest zawsze 21) i liczba ta nigdy nie będzie reprezentować na przykład liczby 99. Taka jest istota literałów. Drugim rodzajem stałych są stałe symboliczne. Deklarujemy je w następujący sposób:
    const typ_stałej nazwa_stałej = wartość_stałej
    Jak widzimy, do zadeklarowania stałych symbolicznych używamy słowa kluczowego const. Tak jak w przypadku zmiennych, również i tutaj musimy podać typ naszej stałej symbolicznej. Stałe takie musimy zainicjalizować w miejscu deklaracji naszego programu, a jej wartość nie może ulec już nigdzie zmianie w trakcie pisania naszego programu.
    Poniższy przykład przedstawia inicjalizację stałych symbolicznych:

    class Program
    {
    static void Main(string[] args)
    {
    const double liczbaPi = 3.14;
    const double podstLogarytmu = 2.72;
    System.Console.WriteLine("Najważniejsze stałe matematyczne i ich wartości");
    System.Console.WriteLine("Liczba Pi ma wartość: {0}", liczbaPi);
    System.Console.WriteLine("Liczba e (podstawa logarytmu naturalnego) ma wartość: {0}", podstLogarytmu);
    }

    }

    W powyższym przykładzie zadeklarowaliśmy 2 stałe symboliczne: liczbaPi oraz podstLogarytmu. Obie te stałe są typu double (typ reprezentujący liczby zmiennoprzecinkowe). Stala symboliczna: liczbaPi określa literał 3.14 natomiast podstLogarytmu określa literał 2.72. Literały te są wykorzystywane w naszym programie w określeniu wartości odpowiednich stałych matematycznych. Po skompilowaniu otrzymamy następujący wynik:

    Aby udowodnić fakt, że nie możemy przypisywać już zadeklarowanym stałym symbolicznym nowych wartości wystarczy uruchomić poniższy programik:

    class Program
    {
    static void Main(string[] args)
    {
    const double liczbaPi = 3.14;
    const double podstLogarytmu = 2.72;
    System.Console.WriteLine("Najważniejsze stałe matematyczne i ich wartości");
    System.Console.WriteLine("Liczba Pi ma wartość: {0}", liczbaPi);
    System.Console.WriteLine("Liczba e (podstawa logarytmu naturalnego) ma wartość: {0}", podstLogarytmu);
    liczbaPi = 5.0;
    }

    }

    Przy kompilacji otrzymamy następujący błąd:

    A więc nie można przypisywać nowych wartości do stałej symbolicznej, która została już zadeklarowana w naszym programie.

    Trzecim rodzajem stałych są wyliczenia. Wyliczenia są alternatywą dla stałych symbolicznych. Składają się bowiem z zestawu stałych o określonych nazwach. Mamy w ten sposób do czynienia z tak zwaną listą wyliczeniową. W poprzednim przykładzie użyliśmy dwie stałe matematyczne jako stałe symboliczne. Jak wiadomo, stałych matematycznych mamy o wiele więcej, stąd deklarowanie ich dalej w programie jako stałe symboliczne traci sens logiczny (ponieważ będziemy mieli dużą ilość zadeklarowanych stałych tego samego typu będących stałymi matematycznymi). Dlatego też język C# udostępnia nam wyliczenia, które są rozwiązaniem powyższego problemu.
    Wyliczenia deklarujemy w następujący sposób:

    [atrybut][modyfikatory] enum identyfikator [: typ_bazowy]
    {
        lista_wyliczeniowa
    }

    Atrybuty oraz modyfikatory są opcjonalne (o nich i ich używaniu będzie mowa w innych artykułach programowania w języku C# 2.0 na portalu CentrumXP.pl). W tym miejscu najistotniejszą częścią deklaracji wyliczenia jest słowo kluczowe: enum, po którym występuje identyfikator. Z punktu widzenia programowania , identyfikatory to nazwy nadawane przez programistów typom, metodom, zmiennym, stałym czy obiektom. Identyfikator musi się zaczynać od litery bądź znaku podkreślenia. Z punktu widzenia konwencji Microsoftu, należy stosować notację wielbłądzią (nazwa rozpoczyna się małą literą: mojaZmienna) bądź notację Pascala (nazwa rozpoczyna się wielką literą: MojaZmienna) przy tworzeniu nazw dla identyfikatorów. Jest jeszcze notacja węgierska (np. iMojaZmienna), ale Microsoft jej nie zaleca używać (podobnie jak podkreśleń: moja_zmienna). Po identyfikatorze występuje typ bazowy. Jest to typ, na którym oparte jest wyliczenie. Gdy nie zadeklarujemy tego typu bazowego, to domyślnym typem jest int. Istotną rzeczą jest to, że typem bazowym może być każdy typ jaki występuje w języku C# 2.0 oprócz typu char. Na przykład w poniższym przykładzie utworzymy sobie wyliczenie oparte na liczbach bez znaku w zakresie: 0 – 255 (typ byte):

    enum liczbyByte : byte
    {
    liczba1 = 0,
    liczba2 = 5,
    liczba3 = 44,
    liczba4 = 249

    }

    Nie wspomniałem jeszcze o liście wyliczeniowej. Zawiera ona stałe przypisane do naszego wyliczenia, które są oddzielone przecinkiem.

    Napiszmy teraz krótki program, który pokaże w jaki sposób stosować wyliczenia:

    class Program
    {
    enum Oceny
    {
    Niedostatyczny = 1,
    Mierny = 2,
    Dostateczny = 3,
    Dobry = 4,
    BardzoDobry = 5,
    Celujacy = 6
     
    }

    static void Main(string[] args)
    {
    System.Console.WriteLine("Dzisiaj w szkole otrzymałem notę: {0}", (int)Oceny.Mierny);
    System.Console.WriteLine("Na pewno się poprawię i jutro otrzymam notę: {0}", (int)Oceny.Celujacy);

    }

    }

    W powyższym przykładzie stworzyliśmy wyliczenie o nazwie Oceny, który oparty jest na typie domyślnym (jak wiemy, typem domyślnym dla wyliczeń w języku C# 2.0 jest intiger). Domyślne wartości wyliczenia są wyświetlane jako nazwa: Niedostateczny, Mierny, Dostateczny, etc. Gdy potrzebujemy wyświetlić w naszym programie wartość stałą wyliczeniową, to musimy zrzutować ją na typ (w naszym przypadku intiger).

    W wyniku skompilowania powyższego programiku otrzymamy następujące wyniki:

    Podsumowując wyliczenia należy napisać o przypadku, w którym nie okreslimy wartości dla stałej wyliczeniowej. Co wówczas? Jakie domyślne wartości przyjmuje nasze wyliczenie? Spójrzmy na poniższy przykład:

    enum Liczby
    {
    Liczba1,
    Liczba2,
    Liczba3 = 21,
    Liczba4 = 99,
    Liczba5

    }

    W powyższym przypadku, pierwszy element nieokreślony w wyliczeniu przyjmuje wartość 0 (a więc Liczba1 = 0), a każdy kolejny przyjmuje wartość o jeden większą od poprzedniego (a więc Liczba 2 = 2, a liczba5 = 100).

    Wróćmy jeszcze na chwilkę do użytego wyżej przypisania:
    x = 21;
    Instrukcja, która daje w wyniku wartość jest nazywana wyrażeniem. Dlatego też powyższe przypisanie jest wyrażeniem. Bardzo częto będziemy używać tej definicji w naszych przykładach stąd warto o tym wspomnieć już teraz. Przytoczone przypisanie (x = 21) to wyrażenie, które w wyniku daje liczbę 21, a więc wyrażenie to możemy używać jako element kolejnego przypisania:
    y = x = 21;
    W tej instrukcji (w języku C# pełne polecenia są nazywane właśnie instrukcjami) wartość 21 jest najpierw przypisywana do zmiennej x, a następnie wartość tego przypisania (czyli nasze 21) jest przypisywana do zmiennej y. W ten sposób wartość 21 jest przypisana obu zmiennym. Podsumowując, w taki sam sposób możemy w jednej instrukcji zainicjalizować dowolną liczbę zmiennych za pomocą jednej wartości, np.:
    k = l = m = n = o = p = 99

    Na koniec chciałbym napisać kilka słów na temat odstępów jakie umożliwia nam język C#. Może są one przez programistów rzadko stosowane, niemniej jednak bardzo często wpływają na czytelność i estetykę kodu.
    Odstępy to poprostu znaki spacji, tabulacji, bądź nowej linii. Nazywają się tak, gdyż po ich wpisaniu w kodzie pojawiają się białe, puste przerwy, które przez kompilator sa ignorowane. Na przykład:
        int mojaZmienna = 21;
    i
        int mojaZmienna = 21;
    przez kompilator oba te przypisy są traktowane identycznie.
    Inaczej sprawa wygląda w przypadku łańcuchów (o nich jeszcze będzie mowa na łamach portalu CentrumXP.pl), w których to każda spacja zostanie potraktowana jako osobny znak:

    Console.WriteLine("To jest przykład !");

    To, że czytelność kodu poprzez używanie odstępów jest istotna, nie trzeba nikogo przekonywać. Tak samo ma się kompilator, dla którego:
        int mojaZmienna = 21;
    to to samo co:
        int mojaZmienna=21;
    tyle, że mniej estetyczne dla programisty (mam na myśli drugie przypisanie), ale już:
        intmojaZmienna=21
    powyższego przypisania nie będzie umiał prawidłowo zinterpretować (kompilator potrafi zignorować odstępy po obu stronach operatora przypisania, jednak spacji między typem, a zmienną już nie umie).
    Odstępy mają ogromne znaczenie dla kompilatora w przypadku przetwarzania przez niego słowa kluczowego int, zamiast jakiejś nieznanej nazwy intmojaZmienna (między nimi musi występować co najmniej jedna spacja lub tabulacja, aby kompilator wiedział, że programista zadeklarował zmienną typu intiger).

    W niniejszym artykule uczyniliśmy pierwszy krok, jakim było poznanie podstawowych definicji w programowaniu. Potrafimy już prawidłowo deklarować zmienne oraz wszelkiego rodzaju stałe. Poznaliśmy także takie pojęcia jak: wyrażenia, instrukcje czy wyliczenia, które są bardzo często używane przez programistów.
    Następny krok uczynimy w kolejnym artykule, w którym przypomnimy sobie podstawowe wiadomości na temat konstruktorów oraz destruktorów.

    Jak wykorzystać Copilot w codziennej pracy? Kurs w przedsprzedaży
    Jak wykorzystać Copilot w codziennej pracy? Kurs w przedsprzedaży

    Wydarzenia