Wyobraźcie sobie, że nawet ze zwykłego przekazywania parametrów aktualnych do metod można zrobić temat na artykuł. Ja tak zrobiłem, gdyż i tutaj występuje zróżnicowanie w pisaniu. Większość języków programowania przekazuje zwykle do funkcji kopię wartości, co ma uchronić przed utratą wartości pierwotnej znajdującej się na zewnątrz danej metody. Język C umożliwia jeszcze jeden sposób: przekazywanie przez referencje. Jak to zrobić i jaki to ciągnie za sobą skutek? Czytajcie, a się dowiecie!

JĘZYK C OBSŁUGUJE PRZEKAZYWANIE PRZEZ REFERENCJE

Może Was dziwić nazwa "referencja", natomiast już spieszę z wyjaśnieniem. Chodzi o zachowanie identycznego adresu pamięci wskazującego na tę samą zmienną. Podając zmienną do funkcji, przekazujemy jedynie wartość, która z kolei jest przypisywana zmiennej lokalnej będącej parametrem formalnym funkcji (łopatologicznie, to jest zmienna podana w nawiasach). Ona z kolei jest poddawana operacjom bądź podstawieniom w środku bloku funkcji, a następnie jest usuwana z pamięci. Natomiast przekazując adres takiej zmiennej, zachowujemy jej odniesienie czyli wspomnianą wcześniej "referencję", a to z kolei umożliwia modyfikowanie tej samej zmiennej, która znajduje się na zewnątrz funkcji i zachowanie tych zmian po jej zakończeniu. Widzicie różnicę?

To teraz zastosowanie praktyczne. Przyjrzyjcie się poniższemu kodowi źródłowemu, który zamienia wartości obu liczb całkowitych wykorzystując przekazywanie przez referencje:

#include <stdio.h>

void swap(int *a, int *b);

int main(void)
{
	int x = 50, y = -100;
	
	printf("Wartosci liczb x i y to: %d i %d.\n", x, y);
	swap(&x, &y);			// przekazywanie przez referencje
	printf("Wartosci liczb x i y to: %d i %d.\n", x, y);
	getchar();
	
	return 0;
}

void swap(int *a, int *b)
{
	int temp = *a;
	
	*a = *b;
	*b = temp;
}

Powyższy program wykorzystuje przekazywanie przez referencje. Metoda "swap" pobiera adresy dwóch zmiennych typu liczba całkowita i zamienia wartości. W języku C, adres przekazuje się za pomocą przedrostka w postaci "ampersandu" (&). Efekt jest taki, że funkcja zamienia liczby miejscami, modyfikacje są stałe i obyło się bez zwracania wartości (występuje typ "void").

Możecie sobie myśleć "na co mi to, skoro mogę zwrócić wartość za pomocą słowa "return"?". Pojedynczą wartość tak, ale przekazywanie przez referencje nie tylko pozwala uniknąć zwracania wartości, ale również umożliwia modyfikację WIELU wartości pod rząd znajdujących się na zewnątrz!


Dzięki za przeczytanie. Powyższy trik jest pierwszym krokiem do opanowania operacji na wskaźnikach. Dobrze myślicie: to jeszcze jest łatwe.

PODOBNE ARTYKUŁY

Powrócimy znowu do języka C prezentując całkowicie już archaiczną instrukcję skoku, która była wykorzystywana w czasach nałogowego używania języka FORTRAN. "break" i "continue" przyszły później, najpierw było "goto". Tak się składa, że C również jest zaopatrzony w to słowo kluczowe do dnia dzisiejszego. Od razu napiszę, nie przerzucajcie się na to! To już jest mocno przestarzała instrukcja od co najmniej 20 lat. Tak więc potraktujcie ten artykuł jak zapoznanie się z częścią historii programowania w latach .60 i .70.

GOTO TO INSTRUKCJA SKOKU

Nie wiem jak prezentuje się "goto" w językach FORTRAN, COBOL i w innych dużo starszych od samego C. W każdym razie, zasada jest taka sama i niezmienna. Instrukcja ta powoduje "przeniesienie się" do innego miejsca w kodzie tam, gdzie znajduje się postawiona wcześniej "etykieta". Możecie to potraktować jak alternatywa pętli. Zwykle taką instrukcję osadzało się w instrukcji warunkowej, aby wykonywała te same ciągi instrukcji do pewnego pożądanego momentu. W języku C jest ona poprzedzona dwukropkiem, a przykładowy kod źródłowy wygląda następująco:

