29 sierpnia 2019

C# - samouczek, część II - “Witaj Świecie!” czyli omówienie składni na podstawie najprostszego programu

Jakoś tak przyjęło się, że ucząc się nowego języka wypada stworzyć na nim jakiś program. Tradycyjnie jest to aplikacja, której jedynym zadaniem jest przywitać w imieniu użyszkodnika świat. Ponieważ tradycja ta jest nieszkodliwa - i ponieważ tak twierdzi tytuł tego wpisu - także i ja nie zamierzam porzucić tego zwyczaju.


Zacznijmy więc coś kodzić - w poprzednim wpisie poleciłem IDE Microsoftu znane szerszej publiczności jako Visual Studio (wersja dla użytkowników prywatnych ma swojej nazwie słowo Community i jest wystarczająca dla zdecydowanej większości zastosowań). Aby stworzyć program, który umożliwi nam powitanie ze światem musimy w pierwszej kolejności stworzyć sobie nowy projekt (screeny są z VS 2017, ale dla innych wersji zasada jest podobna):


i wybrać jego typ:


Warto od razu wyrobić sobie nawyk porządnego nazywania swoich aplikacji i biblioteki - inaczej szybko grozić nam będzie organizacyjny burdel, który może być szczególnie bolesny, gdy będziemy chcieli znaleźć kawałek kodu do ponownego wykorzystania. Po kilku miesiącach w morzu katalogów ConsoleApp (lub podobnych) jest to nieco trudniejsze niż się człowiek spodziewa. Idąc więc za swoją radą nazwę swój program HelloWorld. 


Po kliknięciu OK naszym pełnym samozadowolenia oczom ukaże się kod prawie gotowego programu. Należy go uzupełnić o dosłownie jedną linijkę by dotrzeć do celu. Aby tego dokonać musimy wiedzieć nie tylko co napisać, ale też i gdzie. Przyjrzyjmy się więc temu, co już mamy:


using System;
using System.Collections.Generic;
using System.Text;
4  
5  namespace HelloWorld
6  {
7      class Program
8      {
9          static void Main(string[] args)
10         {
11         }
12     }
13 }


A jak widać trochę się tutaj dzieje. Na początek na warsztat bierzemy pięć pierwszych linijek:


using System;
using System.Collections.Generic;
using System.Text;
4  
5  namespace HelloWorld


Pierwsze co rzuca się w oczy to słowo kluczowe “using”. Oznacza ono, że posiłkować się będziemy instrukcjami zawartymi klasach, bądź bibliotekach poza przestrzenią nazw zdefiniowaną w piątej linijce naszego programu. Czym są klasy i biblioteki zajmiemy się ciut później. Na tą chwilę wystarczyć powinna wiedza, że ułatwiają one współdzielenie kodu pomiędzy wieloma aplikacjami, a biblioteki dodatkowo mogą być napisane w innym języku niż ten w którym piszemy. Przestrzeń nazw, to takie ustrojstwo, które ułatwia nam trochę smarowanie kodu rozpisanego w kilku klasach. Możemy wtedy trochę mniej szczegółowo opisywać gdzie dokładnie znajduje się instrukcja, której chcemy użyć. Żeby było śmieszniej tak naprawdę już w tych pierwszych linijkach odwołujemy się nie tylko do biblioteki “System”, ale też i do zdefiniowanych w niej przestrzeni nazw “Text” oraz “Collections” i zawartej w niej podprzestrzeni “Generic”. O tym, że schodzimy w dół po zależnościach świadczą użyte w nazwie kropki. 


Jeśli cały powyższy akapit brzmi dla Ciebie jak bełkot możesz to sobie póki co w głowie przedstawić jako różne grupy instrukcji, które nie są normalnie zdefiniowane w czystej wersji języka i nie zagłębiać się w szczegóły. 


Każdy wiersz “Using” kończy się średnikiem, który oznacza koniec instrukcji. Chociaż wydawałoby się, że instrukcję kończyć powinien znak końca linii (czyli tzw. ENTER), to jednak tak nie jest. wielokrotne spacje, tabulatory, czy “entery” właśnie są przez język właściwie ignorowane w większości przypadków. Jak to się więc przekłada na pisanie kodu? Otóż tak, że zarówno taki zapis:


using System; using System.Collections.Generic; using System.Text;


