Konspekt jest współfinansowany przez Unię Europejską
w ramach Europejskiego Funduszu Społecznego
w projekcie:
"Innowacyjna dydaktyka bez ograniczeń
- zintegrowany rozwój Politechniki Łódzkiej zarządzanie Uczelnią,
nowoczesna oferta edukacyjna
i wzmacniania zdolności do zatrudniania,
także osób niepełnosprawnych".
Ewa Dyka
Marek Mończyk
Konspekt
Podstawy informatyki
Spis treści
Wstęp
INFORMACJA
Słowo informacja (łac. informatio - przedstawienie, wizerunek; informare - kształtować, wyobrażać, określać) początkowo odnoszone było jedynie do relacji społecznych i oznaczało powiadomienie o czymś, zakomunikowanie czegoś; wiadomość, wskazówkę, pouczenie. Stopniowo następowało rozszerzenie znaczenia tego słowa na różne dziedziny nauki,
gdzie przyjmowało ono różnorodne interpretacje w zależności od obiektu i relacji między obiektami, przy czym jako obiekty rozumiane są organizmy żywe, struktury społeczne
i gospodarcze, urządzenia techniczne itp.
Termin informacja używany jest między innymi w:
genetyce (kod DNA)
zoologii (bodźce przekazywane między zwierzętami)
socjologii (czynnik organizujący struktury społeczne)
psychologii (bodziec wpływający na zachowanie człowieka)
ekonomii (czynnik wpływający na racjonalność decyzji człowieka)
Obecnie w fizyce informacja rozumiana jest jako powszechna właściwość każdego układu materialnego i stanowi powszechną własność materii.
Ogólnie termin ten określa właściwości pewnych obiektów oraz relację między elementami zbiorów pewnych obiektów, prowadząc do zmniejszenia ich nieokreśloności.
Informacja jest wielkością abstrakcyjną, która może być przechowywana i przetwarzana
w obiektach, przesyłana pomiędzy obiektami oraz stosowana do sterowania nimi.
W XX w., wraz z wynalezieniem maszyn cyfrowych i rozwojem technologii komputerowych, termin informacja zaczął oznaczać m.in. dane (wyrażone za pomocą znaków językowych), które można gromadzić, przetwarzać i przekazywać.
INFORMATYKA
Informatyka to ogół dyscyplin nauki i techniki, których przedmiotem jest gromadzenie, analizowanie, przetwarzanie i wykorzystywanie informacji. Początkowo była ona częścią matematyki, obecnie stanowi już samodzielną dyscyplinę naukową wykorzystywaną w wielu dziedzinach życia, która oparta jest niezmiennie na podstawach teoretycznych matematyki.
Zakres informatyki obejmuje:
teorię informatyki (badanie właściwości zjawisk dotyczących przetwarzania informacji)
programowanie (ang. software)
sprzęt komputerowy (ang. hardware)
metody informatyki w różnych dziedzinach działalności ludzkiej
W Polsce termin informatyka został zaproponowany w październiku 1968 r.
przez prof. Romualda Marczyńskiego na konferencji poświęconej „maszynom matematycznym”.
Rozwój techniki komputerowej
Podstawowym narzędziem wykorzystywanym w rozwiązywaniu problemów informatycznych jest komputer. Nazwa wskazuje na urządzenie do wykonywania obliczeń,
ale współczesne komputery stały się bardzo uniwersalnymi narzędziami do przekształcania, gromadzenia i udostępniania różnorodnych informacji.
Komputer - urządzenie elektroniczne posiadające system cyfrowy przetwarzający dane wejściowe według algorytmu zapisanego w postaci programu umieszczonego w pamięci.
Sprzęt komputerowy - (ang. hardware) sprzęt elektroniczny pomocny przy przetwarzaniu danych np.: komputer, drukarka, skaner i inne podzespoły.
Umowny podział komputerów
Generacja zerowa (lata 1936-46)
budowane w oparciu o przekaźniki elektromechaniczne działały jak programowalne kalkulatory elektryczne.
Generacja pierwsza (lata 50-te)
budowane w oparciu o lampy elektronowe elektroniczne maszyny cyfrowe programowane w języku wewnętrznym (ang. assembler); duże rozmiary, dane przechowywane na taśmach i kartach perforowanych lub bębnach magnetycznych (ENIAC).
Generacja druga: (lata 60-te)
budowane w oparciu o tranzystory, programowane w językach wysokiego poziomu: Fortranie, Algolu, Cobolu; mniejsze rozmiary, pamięci ferrytowe, taśmy magnetyczne, dane na dziurkowanych kartach, wyniki w postaci wydruków (ZAM 41).
Generacja trzecia (lata 70-te)
budowane w oparciu o układy scalone, możliwa praca wielodostępna pod nadzorem systemu operacyjnego, nowe języki programowania Pascal, C; karty dziurkowane, bardzo drogie dyski magnetyczne (Odra 1305).
Generacja czwarta (lata 80-te)
budowane w oparciu o układy scalone o wielkiej skali integracji, mikrokomputery IBM PC i superkomputery (Cray), pojawia się programowanie obiektowe i komputery równoległe
w różnych architekturach, wieloprocesowe systemy operacyjne, rozwój specjalnych języków i kompilatorów dla potrzeb równoległego przetwarzania.
Generacja piąta (lata 90-te)
budowa jak w generacji czwartej, rozwija się masowo przetwarzanie równoległe (MPP), komputery pracują w sieciach, wykorzystywane jest przetwarzanie heterogeniczne
przy użyciu sieci heterogenicznych komputerów z dzieloną pamięcią wirtualną; systemy MPP piątej generacji są reprezentowane przez projekty takie jak Fujitsu (VPP500), Cray Research (MPP), Thinking Machines Corporation (CM-5) oraz Intel Superior Systems (Paragon).
Generacja szósta (wiek XXI)
komputery o bardzo wielu jednocześnie pracujących procesorach,
komputery przyszłości:
biokomputery - nie będą oparte, tak jak obecnie, na związkach półprzewodnikowych (krzemowych), lecz na związkach biologicznych (węglowych),
komputery optyczne - wykorzystujące światło zamiast prądu elektrycznego, dzięki czemu możliwe będzie zwiększenie aż do prędkości światła ich szybkość działania,
komputery kwantowe i neurokomputery
Trendy rozwoju komputerów
Powrót do terminali
Terminal jest końcówką pozwalającą człowiekowi na pracę z komputerem lub systemem komputerowym. Początkową formą pracy terminalowej był dalekopis. Po powstaniu komputera osobistego prawie całkowicie zrezygnowano z pracy terminalowej, pozostawiając ją jedynie dla dużych serwerów sieciowych. Dokonujący się w ostatnich latach znaczący rozwój sieci komputerowych spowodował powszechny powrót do pracy terminalowej w postaci terminali wirtualnych.
Mobilne komputery
Obecnie komputery mobilne (przenośne) wypierają w coraz większym stopniu osobiste komputery stacjonarne. Pierwszym komercyjnie oferowanym komputerem mobilnym był zaprojektowany w 1979 roku laptop (ang. lap - kolana, top - na wierzchu) o nazwie Grid Compass Computer 1109, który używany był przez NASA w programie promów kosmicznych. W latach 80-tych XX w. powstały prototypy pierwszych palmtopów
(ang. palm - dłoń, top - na wierzchu), komputerów wielkości dłoni, których podstawowymi funkcjami były: kalendarz, terminarz, kalkulator, notatnik (także notatki odręczne), książka adresowa. Do grupy komputerów mobilnych należą również mniejsze od laptopów notebooki oraz netbooki.
Przetwarzanie rozproszone
Przetwarzanie rozproszone (ang. distributed processing) polega na wykonywaniu określonych zadań przez użytkownika korzystającego ze współdzielonych zasobów sieci komputerowej. Przeważnie przetwarzanie to dotyczy heterogenicznych sieci komputerowych z dzieloną pamięcią wirtualną. Przykładem przetwarzania rozproszonego są obliczenia rozproszone, które polegają na jednoczesnej pracy wielu komputerów nad jednym zagadnieniem. Na podstawie danych pobranych z serwera komputery wykonują zaprogramowane obliczenia, których wyniki przesyłają z powrotem do serwera, gdzie są one gromadzone i udostępniane do dalszej analizy.
Wolne Oprogramowanie
Wolne Oprogramowanie (ang. Free Software, Open Source) rozprowadzane jest zgodnie
z regułami zawartymi w Powszechnej Licencji Publicznej GNU, której celem jest prawne zagwarantowanie producentom możliwości tworzenia oprogramowania bez ograniczeń licencyjnych dla wszystkich użytkowników. Użytkownicy licencji mają zagwarantowaną swobodę zmieniania i udostępniania tego oprogramowania, przy czym zobowiązani są
do udostępniania postaci źródłowej programu wraz z każdą jego dystrybucją binarną.
Na zasadach GNU GPL udostępniane jest m.in. jądro systemu operacyjnego Linux
oraz większość jego oprogramowania.
Podstawy teorii informacji
Informacja
każdy czynnik, zmniejszający stopień niewiedzy o jakimś zjawisku czy obiekcie
każdy czynnik zmniejszający niewiedzę odbiorcy
czynnik, dzięki któremu człowiek lub urządzenie mogą lepiej działać.
Wiadomość
czynnik, na podstawie którego ludzie, organizmy żywe lub urządzenia automatyczne mogą w sposób sprawny przeprowadzać celowe działanie.
Komunikat
zakodowana wiadomość zawierająca informację.
WŁASNOŚCI INFORMACJI
istnieje niezależnie od obserwatora, który ją odbiera, choć różnie interpretuje,
odzwierciedla tylko pewną cechę obiektu, nie stanowi jego wyczerpującej charakterystyki,
kolejne informacje o obiekcie tworzą nowy obraz obiektu,
jest różnorodna,
może być powielana i przenoszona w czasie i przestrzeni, choć może ulec zniekształceniu,
informację można przetwarzać.
FUNKCJE INFORMACJI
może być obrazem rzeczywistości, miarą złożoności i różnorodności badanego wycinka rzeczywistości,
może motywować do działań, a więc osiągania pewnych celów,
jest czynnikiem sterującym: stanowi podstawę do budowania planów i podejmowania decyzji, itp.,
informacja prowadzi do wiedzy,
jest podstawowym czynnikiem w rozwoju systemu rynkowego (obok kapitału, ziemi, pracy i organizacji).
JEDNOSTKI INFORMACJI
najmniejsza jednostka informacji - bit (ang. binary digit);
przyjmuje jedną z dwóch wartości 0 lub 1
najmniejsza jednostka adresowalna pamięci komputerowej - bajt (ang. byte);
bajt = 8 bitów
najkrótsze słowo maszynowe (ang. word) - 16 bitów (2 bajty);
długość słowa jest potęgą liczby 2 (16, 32, 64 ....)
słowo jest jednostką danych używanych przez określony komputer, a jego wielkość uwarunkowana jest przez rozmiar rejestrów procesora oraz szyny danych
wielokrotności bajtów:
1kbajt [KB]=210 bajta= 1024 bajty
1Mbajt [MB]= 220 bajta = 1024 KB =1048576 bajty
1 Gbajt = 230 bajta = 1024 MB = 1073741824 bajty
1 Tbajt [TB] =240 bajta = 1024 GB
Systemy liczbowe
System liczbowy definiuje zbiór wartości (cyfr) wykorzystywany do reprezentowania ilości (liczby) oraz określa zasady zapisu liczb i wykonywania na nich obliczeń.
Wśród dyskretnych zapisów kodowych wyróżnia się:
zapis dwójkowy (binarny),
ósemkowy (oktalny),
dziesiętny,
szesnastkowy (heksadecymalny)
dwójkowy z kodowaniem dziesiętnym BCD (ang. Binary Coded Decimal).
Komputer gromadzi i przetwarza informację zapisaną wyłącznie w systemie dwójkowym.
System dwójkowy
dwa znaki (cyfry) : 0, 1
zapis liczby naturalnej:
L(2) = c0*20 + c1*21 + ... + cn * 2n gdzie: c0, c1, cn - cyfry układu
10110(2) = 0*20 + 1*21 + 1*22 + 0*23 + 1*24 = 0+2+4+0+16 = 22(10)
System dziesiętny
dziesięć znaków (cyfr): 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
zapis liczby naturalnej:
L(10) = c0*100 + c1*101 + ... + cn * 10n gdzie: c0, c1, cn - cyfry układu
2548(10) = 8*100 + 4*101 + 5*102 + 2*103
System szesnastkowy
szesnaście znaków: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F
zapis liczby naturalnej:
L(16) = c0*160 + c1*161 + ... + cn * 16n gdzie: c0, c1, cn - cyfry układu
400(16) = 0*160 + 0*161 + 4*162 = 1024(10)
System BCD
dwa znaki (cyfry): 0, 1
zapis liczby naturalnej:
L(BCD) = L(2) L(2) gdzie: L(2) - czteropozycyjna liczba w systemie dwójkowym
34(10) = 0011 0100(BCD)
Jest to dziesiętny kod pozycyjny; każda cyfra dziesiętna kodowana jest na czterech pozycjach
w systemie dwójkowym. Kod BCD jest kodem nadmiarowym, ponieważ wykorzystuje jedynie 10 liczb
z 16 możliwych do zakodowania na czterech pozycjach kodu binarnego. Ze względu na przechowywanie informacji w bajtach, w jednym bajcie przechowuje się 1 lub 2 liczby (upakowany BCD).
Konwersja układów z dwójkowego na szesnastkowy
W celu dokonania konwersji liczby zapisanej w systemie dwójkowym na system szesnastkowy należy tę liczbę podzielić na czteroznakowe fragmenty i przypisać im odpowiednie wartości kodu szesnastkowego:
10010101001111110001(2) = (1001) (0101) (0011) (1111) (0001)
(1001)(2) (0101)(2) (0011)(2) (1111)(2) (0001)(2)
(9)(10) (5)(10) (3)(10) (15)(10) (1)(10)
(9)(16) (5)(16) (3)(16) (F)(16) (1)(16)
Aby zamienić liczbę z systemu szesnastkowego na system dwójkowy, należy każdą cyfrę szesnastkową zastąpić ciągiem czterech cyfr w systemie dwójkowym.
Konwersja układów z dziesiętnego na dwójkowy
Aby liczbę dziesiętną zapisać w postaci binarnej należy dzieląc ją kolejno przez dwa zapisywać resztę z dzielenia:
41 : 2 = 20 r 1
20 : 2 = 10 r 0
10 : 2 = 5 r 0
5 : 2 = 2 r 1
2 : 2 = 1 r 0
1 : 2 = 0 r 1
Wynik stanowi kolumna reszt z dzielenia przepisana kolejno od dołu w górę:
(41)(10) = (101001)(10)
Kodowanie informacji
Komputer może przetwarzać jedynie dane zapisane w postaci binarnej (zero-jedynkowej), dlatego wszystkie informacje wprowadzane do komputera (liczby, litery, wartości logiczne, kolory, obrazy, dźwięki itp.) muszą zostać przekształcone do tej postaci. Zapis w postaci binarnej (według ustalonych reguł) dowolnej informacji nazywany jest kodowaniem.
Kodowanie liczb całkowitych
Liczba całkowita jest przekształcana do postaci binarnej. Istnieją różne systemy kodowania, np. system ZM (znak-mantysa) lub U2 (uzupełnienie do dwóch), gdzie wszystkie bity zamieniane są na przeciwne i dodawana jest binarna jedynka.
(10) ZM U2
-127 1 1111111 1 0000001
-126 1 1111110 1 0000010
-1 1 0000001 1 1111111
0 0 0000000 0 0000000
Istnieją też inne sposoby kodowania np. kod nadmiarowy (ang. redundancy code). Kod ten, oprócz bitów przedstawiających kodowaną informację, zawiera również tzw. bity kontrolne, dzięki którym możliwe jest poprawianie błędów kodowania. Przykładowo informacja przyjmująca 3 wartości (-1, 0, 1) może zostać zakodowana w 4 bitach w taki sposób, że 1000 oznacza 0, 1001 oznacza 1 a 0111 to -1.
Minimalna i maksymalna liczba, którą można zapisać na n bitach wynosi:
Lmin = - 2n-1 Lmax = 2n-1-1
Np. dla typu short int (C, C++) reprezentującego liczby całkowite za pomocą dwóch bajtów (16 bitów) zakres jest następujący: -32768 ÷32767 (ze znakiem) lub: 0 ÷ 65535 (bez znaku).
Kodowanie liczb rzeczywistych
Liczbę zapisujemy w postaci:
L = ± m · pc gdzie:
m - mantysa,
c- cecha,
p - podstawa systemu liczbowego
Przykład zapisu w systemie dziesiętnym (p = 10)
0,000123 = 0,123 ⋅ 10-3
32,25 = 0,3225 ⋅ 102
Przykład zapisu w systemie dwójkowym (p = 2)
5,625
5 = 101 część całkowita 101
0,625 ⋅ 2 = 1,25 część ułamkowa 0,25 całkowita 1
0,25 ⋅ 2 = 0,5 część ułamkowa 0,5 całkowita 0
0,5 ⋅ 2 = 1 część ułamkowa 0 całkowita 1
Zapisujemy części całkowite w kierunku z góry na dół
5,625 = 101,101
5,625 = 0,101101 ⋅ 23
Błędy zaokrągleń
Zaokrąglenia przy zamianie liczb w systemie dziesiętnym na liczby w systemie dwójkowym (i odwrotnie):
np. nie można przedstawić liczby 0,1 w systemie dwójkowym w postaci
skończonej liczby cyfr:
1/16 + 1/32 + 1/256 + 1/512 + 1/4096 + 1/8192 + 1/65536 = 0,0999908
Zaokrąglenia przy wykonywaniu obliczeń:
np. trzy cyfry dziesiętne w mantysie:
1,51
+ 0,00001
--------------------
1,51001 komputer przechowa wartość 1,51
Złożenie błędów zaokrąglania z utratą cyfr znaczących przy dodawaniu i odejmowaniu:
np. 7,54293 - 7, 54129 i TRZY cyfry dziesiętne w mantysie.
Kompilator obliczy: 7,54 - 7,54 = 0, choć dokładny wynik wynosi 0,00164
Zero maszynowe - liczba która nie jest zerem, ale w komórce przyjmuje wartość zero.
Kodowanie tekstu
Rozszerzone kody ASCII (American Standard Code for Information Interchange) mają rozmiar 8 bitów (jeden bajt), co pozwala na zakodowanie 256 znaków. Podstawowy kod ASCII jest kodem 7-bitowym umożliwiającym zakodowanie 128 znaków w zakresie 0 ÷ 127.
Wszystkie znaki drukowane (tzn. duże i małe litery, cyfry znaki przystankowe itp.), których jest w sumie 95, mają przypisane wartości kodu od 32 do 126.
Kody ASCII z zakresu 0 ÷ 31 oraz kod 127 ( w sumie 33 kody) stosowane są
do kodowania znaków sterujących (np. przejdź do nowego wiersza LF - kod 10, powrót kursora do początku wiersza CR - kod 13).
Dodatkowe 128 znaków i symboli (zakres kodu: 128 ÷ 255) jest zarezerwowane
dla wykorzystania przez producenta komputera, choć przeważa standard kodowania stosowany przez firmę IBM. W powyższym zakresie zawarte są znaki narodowe i znaki semigrafiki (symbole, pozwalające tworzyć na ekranie ramki itp.) .
Korzystanie ze znaków narodowych wymaga zainstalowania strony kodowej
w odpowiednim standardzie. Obecnie istnieje 28 standardów kodowania polskich znaków. Polska Norma zaleca stosowanie standardu ISO-8859-2, który domyślnie instalowany jest
w systemach Linux.
W systemie Microsoft Windows stosowana jest czcionka w standardzie Windows-1250. Różni się ona od ISO-8859-2 pozycją sześciu liter w tablicy ASCII (ąśźĄŚŹ).
Czcionkę ISO można znaleźć w Internecie i zainstalować w systemie Windows. Dostępne są także programy do konwersji czcionki między formatami.
Niektóre bardziej rozbudowane edytory stron WWW mają wbudowane konwertery znaków. Na stronach WWW zaleca się stosowanie kodowania
wg PN.
Kodowanie obrazu
Reprezentacja kolorów
Historycznie trzema podstawowymi barwami były kolory czerwony, niebieski i żółty. Obecnie wykorzystuje się dwa różne zestawy barw podstawowych stosowane do kodowania kolorów. Barwy podstawowe po odpowiednim zmieszaniu pozwalają na uzyskanie dowolnego koloru z zakresu światła widzialnego.
Istnieją dwa podstawowe sposoby kodowania barw:
RGB (red-czerwony, green-zielony, blue-niebieski) - system mieszania barw addytywny (mieszanie światła emitowanego) stosowany jest w telewizji, monitorach (bezpośrednie źródła światła).
CMYK (cyan-turkusowy, magenta-karmazynowy, yellow-żółty, black-czarny) - system mieszania barw subtraktywny (mieszanie światła odbitego) stosowany jest
w druku. Barwa światła wpływa na kolory widziane na wydruku, barwniki pochłaniają wybrane barwy, odbijają pozostałe (biały papier odbija, czarny pochłania wszystkie barwy).
Rys. 3.1Mieszanie barw addytywne Rys. 3.2 Mieszanie barw subtraktywne
Grafika rastrowa
Grafika rastrowa wykorzystywana jest do prezentacji obrazu na monitorach, drukarkach oraz innych urządzeniach wyjściowych. Obraz złożony z pikseli tworzony jest na pionowo-poziomej siatce zwanej pixmapą. Mapa pikseli przyjmujących wartości binarne nazywana jest bitmapą. Zmiana skali z zastosowaniem aproksymacji powoduje pogorszenie jakości grafiki.
W grafice jednokolorowej (całotonalnej), każdy piksel ma kodowane za pomocą jednego bitu tylko dwie informacje (tj. stan zapalony lub wygaszony), dlatego grafika ta daje się zwykle dobrze kompresować metodami bezstratnymi.
Pixmapa w grafice wielotonalnej określa położenie każdego piksela i jego dokładny kolor (RGB, CMYK), dzięki czemu jest ona bardzo dokładna i wyraźna, ale pliki takie są bardzo duże i z reguły wymagają kompresji.
Liczba kolorów przypisanych do każdego piksela zależy od ilości bitów przeznaczonych do kodowana:
8 bitów - 256 kolorów,
16 bitów - 65536 kolorów,
24 bity - 16.8 milionów kolorów (tzw. true color).
Większą ilość bitów (np. 32, 48) stosuje się wtedy, gdy obraz ma podlegać obróbce lub ma dużą gęstość optyczną (np. skanowane diapozytywy).
Programy pracujące z bitmapami często nazywają się malarskimi.
Tab. 3.1 Przykładowe rozmiary plików bez kompresji (TIFF) dla formatu A4
Przykładowe formaty grafiki rastrowej:
BMP (Bitmap) 1-24 bitów jest standardowym formatem dla systemów operacyjnych Windows i OS/2,
TIFF (Tagged Image File Format), 48 bit / 16 bit na kanał, przechowuje kanały alfa (odpowiadające za przezroczystość), profile koloru, komentarze tekstowe, umożliwia stosowanie kompresji bezstratnej, główne zastosowania - DTP (Desktop Publishing),
GIF (Graphics Interchange Format), 8 bitów, bezstratna kompresja, możliwa przezroczystość i animacja, tworzenie wymaga opłat licencyjnych,
PNG (Partable Network Graphics) 1-49 bitów, bezstratna kompresja,
JPEG (Joint Photographic Experts Group) 24 bitowe kodowanie oraz kompresja z utratą danych (im gorsza jakość, tym mniejszy plik wynikowy). JPEG może zapisać kolory
w systemie RGB lub CMYK.
Kompresja JPEG
Kompresja JPEG to najbardziej powszechny algorytm kompresji obrazów.
Kolejne kroki algorytmu JPEG to:
różne stopnie kompresji dla jasności i kolorów. Oko lepiej postrzega różnice jasności
od różnic barwy, stąd zamiana RGB na kanał jasności i dwa kanały kolorów,
obniżenie rozdzielczości kanałów koloru, ponieważ rozdzielczość postrzegania kolorów przez ludzkie oko jest słaba,
podzielenie każdego kanału obrazka na bloki 8x8. Transformata kosinusowa każdego
z bloków. Zamiast wartości pikseli otrzymujemy średnią wartość i częstotliwość zmian wewnątrz bloku wyrażone przez liczby zmiennoprzecinkowe. Transformata ta jest odwracalna,
zastąpienie średnich wartości bloków przez różnice wobec wartości poprzedniej. Poprawia to w pewnym stopniu współczynnik kompresji,
zastąpienie danych zmiennoprzecinkowych przez liczby całkowite. Zależnie od parametrów kompresora, odrzuca się mniej lub więcej danych.
Grafika wektorowa (obiektowa)
Obraz przedstawiany jest za pomocą obiektów, którymi są figury geometryczne (grafika dwuwymiarowa) lub bryły geometryczne (grafika trójwymiarowa), umieszczanych
w odpowiednim układzie współrzędnych. Obiekty te złożone są z prostych figur geometrycznych (odcinków, kół, wielokątów), które zdefiniowane są za pomocą swoich charakterystycznych parametrów. Przykładowo odcinek kodowany jest przez współrzędne początku, końca, barwę i grubość linii a okrąg przez współrzędne środka, promień, barwę
i grubość linii.
Grafikę wektorową można przekształcać (przeskalowywać, deformować) bez utraty jakości. Rysunek w formacie wektorowym zajmuje znacznie mniej miejsca, niż w postaci bitmapy. Grafika wektorowa znalazła zastosowanie w grafice użytkowej, rysunkach technicznych, rysunkach biznesowych, mapach, planach itp.
Kodowanie dźwięku
Fala dźwiękowa jest sygnałem analogowym, w celu zakodowania wymaga przetworzenia na sygnał dyskretny (postać cyfrową).
Podstawowe parametry określające transformacje dźwięku to:
rozdzielczość próbkowania określająca natężenie dźwięku w danym momencie (zapisywana jest w postaci liczby 8 lub 16-to bitowej),
częstotliwość próbkowania określa częstość pobierania próbki z analogowej fali dźwiękowej (im większe częstotliwości występują w fali, tym wymagana jest większa wartość tego parametru).
Aby nie tracić jakości należy stosować częstotliwość próbkowania dobraną
do maksymalnych częstotliwości występujących w próbce. Przykładowo wg kryterium Nyquist'a dla dźwięków odbieranych przez ucho (ok. 22 kHz) potrzeba częstotliwości próbkowania
ok. 44 kHz.
Przykłady digitalizacji 10s dźwięku:
rozmowa telefoniczna 8 bitów, 8 kHz, 78 KB
płyta CD 16 bitów, 44 kHz, 860 KB
DTS-Digital Surround Audio 24 bity, 96 kHz, 3750 KB
DTS-HD Master Audio 24 bity, 192 kHz, 7500 KB
Podstawowe formaty dla zapisu nieskompresowanego dźwięku:
wav - platforma MS Windows
aiff - platforma Apple Macintosh
au - platforma Unix (Solaris).
Inne ważniejsze formaty:
mp3 - obecnie najpopularniejszy format przenośny (MPEG Audio Layer 3) z kompresją fizjologiczną, zaletą jego jest wysoka kompresja dźwięku, co przy jakości CD mp3 daje średnio 12-krotną kompresję,
midi - zapis nutowy, nadaje się jedynie dla muzyki (nie nadaje się do kodowania mowy, śpiewu, szumów), zaletą formatu są wyjątkowo małe rozmiary pliku: kilkanaście minut muzyki to 30-40 kB,
Ogg Vorbis - podobny sposób kompresji dźwięku jak mp3, dostępny bez opłat licencyjnych, wyższy stopień kompresji niż w mp3 przy zachowaniu podobnej jakości dźwięku.
Mp3 jest objęty prawem autorskim, za jego użycie trzeba płacić (sierpień 2002: opłaty licencyjne obejmują teraz nie tylko kodowanie do mp3, ale również odtwarzanie mp3).
Model psychoakustyczny ludzkiego słuchu uwzględnia:
różnicę w słyszalności dźwięków o różnych częstotliwościach, dźwięki ze środka zakresu są znacznie lepiej słyszalne niż bardzo niskie i bardzo wysokie. Różnice te są bardzo duże, więc niektóre skrajne dźwięki muszą być setki a nawet tysiące razy silniejsze niż inne,
aby były słyszalne, dlatego część tych dźwięków można usunąć z sygnału.
maskowanie dźwięków - niektóre słabsze dźwięki w pobliżu silniejszych są niesłyszalne, więc można je usunąć.
specyfikę sygnału dwukanałowego, gdzie część dźwięków w kanałach powtarza się lub jest nierozróżnialna między sobą, więc można je usunąć.
Przykłady kodowania 6-cio minutowego fragmentu muzyki:
wav: 66 MB
mp3: 9 MB
ogg: 6 MB
Składniki systemu komputerowego
Komputer - system cyfrowy przetwarzający dane według algorytmu zapisanego w postaci programu umieszczonego w pamięci.
Sprzęt komputerowy - (ang. hardware) sprzęt elektroniczny pomocny przy przetwarzaniu danych np.: komputer, drukarka, skaner i inne podzespoły.
Oprogramowanie - (ang. software) zbiór wykonywanych przez komputer instrukcji sterujących obliczeniami, działaniem sprzętu komputerowego itd..
Budowa komputera
Podział funkcjonalny
Rys. 4.1 Schemat funkcjonalny komputera
Podział ze względu na urządzenia
Rys. 4.2 Schemat blokowy komputera
Podział według kryterium techniczno-aplikacyjnego:
szczególnego przeznaczenia (mają wmontowane systemy, preprogramowane):
sygnalizacja świetlna, telewizor, telefon, urządzenia nawigacyjne i sterujące itp.,
ogólnego przeznaczenia (programowane przez użytkownika):
superkomputer, mainframe, minikomputer, stacja robocza, komputer osobisty.
Superkomputery: projektowane do ściśle określonych zadań: prognozowanie pogody, projektowanie awioniki, analiza deformacji metali pod wpływem zgniatania, symulacje giełdowe,.
Marki: CRAY, IBM, Fujitsu, NEC, UNISYS, HP
Mainframe - bardzo duże maszyny do przetwarzania wielkich ilości danych, konstruowane
do jednoczesnej obsługi wielu użytkowników (rozbudowane układy IO, wiele systemów
na jednej maszynie). Banki, linie lotnicze, duże uczelnie. Przetwarzają ok. 90% krytycznych danych na rynku biznesowym.
Przykład: IBM System/390
Minikomputery - podobne funkcje, tańsze. Obsługują do kilkudziesięciu osób na raz. Zwykle UNIX. Duża moc obliczeniowa: np. IBM AS/400, ponad 200 tys. instalacji na świecie, uważany za najbardziej stabilną platformę z systemem operacyjnym IBM OS/400, głównie jako serwer baz danych bądź aplikacji w sieciach korporacyjnych.
Stacje robocze - zaawansowane technologicznie komputery osobiste. Duża moc obliczeniowa; praca naukowa i inżynierska, CAD; zwykle duże możliwości graficzne. Często pracują
w architekturze klient/serwer jako indywidualne stanowiska robocze podłączone do sieci.
Przykłady: AlphaStation 500/500 firmy DEC; procesor Alpha, UNIX
Mikrokomputery (osobiste) - stacjonarne zwykle jednoprocesorowe wykorzystywane
do prostych zastosowań np. procesorów tekstu, rozrywki itp.
Przykład: komputer klasy IBM PC.
System operacyjny
System operacyjny to pakiet programów, zapewniających wykonywanie na komputerze podstawowych operacji, niezbędny do jego poprawnego funkcjonowania.
Zadaniem systemu operacyjnego jest tworzenie bezpiecznego i niezawodnego środowiska, w którym użytkownik może wykonywać swoje programy w sposób wygodny i wydajny.
System operacyjny rozpoczyna działanie jako pierwszy program w komputerze i nie zaprzestaje działania aż do wyłączenia komputera.
Szczegółowe zadania systemu operacyjnego:
zarządzanie zasobami płyty głównej (podział czasu procesora, przydział pamięci itp.),
zarządzanie systemami plikowymi,
zapewnienie komunikacji pomiędzy urządzeniami podłączonymi do komputera,
przydział zasobów dla uruchamianych programów,
tworzenie interfejsu pomiędzy maszyną i użytkownikiem
Rys. 4.3 Abstrakcyjne przedstawienie miejsca systemu operacyjnego w systemie komputerowym.
Systemy operacyjne
jednozadaniowe - w danej chwili może działać tylko jeden program: np. MS-DOS;
wielozadaniowe - w danej chwili może działać kilka programów: np. MS Windows 9x/Me [oraz NT/2000/2003/XP/Vista7], Mac OS, Unix, BeOS, Linux;
jednodostępne - obsługują jednego użytkownika w tym samym czasie:
np. MS-DOS, Windows 9x/Me, BeOS;
wielodostępne - wielu użytkowników jednocześnie: np. MS Windows NT/2000/XT/Vista7, Mac OS X, Unix, Linux.
Zalety wielozadaniowości:
dzielenie czasu procesora, wznawianie zadań, synchronizacja i komunikacja,
dzielenie pamięci operacyjnej, lepsze jej wykorzystanie przez programy działające jednocześnie,
dzielenie urządzeń peryferyjnych,
planowanie zadań i przydziału procesora
System z podziałem czasu:
Procesor jest przełączany pomiędzy wieloma różnymi zadaniami, przy czym przełączenia występują tak często, że użytkownicy mogą współdziałać z programem podczas jego wykonania. Dokonywany jest podział czasu pracy procesora na kwanty przydzielane poszczególnym procesom, dzięki czemu możliwe jest sekwencyjne i quazi-równoległe wykonywanie zadań.
W systemie takim występuje:
interakcja użytkownika z systemem komputerowym (zadanie interakcyjne składa się z wielu krótkich zadań,
wymiana zadania pomiędzy pamięcią i dyskiem (swapping).
Systemy czasu rzeczywistego:
Systemy czasu rzeczywistego (ang. Real-Time Operating System - RTOS) są elementami komputerowych systemów sterowania pracujących w reżimach czasu rzeczywistego.
Podstawowym kryterium pracy tych systemów jest dokładnie określony czas w którym musi nastąpić przetworzenie danych wejściowych i uzyskanie sygnału wyjściowego. Systemy te stosowane są w sterownikach urządzeń o ściśle określonym przeznaczeniu. Przykładem może być sterowanie procesem przemysłowym, monitorowanie stanu zdrowia pacjenta, elektroniczny wtrysk paliwa itp.
Przerwanie (ang. interrupt) - w systemie komputerowym jest to sygnał przesyłany do procesora jednostki centralnej, przez inne urządzenie systemu lub program, powodujący wstrzymanie przez procesor bieżących obliczeń i rozpoczęcie innych, związanych ze zdarzeniem w systemie, które spowodowało przerwanie.
System operacyjny jest sterowany poprzez przerwania.
Obsługa przerwań odbywa się poprzez:
wektor przerwań (ang. interrupt vector) - indeksowaną numerem urządzenia tablicę wskaźników zawierająca informacje o procedurze obsługi przerwania,
odpytywania (ang. polling) - badanie stanu wszystkich urządzeń w celu wykrycia tego, które potrzebuje obsługi.
Architektura przerwań musi zapewnić przechowywanie adresu przerwanej instrukcji (licznik rozkazów, rejestrów).
Nowe przerwania są ignorowane, dopóki aktualnie obsługiwane przerwanie nie zostanie zakończone.
Przerwanie generowane przez oprogramowanie, wywołane błędem lub działaniem użytkownika, nazywane jest pułapką (ang. trap).
System operacyjny - zarządzanie procesami
Proces jest programem w trakcie wykonywania. Wykonanie procesu musi przebiegać sekwencyjnie. Proces jest jednostką pracy w systemie z podziałem czasu.
W skład procesu wchodzi:
kod programu (text section),
licznik rozkazu (program counter),
stos procesu (process stack),
sekcja danych (data section).
Każdy proces jest reprezentowany w systemie operacyjnym przez blok kontrolny procesu (ang. process control bloc k-PCB). Zawiera on informacje związane z danym procesem, które obejmują:
stan procesu,
licznik rozkazów,
informacje o planowaniu przydziału procesora,
informacje o zarządzaniu pamięcią,
informacje do rozliczeń,
informacje o stanie wejścia-wyjścia.
Wątek (ang. thread) zwany też procesem lekkim jest podstawową jednostką wykorzystania procesora.
Wątek określany jest przez:
licznik rozkazów,
zbiór rejestrów,
obszar stosu,
stan,
wątki potomne.
Wątek współużytkuje wraz z innymi równorzędnymi wątkami sekcje kodu, sekcje danych, zasoby systemowe. Tradycyjny proces (ciężki) jest równoważny zadaniu z jednym wątkiem.
Jeżeli zadanie składa się z wielu wątków to w czasie, gdy jeden wątek jest zablokowany może się wykonywać inny wątek tego zadania. Współpraca wielu wątków w jednym zadaniu pozwala zwiększyć przepustowość i poprawić wydajność.
Planowanie zadań
System operacyjny musi wybierać procesy z kolejek oczekiwania. Selekcji dokonują odpowiednie procesy zwane planistami (programami szeregującymi).
Planista długoterminowy - zwany planistą zadań wybiera procesy oczekujące w pamięci masowej na wykonanie (przetwarzanie na dyskach) i ładuje je do pamięci operacyjnej w celu wykonania.
Planista krótkoterminowy - zwany planistą przydziału procesora wybiera jeden proces spośród procesów gotowych i przydziela mu procesor.
Planista średnioterminowy - powoduje usunięcie procesów z pamięci (i z aktywnej rywalizacji
o procesor) w celu zmniejszenia stopnia wieloprogramowości.
Planista długoterminowy dokonuje wyboru spośród procesów:
ograniczonych przez wejście-wyjście - czyli spędzających więcej czasu na wykonywaniu operacji wejścia-wyjścia niż na obliczenia,
ograniczonych przez dostęp do procesora - spędzających więcej czasu na wykonywaniu obliczeń.
Ważne jest, aby planista długoterminowy wybrał właściwą mieszankę procesów
(ang. process mix) zawierającą zarówno procesy ograniczone przez procesor jak i wejście-wyjście.
Przełączanie procesora do innego procesu nazywamy przełączaniem kontekstu
(ang. context swich).
Uwaga:
czas przełączania kontekstu jest narzutem na działanie systemu,
czas przełączania kontekstu zależy od wsparcia ze strony sprzętu.
Kryteria planowania:
wykorzystanie procesora - dąży się do tego, by procesor był maksymalnie zajęty pracą,
przepustowość - maksymalizacja liczby procesów, które zakończyły się w jednostce czasu,
czas cyklu przetwarzania - czas potrzebny do wykonania procesu,
czas oczekiwania - czas spędzony przez proces w kolejce procesów gotowych,
czas odpowiedzi - czas liczony od chwili dostarczenia żądania do chwili uzyskania odpowiedzi (w systemie z podziałem czasu).
Wstęp do programowania
Przygotowanie programu - algorytmy
Algorytm jest graficznym przedstawieniem programu realizowanego przez komputer. Algorytmy możemy podzielić na liniowe i warunkowe. Najpopularniejszym sposobem prezentacji algorytmu jest reprezentacja graficzna. W metodzie tej wykonywane operacje przedstawione są za pomocą odpowiednio połączonych bloków różniących się między sobą wielkością i kształtem.
Symbol |
Operacja |
|
Rozpoczęcie programu |
|
Blok wprowadzenia danych |
|
Blok operacji np. arytmetycznych |
|
Blok decyzyjny - warunkowy |
|
Blok wyprowadzania wyników |
|
Koniec programu |
Tab. 5.1 Podstawowe bloki programu
Rys.5.1 Przykład algorytmu wyznaczanie liczby większej.
Elementy programowania w C++
Ogólna budowa programu w C++
dyrektywy dołączające pliki nagłówkowe bibliotek
dyrektywy prekompilatora
deklaracje funkcji
deklaracje zmiennych globalnych
program główny
deklaracje zmiennych lokalnych
treść programu
definicje funkcji
Przykładowy program podnoszący daną liczbę do potęgi
#include <iostream.h>
#include <conio.h>
#pragma hdrstop //koniec pliku nagłówkowego prekompilatora
long potega(int stopien, long liczba) ;
long wynik;
void main()
{
int x,y;
cout << "Podaj wartosc stopnia potegi";
cin >> x;
cout << "Podaj wartosc liczby potegowanej";
cin >> y;
wynik=potega(x,y);
cout << ”Wynik = “ << wynik;
}
long potega(int stopien, long liczba)
{
long wynik;
wynik = liczba;
for (int i=1; i<stopien; i++)
{
wynik = wynik * liczba;
}
return wynik;
}
Typy danych i zmienne
Zmienną określany jest obszar w pamięci komputera, w którym mogą być przechowywane dane.
Zmienna posiada następujące cechy:
nazwę (identyfikator) - pozwalającą na dostęp do zmiennej
typ danych - określający zajętość pamięci
wartość
Typy reprezentujące liczby całkowite:
short int (short)
int
long int (long)
Typ reprezentujący znaki alfanumeryczne:
char
Typ reprezentujący łańcuch:
string
Typy reprezentujące liczby zmiennoprzecinkowe:
float
double
long double
Typ wyliczeniowy:
enum nazwa_typu {lista wyliczeniowa};
np.: enum dni {pn, wt, sr, cz, pt, sb, nd};
Reprezentacja liczbowa elementów listy:
0, 1, 2, 3, 4, 5, 6
Składnia definicji zmiennej jest następująca:
[modyfikator] typ nazwa [= wartość];
int a;
double b = 6.4;
char c = `A';
static double d = 4.5;
Zakres ważności i czas życia zmiennej.
wszystkie zmienne są znane od miejsca zadeklarowania
zmienne globalne - deklarowane na zewnątrz funkcji; znane w obrębie pliku; przestają istnieć wraz z końcem działania programu
zmienne lokalne automatyczne - deklarowane wewnątrz funkcji; znane w obrębie funkcji; przestają istnieć po zakończeniu działania funkcji.
zmienne lokalne statyczne - deklarowane wewnątrz funkcji (bloku {...}); znane w obrębie funkcji; przestają istnieć wraz z końcem działania programu
Przesłanianie zmiennych
Przesłanianie zmiennych polega na tym, że zmienna lokalna posiadająca tę samą nazwę co zmienna globalna lub inna lokalna może uniemożliwić odczytanie wartości tych zmiennych
w momencie, gdy znajdzie się w zakresie ważności. Tylko zmienna globalna może zostać odsłonięta poprzez zastosowanie operatora zakresu.
::.
np. ::k;
Tablice
Tablice są zmiennymi mogącymi przechowywać zbiór elementów tego samego typu, elementy tablicy są numerowane począwszy od zera. Nazwa tablicy wskazuje na adres pierwszego jej elementu. Do elementu tablicy odwołujemy się przez indeks.
int t[5];
int x[3] = {5, 8, 10};
int y[] = {5, 8, 10};
int dd[3][2];
int dd[3][2] = {3, 4, 5, 6, 7, 8};
Struktura
Struktura składa się z elementów różnych typów. Elementy struktury nazywamy polami. Pola struktury istnieją tylko w jej obrębie.
struct nazwa
{
definicja pola_1;
...
definicja pola_n;
};
struct czlowiek
{
char nazwisko[25];
long wiek;
};
Deklaracja zmiennej:
struct czlowiek pracownik;
struct czlowiek pracownik = {”Kowalski”, 40};
Odwołanie do pola: pracownik.nazwisko
Operatory
Operatory arytmetyczne
Operator |
Działanie |
Postać matematyczna |
+ |
dodawanie |
z = x + y; |
- |
odejmowanie |
z = x - y; |
* |
mnożenie |
z = x * y; |
/ |
dzielenie |
z = x / y; |
% |
dzielenie modulo |
z = x % y; |
-- |
dekrementacja |
z = z - 1; |
++ |
inkrementacja |
z = z + 1; |
= |
przypisanie |
z = x ; |
+= |
skrót dodawania |
z += x z = z + x; |
-= |
skrót odejmowania |
z -= x z = z - x; |
*= |
skrót mnożenia |
z *= x z = z * x; |
/= |
skrót dzielenia |
z /= x z = z / x; |
Tab. 6.1 Operatory arytmetyczne
Operatory logiczne
Operator |
Działanie |
<, <=, >, >=, ==, != |
operatory relacji |
|| |
suma logiczna |
&& |
iloczyn logiczny |
! |
negacja |
Tab. 6.2 Operatory logiczne
Instrukcje sterujące
Rodzaje instrukcji sterujących:
instrukcje warunkowe (instrukcje wyboru): if oraz switch.
instrukcje iteracyjne (instrukcje pętli): for, while oraz do...while.
instrukcje skoku: break, continue, goto, return.
if
if (wyrażenie) instrukcja1; [else instrukcja2;]
if (wyrażenie)
{
ciąg instrukcji1
}
else
{
ciąg instrukcji2
}
Wyrażenie to pewien warunek, który ma zostać spełniony, bądź też nie. Kiedy wynikiem warunku jest prawda (w C++ wartość różna od zera), następuje wykonanie instrukcja1. Jeśli wynikiem jest fałsz zostanie wykonana (jeśli jest podana) instrukcja2. Wszystkie instrukcje należy zakończyć średnikiem, również w przypadku użycia "else".
Przykład:
Sprawdzenie parzystości liczby wprowadzonej z klawiatury:
#include <iostream.h>
#include <conio.h>
void main()
{
int liczba;
cout << "wprowadz liczbe \n"; cin >> liczba;
if (liczba % 2) cout << "liczba " <<liczba << " jest nieparzysta";
else cout << "liczba " <<liczba << " jest parzysta";
}
switch
switch (wyrażenie typu całkowitego) np: int, char, enum
{
case wartość1: instrukcja1;
case wartość2: instrukcja2;
[default : instrukcja3;]
}
switch( wyrażenie )
{
case wartość1:
lista instrukcji;
break;
case wartość2:
lista instrukcji;
break;
...
default:
lista instrukcji;
}
Przykład:
Prosty kalkulator rozpoznający rodzaj działania:
#include <iostream.h>
#include <conio.h>
void main()
{
char str;
float x, y;
cout << "wprowadz dwie liczby i znak operacji +,-,*,/ \n";
cin >> x >> y >> str;
switch (str)
{
case '+':
cout << (x+y); break;
case '-':
cout << (x-y); break;
case '*':
cout << (x*y); break;
case '/':
cout << (x/y); break;
default:
cout << " Nieprawidlowe dzialanie ";
}
cout << endl << "Nacisnij klawisz..."; getch();
}
for
for (wyrażenie inicjalizujące; warunek; inkrementacja) instrukcja;
Wyrażenie inicjalizujące deklaruje zmienne lokalne pętli oraz ustala ich początkowe wartości; ta sekcja wykonywana jest raz na początku działania pętli. Pętla trwa tak długo, jak długo spełniony jest warunek sprawdzany przed każdym rozpoczęciem pętli.
Inkrementacja to sekcja wykonywana po każdym przebiegu pętli (na przykład do zmiany licznika pętli). Pętle można dowolnie zagnieżdżać, a instrukcja może być złożona. Żadna z sekcji pętli for nie jest wymagana; dopuszczalna jest pętla nieskończona postaci for( ; ; ). Przerwanie wykonania może zapewnić zastosowanie instrukcji break.
Przykład:
Program wypisujący liczby całkowite z podanego przez użytkownika zakresu w jednej linii:
#include<iostream.h>
#include<conio.h>
void main()
{
int a,b,i;
cout << "Podaj dolna i gorna granice przedzialu (a,b)\n\n"; cout << "Podaj a = ";
cin >> a; cout << "Podaj b = "; cin >> b;
for (i=a;i<=b;i++)
{
cout << i << " ";
}
}
while
while (warunek) instrukcja;
While oznacza "dopóki". Instrukcja jest wykonywana tak długo, jak długo warunek jest prawdziwy (różny od zera).
Przykład:
Program reagujący na klawisz „n” lub „t”, symulując wyjście z programu.
#include <iostream>
#include <conio.h>
main()
{
char znak;
cout << "Nacisnji jakis klawisz\n";
znak = getch();
while ((znak != 't')&& (znak != 'n'))
{
cout << "Reaguje na 't' lub 'n'\n";
znak = getch();
}
}
do while
do
instrukcja
while (warunek);
do..while czyli "wykonuj...dopóki". Pętla jest podobna do pętli while. Różnica polega
na tym, że warunek jest sprawdzany na końcu pętli.
Przykład:
Program pozwalający na wyjście z programu:
#include<iostream.h>
#include<conio.h>
main()
{
char znak;
do
{
cout << "Czy chcesz zakonczyc proram t/n ";
znak = getch(); cout << endl;
}
while (znak == 'n');
}
break, continue, return i goto
Break (przerwij) - wywołanie tej instrukcji powoduje natychmiastowe opuszczenie pętli.
Continue (kontynuuj) - powoduje skok do wyrażenia warunkowego pętli while
lub do while lub zwiększenie indeksu pętli for.
Return (zwróć) - wywołanie tej instrukcji powoduje zakończenie wykonywania funkcji
i zwrócenie wartości podanej jako parametr do return.
Goto (skocz) - powoduje skok bezwzględny do etykiety podanej jako parametr. Etykiety deklarowane są w następujący sposób:
etykieta:
Funkcje
Funkcja to podprogram, który jako rezultat zwraca jakąś wartość. W funkcji można wyróżnić: nazwę, argumenty, blok instrukcji, zwracany wynik.
Funkcja wywoływana jest przez podanie jej nazwy uzupełnionej listą parametrów ujętych w nawiasy zwykłe. Lista parametrów z jakimi wywołuje się funkcję nazywa się listą parametrów aktualnych funkcji. Parametry funkcji wymienione w jej definicji nazywa się parametrami formalnymi. Lista parametrów aktualnych musi zgadzać się w ogólnym przypadku z listą parametrów formalnych, zarówno co do liczby jak i typu.
typ_wyniku nazwa_funkcji(parametry_funkcji)
{
deklaracje typów, zmiennych, stałych;
instrukcje;
return wynik;
}
Instrukcja return jest odpowiedzialna za podstawienie pod nazwę funkcji przekazywanego wyniku, musi ona wystąpić w każdej funkcji zwracającej jakąś wartość.
long potega(int stopien, long liczba)
{
long wynik;
wynik = liczba;
for (int i=1; i<stopien; i++)
{
wynik = wynik * liczba;
}
return wynik;
}
Możliwe jest napisanie funkcji, która nie zwraca żadnej wartości (void przed nazwą)
lub funkcji do której nie są przekazywane żadne parametry (zakończonej pustym nawiasem ()).
Jeżeli program składa się z jednego pliku to funkcja może być zadeklarowana i koniecznie powinna być zdefiniowana. W przypadku pominięcia deklaracji funkcji, wywołanie funkcji może nastąpić dopiero po jej zdefiniowaniu.
Zasięg ważności funkcji jest związany z miejscem jej zadeklarowania, czyli z miejscem umieszczenia jej nagłówka i tak umieszczona:
na początku pliku jest znana wewnątrz wszystkich funkcji w pliku
wewnątrz funkcji (jest dostępna tylko wewnątrz tej funkcji)
w pliku nagłówkowym jest znana we wszystkich plikach, do których dołączony został ten plik.
Ponieważ kompilator sprawdza jedynie zgodność typów parametrów formalnych
i aktualnych możemy deklarować funkcję na dwa sposoby:
z nazwami argumentów: long potega(int stopien, long liczba);
bez nazw argumentów: long potega(int , long);
Pierwszy sposób zwiększa czytelność kodu.
Przesyłanie argumentów do funkcji:
przez wartość - void t(int x);
przez referencję - void t(int &x);
W pierwszym przypadku, wartość parametru aktualnego kopiowana jest na stos (pamięć tymczasową) i dostępny jest on poprzez nazwę parametru formalnego funkcji. Po wykonaniu funkcji stos zostaje wyczyszczony, dzięki temu wartość oryginalna parametru aktualnego nie ulega zmianie.
W drugim przypadku do funkcji przekazany zostaje adres parametru aktualnego
i to na nim funkcja dokonuje zmian. W wypadku przekazania do funkcji tablicy przez referencje nie ma potrzeby stosowania & przed nazwą tablicy, gdyż nazwa tablicy przechowuje adres pierwszego elementu.
Argumenty domniemane
float temp(float stopnie, int skala = 0); deklaracja funkcji
...
float temp(float stopnie, int skala) definicja funkcji
{ ...}
w = temp(100.5); //wywołanie funkcji
Parametry domniemane funkcji muszą znaleźć się zawsze na końcu funkcji i mieć przypisaną wartość.
Przeciążanie funkcji
W jednym programie może wystąpić kilka funkcji o tych samych nazwach, muszą się jednak one różnić liczbą bądź typem parametrów.
double dodaj (double a, double b)
{ return a+b;}
int dodaj (int a, int b)
{ return a+b;}
double dodaj (double a, double b, double c)
{ return a+b+c;}
Definiowanie wskaźników
int *w;
w - jest wskaźnikiem wskazującym na obiekt typu int to znaczy, że w może przechowywać adres jakiegoś obiektu typu int.
int *w; int zm = 23; w = &zm;
W powyższym przykładzie zmienna wskaźnikowa w pokazuje na zmienną zm ,
czyli *w i zm znajdują się pod tym samym adresem, a więc mają tę samą wartość.
Obszary zastosowań wskaźników:
praca z tablicami;
praca z funkcjami;
dostęp do specjalnych komórek pamięci;
rezerwacja obszarów pamięci.
Wskaźniki - praca z tablicami
int *w;
char tab[3] = {'a','b','c','d'};
w = &tab[0]; cout << *w; // wyświetla 'a'
w = &tab[1]; cout << *w; //wyświetla 'b'
w = w + 2; cout << *w; //wyświetla 'd'
*w='f'; cout << *w; //wyświetla 'f'
Dodanie do wskaźnika liczby całkowitej n powoduje, że wskazuje on na element tablicy leżący o n pozycji dalej niż przed tą operacją. Jest to niezależne od typu elementów tablicy.
Wskaźniki - praca z funkcjami
void funkcja(int *wformalna);
funkcja(&waktualna); cout
Dzięki takiej deklaracji i wywołaniu funkcji, funkcja może zmieniać wartość obiektu
na który ustawiony jest wskaźnik.
Wskaźniki - praca z komórkami pamięci
long *w; w = adres; //adres - adres komórki pamięci
Zastosowanie wskaźnika pozwala na odczyt zawartości komórki o znanym adresie wykorzystywanym np. do przekazywania wartości mierzonej przez urządzenie pomiarowe.
Wskaźniki - rezerwowanie obszarów pamięci
int *wi; wi = new int; cout << *wi; //zawiera przypadkową wartość zastaną pod przydzielonym operatorem new adresem pamięci
*wi=15; cout << *wi; // wyświetli 15
delete wi; // zwalnia miejsce w pamięci
new - operator tworzący obiekt; delete - operator likwidujący obiekt;
Cechy obiektów utworzonych operatorem new:
nie mają nazwy - można na nich operować tylko za pomocą wskaźników;
istnieją od momentu utworzenia operatorem new do momentu skasowania operatorem delete;
są dostępne w całym programie;
aby zlikwidować przypadkową wartość po przydzieleniu zmiennej adresu, należy pamiętać o nadaniu jej wartości.
Tablice znakowe
Do przechowywania znaków (np. liter) stosuje się specjalny rodzaj tablic tzw. tablice znakowe.
char tekst[80] ;
Zdefiniowana powyżej zmienna jest tablicą 80 elementów będących znakami. Tablica ta może przechować do 79 znaków oraz zero (NULL) oznaczające koniec tablicy. Ciąg liter zakończony znakiem NULL nazywamy stringiem. Inicjowanie zmiennej możliwe jest
w momencie jej definiowania (tekst inicjujący musi być ujęty w cudzysłów):
char tekst[80] = {"lancuch tekstowy"} ;
char tekst[80] = "lancuch tekstowy" ;
Taka inicjalizacja powoduje wypełnienie tablicy kolejnymi znakami i zerowanie pozostałych jej elementów. Pamiętać należy, że w C++ możliwe jest wpisanie elementu poza obszar tablicy, jeżeli podamy indeks tablicy spoza jej zakresu. Taka operacja nie spowoduje wykrycia błędu przez kompilator. Dopuszczalna długość łańcucha zależna jest od rodzaju kompilatora i najczęściej ogranicza się do 65536 znaków.
char zdanie[80] = { 'i', 'm', 'i' , 'e' };
Możliwe jest zainicjowanie tablicy znakowej pojedynczymi znakami w przypadku,
gdy rozmiar tablicy jest określony a deklaracja jest zbiorcza (znaki w klamrze {}), w takim wypadku pozostałe elementy tablicy zostaną wyzerowane.
Inicjowanie tablicy poprzez przepisanie elementów z jednej tablicy do drugiej:
void strcpy(char cel [ ] , char zrodlo[])
}
int i = 0;
do
{
cel [i] = źródło [i];
}
while(cel [i++] != NULL) ;
}
Podobne funkcje operujące na łańcuchach znajdują się w bibliotece dołączanej plikiem nagłówkowym string.h np:
strcat(napis1, napis2) - sklejanie łańcuchów.
strlen(napis1) - długość łańcucha znakowego.
strcpy(napis1, napis2) - kopiuje string.
strncpy(napis1, napis2,n) - kopiuje zadaną początkową liczbę znaków łańcucha.
strstr(napis1, napis2) - wyszukuje pierwsze wystąpienie danego tekstu. Funkcja strstr zwraca wskaźnik do szukanego tekstu.
Klasy
Klasa posiada zmienne tzw. pola oraz funkcje zwane metodami które operują na polach. Metoda, jest to prawie to samo co funkcja, z tym, że ma do dyspozycji pola klasy. Metody można przeciążać.
Definicja klasy
class tklasa
{
public:
int x; // pole typu integer
double y; // pole typu double
void metoda();
};
Definicja metody
void NAZWA::metoda()
{
x+=y;
}
Wykorzystanie klasy
void main()
{
tklasa klasa; klasa.x=3; klasa.y=3.13;
klasa.metoda(); cout<<klasa.y;
}
Konstruktor i destruktor
Konstruktor klasy jest to specjalna metoda, która jest wywoływana zawsze, gdy klasa jest inicjowana.
Konstruktor i destruktor nie zwraca żadnej wartości. Nazwa konstruktora jest dokładnie taka sama jak nazwa klasy, nazwa destruktora jest nazwą klasy poprzedzoną znakiem ~.
Destruktor jest wywoływany, gdy klasa nie będzie więcej używana.
Są trzy stopnie ochrony klasy:
public, protected, private.
Stopień private ma największy zakres ochrony. Można do danych i metod chronionych tym stopniem odwoływać się tylko poprzez inne metody tej klasy, w której te dane zostały zdefiniowane. Nie mogą z tych danych korzystać klasy pochodne.
Stopień ochrony protected jest mniej rygorystyczny, klasy pochodne mogą już korzystać
z pól i metod klasy bazowej.
Stopień ochrony public w ogóle nie ogranicza dostępu do danych.
Dziedziczenie klas
Przykład:
Konstruujemy klasę, która oblicza pole figur geometrycznych.
Klasa bazowa:
class TPolePowierzchni
{
public:
double pole;
};
class TKolo: public TPolePowierzchni
{
public:
double promien;
void pole_powierzchni();
};
Klasy pochodne będą miały pola i metody klasy bazowej oraz te, które dodamy dodatkowo.
class TTrojkat: public TPolePowierzchni
{
public:
double a,h;
void pole_powierzchni();
};
Klasy można dziedziczyć wielokrotnie, tzn., klasa pochodna może być klasą bazową dla innej klasy.
Metody klas pochodnych
void TKolo::pole_powierzchni()
{
pole=3.1415*promien*promien;
}
void TTrojkat::pole_powierzchni()
{
pole=0.5*a*h;
}
void main()
{
TTrojkat trojkat;
TKolo kolo;
trojkat.a=4.0;
trojkat.h=2.0;
kolo.promien=4.0;
kolo.pole_powierzchni();
trojkat.pole_powierzchni();
cout <<"Pole powierzchnii kola: "<<kolo.pole<<endl;
cout <<"Pole powierzchnii trojkata: "<<trojkat.pole<<endl;
}
Każda klasa bazowa musi być zdefiniowana przed definicją klasy pochodnej. Klasę bazową można deklarować jako publiczną, chronioną lub prywatną. Pola i metody dostępne
w klasie bazowej będą z takim atrybutem w klasie pochodnej.
Literatura:
A. Kisielewicz: Wprowadzenie do informatyki, Helion 2002
K. Masłowski: Darmowe oprogramowanie w codziennym życiu, Helion 2009
K. Sayood: Kompresja danych - wprowadzenie, READ ME 2002
A. Przelaskowski: Kompresja danych: Podstawy, Metody bezstratne, Kodery obrazów, BTC, Warszawa 2005
W. Stallings: Systemy operacyjne struktura i zasady budowy, PWN 2010
A. S. Tanenbaum: Strukturalna organizacja systemów komputerowych, Helion 2006
J. Grębosz: Symfonia C++, Oficyna Kallimach, Kraków 1999
J. Grębosz: Pasja C++, Oficyna Kallimach, Kraków 1999
Pliki pomocy dołączone do C++ Builder 3.0 wersja standard
Dowolny podręcznik z opisem języka C++
Dowolny podręcznik z opisem środowiska C++ Builder w wersji 3 (ewentualnie nowszej)
Serwisy internetowe dotyczące C++
Konspekt jest współfinansowany przez Unię Europejską
w ramach Europejskiego Funduszu Społecznego
w projekcie:
"Innowacyjna dydaktyka bez ograniczeń
- zintegrowany rozwój Politechniki Łódzkiej zarządzanie Uczelnią,
nowoczesna oferta edukacyjna
i wzmacniania zdolności do zatrudniania,
także osób niepełnosprawnych".
2