#include <stdio.h>

int main(void)
{
	int i = 0;
	
	increment:			// etykieta "goto"
	++i;
	
	printf("I = %d\n", i);
	
	if(i < 10)
	{
		goto increment;
	}
	
	getchar();
	
	return 0;
}

Powyżej widzimy kod źródłowy wraz z funkcją "main" wykorzystującą instrukcję "goto". Idąc od samej góry mamy przydzielenie pamięci dla zmiennej "i" i inicjalizację wartością równą zero. Następnie trafiamy na tę etykietę o której wspomniałem. Z posiadanych przeze mnie informacji wynika, że C wspierał dodatkowo nazwy etykiet dla "goto" co czyniło go jeszcze chętniej wybieranym, ponoć starsze języki miały tylko numerki (przynajmniej pierwsze wersje). Następnie mamy preinkrementację licznika, wypisywanie aktualnej wartości, a potem trafiamy na instrukcję warunkową, która decyduje o tym, czy przejść do powyższej etykiety, czy nie. Tutaj mamy do czynienia z dokładnym zachowaniem pętli "while". Dopóki wartość "i" nie jest większa bądź równa 10, instrukcja skoku będzie powodować "przenoszenie się" do powyższej etykiety i ponowne wykonanie wszystkich instrukcji.

goto

Instrukcja skoku "goto" była wykorzystywana w latach .60 i .70 jako starszy odpowiednik dzisiejszych instrukcji "break" i "continue".


Oto fragment historii przestarzałej instrukcji skoku. Możecie sobie skompilować powyższy program i zobaczyć jak to dokładnie, ale zaklinam Was, nie korzystajcie z tego regularnie! Dzisiaj macie wygodniejsze sposoby do kontrolowania przebiegu wykonywania instrukcji. DUŻO WYGODNIEJSZE.

Po mocnym spóźnieniu zapraszam Was na drugą część poprzedniego artykułu opowiadającego o klauzuli "try-catch" służącej do przechwytywania wyjątków z prostymi przykładami w języku Java. Postanowiłem poświęcić odrębny artykuł na te dodatkowe słowo kluczowe mające związek z wyjątkami, "finally". To jest blok, który wykonuje się zawsze niezależnie od tego, czy pewna ryzykowna operacja zakończyła się porażką lub sukcesem. Sprawdźmy jak to wygląda w praktyce.

FINALLY W BLOKU TRY-CATCH

Blok o powyższej nazwie jest całkowicie opcjonalny i zwykle jest rzadko wykorzystywany. Pobierając przykład z poprzedniej części, całość z "doczepionym" blokiem wygląda tak:

try
{
	ryzykownaMetoda();
}
catch (Exception e)
{
	//instrukcje wykonywane w momencie przechwycenia wyjątku
}
finally
{
	System.out.println("Koniec ryzykownej operacji.");
}

Ta część klauzuli umieszczana jest zawsze na końcu "ciągu" bloków "catch" i jak wspomniałem, wykonuje się po przeprowadzeniu wszystkich operacji w "try" (gdy obyło się bez przeszkód) oraz określonego bloku "catch" (gdy funkcja napotkała problem i zgłasza go funkcji wywołującej), niezależnie od rezultatu. Jest rzadko widziana w kodach źródłowych z tego względu, iż po tej strukturze "try-catch" dalsze instrukcje i tak są nadal wykonywane w taki sam sposób. Zatem, użycie części "finally" przeważnie jest bezcelowe.

Być może zaczyna mieć to istotne znaczenie dopiero przy programowaniu współbieżnym albo przy przechwytywaniu bardzo specyficznych wyjątków takich jak "RuntimeException", natomiast w chwili obecnej są to jedynie moje spekulacje niepoparte żadnymi dowodami. Gdy wrócę do języka Java i natrafię na jakąś różnicę, z pewnością napiszę stosowny artykuł o konkretnym spostrzeżeniu.

Finally

Blok "finally" występujący w klauzuli "try-catch" wykonuje się zawsze niezależnie od wyniku przeprowadzenia ryzykownych poleceń, zatem użycie tego jest opcjonalne.