jak i taki zapis:


using 
    System;
using 
    System.Collections.Generic;
using 
    System.Text;


Będą poprawne. Na pierwszy rzut oka może się to wydawać zbędnym utrudnieniem, ale w tym szaleństwie jest metoda - dzięki niej można tak przedstawić kod, aby jego czytanie było w miarę wygodne. Osobiście dość często korzystam z możliwości zapisania wywołania funkcji w kilku wierszach w sytuacji, gdy pokazanie całego kodu wymagałoby przesuwania widoku w oknie na boki.


Następnie mamy mały, ale dość istotny znak:
6         {
oraz jego nieodłączny braciszek:
13        }


Oznaczają one blok kodu. Nie ważne jaki blok - jakiś. To może być zawartość klasy, funkcji, czy zestaw instrukcji do wykonania po spełnieniu jakiegoś warunku. Każdy otwierający nawias musi mieć zamknięcie, każdy zamykający - najpierw musi być otwarty. Od tej zasady nie ma wyjątków, ale na szczęście ani IDE, ani tym bardziej kompilator nam tego nie przepuści. Trzeba zwracać naprawdę dużą uwagę gdzie i jak umieszcza się nawiasy klamrowe - beztroskie ich rozrzucanie tu i tam skończyć się może kilkugodzinną sesją grzebania w kodzie z hasłem “bo mi tu nie działa!”. Aby się nie zagubić w tym bałaganie bardzo pomocne są wcięcia - bloki kodu będące na tym samym poziomie mają identyczną głębokość wcięcia. IDE Visual Studio będzie się starało w tym pomóc, ale nie zawsze sobie samo poradzi.


Wreszcie dochodzimy do:


7      class Program


C# jest językiem obiektowym i naprawdę wszystko jest w nim obiektem. Aby powstał taki obiekt, potrzebna jest instrukcja jego wykonania i tą instrukcją jest właśnie klasa. W tej linii definiujemy więc klasę program, która jest przepisem na wykonanie obiektu. Tak jak w życiu - jeden przepis możemy wykorzystywać wiele razy i tak samo jest w programowaniu obiektowym - jedna klasa może “dać życie” wielu obiektom. Do tego co można zrobić z klasami (i po co) jeszcze wrócimy. Na tą chwilę wiemy już jak ją zadeklarować.


Na koniec zostaje to co najważniejsze:


9          static void Main(string[] args)
10         {
11         }


Deklaracja funkcji. Dzieje się tu naprawdę dużo. Najpierw mamy tutaj słowo kluczowe “static” oznacza ono, że funkcja którą deklarujemy może być wywołana bez tworzenia jakiegoś konkretnego obiektu z naszej klasy. Drugie słowo kluczowe “void”. Normalnie w tym miejscu deklaracji funkcji powinien stać typ zmiennej jaki zwróci nam funkcja. Ponieważ jednak typów zmiennych jeszcze nie znamy (niektórzy być może jeszcze nie wiedzą co to jest zmienna - spokojnie, będzie wyłożone później) nie chcemy, aby nasza funkcja zwracała cokolwiek, albo aby dosłownie zwróciła nam nic - “void” to w angielskim “pustka”, czyli nasze upragnione nic. Następne słowo “Main” to nazwa naszej funkcji. W językach z rodziny C, czy też C-podobnych jest to funkcja wywoływana zawsze na starcie programu. Następnie “(string[] args)”. Tutaj naprawdę dużo się dzieje i bez zahaczenia o typy zmiennych (i to złożone) ciężko będzie dokładnie wytłumaczyć co się dzieje. Wytłumaczę więc rzecz póki co po łebkach, a z czasem wszystko stanie się jaśniejsze. Otóż w tym nawiasie definiujemy co ma być wejściem dla naszej funkcji (najczęściej dane, choć nie zawsze), ale dla nas póki co najwazniejsze, że ten nawias może być też pusty. W tym konkretnym wypadku będą to argumenty jakie można wpisać po wywołaniu programu w linii poleceń.


Skoro więc jesteśmy w głównej (“Main”) funkcji naszego programu, to właśnie tutaj napiszemy linijkę kodu , która pozwoli przywitać nam świat. Wpychamy się więc pomiędzy nasze nawiasy klamrowe i piszemy:


Console.WriteLine(“Hello World”);


Zacznijmy od tego, że wielkość liter jest ważna w większości języków programowania i C# niej jest tutaj wyjątkiem. Czasem może to prowadzić do pomyłek w kodzie, bo łatwiej nam zapamiętać tekst tak jak on brzmi, a nie jak jest napisany. Na szczęście tutaj też IDE okaże się nam wielce pomocne podpowiadając, które nazwy są dostępne z uwzględnieniem wielkości liter. W przypadku VS najważniejszym wg mnie skrótem klawiszowym jest Ctrl+spacja. Włącza on podpowiedzi, które pozwalają szybko ogarnąć jak jeszcze można pomęczyć nasz kod. Dobra, tyle naskrobałem, a ani słowem nie wytłumaczyłem o co chodzi w linii kodu jaką każę wam wpisać.No to jedziemy. “Console” jest to klasa statyczna (czyli zawierająca same funkcje statyczne - a co to jest już wiemy), która pozwala nam pastwić się nad konsolą, czy jak kto woli wierszem poleceń. “WriteLine” dosłownie znaczy “PiszLinię” i dokładnie to robi - wypisuje linię tekstu na konsoli, natomiast jako argument naszej funkcji wpisujemy w nawiasach “Hello World” (razem z cudzysłowami, a dlaczego - o tym przy okazji typów zmiennych).


Możemy teraz radośnie kliknąć ikonkę:
lub wcisnąć klawisz F5.


Zachurkocze, zafurkocze coś tam mignie jakieś czarne okienko i natychmiast zniknie, a w okienku pod kodem przeczytacie coś w stylu:


(kod 0 oznacza, że nasz program skończył się prawidłowo).


Niektórzy z was - ci nie mający okazji dobrze poznać specyfiki systemu Windows - mogą poczuć się oszukani, no bo jak to?! Program się skończył, a nic nie było widać. Otóż było widać - przez ułamek sekundy w czarnym okienku, które nam mignęło na ekranie. Nie trzymając nikogo dłużej w niepewności podpowiem jak się dobrać do tego wyniku. Przesuwamy wzrok na prawą część ekranu i klikamy prawym przyciskiem myszy “Rozwiązanie XXX” (gdzie XXX to nazwa naszego projektu), a następnie wybieramy:


Co otworzy nam okienko eksploratora w lokalizacji, gdzie znajduje się nasz projekt. Musimy jednak dostać się do folderu “Debug” który można odnaleźć według schematu poniżej (lądujemy w folderze zaznaczonym niebieskim tłem, a chcemy się dostać do folderu zaznaczonym niebieską, nieregularną figurą, która miała być piękną elipsą.
Gdy już tam będziemy trzymając klawisz SHIFT klikamy prawym przyciskiem myszy gdzieś w polu naszego okna i otrzymujemy (w zależności od zainstalowanych programów zawartość okienka może się różnić od trochę do bardzo, bardzo):


I klikamy “Otwórz tutaj okno programu PowerShell” - w Windows 7 będzie to coś bardziej w stylu “Otwórz wiersz poleceń tutaj”, ale jako, że siódemki już jakiś czas nie używam, to dokładnie nie pamiętam (ósemki nie używałem wcale, więc kompletnie nie wiem co tam wypisuje). Jeśli wyskoczy nam niebieskie okienko wpisujemy:
.\helloworld 
(wielkość liter nie ma znaczenia), a jeśli czarne to możemy radośnie pominąć dwa pierwsze znaki (przy założeniu, że komputer ma standardową konfigurację).


Jeśli nic nie wybuchło i kod został prawidłowo przeklejony (bo nie wierzę, żeby ktoś go przepisał - a warto, bo wtedy IDE fajnie siecze podpowiedziami) to wtedy nasz program się z nami przywita.


Gratulacje - omówiliśmy Twój pierwszy program (mój jakoś nie - ja jakoś zaczynam naukę nowych języków od napisania symulatora oddziaływań grawitacyjnych, ale ja to w ogóle dziwny jestem).

Brak komentarzy:

Prześlij komentarz

„Obrażać też trzeba umieć!”

W zasadzie ten jeden cytat wystarczyłby za cały wpis. Nie wiem, czy w tym ukopanym kraju uchował się jeszcze ktokolwiek powyżej 25 roku życi...