Dekrementacja - instrukcja zmniejszająca o jeden wartość zmiennej podanej jako argument, jest działaniem odwrotnym do inkrementacji. Dekrementacja zwraca w miejsce swojego wywołania nową wartość argumentu.
Dekrementacja może występować jako pre-dekrementacja i post-dekrementacja.
Pre-dekrementacja
zmniejsza argument o jeden a następnie zwraca jego wartość
przykładowo w języku C++
int i; // dla zmiennej i
--i;
Post-dekrementacja
zwraca wartość argumentu a następnie zmniejsza jego wartość (dokładniej to zmniejsza wartość o 1, a następnie zwraca wartość sprzed zmniejszenia)
przykładowo w języku C++
int i; // dla zmiennej i, to samo na 3 sposoby
i=i-1;
i-=1;
i--;
Inkrementacja to operacja matematyczna powodująca zwiększenie wartości zmiennej o jeden.
Ze względu na częste użycie tej operacji przez programistów posiada ona osobny operator w wielu językach programowania (np. w języku C) lub nawet jest implementowana jako osobny rozkaz w procesorach (np. w rodzinie Intel x86 jest to rozkaz reprezentowany za pomocą mnemonika INC).
Jej przeciwieństwem jest dekrementacja.
Rekurencja albo rekursja (ang. recursion, z łac. recurrere, przybiec z powrotem) to w logice, programowaniu i w matematyce odwoływanie się np. funkcji lub definicji do samej siebie. Wbrew próbom rozróżnienia terminów[potrzebne źródło] rekursja i rekurencja w rzeczywistości słowa te mają identyczne znaczenie[potrzebne źródło]. Z punktu widzenia języka polskiego preferowane jest określenie rekurencja[1].
W logice wnioskowanie rekurencyjne opiera się na założeniu istnienia pewnego stanu początkowego oraz zdania (lub zdań) stanowiącego podstawę wnioskowania (przy czym aby cały dowód był poprawny zarówno reguła jak i stan początkowy muszą być prawdziwe). Istotą rekurencji jest tożsamość dziedziny i przeciwdziedziny reguły wnioskowania, wskutek czego wynik wnioskowania może podlegać tej samej regule zastosowanej ponownie.
Na prostym przykładzie:
reguła: każdy ojciec jest starszy od swojego syna; każdy ojciec jest czyimś synem
stan początkowy: jestem 22-letnim mężczyzną
teza: ojciec ojca mojego ojca jest starszy ode mnie
dowód:
mój ojciec jest starszy ode mnie
mój ojciec jest czyimś synem
ojciec mojego ojca jest starszy od mojego ojca
ojciec mojego ojca jest czyimś synem
itd.
Na przykładzie zastosowań matematycznych poniższa definicja ciągu Fibonacciego jest rekurencyjna:
, dla
gdyż definiuje funkcję odwołując się w definicji do niej samej.
Każda definicja rekurencyjna potrzebuje przynajmniej jednego przypadku bazowego (nie rekurencyjnego), w tym przypadku są to wartości dla 0 i 1. W przeciwnym wypadku nigdy się nie zakończy.
Dla przykładu, obliczenie wygląda następująco:
Innym przykładem jest wyliczanie największego wspólnego dzielnika za pomocą algorytmu Euklidesa:
,
dla oznacza tu resztę z dzielenia przez
lub inaczej:
Rekurencja jest podstawową techniką wykorzystywaną w funkcyjnych językach programowania.
Należy jednak zachować ostrożność przy używaniu rekurencji w rzeczywistych programach. Jeśli program nie jest w rzeczywistości rekurencyjny, to rekurencja może dramatycznie zwiększyć złożoność obliczeniową. Ponadto rekurencja zawsze zwiększa pamięciowe zapotrzebowanie programu (chyba że zostanie użyta możliwa w pewnych przypadkach optymalizacja zwana rekursją ogonową), gdyż wymaga ona zapamiętania m.in. adresów powrotu, pozwalających programowi "zorientować się" do którego miejsca ma wrócić po zakończeniu jednego z wywołań rekurencyjnych. Inną częstą wadą rekurencji jest kompletnie niezależne rozwiązywanie podproblemów, tak, że czasem jeden problem jest rozwiązywany w kilku miejscach rozwinięcia rekurencji, np. w powyższym przykładzie obliczania niepotrzebnie jest dwukrotnie obliczana wartość (porównaj: programowanie dynamiczne). Takie problemy nie pojawiają się przy drugim z przykładów. Niezaprzeczalną zaletą rekurencji jest przejrzystość programów, które z niej korzystają.
Instrukcje sterujące
Instrukcje są bardzo przydatnymi poleceniami służącymi do sterowania przebiegiem programu (stąd ich nazwa: instrukcje sterujące). Za pomocą instrukcji sterujących podejmowane są decyzje o wykonaniu tych czy innych instrukcji programu. Decyzje te podejmowane są na podstawie pewnych warunków - prawdziwości lub fałszywości pewnego wyrażenia:
Wartość zero – fałsz
Wartość inna niż zero – prawda
Po tym wstępie zajmiemy się pierwszą instrukcją sterującą – instrukcją warunkową if, która może mieć następujące formy:
if(wyrażenie) instrukcja1;
lub
if(wyrażenie) instrukcja1;
else
instrukcja2;
Wyrażenie jest to coś, co ma jakąś wartość. Może to być wyrażenie, które najpierw trzeba obliczyć, by poznać jego wartość i na przykład użyć w dalszej części programu; może to być również obiekt do przechowywania określonej zmiennej logicznej.
W pierwszej wersji instrukcji if obliczana może być wartość wyrażenia, jeśli jest ona niezerowa (prawda), to instrukcja jest wykonywana. W przeciwnym razie (wartość wyrażenia jest równa 0 – fałsz), instrukcja nie zostanie wykonana.
W drugim przypadku przypadku widzimy dodatkowe słowo else, które można przetłumaczyć jako: „w przeciwnym razie”. A zatem jeśli w tym drugim przypadku wartość wyrażenia jest niezerowa, to zostanie wykonana instrukcja pierwsza w przeciwnym razie (nasze słowo else), gdy wartość wyrażenia jest zerowa, to zostanie wykonana instrukcja druga.
Wynik wyrażenie może być wynikiem różnego typu (np. całkowity). Sprawdza się tylko czy jest równy 0 czy nie.
Zanim przejdziemy do przykładu należy wspomnieć jeszcze o tzw. bloku instrukcji.
Z blokiem instrukcji mamy do czynienia w przypadku, kiedy chcemy wykonać kilka instrukcji. Należy wówczas stosować instrukcję składaną zwaną inaczej blokiem. Jest to zbiór instrukcji ograniczonych nawiasami „{}”.
{
instrukcja1;
instrukcja2;
instrukcja3;
instrukcja4;
}
Po klamrach nie trzeba stawiać średników.
A oto przykładowy program:
#include <iostream.h>
main()
{
int wiek;
cout<
cin>>wiek;
if(wiek<18)
{
cout<<”\\n”<<”Pamiętaj, że nie wolno ci kupować papierosów!”;
}
else
{
cout<<”\\n”<<”Jesteś już dorosły”;
}
}
Różna wielkość odstępów od lewego marginesu nie ma dla kompilatora żadnego znaczenia. Pomagają one programiście – chodzi o tzw. estetykę programu.
Instrukcje warunkowe są podstawą każdego języka programowania. Używa się jej do wykonania pewnej instrukcji (lub bloku instrukcji), ale tylko w pewnych okolicznościach - zostanie spełniony określony warunek (lub cały zestaw warunków). Składnia instrukcji warunkowej jest następująca:
<?
if(wyrażenie_warunkowe)
instrukcja wykonywana jeśli spełniony zostanie warunek
else if(inne_wyrażenie_warunkowe)
instrukcja wykonywana jeśli spełniony zostanie drugi warunek, a pierwszy nie
else
instrukcja wykonywana jeśli nie zostanie spełniony żaden z warunków
?>
Wyrażeniem warunkowym jest w zasadzie dowolne wyrażenie, ponieważ za warunek uznawane jest wszystko co zwraca wartość, czyli wszystkie zmienne, wyrażenia logiczne, funkcje itp. Za spełniony warunek uznawana jest wartość większa od zera.
<?
$a = 2;
$b = 5;
$c = 1;
if($a > $b)
echo "$a jest większe od $b";
else if($b > $c)
echo "$b jest większe od $c";
else
echo "$c jest większe od $a i $b";
if($a)
echo "Zmienna $a ma wartość większą od zera";
?>
Specyfikatory dostępu
a lekcja będzie szybka i bez bolesna, otóż omówimy specyfikator dostępu: private. Samo pojęcie specyfikator dostępu jest ci znane z poprzednich lekcji, poznałeś na razie jeden specyfikator otóż public dzięki niemu mieliśmy dostęp przez obiekt do składników klasy, a dokładnie do ich kopi gdyż każdy obiekt posiada własną kopię danych klasy. Przejdziemy do rzeczy, gdy jakiś składnik klasy zadeklarujemy jako private to będziemy mieli do niego tylko dostęp z wnętrza klasy, a nie z poza jej jak to było w przypadku specyfikatora dostępu public. Zapewne mniej więcej wiesz o co chodzi, jednak aby utwierdzić cię w tym przekonaniu zaprezentuje krótki przykład w którym wykorzystuję specyfikator dostępu private.
Początek kodu:
using System;
class X
{
private int x = 10;
public void Wyjscie()
{
Console.WriteLine(x);
}
}
class Pokaz
{
public static void Main()
{
X obiekt_x = new X();
//obiekt_x.x = 10 ; <- Błąd gdyż poza klasą składnik 'x' nie jest widoczny
obiekt_x.Wyjscie();
}
}
Koniec kodu:
Zmienną ‘x’ deklarujemy jako private, oznacza to, że jest ona widoczna we wnętrzu klasy, widzą ją wszystkie metody, konstruktory, własności itd. Które są zadeklarowane w klasie, czyli metoda Wyjscie() nam wyświetli wartość zmiennej ‘x’. Ale w klasie Pokaz, już musiałem wy komentować linijkę obiekt_x.x = 10 gdyż nie mam dostępu z poza klasy do tej zmiennej. Nie jest konieczne pisanie w klasie przed każdą zmienną czy to np. metodą słowa private, jeżeli tego nie uczynimy, będzie ona automatycznie zawsze uznawana jako private, ja jednak zalecam zawsze pisanie słowa private, gdyż potem gdy poprawiamy program, unikniemy nie potrzebnej frustracji. Specyfikator dostępu jak wiesz nie odnosi się tylko do zmiennych ale także do metod, jeżeli w powyższym programie metodę Wyjscie() ustawili byś my na private to podczas wywołania obiekt_x.Wyjscie() ; wystąpił by błąd gdyż, obiekt_x nie ma dostępu do metody Wyjscie() więc jej nie może wywołać. Pisząc swoje klasy będziesz często korzystał z specyfikatora dostępu: private, aby użytkowników swojej klasy nie narażać na błędy.
Interfejs tekstowy to interfejs użytkownika, w którym prezentowane informacje mają formę tekstu lub innych znaków wyświetlanych w trybie tekstowym. Użytkownik programu komputerowego z interfejsem tekstowym może wprowadzać polecenia z użyciem różnych urządzeń wejściowych, nie tylko z klawiatury, linia po linii, jak to ma miejsce w przypadku wiersza poleceń. Interfejs tekstowy mogą posiadać także aplikacje uruchamiane w trybie graficznym, zwykle w oknie które emuluje tryb tekstowy.
Tworzenie i obsługę interfejsu tekstowego wspomagają biblioteki programistyczne, takie jak Turbo Vision, ncurses czy S-Lang.
Mimo tego, iż interfejs tekstowy posiada mniejsze możliwości prezentowania informacji dla użytkownika niż interfejs graficzny, to powstają gry wykorzystujące ten sposób interakcji z graczem. Przykładem są gry typu Roguelike.
Interfejs ten był często stosowany w aplikacjach działających na systemach operacyjnych takich jak MS-DOS, PC-DOS, RS-DOS oraz CP/M.
Klasa abstrakcyjna w programowaniu obiektowym jest to klasa, która nie może mieć swoich reprezentantów pod postacią obiektów.[1] Stosuje się ją zazwyczaj do zdefiniowania interfejsów. Zależnie od użytego języka programowania klasy abstrakcyjne tworzy się na różne sposoby.
W Javie klasę abstrakcyjną możemy stworzyć na dwa sposoby: za pomocą słowa kluczowego abstract, które tworzy klasyczną klasę abstrakcyjną lub za pomocą słowa kluczowego interface tworzącego abstrakcyjny interfejs
Klasa abstrakcyjna w Javie nie musi posiadać metod czysto wirtualnych aby być abstrakcyjną, jednak takie użycie klasy abstrakcyjnej określa klasę jako nieinstancjowalną i jest rzadziej spotykane.
Jeśli co najmniej jedna metoda w klasie zostanie zadeklarowana jako czysto wirtualna (abstrakcyjna), to ta klasa musi zostać zadeklarowana jako abstrakcyjna.
Jeżeli wszystkie metody klasy są czysto wirtualne, zaleca się, aby taką klasę zadeklarować jako interfejs klasy.
Klasy Wewnętrzne
Klasy Wewnętrzne - wprowadzenie
Klasę wewnętrzną tworzymy umieszczając jej definicję wewnątrz innej klasy. Nazwa klasy wewnętrznej jest znana w obrębie klasy zewnętrznej. Poza tą klasą musimy użyć konstrukcji NazwaKlasyZewnętrznej.NazwaKlasyWewnętrznej.
Klasa wewnętrzna nie musi być znana wewnątrz całej klasy zewnętrznej, można zdefiniować ją wewnątrz jakiejś metody klasy zewnętrznej, a nawet w dowolnym, ograniczonym nawiasami klamrowymi zakresie wewnątrz takiej metody. Taką klasę wewnętrzną nazywamy lokalną, nie jest zdefiniowana poza tym zakresem.
Kiedy stosować klasy wewnętrzne?
Klasy wewnętrzne przydają się w specyficznych sytuacjach. Jednym z ważniejszych powodów stosowania klas wewnętrznych jest fakt, że każda może dziedziczyć niezależnie od innych klas wewnętrznych, jak i od klasy zewnętrznej, zachowując jednocześnie dostęp do składników klasy zewnętrznej (także prywatnych!).
Jest do dobry sposób na ominięcie zakazu dziedziczenia po dwóch klasach. Wynika z tego także, że każda klasa wewnętrzna może na swój sposób dziedziczyć z tej samej klasy bądź implementować ten sam interfejs, co jest szczególnie przydatne w obsłudze zdarzeń.
public class Pos
{
int x, y, z;
}
public abstract class Movement
{
//przechowuje tor ruchu do p
public abstract void move(Pos p);
}
class Bird
{
private Pos currentPos;
class Flying extends Movement
{
public void move(Pos p)
{
//generuje tor lotu od currentPos do p
}
}
class Jumping extends Movement
{
public void move(Pos p)
{
//generuje tor ruchu od currentPos do p
}
}
public Flying fly(Pos p)
{
Flying f = new Flying();
f.move(p);
return f;
}
public Jumping jump(Pos p)
{
Jumping j = new Jumping();
j.move(p);
return j;
}
}
Generalnie ptaki mogą poruszać się na dwa sposoby: potrafią latać i skakać. Powyższa konstrukcja umożliwia wygenerowanie toru ruchu ptaka na dwa sposoby, w zależności od wywołanej klasy. Ponadto widzimy, że obie klasy wewnętrzne mogą korzystać z prywatnego pola currentPos.
Jeżeli zdefiniujemy klasę w jakiejś innej klasie, wewnątrz tej klasy kolejną, wewnątrz niej kolejną i tak dalej, to każda z tych klas będzie miała dostęp do składowych wszystkich klas dla niej zewnętrznych, np.
class A { //ma dostęp tylko do własnych składników
class B { //ma dostęp do składników klas A i B
class C { //ma dostęp do składników klas A, B i C
class D { //ma dostęp do składników klas A, B, C i D
}
}
}
}