Wniosek z tego taki, że możecie śmiało pisać dowolnie jak chcecie czyli pisać bloki "try-catch" z "finally" albo bez. Oddzieliłem te część od poprzedniej, aby nie mieszać Wam fragmentu opcjonalnego z fragmentem wymaganym i to jest cały powód. Tym razem bez żadnych magicznych sztuczek ani trzymania w napięciu.

Znowu artykuł i znowu Java. Przejdziemy do przechwytywania wyjątków, dowiemy się co to takiego, jak działa i jak się zabezpieczyć przed niepożądanym działaniem w trakcie korzystania z "ryzykownej" metody za pomocą klauzuli "try-catch". Jeśli nałogowo korzystacie z języka Java, opanujcie to jak najprędzej, to jest jeden z tematów podstawowych.

TEORIA WYJĄTKU I KLAUZULA TRY-CATCH

"Wyjątek" jest mechanizmem zmieniającym przebieg działania programu polegającym na wysyłaniu sygnału do systemu gdy nastąpi sytuacja nieoczekiwana, a także niepożądana. Dam przykład. Brakuje pliku tekstowego w podanym katalogu. Wyjątkiem będzie nieznalezienie wymaganego pliku o podanej ścieżce dostępu. Może to być również próba dzielenia przez zero i wtedy wyjątek jest oczywisty - sprzeczna równość niemająca sensu matematycznego. Jeśli dopiero się zaznajamiacie się z wyjątkami, dobrze jest na sam początek wymyślić samemu jakieś sytuacje w których może wystąpić wyjątek. Takie proste rzeczy z życia wzięte.

Zanim przejdę do omawiania klauzuli "try-catch" chcę napisać jeszcze o jednej istotnej rzeczy. Wyjątek w przeciwieństwie do błędu, może zostać "przechwycony" przez metodę i w ten sposób możliwe jest wykonanie pewnych instrukcji, która ten wyjątek "obsłuży" i zapobiegnie wysypaniu się programu. Wiadomym jest, że w większości przypadków nie da się "naprawić wyjątku". Można za to spróbować taki wyjątek "ładniej ubrać w słowa", osadzić w okienko komunikatu i jakoś podpowiedzieć użytkownikowi co KONKRETNIE może zrobić w tej sytuacji.

Pora na wyjaśnienie od strony "kodowej"! Pokażę Wam jak korzystać z przechwytywania wyjątków w kodzie źródłowym. Podstawowa struktura klauzuli "try-catch" zawsze składa się co najmniej z dwóch części (może być również trzecia "finally"):

try
{
	ryzykownaMetoda();
}
catch (Exception e)
{
	//instrukcje wykonywane w momencie przechwycenia wyjątku
}

Metoda "ryzykownaMetoda" posiada w naszym przykładzie instrukcje, które mogą się "zderzyć" z nieoczekiwaną sytuacją. Gdy takowa wystąpi, metoda "zgłasza" wyjątek i przekazuje go metodzie korzystającej z tej samej metody, która ten sygnał przesłała. Traktujcie "try-catch" jak punkt obsługi sygnału wysłanego przez wyjątek.

Try-catch

Przechwytywanie wyjątków jest możliwe po zastosowaniu klauzuli "try-catch".

PRZEKAZYWANIE SYGNAŁU DO POPRZEDNICH FUNKCJI

Możemy również sprawić, aby funkcja, która korzysta z ryzykownej metody nie obsługiwała wyjątku tylko również go przekazała dalej, aby poprzednia metoda posiadała "try-catch". Tutaj przyda się znajomość wyrażeń ze słowem "throws". Po zakończeniu podawania argumentów formalnych w nagłówku funkcji, po zamknięciu nawiasu piszemy coś takiego:

void metoda() throws Exception
{
	// instrukcje
	
	ryzykownaMetoda();
	
	// instrukcje
}

Ten zapis pozwala na pominięcie obsługi sygnału na tym "etapie" i przekazanie tej czynności poprzedniej funkcji, która ją wywołała. Dzięki temu, można zapisać klauzulę "try-catch" w poprzedniej metodzie.

WIELE GAŁĘZI PRZECHWYTYWANIA

Jak wiecie (albo i nie), wyjątki także są obiektami języka Java! Cenny wniosek nasuwa się taki, że one również mają swoje dziedziczenia. Samo "Exception" to klasa główna, a na przykład "ArithmeticException" dziedziczy od klasy bazowej. To z kolei oznacza, że możemy obsłużyć wiele sytuacji w jednej klauzuli "try-catch". Pozwólcie, że zaprezentuję:

try
{
	int n = 12 / 0;
	
	ryzykownaMetoda();
}
catch (ArithmeticException ae)
{
	System.out.println("Nie dzieli się przez zero!");
	ae.printStackTrace();
}
catch (Exception e)
{
	System.out.println("Pojawił się inny błąd niż dzielenie przez zero.");
	e.printStackTrace();
}

Patrząc na ten fragment możecie dostrzec dwa kolejne istotne spostrzeżenia. Po pierwsze, można bez przeszkód podstawiać wiele bloków "catch", które mają na celu zapobiec każdemu przypadkowi wszystkich "ryzykownych" metod i instrukcji. Dlatego też należy dać osobny blok dla sytuacji dzielenia przez zero oraz dla innej dowolnej sytuacji, która może pojawić się w funkcji "ryzykownaMetoda". "try-catch" pozwala na takie rozgałęzienia.

Po drugie, bloki "catch" są sprawdzane po kolei idąc z góry na dół. To jest bardzo ważne, aby zaczynać od uwzględniania najbardziej szczególnych przypadków, a kończyć na klasie bazowej "Exception". Gdy wystąpi wyjątek i on "znajdzie" odpowiedni typ, przechodzi do niego, wykonuje instrukcje i KOŃCZY. To działa identycznie jak w instrukcji "switchomawianej parę dni wcześniej albo nawet w zwykłej instrukcji warunkowej posiadającej kilka bloków "else if". Też wykonuje tylko jeden z nich, prawda?


W taki oto sposób załatwiliśmy następny temat dotyczący ochrony programu. Wspomniałem jeszcze o trzeciej części klauzuli "try-catch", "finally". Na nią poświęcę kolejny artykuł, który pojawi się za parę godzin. Jest powód aby to zrobić.

Ten artykuł też będzie prezentował moje kilkuletnie obserwacje. Raz kolejny weźmiemy pod lupę gry online od strony najpopularniejszych i najczęściej spotykanych gatunków. Przynajmniej od strony "indie" deweloperów. Popatrzyło się to tu, to tam i zauważyło się, że teraz niektóre gatunki gier online już wyszły z mody, a część z nich jest na topie. Jakie konkretnie?

DOMINUJĄCE GATUNKI GIER ONLINE

Zaznaczam na samym początku, że to jest wynik obserwacji z takich serwisów jak Kongregate, Newgrounds, itch.io i Google Play od 2016 roku. Początki sukcesywnego publikowania własnych produkcji nie były zadowalające, a pierwszym moim krokiem do "podpatrzenia" czyjegoś sukcesu jest zawsze badanie środowiska. Zwłaszcza gatunki gier online brałem na celownik bo jak to u mnie jest w zwyczaju, wszystko to, co podoba się zdecydowanej większości, dla mnie jest "ble" i odwrotnie. Nic na to nie poradzę, że właśnie w chwili, kiedy mam możliwość wypuszczania swoich gier akcji, te już się przejadły i większość przesiadła się na logiczne. Właśnie gry logiczne "zajmują" najwięcej miejsca wśród produkcji online na wyżej wymienionych serwisach. Wydaje mi się, że to dlatego, iż większość ludzi pragnie się zabawić przy mało ważącej gierce podczas wykonywanej przez siebie pracy nie chcąc tracić czasu na zrozumienie skomplikowanych zasad gry. Teraz liczą się gry proste i nieskomplikowane, aby przeznaczyć te pięć minut wolnego na granie, nie na zrozumienie zasad gry. W okresie 2006 roku to była inna polityka jak pisałem o tym wcześniej, ale teraz w miarę możliwości i rozrostu narzędzi do tworzenia gier, dzisiaj dominuje inna zasada: wypuścić małą grę logiczną i mieć pozytywne recenzje.

WŁASNA PRÓBA PUBLIKACJI GRY LOGICZNEJ

Oczywiście, że to coś dało do myślenia. W zeszłym roku wziąłem się za projekt "Jason Picross" i jak myślicie, dało to coś? Nie! Widocznie sam gatunek to za mało. Przyznam, że nawet przy małym odstępie czasowym ja już przestaję się nad tym zastanawiać i przejmować. Nie przestanie mnie dziwić to durne fatum w którym mogę sobie "pomarzyć". Gatunki gier online to też kwestia gustu, natomiast większość pójdzie tam, gdzie bardziej pachnie kasiorą. Ja pozwoliłem sobie jedynie na eksperyment. Nie powiódł się więc to się nie opłaca. Dziecinnie prosta kalkulacja.


Kolejna mniejsza wypowiedź bo też w końcu muszę odsapnąć od tego pisania. Temat, który też może dawać do myślenia bo możecie chcieć się "ustosunkować" do obecnych trendów jako niezależni twórcy gier. Ja już nie zamierzam...

PODOBNE ARTYKUŁY

Pora podsumować serwis na którym się udzielałem przez okres sześciu miesięcy. To jest ten wcześniej przeze mnie wspomniany o nazwie Quora (link Wikipedii). Do czego on służy? W jaki sposób działa? Czy może pomóc przyciągnąć więcej ludzi do swojego biznesu? Czytajcie dalej, a poznacie odpowiedzi na te pytania.

CZYM JEST QUORA?

Serwis ten jest portalem polegającym na tym, że jedna osoba zadaje określone pytanie z danej dziedziny, a Ci co znają odpowiedź, przedstawiają ją w oparciu o swoje doświadczenia i wiedzę naukową. Jest w nim tysiące różnych tematów. Poznacie odpowiedzi na pytania z programowania, psychologii, relacji interpersonalnych, przemocy domowej, księgowości, fizyki, matematyki i wiele wiele innych. System pobiera wiele funkcjonalności z Facebooka, zatem te odpowiedzi, które się podobają mogą zostać przez nas "polubione". Ponadto, można zostawić komentarz pod którąś z odpowiedzi. Któregoś razu natrafiłem na ten serwis przez przypadek i wywnioskowałem, że można spróbować jak on działa będąc aktywnym uczestnikiem. W czerwcu zeszłego roku zacząłem wysyłać pierwsze odpowiedzi. Oto streszczenie moich doświadczeń na Quora.

Quora

Portal Quora to serwis typu Q&A w którym ludzie pragnący otrzymać odpowiedź na nurtujące ich pytanie, zostawiają je ludziom którzy mają jakąś wiedzę na ten temat.

PÓŁ ROKU UDZIELANIA SIĘ NA PORTALU

Samo pisanie odpowiedzi było przez jakiś czas nawet wciągające. Zdarzały się błędy i niedomówienia, a także nawet nieprzyjemny odbiór niektórych osób. Prawda jest taka, że udzielając odpowiedzi, nie wolno Wam się mylić! Jeżeli odpowiadacie na jakieś pytanie, musicie być święcie przekonani o słuszności swojej wypowiedzi! Raz tak u mnie było, że dosłownie po pięciu minutach otrzymałem komentarz, że piszę niezgodnie z prawdą. Osoba była akurat na tyle przyjemna, że nie robiła żadnej afery. Szybko poprawiłem i podziękowałem za zwrócenie uwagi.

Po sześciu miesiącach oraz po miesiącu pisania jeszcze na polskim Quora, dałem już sobie z tym spokój całkowicie bo przestało to mieć jakikolwiek sens. Nie ukrywam, że pokusiłem się o udzielanie odpowiedzi na tym serwisie również z tego względu, iż u niektórych osób przynosiło to nadzwyczajne rezultaty jeśli chodzi o przyciąganie widzów do swojej strony czy biznesu. Raz kolejny się wyłożyłem jak Zabłocki na mydle. Nawet po tym pół roku pisania nie dostrzegłem ŻADNYCH widocznych wzrostów na mojej stronie. Nie wiem jak reszta to zrobiła, ale u mnie ta sztuczka nie chce działać.


To tyle na ten temat. Ogólnie serwis oceniam pozytywnie i możecie się spokojnie na nim udzielać, o ile wiecie co piszecie i jest to zgodne z nauką czy brzmi sensownie. Możecie dzięki niemu dowiedzieć się wielu niesamowitych rzeczy.

PODOBNE ARTYKUŁY

62213
Dzisiaj / TodayDzisiaj / Today224
Wczoraj / YesterdayWczoraj / Yesterday217
Tydzień / WeekTydzień / Week697
Miesiąc / MonthMiesiąc / Month1893