Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej...

155
Vademecum informatyki praktycznej (aktualizacja: 2021-07-27) W założeniu ma to być kompleksowy przegląd podstawowych zagadnień z zakresu elektroniki, programowania oraz użytkowania i administracji systemami unixowymi. Nie jest to tutorial, ani samouczek prowadzący krok po kroku w zgłębianie tajników "komputerologii", natomiast tekst ten może być wykorzystywany jako materiał pomocniczy do zająć o takiej tematyce, bądź też materiał służący przypomnieniu / uzupełnieniu posiadanej wiedzy na przedstawiane tematy. Korzystanie z tego dokumentu przy samodzielnej nauce jest także możliwe, należy jednak liczyć się z tym że konieczne może być sięganie do innych, bardziej szczegółowych źródeł, a co najważniejsze także duża ilość praktyki i prób samodzielnego rozwiązywania problemów - samo przeczytanie nie wystarczy. Założeniem tego dokumentu było że ma być kompletny i zamknięty, jednym z efektów tego jest unikanie odsyłania do innych materiałów bezpośrednio w tekście, wszystkie odnośniki do zewnętrznych źródeł (za wyjątkiem powoływania się na dokumentację narzędzi/bibliotek) znajdują się wyłącznie w dziale "Literatura". Założeniem tego dokumentu było także że ma być w miarę uniwersalny i ponadczasowy (nie zdezaktualizować się po roku) dlatego też skupia się na bardziej uniwersalnych aspektach omawianych zagadnień, faktach, definicjach, itp bez odniesień w stylu "obecnie już", "nadal jest używany", itd, nie pokazuje też różnego rodzaju sztuczek czy obejść doraźnych problemów, ani nie omawia szczegółów technologii szybko zmieniających się. Elektronika Elektronika zajmuje się wytwarzaniem i przetwarzaniem sygnałów w postaci prądów i napięć elektrycznych. Zjawisko prądu związane jest z przepływem ładunku (z uporządkowanym ruchem nośników ładunku), aby wystąpiło konieczna jest różnica potencjałów (napięcie) pomiędzy końcami przewodnika, prowadzi ono do neutralizacji tej różnicy. Dlatego dla podtrzymania stałej różnicy potencjałów konieczne jest istnienie źródeł prądu, prowadzących do rozdzielania ładunków dodatnich od ujemnych. Podstawy Napięcie i prąd Dla elementów liniowych (np. zwykły kawałek przewodu) zachodzi proporcjonalność natężenia prądu płynącego przez taki element do napięcia pomiędzy jego końcami: R = U I . Natężenie prądu elektrycznego I (określane skrótowo jako prąd) jest to stosunek przemieszczonego ładunku do czasu jego przepływu. Napięcie elektryczne U pomiędzy punktem A i B (jakiegoś obwodu) jest to różnica potencjału elektrycznego w punkcie A i w punkcie B. Potencjał elektryczny V w punkcie A jest skalarną wielkością charakteryzującą pole elektryczne w danym punkcie. Odpowiada pracy którą trzeba by wykonać aby przenieść ładunek q z tego punktu do nieskończoności podzielonej przez wielkość tego ładunku (jest niezależny od wartości q ). W elektronice używa się wartości potencjałów względem umownego potencjału zerowego GND (co umożliwia traktowanie ich jako różnic potencjałów - napięć elektrycznych), w efekcie tego określenia "(stałe) napięcie" i "potencjał" bardzo często stosowane są zamiennie. Masa, GND umowny potencjał zerowy, względem którego wyraża się inne potencjały w układzie (co umożliwia traktowanie ich jako różnic potencjałów - napięć elektrycznych). Potencjał ten może być równy potencjałowi ziemi (masie ochronnej PE), bądź może być z nim nie związany (układy izolowane). Podstawowym przykładem teoretycznych (w rzeczywistości mogą występować tylko elementy realizujące ich funkcję w pewnym zakresie i w pewnym przybliżeniu) elementów nieliniowych są: Idealne źródło prądowe wymusza przepływ określonego prądu przez przyłączony układ, niezależnie od spadków napięć w układzie (czyli może odłożyć się na nim dowolne napięcie). Idealne źródło napięciowe wymusza określoną różnicę potencjałów pomiędzy swoimi zaciskami (czyli może przez nie przepływać dowolne natężenie prądu). Węzeł układu (sam w sobie, pomijając zjawiska pasożytnicze) nie jest w stanie gromadzić ładunku elektrycznego zatem: Suma prądów wpływających do węzła jest równa sumie prądów wypływających z tego węzła. Jeżeli rozważamy obwód zamknięty od punktu A z potencjałem V A to sumując napięcia na kolejnych elementach obwodu (oporach, źródłach napięciowych, etc) z uwzględnieniem ich znaku gdy wrócimy

Transcript of Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej...

Page 1: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

Vademecuminformatykipraktycznej(aktualizacja:2021-07-27)

W założeniu ma to być kompleksowy przegląd podstawowych zagadnień z zakresu elektroniki,programowania oraz użytkowania i administracji systemami unixowymi. Nie jest to tutorial, anisamouczekprowadzącykrokpokrokuwzgłębianietajników"komputerologii",natomiastteksttenmożebyć wykorzystywany jako materiał pomocniczy do zająć o takiej tematyce, bądź też materiał służącyprzypomnieniu/uzupełnieniuposiadanejwiedzynaprzedstawianetematy.Korzystanieztegodokumentuprzysamodzielnejnaucejesttakżemożliwe,należyjednakliczyćsięztymżekoniecznemożebyćsięganiedo innych, bardziej szczegółowych źródeł, a co najważniejsze także duża ilość praktyki i próbsamodzielnegorozwiązywaniaproblemów-samoprzeczytanieniewystarczy.

Założeniemtegodokumentubyłożemabyćkompletnyizamknięty,jednymzefektówtegojestunikanieodsyłaniadoinnychmateriałówbezpośredniowtekście,wszystkieodnośnikidozewnętrznychźródeł(zawyjątkiem powoływania się na dokumentację narzędzi/bibliotek) znajdują się wyłącznie w dziale"Literatura".Założeniemtegodokumentubyłotakżeżemabyćwmiaręuniwersalnyiponadczasowy(niezdezaktualizować się po roku) dlatego też skupia się na bardziej uniwersalnych aspektach omawianychzagadnień, faktach, definicjach, itp bez odniesień w stylu "obecnie już", "nadal jest używany", itd, niepokazuje też różnego rodzaju sztuczek czy obejść doraźnych problemów, ani nie omawia szczegółówtechnologiiszybkozmieniającychsię.

ElektronikaElektronika zajmuje się wytwarzaniem i przetwarzaniem sygnałów w postaci prądów i napięćelektrycznych.Zjawiskoprąduzwiązanejestzprzepływemładunku(zuporządkowanymruchemnośnikówładunku), aby wystąpiło konieczna jest różnica potencjałów (napięcie) pomiędzy końcami przewodnika,prowadzionodoneutralizacjitejróżnicy.Dlategodlapodtrzymaniastałejróżnicypotencjałówkoniecznejestistnienieźródełprądu,prowadzącychdorozdzielaniaładunkówdodatnichodujemnych.

PodstawyNapięcieiprąd

Dlaelementów liniowych (np. zwykłykawałekprzewodu)zachodziproporcjonalnośćnatężeniaprądupłynącegoprzeztakielementdonapięciapomiędzyjegokońcami:R = UI .

NatężenieprąduelektrycznegoII (określaneskrótowojakoprąd)jesttostosunekprzemieszczonegoładunkudoczasujegoprzepływu.

NapięcieelektryczneUU pomiędzypunktemAiB(jakiegośobwodu)jesttoróżnicapotencjałuelektrycznegowpunkcieAiwpunkcieB.

PotencjałelektrycznyVV wpunkcieAjest skalarną wielkością charakteryzującą pole elektryczne w danym punkcie. Odpowiada pracyktórą trzebabywykonaćabyprzenieść ładunek q z tegopunktudonieskończoności podzielonejprzezwielkośćtegoładunku(jestniezależnyodwartościq ).WelektroniceużywasięwartościpotencjałówwzględemumownegopotencjałuzerowegoGND(coumożliwia traktowanie ich jako różnic potencjałów - napięć elektrycznych), w efekcie tegookreślenia"(stałe)napięcie"i"potencjał"bardzoczęstostosowanesązamiennie.

Masa,GNDumownypotencjałzerowy,względemktóregowyrażasięinnepotencjaływukładzie(coumożliwiatraktowanie ich jako różnic potencjałów - napięć elektrycznych). Potencjał ten może być równypotencjałowiziemi(masieochronnejPE),bądźmożebyćznimniezwiązany(układyizolowane).

Podstawowym przykładem teoretycznych (w rzeczywistości mogą występować tylko elementyrealizująceichfunkcjęwpewnymzakresieiwpewnymprzybliżeniu)elementównieliniowychsą:Idealneźródłoprądowe

wymuszaprzepływokreślonegoprąduprzezprzyłączonyukład,niezależnieodspadkównapięćwukładzie(czylimożeodłożyćsięnanimdowolnenapięcie).

Idealneźródłonapięciowewymusza określoną różnicę potencjałów pomiędzy swoimi zaciskami (czyli może przez nieprzepływaćdowolnenatężenieprądu).

Węzeł układu (sam w sobie, pomijając zjawiska pasożytnicze) nie jest w stanie gromadzić ładunkuelektrycznegozatem:Sumaprądówwpływającychdowęzłajestrównasumieprądówwypływającychztegowęzła.

Jeżeli rozważamyobwódzamkniętyodpunktuAzpotencjałemVA to sumującnapięcianakolejnychelementachobwodu (oporach, źródłachnapięciowych,etc) zuwzględnieniem ichznakugdywrócimy

Page 2: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

do punktu A to potencjał nadal musi wynosić VA , zatem: Suma spadków napięć w zamkniętymobwodziejestrównazeru.

Opór,pojemnośćiindukcyjnośćPojęcia

Rezystancja(opórelektryczny)wyraża trudność przepływu prądu przez dany przewodnik - im większy opór elementu to (przytakimsamymprzyłożonymnapięciu)będziepłynąłmniejszyprąd.R = UI

Pojemność(wzajemna)wyrażazdolnośćdogromadzeniaładunkuprzezdanyelement-imwiększapojemnośćtymwięcejładunku(przytakimsamymprzyłożonymnapięciu)zgromadzielement.C = qU

Indukcyjnośćwyrażazdolnośćdowytwarzaniastrumieniapolamagnetycznegozwiązanegozprzepływemprąduprzezdanyelement.L = IΦ

Obwodyprądustałegoazmiennego

Pojemność oraz indukcyjność wprowadzona do obwodu ma znaczenie tylko gdy zachodzi zmiananatężaniaprądupłynącegoprzezobwód/zmianawartościnapięćodłożonychnajegoelementach.Wstanieustalonymobwoduprądustałegowprowadzonadoobwodupojemnośćoraz indukcyjnośćnieodgrywająroli,gdyż:

pojemności zgromadziły już (stosowny do przyłożonego do nich napięcia) ładunek i niepobierająprąduzobwodu,indukcyjnościwytworzyłypolemagnetyczne(stosownedoprzepływającegoprzeznieprądu) iniestanowiąoporudlapłynącegoprąduwobwodzie.

Wtakimprzypadkumożnatraktowaćpojemnościjakorozwarcia,aindukcyjnościjakozwarcia.

Impedancjajest wielkością charakteryzującą zależność pomiędzy natężeniem prądu i napięciemuwzględniającąreaktancjęobwodu.Z = R + jX

Reaktancjajest wielkością charakteryzującą opór bierny elementów pojemnościowych (kapacytancjaXC = − 1

ωC )iindukcyjnych(induktancjaXL = ωL ).

Pulsacjaωωcharakteryzuje szybkość zmian (jest proporcjonalna do odwrotności czasu trwania okresuzmiany).ω = 2πT

Elementyrzeczywiste

Rezystor(opornik)wprowadza do układu rezystancję związaną z swoją wartością nominalną. Typowo służy doograniczaniawartościprąduprzezniegoprzepływającego.Symbole: , .Powodujewydzielaniesięenergii(cieplnej)związanejzstrataminarezystancji-mocwydzielanadanajestzależnościami:P = UI = U

2

R = I2R ,czyliprzystałymnapięciuprzyłożonymdorezystoraim większy jego opór tym mniejsza moc się wydzieli (gdyż popłynie mniejszy prąd), ale przystałymprądziepłynącymprzezrezystormocrośniewrazzewzrostemoporu.

Kondensatorwprowadza do układu pojemność związaną z swoją wartością nominalną. Typowo służy doograniczaniazmiannapięcia(poprzezgromadzenieenergiiwpoluelektrycznym).Symbole: ,

.Czaspotrzebnydozmianynapięcianakondensatorzedanyjestzależnością:ΔT = C ⋅ ΔUICewka(dławik)

wprowadza do układu indukcyjność związaną z swoją wartością nominalną. Typowo służy doograniczaniazmianprądu(poprzezgromadzenieenergiiwpolumagnetycznym).Symbol: .Czaspotrzebnyzmianyprądupłynącegoprzezcewkę(dławikstawiaopórtakiejzmianietakjakkondensatorzmianienapięcia)danyjestzależnością:ΔT = L ⋅ ΔIU .Częstocewkanawinięta jestnardzeń ferrytowy,bardzosilniezwiększaon indukcyjnośćcewki,aleograniczaodgóryczęstotliwośćpracycewki.Ponadtoprzyodpowiedniodużymprądziemożedochodzić do nasycenia rdzenia, które objawia się tym, że zaczyna in hamować wzrost polazamiastgopoprawiać.Cewkanawiniętanaodpowiednimrdzeniumożestanowićelektromagnes.

Transformator

Page 3: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

Układ cewek sprzężonych magnetycznie, z których część służy do wytwarzania energii polamagnetycznego,aczęśćdo jejodbierania.Typowosłużydoprzekazywaniaenergiipoprzezpolemagnetycznymcelemzmianynapięcialubseparacjigalwanicznejobwodów.W przypadku dwu uzwojeniowego transformatora zachodzi:

UweUwy

=IwyIwe

= nwenwy = z , gdzie z to

przekładniatransformatora,nwe toliczbauzwojeństronypierwotnej(wejściowej),anwy toliczbauzwojeństronywtórnej(wyjściowej).

Stykjesttoelementsłużącydomechanicznegozałączanialubodłączaniaprądu,nazywanybywatakżeprzełącznikiem. Wyróżnia się styki monostabilne (chwilowe), które samoistnie (po ustaniuczynnika przełączającego) wracają do jednej ze swoich pozycji oraz styki bistabilne, które poprzełączeniu pozostają w wybranej pozycji. Wyróżnia się także styki zwierne (normalnierozwarte),rozwierne(normalniezwarte)lubprzełączne(następujeprzełączaniepomiędzydwomalubwięcejmożliwymiwyjściami).Czynnikiemodpowiedzialnymzaprzełączaniestykówmożebyćmanualne działanie (przełącznik naciskany, przekręcany, pociąganym, itd przez człowieka) lubdziałanieelektromagnesu(cewki)-jesttowtedyprzekaźnikelektromagnetycznylubstycznik.Stanzwarciaokreślasięczęstomianem"zamknięty"(ang."close"),arozwarciamianem"otwarty"("open").Należy(zwłaszczawsystemachcyfrowych)pamiętać,żestykipotrafiądrgać -naogółprzyzmianiepozycjizamiastpojedynczegoimpulsugenerującałąserię.

Elementy rzeczywiste oprócz wartości nominalnej (wprowadzanej przez nie rezystancji, pojemnościlubindukcyjności)charakteryzujątakże:

wartościgraniczne(takiejakmaksymalnamocktóramożewydzielićsięnarezystorze,napięcieprzebiciakondensatora,maksymalnyprądprzewodzeniacewki, temperaturowyzakrespracy,...),impedancje pasożytnicze (każdy element rzeczywisty wprowadza zarówno niepożądanąrezystancję,jakiniepożądanąreaktancjęniezwiązanązjegowartościąnominalną).

W większości przypadków impedancję pasożytniczą można pominąć. Jednak np. w przypadkurzeczywistych źródeł napięciowych i prądowych rezystancja wewnętrzna takiego źródła częstoodgrywaistotnąrolędladziałaniaukładuiniemożezostaćpominięta.

Układypołączeń

Połączenieszeregowejesttotakiepołączenieelementówżeprzepływaprzeznie jednakowyprąd.Impedancje(zarównorezystancyjnejakireaktancyjne)takpołączonychelementówsumująsię.

~ Z1 Z2

Połączenierównoległe

jesttotakiepołączenieelementówżeprzyłożonedonichnapięciasąjednakowe(aprądpłynącywobwodzie ulega rozdzieleniu). Odwrotność impedancji takiego układu jest sumą odwrotnościimpedancjitakpołączonychelementów.

~ Z1 Z2

Dzielniknapięcia(rezystancyjny)

jest to szeregowepołączeniedwóch rezystorów.Poprzezdobórwartości rezystorówuzyskuje siępożądanenapięcienawyjściu takiegodzielnika,któredane jest zależnościąUwy = Uwe

R2R1+R2

.Ze

względu na to iż jest ono proporcjonalne do napięcia przyłożonego do całego dzielnika może onsłużyćtakżedoskalowanianapięciowegosygnałuwejściowego.Abyminimalizowaćwpływwartościimpedancjipodłączonejdowyjściadzielnikananapięciewyjściowenależyzapewnićodpowiedniomałewartości rezystorówwdzielniku - takabyprądpłynącyprzezR2byłzdecydowaniewiększy(typowo5do10razy)odprądupłynącegoprzezobciążenie(RL ).

Uwe

R1

R2

Uw

y RL

Dzielnikprądu(rezystancyjny)jest torównoległepołączeniedwóchrezystorów.Poprzezdobórwartości rezystorówuzyskujesiępożądanenatężenieprąduwwyjściowejgałęzi.

Z = Z1+ Z2

Z = Z1| |Z2⟺1Z =

1Z1+ 1Z2

⟺Z = 11Z1+ 1Z2

Page 4: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

dioda

LED

diodaZenera

A K

A K

A K A K

B

C

E NPN

Rb

Rload

Vzasilania

Vster

Rb

Rload

Vzasilania

Vster

B

C

E

PNP

ObwódRCjest to szeregowe połączenie rezystora i kondensatora. Obwód taki charakteryzuje się stałączasową τ = RC . Napięcie na kondensatorze w trakcie jego ładowania dane jest zależnością

UC t = Uwe ⋅ 1 − e−tτ , a w trakcie rozładowywania UC t = UC 0 ⋅ e−

tτ . W przypadku

wyjścianazaciskachrezystorastanowifiltrgórnoprzepustowy,awprzypadkuwyjścianazaciskachkondensatora stanowi filtr dolnoprzepustowy, częstotliwość graniczna (zapewniająca tłumieniewiększeniż3dB)takichfiltrówwynosifgr = 1

2πτ .

Dioda

Diodaidealnatoelementprzewodzącyprądtylkowjednymkierunku.Rzeczywiste diody przewodzą prąd zdecydowanie chętniej w jednymkierunkuniżwdrugim(naogółprzewodzeniewkierunkuzaporowymsię pomija) ponadto charakteryzują je cechy zależne od technologiwykonaniatakiejak:

spadek napięcia w kierunku przewodzenia (typowo dla diodkrzemowych0.6V-0.7V,adladiodSchottky’ego0.3V)napięcie przebicia - napięcie, które przyłożone w kierunku zaporowym powoduje znacząceprzewodzenie diody w tym kierunku - w większości przypadków parametr którego nie należyprzekraczać,jednakwykorzystywane(istanowiąceichparametr)wniektórychtypachdiodmaksymalnyprądprzewodzeniaczasprzełączania(związanygłówniezpasożytnicząpojemnościązłącza)-zdecydowaniekrótszy(około100ps)wdiodachSchottky’egoniżwdiodachkrzemowych,.

Ponadtostosowanesąm.in.:diodyZenera-wykorzystujesię(charakterystycznądladanegotypu)wartośćnapięciaprzebiciadouzyskaniawukładziespadkunapięciaotejwartości,diodyświecące(LED)-emitująceświatłowtrakcieprzewodzenia(naelemenciewystępujestałyspadeknapięcia,jasnośćzależyodnatężeniaprądu),fotodiody - będące detektorami oświetlenia (przewodzenie spolaryzowanej w kierunkuzaporowym zależy od ilości padającego na element światła, niespolaryzowana pod wpływemoświetleniastajesięźródłemprądu).

TranzystorTranzystor jest to element o regulowanym elektrycznie przewodzeniu prądu (oporze), częstowykorzystywanydowzmacnianiasygnałówlubjakoprzełącznikelektroniczny.

NPN,PNP,JFET,MOSFET,...

NPNPrąd przepływający pomiędzy kolektorem aemiterem jest funkcją prądu przepływającegopomiędzy bazą a emiterem: IC = βIB . Napięciepomiędzy kolektorem a emiterem wynosi:UCE = Uzasi lania − IC ⋅ Rload . Napięcie to nie możejednakspaśćponiżejwartościminimalnejwynoszącejokoło 0.2V, gdy z powyższych zależności wynikałbytaki spadek to tranzystor pracuje w stanemnasyceniaiUCE ≈ 0.2V .

PNPPodobnie jak w NPE tyle że prąd przepływający pomiędzy emiterem a kolektorem jest funkcjąprąduprzepływającegopomiędzyemiteremabazą.

SpadeknapięciapomiędzybaząaemiteremUBE wtranzystorzeNPN(międzyemiteremabaząwPNP)wynosi nie więcej niż około 0.7V. Utrzymanie takiej wartości spadku napięcia podowduje powstanieokreślonegoprądubazy.Jeżelispadektenwynosidużomniej(np.zero),toprądbazyniepłynie,awięctranzystornieprzewodzi.

ZatemwukładzieprzedstawionymobokzmianaVster spowodujetakązmianęprądubazy IB abynaRbodłożyłosięnapięcieVster − 0.7V .Z tegoteżwzględukonieczne jeststosowanierezystancjipomiędzybaząanapięciamisterującymiinnymiodnapięciaemitera.

N-JFETPrąd przepływający pomiędzy drenem (drain) a źródłem (source) jest funkcją napięcia pomiędzybramką(gate)aźródłem(potencjałubramkiwzględemźródła-UGS ),prądbramkimożnauznaćzapomijanie mały. Tranzystor ten przewodzi tylko gdy napięcie pomiędzy bramką a źródłem jest

Page 5: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

Rload

Vzasilania

Vster(<=0)

RloadVzasilania

Vster(>=Vzasilania)

G

D

S

N−JFET

G

D

S P−JFET

RloadVzasilania

Vster

Rload

Vzasilania

Vster

G

D

S

N−MOSFETenhancement

G

D

S

P−MOSFETenhancement

G

D

S

N−MOSFETdepletion

G

D

S

P−MOSFETdepletion

większe od napięcia odcięcia (UGSoff < 0), przewodzonyprąd wzrasta wraz ze wzrostem UGS , a maksimum jestosiąganedlaUGS = 0.

Gdy tranzystor jest spolaryzowany tak aby UDS > 0 orazUGS > UGSoff towzależnościodwartości spadkunapięciana tranzystorze UDS oraz wartości napięcia nasyceniaUsat = UGS −UGSoff wyróżniasiędwatrybypracy:

1. liniowy(gdyUDS > Usat ),wktórymID = β ⋅ Usat22. nasycenia (gdy UDS ≤ Usat ), w którymID = β ⋅ UGS ⋅ 2Usat −UDS

gdzieβ = IDSSUGSoff

2

P-JFETPodobnie jak N-JFET tyle że: prąd przepływa pomiędzy źródłem a drenem, przewodzony prądwzrastawrazzezmniejszaniemUGS (odUGSoff > 0dozera).

N-MOSFETPrądprzepływającypomiędzydrenem(drain) a źródłem (source) jestfunkcją napięcia pomiędzy bramką(gate) a źródłem (potencjału bramkiwzględemźródła -UGS ),bramka jestizolowana(niepłynieprzezniąprąd).

Wkierunkudren→źródłotranzystorten przewodzi gdy UGS > UGS( th) ,natomiast w przeciwnym kierunkuprzewodzi zawsze. Dla tranzystorówN-MOSFET z kanałem wzbogacanym(enhancement)UGS( th) > 0,azkanałemzubożonym(depletion)UGS( th) < 0.

Konkretna wartość UGS( th) zależna jest od konkretnego modelu tranzystora, innym istotnymparametrem związanym z sterowaniem tranzystorem jest maksymalna i minimalna dopuszczalnawartośćnapięciaUGS .

P-MOSFETPodobniejakN-MOSFETtyleże:

1. regulowane jest przewodzenie w kierunku źródło → dren (a w kierunku dren → źródłoprzewodzizawsze),

2. przewodzeniewkierunkuźródło→drenmamiejscegdyUGS < UGS( th) ,

3. dla tranzystorów z kanałem wzbogacanym (enhancement) UGS( th) < 0, a z kanałemzubożonym(depletion)UGS( th) > 0.

Przykłady:BC846(NPN,65V,0.1A),BC337(NPN,50V,0.8A),BD139(NPN,80V,1.5A);BC327(PNP,50V,0.8A),BD140(PNP,80V,1.5A);BS170(N-MOSFET,60V,5Ohm,0.5A),IRF540N(N-MOSFET,100V,44mOhm,33A),IRFZ44N(N-MOSFET,55V,17.5mOhm, 49A); IRF9Z34N (P-MOSFET, 55V, 100mOhm, 19A), IRF5210 (P-MOSFET, 100V, 60mOhm, 40A), IRF5305 (P-MOSFET,55V,60mOhm,31A);BF245(N-JFET)iwieleinnych

(inne)elementymocy

Tyrystor

Jestelementemprzewodzącymwyłączniew jednymkierunku (odanodydokatody).Przewodzeniemusizostaćzainicjowanepodaniem(dodatniegowzględemkatody)napięcianabramkę.Wyzwolony(raz przyłożonym napięciem bramki) tyrystor przewodzi do momentu spadku prądu poniżejminimalnejwartościprzewodzenialubwystąpieniaodwrotnejpolaryzacji.Zasadędziałaniatyrystoraobrazujeprzedstawionyobokdwu-tranzystorowymodel.

Triak

Jestelementemodwukierunkowymprzewodzeniuinicjowanymimpulsemnapięciowympodanymnabramkę. Zasadę jego działania obrazuje schemat zastępczy złożony z dwóch połączonych anty-równolegletyrystorów.Używanyjestjakoelektronicznyprzełącznikprąduprzemiennego.

Przykłady:BTA16

Page 6: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

G

A

K G

A

KTYRYSTOR

<=>G

A2

A1

G<=>

A2

A2TRIAK

C

E

G

IGBT

G

C

E

<=>

TranzystorIGBT

Jest to tranzystor bipolarny z izolowanąbramką. Z punktu sterowania należy patrzećna niego jak na tranzystor typu N-MOSFET.Stosowany do przełączania w układach dużejmocy.

transoptory

Poprzezpołączeniewjednejobudowiediodyświecącejzfototranzystorem,fotodiodą(niekiedywrazztranzystoremdobramkiktóregojestpodłączona), fototriakiemlubpodobnymelementem(toznaczytakim którego przewodność zależy od padającego na niego oświetlenia) uzyskuje się elementnazywany transoptorem. W układzie może być zawarty także dodatkowy stopień wyjściowydostosowującynapięciadopoziomówwymaganychprzezjakiśstandard.

Transoptor zapewniaon izolację (typowo rzędu tysięcywoltów)galwanicznądwóchczęści obwodu.Pozwalatom.in.naodbiórsygnałówwysokonapięciowychprzezniskonapięciowączęśćukładu(diodaLEDmożebyćsterowananp.znapięcia230V,atranzystormożesterowaćukładem3.3V).Ponadtotransoptorzabezpieczaczęśćodbiorczą(podłączonądoswojegowyjścia)przedprzepięciamiw części sterującej diodą LED. Jednak ze względu na fizyczną bliskość diody i elementu foto-elektrycznego przy napięciu przekraczającym wartość izolacji może zdarzyć się przebicie (pełnąizolacjęoptycznązapewniaużyciepołączeńświatłowodowych).

Przykłady: 4N25 (analogowy), 4N35 (analogowy), 6N136 (cyfrowy), 6N137 (cyfrowy), MOC3023 (optotriak), MOC3063(optotriak)

Klucztranzystorowy

Klucz jest układem przełączającym wykorzystującym dwa skrajne stany pracy tranzystora - zatkania(tranzystornieprzewodzi),nasycenia(tranzystorprzewodzizminimalnymiograniczeniami).

kluczNPN

Abywprowadzić tranzystorNPNwstanzatkanianależypodaćna jegobazępotencjałmniejszy lubrównypotencjałowiemitera(zakładamyżepotencjałkolektorajestniemniejszyniżemitera-comamiejscewtypowychwarunkachpolaryzacjitranzystoraNPN),czyliUBE ≤ 0.AbywprowadzićtranzystorNPNwstannasycenianależynajegobazęwprowadzićpotencjałwiększyodpotencjałówemiteraikolektora,uzyskujesiętopoprzezwprowadzeniedotranzystoraprądubazyIB ≫

Uzasi laniaβRload

.

kluczPNP

Aby wprowadzić tranzystor PNP w stan zatkania należy podać na jego bazę potencjał większy lubrównypotencjałowiemitera(zakładamyżepotencjałemiterajestniemniejszyniżkolektora-comamiejscewtypowychwarunkachpolaryzacjitranzystoraPNP),czyliUBE ≥ 0.AbywprowadzićtranzystorPNPwstannasycenianależynajegobazęwprowadzićpotencjałmniejszyodpotencjałówemiteraikolektora,uzyskujesiętopoprzezwyprowadzenieztranzystoraprądubazyIB ≫

Uzasi laniaβRload

.

kluczJFET

Aby wprowadzić w stan zatkania tranzystor N-JFET należy podać UGS ≤ UGSoff , a dla tranzystora P-JFETnależypodaćUGS ≥ UGSoff .AbywprowadzićwstanprzewodzeniatranzystorN-JFETnależypodaćUGS ≥ 0} ,adlatranzystoraP-JFETnależypodaćUGS ≤ 0.

kluczMOSFET

AbywprowadzićtranzystorMOSFETwstanzatkanianależypodaćUGS < UGS( th) .Dlatranzystorów:

N-MOSFET z kanałem wzbogaconym i P-MOSFET z kanałem zubożonym wystarczy obniżyć

Page 7: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

G

D

SQ1

IRF5305

IRF5210

R11 75k

R31

330k G

D

S

Q2

IRFZ44N

IRF540N1

3

2

Q3

BC846

R12 75k

12

Z21

10V

12

Z11

10V

S1

Load

mostekH

S3

S2 S4

STER0V/5V

1

3

2

Q4

BC846R41

330k

R21 150k

OUT

STER==0V=>OUT=GND

STER==5V=>OUT=+12V

+12V+12V

+12V

+12V+12V

potencjałbramkidowartościniewielewyższejniżpotencjałźródłaP-MOSFETzkanałemwzbogaconymiN-MOSFETzkanałemzubożonymmusitobyćwartośćponiżejpotencjałuźródła.

AbywprowadzićtranzystorMOSFETwstanprzewodzenianależypodaćUGS ≫ UGS( th) .

(pół)mostekH

Mostek H jest to układ (oparty o 4 przełączniki,których rolę mogą pełnić klucze tranzystorowe)pozwalający na zmianę polaryzacji zasilaniapodłączonego do niego odbiornika. Układ takizłożony jest zdwóch identycznychgałęzi (S1+S2oraz S3 + S4, każda włączona pomiędzy dwomabiegunami zasilania). Pojedyncza taka gałąźnazywana jest pół-mostkiem i składa się z dwóchkluczy które powinny być sterowaneprzeciwstawnie (aby wyeliminować możliwośćzwarcia zasilania z masą). Układ pół-mostka możebyć wykorzystywany także samodzielnie jakouniwersalny układ klucza pozwalającego nazałączanie odbiornika zarówno od strony napięciadodatniego jak i od strony masy (w zależności odsposobu jego podłączenia) lub przełączania dwóchodbiorników (jednego umieszczonego pomiędzyzasilaniemawyjściemmostka,adrugiegopomiędzywyjściemamasą).

Na schemacie umieszczonym obok przedstawiona jest także przykładowa realizacja pół-mostka woparciuodwakluczenatranzystorachMOSFETisterującenimikluczeNPN.ZastosowaniekluczyNPN(tranzystoryQ3iQ4)pozwalanasterowaniezużyciemnapięcianiższegoodnapięciaprzełączanego.

WstaniezatkaniaQ3iQ4:potencjałbramkiQ1równyjestpotencjałowizasilania(czylitakżepotencjałowiźródła),zatemQ1(P-MOSFETwzbogacony)nieprzewodzi;potencjałbramkiQ2ustaladzielnikzłożonyzR21iZ21(jestonwyższyodpotencjałuźródła,minimalnie o wartość napięcia zasilania, a maksymalnie o wartość spadku na Z21) i jest onwyższy o conajmniej UGS( th) od potencjału źródła, zatem Q2 (N-MOSFET wzbogacony)przewodzi.

Wstanienasycenia(pzewodzenia)Q3iQ4:potencjałbramkiQ1ustalany jestprzezdzielnikR11 iR12albo(jeżelinapięciezasilania jestodpowiednio wysokie) przez dzielnik Z11 i R12 i jest on niższy o conajmniej UGS( th) odpotencjałuźródła,zatemQ1przewodzi;potencjałbramkiQ2jestrównypotencjałowimasy(czylitakżepotencjałowiźródła),zatemQ2nieprzewodzi.

ZastosowaniediodZeneraZ1iZ2zabezpieczatranzystoryMOSFETprzedpodaniemnabramkęzbytdużego(codowartościbezwzględnej)napięciawstosunkucodoźródła.Niestetywiążesiętotakżezzastosowaniem to zastosowaniem rezystora R12, który (tworząc dzielnik) powoduje iż układ niebędziedziałałpoprawniedlaniskichnapięćzasilaniatoruprądowego-napięciemusibyćwiększeod2UGS( th) zamiast od UGS( th) . Ponadto wymaga to zastosowania osobnych gałęzi sterujących dlaposzczególnych tranzystorów MOSFET (dwóch kluczy NPN), ponieważ obecność Z21 w gałęzisterującejP-MOSFETem(Q1)przywyższymnapięciuzasilaniapowodowałabyprzepływprąduprzeztągałąźniezależnieodQ3comogłobyprowadzićdoprzewodzeniaQ1.

Wzmacniaczsygnałupunktpracy

Aby móc wykorzystać tranzystor do wzmacniania sygnału konieczne jest wstępne ustalenie punktupracytranzystorawtensposóbabyniewchodziłwstanynasyceniaizatkaniaorazabyukładposiadałustalonewzmocnienie.

WprzypadkutranzystorówNPNiPNPmożnabypróbowaćustalićgozużyciemokreślonejwartościprądubazy(pokazanypowyżejukładzrezystorembazyirezystancjąobciążenia),jednakzewzględuna znaczny rozrzut wartości współczynnika β pomiędzy egzemplarzami układ taki cechowałby sięmałąpowtarzalnością.Wzwiązkuztymstosujesiępokazanyobokukładzestałympotencjałembazyiopornikiememiterowym,gdzieIE =

UB − 0.6VRe

,IB =IEβ + 1 ,IC = IE − IB ,β ≫ 1,zatemIC = IE

ββ + 1 ≈ IE .

Page 8: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

Rc

VccVcc

Rb1

Rb2

Re

Cin

Cout

Cb

VccVcc

Rb1

Rb2 Re

Cin

Coutin

out

out

in

wspolnykolektor wspolnabaza

B

C

E

B

C

E

Rc

VccVcc

Rb1

Rb2 Re

Cin

Cout

Ce

in

out

B

C

E

B

C

ET1

B

C

E T2

out1 out2

RC2RC1

Vcc Vcc

in1 in2

−Vee

Ree

B

C

E T1

B

C

ET2

in out

RLR1

Vcc Vcc

wspólnyemiter

Przedstawiony układ jest także przykładem jednego z 3podstawowych układów pracy tranzystora bipolarnego (NPN,PNP) w funkcji wzmacniacza określanym "wspólny emiter".Układ tego typu charakteryzuje się wejściem sygnału na bazętranzystora(napięciebazywstosunkucodonapięciaemitera/masy dla układów NPN) i wyjściem wzmocnionego sygnału zkolektora (napięcie kolektorem w stosunku co do napięciaemitera/masydlaukładówNPN).

Wprzypadkupolaryzacjistałymprądembazyemiterwukładzietymmapotencjałmasy.Wprzypadkuprzedstawionejpolaryzacjistałym potencjałem bazy aby w układzie tym móc uzyskaćwzmocnienie konieczne jest zwarcie emitera do masy dlasygnałów zmiennych, realizowane przy pomocy kondensatoraCe.

wspólnykolektoriwspólnabaza

Kolejnymi dwoma z 3podstawowych układówpracy są układy wspólnegokolektoraiwspólnejbazy.

W układzie wspólnegokolektora sygnał wejściowypodawanyjestmiędzybazęakolektor, natomiastwzmocniony sygnałodbierany jest z pomiędzyemitera i kolektora.Wzmacniacz w układziewspólnego kolektora nieposiada wzmocnienianapięciowego (napięcie wyjściowe jest wręcz pomniejszone o spadek na złączu PN), natomiastposiadaznacznewzmocnienieprądu.Układczęstookreślanyjestjakowtórnikemiterowy.

W układzie wspólnej bazy sygnał wejściowy podawany jest między emiter a bazę, natomiastwzmocnionysygnałodbieranyjestzpomiędzykolektoraibazy.

UkładytranzystoroweLustroprądowe

T1iT2musząmiećzapewnionątąsamątemperaturę(najlepiejbyćwykonanewramach jednegoukładu scalonego.T1pracuje jakodioda (stosujemy tranzystoraby zapewnić taką samą charakterystykę jak T2), która wraz z R1 tworzysprzężony termicznie z T2 dzielnik sterujący tranzystorem T2. Układ tensterowany prądem płynącym przez R1 powoduje przepływ (niemalże) takiegosamegoprądupoprzezRL.

Wzmacniaczróżnicowy

Wprzypadkuukładuz tranzystoramiNPN"bardziej"przewodzićbędzietranzystornawejściuktóregojestwiększenapięcie(niżnatymdrugim).Fakt tego że on przewodzi powoduje ustalenie się potencjału w węźlełączącym emitery obu tranzystorów na wartość napięcia jego bazypomniejszonego o spadek na przewodzącym złączu PN. W sytuacji gdynapięcia baz obu tranzystorów są odpowiednio bliskie przewodzić będąoba,zakrestenokreślasięstrefąprzejściową.

Układtenmożepełnićrolękluczaprądowego(gdypodanysygnałnatyledużyaby zatkać jeden z tranzystorów) lubwzmacniacza (gdypracowaćbędąobatranzystory.Układjestczułynaróżnicęnapięćprzyłożonychdoin1 i in2.Reepełni rolę źródłaprądowego (ipowinienbyć takdobranyaby wraz z wartością -Vee zapewnić jego stabilność). Zastosowanieregulowanego źródła prądowego (tranzystor) zamiast Ree (realnie - wszereguzRee)pozwalanaregulacjęwzmocnieniategoukładu.

Page 9: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

B

C

ET1

B

C

E T2

RC2RC1

in1

R1

Ree

AK

D1

Up

B

C

E

T1B

C

E

T2

RC2

RC1

outRB1

RB2

inC1

B

C

E

T1B

C

E

T2

RC2

RC1

Vcc

in2

out2RB1RB2

out1

AK

D2

in1A

K

D1

B

C

E

T1B

C

E

T2

RC2

RC1

out2

RB1

RB2

out1C1 C2

ASTABILNY

BISTABILNY

MONOSTABILNY

SHMITTA

−Vee

−Vee

Vcc Vcc Vcc Vcc Vcc

VccVcc

VccVccVcc

R1 R2in

out

wzmacniaczodwracającyR1

R2

inout

wzmacniacznieodwracający

U1+12V U1

R2RsVin2

out

U1

R1Vin1

sumatornapięćR1=R2=...=Rs...

+12V

+12V

-12V

-12V

-12V

Przerzutniki

PrzerzutnikbistabilnyUkład ten służy do zapamiętaniastanu binarnego. Może byćprzełączony poprzez podaniekrótkiego sygnału na którejś zwejść lub zwarcie któregośwyjścia do masy. powoduje torozpoczęcie przewodzenia przezwybrany z tranzystorów, coprowadzi do spadku napięcia nabazie drugiego tranzystora,prowadząc do jego zatkania itrwałego ustalenia stanuwysokiego na bazie wybranegotranzystora.

PrzerzutnikmonostabilnyUkładsłużydogeneracjiimpulsutrwającego ustaloną długość.Działa on podobnie jakprzedstawiony przerzutnikbistabilny, z taką różnicą iżkrótkotrwałe zwarcie wejścia domasy powoduje obniżeniepotencjałubazyT2onapięciedojakiegozostałnaładowanyC1(wnormalnymstanieUCC −UBE ).Powoduje to zatkanie T2 i przewodzenie T1, następuje także ładowanie C1 z stopniowymzwiększaniemnapięcianabazieT2ażdoosiągnięciasytuacjipierwotnej.Należyzwrócićuwagęże po zatkaniu T1 (zaprzestaniu generowania sygnału wyjściowego) układ nie osiągnął jeszczegotowościdogeneracjinastępnegoimpulsugdyżmusinastąpił ładowanieC1przezRC1(należyodczekać t≳5τ = 5RC1C1). Wadą takiego rozwiązania są duże ujemne napięcia na bazachtranzystorówwchwiliprzerzutu,co(przywiększychnapięciachzasilania)możedoprowadzićdoichprzebicia.

PrzerzutnikastabilnyPrzerzutnik ten służy do generacji sygnału prostokątnego o zadanym wypełnieniu. Działanieukładu jest podobne do opisanego przerzutnika montostabilnego z tym że po (ponownym)nasyceniu drugiego tranzystora powstały spadek napięcia rozpoczyna taki sam proces dlapierwszego tranzystora i kondensatora podłączonego do jego bazy. Dodatkową wadą tegorozwiązania jest problem startu przy wypełnieniu 1/2 (jednakowych elementach) i łagodnymwłączaniu.

PrzerzutnikShmittaSłużyoddouzyskaniahisterezy-większenapięciepowodujeprzejściewstanwysoki,amniejszeod niego w stan niski. Pozwala to m.in. na odszumianie sygnałów. Idea działania polega nazmianie potencjału drugiego wejścia wzmacniacza różnicowego zależnie od jego stanu.PrzesuwnikpoziomówzrealizowanynaD1orazR1służydodostosowanianapięciawyjściowegodozakresuhisterezy(wynosionUCC −Up =wartośćgórna,UCC − IEERC1−Up =wartośćdolna).

Wzmacniaczoperacyjny

Jest toukład służącydowzmacnianiabardzowiele razyróżnicy napięć wejściowych, oparty na układziewzmacniacza różnicowego z lustrem prądowym. Nastopniuwejściowymposiadaonwzmacniaczróżnicowyzlustrem, dalej jest układ wzmacniający o dużymwzmocnieniu, a na stopniu wyjściowym wtórnikemiterowy. Charakteryzuje się dużą rezystancjąwejściowąibardzodużąwartościąwzmocnienia.

Jako iż wzmocnienie wzmacniaczy operacyjnych jestbardzo duże nie da się w praktyce wykorzystać ichbezpośrednio do wzmacniania sygnału. Robi się to zwykorzystaniem sprzężenia zwrotnego, czyli podaniemprzeskalowanegosygnałuwyjściowegonawejście.Dziękiwykorzystaniuujemnegosprzężeniaukładzachowujesięstabilnie dążąc do utrzymania różnicy napięćwejściowych bliskiej zeru oraz posiada bardzo małą(prawie zerową) rezystancję wyjściową. Wzmocnieniezależy od parametrów dzielnika występującego w pętli

Page 10: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

1 +3out

2 -Vin1

Vin2

Vcc

Vout

Podstawowyukładpracy: Vin1>Vin2=>Vout=0 Vin1<Vin2=>Vout=Vccpozwalanakonwersjępoziomów-możemyporównywaćnapięciaoinnychpoziomach(takżewyższych)niżpoziomnapięciawyjściowego

1 +3out

2 -

R3

Vcc

Vout

R2 zhisterezą

Vin1

Vin2

R1

dyskryminatorokienkowy

1 +3out

2 -Vin

Vref1

Vcc

Vout1 +

3out2 -

Vref2

sprzężeniazwrotnegoidlawzmacniaczaodwracającegofazęwynosiku = −R2R1

,adlawzmacniaczanie

odwracającegofazyku = 1 +R2R1

(abyuzyskaćwtórnikR2należyzastąpićzwarciem,aR1rozwarciem).

W wzmacniaczu odwracającym rezystancja wejściowa Rwe = R1, natomiast w odwracającym jest tozasadniczo tylko rezystancję sumacyjnąwzmacniacza różnicowego (różnicowejpraktycznieniewidaćbo dzięki sprzężeniu zwrotnemu napięcie na niej bliskie zeru). Częstotliwość graniczną oblicza się zzależnościfg =

fT1 + R2R1

.

Niekiedystosujesię takżetzw"R3"podłączonydonieodwracającegowejściawzmacniacza,matonaceluminimalizacjęwpływuprądówwejściowych(niewpływananapięcieniesymetryczności,którejestcechąsamegowzmacniacza),wtedyR3=R1||R2gdysprzężenieDC,lubR3=R2gdysprzężenieAC(źródło sygnału oddzielone kondensatorem). Ze względu na stosowanie sprzężenia zwrotnego niemożnanaukładtakipodawaćsygnałuktóregoprzesunięciefazowenawzmacniaczubyłobywiększeniż135°, aby nie doprowadzić do wzbudzania się układu. Uzyskuje się to poprzez zapewnieniewzmocnienia mniejszego od jedności dla częstotliwości przy których byłoby takie lub większeprzesunięciefazowe.

W oparciu o wzmacniacz operacyjny w układzie odwracającym można zrealizować sumator napięćwejściowych. Suma prądów wpływających przez rezystory R1, R2, R3, itd, ze względu na dużąrezystancjęwejściowąwzmacniaczamusibyćrównaprądowiwypływającemuprzezRs.NapięcienaRfmusibyćrównenapięciuwyjściowemu(wejścienieodwracającepodłączonedomasy,aukładdążydozerowego napięcia różnicowego na wejściach wzmacniacza). ZatemU1R1+ U2R2

+… = − UwyRs⟺Uwy = −Rs

U1R1+ U2R2

+… co przy równych wartościach rezystancji daje:

Uwy = U1+U2+… .

Przykłady:LM358;TL081

Komparatoranalogowy

Jest to układ służący doporównywania dwóch napięćwejściowych, oparty (podobnie jakwzmacniacz operacyjny) naukładzie wzmacniacza różnicowegoz lustrem prądowym.Charakteryzujesiędużąrezystancjąwejściową(małympoboremprąduzwejść), szybką i stromą zmianąwyjścia w odpowiedzi na zmianęsygnału wejściowego. Opróczpodstawowego układu pracykomparator może być stosowanym.in.wukładach:

zhisterezą:dzielnik R1, R3zapewnia sprzężeniezwrotne,R3≫ R1(rzędu

megaomów),wartośćhisterezydanajestzależnością:VH = VccR1

R1+R3rezystorR2zapewnia jednakowerezystancjęobuwejśćkomparatora iwynosićpowinien:R2 ≈ R1

dyskryminatorokienkowy:układ złożony z dwóch komparatorów wykrywający to iż napięcie znajduje się w przedzialepomiędzy Vref1 a Vref2, jeżeli Vref1 > Vref2 to znajdowanie się napięcia w zakresie będziesygnalizowanestanemwysokim,wprzeciwnymraziestanemniskim.

detektoraprzejściaprzezzero:zasadniczo dowolny układ (podstawowy, z histerezą, ...) wtedy gdy napięciem z którymporównujemyjestpotencjałzerawoltów(masa)

Przedstawione schematy są dla komparatora z wyjściem NPN (zwierającym do masy). Dlakomparatorówzinnymtypemwyjściamogąwymagaćpewnychmodyfikacji.

Przykłady:LM239;LM393;LM311

Page 11: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

CyfrowaAlgebraBoole'aisystemdwójkowypodstawoweoperacjeielementyneutralne

sumalogiczna(OR,+,|) aOR1=1 aOR0=a aORa=a

iloczynlogiczny(AND,*,&) aAND1=a aAND0=0 aANDa=a

negacja(NOT,~,^,!) NOT1=0 NOT0=1 NOT(NOTa)=a

własnościdziałań

łączność (aORb)ORc=aOR(bORc) (aANDb)ANDc=aAND(bANDc)

przemienność aORb=bORa aANDb=bANDa

rozdzielność aAND(bORc)=(aANDb)OR(aANDc)

aOR(bANDc)=(aORb)AND(aORc)

absorpcja aAND(bORa)=a aOR(bANDa)=a

negacjasumyiiloczynu

NOT(aORb)=(NOTa)AND(NOTb)

NOT(aANDb)=(NOTa)OR(NOTb)

pochłanianie aOR(NOTa)=1 aAND(NOTa)=0

dodatkoweoperacje

alternatywawykluczająca(XOR)

aXORb=(aAND(NOTb))OR(bAND(NOTa))

aXOR0=a

aXORa=0

aNANDb=NOT(aANDb) (aNANDb)NAND(cNANDd)=(aANDb)OR(cANDd)

aNORb=NOT(aORb) (aNORb)NOR(cNORd)=(aORb)AND(cORd)

aXNORb=NOT(aXORb)=aXANDb

tabliceprawdy

a b aORb aANDb aNORb aNANDb aXORb aXNORb NOTa

0 0 0 0 1 1 0 11

0 1 1 0 0 1 1 0

1 0 1 0 0 1 1 00

1 1 1 1 0 0 0 1

reprezentacjaliczb

Pojedynczą cyfrę systemu dwójkowego (przybierającą wartość 0 albo 1) określa się mianem bitu,liczbyreprezentowanesąjakociągitakichcyfr.Terminembajtokreślasięzazwyczajciągodługości8bitów(alewniektórychsystemachciągoinnejdługości).

Podstawowymsposobemzapisyliczbcałkowitychnieujemnychwsystemiedwójkowymjestnaturalnykod binarny (NKB), w którym np. 4 bitowy ciąg a3 a2 a1 a0 reprezentuje liczbę20 ⋅ a0+ 21 ⋅ a1+ 22 ⋅ a2+ 23 ⋅ a3.

Podstawowymsposobemzapisyliczbcałkowitych(zeznakiem)jestkoduzupełnieńdodwóch(U2)wktórym n-bitowa liczba reprezentowana przez ciąg an-1 ... a3 a2 a1 a0 będzie miała wartość20 ⋅ a0+ 21 ⋅ a1+ 22 ⋅ a2+ ... + 2n − 2 ⋅ an − 2− 2n − 1 ⋅ an − 1.Jakożenajstarszybitwchodzizujemnąwagą,jegoustawieniena1oznaczaliczbęujemną(aleniejesttokodznaku).WartozauważyćkompatybilnośćzNKB.

Liczby zapisywane w tych kodowaniach systemu dwójkowego oznacza się często przy pomocyprefiksu "0b" albo sufiksu "b", np. 0b101 = 101b reprezentuje liczbę 5 w systemie dziesiętnym (

Page 12: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

Vdd

Pull−up

Outctrl1 ctrl2

U1 U2

<=>ctrl1

ctrl2Out

AND

NAND

BUFOR

BUFOR3statezzanegowanymsygnałemaktywacji

BUFOR3state

NORNOT

OR

XNOR

XOR

bramki(AND,OR,XOR,NAND,NOR,XNOR)mogąwystępowaćtakżewwariantachwielo-wejściowych

wwariancie3stanowymmogąwystępowaćtakżewszystkiepozostałeelementy

20 ⋅ 1 + 21 ⋅ 0 + 22 ⋅ 1 = 5).

Opróczpodanychistniejejeszczekilkastosowanychsposobówzapisuliczbbinarnychtakichjak(dlaliczbbezznaku):kod"1zn",kodGraya,kodJohnsona,(dlaliczbzeznakiem):kodznak-moduł,koduzupełnieńdojedności(U1).Odmiennymzagadnieniemjestkodowanieliczbzmiennoprzecinkowych.

zapishexalny(szesnastkowy)

Celem skrócenia zapisu liczb binarnych często zapisuje się je w postaci szesnastkowej, jest onwygodniejszyoddziesiątkowegogdyżkażdacyfrasystemuszesnastkowegorozkładasięnadokładnie4 bity, co pozwala na niezależne konwertowanie poszczególnych cyfr szesnastkowych / ciągów 4bitowychiichłączeniewdłuższeciągi.

Cyfryowartościachpowyżej9zapisujesięjakokolejnemałelubwielkieliterya,b,c,d,e,f.Liczbyzapisywanewsystemieszesnastkowymoznaczasięprzypomocyprefiksu "0x" lub "#"albosufiksu"h" np. 0xc7 = #c7 = c7h reprezentuje liczbę 199 w systemie dziesiątkowym (160 ⋅ 7 + 161 ⋅ 12 = 199).Konwersjanasystembinarnymożeodbywaćsięniezależniedlakażdejcyfry,jakoże:0xc=0b1100oraz0x7=0b0111to0xc7=0b11000111.

reprezentacjaelektryczna

Typowologicznej1odpowiadastanwysoki(napięciedodatnie),alogicznemu0stanniski(potencjałmasy).Wprzypadkulogikiodwróconej(ujemnej)logicznej1odpowiadastanniskialogicznemuzeruwysoki.

Bramki

Bramki są układami elektronicznymi realizującymipodstawowe, opisane powyżej funkcje logiczne. Obokzostały przedstawione podstawowe symboleposzczególnychbramekwwarianciedwuwejściowym,spotkaćsięmożnatakżezsymbolamizzanegowanymiwejściami - w takiej konwencji np. bramka ANDreprezentowana jest przez NOR z zanegowanymiwejściami. Bramki (z wyjątkiem buforów oraz bramkiNOT), mogą występować także w wariantach wielo-wejściowych (ze względu na łączność podstawowychoperacji nie ma wątpliwości co don wyniku jakipowinnadawaćnp.8wejściowabramkaOR).Naogółw pojedynczym układzie scalonym znajduje się kilkajednakowychbramek.

trój-stanowe

Typowabramkawymusza(wsposóbsilny)naswoimwyjściustanwysoki lubniski,couniemożliwiabezpośredniełączeniewyjśćbramek.Bramkitrój-stanowemająmożliwośćskonfigurowaniawyjściawstanwysokiej impedancji czyli nie wymuszania żadnej jego wartości. Sterowanie załączeniem bądźwyłączeniem wyjścia (przełączeniem w stan wysokiej impedancji) odbywa się przy pomocyzewnętrznegosygnałusterującego"outputenabled" ("OE"), sygnał tenmożewystępowaćwpostaciprostejizanegowanej.Pozwalatonapodłączaniedojednejliniiwielubramekidecydowaniuktóraznichbędzieniąsterować.

opencollector/drain

Sąkolejnymrodzajembramekktórychwyjściamożna podłączać do wspólnej linii. Układy teposiadają wyjście w postaci tranzystorazwierającego linię wyjściową do masy, z tegowzględu samodzielnie zapewniają jedynie stanniski wyjścia (są w stanie wymusić stan niski,aleniemająmożliwościwymuszeniastanuwysokiego).

Stanwysokimusizostaćzapewnionyzewnętrznymrezystorempodciągającym.Pozwala tostosowaćnatakiejliniiinnypoziomstanuwysokiegoniżnawejściachtakiejbramkiorazpozwalanasterowaniewspólnejliniiprzezwielebramek(czyliłączeniewyjśćbramek,jednakwodróżnieniuodbramektrój-stanowychniewymagadodatkowychsygnałówsterujących).

Na schemacie obok przedstawiono dwa układy (U1 i U2) typu open-drain sterujące wspólną liniąwyjściową w układzie suma na drucie. Jeżeli jeden z podłączonych do linii układów będzie miałwewnętrznewyjście("ctrlX")wstaniewysokimtojegowyjścieOCbędziezwartedomasy(negacjanatranzystorzeN-MOSlubNPN),wtedyteżcałaliniabędziewstanieniskim.

Page 13: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

Vdd

input output

NOT NAND

Vdd

input1 output

input2

Vdd

input1output

input2

NOR TRANSMISYJ NA(bufor3stanowy)

input outputVdd

ster

notster

budowawewnętrzna

Przedstawionypowyżejukładsumynadruciejestbardzo prostą (jedno tranzystorową) realizacjąbramkilogicznejrealizującąfunkcjęlogicznąNOTOR (z punktu widzenia wejść ctrl1 i ctrl2 orazwyjścia Out). W podobny sposób możnazrealizować bramkę AND (negując wejścia, np.przy pomocy jednego traznzystora). Jeszczebardziej uproszczoną realizację można uzyskaćstosując diody pozwalające na wpływanie prądudo węzła (funkcja OR) lub wypływanie z niego(funkcjaAND).

Poprawejprzedstawionezostałyschematyideoweinwertera, dwóch podstawowych bramek (NOR iNAND) oraz bramki transmisyjnej (bufora 3stanowego)wtechnologiiCMOS.

Działanie tych bramek (za wyjątkiemtransmisyjnej)poleganaotwieraniu tranzystorówpodłączonychdonapięciaktórechcemyotrzymaćna wyjściu, a zamykaniu prowadzących donapięcia przeciwnego. W szczególności bramkaNOT stanowi pół-mostek H pomiędzy stanemwysokim a stanem niskim. Dzięki zastosowaniutranzystorówPMOSpolaryzowanychVddorazNMOSpolaryzowanychGNDobiegałęzieoperująnatymsamymsygnalewejściowym(niejestwymaganajegonegacja).Szeregowełączenietranzystorówzapewnia że należy otworzyć oba aby otworzyć daną drogę, a równoległe że otwarcie danej drogipowodowane jest otwarciem pojedynczego tranzystora. Dzięki zastosowaniu technologi MOS ipodłączaniu wejść bramki tylko do bramek tranzystorów wejścia praktycznie nie pobierają prądu(istotnymwyjątkiemjestchwilazmianysygnału).

Działanie bramki transmisyjnej polega na przepuszczaniu lub nie (w zależności od stanu wejściasterującego) sygnału z wejścia na wyjście. Bramka taka nie regeneruje sygnału. Ponadto wuproszczonym (jedno tranzystorowym) rozwiązaniu prowadzi ona do degradacji sygnału wartość wprzybliżeniurównąnapięciuprogowemutranzystora.Dlatego teżnaogółwystępujewrazzbramkąNOT (bufor 3 stanowy z negacją) lub dwiema szeregowo połączonymi bramkami NOT (bufor 3stanowybeznegacji).

wejścieSchmitta

Układy z wejściem Schmitta zapewniającym histerezę sygnału wejściowego stosowane są wprzypadku mało stromych, zaszumionych sygnałów dla których układy z normalnym wejściemmogłybyzmienićkilkukrotniestanwyjścianajednymzboczusygnałuwejściowego.

Przykłady:74HC00 (4x2-inputNAND);74HC1G00 (1x2-inputNAND);74HC20 (2x4-inputNAND);74HC30 (1x8-inputNAND);74HC03(4x2-inputNAND,open-drain);74HC132(4x2-inputNAND,Schmitt);74HC04(6xNOT);74HC1G04(1xNOT);74HC14(6xNOT,Schmitt);74HC1G14(1xNOT,Schmitt);74HC02(4x2-inputNOR); 74HC1G02 (1 x 2-inputNOR); 74HC08 (4 x 2-inputAND); 74HC1G08 (1 x 2-inputAND); 74HC32 (4 x 2-inputOR);74HC1G32 (1 x 2-input OR); 74HC86 (4 x 2-input XOR); 74HC1G86 (1 x 2-input XOR); 74HC7226 (4 x 2-input XNOR);74HC7014(6xSchmitt);

Przerzutnikiirejestryprzerzutnik/zatrzaskRS

RS Flip-flop (RS Latch) jest podstawowym układem służącym do zapamiętania jednego bituinformacji.Posiadaondwawejścia(setireset)idwawyjścia(QiNOTQ),wejściamogąreagowaćnastanwysoki(oznaczanejakoSiR)lubniski(oznaczanejakowejściazanegowane~Si~R), jednozwyjść może być jedynie wewnętrzne (nie wyprowadzone na zewnątrz układu). Podanie stanuwysokiego na wejście S (niskiego na ~S) powoduje wystawienie stanu wysokiego na wyjściu Q, apodanie stanu wysokiego na wejście R (niskiego na ~R) powoduje wystawienie stanu niskiego nawyjściu Q. Stan na wyjściu Q nie zmienia się po zmianie wejść S i R na stan niski (zostajezapamiętany).

Na schemacie przedstawiono dwubramkową budowę przerzutnika RS zarówno w wariancie zwejściaminiezanegowanymijakiwwarianciezwejściamizanegowanymi.

zatrzaskaprzerzutnik

Zatrzask jest elementem reagującym na poziom sygnału na wejściu "enable" (E). W przypadku niezanegowanego wejścia E, jeżeli jest ono w stanie wysokim sygnał na wyjściach (Q i NOT Q) jestfunkcją sygnałówwejściowych,natomiast stanniskiwejściaEblokuje zmianę sygnałuwyjściowego

Page 14: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

Q

~Q

E

J

K

Q

~Q

~S

~R

<=>

~S

~R

Q

~Q

R

S

R1

S2

Q 3

Q 4

R1

S2

Q 3

Q 4<=> <=>

Przerzutnik/zatrzaskRS PrzerzutnikRSzwejsciamizanegowanymi

Zatrzask(latch)J K

D1

CLK2

Q 3

Q 4

R5

S6

D1

E2

Q 3

Q 4

R5

S6

D1

E2

Q 3

Q 4

R5

S6

Q

~QCLK

D<=>

PrzerzutnikD

D1

E2

Q 3

Q 4

R5

S6

J1

E2

K3

Q 4

Q 5

R6

S7

J1

E2

K3

Q 4

Q 5

R6

S7

D Q

~QE

Zatrzask(latch)D

<=>Q

~Q

E

D

~S

~R

<=>

(zostajeonzapamiętany).

Przerzutnik jest elementemreagującym na zboczesygnału na wejściu "clock"(CLK). W zależności odkonstrukcji może reagowaćna zbocze narastające,opadającealbonaoba(wtedyna jednym realizuje odczytwejść a na drugim zmianęstanuwyjść).

zatrzaskiprzerzutnikJK

Posiada dwa wejściasygnałowe(JiK)orazwejście"enable" (E) w przypadkuzatrzasku lub wejście "clock"(CLK) w przypadkuprzerzutnika. Może takżeposiadać asynchroniczne(niezależne od stanu wejściaE / CLK) wejścia reset i set(zanegowanelubproste).

J K Qn+1 Opis

0 0 Qn brakzmiany

0 1 0 reset

1 0 1 set

1 1 NOTQn zmianawyjścianaprzeciwny

Stan wejść J = K = 1 dozwolony jest tylko w przypadku przerzutnika, gdyż wtedy sygnał CLKdecyduje o momencie zmiany wyjścia Q na przeciwne. W przypadku zatrzasku, przy wysokim Ewystąpiłybyoscylacjenawyjściu.

Przykłady: 74HC73 (2 x przerzutnik JK, zbocze opadające, wejścia~R); 74HC107 (2 x przerzutnik JK, zbocze opadające,wejścia ~R); 74HC112 (2 x przerzutnik JK, zbocze narastające, wejścia ~S i ~R); 74HC112 (2 x przerzutnik JK, zboczeopadające,wejścia~Si~R)

zatrzaskiprzerzutnikD

Posiada jedno wejścia sygnałowe "data" (D) oraz wejście "enable" (E) w przypadku zatrzasku lubwejście"clock"(CLK)wprzypadkuprzerzutnika.Możetakżeposiadaćasynchroniczne(niezależneodstanuwejściaE/CLK)wejściaresetiset(zanegowanelubproste).ObniżeniesygnałuElubzboczesygnałuCLKpowodujązapamiętanie(iwystawienienawyjściuQ)stanuwejściaD.

Wprzypadkuzaprezentowanejrealizacjiprzerzutnikazdwóchzatrzaskówsygnałwejściowyzostanieodczytanynazboczuopadającymzegaraawystawionynawyjścienazboczunarastającym.

DEQ

DCLK

Q

Przykłady: 74HC74 (2 x przerzutnik D, zbocze narastające, wejścia ~S i ~R); 74HC173 (4 x przerzutnik D, zboczenarastające, sygnał input-enable, wspólny reset i clock, wyjścia Q trój-stanowe); 74HC174 (6 x przerzutnik D, zboczeopadające,wspólnyreseticlock);74HC175(4xprzerzutnikD,zboczenarastające,wspólnyreseticlock,wyjściaQiNOTQ);

rejestry

Mianem rejestru n-bitowego określa się zespół n przerzutników (rzadziej zatrzasków), często zuwspólnionymsterowaniem(sygnałyclock,set,reset,etc)służącydozapamiętanian-bitowejwartości

Page 15: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

D1

CLK2

Q 3

Q 4

R5

S6

LOAD

IN0

D1

CLK2

Q 3

Q 4

R5

S6

SerialInput

CLK

...

...

...

INn

D1

CLK2

Q 3

Q 4

R5

S6

SerialOutput

parallel−in,serial−out,asynchronousload

Shift(NotLoad)

SerialInput

CLK...

parallel−in,serial−out,synchronousload

CLEAR

INn

...

SerialOutputD1

CLK2

Q 3

Q 4

R5

S6

D1

CLK2

Q 3

Q 4

R5

S6

IN0

...

serial−in,parallel−outCLEAR

SerialInput

CLK

D1

CLK2

Q 3

Q 4

R5

S6

SerialOutput

...

...

D1

CLK2

Q 3

Q 4

R5

S6

CLEAR

Input

OUT0 OUTn

asynchronouscounter

......

D1

CLK2

Q 3

Q 4

R5

S6

D1

CLK2

Q 3

Q 4

R5

S6

CLEARCLK

D1

CLK2

Q 3

Q 4

R5

S6OUT0 OUTn

parallel(standard)register

...

INnIN0

J1

CLK2

K3

Q 4

Q 5

R6

S7

J1

CLK2

K3

Q 4

Q 5

R6

S7

Input

CLEAR

OUT0

J1

CLK2

K3

Q 4

Q 5

R6

S7

OUT1

J1

CLK2

K3

Q 4

Q 5

R6

S7

OUT2 OUT3

...−>J ,Knextstage

...synchronouscounter

toOUTPUTregister(D0)

toOUTPUTregister(Dn)

(liczby). W zależności odsposobu zapisu i odczytumożnawyróżnić:rejestryrównoległe

Posiadają taką samąliczbęwejśćjakiwyjść,sygnałna i-tymwyjściujest bezpośredniopowiązanyzsygnałemzi-tego wejścia (jestsygnałemzapamiętanym z tegowejścia).

Przykłady: 74HC273 (8bit,zbocze narastające, sygnałreset); 74HC374 (8bit,zbocze narastające, wyjściatrój-stanowe); 74HC377(8bit, zbocze narastające,sygnał reset, sygnał input-enable); 74HCT534 (8bit,zbocze narastające, wyjściatrój-stanowe zanegowane);74HC574 (8bit, zboczenarastające, wyjścia trój-stanowe);74HC373 (8bit, zatrzaskprzeźroczysty w staniewysokim, wyjścia trój-stanowe); 74HC563 (8bit,zatrzask przeźroczysty wstaniewysokim,wyjściatrój-stanowezanegowane);74HC573(8bit,zatrzaskprzeźroczystywstaniewysokim,wyjściatrój-stanowe);

rejestryszeregoweserial-inputZ kolejnymi sygnałami zegarowymi odczytywany jest stan wejścia szeregowego, a stanpoprzedni przenoszony jest do kolejnego przerzutnika w ramach rejestru. W ten sposób po ncyklachzegaran-bitowyrejestrmazapisanąnowązawartość.Częstoposiadazespolonyznimrejestr równoległy zapobiegający zmianie stanu wyjść w trakcie ładowania danych z wejściaszeregowego przepisanie danych z rejestru przesuwnego do rejestru odpowiedzialnego zasterowaniewyjściamisterowanejestosobnymsygnałemzegarowym.

Przykłady:74HC164(8bit,bezrejestruwyjściowego);74HC194(4bit,wejścierównoległe,przesuwaniewprawoiwlewo);74HC195(4bit,wejścierównoległe);74HC594(8bit,zatrzaskwyjściowyzresetem,wyjścieszeregowe,sygnałresetu);74HC595(8bit,zatrzaskwyjściowyzwyjściamitrój-stanowymi,wyjścieszeregowe,sygnałresetu);74HC4094(8bit,zatrzaskwyjściowyzwyjściamitrój-stanowymi,wyjścieszeregowe,zatrzaskwyjściaszeregowego);

rejestryszeregoweparaller-inputserial-outputZ kolejnymi sygnałami zegarowymi na wyjście szeregowe wystawiany jest stan kolejnego zrejestrówwejściowych.Wariantasynchronicznyposiadaosobnysygnałpowodującyodczytwejśćdo rejestru (sygnał działa jak "enable" w zatrzaskach). Wariant synchroniczny posiada sygnałdecydujący o tym czy na zboczu zegara dokonywany jest odczyt wejść czy też przesuwaniezawartościrejestruumożliwiającyodczytzwyjściaszeregowego.

Przykłady: 74HC165 (asynchroniczne wczytanie danych wejściowych, wejście szeregowe, sygnał clock-enable);74HC166 (synchroniczne wczytanie danych wejściowych, wejście szeregowe, sygnał clock-enable); 74HC589(dodatkowy zatrzask wejściowy, asynchroniczne wczytanie danych wejściowych, wejście szeregowe, wyjście trój-stanowe); 74HC597 (dodatkowy zatrzask wejściowy, asynchroniczne wczytanie danych wejściowych, wejścieszeregowe,sygnałclock-enable);

licznikiZ kolejnymi sygnałami zegarowymi zwiększana jest o jeden wartość rejestru. Prostszy wbudowie licznik asynchroniczny ma większe (i w dodatku rosnące wraz z bitowością licznika)ograniczenia dotyczące szybkości zliczania od licznika synchronicznego, ze względu naopóźnieniezjakimdochodzizliczanysygnał(CLK)dokolejnychstopnilicznika.

Przykłady: 74HC93 (2x 4bit synchroniczny, zbocze opadające); 74HC161 (4bit synchroniczny, zbocze narastające,presetwartościąpoczątkową,wejście zezwoleniana zliczanie, sygnał przepełnienia); 74HC163 (4bit synchroniczny,zboczeopadające,presetwartościąpoczątkową,wejściezezwolenianazliczanie,sygnałprzepełnienia);74HC191(4bitsynchroniczny, zbocze narastające, liczącyw górę iw dół - sygnałwyboru,wejście zezwolenia na zliczanie, presetwartością początkową); 74HC192 (4bit synchroniczny, zbocze narastające, liczącyw górę i w dół - osobne zegary,wejście zezwolenia na zliczanie, preset wartością początkową, sygnał przepełnienia przy 9 - BCD); 74HC193 (4bitsynchroniczny, zbocze narastające, liczącyw górę iw dół - osobne zegary,wejście zezwolenia na zliczanie, preset

Page 16: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

wartością początkową, sygnał przepełnienia przy 15); 74HC393 (2x 4bit asynchroniczny, zbocze opadające, sygnałresetu);74HC40103(8bitsynchroniczny);74HC4017(dekadowy-wartościodpowiadanumeraktywnegowyjścia,10wyjść); 74HC4020 (14 bitowy asynchroniczny); 74HC4040 (12 bitowy asynchroniczny); 74HC390; 74HC4024;74HC4060;74HC4518;74HC4520;

PrzetwornikiADCiDAC

Przetwornik analogowo-cyfrowe (ADC) służy do konwersji sygnału analogowego na postać cyfrową.Realizowane jest to poprzez pomiar napięcia, na ogół w regularnych odstępach czasowych (celemuzyskania przebiegu sygnału a nie tylko wartości chwilowej). Przetwornik ADC o porównaniubezpośrednim realizowany jest w oparciu o zespół komparatorów analogowych (od ich liczby zależybitowośćdanegoprzetwornika,ale ich liczbanie jestrównabitowości)któreużywająróżnychnapięćreferencyjnych (typowo uzyskiwanych z jednego napięcia referencyjnego poprzez dzielnik). Stan zkomparatorówpodawanyjestnaenkodercelemkonwersjidokodubinarnego.Innestosowanesposobyrealizacji przetworników ADC opierają się o pojedynczy komparator i podawanie na niegonarastającego napięcia referencyjnego oraz zliczanie liczby kroków podnoszenia tego napięcia bądźpodawaniu kolejnych napięć z przetwornika DAC i wyszukiwaniu tego które jest najbliższewejściowemu.

Przetwornikcyfrowo-analogowy(DAC)służydokonwersjisygnałucyfrowegonaanalogowy.Opartyjestnazasadziesumatoranapięć,któregowejściazałączanesąwzależnościodustawienialubniedanegobitu w konwertowanej wartości. Typowo zamiast stosowania różnych wartości napięć i jednakowychrezystorów(jakwsumatorze),stosujesięróżnewartościzałączanychrezystorówijednakowenapięciedoktóregosąpodłączone.

pomiarnapięciaiprądu

Pomiar napięcia realizuje bezpośrednio przetwornik ADC. W przypadku konieczności pomiaruwysokich napięć stosuje się przekładniki napięciowe, będące w istocie transformatorami o dobrzeustalonych parametrach pomiarowych. W przypadku małych napięć konieczne może okazać się ichwzmocnienienp.zużyciemwzmacniaczaoperacyjnego.

Pomiarprądumożebyćrealizowanynakilkasposobów:jako pomiar napięcia na rezystancji włączonej w mierzony obwód; umożliwia pomiar prądówzmiennychistałychpoprzez przekładnik prądowy - transformator włączony szeregowo w obwód lub toroidalnącewkęprzezktórąprzeprowadzony jestprzewodnikwktórymdokonywany jestpomiarprądu(pojedynczeuzwojeniepierwotne);stosujesiętylkodlaprądówprzemiennych(zmiennyprądwprzewodzie powoduje powstanie indukcji magnetycznej która wymusza przepływ prądu wobwodziepomiarowym)zwykorzystaniemefektuHalla (prądmożeprzepływaćbezpośrednioprzezukładpomiarowy,może płynąć pętlą ścieżki umieszczoną z drugiej strony płytki drukowanej niż czujnik efektuHalla lub może być realizowany analogicznie do toroidalnego przekładnika prądowego);umożliwiapomiarprądówzmiennychistałych

Przykłady:ACS712(czujnikprąduACiDCopartynaefekcieHallazwyjściemnapięciowym,opornośćtorupomiarowego1.2mΩ,wersje: 5A (185mV/A), 20A (100mV/A) i 30A (66mV/A); ACS770 (czujnik prądu AC i DC oparty na efekcieHalla zwyjściemnapięciowym,opornośćtorupomiarowego0.1mΩ,wersje:50A,100Ai200A);WCS1800(przekładnikprądowyzwbudowanymczujnikiemprąduACiDCopartymnaefekcieHallazwyjściemnapięciowym,czułość:66mV/A,25AAC/35ADC); WCS1600 (przekładnik prądowy z wbudowanym czujnikiem prądu AC i DC opartym na efekcie Halla z wyjściemnapięciowym,70AAC /100ADC);SS49E (czujnikefektuHalla);SS411P (czujnikefektuHalla);TLE4905L (czujnikefektuHalla);

TransmisjaSterowanieliniąbufory

Buforjesttoukładprzekazującysygnałlogicznyzwejścianawyjście.Buformożesłużyćdo:regeneracjisygnału,uniemożliwieniuwprowadzeniasygnałuzjegostronywyjściowejnawejściową,decydowaniaojegoprzepuszczeniulubnie(trój-stanowy),decydowania o kierunku przepuszczenia sygnału (dwa trój-stanowe albo trój-stanowydwukierunkowy),konwersjinalinięopen-collector/open-drain,negacjisygnału(niektórebuforyrealizująfunkcjęNOT).

Przykłady:74HC125(4bit, trój-stanowy,wyjścieaktywowaneniskim);74HC1G125(1bit, trój-stanowy,wyjścieaktywowaneniskim);74HC126 (4bit, trój-stanowy,wyjścieaktywowanewysokim);74HC1G126 (1bit, trój-stanowy,wyjścieaktywowanewysokim);74HC240(2x4bit, trój-stanowy,wyjścieaktywowaneniskim,odwracający);74HC241(2x4bit, trój-stanowy,wjednejgrupiewyjścieaktywowanewysokimwdrugiejniskim);74HC244(2x4bit,trój-stanowy,wyjścieaktywowaneniskim);

Page 17: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

A0

B0

OE

DIR

An

Bn

...

dwukierunkowybufortrójstanowyOE==1&&DIR==0 => BdoAOE==1&&DIR==1 => AdoB

1 X1

3

A

2 X24Y

IN3

IN2

IN1

IN0

OUT1

OUT0

VALIDIN3

OUT0

OUT1

VALID

IN2

IN1

IN0

priority

encoder4to2

<=>

IN0

IN1

OE1

OE2

OUT0

OUT1

OUT2

OUT3

IN1

IN0

OUT1

OUT0decoder2to4

<=>OE1

OE2 OUT2

OUT3

jeżeliIN1,IN2traktowacjakoadres,to:-OE1możnatraktowaćjakosygnalpoprawnosci adresu(HAS_INPUTzencodera)-OE2możnatraktowaćjakolinietransmitujaca danedourzadzeniaopodanymadresie

decoder1to2IN0

OUT0

OUT1

A

X1

X2

Y<=>

multiplexer2to1

trueonlywhenusethisoutput

trueonlywhenusethisoutput

OUT0

OUT1

INPUTtrueonlywhenusethisoutput

trueonlywhenusethisoutput

OUT01 X1

3

A

2 X24Y

1 X13

A

2 X24Y

OUT1INPUT

demultiplekseropartyobufory3stanowe demultiplekseropartyomultipleksery

74HC245 (8bit, trój-stanowy, dwukierunkowy -wejście wyboru kierunku, wyjście aktywowaneniskim); 74HC367 (4bit + 2bit, trój-stanowy,wyjścieaktywowaneniskim);74HC540(8bit,trój-stanowy, wyjście aktywowane niskim, dwasygnałyaktywacji-AND,odwracający);74HC541(8bit, trój-stanowy, wyjście aktywowane niskim,dwa sygnały aktywacji - AND); 74HC7541 (8bit,trój-stanowy, wyjście aktywowane niskim, dwasygnały aktywacji - AND, wejścia Schmitta);74HC05 (6 bit, open-drain, odwracający);ULN2802A (8 bit, open-collector, odwracający,500mA);

enkodery

Enkoder "n to m" jest to układ o nwejściach, który na swoim m bitowymwyjściu wystawia numer (typowo)wejścia o najwyższym numerze, któreznajdujesięwstanieniskim.Możliwesąteż warianty wystawiające numerpierwszego (a nie ostatniego) wkolejności wejścia lub wybierającewejściezestanemwysokim.

Jako że wejścia numerowane sązazwyczaj od zera do 2m to układnajczęściej posiada dodatkowe wyjścieinformująceżektórekolwiekzwejśćjestw stanie aktywnym. Typowo numerwystawiany jest w postaci NKB, alemożliwesąinnekodowania.

Układ pozwala na redukcję ilości wejśćpotrzebnych do obsługi n-bitowegosygnału w którym tylko jeden bit możebyć ustawiony lub w którym możnapozwolićsobienaobsługękolejnychliniiz kasowaniem ich bitu (np. wektorprzerwańzpriorytetyzacją).

Przykłady:74HC148(8to3,priority,activelow);74HC147 (9 + "none" to 4 / 10 to 4, priority,activelow);

dekodery

Dekoder "m to n" jest układem odziałaniuprzeciwnymdoenkodera.Aktywujeonwyjścieonumerzeodpowiadającymwartościnam-bitowym wejściu adresowym. Typowo posiada także wejście zezwolenia na aktywację wyjść, któremoże zostać użyte do podłączenia informacji że którekolwiek z wejść enkodera było w stanieaktywnymlubdopodłączeniasygnałudanychzmultipleksowanejliniicelemjejdemultipleksacji.

Przykłady: 74HC138 (3 to 8, trzy wejścia zezwolenia, odwracający); 74HC238 (3 to 8, trzy wejścia zezwolenia,nieodwracający); 74HC137 (3 to 8 + zatrzask na adresie, odwracający); 74HC237 (3 to 8 + zatrzask na adresie,nieodwracający); 74HC259 (3 to 8 + zatrzask na wyniku, sygnał reset, nieodwracający); 74HC139 (2x "2 to 8", osobnewejściazezwolenia,nieodwracający);74HC154(4to16,dwawejściazezwolenia,odwracający);

(de)multiplekserycyfrowy

Multipleksercyfrowy(jednokierunkowy)nawyjściekopiujestanwskazanego(poprzezadrespodanyna wejście adresowe) wejścia. W przypadku braku sygnału "enable" w zależności od rozwiązaniawyjściepozostaniewstanieniskimlubwysokiejimpedancji.

Demultipleksercyfrowy(jednokierunkowy)tozazwyczajukładdekoderawktórymnawejścieenabledpodany jest sygnał z multipleksowanej linii. Nie wybrane wyjścia pozostają w stanie niskim lubwysokim (zależnie od użycia nieodwracającego lub odwracającego dekodera). Cyfrowedemultiplekseryz3stanowymwyjściemsąrzadkością.Demultipleksacjęmożnarozwiązaćtakżeprzypomocy odpowiednio sterowanych (np. z dekodera adresu) buforów trój-stanowych lub dwu-wejściowychmultiplekserów.

Przykłady:74HC151(1x"8to1",multipleksercyfrowyjednokierunkowy,wyjściaprosteizanegowane);74HC153(2x"4to1", multiplekser cyfrowy jednokierunkowy, wspólne wejścia adresowe); 74HC157 (4 x "2 to 1", multiplekser cyfrowyjednokierunkowy,wspólnewejściaadresowe);

Page 18: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

74HC251(1x"8to1",multipleksercyfrowyjednokierunkowy,wyjściatrój-stanoweprosteizanegowane);74HC253(2x"4to 1", multiplekser cyfrowy jednokierunkowy, wyjścia trój-stanowe, wspólne wejścia adresowe, osobne wejścia output-enable); 74HC257 (4 x "2 to 1",multiplekser cyfrowy jednokierunkowy,wyjścia trój-stanowe,wspólnewejścia adresowe ioutput-enable);74LVC1G18 (1 x "1 to 2", demultiplekser cyfrowy jednokierunkowy, wyjścia trój-stanowe, można zastąpić układempołączonych74HC1G125z74HC1G126);

(de)multiplekseryanalogowy

Multiplekser analogowy (dwukierunkowy) działa na zasadzie przełącznika łączącego wskazanewejście z wyjściem, dzięki elektrycznemu "zwarciu" (na ogół rezystancja takiego zwarcia tokilkadziesiątomów)wejściazwyjściemtransmisjamożeodbywaćsięwobukierunkach.Pozwalatotakżenawykorzystanietegosamegoukładuwrolimultiplekseraidemultipleksera.

Przykłady: 74HC4053 (3 x "2 to 1 / 1 to 2",multiplekser analogowy dwukierunkowy, osobnewejścia adresowe, wspólnewejście enable, trój-stanowy); 74HC4052 (2 x "4 to 1 / 1 to 4",multiplekser analogowy dwukierunkowy,wspólnewejściaadresowe ienable, trój-stanowy);74HC4051 (1x "8 to1 /1 to8",multiplekseranalogowydwukierunkowy, trój-stanowy);74HC4067(1x"16to1"/1to16",multiplekseranalogowydwukierunkowy,trój-stanowy);74HC4066 (4 x analog switch on-off, dwukierunkowy, osobne wejścia sterujące); 74HC1G66 (1x analog switch on-offdwukierunkowy);DG212B(4xanalogswitchon-off,dwukierunkowy,osobnewejściasterujące);

Mediumtransmisyjne

Mianem medium transmisyjnego określa się nośnik informacji służący do łączności pomiędzysystemami.Wyróżnićmożnanastępującemediatransmisyjne:

przewódelektryczny,m.in.:zwykłyprzewód,naogółwielożyłowy(tzw"taśmy",przewodytelefoniczne)kabeltypuskrętka(takżewróżnychwariantachekranowania)kabelwspółosiowy(koncentryczny)kabelsymetryczny"twin-lead"

światłowód:wielomodowyjednomodowy

bezprzewodowe(zarównoradiowejakioptyczne):dookolne(izotropowe)kierunkowe(wszczególnościoptycznelinielaserowe)

W przypadku przewodów typu skrętka stosowana jest transmisja różnicowa to znaczy informacjakodowana jest w różnicy napięć pomiędzy dwoma przewodami wchodzącymi w skład pojedynczejskręconejpary.Żadenzprzewodówwchodzącychwskładparyniejestpowiązanyzpotencjałemmasy,niema teżznaczeniaróżnicapotencjałupojedynczegoprzewoduwstosunkucodomasy (ważna jesttylko wzajemna różnica potencjałów), sygnał nadawany w jednym z nich jest w przeciw-fazie dosygnału nadawanego w drugim. Służy to eliminacji zakłóceń elektromagnetycznych (zakłócenieindukujesięwobuprzewodachjednakowo,więcróżnicanieulegazmianie)orazzakłóceńwzajemnych,przesłuchów (sumaryczny prąd płynący parą jest bliski zeru). Typowo linie takie korzystają zdedykowanychukładównadawczo-odbiorczychopartychnazasadziewzmacniaczaróżnicowego.

Połączeniaświatłowodowecharakteryzująsięm.in.:pełnąseparacjągalwaniczną(opto-izolacją)pomiędzyłączonymisystemamibardzodużąodpornościąnazakłóceniadużąprzepustowościąidużąprędkościątransmisjimożliwością bezpośredniej (bez stosowania wzmacniaczy umieszczonych w środku linii)transmisjinabardzodużeodległości

Topologiapołączeńitypytransmisji

Obokprzedstawionezostałygłównetopologiepołączeń:linearbus(magistrala)

wszystkie urządzenia są podłączone do jednej linii (wspólnego medium transmisyjnego),okablowanieniewyróżniapunktucentralnego

daisychainstruktura okablowania podobna jak w magistrali, ale medium transmisyjne jest podzielone(połączenienurządzeńskładasięzn-1łączypunkt-punktpomiędzyurządzeniami)

ring(pierścień)topologiadaisychainwktórejkońcesąpołączone,uodparniatonapojedynczeuszkodzenie

star(gwiazda)wszystkie podłączenia biorą początek w węźle centralnym, w zależności od konstrukcji węzła

Page 19: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

Dev#1

Linearbus

Dev#2 Dev#n...

Dev#1

DaisychainDev#2 Dev#n...

Dev#1

Dev#2

Dev#n

Central HUB

Star

...

Dev#1

RingDev#2 Dev#n...

Dev#1

Dev#2

Dev#4

Mesh

Dev#3

Dev#5

Dev#6

dekoderadresu

DANE/ADRES,n-bitów

Adres/NotDane

Read/NotWrite

Clock

kontrolermagistrali/master

1(TRUE)gdy

adreszgodny

DataOUT

WR

RD

sygnałyread(RD)iwrite(WR)wyrażonezpunktuwidzeniapodłączonegourządzenia: WR=zapisnamagistralę RD=odczytzmagistrali(częstoprzedstawianesazpunktuwidzeniamagistrali)

wprzypadkurozdzielonychliniidanychiadresu: -zamiastsygnału"Adres/NotData" jestm-bitowaszynaadresowa -dekoderadresuniekorzystazliniidanych tylkozszynyadresowej Da

taINŻądanieobsługi,i-bitów

Vcc

1

2

3

sygnał

przerwania

wybranyzestawbitówIRQ

ClockIN

centralnego może byćrealizowana w oparciu owspółdzielonemedium lubpołączeniapunkt-punkt

mesh(krata)każde urządzenie mabezpośrednie połączeniepunkt-punkt do każdegoinnego urządzenia(połączenie n urządzeńwymaga n(n-1)/2 połączeńpunktpunkt)

Ponadto występują topologiemieszane złożone z opisanychpowyżej: gwiazda wielokrotna(tzn. takagdzieniektórezwęzłówstanowiąpunktycentralnekolejnychgwiazd),magistrala lub ringpomiędzy punktami centralnymi gwiazd, gwiazda w której w węzłach występują magistrale lubpierścienie,itd.

Wyróżnićmożnatypytransmisji:simplex

umożliwiatylkotransmisjęjednokierunkowąhalf-duplex

umożliwiatransmisjędwukierunkową,aletylkowjednąstronęrównocześniefull-duplex

umożliwiapełnątransmisjędwukierunkową(równoczesnenadawanieiodbiór)

Magistralarównoległa

Magistrala równoległa jestzespołem linii, wraz zukładami nimi sterującymi,umożliwiającym równoległeprzesyłanie danych (wjednymczasie/takciezegarana magistrali wystawiane /przesyłane jest całe n-bitowesłowo). Można wyróżnićszyny sterującą (kierunekprzypływu, żądania obsługi,etc), adresową (adresukładuktóry ma prawo nadawać) idanych (przesyłane dane).Często szyna adresowawspółdzieli linietransmisyjnez szynądanych.Do realizacjimagistrali (celemumożliwiania podłączeniawielu układów) stosuje sięzazwyczaj bufory trój-stanowe, a do zapewnienia współdzielonej szyny żądania obsługi (interruptrequest)częstoukładytypuopen-collector.

Typowyukładrealizacjimagistralihalf-duplexzewspółdzielonymiliniamidanychiadresuprzestawionyzostałnaschemaciezamieszczonymobok.Zadaniem dekodera adresu jest ustalenie czy wystawiony na magistrali adres (w trakcie wysokiegostanulinii"Adres/NotDane")jestadresemdanegourządzeniaizapamiętanietejinformacjidoczasuwystawienia nowego adresu. Informacja ta jest wykorzystywana do sterowania dwukierunkowymbuforemtrój-stanowym(jakosygnałenable).O kierunku działania bufora decyduje sygnał "Read / Not Write". Przy magistralach o ustalonymprotokole transmisyjnym sterowanie kierunkiem może być zależne od wykonywanej komendy (poustawieniu adresu urządzenie odczytuje z magistrali polecenie i w zależności od niego sterujekierunkiembufora-odczytujelubzapisujedanenamagistralę).ZastosowaniekilkuliniitypuOCdoodbieraniażądańobsługipozwala(napodstawietegoktóreztychlinii znalazły się w stanie niskim na identyfikację urządzenia lub grupy urządzeń, z której niektórezgłaszajążądanieobsługi.

W przypadku prostych urządzeń wejścia / wyjścia zamiast buforu dwukierunkowego może byćumieszczony np. jednokierunkowy bufor (lub n-bitowy rejestr) z wyjściami trój-stanowymi, którywystawiadanenamagistralęwoparciuosygnałzapisunamagistralę(WR)orazzegar(clock)albon-

Page 20: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

dekoderadresu

DANE

Adres

Strobekontrolermagistrali/master

1(TRUE)gdyadreszgodny

rejestrprzesównyclkserial_in

Clock

buforwyjściowyclk

clkserial_in

clk

serial_out

rejestrprzesówny

buforwyjściowy

bitowyrejestrdoktóregozapisywanesądanezmagistraliwoparciuosygnałRDiClock.

Magistralaszeregowa

W magistrali szeregowej daneprzesyłane są bit po bicie wpojedynczej linii. Podobnie jak wmagistrali równoległej oprócz liniidanych mogą występować także liniesterujące. Prostą realizację magistraliszeregowej zapewniają rejestryprzesuwne.

Przykładowy układ realizacjimagistrali simplex (jednokierunkowej)z rozdzielonymi szynami danych iadresową został na schemaciezamieszczonymobok.W prezentowanym przykładzie opróczadresumasterwystawiatrzysygnały-dane,zegaristrobe.Zkażdymtaktemzegaranaliniidanychwystawianyjestkolejny bit który jest wczytywany dozespołurejestrów.Sygnałstrobesłużydoprzepisaniawartościzrejestrówprzesuwnychdorejestrówwyjściowych, takie rozwiązanie zapobiega zmianom wyjść w trakcie przesyłania nowych danychpoprzezszynęszeregową,jestonojednakopcjonalne.

Wzależności odkonstrukcji dekoderaadresu szynaadresowamożebyć równoległa (wnajprostszymprzypadku-przezcałątransmisjędodanegourządzeniajegoadresmusibyćwystawionynaszynieadekoder jestukładembramekNOTiwielowejściowejbramkiAND) lubszeregowa(wtakimwypadkupowinna posiadać własny zegar lub sygnał informujący o nadawaniu adresu z taktami zegaragłównego,adekoderpowinienbyćwyposażonywrejestrprzesuwnydoodebrania iprzechowywaniaaktualnego adresu z magistrali). Natomiast jeżeli magistrala byłaby oparta tylko na połączonychszeregoworejestrach(wyjścieserial-outdowejściaserial-in)toszynaadresowaniejestpotrzebna,alekoniecznemożebyćkażdorazowewpisaniewszystkichwartościnaszynę(czaszapisurośniezilościąpodłączonychrejestrów).

Standardoweinterfejsy

Istnieje wiele zestandaryzowanych interfejsów zarówno szeregowych jak i równoległych, wśródnajważniejszychnależywymienić:SPI(SerialPeripheralInterface)

jest to szeregowa magistrala full-duplex działająca w układzie master-slave złożona z liniizegarowej (SCLK), nadawania przez mastera (MOSI), odbioru przez mastera (MISO) oraz liniisłużącychdoaktywacjiurządzeniaslave(SS/CS).

I2C(TWI)jest to szeregowa magistrala half-duplex złożona z linii sygnałowej (SDA) i zegara (SCL)posiadającazdefiniowanyformatramkiwrazzadresowaniem.Zwyjątkiembitustartuistopustanliniidanychmożezmieniaćsię tylkoprzyniskimstanie liniizegarowej.Nadajnikisą typuopen-drainprzezcorealizowanyjest iloczynnadrucie,copozwalanawykrywaniekolizji (jeżelidanynadajniknienadajezeraaliniajestwstaniezeratonadajetakżektośinny).Pozwalatotakżenauzyskanie układów multimaster, pomimo iż typowo na magistrali takiej występuje tylko jedenukładmaster(nadającysygnałzegaraiinicjującytransmisję).

1wire(one-wire)jest to szeregowamagistralahalf-duplex złożona z jedynie z linii sygnałowej (któramoże takżesłużyć do zasilania urządzeń) posiadająca zdefiniowany format ramki wraz z adresowaniem.Standardowenadawaniejestrealizowanejakoopen-drain(wyjątkiemjestnadawanietzwpower-byte).

USARTjest to uniwersalny synchroniczny i asynchroniczny nadajnik i odbiornik, umożliwia realizacjęszeregowej transmisji synchronicznej (zgodnie z zegarem) lub asynchronicznej (wykrywaniepoczątku ramki na podstawie linii danych). Interfejs korzysta z rozdzielonych linii nadajnika iodbiornika(wyjściedanychTxDorazwejściedanychRxD,coumożliwiarealizacjętransmisjifull-duplex) oraz może korzystać z dodatkowych sygnałów sterujących (wyjście RTS informujące ogotowości do odbioru oraz wejście CTS informacji o gotowości odbioru / zezwolenia nanadawanie).Niekiedydostępnejesttakżewyjściezałączenianadajnikaużywanedopracywtrybiehalf-duplex(linieTxDiRxDpołączonebuforemtrój-stanowymnadajnika).

Interfejs ten najczęściej wykorzystywany jest w trybie asynchronicznym jako UART. WpołączeniachUARTzarównonadajnikjakiodbiornikmusząmiećustawionetakiesameparametry

Page 21: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

transmisji(szybkość,znaczenie9bitu(typowobitparzystości,alemożetakżeoznaczaćnp.poleadresowe), itp). Głównymi standardami elektrycznymi dla UART są: poziomy napięć układówelektronicznych używających tych portów (3.3V, 5V), RS-232 (w pełnym wariancie używasygnałówkontroliprzepływu,poziomlogiczny1wynosiod -15Vdo -3V,apoziomlogiczny0od+3V do +15V), RS-422 (transmisja różnicowa full-duplex pomiędzy dwoma urządzeniami) i RS-485 (transmisja różnicowahalf-duplexwoparciuo szynę łączącąwieleurządzeń, kompatybilnyelektryczniezRS-422),możliwiajestteżtransmisjaświatłowodowaibezprzewodowa.

CANjest to dwu przewodowa magistrala multi-master działająca na zasadzie rozgłoszeniowej,obsługująca11-tolub29-bitoweidentyfikatorykomunikatów(niesątoadresyodbiorców),bazujenaniejwieleprotokołówkomunikacyjnych(np.CANopen).

Ethernetjest to interfejs szeregowy przeznaczony dla sieci komputerowych, występuje w różnychodmianach od których zależy wykorzystywane medium transmisyjne oraz topologia połączeń.Posiadaustalonyformatramki(niezależnyododmiany)wrazzadresacją(ramkazawierazarównoMACadresnadawcy,jakiodbiorcy).

W przypadku połączeń przewodowych (zarówno elektrycznych jak i optycznych) najczęściejstosowane są połączenia punkt-punkt w topologii gwiazdy, można się także spotkać z układemtypuring.Pętlewtopologiifizycznejsązabronioneiwprzypadkuichwystąpieniakoniecznejeststosowanieprotokołuichwykrywaniairozłączania(dotyczytotakżepołączeniatypuring).

Typowo połączenia fizyczne realizowane są z wykorzystaniem switchy odpowiedzialnych zaprzesyłanierameknaodpowiednieportywoparciuoadresyMAC.Wtymceluswitchpamiętazktórego portu przychodzą ramki z danym adresem źródłowym i tam wysyła ramki z takimadresemdocelowym, jeżeliswitchnieposiada informacjigdziewysłaćdanąramkęwysyła jąnawszystkieswojeporty.

ISAmagistralarównoległastworzonadlaarchitekturyPC(x86),początkowoz8-bitowąszynądanychiniezależną 20 bitową szyną adresową, następnie rozszerzona do 16 bitowej szyny danych i 24bitowejszynyadresowej,wariancie16bitowymtaktowanazegarem8Mhz(wcześniej4.77Mhz,anastępnie6Mhz).W skład magistrali wchodzą m.in. następujące sygnały sterujące związane z szyną adresową iszynądanych:

ALE-poleceniezatrzaśnięciaadresu/adrespoprawny(wystawianeprzezCPU)IOR/IOW-odczyt/zapiswprzestrzeniIO(2osobnesygnaływystawianeprzezCPU)MEMR/MEMW-odczyt/zapiswprzestrzenipamięci(2osobnesygnały,wystawianeprzezCPU)IOCHRDY-rządanieopóźnieniawobsłudzeodczytu/zapisu(wystawianeprzezkartę)IOCS16/MEMCS16-informacjaoobsłudzewtrybie16bitowym(wystawianeprzezkartę)DRQ*,DACK*,AEN,TC-sygnałyDMA

Ponadto złącze magistrali zapewnia dostęp do 6 (w podstawowej 62 stykowej części złącza) +dodatkowych 5 (w rozszerzającej do 16 bitów 36 stykowej części złącza) linii przerwań IRQ*,sygnału MASTER pozwalającego na przejęcie sterowania nad systemem przez procesorumieszczonynakarcie oraznapięć zasilających+12V, -12V,+5V, -5V, kilku liniimasy (GND) izegarasystemowegoorazzegarasynchronizowanegozzegaremprocesora.

Magistrala (w innej postaci złącza) obecna jest także w standardzie PC/104. Standard EISAokreślarozszerzoną,kompatybilnąwdół(takżepodwzględemgniazda),wersjęz32bitowąszynądanych.

PCImagistralarównoległawystępującawodmianie32i64bitowej,kilkasygnałówzwiązanychz arbitrażem prowadzonych jest do każdego gniazda / urządzenia PCI bezpośrednio zkontroleramagistrali,linie przerwań są poprzeplatane między slotami, specyfikacja dopuszcza też przerwaniasygnalizowanewramachkomunikatu(przesyłanegoszynądanych);stosowanie mostków PCI pozwala na rozgałęzianie / łączenie magistrali (zarównoszeregowojakirównolegle);często spotykane są karty PCI o niepełnych wymiarach (prawie zawsze krótsze odmaksymalnej dopuszczalnej długości, często także niższe), magistrala PCI jest takżespotykanawramachinnychtypówzłącz-takichjakMini-PCI,czyPCMCIA

PCIExpressszeregowy interfejs różnicowy full-duplex do połączeń punkt-punkt, w zależności od

Page 22: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

wariantuzłożonyz1,4,8lub16zestawówparnadawaniaiodbioru;stosowanie mostków pozwala na rozgałęzianie / łączenie magistrali oraz np. podłączanieklasycznychmagistralPCI;standardowe złącze zapewnia także m.in. sygnał zegara referencyjnego, resetu, sygnałySMBus(I2C);standardwystępujenakilku rodzajachzłącz (oprócz standardowego) takżem.in.miniPCIExpress,SATAExpress,M.2,Thunderbolt/USB-C.

IDE,ATA,P-ATAwywodzącysięzmagistraliISAstandardsłużącyzapewnieniukomunikacjizurządzeniamipamięcimasowejtakimijakdyskitwarde,czynapędyoptyczne;określatakżepełnyprotokółkomunikacjizurządzeniami;stosowanytakże(zniewielkimizmianami)wkartachCompactFlash.

SATAszeregowy interfejs różnicowy full-duplexdopołączeńpunkt-punkt, złożony z jednejparynadawczej,jednejparyodbiorczejorazliniiGND;służący do podłączania urządzeń pamięci masowej takich jak dyski twarde, czy napędyoptyczne;standardSATAokreślatakżepełnyprotokółkomunikacjizurządzeniami;standard występuje na kilku rodzajach złącz - oprócz standardowego także m.in. eSATA(zewnętrzne),mSATA,SATAExpress,M.2.

USBszeregowy interfejs różnicowy half-duplex do połączeń punkt-punkt posiadający (wwersjachdo2.0włącznie)jednąparęużywanazarównodonadawaniajakiodbioru;pozwalanatworzenietopologiigwiazdyzwykorzystaniemhub'ówUSB;stosujekilkarodzajówzłączorazwystępujewramachzłączinnychstandardów(np.wM.2).

TMDS,HDMI,DVITMDS jest standardem jednokierunkowej różnicowej transmisji szeregowej, stosowany winterfejsachHDMIiDVI-D;korzystazosobnejparyróżnicowejdlakażdegokoloruskładowegoRGB(lubYCbCr)orazosobnejparydladanychzegarowych;pomocniczo (dla dwukierunkowego przekazywania parametrów kontrolnych/sterującychzwiązanych z trybem wyświetlania) wykorzystywany jest także dwuprzewodowy interfejsDDCopartynaI2C;danewkanałachTMDSprzesyłanesąwpostaci (zakodowanychprzypomocy8b/10b)10bitowychciągów,któremogąbyć interpretowane jako8bitowawartośćkoloru,2bitowawartość sterująca (na kanale zerowym wykorzystywane do synchronizacji poziomej ipionowej);złącze DVI pozwala na przesyłanie dwóch kanałów cyfrowego wideo (6 kanałów TMDS)oraz przesyłanie analogowego sygnału VGA (RGB, Hsync, Vsync), standard DVI zakładawykorzystaniełączTMDSdoprzesyłaniawyłącznieobrazuRGB;standardHDMIpozwalanaprzesyłaniezużyciemTMDSobrazuRGBabloYCbCr,ponadtostandard HDMI korzystając z bitów sterujących transmisji TMDS i kodowania 4b/10pozwala na przesyłanie poprzez TMDS dźwięku oraz danych sterujących CEC, ponadtozłączeHDMIpozwalanaprzesyłanie (osobnąparą) zwrotnegosygnałuaudio lub sygnałuEthernetowego;

DisplayPortinterfejs złożony z 1 do 4 szybkich jednokierunkowych kanałów różnicowej transmisjipakietowejoraz1dwukierunkowegokanałupomocniczego(takżeztransmisjąróżnicową)wersja"Dual-mode"(DisplayPort++)pozwalanaprzesyłaniesygnałówzgodnychzHDMI/jednokanałowymDVI-DwystępujetakżewzłączuThunderbolt/USB-C

UkładyprogramowalneUkładyprogramowalnemożnapodzielićnadwarodzaje:układyoprogramowalnejstrukturze(PLD)

toukładywktórychprogramowanyjestukładbramek,przerzutników,itp."umieszczanych"wkościorazichpołączeń.Programdla takichukładów tworzony jestwHardwareDescriptionLanguage (najczęściejVHDLlub Verilog) i zamiast wykonywanego kodu opisuje strukturę układu logicznego (połączenia

Page 23: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

bramek,tabliceprawdy,etc),któranastępniejestprogramowanawfizycznejkości.

Najprostszym przykładem układu o programowalnej strukturze logicznej jest układ pamięci 2n

bitowejzn-bitowąszynąadresowąadresującąpojedynczebity-pozwalaonnarealizacjędowolnejfunkcjilogicznejonwejściachipojedynczymwyjściu.

Dokategoriitejzaliczająsięukładytypu:SPLD

PLE-programowalnamatrycabramekORPALiGAL-programowalnamatrycaANDzdodatkowymibramkamiOR(częstotakżeobudowanarejestramiimultiplekseraminawyjściach)PLA-programowalnematryceANDiOR

CPLDFPGA-programowalnyelementpamięciowy(możliwośćzdefiniowaniadowolnej-naogół4wejściowej - funkcji w każdym elemencie logicznym, programowalne połączenia międzyelementamilogicznymiipinami,itd)

systemyprocesorowetosystemyrealizująceciąginstrukcjipobieranychzjakiejśpamięci.System taki składa się z procesora odpowiedzialnego za interpretację i wykonywanie kolejnychinstrukcjiorazpamięcizktórejpobieranesąinstrukcjeidane(możetobyćjednapamięć,mogątobyć rozdzielone pamięci). Do kategorii tej zaliczają się zarówno typowe systemy komputerowe,systemyobliczeniowejakiróżnegorodzajuprogramowalnemikrokontrolery.

Procesor pracuje w cyklach rozkazowych, w ramach których przetwarza pojedynczą instrukcję.Cykltakimożetrwaćod1dokilkulubwięcejcyklizegarowychitypowoskładasięznastępującychkroków:

1. pobranie instrukcji z pamięci - realizowane jest poprzez wystawienie na szynę adresowązawartości licznika programu (zawierające adres instrukcji do wykonania) orazwygenerowanie cyklu odczytu z pamięci, po wykonaniu odczytu danych następuje ichzapamiętaniewrejestrzeinstrukcjiorazzwiększeniewartościlicznikaprogramuojeden;(zawartość rejestru licznikaprogramu po resecieprocesoraokreśla skądpobieranabędziepierwszainstrukcja,podtakimadresemzazwyczajumieszczanajestjakaśpamięćtypuROMlubflash)

2. dekodowanie instrukcji - układ dekodera (np. oparty o PLA) dokonuje zdekodowaniainstrukcji znajdującej sięwrejestrze instrukcji ikonfiguracjiprocesorawzależnościod jejkodui(opcjonalnie)jejargumentów;możetobyćnp.:

odpowiednie ustawienie multiplekserów pomiędzy rejestrami a jednostką ALU orazwystawienie odpowiedniego kod operacji dla ALU (celem wykonania operacjiarytmetycznejnawartościachrejestrów)wystawienie zawartości wskazanego rejestru na szynę adresową, podłączeniewskazanego rejestru do szyny danych oraz skonfigurowanie operacji odczytu/zapisu(celemwykonaniaodczytulubzapisuwartościrejestruz/dopamięci)

3. wykonanie instrukcji - realizacja wcześniej zdekodowanej instrukcji zgodnie z ustawionąkonfiguracjąprocesora

Instrukcje skoku polegają na załadowaniu nowej wartości do licznika programu, w przypadkuskokówwarunkowych jest touzależnioneod stanu rejestru flag, któreustawiane sąwoparciuowynikostatniejoperacjiwykonywanejprzezALU.Przedstawionymodeldziałaniajestprzykładowymiwrzeczywistymprocesorzemożetowyglądaćodmiennie-np.długośćinstrukcjimożebyćwiększaniżdługośćsłowaużywanegoprzezprocesor/szerokość szyny danych co rozbudowuje fazę pobierania instrukcji z pamięci, mogą występowaćinstrukcjebardziejzłożone(np.operacjewykonywanezargumentempobieranymzpamięcianierejestru),możetakżewystępowaćwięcejfaz(np.poprzezwydzieleniefazdostępudopamięci,czyzapisywaniawynikówdziałania instrukcji).Procesormoże takżedziałaćpotokowo,czylinakładaćnasiebiekolejnefazywykonywaniaróżnychinstrukcji(np.wczasiewykonywaniajednejinstrukcjirealizowaćpobieraniekolejnej).

Mikrokontrolery

Mikrokontrolerjestukłademtypu"SystemonChip"zawierającymwjednymukładzieprocesor,pamięćRAM, układy wejścia-wyjścia (np. GPIO, porty szeregowe typu USART, SPI, I2C, przetworniki ADC),pamięćtypuFlash(dlaprogramu).

Przykłady:ATmega8A(ADC(6-8ch),3xTimer,I2C,USART,SPI,28-32pin,8kBFlash,1kBRAM,8bit,16MHz),STM32F072V8(1xADC(12ch),1xDAC(2ch),12xTimer,2xI2C,4xUSART,2xSPI,CAN,USB,100pin,64kBFlash,16kBRAM,32bit,48MHz),STM32F103VC(3xADC(21ch),2xDAC,11xTimer,2xI2C,5xUSART,3xSPI,CAN,USB,100pin,256kBFlash,48kBRAM,32bit,72MHz)iwieleinnych

Page 24: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

ProgramowanieZagadnieniasą ilustrowaneprzykładowymikodamiwjednymlubkilkuzpośródnastępujących języków:C++(niekiedyzpodziałemnapodejściewstyluCiwstyluC++),Python,Bash,PHPiJavaScript.Wybórtakiegozbiorujęzykówwynikazodmiennychcechkażdegoznich:

C++/Csąnajpopularniejszymijęzykamikompilowanymidokodumaszynowego(ajeżelitraktowaćje łącznie to najpopularniejszymi językami w ogóle), pozwalają na stosowanie niskopoziomowychmechanizmów (łącznie z wstawkami asemblerowymi), są użyteczne do bezpośredniegoprogramowania sprzętu (bez warstwy systemu operacyjnego) czy też tworzenia systemówoperacyjnychPython -najpopularniejszy język skryptowy,wygodny (wmiarę łatwy / szybki)wpisaniu i nauce,oferujebardzowielegotowychbibliotek,pozwalanadośćprostąintegracjęzkodemC/C++Bash - najpopularniejsza powłoka tekstowa, stanowiąca jednocześnie (specyficzny) językprogramowaniaPHP-popularnyiwygodnyjęzykdotworzeniaserwisówwwwJavaScript-najpopularniejszyjęzykskryptowydlaWWW,elementHTML5

Ponadto każdy z tych języków wykorzystywany jest w wielu projektach (od jądra Linuxa do systemuMediaWiki)iichprzynajmniejzgrubnaznajomośćmożeokazaćsięprzydatna.

Język C++ oraz C są językami kompilowalnymi to znaczy (po zmodyfikowaniu źródeł) przeduruchomieniemprogramukoniecznejestdokonanietłumaczeniakoduźródłowegonakodmaszynowyprzypomocyodpowiedniegoprogramu(np.clang++ lubg++).KompilacjaC iC++przebiegakilkuetapowo.Wpierwszej kolejności wywoływany jest preprocesor, który jest odpowiedzialny za włączanie plikówokreślonychpoprzez#include (jestto literalnewłączeniezawartościwskazanegoplikuwdanymmiejscu,obsługę rozwijania stałych makr preprocesora (definiowanych z użyciem #define) oraz kompilacjęwarunkowązwykorzystaniempoleceńtakich jak#ifdefczy#if.Kompilatorypozwalająnauzyskanienietylko wynikowego pliku binarnego, ale także plików po przetworzeniu przez preprocesor czy też pokonwersjinaassembler.

Python,BashiPHPsąjęzykamiinterpretowanymi,czyliuruchamianiupodlegabezpośredniokodźródłowyktóry jest analizowany i wykonywany przez interpreter danego języka. Mogą one uruchamiać kod zpodanegoplikulubinteraktywniewprowadzanywkonsoliinterpretera.Kodwprowadzanyinteraktywniemoże być wykonywany bezpośrednio po jego wprowadzeniu (tzn. wprowadzeniu znaku nowej linii, a wprzypadku bloków instrukcji - zakończenia takiego bloku). W Bashu i Pythonie jest to zachowaniedomyślne,natomiastwprzypadkuPHPwymagapodaniaopcji-a (jejpodaniezakładażepodawanykodjest tylko częścią ujętą w <?php i ?>, bez tej opcji kod zostanie zinterpretowany i wykonany dopiero powczytaniuznakukońcapliku,którymożnawprowadzićCtrl+D).

Zarównokompilatoryjakiinterpreterymogągenerowaćbłędylubostrzeżeniadotycząceprzetwarzanegokodu,przyjegopoprawianiuważnejestichczytaniezpróbązrozumienia(niekiedypotrafiąbyćdziwneiodnosićsięniedotegocojestprzyczynąproblemu).Rozwiązującproblemnależyskupićsięnapierwszymbłędzie,gdyżkolejnemogąbyćjegowynikiem(jesttoszczególnieważnewprzypadkukompilacjiC++/C,gdzie możemy uzyskać bardzo wiele błędów). Programy mogą także generować błędy typu "run timeerror" w trakcie działania, przykładami takich błędów są rzucane i nie obsługiwane wyjątki oraz błędyzwiązanezodwołaniamidopamięci (np.przekroczeniemzakresutablicywC)komunikowanezazwyczajjako"Segmentationfault".

Pamięćdanych-zmienneWszelkiedanenaktórychoperujeprogramkomputerowyprzechowywanesąwjakimśrodzajupamięci-najczęściej jest topamięćoperacyjna.Wpewnychsytuacjachniektóredanemogąbyćprzechowywanenp.tylkowrejestrachprocesoralubrejestrachurządzeńwejścia-wyjścia.

Wprogramowaniunapoziomiewyższymodkodumaszynowegoiasembleraużywasiępojęciazmienneji(niemal zawsze) pozostawia kompilatorowi/interpretatorowi decyzję o tym gdzie ona jestprzechowywana.Oczywistymwyjątkiemsągrupyzmiennych,czyteżbuforyalokowanewsposóbjawnywpamięci.Zewzględunaograniczonąliczbęrejestrówprocesorawiększośćzmiennych(wszczególnościtychdłużej istniejącychiwiększych)będzieznajdowałasięwpamięci ibędąprzenoszonedorejestrówcelemwykonaniajakiśoperacjinanichpoczymwynikbędzieprzenoszonydopamięci.

Zkażdązmiennąprzechowywanąwpamięcizwiązanyjestadrespamięcipodktórymsięonaznajduje.Niektóre z języków programowania pozwalają na odwoływanie się do niego poprzez wskaźnik nazmienną lubreferencjędozmiennej (odwołaniadoadresuzmiennejmogąwymusićumieszczenie jejwpamięcinawetgdybynormalnieznajdowałasiętylkowrejestrzeprocesora).

Wszystkiedanesązapisywanewpostaciliczblubciągówliczb.Typzmiennej(jawnylubnie)informujeotymjakiejdługościjestdanaliczbaijaknależyjąinterpretować(jaknależyinterpretowaćciągliczb).

Page 25: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

intmain(){ //liczbacałkowitazeznakiem intliczbaA=-34; //liczbarzeczywista(pojedynczejprecyzji) floatliczbaB=673.1; //8bitowaliczbacałkowitabezznaku uint8_tliczbaC=0xf3; //zmiennanapisowa"CNULL-endstring" char*napisA="qwe"; //zmiennanapisowatypu"C++string" std::stringnapisB="abc";}

#dynamicznetypowanie-typokreślanyjest#napodstawiewartościzapisywanejdozmiennej

zmiennaA=-91.7zmiennaB="qaz"

#dynamicznetypowanie-typokreślanyjest#napodstawiewartościznajdującejsięwzmiennej##zasadniczowszystkiezmiennesąnapisami,ainterpretacja#mamiejsceprzyichużyciuanieprzytworzeniu

#obsługiwaneliczbycałkowiteoraznapisy#brakobsługiliczbzmiennoprzecinkowych##brakspacjipomiędzynazwązmiennejaznakiemrówności#woperacjiprzypisaniajestwymogiemskładniowym

zmiennaA=-91zmiennaB="qaz"zmiennaC=98.6#tobędzietraktowanejakonapisanieliczba

<?php

#dynamicznetypowanie-typokreślanyjest#napodstawiewartościzapisywanejdozmiennej

$zmiennaA=-91.7$zmiennaB="qaz"

?>

vara=13.3varb="qaz"

Kodprogramu-instrukcje,...Program komputerowy składa się z instrukcji wykonywanych kolejno przez procesor. Instrukcje temożnapodzielićna:

instrukcjeprzenoszeniadanych(m.in.pomiędzypamięciąirejestramiprocesora),instrukcjemodyfikującedane(wykonującenanichjakieśoperacjearytmetyczne,logiczneitp.),instrukcjęmodyfikującesterowaniewprogramie.

Dwie pierwsze kategorie instrukcji odpowiadają za modyfikowanie wartości zmiennej na skutekprzypisań wartości oraz operacji wykonywanych na zmiennych. Trzecia kategoria to instrukcjeodpowiedzialnezawarunkowelubbezwarunkowemodyfikowanielicznikprogramu.Mogąwystępowaćtakże instrukcjezłożonerealizującezadaniaz różnychgrupwramach jednej instrukcji (np. instrukcjewykonywanewarunkowo).

Podstawoweoperacjearytmetyczne,bitoweilogiczne

Z punktu widzenia procesora (kodu maszynowego) podstawowymi operacjami wykonywanymi nadanych(opróczprzenoszenia)sątypoweoperacjearytmetyczneilogiczneorazoperacjebinarne.Wiele

///PrzykładC++

###PrzykładPython

###PrzykładBash

///PrzykładPHP

///PrzykładJavaScript

Page 26: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

architekturposiada także bardziej złożone instrukcje (np.wykonywane niena pojedynczych liczba acałychwektorachliczblubteżwykonującychjakąśbardziejzłożonąoperacjęmatematycznąwsposóbsprzętowy),któreodgrywająistotnąrolęwoptymalizacjikodunadanąarchitekturę.

Zpunktuwidzeniajęzykówprogramowanianajczęściejzapodstawoweoperacjeuważasię:operacje arytmetyczne: dodawanie, odejmowanie, mnożenie, dzielenie całkowite, dzieleniezmiennoprzecinkowe,obliczanieresztyzdzielenia,niekiedypodnoszeniedopotęgioperacje logiczne: AND, OR, NOT, niekiedy XOR, porównania (równość, nierówność, większe,mniejsze,większerówne,mniejszerówne)operacjebitowe(wykonywaneniezależnienakażdymbicieargumentów):AND,OR,NOT,XOR,przesunięciabitowe

Dośćistotnymwyjątkiemsąniektórejęzykiskryptowe(takiejakbash),którychgłównymzadaniemjesturuchamianieinnychprogramówitojestoperacjąpodstawowąwtychjęzykach.

#include<stdio.h>

intmain(){ doublea=12.7,b=3,c,d,e; intx=5,y=6,z; //dodawanie,mnożenie,odejmowaniezapisujesię //idziałająonetakjakwnormalnejmatematyce: e=(a+b)*4-y; //dzieleniezależyodtypówargumentów d=a/b;//będziedzieleniemzmiennoprzecinkowymboaibsątypufloat c=x/y;//będziedzieleniemcałkowitymboziysązmiennymitypuint b=(int)a/(int)b;//będziedzieleniemcałkowitym a=(double)x/(double)y;//będziedzieleniemzmiennoprzecinkowym //resztazdzielenia(tylkodlaargumentówcałkowitych) z=x%y; //wypisaniewyników printf("%d%f%f%f%f%f\n",z,e,d,c,b,a); //operacjelogiczne: //((awiększerówneod0)AND(bmniejszeod2))OR(zrówne5) z=(a>=0&&b<2)||z==5; //negacjalogicznaz x=!z; printf("%d%d\n",z,x); //operacjebinarne: //bitowyOR0x0fz0x11iprzesunięciewynikuo1wlewo x=(0x0f|0x11)<<1; //bitowyXOR0x0fz0x11 y=(0x0f^0x11); //negacjabitowawynikubitowegoAND0xfffi0x0f0 z=~(0xfff&0x0f0); printf("%x%x%x\n",x,y,z); //uwaga:powyższyprogrammożeniewykonywaćobliczeńwczasiedziałania //zewzględunaoptymalizacjęifaktiżwynikiwszystkichoperacji //sąznanewmomenciekompilacjiprogramu}

a=12.7b=3x=5y=6

#dodawanie,mnożenie,odejmowaniezapisujesię#idziałająonetakjakwnormalnejmatematyce:e=(a+b)*4-y

#dzieleniezmiennoprzecinkowec=x/y

#dzieleniecałkowite

///PrzykładC++

###PrzykładPython

Page 27: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

b=a//b

#resztazdzieleniaz=x%y;

#wypisaniewynikówprint(e,c,b,z)

#operacjelogiczne:#((awiększerówneod0)AND(bmniejszeod2))OR(zrówne5)z=(a>=0andb<2)orz==5;#negacjalogicznazx=notz;

print(z,x);

#operacjebinarne:#bitowyOR0x0fz0x11iprzesunięciewynikuo1wlewox=(0x0f|0x11)<<1;#bitowyXOR0x0fz0x11y=(0x0f^0x11);#negacjabitowawynikubitowegoAND0xfffi0x0f0z=~(0xfff&0x0f0);

print(hex(x),hex(y),hex(z&0xffff));#wypisujączmusimyokreślićjegobitowość

#wieloargumentowaoperacjaprzypisania#możebyćużytadozamianywartościpomiędzydwomazmiennymi#bezjawnegoużywaniazmiennejtymczasowejprint(a,b)a,b=b,aprint(a,b)#oczywiściemożnawjejramachużywaćwięcejniżdwóchzmiennych

a=12;b=3;x=5;y=6

#abywykonaćdziałaniaarytmetycznenależy#umieścićjewewnątrz$((i))

#dodawanie,mnożenie,odejmowaniezapisujesię#idziałająonetakjakwnormalnejmatematyce:e=$((($a+$b)*4-$y))

#dzieleniecałkowitec=$(($x/$y))

#wypisaniewyników#(zwróćuwagęnawynikwypisanianiezainicjalizowanejzmiennejz)echo$e$c$z

#operacjelogiczneobsługiwanesąkomendątest#luboperatorem[]wynikzwracanyjestjakokodpowrotu#należyzwrócićuwagęnaescapowanieodwrotnymukośnikiem#nawiasówinatożespacjemająznaczenie

#((awiększerówneodzera)AND(bmniejszeoddwóch))OR(zrówne5)[\($a-ge0-a$b-lt2\)-o$z-eq5];z=$?

#negacjęrealizuje!,alewynikiemnegacjądowolnejliczbyjestFALSE#więcniedasięzanegowaćzjakwpozostałychprzykładach

echo$z#bashstosujelogikęodwróconą0==TRUE,cośniezerowegotoFALSE

#bashnieobsługujeliczbzmiennoprzecinkowychanioperacjibitowych#nieobsługiwaneoperacjemożnawykonaćzapomocąinnegoprogramunp:a=`echo'print(3/2)'|python3`b=$(echo'3/2'|bc-l)echo$a$b

#ujęciepoleceniawznaki`powodujepodstawieniewtymmiejscu#standardowegowyjściategopolecenia(wtymwypadkuzapisaniago#dozmiennej),alternatywnąskładniąjest$(polecenie)#pokazanynaprzykładziezmiennejb

###PrzykładBash

Page 28: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

vara=12.7,b=3,c=13,d,e;

//dodawanie,mnożenie,odejmowaniezapisujesię//idziałająonetakjakwnormalnejmatematyce:e=(a+b)*4-c;

//dzieleniezawszejestzmiennoprzecinkowed=a/b;c=b/c;

//wypisaniewynikówconsole.log( "e="+e+"\n"+ "d="+d+"\n"+ "c="+c+"\n");

//operacjelogiczne://((awiększerówneod0)AND(bmniejszeod2))OR(crówne5)varz=(a>=0&&b<2)||c==5;//negacjalogicznaza=!z;

console.log( "z="+z+"\n"+ "a="+a+"\n");

//operacjebinarne: //bitowyOR0x0fz0x11iprzesunięciewynikuo1wlewo a=(0x0f|0x11)<<1; //bitowyXOR0x0fz0x11 b=(0x0f^0x11); //negacjabitowawynikubitowegoAND0xfffi0x0f0 c=~(0xfff&0x0f0);console.log( "a=0x"+a.toString(16)+"\n"+ "b=0x"+b.toString(16)+"\n"+ "c=0x"+(c&0xffff).toString(16)+"\n");

Przepływsterowaniawprogramie-skoki,warunki,pętle,funkcje

Licznikprogramu(programcounter,instructionpointerlubinstructionaddressregister)jestrejestremprocesora który określa adres następnej (w niektórych architekturach aktualnej) instrukcji która mazostaćprzetworzonaprocesor.

Skoki bezwarunkowe, instrukcje warunkowe, pętle, wywołania funkcji są realizowane poprzezmodyfikację licznika programu. W przypadku wywołań funkcji dodatkowo wykonywane są operacjezwiązanezobsługąstosu(zachowywaniemstanurejestrów,umieszczaniemargumentównastosie,...).Instrukcja goto (realizująca skok bezwarunkowy) jest pełnoprawną instrukcją skoku, jedyną wadą jejstosowania jest to że przy niewłaściwym / zbyt częstym wykorzystywaniu (zamiast wywołań funkcji,warunkówipętli)kodprogramustajesięmniejczytelny.

Wwiększościprzypadkówpętlerealizowanesąnapoziomiekodumaszynowegojakozestawinstrukcji(np. inkrementacji zmiennej, sprawdzaniawarunku, skoku), jednakwniektórychrozwiązaniachpętle(np.typu"powtórznrazy")mogąbyćrealizowanesprzętowoprzypomocypojedynczejinstrukcji.

#include<stdio.h>

intmain(){ inti,j,k; //instrukcjawaunkowaif-else if(i<j){ puts("i<j"); }elseif(j<k){ puts("i>=jANDj<k"); }else{ puts("i>=jANDj>=k"); }

///PrzykładJavaScript

///PrzykładC++

Page 29: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

//podstawoweoperatorylogiczne if(i<j||j<k) puts("i<jORj<k"); //innymioperatoramilogicznymisą&&(AND),!(NOT) //pętlafor for(i=2;i<=9;++i){ if(i==3){ //pominięcietegokrokupętli continue; } if(i==7){ //wyjściezpętli break; } printf("a:%d\n",i); } //pętlawhile while(i>0){ printf("b:%d\n",--i); } //pętlado-while do{ printf("c:%d\n",++i); }while(i<2); //instrukcjawyboruswitch switch(i){ case1: puts("i==1"); break; default: puts("i!=1"); break; } gotoETYKIETA; puts("tosięnigdyniewykona"); puts("bowcześniejrobimybezwarunkowegoto"); ETYKIETA: puts("atosięwykona");}

i=k=j=0

#instrukcjawaunkowaif-elseifi<j: print("i<j")elifj<k: print("i>=jANDj<k")else: print("i>=jANDj>=k")

#podstawoweoperatorylogiczneif(i<jorj<k) puts("i<jORj<k");#innymioperatoramilogicznymisąandoraznot

#pętlaforforiinrange(2,9): ifi==3: #pominięcietegokrokupętli continue; ifi==7: #wyjściezpętli break; print("a:",i);else: #niewejdzietutajbopętlakończy #sięzużyciembreak print("elsewpętli");

###PrzykładPython

Page 30: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

#pętlawhilewhilei>0: i=i-1; print("b:",i);else: #wejdzietugdywaruneki>0 #niebędziespełniony #zarównoprzypierwszym #jakikolejnychsprawdzeniach print("elsewpętli");

#pętlaforfor((i=0;$i<=20;i++));do echo$i;done

#wbardziej"shellowym"stylu:foriin`seq020`;do echo$i;done

#pętlaforpoliścierozdzielanejspacjami#wypisanienazwwszystkichplikówz/tmpfornazwain/tmp/*;do echo$nazwa;done

#pętlawhilezread(poliniachpliku)cat/etc/fstab|whilereadsloworeszta;do echo$reszta;done#powyższapętlawypiszepokoleiwszystkie#wierszeplikuprzekazanegoprzezstdin#(catnazwa_pliku|)zpominięciem#pierwszegosłowa(którewczytywanebyłodo#zmiennejslowo)#domyślnymseparatorempóldlakomendyread#jestdowolnyciągbiałychznaków(spacjii#tabulatorów)możnagozmienićprzypomocy#zmiennejIFS:IFS=:whilereadabcd;do echo$cdone</etc/passwdunsetIFS

#instruikcjaif-elseif["$xx"="kot"-o"$xx"="pies"];then echo"kotlubpies";elif["$xx"="ryba"];then echo"ryba"else echo"cośinnego"fi

#spacjewokółiwewnątrznawiasówkwadratowych#przywarunkusąistotneskładniowo,zawartość#nawiasówkwadratowychtotaknaprawdę#argumentydlakomendytest,zatemwywołanie:#if["$xx"="ryba"];then#jestrównoważne:#iftest"$xx"="ryba";then#awięcejnatematwarunkówmożnaznaleźćw:#mantest

#jakowarunekmożewystąpićdowolnepolecenie#wtedysprawdzanyjestjegokodpowrotu#0oznaczaprawdę/zakończeniesukcesem#wartośćniezerowafałsz/błądifgrep'^root:'/etc/passwd>/dev/null;then echo/etc/passwdzawieraużytkownikaroot;fi

#istniejemożliwośćskróconegozapisuwarunków

###PrzykładBash

Page 31: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

#zużyciemłączeniainstrukcjiprzypomocy:#&&wykonajinstrukcjęwystępującapoprawej#gdypoprzedniazwróciłazero(true)#||(wykonajinstrukcjęwystępującapoprawej#gdypoprzedniazwróciłaniezero--false["$xx"="ryba"]&&echo'$xx=toryba'grep'^root:'/etc/passwd>/dev/null&&\echo/etc/passwdzawieraużytkownikaroot;

#instrukcjacase#(wodróżnieniuodswitchzCobsługujenapisy)case$xxin kot|pies) echo"kotlubpies" ;; ryba) echo"ryba" ;; *) echo"cosinnego" ;;esac

<?php

$i=$j=$k=0;

//instrukcjawaunkowaif-elseif($i<$j){ echo("i<j\n");}elseif($j<$k){ echo("i>=jANDj<k\n");}else{ echo("i>=jANDj>=k\n");}

//pętlaforfor($i=2;$i<7;++$i){ if($i==$j){ //pominięcietegokrokupętli continue; } printf("a:%d\n",$i);}

//pętlawhilewhile($i>0){ if($i==$k){ //wyjściezpętli break; } printf("b:%d\n",--$i);}

//pętlado-whiledo{ printf("c:%d\n",++$i);}while($i<2);

//instrukcjawyboruswitchswitch($i){ case1: echo("i==1\n"); break; default: echo("i!=1\n"); break;}

?>

vari,j,k;

//instrukcjawaunkowaif-elseif(i<j){

///PrzykładPHP

///PrzykładJavaScript

Page 32: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

console.log("i<j\n");}elseif(j<k){ console.log("i>=jANDj<k\n");}else{ console.log("i>=jANDj>=k\n");}

//podstawoweoperatorylogiczneif(i<j||j<k) console.log("i<jORj<k\n");//innymioperatoramilogicznymisą&&(AND),!(NOT)

//pętlaforfor(i=2;i<=9;++i){ if(i==3){ //pominięcietegokrokupętli continue; } if(i==7){ //wyjściezpętli break; } console.log("a:",+i+"\n");}

//pętlawhilewhile(i>0){ console.log("b:"+--i+"\n");}

//pętlado-whiledo{ console.log("c:"+++i+"\n");}while(i<2);

//instrukcjawyboruswitchswitch(i){ case1: console.log("i==1\n"); break; default: console.log("i!=1\n"); break;}

Typowo funkcja przyjmuje określoną ilość argumentów (może ich nie posiadać) i zwraca pojedyncząwartość.Istniejemożliwośćzwracaniaprzezfunkcjęstrukturyzłożonejzkilkuwartości,jednaknaogółodebranie z funkcji dodatkowych wyników działania odbywa się poprzez argument typuwskaźnikowego,wskazującynazmiennąwktórejmajązostaćzapisane.Wiele językówpozwalatakżenadefiniowaniefunkcjiprzyjmującychdowolnąilośćargumentów.

#include<stdio.h>

#include<stdarg.h>//potrzebnedlaobsługidowolnejilościargumentów

//funkcjabezargumentowaniezwracającawartościvoidf1(){ puts("ABC");}

//funkcjadwuargumentowazwracającawartośćintf2(inta,intb){ returna*2.5+b;}

//funkcjazjednymargumentemobowiązkowym//ijednymopcjonalnymfloatf3(inta,intb=1){ puts("F3"); returna*2.5+b;}

///PrzykładC++

Page 33: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

//funkcjazdwomaargumentamiwymaganymi//idowolnąilościąargumentówopcjonalnychfloatf4(inta,intb,...){ floatret; va_listvl; va_start(vl,b); //wtymmiejscupotrzebujemyznaćilość //oraztypyargumentów for(inti=0;i<a;i++){ ret+=b*va_arg(vl,double); } va_end(vl);

returnret;}

intmain(){ f1(); inta=f2(3,6); //zwracanąwartośćmożnawykorzystać //(jakwyżej)lubzignorować: f3(0); floatb=f4(2,1,2.8,3.5); printf("%d%f\n",a,b);}

#funkcjabezargumentowa,zwracającawartośćdeff1(): print("AA") return5

a=f1()print(a)

#funkcjaprzyjmującajedenobowiązkowy#argumentorazdwaopcjonalnedeff2(a,b=2,c=0): print(a**b+c)

f2(3)f2(3,3)#możnapominąćdowolnezargumentówzwartością#domyślnąodwołującsiędopozostałychnazwamif2(2,c=1)#możnapodawaćargumentywdowolnejkolejności#odwołującsiędonichnazwamif2(b=3,a=2)

#nieokreślonailośćargumentówpozycyjnychdeff(*a): foraaina: print(aa)

f(1,"y",6)#alenie:f(1,"y",u="p")

#nieokreślonailośćargumentównazwanychdeff(**a): foraaina: print(aa,"=",a[aa])

f(a="y",u="p")#alenie:f(1,u="p")

#nieokreślonailośćargumentówpozycyjnychinazwanychdeff(*a1,**a2): print(a1) print(a2)

f(1,"y",6)

###PrzykładPython

Page 34: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

f(a="y",u="p")f(1,"y",u="p")

#możnateżwymusićileśargumentówjawnychdeff(x,*a1,y="8",**a2): print(x,y) print(a1) print(a2)

f(1,"y",6)f(1,"y",u="p")f(1,"z",y="y",u="p")#alenie:f(a="y",u="p")

#wbashukażdafunkcjamożeprzyjmować#dowolnąilośćparametrówpozycyjnych#(widentycznysposóbobsługiwanesą#argumentyliniipoleceńdlacałegoskryptu)f1(){ echo"wywołanoz$#parametrami" echo"parametryto:$@" [$#-lt2]&&return; #możnaodwoływaćsiędopojedynczychparametrów echo"drugi:$2" echo"pierwszy:$1" #albokolejnychwpętli forain"$@";doecho$a;done #lubzużyciempoleceniashift foriin`seq1$#`;do echo$1 shift#powodujezapomnienie$1 #iprzenumerowaniepozostałych #argumentówpozycyjnycho1 #wpływanawartości$@$#itp done #funkcjamożezwracaćtylkowartośćnumeryczną #tzwkodpowrotu return83}

#wywołanie-takjakkomendy,czylibeznawiasów,#aargumentyrozdzielanebiałymznakiem(spacją)f1aaa3t56

#kodpowrotuostatniowywołanejkomendylubfunkcji#uzyskujesiępoprzez$?:echo$?

#częstofunkcje(takjakwielekomend)wynikswojego#działaniazwracająpoprzezstandardowewyjście

f2(){echo"Uwolnićmrożonetruskawki$1";}

#pozyskaćgomożnapoprzez``lub$()a=`f2'!!!'`echo$a

b=$(f2'!')echo$b

#wjednolinijkowymzapisiedefinicjifunkcji(jak#miałotomiejscedlaf2)spacjepo{iprzed}są#obowiązkowe,podobniejakśrednikipoinstukcjach

<?php

#funkcjabezargumentowa,zwracającawartośćfunctionf1(){ print("AA\n");

###PrzykładBash

///PrzykładPHP

Page 35: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

return5;}

$a=f1();print($a);print("\n");

#funkcjaprzyjmującajedenobowiązkowy#argumentorazdwaopcjonalnefunctionf2($a,$b=2,$c=0){ print($a**$b+$c); print("\n");}

f2(3);f2(3,3);

#nieokreślonailośćargumentówpozycyjnychfunctionf3(){ $num=func_num_args(); print("ilośćargumentów:\n"); print($num); print("\n"); for($i=0;$i<$num;++$i){ print("argument$i:"); print(func_get_arg($i)); print("\n"); }}

f3();f3("a",1,"c",5);

#jedenwymagany,jedenopcjonalny#inieokreślonailośćdodatkowychfunctionf4($a,$b="16"){ #tablicazwszystkimiargumentami #jestalternatywnąmetodądostępu #dowszystkichargumentówwstosunku #codopokazanejwf3() $args=func_get_args(); print_r($args);}

f4("a",1,"c",5);

?>

functionf1(){ console.log("ABC\n");}

//funkcjadwuargumentowazwracającawartośćfunctionf2(a,b){ returna*2.5+b;}

//funkcjazjednymargumentemobowiązkowym//ijednymopcjonalnymfunctionf3(a,b=1){ console.log("F3\n"); returna*2.5+b;}

//funkcjazdowolnąilościąargumentówfunctionf4(){ varret=0; for(vari=0;i<arguments.length;i++){ ret+=arguments[i]; } returnret;}

///PrzykładJavaScript

Page 36: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

f1();//zwracanąwartośćmożnawykorzystać:vara=f2(3,6);//lubzignorować:f3(0);varb=f4(2,1,2.8,3.5);

console.log("a="+a+"b="+b+"\n");

Punktstartu

Jako że program komputerowy jest sekwencją wykonywanych instrukcji musi rozpoczynać się odokreślonegomiejsca.Wprzypadkujęzykówinterpretowanychjesttonaogółpoczątekplikuzkodemprogramu.Częstowpierwszejliniiznajdujesięspecjalnykomentarz(postaci#!/ścieżka/do/programu)stanowiącyinformacjędla programu uruchamiającego skrypt jakiego interpretera ma użyć w celu wykonania koduzawartegowpliku(niekiedyzawierateżopcjezjakiminależyuruchomićinterpreter).NatomiastwprzypadkuskompilowanegokoduC/C++punktemstartujestfunkcjamain.Zakończenietejfunkcjioznaczazakończenieprogramu,awartośćprzezniązwracanaodpowiedzialnajestzatzw.kodpowrotuprzekazanyprocesowiwywołującemuprogram.

Rekurencja

Rekurencjajestmechanizmem,polegającymnawywoływaniufunkcjiprzezsamąsiebie,którymanacelu implementację niektórych algorytmów. Może być zastosowana chyba w każdym językupozwalającym na definiowanie funkcji. Ograniczeniem jest maksymalna ilość wywołań funkcjizwiązanazwielkościąstosu -wprzypadkuzbytwieluwywołańkolejnych funkcjiprogramzakończysiębłędem.Każdyalgorytmzapisywanyrekurencyjniemożezostaćzamienionynaalgorytmiteracyjny(wykorzystującypętle).

#obliczaniesilnizużyciemrekurencjidefsilnia(n): #każdarekurencjamusimiećwarunekkońca ifn==1: return1 else: returnn*silnia(n-1)

silnia(20)

#iteracyjneobliczaniesilnidefsilnia(n): s=1 foriinrange(2,n+1): s=s*i returns

silnia(20)

Więcejo(bardziejzłożonych)zmiennychGrupowaniezmiennychStrukturyiklasy

Struktura jest złożonym typem danych służącym do grupowania powiązanych ze sobą logiczniezmiennych. Zmienne wchodzące w skład struktury (pola) identyfikowane są nazwami i mogą byćróżnychtypów.Strukturazajmujeciągłyobszarpamięci,wktórymumieszczanesąwartościkolejnychpól.

Klasa opróczpólmożezawierać także funkcje (metody) - zarównooperującena tychpolach jak i zniminiepowiązane.Wniektórychprzypadkachtakżestrukturymogązawieraćmetody-np.wC++niemasilnegorozróżnieniapomiędzystrukturamiaklasami(różniąsiętylkodomyślnąwidocznościąpólimetod).

Zmiennektórychtypemjestjakaśklasaczęstookreślasięjakoobiektdanejklasy.Niekiedymówisiętakżeoinstancjidanejklasy(reprezentowanejprzezzmienną).

Niektóre z języków pozwalają na definiowanie w ramach struktury lub klasy pól i/lub metodstatycznych,któreniesąpowiązanezżadnymistniejącymegzemplarzemdanejstrukturyczyklasy-

###PrzykładPython

###PrzykładPython

Page 37: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

sąwspólnedlawszystkichimożnasiędonichodwoływaćbezistnieniaobiektu.

#include<iostream>#include<stdint.h>

structNazwaStruktury{ //polaskładowe inta; std::stringd; //zmiennastatyczna //wspólnadlawszystkichobiektówtejklasy staticintx; //stała staticconstinty=7; //polabinarne(jednoitrzybitowe) uint8_tmA:1; uint8_tmB:3; //metodyskładowe voidwypisz(){ std::cout<<"a="<<a<<"d="<<d<<"\n"; } //deklaracjametody //definicjamusibyćpodanagdzieśindziej intgetSum(intb); ///metodystatyczna staticvoidinfo(){ std::cout<<"INFO\n"; } //konstruktoridestruktor NazwaStruktury(intaa=0){ std::cout<<"konstruktor\n"; a=aa; d="abc..."; } ~NazwaStruktury(){ //potrzebnygdyklasatworzyjakieś //obiektyktórenalezyusuwać,itp std::cout<<"destruktor\n"; }};

//definicjazmiennejstatycznejznadaniemjejwartości//jesttoniezbędneabybyłaonawidoczna...intNazwaStruktury::x=13;

//wcześniejzdeklarowanemetody//możemydefiniowaćtakżepozadeklaracjąklasyintNazwaStruktury::getSum(intb){ returna+b;}

intmain(){ //korzystaniezestruktur NazwaStrukturys; s.a=45; s.wypisz();

//korzystaniezmetodstatycznych NazwaStruktury::info(); //atakżepoprzezobiektdanejklasy s.info();}

classNazwaKlasy: #polaskładowe a=0 d="alamakota"

///PrzykładC++

###PrzykładPython

Page 38: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

#metodyskładowe defwypisz(self): print(self.a+self.b) #wartozauważyćjawnyargument #wpostaciobiektutejklasy #wC++takżewystępujealeniejest #jawniedeklarowany,aninietrzeba #sięnimjawnieposługiwać #metodystatyczna @staticmethod definfo(): print("INFO") #konstruktor(zjednymargumentem) def__init__(self,x=1): print("konstruktor",self.a,self.d) #ikolejnysposóbnautworzenie #polaskładowegoklasy self.b=13*x

#korzystaniezklasyk=NazwaKlasy()k.a=67k.wypisz()

#dometodmożnaodwoływaćsiętakżetak:#(jawneużycieargumentuwpostaciobiektuklasy)NazwaKlasy.wypisz(k)

#korzystaniezmetodstatycznychNazwaKlasy.info()

print("kjesttypu:",type(k))print("natomiastk.ajesttypu:",type(k.a))

#obiektymożnarozszerzaćonoweskładoweifunkcje:k.b=k.a+10print(k.b)

<?php

classNazwaKlasy{ public$a; public$d="tekst"; #metodyskładowe publicfunctionwypisz(){ echo"a=".$this->a."d=".$this->d."\n"; } #wartozauważyćjawneodwołaniadoskładowych #poprzezzmienną$this #metodystatyczna publicstaticfunctioninfo(){ echo"INFO\n"; }}

//korzystaniezklasy$k=newNazwaKlasy;$k->a=87;$k->wypisz();

//korzystaniezmetodstatycznychNazwaKlasy::info();//atakżepoprzezzmiennąprzechowującąnazwęklasy$t="NazwaKlasy";$t::info();

?>

Metodywchodzącewskładstrukturyorazpolastatyczneniewpływająnarozmiarobiektówktórychjesttypem.

///PrzykładPHP

Page 39: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

Tablice

Tablica jest strukturą danych w której elementy (takiego samego typu) są ułożone w porządkuliniowym i są dostępne za pomocą indeksów (kluczy). Typowo tablica indeksowana jest liczbamicałkowityminieujemnymiorazzajmujeciągłyobszarpamięci.Dostępdoelementówtablicyodbywasięwoparciuoobliczanieichadresunapodstawiezależności:AdresElementu=AdresPoczatkuTablicy+IndexElementu*RozmiarElementu.

#include<iostream>#include<vector>

intmain(){ //klasycznatablica intt[4]={1,8,3,2}; std::cout<<t[2]<<"->"; t[2]=55; std::cout<<t[2]<<"="<<*(t+2)<<"\n"; //jestonapodobniejakstrukturaciągłymobszarempamięci, //możliwejestzatemtraktowanietakiejtablicyjakostruktury structStruktura{ inta,b,c,d; }; Struktura*tt=(Struktura*)t; std::cout<<tt->a<<""<<tt->c<<"\n"; //dynamiczniealokowanatablicaC++STL std::vector<int>v(4); v[3]=21; std::cout<<v[3]<<"\n";}

a[0]="abc"a[1]=123a[2]=zza[3]=qq

x=1echo"wybraneelementytablicy:"${a[$x]}${a[0]}echo"całatablica:"${a[@]}echo"ilośćelementówwtablicytablica:"${#a[@]}

vart=['abc',8,3,2];

console.log( "pierwszyelement:"+t[0]+"\n"+ "długośćtablicy:"+t.length+"\n");

//usuwamy2elementyodpozycji1t.splice(1,2)

//dodajemynoweelementyt[5]="pp";t[7]="ww";

//wypisaniewszystkichelementówfor(vari=0;i<t.length;++i){ console.log("t["+i+"]="+t[i]+"\n");}

//zapomocąfor..infor(variiint){ console.log("t["+ii+"]="+t[ii]+"\n");}

Listy

Listajeststrukturądanychwktórejelementysąułożonewporządkuliniowymnazasadziepoprzedni-

///PrzykładC++

###PrzykładBash

///PrzykładJavaScript

Page 40: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

następny.Wyróżnialisty:jednokierunkowe

wktórychwoparciuoelement listymożnauzyskaćtylkoelementnastępny lubustalićże jestostatni-możnaprzemieszczaćsiępotakiejliścietylkowjednymkierunku

dwukierunkowew których w oparciu o element listy można uzyskać następny i poprzedni, lub ustalić że jestpierwszym lub ostatnim - umożliwia to przemieszczanie się po elementach listy w obukierunkach

cykliczne(zarówno jedno idwukierunkowe)wktórychostatnielementwskazuje jakonastępnypierwszyelement, a (w przypadku dwukierunkowych) pierwszy element wskazuje ostatni jako swojegopoprzednika

#include<iostream>#include<list>

intmain(){ std::list<int>l; //dodanieelementunakońcu l.push_back(17); l.push_back(13); l.push_back(3); l.push_back(27); l.push_back(21); //dodanieelementunapoczątku l.push_front(8); //wypisanieliczbyelementów std::cout<<"size="<<l.size()<<"\n"; //wypisaniepierwszegoiostatniegoelementu std::cout<<"first="<<l.front()<<"last="<<l.back()<<"\n"; //usuniecieostatniegoelementu l.pop_back(); //posortowanielisty l.sort(); //odwróceniekolejnościelementów l.reverse(); //usunieciepierwszegoelementu l.pop_front(); for(std::list<int>::iteratori=l.begin();i!=l.end();++i){ //wypisaniewszystkichelementów std::cout<<*i<<"\n"; //możliwejesttakże: //-usuwanieelementuwskazanegoprzeziterator //-wstawianieelementuprzedwskazanymprzeziterator }}

l=[3,5,8]

#wstawienieelementunakoniecl.append(1)

#wstawienieelementunapozycje2l.insert(2,13)

print("liczbaelementów=",len(l))print("pierwszy=",l[0])

#wypisaniewszystkichelementówforeinl: #możemymodyfikowaćzmienną"e", #aleniebędziemaiłotowplywunalistę print(e)

///PrzykładC++

###PrzykładPython

Page 41: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

#alternatywneiterowaniepoelementach#(pozwalanaichmodyfikowanie)foriinrange(len(l)): l[i]=l[i]+1 print(l[i])

#możemyteżuzyskaćlistęwoparciuowykonaniejakiś#operacjinadanejliściewformiejednolinijkowca:l=[a*2forainl]#listętakąmożemyprzypisaćdoinnej#lub(jakwyżej)dotejsamejzmiennej

#pobranieiusuniecieostatniegoelementuprint("ostatnimbył:",l.pop())print("ostatnimbył:",l.pop())

#pobranieiusuniecieelementunawskazanejpozycjiprint("drugimelementembył:",l.pop(1))

#wypisaniecałejlistyprint(l)

#niekiedyzamiasttworzenialistylepszemożebyć#uzyskiwaniejejkolejnychelementów"nażywo"#funkcjonalnośćtakąwpythoniezapewniajągeneratory:

deff(l): a,b=0,1 foriinrange(l): r,a,b=a,b,a+b yieldr

#użyciegeneratorawpętliforforiinf(16): print(i)

#możnatakżetworzyćgeneratorynieskończonedefff(): a,b=0,1 whileTrue: r,a,b=a,b,a+b yieldr

#pobieraniekolejnychelementówa=iter(ff())print(next(a))print(next(a))

Listyumożliwiająłatwąimplementacjęm.in.:kolejkitypuFIFO(FirstInFirstOut)

poprzezdodawanieelementównakonieclisty,apobieraniezpoczątkulistystosu,czylikolejkitypuLIFO(LastInFirstOut)

poprzezdodawanieelementównakonieclistyipobieranietakżezkońcalisty

Listyniemuszązajmowaćciągłegoobszarupamięci-każdyzelementówmożebyćalokowanyosobnoitylkozawieraćwskaźnikinanastępnyiew.poprzednielement.Utrudnia(wydłuża)todostępdon-tegoelementulisty,aleusprawniadodawanieiusuwanieelementów(zarównozpoczątku,środkajakikońcalisty).

Tabliceasocjacyjna(mapy)

Tablicaasocjacyjna(nazywanatakżemapąlubsłownikiem)podobniedozwykłejtablicyjestzbioremparklucz-wartość,ztymżekluczeniemuszątutajbyćkolejnymiliczbamicałkowitymizaczynającymisię od zera a mogą być dowolnymi wartościami (napisami, wskaźnikami, etc). Często (np. C++)tablice takie implementowane są jako posortowane drzewa binarne, dzięki czemu dostęp doszukanegoelementurealizowanyjestwczasielogarytmicznym.

#include<iostream>#include<map>

intmain(){

###PrzykładPython

///PrzykładC++

Page 42: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

std::map<std::string,int>m; m["a"]=6; m["cd"]=9; std::cout<<m["a"]<<""<<m["ab"]<<"\n"; //wyszukanieelementupokluczu std::map<std::string,int>::iteratoriter=m.find("cd"); //sprawdzenieczyistnieje if(iter!=m.end()){ //wypisaniepary-kluczwartość std::cout<<iter->first<<"=>"<<iter->second<<"\n"; //usunięcieelementu m.erase(iter); } m["a"]=45; //wypisaniecałejmapy for(iter=m.begin();iter!=m.end();++iter) std::cout<<iter->first<<"=>"<<iter->second<<"\n"; //jakwidaćmapajestwewnętrznieposortowana}

m={"ab":11,"cd":"xx"}x="e"m[x]=True;

#pobraniesamychkluczyforkinm: print(k,"=>",m[k])

#sprawdzenieistnieniaif"ab"inm: print("jestab") #usunięcieelementu delm['ab']

#modyfikacjawartoscim["cd"]="oi"

#pobranieparkluczwartoscfork,vinm.items(): print(k,"=>",v)

<?php

$a=array('ab'=>True,'cd'=>'xx');$a['efg']=15;$a['cd']="yu";

#sprawdzenieistnieniaif(isset($a['ab'])){ //uwaga:gdy$a['ab']=null //toissetzwróciFALSE //patrzarray_key_exists() echo"jestab"; #usunięcieelementu unset($a['ab']);}

while(list($k,$v)=each($a)){ echo"a[$k]=$v\n";}

?>

//pseudoodpowiednik//tablicyasocjacyjnej

varo={a:1,b:2,c:3};

//dodanieelementu

###PrzykładPython

///PrzykładPHP

///PrzykładJavaScript

Page 43: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

o.ab="pp";

//usunięcieelementudeleteo.b;

for(varkino){ console.log( `o.${k}=${o[k]}\n` );}

W standardowej mapie klucz jest unikalny (tzn. nie mogą występować elementy z takim samymkluczem),zapewniatojednoznacznośćodwołańpoprzezoperatortablicowy[].WC++jeżelichcemymiećkilkajednakowychkluczyzróżnymiwartościamimożnaskorzystaćstd::multimap<>.

Strukturamizbliżonymiwdziałaniudomapysązbiory(std::set<>istd::multiset<>zC++orazset([k1,k2, ...]) z Pythona). Różnią się one od map tym że nie przechowują one wartości a jedynie sameklucze.

Wskaźnikiireferencje

Wskaźnik jest zmienną, któraprzechowujeadrespamięci, podktórymznajdują się jakieśdane (innazmienna).Jakożewskaźnikjestzmiennąktórateżjestumieszczonagdzieśwpamięcimożnautworzyćwskaźnikdowskaźnikaitd.Nawskaźnikachmożnawykonywaćoperacjearytmetyczne(najczęściejjestto dodawanie offsetu). Na wskaźniku można wykonać operację wyłuskania czyli odwołania się dowartości zmiennej pod adresem na który wskazuje, a nie do zmiennej wskaźnikowej (zawierającejadres).

Wskaźniki pozwalają na operowanie dużymi zbiorami danych (duże struktury, napisy, etc) bezkonieczności ich kopiowania przy przekazywaniu do funkcji, umieszczaniu w różnych strukturachdanych, sortowaniu, itd (kopiowaniuulega jedyniewskaźnikczyli adres)oraznawspółdzielenie tychsamychdanychpomiędzyróżnymiobiektami.

Wskaźnikmożewskazywaćnaniewłaściwyadreswpamięci(np.naskutekzwolnieniategofragmentulub błędu w operacjach matematycznych na wskaźnikach - wyjściu poza dozwolony zakres), typowowskaźnikowi który nic nie wskazuje przypisuje się wartość NULL (zero). Wyłuskania wskaźników owartościNULL lubwskazującychniewłaściwyobszarpamięciprowadządobłędówprogramu,częstodozakończeniaprogramuzpowodunaruszeniaochronypamięci("Segmentationfault").

Referencjajestzbliżonadowskaźników(wzasadzie jesttowskaźniktrochęinaczejtraktowanyprzezkompilator) - także pozwala na unikanie kopiowania dużych danych. W odróżnieniu od wskaźnikaodwołania do referencji zawsze skutkują wyłuskaniem, nie jest możliwa arytmetyka wskaźnikowa nareferencjach,referencjamusiteżwskazywaćnapoprawnyobszarpamięci(minimalizacjaryzykabłęduodwołania do niewłaściwego adresu). Możliwa jest referencja na wskaźnik a także wskaźnik doreferencji.

#include<stdio.h>#include<iostream>

voidf1(int*b){ *b=2**b;}

voidf2(int(*f)(constchar*s)){ f("Uwolnićmrożonetruskawki!!!");}

structkl{ //polaskładowe inta; intgetSum(intb){ returna+b; }};

intmain(){ //zmiennatypuintiwskaźniknazmiennatypuint inta=5678; int*b=NULL; //pobranieadresuzmiennejdowskaźnika

///PrzykładC++

Page 44: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

b=&a; std::cout<<"amaadres"<<b<<"\n"; //modyfikacjawartościnaktórawskazujewskaźnik *b=3456; std::cout<<a<<"="<<*b<<"\n"; //referencja int&c=a; c=6543; std::cout<<a<<"="<<c<<"\n"; //wskaźnikinaobiekty std::pair<int,int>p=std::make_pair(2,5); std::pair<int,int>*q=&p; //dostępdoskładowychpoprzezwskaźniknastrukturę (*q).first=7; q->second=8; std::cout<<p.first<<""<<p.second<<"\n"; //wskaźniknaskładową b=&(q->second); *b=3; std::cout<<p.first<<""<<p.second<<"\n"; //przekazywaniewskaźnikadofunkcji: //1.(podobniejaktrzymaniewskaźnikównaobiekty, //zamiastobiektówwlistachitp)pozwalana //przekazywaniewiększychobiektówbezichkopiowania //2.pozwalanamodyfikowaniewartościargumentów: f1(b); std::cout<<p.first<<""<<p.second<<"\n"; //wskaźnik"fun"nafunkcjeprzyjmującą //wskaźnikconstcharizwracającąint int(*fun)(constchar*s); //przypisanieadresufunkcjiputsdozmiennejfun fun=&puts; //użyciewskaźnikanafunkcjęjakofunkcji fun("aaa"); //wskaźniknafunkcjęmożebyćprzekazywany //doinnychfunkcjijakoargument f2(fun); //wskaźnikiatablice //wCtablicatowskaźniknapierwszyelement //at[x]jestrównoważne*(t+x) shortt[4]={11,22,33,44}; short*tt=t; std::cout<<"t[2]="<<t[2]<<"="<<*(t+2)<<"\n"; std::cout<<"t[0]="<<*tt<<"@"<<tt<<"\n";++tt; std::cout<<"t[1]="<<*tt<<"@"<<tt<<"\n"; //wskaźniknametodęskładowąjakiejśklasy //(zwyjątkiemmetodstatycznych) //wymagaokreśleniatyputejklasy, //gdyżjestontypemniejawnegoargumentujejmetod int(kl::*fun2)(int)=&kl::getSum; //abyskorzystaćtrzebamiećobiektdanejklasy //(lubwskaźnikdoniego) klo1; o1.a=2; kl*o2=&o1; std::cout<<(o1.*fun2)(3)<<""<<(o2->*fun2)(3)<<"\n";}

a,b=5,[1,2,3]

defpinfo(x,xx): print( "id(x)=",hex(id(x)), "=="ifid(xb)==id(xx)else"!=",

###PrzykładPython

Page 45: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

"id(xx)=",hex(id(xx)) )

#utworzeniekopiizmiennejoznaczautworzenie#nowejreferencjiwskazującejnadalnatensam#obiektwpamięciaa=apinfo(id(a),id(aa)bb=bpinfo(id(b),id(bb)

#przypisanienowegoobiektupodzmienną#powodujezmianę(adresu)obiektuktóry#wskazuje:aa=5pinfo(id(a),id(aa)bb=[9,11,13]pinfo(id(b),id(bb)

#alemodyfikacjaobiektów"immutable"#(takichjakliczby,napisy)niejestmożliwa#zatemzawszetworzonyjestnowyobiektaa=aaa+=1pinfo(id(a),id(aa)

#jeżelidostaregoobiektuniemainnych#referencjimożeonzostaćusunięty#anowymożebyćumieszczonywjegomiejscu#(wtakimprzypadkuwynikidsięniezmieni)

#natomiastmodyfikacjaobiektów"mutable"#(takichjaklistyisłowniki)#nietworzynowegoobiektutylkomodyfikuje#istniejący(wynikidsięniezmieni)zatem#wszystkiereferencjewskazująnazmodyfikowany#obiekt:bb=bbb[0]=17print("bb=",bb,"b=",b)pinfo(id(b),id(bb)

#abyuzyskaćkopięnależyskorzystać#zodpowiedniejmetodybb=b.copy()

print("bb=",bb,"b=",b)

bb[0]=99print("bb=",bb,"b=",b)pinfo(id(b),id(bb)

#uwagakopiowanietakiejestpłytkie:jeżeliw#liściemamyobiekty"mutable"obie(niezależne#podwzględemzbioruelementów)kopielisty#będąwskazywaćnatesameobiekty

#usuwaniezmiennejb=None#mapowaniezmiennej"b"zostałozmienione#niewskazujejużnalistętylkona#obiekttypuNoneType

bbb=bbdelbb#nazwa"bb"zostałausunięta#aledodanychmożemydostawaćsięprzez"bbb"

#dopieropousunięciuwszystkichreferencji#nadanyobiekttoPythonmożegousunąć(ale#niemusiwykonaćtegonatychmiast)

#pythontakżeumożliwiaprzekazywaniefunkcji#jakoargumentudoinnejfunkcjidefa(z):

Page 46: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

print(z*3)

defb(x,y): x(y+2)

b(a,1)

#ponadtofunkcjamożetakżezwracaćfunkcję:defaa(y): deft(x): returny*x returnt

b=aa(3)b(2)

#możnateż:aa(3)(4)

#wBashuniemaoperacjinawskaźnikach#alepodobnąfunkcjęwpewnychwypadkach#możepełnićzmiennazawierającanazwę#innejzmiennej

A='tekstdowypisania,$HOME,`ls`';B="A";

#prostepodejścietypuecho${$B}#(działającenp.wPHP)niezadziała,#alemożnatozrobićnakilkainnychsposobów:

C=${!B};#tametodaniedziaławczystymshecho$C

exportAC=$(echo"\$$B"|envsubst)#tametodawymagazewnętrznegopolecenia#envsubstiwyeksporotwaniazmiennychecho$C

C=$(eval"echo\$$B")echo$C

#zużyciemwiększejliczbypoleceńevalmożemy#zapewnićtakżepodstawieniekolejnegopoziomu#zmiennychlubwykonaniewpisanychwnichpoleceńC=$(evaleval"echo\$$B")echo$C

#zmiennamożeprzechowywaćkomendę/nazwę#funkcjidowykonaniax=ls

$x/tmp

<?php

//wPHPkorzystanieznazwyzmiennej//przechowywanejwinnejzmiennej//jestjeszczeprostsze:$a="12";$b="a";$c="b";

echo"$a$b$c\n"echo"${$b}${$c}\n"echo"${${$c}}\n"

//możliwejesttakżeużywaniezmiennych//zawierającychnazwyfunkcjioraz//przekazywanieichdoinnychfunkcjifunctionfa($z){ print($z*3); print("\n");

###PrzykładBash

///PrzykładPHP

Page 47: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

}

$c="fa";$c(2);

functionfb($x,$y){ $x($y+2);}

fb("fa",1);

?>

Zasięgzmiennej

Często (np. C / C++) zasięg zmiennych (widoczność i istnienie) jest limitowany do bloku w którymzostały zadeklarowane, zmienne z bloków wewnętrznych mogą przesłaniać zmienne zadeklarowanewcześniej.Wniektórychjęzykach(np.Pythonie,Bash'u)mechanizmtenniejeststosowany(utworzeniezmiennejwewnątrzif'alubpętlipowodujejejwidocznośćpozatymblokiem).

Wywołaniefunkcjipowodujerozpoczęcienowegokontekstuwktórymzmiennezblokuwywołującegofunkcję nie są widoczne (ale nadal istnieją). Typowo argumenty do funkcji przekazywane są przezkopiowanie,więcfunkcjaniemamożliwościmodyfikacjizmiennychzblokująwywołującegonawetdoniejprzekazanych(wyjątkiemjestprzekazanieprzezreferencjęlubwskaźnik).

W przypadku manualnej alokacji pamięci lub tworzenia obiektów poprzez new limitowana jestwidoczność i istnienie otrzymanego wskaźnika, ale nie zaalokowanego bloku pamięci. Zatemograniczona jest widoczność takich zmiennych ale nie czas ich istnienia, dlatego też przed utratąwskaźnikananienależyjeusunąć(zwolnićzaalokowanąpamięć).

#include<iostream>

intfunA(inta){ a=a*2; returna;}

intfunB(int&a){ a=a*2; returna;}

intmain(){ inta=57,b=23; std::cout<<++a<<""<<++b<<"\n"; //wypisze5824 { inta=b; std::cout<<++a<<""<<++b<<"\n"; //wypisze2525 //boaztegobloku(==24)przesłoniłowcześniejszazmiennąa(==58) } std::cout<<++a<<""<<++b<<"\n"; //wypisze5926 //boazwcześniejszegoblokujużnieistniejeinieprzesłanianaszegoa(==58) std::cout<<funA(a)<<""<<funB(b)<<"\n"; //wypiszewartościzwracaneprzezfunkcjeczyli118(59*2)i52(26*2) std::cout<<a<<""<<b<<"\n"; //wypiszeaktualnewartościargumentu: //a=59boprzekazanieprzezwartośćifunkcjaoperowałanawłasnejkopii //b=52boprzekazaneprzezreferencjęifunkcjaoperowałanatejsamejkopii}

a,b,d=5,12,[1,2,3]

deff1(c): returnc+b

deff2(c): b=2 returnc+b

///PrzykładC++

###PrzykładPython

Page 48: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

#f1korzystazzmiennejglobalnejb#f2przysłaniasobiezmiennąglobalnąbpoprzezswojązmiennąlokalnąprint("f1(a)=",f1(a),"f2(a)=",f2(a),"alebnadajwynosi:",b)

deff3(c): globalb b=16 returnc+b

#f3dziękitemużejawniedeklarujeiżużywaglobalnegob#możemodyfikowaćzmiennąglobalnąprint("f3(a)=",f3(a),"terazbwynosi:",b)

deff4(c): c=2*c returnc

#argumentyfunkcjisązmiennymilokalnymiprint("f4(a)=",f4(a),"aleanadajwynosi:",a)

deff5(c): c[0]="xx" returnc

print("f5(d)=",f5(d),"tymrazemduległomodyfikacji:",d)

ifd[1]==2: x="ABC"else: x=22

print("zmiennaxjestwidocznapozablokiemwktórymzostałautworzona",x)

Kolejnośćbajtów

#include<inttypes.h>#include<stdio.h>intmain(){ //danejakotablicaliczb16bitowych uint16_taa[4]={0x1234,0x5678,0x9abc,0xdeff}; //wypisujemyją printf("A0:%x%x%x%x\n",aa[0],aa[1],aa[2],aa[3]); //chybanikogoniezaskoczywynikpowyższegoprintf:A0:123456789abcdeff //wypisujemydwiepierwszeliczbyrozłożonenaczęści8bitowe(poszczególnebajty) printf("A1:%x%x%x%x\n",(aa[0]>>8)&0xff,aa[0]&0xff,(aa[0]>>8)&0xff,aa[0]&0xff); //efektteżjestoczywisty:A1:12341234 //każemynatesamedanepatrzećjakonaliczby8bitowe(poszczególnebajty) uint8_t*bb=(uint8_t*)aa; printf("B0:%x%x%x%x\n",bb[0],bb[1],bb[2],bb[3]); //czegosięterazspodziewamy? //-wypiszenamtylkopołowęoryginalnejtablicy //-aledokładnywynikzależyodarchitekturynaktórejuruchamiamyprogram: //*nalittleendian(np.x86)będzieto:B0:34127856 //*nabigendian(np.sparc)będzieto(bardziejnaturalnedlaczłowieka):B0:12345678}

Fakt, że różne komputery ten sam ciąg zero-jedynkowy mogą interpretować jako różne liczby (wzależności od architektury big endian vs little endian), powoduje że przy wymianie danych międzysystemami konieczne jest ustalenie sposobu tej interpretacji (np. protokoły sieciowe takie jak IPużywająbigendian)lubzawarcietejinformacjiwwymienianychdanych(kodowaniaUnicodeUTF-16iUTF-32zawierająnapoczątkudanychznacznikBOM).

Napisy

Napisy są to ciągi liczb, w których kolejne liczby (pojedynczo lub grupami) interpretowane są jakokolejneznaki (litery).Wprzypadkukodowańoustalonejdługościznaku(np.UTF-32,ASCI)każdan-bitowaliczbaodpowiadajednemuznakowinapisu(przyczymitakmogąsięonegraficznienakładać,

Page 49: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

ale każdy jest integralną całością). W przypadku kodowań o zmiennej długości znaku długość znakukodowana jest w ramach tego znaku (np. w UTF-8 długość wynosi od 1 do 4 bajtów, informacja odługościzakodowanajestwpierwszymbajcie,adodatkowebajtymająustawionenajstarszebityna10cojednoznacznieidentyfikujejejakouzupełniające).

Mogąonebyćprzechowywane jako tablica lub lista tablic (ułatwia tooperowaniedużymizmiennyminapisowymi - unikanie relokacji i przepisywania dużej ilości danych). Możliwe jest kilka sposobówprzechowywanianapisuwtablicyróżniącychsięmetodąuzyskiwaniainformacjiokońcunapisu-możeto być osobna zmienna przechowująca długość napisu (lub adres jego końca) albo znacznik końcaprzechowywanywsamymnapisie(wtejrolistosowanejest0wtzw.NULL-endstringachzjęzykaC).

Wprzetwarzaniunapisówbardzoczęstostosowanesąwyrażeniaregularnesłużącedodopasowywanianapisówdowzorcaktóryopisują,wyszukiwaniu/zastępowaniutegowzorca.Dotypowej,podstawowejskładniwyrażeńregularnychzaliczasięm.in.następująceoperatory:

.-dowolnyznak[a-z]-znakzzakresu[^a-z]-znakzpozazakresu(abymiećzakresz^należydaćgonienapoczątku)^-począteknapisu/linii$-koniecnapisu/linii

*-dowolnailośćpowtórzeń?-0lubjednopowtórzenie+-jednolubwięcejpowtórzeń{n,m}-odndompowtórzeń

()-pod-wyrażenie(możebyćużywanedlaoperatorówpowtórzeń,atakżedlareferencjiwstecznych)|-alternatywa:wystąpieniewyrażeniapodanegopolewejstroniealbowyrażeniapodanegoprawejstronie

#include<stdio.h>#include<iostream>

#include<string>#include<string.h>#include<bitset>#include<regex>#include<sstream>

intmain(){ //napisywstyluC //czylitaknaprawdętablicebajtów(znaków) constchar*x="abcdefg"; //wypisaniedługościnapisu printf("%d\n",strlen(x)); //wypisaniepod-napisuod2dokońca puts(x+2); //wyszukiwanie //pod-napisu"cd"wxodpozycji1 constchar*cd=strstr(x+1,"cd"); printf("%d\n",cd-x); //3znakowypod-napisnapisux //rozpoczynającysięodcd charbuf[16]; strncpy(buf,cd,3); buf[3]=0;//NULLend puts(buf); //porównywanie if(strcmp(x,"a")==0) puts("x==\"a\""); if(strncmp(x,"a",1)==0) puts("pierwsze1znakówxto\"a\""); //napisywstyluC++ std::stringxx(x); std::stringy="aabbccbbddbbee"; //wypisaniedługościnapisu std::cout<<xx.size()<<"\n"; //.size()totosamoco.length()

///PrzykładC++

Page 50: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

//uzyskanienapisywstyluC puts(xx.c_str()); //wypisaniepod-napisuod2dokońca std::cout<<xx.substr(2)<<"\n"; std::cout<<xx.substr(2,std::string::npos)<<"\n"; //iod0(początku)do3 std::cout<<xx.substr(0,3)<<"\n"; //wyszukiwaniepod-napisu"bb"wyodpozycji5 std::cout<<y.find("bb",5)<<"\n"; //porównywanie if(xx=="a") std::cout<<"x==\"a\"\n"; if(xx.compare(0,1,"a")==0) puts("pierwsze1znakówxto\"a\""); if(std::regex_match(xx,std::regex(".*[dz].*"))) puts("xzawieradlubz"); //regex_matchdopasowujecałośćnapisudowyrażeniaregularnego //dopasowanieczęściowewrazzopcjonalnymuzyskaniem //pasującejczęściumożliwia:std::regex_search() //modyfikowaniestd::string xx="Alamapsa"; //wstawianie-insert(pozycja,co) xx.insert(6,"kotai"); std::cout<<xx<<std::endl; //zastępowanie-replace(pozycja,ile,czym); xx.replace(4,2,"miałasamochód",0,6); //mogłobyteżbyćxx.replace(4,2,"miała");iparęinnychwariantów... std::cout<<xx<<std::endl; //usuwanie-erase(pozycja,ile); xx.erase(9,1);//9zamiast8boUTF-8iłmadwaznaki std::cout<<xx<<std::endl; //zastępowaniezużyciemwyrażeńregularnych std::cout<<std::regex_replace(y,std::regex("[bc]+"),"XX")<<"\n"; //zastępowaniezużyciempodstawienia //$2zostaniezastąpionewartościądrugiepod-wyrażenia, //czylifragmentuujętegownawiasach std::cout<<std::regex_replace( y,std::regex("([bc]+)([bc]+)"),"X-$2-X" )<<"\n"; //konwersjaliczbnanapiswsystemach: //dwójkowym,ósemkowym,dziesiętnymiszesnastkowym std::cout<<std::bitset<8>(7)<<""; std::cout<<std::oct<<0xf<<""; std::cout<<std::dec<<010<<""; std::cout<<std::hex<<0b11<<"\n"; //liczbypodawanedowypisywaniasąwodpowiedniosystemach: //dziesiętnym,szesnastkowym,ósemkowymidwójkowym //wskazanejesttoprzezbrakprefixuiprefixy"0x""0""0b" //alternatywniewstyluprintf,alebezdwójkowego printf("0o%o%d0x%x\n",0xf,010,0b11); //wypisywanieznakówunicodu puts("\u21c4=⇄"); //strumienienapisowe std::ostringstreamzzz; zzz<<xx<<"cpp\n"; zzz<<34.6<<""<<std::oct<<0xf<<""; //konwersjadostd::string xx=zzz.str(); std::cout<<xx<<"\n";

Page 51: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

}

importre

x="abcdefg"y="aabbccbbddbbee"z="qw=rt"

#wypisaniedługościnapisuprint(len(x))

#wypisaniepod-napisuod2dokońca#iod0(początku)do3print(x[2:],x[0:3])

#wypisanieostatniegoi3ostatnichznakówprint(x[-1],x[-3:])

#wypisanieco3ciegoznakuznapisuoraznapisuodtyłuprint(y[::3],x[::-1])

#wyszukiwanie#pod-napisu"bb"wyodpozycji5print(y.find("bb",5))

#porównywanieifx=="a": print("x==\"a\"")

ifre.search("[dz]",x): print(x,"zawieradlubz")

#sprawdzanieczyjestpod-napisemif"ab"inx: print("abjestpod-napisem:",x)

#sprawdzanieczyjestpod-napisemif"ba"inx: print("bajestpod-napisem:",x)

#zastępowanieprint(re.sub('[bc]+',"XX",y,2))print(re.sub('[bc]+',"XX",y))

#zastępowaniezużyciempodstawienia#\\2zostaniezastąpionewartościądrugiepod-wyrażenia,#czylifragmentuujętegownawiasachprint(re.sub('([bc]+)([bc]+)',"X-\\2-X",y))

#mamyteżwpływnazachłannośćwyrażeńregularnych:

print(re.sub('bb(.*)bb',"X\\1X",y))#"bb(.*)bb"dopasowałonajdłuższymożliwyfragment,czyli:ccbbdd

print(re.sub('.*bb(.*)bb.*',"\\1",y))#"bb(.*)bb"dopasowałojedynie"dd",bonajdłuższymożliwy#fragmentzostałdopasowanyprzezpoprzedzające".*"

print(re.sub('.*?bb(.*)bb.*',"\\1",y))#"bb(.*)bb"mogłoidopasowałonajdłuższymożliwyfragment,#gdyżbyłopoprzedzoneniezachłannąodmianądopasowania#dowolnegonapisu,czyli:.*?

#Pokażdymzoperatorówpowtórzeń(.?+{n,m})możemydodać#pytajnik(.???+?{n,m}?)abywskazaćżemaondopasowywać#najmniejszymożliwyfragment,czylimadziałaćniezachłannie.

#niedasięmodyfikowaćnapisuzużyciemodwołańx[numer]np.#x[2]="X"#niezadziała

#można(gdydużotegotypumodyfikacji)przepisaćdolisty:l=list(x)#alternatywniemożnamanualnie:# l=[]

###PrzykładPython

Page 52: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

# forcinx:# l.append(c)#albotak:# l=[cforcinx]

l[1]="X"l[3]="qqq"dell[5]print("".join(l))

#albotak(gdymniejmodyfikacji)print(x[:2]+"XXX"+x[3:])

#możnatakżemodyfikowaćpokoleiidodawaćdonowegonapisus=""forcinx: ifc=="a": s+="AA" else: s+=c

print(s)

#przypomocymetodysplit()napismożemypodzielić#nalistęnapisówprzypomocydowolnegoseparatoraprint(y.split(""))print(y.split("cc"))

#konwersjaliczbnanapiswsystemach:#dwójkowym,ósemkowym,dziesiętnymiszesnastkowymprint(bin(7),oct(0xf),str(0o10),hex(0b11))

#liczbypodawanedowypisywaniasąwodpowiedniosystemach:#dziesiętnym,szesnastkowym,ósemkowymidwójkowym#wskazanejesttoprzezbrakprefixuiprefixy"0x""0o""0b"

#alternatywniewstyluprintf,alebezdwójkowegos="0o%o%d0x%x"%(0xf,0o10,0b11)print(s)

#wypisywanieznakówzużyciemichnumeruwunikodzie#-funkcjachr()zwracanapiszłożonyzeznakuopodanymnumerze#wramachnapisówmożnateżużyć\uNNNNgdzieNNNNjestnumeremznaku#lubpoprostuumieścićdanyznakwplikukodowanymUTF8print(chr(0x21c4)+"==\u21c4==⇄")

#funkcjaord()umożliwiakonwersjęnapiszłożonego#zpojedynczegoznakunanumerunicodowyprint(hex(ord("⇄")),hex(ord("\u21c4")),hex(ord(chr(0x21c4))))

#PythonużywaUnicodedlaobsługinapisów,jednakprzed#przekazaniemnapisudoświatazewnętrznegokonieczne#możebyćzastosowaniekonwersjidookreślonejpostaci#bytowej(zastosowanieodpowiedniegokodowania)#służydotegometodaencode()np.a="aąbcć...⇄"inUTF7=a.encode('utf7')inUTF8=a.encode()#luba.encode('utf8')print("'"+a+"'wUTF7to:"+str(inUTF7))print("ijesttypu:"+str(type(inUTF7)))

#obiektytypu'bytes'mogązostaćzdekodowanedonapisuprint("zdekodowanyUTF7:"+inUTF7.decode('utf7'))

#lubzostaćpoddanedalszejkonwersjinp.kodowaniubase64:importcodecsb64=codecs.encode(inUTF8,'base64')print("napiswUTF8pozakodowaniubase64to:"+str(b64))

<?php

$x="abcdefg";$y="aabbccbbddbbee";$z="qw=rt";

#wypisaniedługościnapisu

///PrzykładPHP

Page 53: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

echostrlen($x)."\n";

#wypisaniepod-napisuod2dokońcaechosubstr($x,2);#iod0(początku)3kolejneznakiechosubstr($x,0,3)."\n";

#wyszukiwanie#pod-napisu"bb"w$yodpozycji5echostrpos($y,"bb",5)."\n";

#porównywanieif($x=="a") echo"$x==a\n";

if(substr_compare($x,"de",3,2)){ echo"2znakowypod-napisod"; echo"pozycji3w$xto\"de\"\n";}

if(preg_match("/[dz]/",$x)){ echo"$xzawieradlubz\n";}

#zastępowanieechostr_replace("bb","BB",$y)."\n";echopreg_replace('/[bc]+/',"XX",$y,2)."\n";echopreg_replace('/[bc]+/',"XX",$y)."\n";

#zastępowaniezużyciempodstawienia#$2zostaniezastąpionewartościąpierwszegopod-wyrażenia,#czylifragmentuujętegownawiasachechopreg_replace('/^([^=]*)=.*$/','$1',$z);echo"=";echopreg_replace('/^[^=]*=(.*)$/','$1',$z);echo"\n";

#wypisywaniewróżnychsystemachliczbowychprintf("0b%b0o%o%d0x%x\n",7,0xf,010,0b11);

?>

#${zmienna:-"napis"}zwrócinapisgdy#zmiennaniejestzdefiniowanalubjestpusta#${zmienna:="napis"}zwrócinapis#orazwykonapodstawieniezmienna="napis"gdy#zmiennaniejestzdefiniowanalubjestpusta#${zmienna:+"napis"}zwrócinapisgdy#zmiennajestzdefiniowanainiepustaa="";b="";c=""echo${a:-"aa"}${b:="bb"}${c:+"cc"}echo$a$b$ca="x";b="y";c="z"echo${a:-"aa"}${b:="bb"}${c:+"cc"}echo$a$b$c

#${#str}zwrócidługośćnapisuwzmiennejstr#${str:n}zwrócipod-napis$strodndokońca#${str:n:m}zwrócipod-napis$strodnodługościmx=abcdefgecho${#x}${x:2}${x:0:3}${x:0:$((${#x}-2))}

#${str#"ab"}zwróci$strzobciętym"ab"zpoczątku#${str%"fg"}zwróci$strzobciętym"fg"zkońcaecho${x#"abc"}${x%"efg"}echo${x#"ac"}${x%"eg"}#wnapisachdoobcięciamożliwejeststosowanieshellowych#znakówuogólniających,czyli*,?,[abc],itd#operator#i%dopasowująminimalnynapisdousunięcia#operatory##i%%dopasowująmaksymalnynapisdousunięciax=abcd.e.fgecho${x#*.}${x##*.}${x%.*}${x%%.*}

#${str/"n1"/"n2"}zwróci$strzzastąpionym

###PrzykładBash

Page 54: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

#pierwszymwystąpieniemn1przezn2#${str//"n1"/"n2"}zwróci$strzzastąpionymi#wszystkimiwystąpieniamin1przezn2y="aabbccbbddbbee"echo${y/"bb"/"XX"}echo${y//"bb"/"XX"}

#polecenieexprmatch$x'wr1\(wr2\)wr3'#zwróciczęść$xpasującądowyrażeniaregularnegowr2#wyrażeniaregularnewr1iwr2pozwalająna#określanieczęścinapisudoodrzucenia#alternatywnąskładniąjestexpr$x:'wr1\(wr2\)wr3'z="ab=cd"exprmatch$z'^\([^=]*\)='expr$z:'^[^=]*=\(.*\)$'

#możliwejestteżsprawdzaniedopasowańwyrażeń#regularnychpoprzez(uwaganabrakcytowania):[["$z"=~^([^=]*)=]]&&echo"OK"

#wypisywaniewróżnychsystemachliczbowychprintf"0o%o%d0x%x\n"0xf0103

#dobardziejzaawansowanychoperacji#mogąbyćprzydatnetakżepolecenia:#grepdiffsedawk#joincommpaste

#należyteżpamiętaćoróżnicywdziałaniuecho"$a"i#echo$awprzypadkugdyzmiennaazawieraznakinowejlinii:#-wpierwszymwypadkubędątraktowanejakoznakinowejlinii#-wdrugimjakospacje

#obsługanapisówwbash'uprzypomocystandardowychkomendPOSIXa

#jakożewiększośćoperacjibashowychwiążesięz#uruchamianiemzewnętrznychprogramówtotakże#przetwarzanienapisówmożebyćrealizowanewtensposób

a="aąbcć123"

#obliczaniedługościnapisuwznakach,wbajtachiilościsłówwnapisieecho-n$a|wc-mecho-n$a|wc-cecho-n$a|wc-w

#obliczanieilościlinii(dokładniejilościznakównowejlinii)wc-l</etc/passwd

#wypisanie5pola(rozdzielanego:)zpliku/etc/passwdzeliminacją#pustychliniiorazliniizłożonychtylkozespacjiiprzecinkówcut-f5-d:/etc/passwd|grep-v'^[,]*$'#komendacutwybierawskazanepola,opcja-dokreślaseparator

#alternatywnepodejściezużyciemAWKawk-F:'$5!~"^[,]*$"{print$5}'/etc/passwd

#awkdajedużemożliwościprzyprzetwarzaniutegotyputekstowychbaz#danych...możemynp.wypisywaćwypisywaćpierwszepolewoparciu#owarunkinałożonenainne:awk-F:'$5!~"^[,]*$"&&$3>=1000{print$1}'/etc/passwd

#jakwidaćwpowyższychprzykładachdoposzczególnychpólodwołujemy#siępoprzez$n,gdzienjestnumerempola,$0oznaczacałyrekord

#programdlakażdegorekorduprzetwarzakolejneinstrukcjepostaci#"warunek{komendy}",instrukcjitakichmożebyćwielewprogramie#(przetwarzanesąkolejno)komenda"next"kończyprzetwarzaniedanegorekordu

#separatorpolaustawiamyopcją-F(lubzmiennąFS)domyślnymseparatorem#polajestdowolnyciągspacjiitabulatorów(wodróżnieniuodcut#separatormożebyćwieloznakowymnapisemlubwyrażeniemregularnym)#domyślnymseparatoremrekordujestznaknowejlinii#(możnagozmienićzmiennąRS)

#awkjestprostymjęzykiemprogramowaniaobsługującympodstawowepętle

###PrzykładBash

Page 55: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

#iinstrukcjewarunkoweorazfunkcjewyszukująceimodyfikującenapisyecho"abaaabbabbaabbabba"|awk'{ for(i=1;i<=NF;++i){#dlakażdegopolawrekordzie if(i%2==0)#jeżelijegonumerjestparzysty gsub("b+","B",$i);#zastąpwszystkieciągibpojedynczymB ii=index($i,"B")#wyszukajpozycjępod-napisuB if(ii)#jeżeliznalazłtowypiszpozycjęipod-napis printf("#%d%s\n",ii,substr($i,ii))#odtejpozycjidokońca } print$0}'

#AWKobsługujetakżetabliceasocjacyjnepozwalatonp.policzyć#powtórzeniasłówecho"aabbaaeeddaadd"|awk' BEGIN{RS="[\t\n]+";FS=""} {slowa[$0]++} {printf("rekord:%ddone\n",NR)} END{for(sinslowa)printf("%s:%s\n",s,slowa[s])}'#podobnyefektmożemyuzyskaćstosując"uniq-c"(którywypisujeunikalne#wierszewrazzichilością)naodpowiednioprzygotowanymnapisie#(spacjezastąpionenowąlinią,alinieposortowane)echo"aabbaaeeddaadd"|tr'''\n'|sort|uniq-c#jednakrozwiązanieawkmożnałatwozmodyfikowaćabywypisywałopierwsze#wystąpienieliniibezsortowaniapliku

#innąbardzoprzydatnąkomendąjestsedpozwalaonam.innazastępowanie#wyszukiwanegonapodstawiewyrażeniaregularnegotekstuinnymecho"aabbccbbddbbee"|sed-e's#\([bc]\+\)\([bc]\+\)#X-\2-X#g'

#sedowepoleceniesprzyjmuje3argumenty(oddzielanemogąbyćdowolnym#znakiemktórywystąpizas),pierwszytowyszukiwanewyrażenie,drugi#tekstktórymmazostaćzastąpione,atrzecigdyjestgtopowoduje#zastępowaniewszystkichwystąpieńanietylkopierwszego

#należyzwrócićuwagęnaróżnicęwskładniwyrażeniaregularnegopolegającą#napoprzedzaniu(,)i+odwrotnymukośnikiemabyMIAŁYznaczeniespecjalne

#sedzopcją-iiwskazaniemplikumodyfikujezawartościtegopliku#pozwalatonałatwestworzeniefunkcjirekurencyjnegozastępowania:rreplace(){ if[$#-ne2];then echoUSAGE:$1str1str2 return fi grep-R"$1".|cut-f1-d:|uniq|whilereadf;do [-L$f]||sed-e"s#$1#$2#g"-i$f; done;}

varx="abcdefg";vary="aabbccbbddbbee";varz="qw=rt";

//podstawianiewartościzmiennychwnapisieconsole.log(`x=${x}y=${y}z=${z}\n`)

functionecho(a){ //łączenienapisów(lubnapisuiczegoś //comożnaskonwertowaćnanapis) //zużyciemoperatora+ console.log(a+"\n");}

//wypisaniedługościnapisuecho(x.length);

//wypisaniepod-napisuod2dokońcaecho(x.substr(2));//iod0(początku)3kolejneznakiecho(x.substr(0,3));

//wyszukiwanie

///PrzykładJavaScript

Page 56: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

//pod-napisu"bb"w$yodpozycji5echo(y.indexOf("bb",5));

//porównywanieif(x=="abcdefg") echo("x==abcdefg");

if(x.search(/[dz]/)>0){ echo("xzawieradlubz");}

//zastępowanieecho(y.replace("bb","BB"));echo(y.replace(/[bc]+/g,"XX"));

//zastępowaniezużyciempodstawienia//$2zostaniezastąpionewartością//pierwszegopod-wyrażenia,//czylifragmentuujętegownawiasachconsole.log( z.replace(/^([^=]*)=.*$/,'$1')+ "="+ z.replace(/^[^=]*=(.*)$/,'$1')+ "\n");

vara=7,b=0xf,c=010,d=0b11;

echo("0b"+a.toString(2))echo("0o"+b.toString(8))echo(c.toString())echo("0x"+d.toString(16))

XML

Extensible Markup Language (XML) jest tekstowym formatem wymiany danych. W odróżnieniu odformatu klasycznego formatu utożsamiającego linię z rekordem złożonym z pól oddzielanychwskazanym separatorem może on w łatwy sposób opisywać bardziej złożoną (drzewiastą a nietabelkową)postaćdanych.DokumentXMLskładasięzzagnieżdżonychwsobieznaczników,każdyznich może posiadać atrybuty oraz wartość, którą jest tekst zawierający lub nie kolejne znaczniki.Kolejnośćwystępowaniaelementówwdokumenciejestznacząca.Każdyznacznikotwierającyposiadaodpowiadający mu znacznik zamykający (np. <b>aa</b>), znaczniki bez wartości mogą być samo-zamykające (np. <g />). Dokumenty HTML mogą być zgodne z wymogami formalnymi XML tymsamymstanowiącdokumentyXML.

//wymagapobraniabibliotekinagłówkowejrapidxml(http://rapidxml.sourceforge.net/)

#include"rapidxml.hpp"namespacerapidxml{namespaceinternal{ //fixbuginrapidxmlhttps://sourceforge.net/p/rapidxml/bugs/16/ template<classV,classC>Vprint_children(V,constxml_node<C>*,int,int); template<classV,classC>Vprint_element_node(V,constxml_node<C>*,int,int); template<classV,classC>Vprint_data_node(V,constxml_node<C>*,int,int); template<classV,classC>Vprint_cdata_node(V,constxml_node<C>*,int,int); template<classV,classC>Vprint_declaration_node(V,constxml_node<C>*,int,int); template<classV,classC>Vprint_comment_node(V,constxml_node<C>*,int,int); template<classV,classC>Vprint_doctype_node(V,constxml_node<C>*,int,int); template<classV,classC>Vprint_pi_node(V,constxml_node<C>*,int,int);}}#include"rapidxml_print.hpp"

#include<iostream>#include<string.h>

intmain(){ charxmlString[1024]; strncpy(xmlString, "<a>" "<b>A<h>qwe...rty</h></b>" "ABCD...HIJ..." "<cx=\"q\"w=\"pp\">EEF</c>" "<gy=\"zz\"/>"

///PrzykładC++

Page 57: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

"<cx=\"pp\">123<drr=\"oo\">456</d>7890.</c>" "</a>", 1024 ); //utworzenieobiektudrzewaXMLowegowoparciuonapis rapidxml::xml_document<>xmlDoc; xmlDoc.parse<0>(xmlString); //pobraniegłównegowęzła rapidxml::xml_node<>*xmlRoot=xmlDoc.first_node(); std::cout<<"nazwagłównegoelementuto:"<<xmlRoot->name()<<"\n"; std::cout<<"jegozawartośćtekstowato:"<<xmlRoot->value()<<"\n"; std::cout<<"jegowartośćto:{{{{"<<*xmlRoot<<"}}}}\n"; std::cout<<"jegopotomkowieto:\n"; rapidxml::xml_node<>*xmlNode=xmlRoot->first_node(); while(xmlNode){ std::cout<<""<<xmlNode->name()<<":"; rapidxml::print(std::cout,*xmlNode,rapidxml::print_no_indenting); //rapidxml::print()możezapisywaćtakżedonapisu std::cout<<"\n"; xmlNode=xmlNode->next_sibling(); } std::cout<<"pierwszywęzełcmaatrybuty:\n"; xmlNode=xmlRoot->first_node("c"); if(xmlNode){ rapidxml::xml_attribute<>*xmlAtrib=xmlNode->first_attribute(); while(xmlAtrib){ std::cout<<xmlAtrib->name()<<"="<<xmlAtrib->value()<<"\n"; xmlAtrib=xmlAtrib->next_attribute(); } } //modyfikacjedokumentu: //zmiananazwyizawartościelementu xmlNode=xmlRoot->first_node("g"); if(xmlNode){ xmlNode->name("noweGG"); xmlNode->value("!@#$"); } //zmiananazwyiwartościatrybutu xmlNode=xmlRoot->first_node("c"); if(xmlNode){ rapidxml::xml_attribute<>*xmlAtrib=xmlNode->first_attribute(); while(xmlAtrib){ if(xmlAtrib->name()==std::string("w")){ xmlAtrib->name("uu"); xmlAtrib->value("123"); break; } xmlAtrib=xmlAtrib->next_attribute(); } } //usuwaniewszystkichpotomkówostatniego<c> xmlNode=xmlRoot->last_node("c"); xmlNode->remove_all_nodes(); xmlNode->value(""); //usuwaniewszystkichatrybutów... xmlNode->remove_all_attributes(); //sąteżfunkcjeusuwającewskazanegopotomkalubatrybut: //remove_node()iremove_attribute() //dodawanieatrybutów xmlNode->append_attribute( xmlDoc.allocate_attribute("abc","098") ); xmlNode->append_attribute( xmlDoc.allocate_attribute("qwe","...") ); //powyższametodadodajenakoniec,możnatakżedodawaćnapoczątek: //prepend_attribute()lubnawskazanąpozycjęinsert_attribute()

Page 58: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

//dodawaniepotomków rapidxml::xml_node<>*xmlNode2; xmlNode2=xmlDoc.allocate_node(rapidxml::node_data,NULL); xmlNode2->value("ert"); xmlNode->append_node(xmlNode2); xmlNode2=xmlDoc.allocate_node(rapidxml::node_element,"kk"); xmlNode2->value("uio"); xmlNode->append_node(xmlNode2); xmlNode2=xmlDoc.allocate_node(rapidxml::node_data,NULL); xmlNode2->value("bnm"); xmlNode->append_node(xmlNode2); //podobniejakatrybutynodyteżmożemydodawaćnapoczątku //prepend_node()lubnadowolnejpozycjiinsert_node() //wypisaniezmienionegodokumentu std::cout<<xmlDoc;}

importxml.etree.ElementTreeasxml#PythonoferujetakżeinnenizElementTreemodułydoobsługiXML#takżewspierająceDOM

d="""<a> <b>A<h>qwe...rty</h></b> ABCD...&amp;&apos;HIJ... <cx="q"w="pp">EEFĄ</c> <gy="zz"/> <cx="pp">123<drr="oo">456</d>7890.</c></a>"""

rootNode=xml.fromstring(d)

#pobieranieinformacjizdokumentu

print("nazwagłównegoelementuto:",rootNode.tag)print("jegozawartośćtekstowato:",rootNode.text)print("jegopełnazawartośćtekstowato:","".join(rootNode.itertext()))print("jegowartośćto:{{{{",xml.tostring(rootNode,encoding="unicode"),"}}}}")

print("jegopotomkowieto:")forcinrootNode: print("",c.tag,":",xml.tostring(c,encoding="unicode"))

print("pierwszywęzełcmaatrybuty:")try: ci=rootNode.iter("c") print(next(ci).attrib)exceptStopIteration: print("[braktakiegowęzła]")

#modyfikacjedokumentu

#zmiananazwyizawartościelementutry: ci=rootNode.iter("g") cc=next(ci); cc.tag="noweGG" cc.text="!@#$"exceptStopIteration:pass

#zmiananazwyiwartościatrybututry: ci=rootNode.iter("c") cc=next(ci); delcc.attrib["w"] cc.attrib["uu"]="123"exceptStopIteration:pass

try: cc=next(ci); #usuwaniewszystkichpotomkówdrugiego<c> cc.clear()

###PrzykładPython

Page 59: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

#jestteżremove()któreusuwawskazanyelement #usuwaniewszystkichatrybutów... cc.attrib.clear() se=xml.SubElement(cc,"kk",attrib={"aa":str(45)}) se.text="uio" se=xml.SubElement(cc,None) se.text="bnm" #możliwejestteżwstawieniewpodanymmiejscu se=xml.Element(None) se.text="ert" cc.insert(0,se)exceptStopIteration:pass

print(xml.tostring(rootNode,encoding="unicode"))

<?xmlversion="1.0"encoding="utf-8"?><!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.1//EN""http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><htmlxmlns="http://www.w3.org/1999/xhtml"xml:lang="pl"><head> <metahttp-equiv="ContentType"content="application/xhtml+xml;charset=utf-8"/></head><body>

<divid="xyz"> <p> <bid="abc">Lorem<i>ipsum</i></b>dolorsitamet,<i>consectetur</i>adipiscingelit. <ulclass="typAtypX"> <li>Sedcongue,erosquisultriciesornare,</li> <li>massasemauctorarcu,etsemperexarcuidaugue.</li> <li>Fuscepretium<i><b>turpis</b></i>massa,maximus<i>dapibus</i>sitamet.</li> <li>Nullafermentummolestiefinibus.</li> </ul>Etiamaccumsan<i>tempus</i>anteatcongue.</p> <pdata-abc="123"data-zz="0"class="az"id="q23y"> Sedfeugiatvestibulumsapienegetiaculis.<br/> Integerquismagnaneclacustemporsagittis. </p></div>

<scripttype="text/javascript">//<![CDATA[functionfff(){ console.log("wszystkieelementy<i>wdokumencie:"); vara=document.getElementsByTagName("i"); for(varj=0;j<a.length;j++){ console.log(a[j].innerHTML+"\n"); }

//modyfikacjazawartościelementuoid="abc" varb=document.querySelector("#abc"); b.innerHTML="ABC<u>ABC</u>ABC";

//potomkowierodzicawskazanegoelementu varchild=b.parentNode.firstElementChild while(child){ console.log("potomekjestwęzłem:"+child.nodeName+"\n"); if(child.nodeName=="ul"){ //jeżelijesttolista<ul> //któraposiada(wśródklasspodanychwatrybucieclass)klasę"typA" //tojąusuńidodajklasę"typB" if(child.classList.contains('typA')){ child.classList.remove('typA'); child.classList.add('typB'); } } child=child.nextElementSibling; } varc=document.querySelector("#xyz"); //drugipotomektypu<p>elementuokreślonegowzmiennejc vard=c.querySelector("p:nth-of-type(2)"); console.log("maatrybuty:") for(vari=0;i<d.attributes.length;++i){ console.log(""+d.attributes[i].name+"="+d.attributes[i].value+"\n");

///PrzykładXHTML+JavaScript

Page 60: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

} //możnateżpytaćokonkretnyatrybut console.log("abc=>"+d.getAttribute("data-abc")); //orazustawić(zarównododaćnowyjakizmienićistniejący) d.setAttribute("data-def","tyui");}

addEventListener('DOMContentLoaded',fff,false);//]]></script>

</body></html>

JSON

JavaScript Object Notation (JSON) jest tekstowym formatem wymiany danych. Podobnie jak XMLreprezentujeondrzewiastastrukturę,jednakwodróżnieniuodXMLkolejnośćelementówwdanychwejściowychniezawszeprzekładasięnakolejnośćwdanychzinterpretowanych.Wiążesiętoztymiżwyróżniasiędwatypuelementów.Pierwszyznichobejmowanywnawiasyklamrowe i składasięzpar klucz-wartość, jest on interpretowany jako słownik / tablica asocjacyjna i w jego wypadkuidentyfikacjaelementuodbywasięwyłączniepokluczu(którymusibyćunikalny),akolejnośćniemaznaczenia.Drugijestobejmowanywnawiasykwadratoweiskładasięwyłączniezkolejnychwartości,jestoninterpretowanyjakozwykłatablicalublista.

importjsonfrompprintimportpprint

a='''{"info":"bbb","ver":31,"d":[ {"a":21,"b":{"x":1,"y":2},"c":[9,8,7]}, {"a":17,"b":{"x":6,"y":7},"c":[6,5,4]}]}'''

#interpretacjanapisujakozbiorudanychwformaciejsond=json.loads(a)

#wypisaniezbiorudanychpprint(d)#pprintładnieformatujezłożonezbiorydanych

#jakwidaćjesttozagnieżdżonastrukturalistisłowników#odpowiadająca1do1temucobyłownapisie

#dostępdoposzczególnychelementów:"popythonowemu"print(d["d"][1]["b"])print(d["d"][1]["b"]["x"])print(d["d"][1]["c"][1])

#przygotowaniemnowegozbiorudanychb={'aa':'pp','b':[3,4,5],'c':d}b['e']="test"b['f']={'a':1,'b':2}

#wygenerowaniejson-owegotekstuwoparciuoniegoc=json.dumps(b,indent=1,ensure_ascii=False)print(c)

#dlaporównania:pprint(b)

wykonywanienapisu

Częstowygodniejestmiećmożliwośćwykonaniakawałkakodudanegojęzyka,któryjestzapisanywzmiennejnapisowej.Większośćjęzykówskryptowychpozwalatozrobić.Jakożefunkcjetepozwalająnawykonywaniedowolnegokodutoszczególnąostrożnośćnależyzachowaćprzekazującdonichdanewprowadzaneprzezużytkownika.

#dlakodupythonowego

###PrzykładPython

###PrzykładPython

Page 61: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

a="""print("ppp")b=13-17"""exec(a)print(b)

#dlawyrażeńa="9+7"b=eval(a)print(b)

#lubexec("c="+a)print(c)

#oczywiścienapismożepochodzićz#dowolnegoźródła,możebyćteż#treściącałegoskryptupythonowego:#exec(open("plik.py").read())

#dlakodubashowegoa='echo"ppp";b="ooo"'eval$aecho$b

#dlaobliczeńarytmetycznycha="13+17"b=$(($a))echo$b

#alternatywnieprzez#zewnętrznykalkulatornp.:b=`echo$a|bc`echo$b

<?php$a='echo"aaa";$b="cc";';eval($a);echo"\n".$b."\n";

$a='2+6';eval('$b='.$a.';');echo$b."\n";?>

//dlakodujavascripta="console.log('AAA');b='www';"

eval(a);console.log("bto:"+b+"\n");

//dlawyrażeńa="5+7"b=eval(a)console.log("bto:"+b+"\n");

PodstawoweI/OStandardowewejście/wyjście

Typowo program posiada trzy strumienie danych: jeden wejściowy (stdin) i dwa wyjściowe (stdout istderr).Jeżeliniezostałodokonaneprzekierowaniestrumieni(np.napliklubstrumieńinnegoprocesu)tostandardowewejście(stdin)powiązanejestzdanymiwprowadzanymiinteraktywniezklawiatury,astandardowe wyjście (stdout) i standardowe wyjście błędu (stderr) z danymi wyświetlanymi naterminalunaktórymuruchomionoprogram(itypowopóźniejwyświetlanymigdzieśnaekranie).

Standardowewejścieiwyjściemożebyćwykorzystywanedo:przekazywania między programami kolejnych etapów przetwarzania jakiegoś zbioru danych(zwykletekstowego):np.grepin.txt|sort>out.txt(grepwybieraliniespełniającekryteria,asortsortujewynik)interaktywnejobsługiprogramu:programpytaokolejneparametryipobierajezstandardowego

###PrzykładBash

///PrzykładPHP

///PrzykładJavaScript

Page 62: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

wyjścia(podejścienależystosowaćzrozwagągdyżtakieprogramyciężkoużywasięwskryptach-lepszymrozwiązaniemjestprzyjmowanieparametrówzliniipoleceń)

#include<stdio.h>

intmain(){ // //wyjście/wyjściewstyluC // //wykorzystywanejużwcześniejfunkcje //putsiprintfkorzystajązstdout puts("Helloworld"); printf("0x%x==%d==%.3f\n",13,13,13.0); //jeżelichcemykorzystaćzinnegostrumienia //należyużyćwariantupozwalającegonapodanie //plikudoktóregomasięodbywaćzapis: //stdout-standardowewyjście //stderr-standardowewyjściebłędu fputs("Helloworld2",stderr); fprintf(stderr,"0x%x==%d==%.3f\n",13,13,13.0); //wczytanienapisuzstandardowegowejścia: charnapis[10]; fgets(napis,10,stdin); //wczytanynapisbędziemiał9znaków+NULL-end //zapominamyoreszcieinputujeżelibyłdłuższyniż9znaków if(napis[8]!='\n'){ intc; while((c=getchar())!='\n'&&c!=EOF); } //wczytanieliczbyzstandardowegowejścia: intd; fscanf(stdin,"%i",&d); fprintf(stdout,"liczba:%dnapis:\"%s\"\n",d,napis);}

#include<iostream>#include<limits>#include<iomanip>

intmain(){ // //wyjście/wyjściewstyluC++ // //standardowewyjścieistandardowe //wyjściebłędujakostrumienieC++ std::cout<<"HelloC++world\n"; std::cerr<<"HelloC++world2\n"; //strumieniepozwalająnaprostewypisywaniezmiennych, //alejeżelichcemyformatowaćwyjścieto //pisaniajestwięcejniżwprintf intd=1363; std::cout<<"d="<<d<<"d/3="<<d/3.0<<"\n"; std::cout<<std::setprecision(3)<<1.2342; std::cout<<""<<23.567<<"\n"; //wczytanienapisuzstandardowegowejścia: charnapis[10]; std::cin.getline(napis,10); if(std::cin.fail()){ //zapominamyoreszciejeżelibyła std::cin.clear(); std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' ); }

///PrzykładC++

///PrzykładC++

Page 63: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

//wczytanieliczbyzstandardowegowejścia: std::cin>>d; std::cout<<"liczbato:"<<d; std::cout<<"napisto:\""<<napis<<"\"\n";}

importsys

#wypisywanienastandardowewyjścieprint("ABC:"+str(12)+"="+hex(12))

#beznowejliniinakońcuprint("abc",end='')

#wypisywanienastandardowewyjściebłęduprint("QWE",file=sys.stderr)

#odczytzwejściali=iter(sys.stdin)liniaA=next(li)liniaB=next(li)print("l1:"+liniaA+"l2:"+liniaB)

#możnateżzużyciemmetodyczytającejjednąlinięliniaA=sys.stdin.readline()liniaB=sys.stdin.readline()print("l1:"+liniaA+"l2:"+liniaB)

#należyzauważyćżedanewczytywanesą#liniamiizawierająznakkońcalinii

#możnatakżewramach:#forlinsys.stdin:##lubskorzystaćzmetodywczytującejcałyplik#jakolistęposzczególnychjegolinii:#ll=sys.stdin.readlines()#bądźpoprostujakojedennapis#napis=sys.stdin.read()

#jestteż:info=input("Wpiszcoś:")print(info)

f1(){ #wypisywanienastandardowewyjście echo"HelloWorld" printf"%d%.3f\n"12313.15686 #wypisywanienastandardowewyjściebłędu echo"HelloWorld2">/dev/stderr echo"ABC">/dev/stderr}

f2(){ #odczytzestandardowegowejścia #readwczytujedanezstdindopodanychzamiennych #wtakisposóbżedokolejnychzmiennychtrafiają #kolejnesłowa(napisyrozdzielanespacjąlub #tabulatorem),adoostatniejzmiennejresztanapisu #(dokońcaliniibezznakukońcalinii) whilereadab;do echo$(($a+$b)) done}

#przekierowaniastrumienistandardowych:

#wyjściezechoprzekierowywanejestnawejścief2echo-e"23\n16"|f2

###PrzykładPython

###PrzykładBash

Page 64: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

#wyjściaf1doodpowiednichplikówf1>/tmp/out.txt2>/tmp/err.txt

#użycie>>zamiast>spowodujedopisywaniedopliku#zamiastnadpisywaniajegozawartości

#połączonychwyjść(normalnegoibłędu)f1dogrepf1|&grep-vHello

#standardowewyjściemożezostaćprzechwyconei#podstawionewdanymmiejscupoprzezużycie#`polecenie`lub$(polecenie)echoXXX`ls-ld/tmp`echoXXX$(ls-ld/tmp)

#częstoteżchcemyzignorowaćstandardowewyjściei/lub#standardowewejście-możemytouzyskaćprzekierowując#jedo/dev/nullnp:grep'^root:'/etc/passwd>/dev/null

#przekierowaniewyjściacatdopliku/tmp/liczby#<<EOFpowodujeżebashpodajenastandardowe#wejściekomendy(wtymwypadku"cat")daneczytane#zskryptu(lubswojegowejścia)dopókiniewystąpi#wnowejliniisłowopodanepo<<(wtym#wypadkuEOF),jeżelisłowotojestujętew''to#wprzekazywanymtekścieniesądokonywanepodstawienia#shellowe(np.rozwijanezmienne)cat<<EOF>/tmp/liczby1313994710EOF

#przekierowaniepliku/tmp/liczby#nastandardowewejścief2f2</tmp/liczby

zewzględunaspecyfikętegojęzykawszystkocojestpozaznacznikamiphpbędziewypisywanenastandardowewyjście<?php echo"sątakżefunkcje"; print("realizującewypisywanie\n"); printf("%d%.3f\n",13,45.33221);?>

Obsługaplików

Zasadniczoobsługaplikówpodwzględemoperacjiwykonywanychpomiędzyotwarciemazamknięciemplikuniewieleróżnisięodobsługistandardowego/wejściaiwyjścia.Wzdecydowanejwiększości(jeżelinawetniewewszystkich)językówinterfejsobsługistandardowegowejściaiwyjściajestzunifikowanyzinterfejsemobsługiplików.

#include<stdio.h>

intmain(){ // //obsługaplikówwstyluC // //otwieramyplikokreślonywpierwszymargumencie, //wtrybieokreślonymwdrugimargumencie: //r-odczyt,w-zapis,a-dopisywanie, //+-dwukierunkowy(używanepor,walboa) FILE*plik=fopen("/tmp/plik1.txt","w+"); //zapisujemydopliku fputs("HelloWorld!!!\n",plik); fprintf(plik,"%.3f\n",13.13131); //jakożesątooperacjebuforowanetoabymieć

///PrzykładPHP

///PrzykładC++

Page 65: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

//pewnośćżetojestjużwplikunależywykonać //fflush(),niejesttokoniecznegdyzamykamy //plik(wtedywykonywanejestzautomatu) fflush(plik); intpoz=ftell(plik); printf("aktualnapozycjawplikuto%d\n",poz); //przewijamydopoczątku //jesttorównoważnerewind(plik); fseek(plik,0,SEEK_SET); //wczytywaniezpliku charnapis[10]; fgets(napis,10,plik); //wczytanynapisbędziemiał9znaków+NULL-end puts(napis); //powrotdopoprzedniejpozycji fseek(plik,poz,SEEK_SET); //operacjebinarne-wtensposóbmożemyzapisywać //iodczytywaćcałebuforyzpamięci,czylitakżenapisy //zapisdopliku doublex=731.54112,y=12.2; fwrite(&x,1,sizeof(double),plik); fflush(plik); //przesunieciedopozycjinaktórejzapisywaliśmy fseek(plik,poz,SEEK_SET); //iodczytzpliku... fread(&y,1,sizeof(double),plik); printf("zapisano:%f,odczytano:%f\n",x,y); //sątakżefunkcjeread()iwrite()działającewoparciuo //numerycznydeskryptorplikuuzyskiwanynp.zfunkcjiopen() //anieobiektFILEuzyskiwanyzfopen() fclose(plik);}

#include<iostream>#include<fstream>

intmain(){ // //obsługaplikówwstyluC++ // //tworzymystrumieńzwiązanyzplikiem std::fstreamplik_w; //otwieramyplikwtrybiedopisywania //alepozwalającymnamodyfikowanieobecnejtreści //abytodziałałomusibyćtostrumieńin/out plik_w.open( "/tmp/plik2.txt", std::fstream::ate|std::fstream::out|std::fstream::in ); //tworzymystrumień(typuin)związanyzplikiem... std::ifstreamplik_r; //otwieramyplikdoczytania plik_r.open("/tmp/plik1.txt"); //trybymożemybudowaćznastępującychopcji: //std::ios::in-odczyt(domyślnadlaifstream) //std::ios::out-zapis(domyślnadlaofstream) //std::ios::ate-ustawiepozycjinakoniecpliku //std::ios::app-dopisywaniebezmożliwościzmianyzawartości //std::ios::trunc-nadpisujeplik std::cout<<"PozycjawplikuOUT:"<<plik_w.tellp()<<std::endl; std::cout<<"PozycjawplikuIN:"<<plik_r.tellg()<<std::endl;

///PrzykładC++

Page 66: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

//pisanieiczytaniedokładniejakdlacincout... plik_w<<"HelloWorld!!!"; //przesunięciena16bajtblikuwejściowego plik_r.seekg(16); //iwczytanieczegoś doublex; plik_r>>x; std::cout<<"wczytano:"<<x<<"\n"; //przesunięcieo2bajtydotyłuiwczytanie plik_r.seekg(-2,std::ios::cur); //innetrybyprzesunięćto: //ios::beg-odpoczątkupliku(domyślny) //ios::end-odkońcapliku plik_r>>x; std::cout<<"wczytano:"<<x<<"\n"; plik_w.seekp(-3,std::ios::end); plik_w<<123<<"\n"; //nmakonieczamykamypliki plik_w.close(); plik_r.close();}

importos.path

#otwarcieplikudoodczytuf=open("/etc/passwd","r")#funkcjapozwalanaokreśleniekodowaniaplikupoprzez#argumentnazwany"encoding"(np.encoding='utf8'),#domyślnekodowaniezależnejestodustawieńsystemowych#możnajesprawdzićpoprzezlocale.getpreferredencoding()##jeżeliplikmabyćotwartywtrybiebinarnymanie#tekstowymkoniecznejestpodanieflagibwramach#drugiegoargumentu

#odczytpoliniil1=f.readline()l2=f.readline()

#możnatakżeczytaćzjawnymużyciemiteratorów:li=iter(f)l3=next(li)l4=next(li)

print("l1:"+l1+"l2:"+l2+"l3:"+l3+"l4:"+l4)

#albowramachpętlii=5forlinf: print(str(i)+":"+l) i+=1

#powrótnapoczątekplikuf.seek(0)

#odczytjakotablicaliniill=f.readlines()

print(ll)

f.close()

#jeżeliplikistniejeto:ifos.path.isfile("/tmp/plik3.txt"): #otwieramywtrybiedozapisuiodczytu #iustawiamysięnakońcuplikucelemdopisywania f=open("/tmp/plik3.txt","r+") f.seek(0,2)else: f=open("/tmp/plik3.txt","w")

#pobieramyaktualnąpozycjewpliku

###PrzykładPython

Page 67: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

#(którawtymwypadkujestrównadługościpliku)pos=f.tell()

#jeżeliplikmawięcejniż5bajtówifpos>5: #tocofamysięo3 f.seek(pos-3)

f.write("0123456789")

f.close()

#obsługaplikówbinarnych#wymaganejestdodanieflagibwflagachfunkcjiopen():f=open("/tmp/plik1.txt","rb")

#czytaniebajpobajciewhileTrue: b=f.read(1) ifb==b"": break print(b)

f.close()

Mapowanieplikówwpamięci

Możliwe jest także operowanie na plikach zmapowanych do pamięci z użyciem mmap, operacjewykonywanesąwtedynaichzawartościtakjaknatablicach/napisachC.

//programkorzystazmechanizmówsystemówPOSIX//imożeniedziałaćnaniekompatybilnychplatformach

#include<sys/mman.h>#include<sys/stat.h>#include<fcntl.h>#include<unistd.h>

#include<errno.h>#include<string.h>#include<stdio.h>

#define_MMAP_MODE_MAP_PRIVATE//MAP_SHARED

//MAP_PRIVATEpowodujebezwidocznościzmianwmapowanymplikudlainnychprocesów//MAP_SHAREDpozwalawspółdzielićzamapowanyobszarzinnymiprocesami,//jestwymaganeabymóczmodyfikowaćplikzużyciemmsync()

intmain(){ constchar*fname="/tmp/aaa.txt"; intfsize;

//pobieramyrozmiarpliku structstatst; if(stat(fname,&st)){ if(errno==ENOENT){ printf("plik\"%s\"nieistnieje\n",fname); fsize=0; }else{ fprintf(stderr,"Errorinstat():%s\n",strerror(errno)); //powyższezadziałajakperror() return-1; } }else{ fsize=st.st_size; }

//otwieramyplikwtrybiezapis-odczytuzyskującdeskryptor //(jeżelipliknieistniejezostanieutworzonyzprawami600) intfd=open(fname,O_RDWR|O_CREAT,(mode_t)0600); intbufSize=fsize+20; //jeżelichcemyoperowaćnawiększymbuforzeniżrozmiarplikumusimypowiększyćplik

///PrzykładC++

Page 68: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

if(ftruncate(fd,bufSize)) perror("Errorinftruncate()"); //operacjataniemawpływunazajmowanemiejscenadysku: //intfd=open("/tmp/x",O_RDWR|O_CREAT);ftruncate(fd,100000000);close(fd); //utworzyplik/tmp/xktóregorozmiarwg`ls`będzie98MBawg`du`będzie0 //alternatywniemożna: //lseek(fd,bufSize-1,SEEK_SET);write(fd,"",1);lseek(fd,0,SEEK_SET) //mapujemyplikdopamięci...wtrybieodczytuizapisu char*buf=(char*)mmap(NULL,bufSize,PROT_READ|PROT_WRITE,_MMAP_MODE_,fd,0); if(buf==MAP_FAILED){ perror("Errorinmmap()"); return-1; }

buf[fsize]=0; printf("Długośćpliku:%d\n",fsize); printf("Zawartośćpliku:%s\n",buf);

//modyfikujemyprzedostatnibajtwpliku //(jeżelitrafimynafragmentwielo-bajtowegoznakutogopopsujemy) if(fsize>2) buf[fsize-2]='X';

fsize+=snprintf(buf+fsize,bufSize-fsize,"Alamakota\n\n"); fsize+=snprintf(buf+fsize,bufSize-fsize,"KotmaAlę\n\n"); fsize+=snprintf(buf+fsize,bufSize-fsize,"czyżby...\n\n"); //doplikuchcemyzapisać"fsize"bajtówz"buf",czyli:buf[0]...buf[fsize-1] //niechcemyzapisaćkończącegonapisznakuNULL(dodawanegoprzezsnprintf), //jeżeliniedoszłodoprzepełnieniabuforaniejestonwliczanywdługość"fsize" //iznajdujesięwbuf[fsize],zatemniemakoniecznościjawnegopomijaniago // //jeżelinatomiastdoszłodoprzepełnieniabuforajestonostatnimznakiemwbuforze, //czylibuf[bufSize-1]...zatemabygopominąćnależyustawićfsize=bufSize-1 if(fsize>=bufSize){ fprintf(stderr,"Error:przepełnieniebufora\n"); fsize=bufSize-1; } printf("Nowadługośćpliku:%d\n",fsize); printf("Nowazawartośćpliku:%s\n",buf); //ustawiamyprawidłowyrozmiarpliku if(ftruncate(fd,fsize)) perror("Errorinftruncate()");#if_MMAP_MODE_==MAP_SHARED //synchronizujemyzawartośćbuforapamięcidopliku if(msync(buf,fsize,MS_SYNC)) perror("Errorinmsync()");#else //zapisujemyzmianydopliku if(write(fd,buf,fsize)<0) perror("Errorinwrite()");#endif //odmapowanieplikuzpamięci if(munmap(buf,fsize)) perror("Errorinmunmap()"); //zamknięciepliku close(fd);}

Operacjenaplikach

Często oprócz zapisywania i czytania plików zachodzi potrzeba sprawdzenia czy plik istnieje,wylistowaniaplikówzjakiegośkatalogu,zmianynazwylubusunięciapliku.Stosownefunkcjeoferujebiblioteka standardowa C (w oparciu o nie realizowane są komendy shellowe wykonujące takieoperacje), a także większość innych języków. W przypadku C++ można korzystać z bibliotekistandardowejClubbibliotekiboost(jakwponiższymprzykładzie).

//przykompilacjikoniecznejestdodanie://-lboost_filesystem-lboost_system

///PrzykładC++

Page 69: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

#include<iostream>#include<boost/filesystem.hpp>

intmain(){ //sprawdzenieczyplikistnieje boost::filesystem::pathpFile("/tmp/abc.txt"); if(boost::filesystem::is_regular_file(pFile)) std::cout<<"istnieje\n"; else std::cout<<"nieistnieje\n"; //listowaniekataloguisprawdzanietypów boost::filesystem::pathpDir("/tmp/"); boost::filesystem::directory_iteratorend_iter; boost::filesystem::directory_iteratoriter(pDir); for(;iter!=end_iter;++iter){ if(boost::filesystem::is_regular_file(iter->path())){ std::cout <<iter->path().filename().generic_string() <<"jestplikiem\n"; //wypisujemytylkonazwępliku }elseif(boost::filesystem::is_directory(iter->path())){ std::cout <<iter->path().generic_string() <<"jestkatalogiem\n"; //wypisuje,ypełnąścieżkę }else{ std::cout <<iter->path().generic_string() <<"jestczymśinnym\n"; } } boost::filesystem::rename("/tmp/a.txt","/tmp/b.txt"); boost::filesystem::remove("/tmp/b.txt");}

importos

#sprawdzenieczyplikistniejeifos.path.isfile("/tmp/abc.txt"): print("istnieje")else: print("nieistnieje")

#listowaniekataloguisprawdzanietypówdl=os.listdir("/tmp/")print(dl)

forfindl: ifos.path.isfile(f): print("\""+f+"\"jestplikiem") elifos.path.isdir(f): print("\""+f+"\"jestkatalogiem") else: print("\""+f+"\"jestczymśinnym")

#możnatakżerekurencyjniewrazzpodkatalogamiforcurrDir,dirs,filesinos.walk('/tmp'): print("podkatalogi\""+currDir+"\":") fordindirs: print(""+os.path.join(currDir,d)) print("plikiw\""+currDir+"\":") forfinfiles: print(""+os.path.join(currDir,f))

#zmiananazwyos.rename("/tmp/a.txt""/tmp/b.txt")

#usuwanieos.remove("/tmp/b.txt")

###PrzykładPython

###PrzykładBash

Page 70: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

#sprawdzenieczyplikistniejeif[-f"/tmp/abc.txt"];then echo"istnieje"else echo"nieistnieje"fi

#listowaniekataloguisprawdzanietypówforfin/tmp/*;do if[-f"$f"];then echo"\"$f\"jestplikiem" elif[-d"$f"];then echo"\"$f\"jestkatalogiem" else echo"\"$f\"jestczymśinnym" #np.kolejkąluburządzeniem... fidone

#alternatywnelistowaniekataloguls/tmp|whilereadf;do echo"/tmpzawiera:$f"done

#zmiananazwymv/tmp/a.txt/tmp/b.txt

#usuwanierm/tmp/b.txt

Argumentyliniipoleceń

System pozwala na przekazanie do uruchamianego programu zbioru argumentów / opcji, któreprogrammożedowolniezinterpretowaćiwykorzystaćwswoimdziałaniu.

Od systemu program otrzymuje nie zinterpretowaną tablicę argumentów. Za podział całego zbioruargumentów, na poszczególne elementy tablicy odpowiada program tworzący nowy proces. Typowonapisprzekazanywliniipoleceńdzielonyjestnasłowa(ciągiznaków,rozdzielanebiałymiznakami)ikażde słowo stanowi osobny element tablicy, wyjątkiem są napisy ujęte w cudzysłowia któreprzekazywanesąjakopojedynczyargument(elementtablicy).

W świecie POSIXowym przyjętym standardem jest podawanie opcji jednoliterowych po pojedynczymmyślnikuzmożliwością ichgrupowania(np.ls-la totosamocols-l-a),aopcjidługichpodwóchmyślnikach. Ewentualne argumenty opcji podawane są zaraz po opcji i w przypadku opcji krótkichoddzieloneodniejspacją,awprzypadkuopcjidługichpoznakiemrówności (np.ls--color=auto).Poopcjachwystępująargumentypozycyjne(np.listaplikówktóremawyświetlićls).

Obsługę takiego stylu przekazywania opcji do programu (w oparciu o surową tablicę argumentów)zapewniająlicznebiblioteki(takżestandardowebibliotekiróżnychjęzykówprogramowania).

//przykompilacjikoniecznejestdodanie://-lboost_program_options

#include<boost/program_options.hpp>#include<iostream>

//pełnadeklaracjafunkcjimaindlasystemówPOSIX//funkcjamainotrzymuje://-liczbęelementówtablicyargumentów//-tablicęargumentów(jesttotablicanapisówtypuC)//-tablicęzmiennychśrodowiskowychintmain(intargc,char*argv[],char*envp[]){ std::cout<<"programwywołanoz"<<argc<<"argumentami\n"; for(inti=0;i<argc;++i) std::cout<<"argument"<<i<<"to:"<<argv[i]<<"\n"; //deklaracjaopcjiliniipoleceń boost::program_options::options_descriptiondesc("Programoptions"); desc.add_options() ("help,h","showhelpmessage") ("load",boost::program_options::value<std::string>(), "loadfrom\"arg\"file") ;

///PrzykładC++

Page 71: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

//parsowanieopcjiliniipoleceńwrazzobsługąwyjątków boost::program_options::variables_mapvm; try{ boost::program_options::store( boost::program_options::parse_command_line(argc,argv,desc),vm ); boost::program_options::notify(vm); }catch(boost::program_options::error&e){ std::cerr<<"Cmdlineargserror:"<<e.what()<<"\n\n"; std::cerr<<"Use--helptoseefulloptionsdescription\n"; return2; } //przetwarzanieotrzymanychopcji if(vm.count("help")){ std::cout<<desc<<"\n"; }elseif(vm.count("load")){ std::cout<<"Loadfrom:"<<vm["load"].as<std::string>()<<"\n"; }else{ std::cout<<"Wywołanobezopcji\n"; } //jestteżfunkcjagetopt_long()zbibliotekistandardowejC //funkcjamainpowinnazwracaćkodpowrotu //typowo:gdyprogramzakończysiępowodzeniemzero //agdyzakończysiębłędem(niezerowy)kodbłędu return0;}

importargparse

#parseragumentówliniipoleceń#doargumentówmożnasięteżdostawaćbezpośredniopoprzezsys.argv:#len(sys.argv)-ilośćelementówtejtablicy#str(sys.argv[0])-napisodpowiadającynazwiewywołaniaprogramu#str(sys.argv[1])-napisodpowiadającypierwszemuargumentowiprogramu

parser=argparse.ArgumentParser(description='Opisprogramu')parser.add_argument( 'ARG',default='ABC',nargs='?', help='argumentpozycyjny(opcjonalnyzwartościądomyślną)')parser.add_argument( '-v',"--verbose",action="store_true", help='opcjatypuprzełącznik')parser.add_argument( "--input",action="store", help='opcjazargumentem')

parser.add_argument( "--vector",action="store",metavar='V',nargs='*', help='opcjazwielomaargumentami')args=parser.parse_args()

print(args)

#przetworzenieargumentówokreślonychwwywołaniugetopt#dalszeargumentydostępnesąw$1,$2,itdpozakończeniupętli#:->poprzedzającaopcjawymagaargumentu#::->poprzedzającaopcjamożemiećargument#uwagaoilewymaganeargumentymogąbyćrozdzielaneodopcjispacją#otyleopcjonalnenie(krótkienależypodawaćzarazpoopcji,#długierozdzielając=)evalset--"`getopt-oxy:z::-lopcja-x,opcja-y:,opcja-z::--"$@"`"whiletrue;docase$1in-x|--opcja-x)echo"X";shift1;;-y|--opcja-y)echo"Y,argument\`$2'";shift2;;

###PrzykładPython

###PrzykładBash

Page 72: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

-z|--opcja-z)echo"Z,argument\`$2'";shift2;;#tuataj$2możebyćpusty(gdyniepodano),alejestzdefiniowany--)shift;break;;esacdone

#innąkomendąmogącąsłużyćprzetwarzaniuopcjiskryptujestgetopts

<?php/*możliwejestużywaniephpwtrybiecommand-linejednakzewzględunaspecyfikęipodstawowezastosowaniategojęzykajesttoprzypadekdośćegzotyczny

dlategoteżzamiastobsługiopcjiprzekazywanychzliniipoleceńwprzypadkuskryptówphpwiększysensmapokazanieobsługiopcjiprzekazywanychwżądaniuHTTP*/

//wysłanieciasteczka//musibyćprzedwysłaniem//jakiejkolwiektreści$val=time();$val="tmp$val";setcookie("Ciasteczko",$val);

echo'<pre>';echo"wysłałemciasteczko:$val\n";

//tablicazawierajacazmienne//przekazanewadresieURLecho'$_GET:';print_r($_GET);

//tablicazawierajacazmienne//przekazanewitreściżądaniaecho'$_POST:';print_r($_POST);

//tablicazawierajacazmienne//przekazanewciasteczkachecho'$_COOKIE:';print_r($_COOKIE);

echo'</pre>';

?>

ProcesyiwątkiRozgałęzienieprocesu-fork()

Abywsystemiemógłdziałaćwięcejniż1proceskoniecznajestmożliwośćutworzenianowegoprocesu(potomka)zpoziomuprocesuaktualniedziałającego(rodzica).Możliwesądwapodejścia:

utworzenie"czystego"procesuuruchamiającegopodanykodprogramuzpodanymiargumentami(spawn)utworzenie kopii aktualnego procesu, która zacznie wykonywać się niezależnie od momenturozgałęzienia(fork)

W przypadku zastosowania fork proces potomny otrzymuje kopię pamięci rodzica (ma dostęp dowszystkich jego zmiennych oraz zasobów uzyskanych przed fork(); dalsze operacje na zmiennych sąniezależne).Poutworzeniukopiprocesumożna(alenietrzeba)zastąpićwykonywanywnimprograminnympoprzezfunkcjezrodzinyexec.Cechytepowodujążemechanizmforkjestbardziejelastycznyodspawn.

#include<stdlib.h>#include<unistd.h>#include<sys/wait.h>

///PrzykładPHP

///PrzykładC++

Page 73: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

#include<fcntl.h>#include<stdio.h>

voidgetInput(intfd,intpid);

intmain(){ //najprostsząmetodąuruchomieniainnegoprogramujestfunkcjasystem intretcode=system("ls-l"); printf("Programuruchomionyprzezsystem()zwróciłkodpowrotu:%d\n", WEXITSTATUS(retcode) ); //jeżelichcemyodebraćstandardowewyjście //(albozapisaćstandardowewejście)możnaskorzystaćzpopen FILE*p=popen("uname-a","r"); puts("Proceswypisałnaswójstdout:"); charbuf[256]; size_ts; while((s=fread(buf,sizeof(char),sizeof(buf),p))){ fwrite(buf,sizeof(char),s,stdout); } //tworzymyłączanienazwane-rury... inttoSys[2]; if(pipe(toSys)==-1){ perror("Errorinpipe(toSys)"); //perrorwypisujepodanykomunikatnastderrdodającdoniegoopis //błęduokreślonegoprzezerrno,możnateżpobraćidentyfikatorbłędu //lubjegoopis-szczegóływman3errno return1; } //toSys[0]-odbiórzrury //toSys[1]-wysyłanieprzezrurę intfromSys[2]; if(pipe(fromSys)==-1){ perror("Errorinpipe(fromSys)"); return1; } //rozgałęziamyproces intpid; switch(pid=fork()){ case-1:{ //funkcjazwróciła-1cooznaczabłąd perror("Errorinfork"); return1; } case0:{ //funkcjazwróciłazerocooznaczażejesteśmywprocesiepotomnym //podmieniamystdinistdoutpotomkanaodpowiednie //koniecłącznienazwanych dup2(toSys[0],0); dup2(fromSys[1],1); //zamykamykońcełącznienazwanych(tektóreużywamysąjużdostępne //jakostdin,stdout,innychniepotrzebujemy) close(toSys[0]);close(toSys[1]); close(fromSys[0]);close(fromSys[1]); //zastępujemysięinnymprocesem(wtymwypadkugerpdopasowującynapisy //zawierająceznakzzakresuA-C)-wtakisposóbwjakirobitosystem() execl("/bin/sh","sh","-c","grep--line-buffered'[A-C]'",(char*)0); //oczywiściezamiastwywoływaniainnegoprogramumożnatutajużyćwłasnego //kodupracującegorównoleglezprogramemgłównym } default:{ //funkcjazwróciłacośinnegood0i-1oznaczatożejesteśmywprocesie //macierzystymiotrzymaliśmypidnaszegodziecka... //zamykamyniepotrzebnekoncerur close(toSys[0]);close(fromSys[1]);

Page 74: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

//rurymożemyobsługiwaćjakpliki //iwtenspsóbobsługiwanajestkońcówkadozapisu FILE*pout=fdopen(toSys[1],"w"); fprintf(pout,"Alamakota\n"); fprintf(pout,"Kotmacoś\n"); fflush(pout); //możnateżjeobsługiwaćposługującsiębezpośredniodeskryptorem //itakobsługiwanajestruradoczytania //rurędoczytaniaustawiamywtrybienieblokującym fcntl(fromSys[0],F_SETFL,fcntl(fromSys[0],F_GETFL,0)|O_NONBLOCK); //czytaniezostałowyniesionejestdoosobnejfunkcjigetInput() //celemłatwiejszegojegopowtarzania getInput(fromSys[0],pid); //potomekmożepotrzebowaćtrochęczasunaprzetworzeniedanych sleep(1); getInput(fromSys[0],pid); //zamykamynaszkoniecrurydopisania //pozwolitopotomkowiczekającemunainputzakończyćsię fclose(pout); //sprawdzamyczyjestjeszczejakiśinput //(koniecznenp.gdygrepbez--line-buffered) sleep(1); getInput(fromSys[0],pid); //zamykamyrurędoczytania close(fromSys[0]); //czekamynazakończeniepotomka intppid=wait(&retcode); printf("potomekoPID=%dzakończyłsięzkodem%d\n", ppid,WEXITSTATUS(retcode) ); } }}

voidgetInput(intfd,intpid){ char*buf[256]; intlen,gLen=0;

while((len=read(fd,buf,255))>0){ buf[len]=0; gLen+=len; printf("Odebranoodpotomka%d:\n>>>>>\n%s\n<<<<<\n",pid,buf); } printf("Łącznieodebrano:%d\n",gLen);}

print("""##podstawysubprocess#""")importsubprocess

#Pythonpozwalanabezpośredniestosowaniefunkcjitakichjaksystem(),#popen(),fork(),execl()itdpoprzezmodułos...jednakzapewniateż#wygodny,zunifikowanysposóburuchamianiainnychprogramów/poleceń#powłokipoprzezmodułsubprocessorazrozgałęzianiawłasnegoprocesu#poprzezmodułmultiprocessing

#napisktóryzostaniepodanynastandardowewejścieinStr="Alamakota\nKotmapsa\n..."

#uruchamiamysubprocesszgrep'emres=subprocess.run(["grep","-v","A"],input=inStr.encode(),stdout=subprocess.PIPE)print("Kodpowrotuto:"+str(res.returncode))print("Standardowewyjściezkomendyto:"+res.stdout.decode())#wartozwrócićuwagęnakodowanieidekodowanienapisów#(przekazywanych/odbieranychprzezstdin/stdout)do/zutf-8

###PrzykładPython

Page 75: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

#jeżelichcemykorzystaćnp.zznakówuogólniającychpowłokilubpodać#komendęjakopojedynczynapis(anielistęargumentów)tomożnaużyć#opcjishell=True:subprocess.run(["ls-ld/etc/pa*"],shell=True)#jeżelipotrzebujemytylkorozbicianapisunalistęargumentówmożna#użyćshlex.split()

#run()pozwalatakże(oboksubprocess.PIPE)naprzekazywanie#istniejącychdeskryptorów(lubsubprocess.DEVNULL,coignorujewyjście)#wramachstdin,stdout,stderr

#modułsubprocessoferujetakżefunkcjęPopen()dającąwiększąkontrolę#naduruchamianiemkomendy

print("""##podstawymultiprocessing#""")importmultiprocessing,os,timedeffun1(txt,st,cnt): for_inrange(cnt): print("Proces",os.getpid(),"zst=",st,"iargumentem:",txt) time.sleep(st)

deffun2(c,e): #obsługaruryizdarzenia c.send("Uwolnićmrożonetruskawki") time.sleep(1.3) c.send([12,13,{"ab":11,"cd":"xx"}]) c.close() e.clear()

if__name__=='__main__': #przygotowaniepotomków p1=multiprocessing.Process(target=fun1,args=('Alamapsa',1.5,4,)) p2=multiprocessing.Process(target=fun1,args=('piesmakota',1,3,)) print("mójpidto",os.getpid(),"...uruchamiamprocesy") #uruchomieniepotomków p1.start() p2.start() #czekanienazakończeniep2 p2.join() print("p2sięzakończył") #wymuszeniezakończeniap1jeżelinadalżyje ifp1.is_alive(): print("p1żyje") p1.terminate() p1.join() print("p1sięzakończył") #ruraievent #Pipe()tworzynamparęobiektówmultiprocessing.Connection #jednegobędziemyużywaćwprocesiegłównym,adrugiegowpotomnym pConn,cConn=multiprocessing.Pipe() #tworzymyobiekttypuEvent...jesttoprostysygnalizator #zflagąbinarnązapewniającyatomowośćwykonywanychoperacji evt=multiprocessing.Event() evt.set() #tworzymyiuruchamiamykolejnypodproces p1=multiprocessing.Process(target=fun2,args=(cConn,evt,)) p1.start() #odbieramydanezpołączeniadopókieventjestustawiony try: whileevt.is_set(): ifpConn.poll(0.1): print("otrzymałem:",pConn.recv()) exceptEOFError:pass

Page 76: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

print("""##poolibarierawmultiprocessing#""")importmultiprocessing,queue,os,timefromthreadingimportBrokenBarrierError

deffun5Init(b): globalbariera bariera=b

deffun5(arg): foriinrange(arg['n']): print("Wątek",arg['n'],"iter=",i) time.sleep(arg['ts']) try: print("Wątek",arg['n'],"czekamnainnych") ifbariera.wait()==0: print("wątkizsynchronizowane") #więcejnieużywajtejbariery: bariera.abort() exceptBrokenBarrierError: print("czekanieanulowane") returnarg['n']+arg['ts']

if__name__=='__main__': #tworzymybarieręiwarunek b=multiprocessing.Barrier(3) #tworzymypool'a...wramachinicjalizacji #przekazujemybarieręiwarunek pool=multiprocessing.Pool( processes=3,initializer=fun5Init,initargs=(b,) ) #tworzymylistęargumentówdlafunkcji #uruchamianejwprocesachpotomuych args=[ {'n':3,'ts':0.44}, {'n':13,'ts':0.17}, {'n':2,'ts':0.33}, {'n':7,'ts':0.69}, {'n':4,'ts':0.49}, ] #tworzymypulę3procesówpotomnychiuruchamiamywnichwskazaną #funkcjęzkolejnymizbioramiargumentówzpodanejlisty #uwaga:funkcjawywoływanaprzezmapwrazzewentualnymizmiennymi #globalnymimusibyćzdefiniowanaprzedwywołaniemPool() results=pool.map(fun5,args) pool.close() pool.join()

Komunikacjamiędzyprocesowa

W systemie wieloprocesowym konieczne jest zapewnienie mechanizmów komunikacji pomiędzyprocesami,zwłaszczajeżeligrupaprocesówmarealizowaćwspólnezadanie.

Jednym z takich mechanizmów (można powiedzieć że nawet podstawowym) jest pokazane wcześniejłączenienazwane (pipe) pozwalającenaprzekazywanie strumieniadanychod jednegodo kolejnegoprocesu. Podobnie działa łącze nazwane z tym że nie jest uzyskiwane w wyniku funkcji pipe() aotwarcia specjalnego pliku (utworzonego mkfifo()) przez dwa procesy (jeden do czytania drugi dopisania).

Istnieją także inne mechanizmy komunikacji (zarówno prostsze od łącz jak i bardziej od nichzaawansowane),zktórychczęśćzostałaopisanaponiżej.

Sygnały

Najprostszą formą komunikacji międzyprocesowej są sygnały. Podstawowe sygnały niosą tylko i

Page 77: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

wyłącznieinformacjęoswoimnumerze(istniejątakżesygnałyrozszerzone,tzw.czasurzeczywistego,któreniosątakżedodatkowąwartośćliczbową).Sygnałmożezostaćwysłanyprzezdowolnyprocesdodowolnego innego procesu, przy czym warunkiem jego dostarczenia są odpowiednie uprawnienia(procesu użytkowników mogą wysyłać tylko do procesów tego samego użytkownika, root możewysyłaćdowszystkich).

Każdy sygnał ma zdefiniowane domyślne zachowanie procesu po jego otrzymaniu. Wiele sygnałówzwiązanychjestzstandardowymioperacjami(np.wciśnięcieCtrl+C,Ctrl+Z,Ctrl+/,wykonaniekill$PID) i ma odpowiednie do tego zachowania domyślne. Proces może zablokować lub zdefiniowaćwłasnąobsługęwiększości(aleniewszystkich)sygnałów.

#include<stdio.h>#include<signal.h>#include<fcntl.h>#include<time.h>#include<unistd.h>#include<errno.h>

//funkcjeobsługisygnałuvoidobslugaSygnalu(intsig){ printf("Otrzymałemsygnałnumer:%i\n",sig);}

voidakcjaSygnalu(intsig,siginfo_t*info,void*context){ printf("Otrzymałemsygnałnumer:%izkodem%diwartością%dodpid=%d\n", sig,info->si_code,info->si_value.sival_int,info->si_pid); //si_codeokreślapowódwysłaniasygnału}

intmain(){ intsig,pid; pid=getpid(); printf("MójPID=%d\n",pid); //sygnałysąasynchronicznymmechanizmemjednokierunkowejkomunikacji //systemyPOSIXoweoferujądwarodzajesygnałów-standardoweiczasurzeczywistego //sygnałyczasurzeczywistego(wodróżnieniuodstandardowychprzekazującychjedynie //numersygnału)zawierajątakżekodiwartośćorazsąpriorytetyzowane //(niższynumer=>wyższypriorytet=>dostarczanywpierwszejkolejności) //dozdefiniowaniaobsługisygnałustandardowego(dojegoprzechwycenia)służyfunkcja: signal(SIGINT,&obslugaSygnalu);//pojawiasięm.in.wefekcieCtrl+C signal(SIGTSTP,&obslugaSygnalu);//pojawiasięm.in.wefekcieCtrl+Z //oczywiściemożnadefiniowaćróżnefunkcjedlaróżnychsygnałów //zamiastwskaźnikadofunkcjimożemypodaćtakżeSIG_IGNalboSIG_DFL //cooznaczaodpowiednioignorowanietegosygnałulubjegodomyślnąobsługę //możliwejestteżmaskowaniesygnałów sigset_tsigSet; //inicjujemymaskęsygnałównapustą,napełnąbyłobysigfillset() if(sigemptyset(&sigSet)) perror("Errorinsigemptyset()"); //dodajemysygnałdomaski //możnatakżeusuwać-sigdelset()isprawdzaćczyjestobecny-sigismember() //zamaskowanySIGTERMjestdomyślnymsygnałemwysyłanymprzezkill if(sigaddset(&sigSet,SIGTERM)) perror("Errorinsigaddset()"); //ustawiamymaskęsygnałównaprzygotowaną if(sigprocmask(SIG_SETMASK,&sigSet,NULL)) perror("Errorinsigprocmask()"); //sygnałynieobsługiwaneinieblokowaneprzezprocesobsługiwanesąwsposóbdomyślny //naogółprowadzącdozakończeniaprocesu...sygnałówSIGKILL(wysyłanegoprzezkill-9) //orazSIGSTOPniemożnaprzechwycićanizamaskować //dozdefiniowaniaobsługisygnałuczasurzeczywistegosłużyfunkcjasigactionwrazzstrukturą //sigactionopisującąobsługę(możnatakdefiniowaćtakżeobsługęstandardowychsygnałów): structsigactionrtSigAct; //funkcjaobsługi(możatakżepodaćSIG_IGNalboSIG_DFL)

///PrzykładC++

Page 78: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

rtSigAct.sa_sigaction=&akcjaSygnalu; //flagi...SA_SIGINFOoznaczafunkcjęprzyjmującą3argumentyanie1jakwsignal() rtSigAct.sa_flags=SA_SIGINFO; //maskasygnałówblokowanychwtrakcieobsługisygnału...blokujemywszystkocosięda sigfillset(&rtSigAct.sa_mask); //ustawienieobsługi sigaction(SIGRTMIN,&rtSigAct,NULL); //wysłaniesygnałuczasurzeczywistego //(funkcjapozwalateżnawysyłaniestandardowychsygnałów) sigqueue(pid,SIGRTMIN,(constunionsigval)123); //oczekiwanienasygnał: puts("Czekamnadowolnysygnał"); pause(); //dodajemySIGINTdozbioru if(sigaddset(&sigSet,SIGINT)) perror("Errorinsigaddset()"); puts("Czekamnasygnałzpodanejmaski"); puts("innebędąobsługiwanealefunkcjaniezakończysię..."); printf("abykontynuowaćCtrl+Clubkill%d\n",pid); if(sigwait(&sigSet,&sig)) perror("Errorinsigwait()"); printf("Czekaniezakończonepootrzymaniusygnału:%d\n",sig); puts("Śpięprzez10s...dowolnysygnałprzerwie"); sleep(10);//jestteżusleep()dlamikrosekund puts("Czekamprzez10.5snasygnałzpodanejmaski"); siginfo_tsigInfo; structtimespectimeOut; timeOut.tv_sec=10; timeOut.tv_nsec=500000000; sig=sigtimedwait(&sigSet,&sigInfo,&timeOut); if(sig<0){ if(errno==EINTR) puts("otrzymałeminnysygnał"); elseif(errno==EINVAL) puts("timeout"); else perror("Errorinsigtimedwait()"); }else{ printf("Czekaniezakończonepootrzymaniusygnału%dodpid=%d\n", sig,sigInfo.si_pid ); } //jestteżsigwaitinfodziałającajaksigtimedwaitalebeztimeout'u}

importos,signal

pid=os.getpid()print("MójPID:",pid);

#obsługasygnałudefobslugaSygnalu(s,f): print("Otrzymałemsygnałnumer:",s)#SIGINT-pojawiasięm.in.wefekcieCtrl+Csignal.signal(signal.SIGINT,obslugaSygnalu)

#SIGTSTP-pojawiasięm.in.wefekcieCtrl+Zsignal.signal(signal.SIGTSTP,obslugaSygnalu)

print("Czekamnadowolnysygnał")signal.pause()

print("Czekamnasygnałzpodanegozbioru")#wodróżnieniuodCinnebędąobsługiwanedopieropootrzymaniu#sygnałuzezbioru(zostanązakolejkowane)sig=signal.sigwait([signal.SIGTERM,signal.SIGINT])print("Czekaniezakończonepootrzymaniusygnału:",sig)

###PrzykładPython

Page 79: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

print("Czekamprzez10.5snasygnałzpodanegozbioru")#wodróżnieniuodCinnysygnałjestobsługiwany,#alenieprzerywaczekaniasig=signal.sigtimedwait([signal.SIGTERM,signal.SIGINT],10.5)ifsig==None: print("timeout");else: print("Czekaniezakończonepootrzymaniusygnału:", sig.si_signo,"odpid:",sig.si_pid )

Kolejkikomunikatów

Wprzypadkugdygrupaprocesówmazesobąwspółpracowaćpotrzebnesąbardziejzaawansowane(od sygnałów) mechanizmy komunikacji - pozwalające na przekazywanie jakiś danych międzyprocesami.Jednymztakichmechanizmówsąkolejkiwiadomości.Wpewnymstopniusąonepodobnedo omówionych wcześniej łącz (pipe-ów), jednak w odróżnieniu od nich zamiast jednolitegostrumienia danych pomiędzy dwoma procesami (producentem i konsumentem) służą doprzekazywaniawiadomościpomiędzygrupąproducentówigrupąkonsumentów.

//przykompilacjikoniecznejestdodanie://-lrt-lpthread

#include<stdio.h>#include<mqueue.h>#include<errno.h>#include<time.h>#include<string.h>#include<unistd.h>

voidgetMsg(unionsigvalsv){ puts("kolejkaniejestjużpusta"); //tumógłbybyćrealizowanyodbiórwiadomościzkolejki}

intmain(intargc,char*argv[]){ if(argc!=3){ fprintf(stderr,"%s/nazwa1|2\n",argv[0]); return1; } charrunType=argv[2][0]; //kolejkiwiadomosciPOSIX(wiecejman7mq_overview) //kolejkamożemiećzarównowieluproducentówjakiodbiorców //razodebranawiadomośćznikazkolejki //otwarciekolejki structmq_attratrybuty; atrybuty.mq_maxmsg=3;//pojemnośćkolejki-3wiadomości atrybuty.mq_msgsize=20;//po20bajtówkażda mqd_tmsgQ=mq_open( argv[1],//nazwazasobu O_RDWR|(runType=='1'?O_CREAT|O_EXCL:0),//flagi 0770,//prawadostępu &atrybuty ); if(msgQ==(mqd_t)-1){ perror("Errorinmq_open()"); return-1; } charbuf[20]; unsignedpriorytet; structtimespectimeout; clock_gettime(CLOCK_REALTIME,&timeout); timeout.tv_sec+=2; //odbieramywiadomośćztimeoutem... //wiadomosciodbieranesąwkolejnościpriorytetów,anastępniewysłania ssize_tsize=mq_timedreceive(msgQ,buf,20,&priorytet,&timeout); //mq_receive()-wersjabeztimeoutu //mamytakżemożliwośćodbiorubeztimeoutubądźzażądaniapowiadomienia //owpisaniupierwszejwiadomościdoniepustejkolejki-mq_notify() if(size>0){

///PrzykładC++

Page 80: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

printf("odebrałem%dbajtówzpriotytetem%d:%s\n",size,priorytet,buf); }else{ if(errno==ETIMEDOUT) puts("timeout"); else perror("Errorinmq_timedreceive()"); } //ustawieniepowiadamianiaopojawieniusięwiadomościwniepustejkolejce structsigeventsev; sev.sigev_notify=SIGEV_THREAD; sev.sigev_notify_function=getMsg; sev.sigev_notify_attributes=NULL; if(mq_notify(msgQ,&sev)==-1){ perror("Errorinmq_notify()"); } //wysyłamywiadomośćdokolejki //funkcjatazawiesiprocesgdyniemamiejscawkolejcektóraniejest //otwartazO_NONBLOCKnaczasokreślonyprzeztimeout //mq_send()-wersjabeztimeout'u snprintf(buf,20,"infoAod:%d",getpid()); clock_gettime(CLOCK_REALTIME,&timeout); timeout.tv_sec+=2; if(mq_timedsend(msgQ,buf,strlen(buf),9,&timeout)) perror("Errorinmq_timedsend()"); printf("Wysłano:%s\n",buf); if(runType=='1'){ snprintf(buf,20,"infoBod:%d",getpid()); if(mq_send(msgQ,buf,strlen(buf),9)) perror("Errorinmq_send()"); printf("Wysłano:%s\n",buf); sleep(20); mq_unlink(argv[1]); //wprzypadkugdybyprogramzakończyłsiębezwykonaniamq_unlink() //(np.nasutekkill-9)koniecznejestręczneusunięcieplikówz/dev/mqueue }}

print("""##kolejkiwmultiprocessing#""")importmultiprocessing,multiprocessing.managers,queue,os,time

deffun3(q): #obsługakolejki...zakończeniemożnatakżerealizować #np.woparciuodaneotrzymanewkolejce whileTrue: ifnotq.empty(): el=q.get(block=False) #możnatakżeuruchamiaćblokującyget() #ztimeoutemlubbez... ifel[1]==None: break; else: print("potomekotrzymał",el) time.sleep(0.77)

if__name__=='__main__': #tworzymykolejkę #modułmultiprocessingzawieraswojeimplementacjekolejkiFIFO #(Queue,SimpleQueueiJoinableQueue),którychmożnabezpiecznie #używaćpomiędzyprocesami: #q=multiprocessing.Queue() # #chcemyjednakużyćkolejkipriorytetowejzmodułuqueue #(oferujetakżekolejkiFIFO(Queue)iLIFO(LifoQueue)) #abymóczniejpoprawniekorzystaćwmultiprocessing #musimyużyćjejpoprzezSyncManager'a: classManager(multiprocessing.managers.SyncManager): pass Manager.register("PrioQueue",queue.PriorityQueue)

###PrzykładPython

Page 81: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

m=Manager() m.start() q=m.PrioQueue() #dodajemyelementydokolejki q.put((100,"delfinmapsa;-)")) q.put((70,[13,17])) q.put((200,[15,{"ab":11,"cd":"xx"}])) #tworzymyiuruchamiamykolejnypodproces p1=multiprocessing.Process(target=fun3,args=(q,)) p1.start() #wkładaniedanychdokolejki time.sleep(0.404) print("dodajenowewiadomościdokolejki...") q.put((13,"ABC...icodalej")) q.put((180,"blablabla...")) #informacjadlapotomkaozakończeniuobsługikolejki print("czekamnaopróżnieniekolejki...") whileq.qsize()>0: time.sleep(0.333) #kończenie q.put((999,None)) p1.join() m.shutdown()

Pamięćwspółdzielona

Kolejnym mechanizmem komunikacji międzyprocesowej jest współdzielenie części pamięci, którepozwala na operowanie na tych samych danych przez grupę procesów (a nie tylko przekazywaniedanychodprocesudoprocesu jakwyżej opisanemetody).Przypomocy tegomechanizmumożliwejeststworzeniewłasnejimplementacjiłącz(pipe-ów)czyteżkolejekwiadomości.

W przypadku korzystania z wspólnej pamięci konieczne jest mechanizm zabezpieczenia przedmożliwością równoczesnej modyfikacji tego samego fragmentu przez kilka procesów. Pierwszymnasuwającymsięrozwiązaniemjestzastosowaniezmiennejwspółdzielonejinformującejotymżektośblokujedanyfragmentcelemjegomodyfikacjinp.:

intblokada=false;zrownoleglijKod();if(!blokada){ blokada=true; sekcjaKrytyczna(); blokada=false;}

Niestetytakierozwiązanieniegwarantujeskutecznościblokady,gdyż:1. może się zdarzyć że na dwóch rdzeniach kod jest wykonywany dokładnie równolegle i dwa

procesysprawdząwartośćzmiennej"blokada"wtejsamejchwiliadopieropotemzmieniąjejwartość(wefekcieczegoobawejdądosekcjikrytycznejwejdąobaprocesy)

2. nastąpi przełączenie procesów wykonywanych na jednym rdzeniu pomiędzy sprawdzeniemwarunku a modyfikacją zmiennej, co pozwoli wejść drugiemu procesowi do sekcji krytycznejgdypierwszyjużsprawdziłwarunekwejścia

Dlatego też korzysta się z mechanizmów systemowych (semaforów, lock'ów, etc) które zapewniająatomowość(niepodzielność)operacjisprawdzeniawartościzmiennejijejmodyfikacji.

//przykompilacjikoniecznejestdodanie://-lrt-lpthread

#include<stdio.h>#include<semaphore.h>#include<fcntl.h>#include<unistd.h>#include<sys/mman.h>#include<errno.h>#include<time.h>

#defineBUF_SIZE128

///PrzykładC++

Page 82: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

intmain(intargc,char*argv[]){ if(argc!=3){ fprintf(stderr,"%snazwa1|2\n",argv[0]); return1; } intretcode=1; charrunType=argv[2][0]; //pamięćdzielonaprzezshmimmap(więcej`man7shm_overview`) //możnabytakżeprzezmmapizwykłyplik //1)utworzeniezasobu(pliku)SHM //jeżelirunType=='1'izasóbistniejetowywołaniezakończysiębłędem //jajeżelinieistniejezostanieutworzony intshmFd=shm_open( argv[1],//nazwazasobu O_RDWR|(runType=='1'?O_CREAT|O_EXCL:0),//flagi 0770//prawadostępu ); if(shmFd<0){ perror("Errorinshm_open()"); return1; } //2)ustaleniewielkości if(ftruncate(shmFd,BUF_SIZE)){ perror("Errorinftruncate()"); gotoEND_1; } //3)zamapowaniezasobuSHMwpamięci void*addr=mmap(0,BUF_SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,shmFd,0); if(addr==MAP_FAILED){ perror("Errorinmmap()"); gotoEND_1; } //semaforyPOSIX(więcej`man7sem_overview`) //1)utworzeniesemafora //jeżelirunType=='1'isemaforistniejetowywołaniezakończysiębłędem sem_t*sem=sem_open( argv[1],//nazwazasobu O_RDWR|O_CREAT|(runType=='1'?O_EXCL:0),//flagi 0770,//prawadostępu 1//wartośćsemafora ); if(sem==SEM_FAILED){ perror("sem_open"); gotoEND_1; } int*c=(int*)addr; if(runType=='1'){ *c=0; } //próbawejściawkodzabezpieczonysemaforem if(sem_trywait(sem)){ if(errno==EAGAIN) puts("semaforniewpuszcza...trzebaspróbowaćpóźniej"); else perror("Errorinsem_trywait()"); }else{ //semaforzostałopuszczony...jesteśmywsekcjikrytycznej *c=*c+0x01; printf("c=0x%x\n",*c); sleep(3);//śpimy,tonieładniespaćwsekcjikrytycznej,aletotylkodemo... //podniesieniesemafora if(sem_post(sem)) perror("Errorinsem_post()"); } sleep(5);

Page 83: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

//czekanienamożliwośćwejściawkodzabezpieczonysemaforemztimeout'em structtimespectimeout; clock_gettime(CLOCK_REALTIME,&timeout); timeout.tv_sec+=10; if(sem_timedwait(sem,&timeout)){ if(errno==ETIMEDOUT) puts("timeout...trzebaspróbowaćpóźniej"); else perror("Errorinsem_timedwait()"); }else{ //semaforzostałopuszczony...jesteśmywsekcjikrytycznej *c=*c+0x0100; printf("c=0x%x\n",*c); sleep(5);//śpimy,tonieładniespaćwsekcjikrytycznej,aletotylkodemo... //podniesieniesemafora if(sem_post(sem)) perror("Errorinsem_post()"); } sleep(3); //czekamydoskutkunamożliwośćwejściawsekcjękrytyczną if(sem_wait(sem)){ perror("Errorinsem_timedwait()"); }else{ //semaforzostałopuszczony...jesteśmywsekcjikrytycznej *c=*c+0x010000; printf("c=0x%x\n",*c); sleep(5);//śpimy,tonieładniespaćwsekcjikrytycznej,aletotylkodemo... //podniesieniesemafora if(sem_post(sem)) perror("Errorinsem_post()"); } retcode=0; //oilewwiększościprzypadkówzwalnianieizamykaniezasobówwmomencie //kończeniaprogramuniemaznaczenia(zasobysąautomatycznieodbieraneprzez //system-pamięćbędziezwolniona,pliki,gniazdasieciowepozamykane,itd) //towprzypadkuzasobówwspółdzielonychmożemiećistotneznaczenie //np.jeżelinieusuniemyzasobuSHModanejnazwieniebędziegomożnapóźniej //otworzyćgdyużywamyflagO_CREAT|O_EXCL // //dlategowpowyższymkodziewobsłudzebłędówużywamygotodosekcjikończącej:END_2: if(runType=='1'){ //usunięciesemafora(staniesięniedostępnytakżedlainnychprocesów) sem_unlink(argv[1]); }END_1: //odmapowaniezasobuzpamięci munmap(addr,BUF_SIZE); //zamknięciezasobuSHM close(shmFd); if(runType=='1'){ //usunięciezasobuSHM(staniesięniedostępnytakżedlainnychprocesów) shm_unlink(argv[1]); } //wprzypadkugdybyjednakprogramzakończyłsiębezwykonywaniategokodu //(np.nasutekkill-9)koniecznejestręczneusunięcieplikówz/dev/shm}

print("""##współdzieleniedanychwmultiprocessing#""")importmultiprocessing,queue,os,time

deffun4(lock,l,c): #obsługazmiennejwarunkowej

###PrzykładPython

Page 84: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

foriinrange(6): #blokujemydostępdolisty c.acquire() #modyfikujemyzmiennąnaktórejmamywarunek l[0]=i #powiadamiamywszystkichotym c.notify_all() #zwalniamydostępdolisty c.release() time.sleep(0.13) #obsługalockailisty whileTrue: iflock.acquire(timeout=0.5): #jeżeliudałosięzałożyćlock'a... l[1]+=1 print("podprocess:",l) time.sleep(0.77) #zdjęcielock'a lock.release() time.sleep(0.33) else: print("podprocess:can'tlock")

if__name__=='__main__': #tworzymylocka'a,czyliblokadęwejściadosekcjikrytycznej #(zmieniającejdanewspółdzielone) lock=multiprocessing.Lock() #opróczzwykłychLock'ówPythonoferujetakże: #*RLock-Lockwktórymwątekzakładającyblokadęmożejązakładać #kolejnerazybezjejuprzedniegozwalniania,tznsekwencja: #l=RLock(); #l.acquire();l.acquire(); #cos(); #l.release();l.release(); #jestpoprawna(przyzwykłymLock'uzatrzymasięnadrugim #l.acquire()) #*Semaphore-Lockzlicznikiemdozwolonychwejśćdosekcji #krytycznejnp.l=Semaphore(value=3)pozwolina3wywołania #l.acquire()(bezl.release()) #tworzymywspółdzielonąlistę...namenagerze m=multiprocessing.Manager() l=m.list([0,1,2,3]) #tworzymyzmiennąwarunkowąużywającąlock'alock c=multiprocessing.Condition(lock) #tworzymyiuruchamiamykolejnypodproces p1=multiprocessing.Process(target=fun4,args=(lock,l,c,)) p1.start()

print("czekamynaspełnieniewarunku..."); c.acquire() whilel[0]<4: print("czekamy...l[0]=",l[0]) c.wait() c.release() print("warunekspełniony...l[0]=",l[0]); time.sleep(0.17) #obsługalisty foriinrange(3): #założenielock'a print("process:czekamnalock...") lock.acquire() #dodanieelementudolistyiwypisanie l.append(13+i) print("process:",l) time.sleep(0.69) #zdjęcielock'a lock.release() time.sleep(1.0) #zakończenie

Page 85: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

p1.terminate() p1.join() m.shutdown()

Wątki

Opróczmożliwościrozgałęzieniaprocesu(utworzeniapotomka)zużyciemnp.fork()możliwejesttakżetworzenie wątków (zwanych tez lekkimi procesami) w ramach procesu. Podstawowa różnica międzyprocesemawątkiempoleganatymiżwszystkiewątki(wramachdanegoprocesu)współdzielącałośćpamięci (przestrzeni adresowej), podczas gdy każdy z procesów posiada niezależną pamięć i conajwyżej jakiś współdzielony z innymi fragment. Każdy z wątków posiada natomiast niezależny stos(umieszczony we wspólnej przestrzeni adresowej), który jest używany m.in. do przechowywaniazmiennychlokalnych(wtymargumentówfunkcji).Jednakzewzględunaumieszczenietychdanychwwspólnej przestrzeni adresowej są one także dostępne dla innych wątków (poprzez wskaźnik lubreferencję).

//przykompilacjikoniecznejestdodanie://-lrt-lpthread

#include<pthread.h>#include<unistd.h>#include<stdio.h>#include<errno.h>#include<string.h>

structwatekInfo{ pthread_mutex_t*mut; pthread_cond_t*cond; constchar*napis; intlicznik;};

voidwypisz1(structwatekInfo*wi){ inti,l=-99,ret; for(i=0;i<4;i++){ //próbujemyzablokowaćwejścienatenkawałekkodu //możnaczekaćdoskutkuprzypomocypthread_mutex_lock() if((ret=pthread_mutex_trylock(wi->mut))!=0){ fprintf(stderr, "Wątek:errorinpthread_mutex_trylock():%s\n", strerror(ret) ); }else{ wi->licznik+=2; l=wi->licznik; pthread_mutex_unlock(wi->mut); } printf("Wątek:%s%d\n",wi->napis,l); usleep(600000); } sleep(8); pthread_exit(0);//kończydziałaniewątku}

voidwypisz2(structwatekInfo*wi){ inti; printf("Towatek:%s\n",wi->napis); pthread_mutex_lock(wi->mut); for(wi->licznik=0;wi->licznik<10;wi->licznik++){ printf(".");fflush(stdout); if(wi->licznik==5) pthread_cond_signal(wi->cond); sleep(1); } pthread_mutex_unlock(wi->mut); //zabraniamyprzerwaniawatkuwtrakcieponizszegowypisywania pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL); for(i=0;i<10;i++){ printf(".");fflush(stdout); sleep(1);

///PrzykładC++

Page 86: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

} printf("\n"); //aterazjużmożebyćanulowywany pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL); //aleodteraztylkowwyznaczonychmomentach //nafunkcjachtakichjaksleep,system,... //czytezpthread_testcancel() pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL); sleep(50); puts("koniecwypisz2"); pthread_exit(0);}

intmain(){ inti,l,ret; //przygotowaniemutex'a pthread_mutexattr_tmutAttr; pthread_mutexattr_settype(&mutAttr,PTHREAD_MUTEX_ERRORCHECK); //możemyustawić: //*PTHREAD_MUTEX_ERRORCHECKabymechanizmreagowałbłędemna //unlockowaniezalokowanegoprzezinnywątekmutexuitp, //*PTHREAD_MUTEX_RECURSIVEabyblokadanałożonaprzezwątekA //nieobowiazywalawatkuA(umożliwiatokorzystaniez //mutexówwfunkcjachrekurencyjnych) //*PTHREAD_MUTEX_NORMALlubPTHREAD_MUTEX_DEFAULT //flagitemogąsięniecoróżnićwzależnościodstosowanej //bibliotekiiużytych#defineszczegółównależyszukać //wplikachfeatures.hpthread.horazdokumentacjiman pthread_mutexattr_setprotocol(&mutAttr,PTHREAD_PRIO_NONE); //pozanicniezmieniającymPTHREAD_PRIO_NONEmamytakże: //*PTHREAD_PRIO_INHERITzabezpieczającywątkiprzedinwersją //priorytetów(priorytetpowejściudosekcjikrytycznej //jestpodwyższanydonajwyższegozpriorytetówprocesów //czekających //*PTHREAD_PRIO_PROTECTzabezpieczającyrównieżprzed //zakleszczeniemdziękipodnoszeniutegopriorytetupowyżej //najwyższegozpriorytetówprocesówczekających // //dozapobieganiainwersjipriorytetówprzydatnejestteż: //pthread_mutexattr_setprioceiling(); //inicjalizujemymutex(dladomyślnychustawieńmożnapodać //NULLjakodrugiargument) pthread_mutex_tmut; pthread_mutex_init(&mut,&mutAttr); //przygotowaniedanychdlawątku structwatekInfowInfo; wInfo.napis="Alamakota"; wInfo.licznik=10; wInfo.mut=&mut; //tworzymynowywatekuruchomiającwnimfunkcjewypisz1 //iprzekazującjakopierwszyargumenttejfunkcjiwInfo pthread_twatek; if((ret=pthread_create( &watek,0,(void*(*)(void*))wypisz1,(void*)&wInfo) )!=0 ){ fprintf(stderr,"Errorinpthread_create():%s\n", strerror(ret)); return1; } for(i=0;i<7;i++){ pthread_mutex_lock(wInfo.mut); wInfo.licznik-=1; printf("Programgłówny:%d\n",wInfo.licznik); pthread_mutex_unlock(wInfo.mut); sleep(1); }

Page 87: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

#ifdef_GNU_SOURCE //pobranieatrybutuwątku //isprawdzenieczyjestwątkiemprocesuczysystemu pthread_attr_tatrybuty; if((ret=pthread_getattr_np(watek,&atrybuty))){ fprintf(stderr,"Errorinpthread_getattr_np():%s\n", strerror(ret)); return1; } if((ret=pthread_attr_getscope(&atrybuty,&i))){ fprintf(stderr,"Errorinpthread_attr_getscope():%s\n", strerror(ret)); return1; } if(i==PTHREAD_SCOPE_PROCESS){ puts("wątekprocesu"); }elseif(i==PTHREAD_SCOPE_SYSTEM){ puts("wąteksystemu...będziewidocznywps-m:"); system("ps-m"); }else{ puts("innywątek:-o"); }#endif //możemyoczekiwaćnazakończeniewątkupoprzezwywołanie //winnymfunkcjipthread_join()umożliwiaonatakże //uzyskaniekoduzjakimzakończyłsięwątek printf("Programgłównyczekanakoniecwątku\n"); if((ret=pthread_join(watek,NULL))){ fprintf(stderr,"Errorinpthread_join():%s\n", strerror(ret)); return1; } printf("Wątekzakończyłsię\n"); //jejwywołaniejestkonieczneabywątekpozakończeniu //byłwcałościusunięty,chybażewątekzostałokreślony //jakotakidoktóregoniemożnasiędołączyćprzezwywołanie //pthread_detach()lubpodanieprzytworzeniuflagi //PTHREAD_CREATE_DETACHED //przygotowujemyzmiennąwarunkową pthread_cond_tcond; pthread_cond_init(&cond,NULL); //aktualizujemystrukturędanychdlawątku wInfo.napis="drugi"; wInfo.licznik=0; wInfo.cond=&cond; //tworzymykolejnywątek if((ret=pthread_create( &watek,0,(void*(*)(void*))wypisz2,(void*)&wInfo) )!=0 ){ fprintf(stderr,"Errorinpthread_create():%s\n", strerror(ret)); return1; } //czekamy... while(wInfo.licznik<5) pthread_cond_wait(wInfo.cond,wInfo.mut); //pthread_cond_waitzwalniataknaprawdęnachwilepodany //doniegomutexapoodebraniupthread_cond_signalna //dozorowanymprzezniegowarunkuponowniegozamyka printf("jesteśmyzawarunkiem");fflush(stdout); sleep(7); printf("zabijamywątek"); //igokończymyzzewnątrz //wzależnościodustawieńwątkuanulowaniewątkudzieje //sięnatychmiastowoalbowjednymzpunktówanulowania //zobaczfunkcjetoustawiającewwypisz2() pthread_cancel(watek);

Page 88: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

//wypadateżodebraćjegokodpowrotu pthread_join(watek,NULL); puts("aterazwatekjużnieżyje..."); //usunięciemutex'a pthread_mutex_destroy(wInfo.mut); //usunięciezmiennejwarunkowej pthread_cond_destroy(wInfo.cond);}

//przykompilacjikoniecznejestdodanie://-lboost_system-lboost_thread-lpthread#include<boost/thread/mutex.hpp>#include<boost/thread/thread.hpp>

#include<queue>#include<string>#include<iostream>

std::queue<std::string>kolejka;

classWatek1{ Watek1(constWatek1&);public: intabc; boost::mutexmutex; //boostoferujetakżemutx'apozwalającegonatworzeniekolejnych //blokadprzezwątekktóryutworzyłpierwszą-boost::recursive_mutex Watek1(){} voidoperator()(){ for(inti=0;i<8;i++){ if(mutex.try_lock()){ abc+=1; std::cout<<"wątek,abc="<<abc<<std::endl; mutex.unlock(); }else{ std::cout<<"wątekniedostałemmutex'a..."<<std::endl; } boost::this_thread::sleep(boost::posix_time::millisec(500)); } for(inti=0;i<8;i++){ boost::this_thread::sleep(boost::posix_time::millisec(700)); boost::mutex::scoped_lockscoped_lock(mutex); //powyższylock(namutexietegowątku) //blokujeodterazdokońcabloku if(!kolejka.empty()){ std::cout<<i<<")odebrałemzkolejki\ "<<kolejka.front()<<std::endl; kolejka.pop(); }else{ std::cout<<i<<")kolejkapusta"<<std::endl; } } }};

intmain(){ //przygotowaniedanychwątku Watek1wf1; wf1.abc=56; //uruchomieniewątku... //boost::ref()potrzebneboobiektyklasyWatek1sąniekopiowalne boost::threadwatek1(boost::ref(wf1)); boost::this_thread::sleep(boost::posix_time::millisec(1500)); //manipulacjadanymiwątku wf1.mutex.lock();

///PrzykładC++

Page 89: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

wf1.abc=13; boost::this_thread::sleep(boost::posix_time::seconds(1)); wf1.mutex.unlock(); //obsługakolejki wf1.mutex.lock(); kolejka.push("Alamakota"); kolejka.push("KotmaAle"); wf1.mutex.unlock(); std::cout<<"2pierwszeelementysąwkolejce"<<std::endl; boost::this_thread::sleep(boost::posix_time::seconds(4)); wf1.mutex.lock(); kolejka.push("Abecadlo"); kolejka.push("zpiecaspadlo"); wf1.mutex.unlock(); std::cout<<"2kolejneelementysawkolejce"<<std::endl; //czekamynazakończeniewątku watek1.join();}

importthreading,time#UWAGA:#wstandardowejimplementacjiCPythonwdanym#czasietylkojedenwątekmożewykonywać#kodpythonowy##wefekciestosowaniewątkówmasenstylkodla#wątkówczekającychnacoś,aniemasensudla#wątkówmającychwykonywaćsięrównolegle#(naróżnychrdzeniach)##wtakimprzypadkunależyużywaćpełnego#rozgałęzianiaprocesu(modułmultiprocessing)

deffun(txt,st): #używamylokalnejpamięcidladanegowątku daneWatku=threading.local() fordaneWatku.iinrange(4): print(txt,daneWatku.i) time.sleep(st)

#uruchomieniewątkut=threading.Thread(target=fun,args=("AA",2,))t.start();

#możnatakżezdefiniowaćtimerktóry#uruchomiwątekpozadanymczasietim=threading.Timer(3,fun,args=("BB",1.2,))tim.start()

#dlawątkówmożnastosowaćtakżemechanizmy#synchronizacjitakiejakdlamultiprocessing##ponadtowątkimożnatakżeobsługiwaćprzez#interfejsidentycznyzmultiprocessing#poprzezmultiprocessing.dummy

KomunikacjasieciowaWsystemachPOSIXowychkomunikacjasieciowawymagaotwarciatzw.gniazda(socket),przyotwarciuokreślonemuszązostać:

1. rodzina protokołów sieciowych która będzie używana (np. AF_INET dla IPv4 lub AF_INET6 dlaIPv6)

2. typkomunikacjirealizowanejzużyciemgniazda,doistotniejszychtypówzaliczyćnależy:SOCK_STREAM

oznaczającego dwukierunkową niezawodną łączność zapewniającą zachowanie kolejnościdanych(wprzypadkurodzinIPv4iIPv6będzietooznaczałoużycieTCP)

SOCK_DGRAM

###PrzykładPython

Page 90: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

oznaczającegobezpołączenioweprzesyłaniewiadomościolimitowanejdługościmaksymalnej(wprzypadkurodzinIPv4iIPv6będzietooznaczałoużycieUDP)

SOCK_RAWoznaczającegoodbieranie iwysyłaniesurowychpakietówwarstwysieciowej (pozwalam.in.naobsługępakietówICMP,swobodnemanipulowanieadresamiwpakietachIP,itd)

Opcjonalniemożezostaćokreślonykonkretnyprotokółjeżeliwramachwskazanejrodzinyiwskazanegotypuwystępujeichkilka.

Otwarcie gniazda skutkuje uzyskaniem deskryptora plikowego, na którym zależnie od parametrówprzekazanychprzytworzeniugniazdamogąbyćwykonywaneoperacjetakiejakwysyłanie/odbieraniedanych,ustawianyadresnasłuchiwania,zestawionepołączenie,itd.

UDP

User Datagram Protocol (UDP) jest protokołem działającym powyżej protokołu IP umożliwiającymprosteprzesyłaniedanychprzezsieć.PakietUDPopróczźródłowegoidocelowegoadresuIP,zawierateżźródłowyidocelowynumerportu.Numerportuokreślausługę/procesdziałającywramachhosta(określanegonumeremIP)którywygenerował/maotrzymaćdanypakiet.

PootwarciugniazdaobsługującegoUDPmożliwejest:wysyłaniedanychpodwskazanyadresIPinumerportuoczekiwanienaodbiórdanychiichodbiórwskazanieadresuinumeruportunaktórymoczekujemynadane(jeżeliniezostaniewykonane,cojesttypowewklientachUDP,będzieużytylosowynumerportu)

W UDP nie ma zestawionego połączenia zatem nie ma silnego rozróżnienia pomiędzy klientem(nawiązującympołączenie)aserwerem(odczekującymnapołączenie/odbierającymje).Jedynaróżnicapolega na tym że: klient (typowo) nie wywołuje funkcji bind() służącej do określenia adresu wraz znumerem portu używanego do odbioru danych, a zamiast tego korzysta z automatycznieprzydzielonegoprzezsystemoperacyjny(losowego)numeruportu.

#include<sys/socket.h>#include<netinet/ip.h>#include<arpa/inet.h>#include<netdb.h>#include<unistd.h>#include<signal.h>#include<sys/wait.h>

#include<stdio.h>#include<stdlib.h>#include<string.h>

#defineBUF1_SIZE256#defineBUF2_SIZE64

constchar*getAddresInfo( structsockaddr_storage*srcAddr,socklen_tsrcAddrLen,char*buf,intbufLen);

intmain(intargc,char*argv[]){ charbuf1[BUF1_SIZE],buf2[BUF2_SIZE]; intret,pid; if(argc!=3&&argc!=4){ fprintf(stderr,"USAGE:%sdstHostdstPort[listenPort]\n",argv[0]); returnEXIT_FAILURE; } //strukturazawierającaadresnaktórywysyłamy //użyciefunkcjigetaddrinfopozwalanazapewnienieobsługizarównoIPv4jakiIPv6, //atakżepodawanieadresówwpostacinumerycznejbądźprzyużyciunazw //alternatywniemożnaręcznieprzygotowywaćstrukturysockaddr_in/sockaddr_in6 //zużyciemnp.htons(),inet_aton(),... structaddrinfo*dstAddrInfo; if((ret=getaddrinfo(argv[1],argv[2],NULL,&dstAddrInfo))!=0){ fprintf(stderr,"Erroringetaddrinfo():%s\n",gai_strerror(ret)); returnEXIT_FAILURE; } //tutajmogliśmyuzyskaćkilkaadresów, //aleoptymistyczniezakładamyżepierwszybędzieOK

///PrzykładC++

Page 91: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

//utworzeniegniazdasieciowego...SOCK_DGRAMoznaczaUDP //(nagnieździezSOCK_DGRAMstandardowoniebędziewidaćbłędówICMP //związanychnp.zniedostępnościądocelowegohostalubportu) intsfd=socket(dstAddrInfo->ai_family,SOCK_DGRAM,0); if(sfd<0){ perror("Errorinsocket()"); returnEXIT_FAILURE; } if(argc==4){ //jeżelipodaneopcjonalneargumentutookreślamynajakimporciesłuchamy if(dstAddrInfo->ai_family==AF_INET6){ structsockaddr_in6listenAddr; listenAddr.sin6_family=AF_INET6; listenAddr.sin6_port=htons(atoi(argv[3])); //hosttonetworkshort(porządekbajtów),sąteżdlalonginetworktohost listenAddr.sin6_addr=in6addr_any; //in6addr_anyoznaczażenasłuchujemynakażdymadresieIPdanegohosta //(zamiasttegomożnaokreślićkonkretnyadres) if(bind(sfd,(structsockaddr*)&listenAddr,sizeof(structsockaddr_in6))){ perror("Errorinbind()"); returnEXIT_FAILURE; } }elseif(dstAddrInfo->ai_family==AF_INET){ structsockaddr_inlistenAddr; listenAddr.sin_family=AF_INET; listenAddr.sin_port=htons(atoi(argv[3])); //hosttonetworkshort(porządekbajtów),sąteżdlalonginetworktohost listenAddr.sin_addr.s_addr=INADDR_ANY; //INADDR_ANYoznaczażenasłuchujemynakażdymadresieIPdanegohosta //(zamiasttegomożnaokreślićkonkretnyadres) if(bind(sfd,(structsockaddr*)&listenAddr,sizeof(structsockaddr_in))){ perror("Errorinbind()"); returnEXIT_FAILURE; } } //określenietegowrazzuruchomieniemrecvfrom()pozwalanaoczekiwaniena //pakietyUDPnawskazanymadresieiporcie,gdybywramachobsługiodebranej //wiadomościodsyłanabyłabyodpowiedźdonadawcytobyłbyto"serwerUDP" } //abymócniezależniewysyłaćiodbieraćrozgałęziamyproces //alternatywniemożnaużyćselect()doczekanianadanezsiecilubstandardowegowejścia switch(pid=fork()){ case-1:{ //funkcjazwróciła-1cooznaczabłąd perror("Errorinfork"); return1; } case0:{ //potomekodbieraodpowiedziwnieskończonejpętli //zostaniezakończonysygnałemodrodzica while(1){ //strukturadoktórejzapisanyzostanieadresnadawcy structsockaddr_storagesrcAddr; socklen_tsrcAddrLen=sizeof(structsockaddr_storage); //informacjętąmożnawykorzystaćdoodsyłaniaodpowiedzidonadawcy //odbiórwiadomości...blokujedomomentuotrzymaniawiadomości ret=recvfrom( sfd,buf1,BUF1_SIZE,0,(structsockaddr*)&srcAddr,&srcAddrLen ); //wypisaniewiadomościzinformacjąonadawcy buf1[ret]='\0'; printf("odebrano%dbajtówod%s:%s\n", ret,getAddresInfo(&srcAddr,srcAddrLen,buf2,BUF2_SIZE),buf1 ); } } default:{ //rodzicwysyławiadomości while(fgets(buf1,BUF1_SIZE,stdin)){

Page 92: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

ret=sendto( sfd,buf1,strlen(buf1),0, dstAddrInfo->ai_addr,dstAddrInfo->ai_addrlen ); printf("wysłano:%dbajtów:%s\n",ret,buf1); } //kończymypotomkagdyskończyliśmynadawanie kill(pid,SIGTERM); wait(0); } } //zamknieciegniazda puts("KONIEC"); freeaddrinfo(dstAddrInfo); close(sfd);}

//konwersjaadresówIPv4iIPv6wrazznumeremportunanapisconstchar*getAddresInfo( structsockaddr_storage*srcAddr,socklen_tsrcAddrLen, char*buf,intbufLen){ if(srcAddrLen>sizeof(structsockaddr_storage)) returnNULL; constchar*addrStr=NULL; uint16_tport; if(srcAddr->ss_family==AF_INET){ structsockaddr_in*srcAddrPtr=(structsockaddr_in*)srcAddr; addrStr=inet_ntop(AF_INET,&(srcAddrPtr->sin_addr),buf,bufLen); port=ntohs(srcAddrPtr->sin_port); }elseif(srcAddr->ss_family==AF_INET6){ structsockaddr_in6*srcAddrPtr=(structsockaddr_in6*)srcAddr; addrStr=inet_ntop(AF_INET6,&(srcAddrPtr->sin6_addr),buf,bufLen); port=ntohs(srcAddrPtr->sin6_port); } if(addrStr){ intlen=strlen(buf); snprintf(buf+len,bufLen-len,":%d",port); } returnaddrStr;}

importsocket,sys,os,signal

iflen(sys.argv)!=3andlen(sys.argv)!=4: print("USAGE:"+sys.argv[0]+"dstHostdstPort[listenPort]",file=sys.stderr) exit(1);

#strukturazawierającaadresnaktórywysyłamydstAddrInfo=socket.getaddrinfo(sys.argv[1],sys.argv[2])

#tutajmogliśmyuzyskaćkilkaadresów,#aleoptymistyczniezakładamyżepierwszybędzieOKdstAddrInfo=dstAddrInfo[0]

#utworzeniegniazdasieciowego...SOCK_DGRAMoznaczaUDP#(nagnieździezSOCK_DGRAMstandardowoniebędziewidaćbłędówICMP#związanychnp.zniedostępnościądocelowegohostalubportu...)sfd=socket.socket(dstAddrInfo[0],socket.SOCK_DGRAM)

iflen(sys.argv)==4: #jeżelipodaneopcjonalneargumentutookreślamynajakimporciesłuchamy ifdstAddrInfo[0]==socket.AF_INET6: sfd.bind(('::',int(sys.argv[3]))) #::oznaczadowolnyadresIPv6 elifdstAddrInfo[0]==socket.AF_INET: sfd.bind(('0.0.0.0',int(sys.argv[3]))) #0.0.0.0oznaczadowolnyadres #określenietegowrazzuruchomieniemrecvfrom()pozwalanaoczekiwaniena #pakietyUDPnawskazanymadresieiporcie,gdybywramachobsługiodebranej #wiadomościodsyłanabyłabyodpowiedźdonadawcytobyłbyto"serwerUDP"

###PrzykładPython

Page 93: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

whileTrue: rdfd,_,_=select.select([sfd,sys.stdin],[],[]) ifsfdinrdfd: #odbieramyiwypisujemydanezUDP data,addr=sfd.recvfrom(4096) print("odebranood",addr,":",data.decode()); ifsys.stdininrdfd: #wczytujemystdin data=sys.stdin.readline() ifnotdata: #konczymy sfd.close() sys.exit() else: #wysyłamydanezstdin sfd.sendto(data.encode(),dstAddrInfo[4])

#alternatywniemożnaużyćfork():#pid=os.fork()#ifpid==0:# #potomekodbieraodpowiedziwnieskończonejpętli# #zostaniezakończonysygnałemodrodzica# whileTrue:# data,addr=sfd.recvfrom(4096)# print("odebranood",addr,":",data.decode());#else:# #rodzicwysyławiadomości# whileTrue:# data=sys.stdin.readline()# ifnotdata:# break# else:# sfd.sendto(data.encode(),dstAddrInfo[4])# os.kill(pid,signal.SIGTERM)# sfd.close()

TCP-klient

TransmissionControlProtocol(TCP)jestprotokołemdziałającympowyżejprotokołuIPgwarantującymniezawodność i kolejność dostarczania danych. Podobnie jak w przypadku UDP pakiety TCP oprócznumerów IP także zawierają docelowy i źródłowy numer portu, służący do identyfikacji procesuotrzymującegoinadającego.

Działanie TCP opiera się na zestawianiu (i kontrolowaniu) połączenia, w związku z tym klient pootwarciu gniazda musi nawiązać połączenie z wskazanym adresem IP i numerem portu, a dopieropotem może wysyłać lub odbierać dane (nie określając już adresów, gdyż odbywa się to w ramachnawiązanego połączenia) nawet poprzez zwykłe funkcje write() i read(). Połączenie należy zamknąćkorzystajączfunkcjiclose(),coinformujezarównonaszsystemjakiserwerozakończeniupołączenia.

#include<sys/socket.h>#include<netinet/ip.h>#include<arpa/inet.h>#include<netdb.h>

#include<unistd.h>#include<stdio.h>#include<stdlib.h>#include<string.h>

#defineBUF_SIZE256

intmain(intargc,char*argv[]){ intret,sfd; charbuf[BUF_SIZE]; if(argc!=3){ fprintf(stderr,"%sdstHostdstPort\n",argv[0]); return1; } //strukturazawierającaadresnaktórywysyłamy //użyciefunkcjigetaddrinfopozwalanazapewnienieobsługizarównoIPv4jakiIPv6, //atakżepodawanieadresówwpostacinumerycznejbądźprzyużyciunazw

///PrzykładC++

Page 94: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

//alternatywniemożnaręcznieprzygotowywaćstrukturysockaddr_in/sockaddr_in6 //zużyciemnp.htons(),inet_aton(),... structaddrinfo*dstAddrInfo; if((ret=getaddrinfo(argv[1],argv[2],NULL,&dstAddrInfo))!=0){ fprintf(stderr,"Erroringetaddrinfo():%s\n",gai_strerror(ret)); return1; } //mogliśmyuzyskaćkilkaadresów,więcpróbujemyużywaćkolejnychdoskutku structaddrinfo*aiIter; for(aiIter=dstAddrInfo;aiIter!=NULL;aiIter=aiIter->ai_next){ //utworzeniegniazdasieciowego...SOCK_STREAMoznaczaTCP sfd=socket(aiIter->ai_family,SOCK_STREAM,0); if(sfd<0){ perror("Errorinsocket()"); continue; } //łączymyzserwerem if(connect(sfd,aiIter->ai_addr,aiIter->ai_addrlen)){ perror("Errorinconnect()"); close(sfd); sfd=-1; continue; } //udałosiępołączyć...przerywamysprawdzaniekolejnychadresów break; } freeaddrinfo(dstAddrInfo); if(sfd<0){ fprintf(stderr,"Can'tconnect\n"); return1; } constchar*msg="AlamaKota\n"; if(send(sfd,msg,strlen(msg),0)<0){ //takiewywołaniesend()jestrównoważnewywołaniuwrite() perror("Errorinsend()"); return1; } //ustalamylimitczasuoczekiwanianadane13s structtimevaltimeOut; timeOut.tv_sec=13; timeOut.tv_usec=0; //tworzymyzestawdeskryptorówdlafunkcjiselect() //iumieszczamywnimdeskryptorgniazdasieciowego fd_setfdSet; FD_ZERO(&fdSet); FD_SET(sfd,&fdSet); //czekamynadanewktórymśzdeskryptorówwchodzących //wskładzestawulubtimeout select(FD_SETSIZE,&fdSet,0,0,&timeOut); //selectzmieniwartośćfdSetitimeOut... //będąonezawierałyodpowiedniozbiórdeskryptorówgotowych //doczytaniaiczasjakipozostałdo"wytimeoutowania" if(FD_ISSET(sfd,&fdSet)){ //jeżelisfdjestwzbiorzegotowychdoczytaniatoczytamy ret=read(sfd,buf,BUF_SIZE); if(ret<0){ perror("Errorinread()"); }elseif(ret==0){ puts("connectionclosebypeer"); }else{ buf[ret]='\0'; printf("odebrano%dbajtów:%s\n",ret,buf); } }else{ puts("timeout"); } //wzależnościodwymagańimplementowanegoprotokołumożnakontynuować //czekanienakolejnedanezTCPi/lubjakiegośinnegowejścia(np.stdin),

Page 95: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

//możnawysłaćkolejnedane(żądanie)doserwera,itd... // //wprzypadkuoczekiwanianadalszedane(ponownegowywołaniaselect)należy //pamiętaćoponownymustawieniufdSetitimeOut //zamknieciegniazda close(sfd);}

importsocket,select,sys

iflen(sys.argv)!=3: print("USAGE:"+sys.argv[0]+"dstHostdstPort",file=sys.stderr) exit(1);

#strukturazawierającaadresnaktórywysyłamydstAddrInfo=socket.getaddrinfo(sys.argv[1],sys.argv[2],proto=socket.IPPROTO_TCP)

#mogliśmyuzyskaćkilkaadresów,więcpróbujemyużywaćkolejnychdoskutkuforaiIterindstAddrInfo: try: print("tryconnectto:",aiIter[4]) #utworzeniegniazdasieciowego...SOCK_STREAMoznaczaTCP sfd=socket.socket(aiIter[0],socket.SOCK_STREAM) #połączeniezewskazanymadresem sfd.connect(aiIter[4]) except: #jeżelisięnieudało...zamykamygniazdo ifsfd: sfd.close() sfd=None #ipróbujemynastępnyadres continue break;

ifsfd==None: print("Can'tconnect",file=sys.stderr) exit(1);

#wysyłaniesfd.sendall("AlamaKota\n".encode())

#czekanienaodbiórrdfd,_,_=select.select([sfd],[],[],13.0)ifsfdinrdfd: d=sfd.recv(4096) print(d.decode())

#zamykaniepołączeniasfd.shutdown(socket.SHUT_RDWR)sfd.close()

TCP-serwer

Ze względu na nawiązywanie połączenia w przypadku TCP serwer wygląda i działa odmiennie odklienta.Pootworzeniugniazdaserwermusi:

1. określićadresuinumeruportunaktórymoczekujenaprzychodzącepołączenia(funkcjabind)2. określićżegniazdotoużywanejestdonasłuchiwaniapołączeńprzychodzących(funkcjalisten)3. rozpocząćoczekiwanienaodbiórpołączenia(funkcjaaccept)

Po nawiązaniu połączenia TCP (realizowanym na poziomie systemu operacyjnego) funkcja accept()zwraca nowe gniazdo związane z nawiązanym połączeniem TCP. Ma ono ustawiony adresem IP iportem używany przez klienta oraz inny (niż używany do nasłuchiwania) numer portu po stronieserwera.

#include<sys/socket.h>#include<netinet/ip.h>#include<arpa/inet.h>

#include<stdio.h>#include<stdlib.h>#include<unistd.h>

###PrzykładPython

///PrzykładC++

Page 96: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

#include<string.h>#include<signal.h>#include<sys/wait.h>

#defineBUF_SIZE256#defineQUERY_SIZE3#defineMAX_CHILD5

intchildNum=0;voidonChildEnd(intsig){ puts("odebranosygnałośmiercipotomka"); --childNum; waitpid(-1,NULL,WNOHANG);}

intmain(intargc,char*argv[]){ intres; charbuf[BUF_SIZE]; if(argc!=2){ fprintf(stderr,"USAGE:%slistenPort\n",argv[0]); returnEXIT_FAILURE; } //obsługasygnałuozakończeniupotomka signal(SIGCHLD,&onChildEnd); //utworzeniegniazdasieciowego...SOCK_STREAMoznaczaTCP intsfd=socket(PF_INET6,SOCK_STREAM,0); if(sfd<0){ perror("Errorinsocket()"); returnEXIT_FAILURE; } //ustawienieopcjigniazda...IPV6_V6ONLY=0umożliwiakorzystanieztego //samegosocketudlaIPv4iIPv6(rozszerzenieLinux-owe-naniektórych //systemachniejestmożliwedualnesłuchanieprzypomocysocketuIPv6) intopt=0;if(setsockopt(sfd,IPPROTO_IPV6,IPV6_V6ONLY,&opt,sizeof(opt))<0){ perror("setsockopt(IPV6_V6ONLY=0)"); returnEXIT_FAILURE; } //utworzeniestrukturyopisującejadres structsockaddr_in6serwer; serwer.sin6_family=AF_INET6; serwer.sin6_port=htons(atoi(argv[1])); //hosttonetworkshort(porządekbajtów),sąteżdlalonginetworktohost serwer.sin6_addr=in6addr_any; //in6addr_anyoznaczażenasłuchujemynakażdymadresieIPdanegohosta //(zamiasttegomożnaokreślićkonkretnyadres)

//przypisanieadresu... if(bind(sfd,(structsockaddr*)&serwer,sizeof(structsockaddr_in6))<0){ perror("Errorinbind()"); returnEXIT_FAILURE; }

//określeniegniazdajakoużywanegodonasłuchiwaniapołączeńprzychodzących if(listen(sfd,QUERY_SIZE)<0){ perror("Errorinlisten()"); returnEXIT_FAILURE; } while(1){ //odebraniepołączenia structsockaddr_in6from; socklen_tfromLen=sizeof(structsockaddr_in6); intsfd2=accept(sfd,(structsockaddr*)&from,&fromLen); //weryfikacjailościpotomków if(childNum>=MAX_CHILD){ printf("zadużopotomków\n"); //możnatutajtakżewysłaćinformacjeobłędzieserweradoklienta close(sfd2); continue; }

Page 97: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

//abymócobsługiwaćwielepołączeńrozgałęziamyproces intpid=fork(); if(pid==0){ //procespotomny...zajmujesiętylkonowympołączeniem, //anienasłuchaniemwięczamykamysfd close(sfd); //konwersjaadresunapostaćnapisową charfromStr[64]; snprintf(fromStr,64,"%s:%d", inet_ntop(AF_INET6,&(from.sin6_addr),buf,BUF_SIZE), ntohs(from.sin6_port) ); //obsługapołączenia printf("połączenieod:%s\n",fromStr); FILE*net; net=fdopen(sfd2,"r+"); //należałobytutajużywaćczekaniaztimeout'em... //inaczejusługajestpodatnanaatakiDoS while(fgets(buf,BUF_SIZE,net)){ printf("odebranood%s:%s\n",fromStr,buf); fputs(buf,net); } fclose(net); printf("koniecpołączeniaod:%s\n",fromStr); //zakończeniepołączeniaipotomka close(sfd2); return0; } if(pid==-1) perror("Errorinfork()"); ++childNum; close(sfd2); }

//zamknieciegniazda close(sfd);}

importsocket,select,signal,sys,os

MAX_CHILD=5QUERY_SIZE=3TIMEOUT=13BUF_SIZE=4096

iflen(sys.argv)!=2: print("USAGE:"+sys.argv[0]+"listenPort",file=sys.stderr) exit(1);

#obsługasygnałuozakończeniupotomkachildNum=0defonChildEnd(s,f): print("odebranosygnałośmiercipotomka") globalchildNum childNum-=1 os.waitpid(-1,os.WNOHANG);signal.signal(signal.SIGCHLD,onChildEnd)

#utworzeniegniazdsieciowych...SOCK_STREAMoznaczaTCPsfd_v4=socket.socket(socket.AF_INET,socket.SOCK_STREAM)sfd_v6=socket.socket(socket.AF_INET6,socket.SOCK_STREAM)

#ustawienieopcjigniazda...IPV6_V6ONLY=1wyłączakorzystanie#ztegosamegosocketudlaIPv4iIPv6sfd_v6.setsockopt(socket.IPPROTO_IPV6,socket.IPV6_V6ONLY,1)

#przypisanieadresów...#'0.0.0.0'oznaczadowolnyadresIPv4(czylitosamocoINADDR_ANY)#'::'oznaczadowolnyadresIPv6(czylitosamocoin6addr_any)sfd_v4.bind(('0.0.0.0',int(sys.argv[1])))

###PrzykładPython

Page 98: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

sfd_v6.bind(('::',int(sys.argv[1])))

#określeniegniazdjakoużywanychdoodbiorupołączeńprzychodzących#(długośćkolejkipołączeńustawionanawartośćQUERY_SIZE)sfd_v4.listen(QUERY_SIZE)sfd_v6.listen(QUERY_SIZE)

#funkcjazajmującasięodbieraniempołączeńiichobsługądefacceptConn(sfd): globalchildNum #odebraniepołączenia sfd_c,sAddr=sfd.accept() #weryfikacjailościpotomków ifchildNum>=MAX_CHILD: print("zadużopotomków-odrzucampołączenieod:",sAddr); sfd_c.send("InternalServerError\r\n".encode()) sfd_c.close() return #abymócobsługiwaćwielepołączeńrozgałęziamyproces pid=os.fork() ifpid==0: print("połączenieod:",sAddr) whileTrue: #czekanienadaneztimeout'em #abyzabezpieczyćsięprzedatakiemDoS rd,_,_=select.select([sfd_c],[],[],TIMEOUT) ifsfd_cinrd: data=sfd_c.recv(BUF_SIZE) ifnotdata: print("koniecpołączeniaod:",sAddr) break print("odebranood",sAddr,":",data.decode()); sfd_c.send(data) else: print("timeoutpołączeniaod:",sAddr) break #zamykaniepołączenia sfd_c.shutdown(socket.SHUT_RDWR) sfd_c.close() sys.exit() else: childNum+=1

#czekanienapołączeniazużyciemselect()wnieskończonejpętliwhileTrue: sfd,_,_=select.select([sfd_v4,sfd_v6],[],[]) ifsfd_v4insfd: acceptConn(sfd_v4) ifsfd_v6insfd: acceptConn(sfd_v6)

InnefunkcjesystemoweAlokacjapamięci

Zadeklarowaniezmiennejwkodzieprogramu(prawiezawsze)wiążesięzprzydzieleniemjej jakiegośobszarupamięci.Kompilatortypowozmiennelokalneumieszczanesąwobszarzepamięcinazywanymstosem (znajdują się tam też m.in. argumenty funkcji, stany rejestrów procesora w momenciewywołaniafunkcjiiadresypowrotufunkcji).

Stosposiadaograniczonyrozmiar,któregoprzekroczenie(np.naskutekzbytdługiegociąguwywołańfunkcji lub zdefiniowania zbyt dużych zmiennych lokalnych) kończy się błędem przepełnienia stosu.Rozmiarstosumożejednakbyćzmienionyzarównoprzeduruchomieniemprocesu(przypomocyulimit-s),lubwtrakciejegopracy(przypomocysetrlimit(RLIMIT_STACK,...)),podwarunkiemżemieścisięwramachogólnosystemowegolimitu.Zwiększenierozmiarustosuwpływanarozmiarpamięciwirtualnejprzydzielonej procesowi, jednak (samo w sobie) nie wpływa na rzeczywiste zużycie pamięci przezproces.

Częstonawetsamozadeklarowaniedużej tablicyniewpływanarzeczywistązajętośćpamięci,wpływmadopieroużywanietakiejtablicy:

Page 99: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<string.h>#include<sys/resource.h>

charbuf[64],*bufS;

intfun(){ inti,j,x[10000000]; for(i=0;i<17;i+=2){ for(j=0;j<20000;++j)x[i*10000+j]=j; sleep(1); system(buf); }}

intmain(){ snprintf(buf,64,"ps-o'vsize,size,rss,cmd'-p%d",getpid()); system(buf); puts("zwiększamrozmiarstosu"); structrlimitrl; rl.rlim_cur=2000000000; rl.rlim_max=rl.rlim_cur; if(setrlimit(RLIMIT_STACK,&rl)) perror("Errorinsetrlimit()"); system(buf); bufS=buf+strlen(buf); snprintf(bufS,64-(bufS-buf),"--no-headers"); fun(); *bufS='\0';system(buf);*bufS=''; fun();}

Mimomożliwościzwiększeniarozmiarustosutypowowiększebuforyczyteżobiektyalokowanesąpozastosem. W C++ stosowane są dwie techniki takie alokacji: operator new i funkcje z rodziny malloc.Alokacja pamięci poza stosem powoduje konieczność jawnego zwalniania pamięci (nie jest onazwalnianawrazzzniknięciemzmiennej)przypomocyodpowiedniooperatoradeletelubfunkcjifree.

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<string>#include<inttypes.h>

structAbc{ std::stringa; intb;private: shortc;public: Abc(){ puts("konstruktorABC"); c=123; } ~Abc(){ puts("destruktorABC"); } voidprint(){ printf("a:%s,b:%d,c:%d\n",a.c_str(),b,c); }};

structXxx{ Abcabc1; Abcabc2; inttab[9];

///PrzykładC++

///PrzykładC++

Page 100: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

intxx1; intxx2;};

intmain(intargc,char*argv[]){ inta[5],aa; //alokacjapamięci int*bb=(int*)malloc(sizeof(int)); int*cc=newint; int*c=newint[20];//tablicaalokowanadynamiczniewstyluC++ Abc*dd=newAbc; printf("nastosie:%p%p%p%p\n",&argv,&argc,&aa,a); printf("pozastosem:%p%p%p%p\n",bb,cc,c,dd); //zwalnianiepamięci free(bb); deletecc; deletec; deletedd; //alokujemywiększyobszarpamięciprzypomocymalloc'a char*x=(char*)malloc(1024); //jestteżrealloc()umożliwiającyzmianęrozmiaruzaalokowanegoobszaru //zerujemyzaalokowanąpamięć...naogółniejesttopotrzebne, //alewtymprzykładziemożesięprzydać memset(x,0,1024); //częstoprzydatnajestteżfunkcjamemcpy()kopiującawskazany //fragmentpamięciwinnemiejsce //pamięćzaalokowanązużyciemmalloc'amożemydzięki //artmetycewskaźnikowejorazrzutowaniutypówwskaźnikowych //interpretowaćwdowolnysposób... Abc*d1,*d2; int*b1,*b2; d1=(Abc*)x; d2=(Abc*)(x)+1; b1=(int*)(x+2*sizeof(Abc)); b2=b1+10; printf("rozmiarAbc:%ld==%ld==%ld\n", sizeof(Abc),(uint64_t)d2-(uint64_t)d1,(uint64_t)b1-(uint64_t)d2 ); d1->b=15; d1->print(); //jakwidaćpowstałobiekttypuAbc,aleniewykonałsiękonstruktor... //anikonstruktoryskładowych(jakstd::string),więcwywołanie: //d1->a="aabbcc"; //możesięnieudać(zakończyćsięnp.Segmentationfault) // //abyuniknąćzwiązanychztymproblemówmożemyskorzystaćzwariantu //operatoranewktóryutworzyobiektwzaalokowanejpamięci: new(d2)Abc; d2->a="aabbcc"; d2->print(); for(aa=0;aa<10;++aa) b1[aa]=aa+16; *b2=136917; //możemyteżnatakiobszarpamięci(nawetjużzapełniony) //patrzećnp.jaknastrukturę Xxx*z=(Xxx*)x; printf("%d==%d%d==%d%d==%d\n", z->tab[2],b1[2],z->xx1,b1[9],z->xx2,*b2 ); free(x);//takiezwolnienieniewywoładestruktorówdlad1id2}

Page 101: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

Czas

Bieżącyczaswsystemachkomputerowychmożebyćreprezentowanynaróżnesposoby.Wprzypadkusystemów POSIXowych jest to ilość sekund od początku epoki czyli 1970-01-01 00:00:00 UTC. Napodstawie tej wartości może zostać obliczona przez funkcje biblioteczne aktualna data i godzina wustawionej(poprzezzmiennąśrodowiskowąTZ)strefieczasowej.

#include<time.h>#include<stdlib.h>#include<string.h>#include<stdio.h>

size_ttime2str( consttime_t*time,constchar*timeZone,constchar*format, char*buf,size_tbufLen,structtm*tmPtr);

intmain(){ time_tczas1=time(0); printf("Odpoczątkuepokiupłynęło%dsekund\n",czas1); //początekepokito:1970-01-0100:00:00UTC //wynikjestniezależnyodlokalnejstrefyczasowej //(zawszewyrażanyjestwUTC) //jeżelipotrzebnajestwiększaprecyzjatomożnaużyćnp.: structtimespecczas2; clock_gettime(CLOCK_REALTIME,&czas2); printf("Odpoczotkuepokiupłyneło%dsekundi%dns\n", czas2.tv_sec,czas2.tv_nsec); //naniektórychplatformach(np.Linux)wclock_gettime() //wspieranesątakżeinnezegaryniżczasurzeczywistego //np.podająceczasmonotonicznyluboduruchomieniasystemu charbuf[128]; //korzystamyzwłasnejfunkcjitworzącejnapiswoparciuo //formatzmiennejczasowej...coprawdadoUTCjestgmtime(), //alewpołączeniuzstrftimepotrafidawaćzłewyniki //(np.dla"%s")ponadtofunkcjatakapozwalatakżena //obsługęinnychstrefczasowych time2str( &(czas2.tv_sec),"UTC","%Y-%m-%d%H:%M:%S%Z(%s)", buf,sizeof(buf),NULL ); printf("Mamyteraz:%s\n",buf); time2str( &(czas2.tv_sec),NULL,"%Y-%m-%d%H:%M:%S%Z(%s)", buf,sizeof(buf),NULL ); printf("Mamyteraz:%s\n",buf);}

size_ttime2str( consttime_t*time,constchar*timeZone,constchar*format, char*buf,size_tbufLen,structtm*tmPtr){ //jeżelipodanotmPtr!=NULLużyjpodanejstruktury, //wprzeciwnymrazieużyjlokalnej structtmtmTmp; if(!tmPtr){ tmPtr=&tmTmp; } //jeżelipodanostrefęczasowąto //zapamiętajoryginalnąstrefęiustawnową charoldTZ[128]; if(timeZone){ strncpy(oldTZ,getenv("TZ"),128); setenv("TZ",timeZone,1); tzset(); } //pobierzrozłożonyczaswustawionejstrefieczasowej localtime_r(time,tmPtr);

///PrzykładC++

Page 102: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

//zapiszsformatowanynapisdobufora bufLen=strftime(buf,bufLen,format,tmPtr); //przywróćoryginalnąstrefęczasową if(timeZone){ setenv("TZ",oldTZ,1); tzset(); } returnbufLen;}

importtimeimportos

deftime2str(t,tz=None,fmt="%Y-%m-%d%H:%M:%S%Z(%s)"): iftz: oldTZ=os.environ['TZ'] os.environ['TZ']=tz time.tzset() tm=time.localtime(t) s=time.strftime(fmt,tm) iftz: os.environ['TZ']=oldTZ time.tzset() return[s,tz]

czas=time.time()print("Odpoczątkuepokiupłynęło"+str(czas)+"sekund")#początekepokito:1970-01-0100:00:00UTC#wynikjestniezależnyodlokalnejstrefyczasowej#(zawszewyrażanyjestwUTC)

tt=time2str(czas,tz="UTC")print("Mamyteraz:"+tt[0]);

tt=time2str(czas)print("Mamyteraz:"+tt[0]);

fromdatetimeimportdatetime,timezone

dt=datetime.fromtimestamp(czas,tz=timezone.utc)print("Mamyteraz:"+dt.strftime("%Y-%m-%d%H:%M:%S%Z(%s)"))

#wcelupobraniaaktualnegoczasuzamiastfromtimestamp()#możnaskorzystaćzmetodynow()

Timery

Jeżeli program ma wykonywać jakąś czynność co określony czas może korzystać z funkcji sleep lubpodobnychcelemprzeczekaniapodanegoczasulubskorzystaćztimerówcelemotrzymaniasygnałupozadanymczasie.

//przykompilacjikoniecznejestdodanie://-lrt-lpthread

#include<time.h>#include<signal.h>#include<stdio.h>#include<unistd.h>#include<errno.h>

voidonTimer(intsig){ puts("timer!!!"); //drzemka0.35s //dospaniamożnawykorzystaćusleep(),sleep()lubnanosleep() //usleepisleepdziałająbardzopodobnie

###PrzykładPython

///PrzykładC++

Page 103: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

//(ztymżepierwszyprzyjmujeczaswsekundach,adrugiwmikrosekundach) usleep(350000);}

intmain(){ //obslugujemysygnałSIGALRM signal(SIGALRM,&onTimer); //najprostrzytimer... alarm(4);pause(); //timeryPOSIX(wiecejmantimer_settime) //1)tworzymytimer timer_ttimer; timer_create(CLOCK_REALTIME,NULL,&timer); //podaniewskaźnikanastrukturęsigeventzamiastNULLpozwalanaokreślenie //innegosygnałujakimawygenerowaćtimerlubobsługętakjakwątku //(więcejw`man7sigevent`) //2)konfiguryujemytimer structitimerspectSpec; //pierwszewykonanietimerapo100ms tSpec.it_value.tv_sec=0; tSpec.it_value.tv_nsec=100000000; //kolejneco1s //(jezeliit_intervalbędziewyzerowanetotimerwykonasiętylkoraz) tSpec.it_interval.tv_sec=1; tSpec.it_interval.tv_nsec=0; //3)uruchamiamytimer //drugimargumentemsąflagi-flagaTIMER_ABSTIMEpozwalana //ustawienietimeranaczasabsolutny(anieokresczasu) timer_settime(timer,0,&tSpec,NULL); chari=0; do{ structitimerspectRest; timer_gettime(timer,&tRest); printf("dotimerapozostało:%dns\n",tRest.it_value.tv_nsec); pause();//czekamynatimer printf("aktualnaliczbautraconychtyknięćtimerawynosi%d\n", timer_getoverrun(timer)); }while(i++<3); //powyższametodazapewniarozpoczynaniewrównychodstępachczasu... //wprzypadkuzastosowaniasleep()należałobyobliczaćczasprzezktóry //wykonywałsiękodiodejmowaćgoodczasuktórypodajemydosleep() //drzemka //nanosleeppozwalanaokreśleniesekundimilisekundorazzwracaczas //różnicępomiędzyplanowanymczasemspaniaarzeczywistymczasem //odwejściadopowrotuzfunkcjinanosleep()-uwzględniającnp.czas //obsługisygnałuktóryprzerwałdziałaniefunkcjinanosleep() structtimespecdrzemka,pobudka; drzemka.tv_sec=2; drzemka.tv_nsec=100000000; //chcemyspac2.1saleobudzinastimer //toilezesmyniedospalizostaniezapisanewpobudka if(nanosleep(&drzemka,&pobudka)<0&&errno==EINTR) printf("niedospalismy:%dsi%dns\n",pobudka.tv_sec,pobudka.tv_nsec); //usuniecietimera timer_delete(timer);}

BibliotekiCelem uniknięcia konieczności wielokrotnego tworzenia funkcji realizujących te same zadania wprogramowaniu powszechnie wykorzystuje się różnego rodzaju biblioteki programistyczne. Bibliotekajest zbiorem funkcji i powiązanych z nimi typów danych oraz danych. Praktycznie każdy z językówoferuje zbiór podstawowych funkcji zgromadzony w tzw. bibliotece standardowej, oprócz bibliotekistandardowejdanegojęzykamożnakorzystaćtakżezzewnętrznych(wtymwłasnych)bibliotek.

Page 104: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

Bibliotekaposiadaokreślonyinterfejsprogramistyczny(API),definiowanynapoziomiekoduźródłowego,którywprzypadkuprogramówwC/C++jestzazwyczajopisanywplikachnagłówkowychzwiązanychzdaną biblioteką (najczęściej z rozszerzeniem .h). Zmiany API biblioteki wraz z kolejnymi jej wersjamimogą(aleniemuszą-zależyodzachowywaniatzw.kompatybilnościwstecznejprzeztwórcówbiblioteki)wymagaćzmianwprogramachzniejkorzystających.Interfejsbibliotekitypowodostępnyjestnatywnietylkodlajęzykawktórymzostałastworzona.Dlainnychjęzykówwymagaonobudowaniawtakispsóbabybyłzrozumiałydlakompilatora/interpretaradanegojęzyka,zadanietorealizujątzw.wrappery.

OpróczAPIbibliotekiposiadają takżeokreślony interfejsbinarny (ABI),któryodpowiadazamożliwośćwywoływania odpowiednich procedur z biblioteki przez skompilowany i zlinkowany program. TypowoABI jest mniej stabilne od API i zmiany wymagające skompilowania i zlinkowania programu z nowąwersjąbibliotekizachodzączęściejniżzmianyAPIniezachowującekompatybilnościwstecznej.

Kod biblioteki może być włączony na stałe w kod programu (biblioteka statyczna) - zapewnia to brakproblemówzzgodnościąABIbibliotekipomiędzysystememnaktórymprogramzostał skompilowany izlinkowany, a systemem na którym jest uruchamiany. Skutkuje to jednak wzrostem rozmiaru plikuwykonywalnegoorazzapotrzebowaniemnapamięćuruchomionegoprogramu.Alternatywąsąbibliotekiładowanedynamicznie, któredostarczane są jakoosobne (w stosunkucodobinarki programu)pliki iładowanedopamięciwmomenciestartuprogramulubpodczasjegodziałania.Kilkaróżnychprogramówużywających tej samej biblioteki dynamicznej będzie używało jednej jej kopi umieszczonej w pamięciRAM.

API,skrypty,...APIpythonowebibliotekiC++

Podstawowy interpreter Pythona stworzony jest w C, podobnie wiele z popularnych modułów(bibliotek)pythonowychjesttworzonywClubC++.PythonpotrafikorzystaćzzwykłychbibliotekC(poprzez moduł ctypes), jednak aby z biblioteki korzystało się wygodnie powinna ona wystawiaćbardziejnatywnyinterfejspythonowywpostacimodułu.NautworzenietakiegointerfejsuzpoziomuCpozwalabibliotekaprogramistycznadostarczanawrazzPythonem,wprzypadkuC++możnatakżekorzystaćzobudowującegowywołaniatejbibliotekiboost::python.

/*PLIK:py_api.cppkompilacja: g++--std=c++11-shared-fPIC-I/usr/include/python3.7m/py_api.cpp\ -oMyPyAPI.so-lpython3.7m-lboost_python37 uwaga:-kolejnośćargumentówmożebyćistotna -plikwynikowypowinienmiećtakąsamąnazwęjakmoduł zadeklarowanyprzypomocyBOOST_PYTHON_MODULE()*/

#include<iostream>#include<string>#include<list>

std::stringf1(inta){ for(inti=0;i<a;++i) std::cout<<"Alamakota\n"; return"KotmaAlę";}

structK1{ inta; staticK1*obj; intf1(intb){returna+b;} staticK1*get(){returnobj;}};

voidf2(K1&k,intn){ std::cout<<"runf2():"<<k.f1(2*n)<<"\n"; k.a+=1;}

K1*K1::obj=NULL;

#include<boost/python.hpp>

BOOST_PYTHON_MODULE(MyPyAPI){ boost::python::def("f1",f1); boost::python::class_<K1>("Klasa") .def_readwrite("a",&K1::a) .def("f1",&K1::f1)

///PrzykładC++

Page 105: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

//wpythoniewodróżnieniuodC++referencjadoklasyjestjawnym //argumentemmetodniestatycznychzatemf2któreprzyjmujejako //pierwszyargumentreferencjędoobiektuklasyK1możemyużyć //jakometodyklasypythonowej .def("f2",f2) //typozfunkcjidopythonazwracanajestwartośćzmiennej(anie //referencjadozmiennejC++)jednakdlafunkcjizwracających //wskaźniklubreferencjęnaogółchcemyabyzwracanabyławłaśnie //referencjadoistniejącejzmiennejC++ .def("get",&K1::get, boost::python::return_value_policy< boost::python::reference_existing_object >() ) ; //f2możemyteżużyćjakoniezależnejfunkcji boost::python::def("f22",f2); //podobniejakf1 boost::python::def("f11",&K1::f1);}

#skryptwykorzystującymoduł#MyPyAPIstworzonywC++

#dodajemybierzącykatalogdościeżkiwktórejpythonszukabibliotekimportsyssys.path.append('./')

#importujemynasząbibliotekę(zplikuMyPyAPI.so)importMyPyAPI

#uruchomieniefunkcjif1iodebraniewynikuret=MyPyAPI.f1(2)print(ret)

#utworzenieobiektuklasyK1(Klasa)kk=MyPyAPI.Klasa()

#orazjegoużywanie...kk.a=3print(kk.f1(2))

kk.f2(1)MyPyAPI.f22(kk,1)print("kk.a=",kk.a)

print(MyPyAPI.f11(kk,1))

#skryptużywającybibliotekiC#bezAPIpythonowego

#skryptpowodujewłączenieNumLock#przypracywtrybiegraficznym#zgodnymzX11

fromctypesimport*X11=cdll.LoadLibrary("libX11.so.6")

X11.XOpenDisplay.restype=c_void_pdisplay=X11.XOpenDisplay(None);X11.XkbLockModifiers( c_void_p(display),c_uint(0x0100), c_uint(16),c_uint(16))X11.XCloseDisplay(c_void_p(display))

interfejsskryptowyprogramuC++

W wielu przypadkach zachodzi potrzeba połączenia zalet programów kompilowanych (szybkośćdziałania) i interpretowanych (elastyczność, łatwość modyfikacji). Jednym z rozwiązań toumożliwiających jest utworzenie w ramach kodu kompilowanego C++ interfejsu modułu

###PrzykładPython

###PrzykładPython

Page 106: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

pythonowego, przy jednoczesnej możliwości zapewnienia wywoływania skryptów pythonowych zpoziomukoduC++korzystającychdokomunikacjiztymkodemztegointerfejsu.

/*PLIK:py_run.cppkompilacja: g++-I/usr/include/python3.7m/py_run.cpp-lpython3.7m-lboost_python37 uwaga:-kolejnośćargumentówmożebyćistotna -plikużywa"py_api.cpp"zpoprzedniegoprzykładu -plikwywołujeskrypt"py_run.script.py"zbieżącegokatalogu*/

//korzystamyzwcześniejprzygotowanego(w"APIpythonowebibliotekiC++")interfejsupythonowego#include"py_api.cpp"

intmain(int,char**){ K1*o1=newK1(); o1->a=1;

K1*o2=newK1(); o2->a=2; K1::obj=o1;

std::cout<<"o1->a="<<o1->a<<"o2->a="<<o2->a<<"\n"; //initialisepython Py_Initialize(); try{ //initialiseandimportMyPyAPImodule PyObject*module=PyInit_MyPyAPI(); PyDict_SetItemString(PyImport_GetModuleDict(),"MyPyAPI",module); Py_DECREF(module); PyRun_SimpleString("importMyPyAPI"); //poprzezPyRun_SimpleStringmożnateżuruchamiaćinnefragmentykodupythonowego //preparetorunscripts boost::python::objectmain=boost::python::import("__main__"); boost::python::objectglobal(main.attr("__dict__")); //exportobjecttopython global["ck1"]=boost::python::ptr(o1); //runfile boost::python::objectresult=boost::python::exec_file( "./py_run.script.py",global,global ); //importobjectfrompython boost::python::objectscript=global["script1"]; //runpythonfunctionwithargsfromC++ if(!script.is_none()){ //runscripts std::cout<<"RUN\n"; std::cout<<"return="<<boost::python::extract<int>( script(boost::python::ptr(o2)) )<<"\n"; } }catch(boost::python::error_already_set&){ PyErr_Print(); exit(-1); } std::cout<<"o1->a="<<o1->a<<"o2->a="<<o2->a<<"\n"; deleteo1; deleteo2; return0;}

#PLIK:py_run.script.py#uruchamianyprzezkodC++zpy_api.cpp

///PrzykładC++

###PrzykładPython

Page 107: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

print("początekpliku.py")

ck0=MyPyAPI.Klasa.get()print("ck0:",ck0.f1(0))print("ck1:",ck1.f1(0))

ck0.a=4print("ck0:",ck0.f1(0))print("ck1:",ck1.f1(0))

defscript1(arg): print("runscript1") print("ck0:",ck0.f1(0)) print("ck1:",ck1.f1(0)) print("arg:",arg.f1(0)) arg.a=13 print("ck0:",ck0.f1(0)) print("ck1:",ck1.f1(0)) print("arg:",arg.f1(0)) print("endscript1") returnarg.a+ck0.a;

print("koniecpliku.py")

Bazydanych

StandardowymjęzykiemużywanymdokomunikacjizsystemamibazodanowymijestSQL.Pomimojegostandaryzacjiistniejąróżnicewskładnizapytańdlaposzczególnychsilnikówbazodanowych(takichjak:MariaDB,PostgreSQL,SQLite,...).

Typowo komunikacja z bazą danych odbywa się za pośrednictwem biblioteki odpowiedzialnej zanawiązanie połączenia z serwerem i przekazywanie do niego zapytań SQL. Wymaga to działaniaosobnego procesu (często nawet na innej maszynie) obsługującego silnik bazodanowy, co jestpożądanym rozwiązaniem dla baz danych z których równocześnie może korzystać wielu klientów.Typowymprzykłademmożebyćkomunikacjaskryptówjakiegośserwisuinteretowegozbaządanych.Jednak takie podejście nie jest wygodne w rozwiązaniach nie wymagających współdzielenia bazydanych.DozastosowańtakichmożnaużyćbibliotekiSQLite,którapozwalanałatwestosowaniebazySQLowej do wewnętrznych potrzeb aplikacji, bez konieczności uruchamiania osobnego systemubazodanowego.

//przykompilacjikoniecznejestdodanie://-lsqlite3

#include<sqlite3.h>#include<stdio.h>

/*bazęmożnautworzyćzarównowponiższymkodziepoleceniamiSQL,*jakteżzpoziomupowłoki:cat<<EOF|sqlite3example.dbCREATETABLEposts(pidINTPRIMARYKEY,uidINT,textTEXT);INSERTINTOpostsVALUES(1,21,'abc..');INSERTINTOpostsVALUES(3,2671,'test');EOF*/

intmain(){ sqlite3*db; if(sqlite3_open("example.db",&db)){ fprintf(stderr,"Can'topendatabase:%s\n",sqlite3_errmsg(db)); sqlite3_close(db); return1; } sqlite3_stmt*stmt; intret=sqlite3_prepare_v2(db, "SELECTuid,textFROMposts", -1,&stmt,NULL ); while((ret=sqlite3_step(stmt))==SQLITE_ROW){

///PrzykładC++

Page 108: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

intuid=sqlite3_column_int(stmt,0); constchar*text=(constchar*)sqlite3_column_text(stmt,1); printf("uid=%d,text:%s\n",uid,text); }}

importsqlite3importos.path

ifos.path.isfile('example.db'): create=Falseelse: create=Trueconn=sqlite3.connect('example.db')c=conn.cursor()

ifcreate: print("createnewdb") c.execute("CREATETABLEusers(uidINTPRIMARYKEY,nameTEXT);") c.execute("CREATETABLEposts(pidINTPRIMARYKEY,uidINT,textTEXT);") c.execute("INSERTINTOusersVALUES(21,'userA');") c.execute("INSERTINTOusersVALUES(2671,'userB');") c.execute("INSERTINTOpostsVALUES(1,21,'abc..');") c.execute("INSERTINTOpostsVALUES(2,21,'qwexyz');") c.execute("INSERTINTOpostsVALUES(3,2671,'test');")

conn.commit()

maxUid=100forrinc.execute("SELECT*FROMusersWHEREuid<?;",(maxUid,)): print(r)

forrinc.execute("""SELECTu.name,p.textFROMusersASuJOINpostsASpON(u.uid=p.uid);"""): print(r)

<?php$sql_conn=mysqli_connect('server','user','password','database');if(!$sql_conn){ echo"ERROR:".mysqli_connect_error(); exit;}else{ echo"ConnectedtoMySQL:".mysqli_get_host_info($sql_conn);}

$query=$db->query("SELECTu.name,p.textFROMusersASuJOINpostsASpON(u.uid=p.uid);");while($row=$query->fetch_array()){ print($row["name"].":".$row["text"]."\n");}?>

(Graficzny)interfejsużytkownika

Jeżeli zachodzi potrzeba interakcji z użytkownikiem programu, zamiast wspomnianego wcześniejprostegopytania o kolejneparametry z użyciem standardowego wyjścia iwejścia, często stosuje siępseudo-graficzny lub graficzny interfejs użytkownika. Interfejs pseudo-graficzny jest zasadniczobardziejwyrafinowanąformąinterakcjiprzezstandardowewyjścieiwejścieprogramuiwykorzystujestandardowewyjściedorysowaniaróżnegotypuokienekdialogowych,itp.wtrybietekstowym.

#interfejspseudograficznyzużyciembibliotekicurces...#ataknaprawdęprogramudialogzniejkorzystającego

fromdialogimportDialogfromtimeimportsleep

d=Dialog(dialog="dialog")#taknaprawdęjesttowraper

###PrzykładPython

///PrzykładPHP

###PrzykładPython

Page 109: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

#wykorzystującyprogramonazwie"dialog"##jestwstanie(wograniczonymzakresie)#współpracowaćzinnymitegotypunarzędziami#(takżedziałającymiwtrybiegraficznym)#takimijak:whiptail,kdialog,...#d=Dialog(dialog="kdialog",compat="kdialog")

d.set_background_title("ABC...")

res=d.yesno("TakczyNIE?")

ifres==d.OK: d.msgbox("TAK!!!")else: d.msgbox("NIE!!!")

d.gauge_start("proszęczekać...będzierozmowa...")foriinrange(0,101,5): d.gauge_update(i) sleep(1)

#interfejspseudograficznyzużyciemQt4

importsysfromPyQt4importQtGui,QtCore

app=QtGui.QApplication(sys.argv)

win=QtGui.QWidget()win.resize(250,150)win.move(300,300)win.setWindowTitle('ABC...')

defshowDialog(): reply=QtGui.QMessageBox.question(None,'Message', "Takczynie?",QtGui.QMessageBox.Yes| QtGui.QMessageBox.No,QtGui.QMessageBox.No) ifreply==QtGui.QMessageBox.Yes: print("YES") elifreply==QtGui.QMessageBox.No: print("NO") else: print("cosinnego?!")

button=QtGui.QPushButton('Nacisnijmnie',win)button.clicked.connect(showDialog)button.resize(button.sizeHint())button.move( 250/2-button.sizeHint().width()/2, 150/2-button.sizeHint().height()/2)

win.show()

#interfejspseudograficznyzużyciemGtk3

importgigi.require_version("Gtk","3.0")fromgi.repositoryimportGtk

window=Gtk.Window(title="HelloWorld")

defshowDialog(caller): dialog=Gtk.MessageDialog(window,0, Gtk.MessageType.QUESTION,Gtk.ButtonsType.YES_NO, "Ważnepytanie!!!") dialog.format_secondary_text("Takczynie?") response=dialog.run() ifresponse==Gtk.ResponseType.YES: print("TAK!!!") elifresponse==Gtk.ResponseType.NO: print("NIE!!!")

###PrzykładPython

###PrzykładPython

Page 110: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

else: print("bezodpowiedzi!?") dialog.destroy()

button1=Gtk.Button("Nacisnijmnie")button1.connect("clicked",showDialog)

window.add(button1)

window.show_all()window.connect("delete-event",Gtk.main_quit)Gtk.main()

ProgramowaniesprzętuTypowo programy komputerowe uruchamiane są pod kontrolą jakiegoś systemu operacyjnego, któryodpowiada za realizację sporej części funkcji określonych przez bibliotekę standardową (np. operacjiplikowych, standardowegowejścia iwyjścia) oraz zapewniamożliwość równoczesnegodziałaniawieluprocesów (ich przełączania). Jednak niekiedy zachodzi potrzeba stworzenia programu który będziedziałał bezpośrednio na sprzęcie bez pośrednictwa systemu operacyjnego. Może to mieć miejsce np.wtedy gdy zasoby danej platformy sprzętowej są zbyt ograniczone aby uruchomić na niej systemoperacyjnyinasząaplikacjęlubtworzymysystemoperacyjny.

Przerwania

Przerwanie (żądanie przerwania, IRQ) jest sygnałem powodującym wstrzymanie wykonywaniaaktualnego kodu i wykonanie zdefiniowanej (dla danego przerwania) procedury jego obsługi.Przerwaniamogąbyćzwiązanez:

sygnałemotrzymanymodzewnętrznegoukładu(tzw.przerwaniasprzętowe)-mającenacelunp.poinformowanie o zakończeniu jakiejś operacji wejścia wyjścia, otrzymaniu danych na jakimśinterfejsie,wykonywanym kodem (tzw. przerwania programowe) - zarówno wywołane celowo (np. celemkomunikacjizsystememoperacyjnym),jakteżpojawiającesięnaskuteknietypowych/błędnychdziałań-tzw."wyjątki"(np.dzieleniaprzezzero).

Na wielu architekturach program może wygenerować dowolne z przerwań (także tych związanych zsprzętem,czyteżwyjątków)poprzezwywołaniestosownejinstrukcjiprocesoraktórejargumentemjestnumer przerwania. Generowanie przerwań instrukcją procesora jest wykorzystywane m.in. celemrealizacji wywołań systemowych (czyli wywołań funkcji jądra z poziomu programu użytkownika). Wprzypadku Linuxa na architekturze x86 za wywołania systemowe odpowiada przerwanie o numerze0x80, numer funkcji systemowej musi być uprzednio umieszczony w rejestrze eax, a jej kolejneargumentywrejestrachebx,ecx,edx,edi,esi,ebp;podobniestatusoperacji iwartośćzwracanajestumieszczanawodpowiednichrejestrachprocesora.

Istniejemożliwośćzablokowaniaobsługiwszystkichprzerwańpochodzącychzzewnątrz (zwyjątkiemprzerwańniemaskowanych)stosowanąinstrukcjąprocesora.Obsługaprzerwańprzezprocesorpoleganazidentyfikowaniu(woparciuonumer/źródłoprzerwaniaidanezawartewobszarzepamięciczęstonazywanym tablicą wektorów przerwań) adresu procedury obsługi przerwania i wykonaniu jej wsposóbpodobnydowykonania funkcji,czylizodłożeniemaktualnegostanuprocesoranastos (celemumożliwieniapowrotudoniegopozakończeniuproceduryobsługiprzerwaniawcelukontynuowaniaprzerwanegokodu).Jeżeliproceduraobsługiprzerwaniamainnypoziomuprzywilejowania(np.działanaprawachjądrasystemuoperacyjnego)toprocesormożetakżedokonaćprzełączeniastosu.

Z punktu widzenia wielozadaniowego systemu operacyjnego szczególnie istotne jest przerwaniesprzętowezwiązanezodmierzeniemustalonegoczasu(zwaneprzerwaniemzegarowym),pozwalaononaodebraniekontroliaktualniewykonywanemuprocesowi,przekazaniejejsystemowioperacyjnemuiumożliwieniaprzełączenianainnyproces.

Mikrokontrolery

Programowaniemikrokontrolerów,azwłaszczazwykorzystaniemperyferiówwktóresąwyposażone,dośćznacznieróżnisięodtworzeniaaplikacjidziałającychpodkontroląsystemuoperacyjnego(nawetpomimo użycia tego samego języka programowania – najczęściej C lub C++), a także pomiędzyposzczególnymitypamimikrokontrolerów.Korzystaniezperyferiówoferowanychprzezmikrokontrolerpolega głównie na wykonywaniu odczytu i zapisów do rejestrów zgodnie z dokumentacją danegoukładu oraz obsłudze odpowiednich przerwań. Niekiedy takie surowe operowanie na rejestrachobudowane jest przez funkcji biblioteki wspomagającej programowanie danej platformy, z którychprogramistamożekorzystaćabywczytelniejszysposóbzapisaćwykonywanyalgorytm.

Także proces kompilacji kodu dla takich platform przebiega odmiennie niż przy „normalnym”

Page 111: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

programowaniu – bardzo często wykorzystywana jest cross kompilacja, czyli kompilator działa podkontrolą innej architektury niż ta dla której tworzy kod. W związku z tym wykorzystywane są innekompilatorywrazzwłasnymizestawamibibliotekstandardowych(stanowiącetzw.toolchaindladanejplatformy). Bardzo istotne jest też często określenie w opcjach takiego kompilatora szczegółówmikrokontrolera dla którego chcemy zbudować dany kod (typowo toolchain dotyczy całej rodziny, akonkretnymodelmikrontrolera,posiadającykonkretnyzbiórperyferiów,itdokreślanyjestwopcjach).

Przykładowe kody wraz z opisem kompilacji lub plikiem Makefile automatyzującym kompilacje dladwóchchybanajpopularniejszych rodzinmikrokontrolerówudostępniony jestwpostaci repozytoriówgit:

AVR-examples-dla8bitowychmikrokontrolerówAVRSTM32-examples-dla32bitowychmikrokontrolerówSTM32(rdzeńARM)

obsługasprzętuwramachOS

Obsługasprzętuniezawszewiążesięz tworzeniemkodudziałającegobezsystemuoperacyjnego,nawiększychukładachmożedziałaćnormalnysystemoperacyjny(np.LinuxnapłytkachtypuRaspberryPiczyOrangePi).Wtakiejsytuacjiobsługęsprzętumożnazrealizowaćpoprzezwłasnymodułjądrazaniąodpowiedzialnylub(gdytojestmożliwe)poprzezfunkcjeudostępnionedoprzestrzeniużytkownikaprzezsystemoperacyjnyijakąśbibliotekę.Przykłademdrugiegopodejściamożebyćwykorzystywanieplików funkcji operujących na przestrzeni I/O (plik nagłówkowy asm/io.h), funkcji realizującychkomunikację I2C (pliknagłówkowy linux/i2c-dev.h), czy teżbiblioteki libusbpozwalającejnaobsługękomunikacjiUSB.

komunikacjaI2C

#include<unistd.h>#include<fcntl.h>#include<sys/ioctl.h>

#include<linux/i2c-dev.h>#ifndefI2C_FUNC_I2C#include<i2c/smbus.h>#endif

#include<stdio.h>#include<string.h>#include<stdlib.h>#include<errno.h>

//wymaganypakietlibi2c-dev,kompilacja://dlalibi2c-dev<4://gcckomunikacja_I2C.c//dlalibi2c-dev>=4://gcc-li2ckomunikacja_I2C.c

voidhelp(constchar*prog_name){ fprintf(stderr,"USAGE(withoutonchipregisteraddres):\n"); fprintf(stderr,"-read:%si2c_devaddrr-\n",prog_name); fprintf(stderr,"-write:%si2c_devaddrw-data\n",prog_name); fprintf(stderr,"USAGE(withonchipregisteraddres):\n"); fprintf(stderr,"-read:%si2c_devaddrrreg_addr\n",prog_name); fprintf(stderr,"-write:%si2c_devaddrwreg_addrdata\n",prog_name); fprintf(stderr,"\n"); fprintf(stderr,"i2c_dev=/dev/ic2...devicepath\n"); fprintf(stderr,"addr=I2C_devide_address\n"); fprintf(stderr,"reg_addr=register(data)addressinI2Cchip\n"); fprintf(stderr,"data=datatowritetodevice\n");}

intmain(intargc,char*argv[]){ intfd,i2c_addr,reg_addr,res,d; if(argc<4){ help(argv[0]); return1; } //otwarcieurządzenia fd=open(argv[1],O_RDWR); if(fd<0){ fprintf(stderr,"ErroropenI2Cdevicefile(%s):%s\n",argv[1],strerror(errno)); return2;

Page 112: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

} //ustawienieadresuslave i2c_addr=strtol(argv[2],NULL,0); res=ioctl(fd,I2C_SLAVE,i2c_addr); if(res<0){ fprintf(stderr,"ERRORsetdeviceaddressto0x%02x:%s\n",i2c_addr,strerror(errno)); return3; } if(argv[3][0]=='r'&&argc==5){//odczyt if(argv[4][0]!='-'){ //jeżelijestpodanytoustawiamyadresrejestrudoodczytu //wartozauważyćżejesttorobionejakoWRITEdourządzeniaI2C reg_addr=strtol(argv[4],NULL,0); res=i2c_smbus_write_byte(fd,reg_addr); if(res<0){ fprintf(stderr,"ERRORwrite(registeraddress)%dtoi2cdevice0x%02xon%s:%s\n",reg_addr return4; } } //czytamydanezurządzenia res=i2c_smbus_read_byte(fd); if(res<0){ fprintf(stderr,"ERRORreadfromi2cdevice0x%02xon%s:%s\n",i2c_addr,argv[1],strerror(errno return5; } printf("0x%02x\n",res); }elseif(argv[3][0]=='w'&&argc==6){//zapis d=strtol(argv[5],NULL,0); if(argv[4][0]!='-'){ //jeżelijestpodanyadresrejestrudozapisutogoużywamyiwykonujemyzapis reg_addr=strtol(argv[4],NULL,0); res=i2c_smbus_write_byte_data(fd,reg_addr,d); if(res<0){ fprintf(stderr,"ERRORwrite%dtoi2cdevice0x%02x,register0x%02xon%s:%s\n",d,i2c_addr return5; } }else{ //wprzeciwnymraziepoprostuzapisujemydanedourządzenia res=i2c_smbus_write_byte(fd,d); if(res<0){ fprintf(stderr,"ERRORwrite%dtoi2cdevice0x%02xon%s:%s\n",d,i2c_addr,argv[1],strerror return5; } } }elseif(argv[3][0]=='R'&&argc==5&&argv[4][0]!='-'){//odczytzrejestrujednąfunkcją reg_addr=strtol(argv[4],NULL,0); res=i2c_smbus_read_byte_data(fd,reg_addr);//odczytzrejestruodanymadresiemożebyćwykonanytakżejednąfunkcją(analogiczniejakzapis) if(res<0){ fprintf(stderr,"ERRORreadfromi2cdevice0x%02x,register0x%02xon%s:%s\n",i2c_addr,reg_addr return5; } printf("0x%02x\n",res); }else{ help(argv[0]); return1; } close(fd);}

Wzorceprojektowe,algorytmy,itpObiektowość

Obiektowośćjestpodejściemdoprogramowaniapolegającymnałączeniudanychipowiązanychznimiprocedur w obiekty. W rezultacie zamiast grupy funkcji operujących na jakiejś strukturze danych i

Page 113: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

osobnych instancjach tej struktury (np. napis typu char* i funkcje z rodziny string.h) operuje sięobiektami zawierającymi w sobie dane i posiadającym metody na nich operujące (np. napis typustd::string). Z obiektowością związane są zagadnienia takie jak: określanie interfejsów klasodnoszących się jedynie do kluczowych dla danego zagadnienie elementów i ukrywaniu pozostałychaspektówwewnątrz implementacjiklasy,wydzielaniewspólnychcechobiektówróżnego typudoklasbazowychpoktórychdziedziczą.

Dziedziczenie,polimorfizm,itp

Dziedziczenie jest jednym z mechanizmów pozwalających na konstrukcję klas opisujących bardziejzłożoneobiektyzklasprostszych.

//klasaabstrakcyjna-definiującainterfejsdlajakiejśgrupyobiektów//faktbyciaklasąabstrakcyjnąwynikazniezdefiniowanejmetodywirtualnej//zfaktutegowynikaniemożnośćutworzeniaobiektówbędącychbezpośrednimi//instancjamitakiejklasyclassKsztalt{public: virtualfloatobjetosc()=0; //użycievirtualwymuszawywoływaniemetodyzklasypotomnej //kiedyodwołujemysięprzyużyciuklasybazowej};

//klasydziedziczącapoklasieKsztaltclassKula:publicKsztalt{ floatpromien;public: Kula(floatr){ promien=r; } floatobjetosc(){ return1.25*3.14*promien*promien*promien; }};classSzescian:publicKsztalt{ floatbok;public: Szescian(floata){ bok=a; } floatobjetosc(){ returnbok*bok*bok; }};

structKolor{ charr,g,b;};

classCena{public: Cena(floatc);};

classMaterial{};

//klasadziedziczącapokilkuklasachbazowychstructOpakowanie:publicKsztalt,publicKolor,publicCena{ Ksztalt*ksztalt; Material*material;public: Opakowanie(Ksztalt*k,constKolor&kolor,floatc): //wywołaniekonstruktorówklasybazowej //jawnegodlaCenaikopiującegodlaKolor Cena(c),Kolor(kolor) { //inicjalizacjazmiennejwskaźnikowejksztalt //dziękirozwiązaniuzzmiennąprzechowującąinformacjęokształcie //niemapotrzebytworzeniaróżnychklasOpakowaniedlaróżnychkształtów ksztalt=k; material=0; }

Opakowanie(Ksztalt*k,floatc):

///PrzykładC++

Page 114: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

//wywołaniekonstruktoraklasybazowejCena //orazinicjalizacjazmiennychksztaltimaterial Cena(c),ksztalt(k),material(0) { //inicjalizacjapólodziedziczonychpostrukturzeKolor r=0x96;g=0xFF;b=0x03; }

floatobjetosc(){ returnksztalt->objetosc(); }

//jesttoalternatywnawstosunkucododziedziczenia //metodarozszerzaniainterfejsujakiejśklasy //dziedziczenie(wprzypadkudziedziczeniapublic)dodajemetody //klasybazowejbezpośredniodointerfejsuklasydziedziczącej //natomiasttorozwiązaniepozwalanapobranieposzczególnychklas //opisującychzłożonyobiektniezależnieioperowaniunaichinterfejsie Material*getMaterial(){ returnmaterial; }

voidsetMaterial(Material*m){ material=m; }};

Tworzenieirozbudowaobiektówmetodawytwórcza

jesttokreacyjnywzorzecprojektowy(inaczejnazywanywirtualnykonstruktor)realizowanypoprzezutworzenie klasy fabryki z metodą statyczną odpowiedzialną za tworzenie różnych produktów(dziedziczącychpowspólnejklasiebazowej).

Efektem zastosowanie jest ukrycie szczegółów implementacji poszczególnych produktów przezużytkownikiem(korzystaontylkozklasybazowejproduktuifabryki).

#include<iostream>

structProduct{ virtualvoidinfo()=0; virtual~Product(){}};

structProductA:publicProduct{ virtualvoidinfo(){ std::cout<<"ProductA:a,b,c\n"; }};

structProductB:publicProduct{ virtualvoidinfo(){ std::cout<<"ProductB:a,f,g\n"; }};

structProductFactory{ staticProduct*getProduct(conststd::string&type){ if(type=="A") returnnewProductA(); elseif(type=="B") returnnewProductB(); else returnNULL; }};

intmain(intargc,char*argv[]){ std::stringid="A"; if(argc>1&&argv[1][0]=='B') id="B";

///PrzykładC++

Page 115: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

Product*p=ProductFactory::getProduct(id); p->info(); deletep;}

fabrykaabstrakcyjna

jest to kreacyjny wzorzec projektowy realizowany poprzez utworzenie klasy fabryki z metodąstatyczną odpowiedzialną za tworzenie różnych typów fabryk dziedziczących po wspólnej klasiebazowej. Klasa bazowa fabryki określa gamę produktów z użyciem klas bazowych produktów, wefekciekażdazfabrykprodukujetakąsamągamęproduktów,aledoichtworzeniamożekorzystaćzspecyficznychdladanejimplementacjifabrykiklasdziedziczącychpoproduktachbazowych.

Efektem zastosowanie jest ukrycie szczegółów implementacji poszczególnych produktów przezużytkownikiem (korzysta on tylko z klasy bazowej produktu i fabryki). W odróżnieniu od metodywytwórczej stosowany jest do produkcji spójnych gam produktów dzięki jednokrotnemu określaniutypu produktów przy tworzeniu fabryki (zamiast niezależnego określania typu każdego produktu).Pozwalatylkorazokreślićużywanytypfabrykiiwytwarzaćproduktuuzyskanąfabrykąkonkretnegotypu, jest to przydatne wtedy gdy konkretna implementacja fabryki jest zależna np. od stosowanejbibliotekilubsystemu.

#include<iostream>

structProduct{ virtualvoidinfo()=0; virtual~Product(){}};

structProductA:publicProduct{ virtualvoidinfo(){ std::cout<<"ProductA:a,b,c\n"; }};

structProductB:publicProduct{ virtualvoidinfo(){ std::cout<<"ProductB:a,f,g\n"; }};

structFactory{ staticFactory*getFactory(conststd::string&type); virtualProduct*getProduct()=0; //fabrykatakamożezłatwościąprodukowaćkilka //różnychproduktów(całąrodzinęproduktów) virtual~Factory(){}};

structFactoryA:publicFactory{ virtualProduct*getProduct(){ returnnewProductA(); }};

structFactoryB:publicFactory{ virtualProduct*getProduct(){ returnnewProductB(); }};

Factory*Factory::getFactory(conststd::string&type){ if(type=="A") returnnewFactoryA(); elseif(type=="B") returnnewFactoryB(); else returnNULL;}

intmain(intargc,char*argv[]){ std::stringid="A"; if(argc>1&&argv[1][0]=='B') id="B";

///PrzykładC++

Page 116: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

Factory*f=Factory::getFactory(id); Product*p=f->getProduct(); p->info(); deletep; deletef;}

budowniczy

jest to kreacyjny wzorzec projektowy realizowany poprzez utworzenie klasy kierownikakorzystającego z bazowego interfejsu klasy budowniczego do realizacji jakiegoś algorytmu (częstokonwersji formatów). Użytkownik odpowiedzialny jest za utworzenie konkretnego budowniczego,przekazaniewskaźnikananiegokierownikowi(ewentualniewrazzdanymipotrzebnymidobudowy,np.danymiktóremajązostaćpoddanekonwertowaniu)orazodebraniuwynikuodbudowniczego.

Efektemjestpełneukrycieszczegółówimplementacjiprzedklasąimplementującąkierownika(niewienicoprodukcie,używatylkobazowegobudowniczego).

#include<iostream>

structProduct{ voidinfo(){ std::cout<<"Product:\n"; std::cout<<""<<el1<<"\n"; std::cout<<""<<el2<<"\n"; } voidsetElement1(conststd::string&e){ el1=e; } voidsetElement2(conststd::string&e){ el2=e; }private: std::stringel1,el2;};

structProductBuilder{ virtual~ProductBuilder(){} voidcreateProduct(){ p=newProduct(); } Product*getProduct(){ returnp; } //wtakiejimplementacjinieodebranielub //nieskasowanieproduktuprzezklientabędzie //prowadziłodowyciekówpamięci virtualvoidbuildElement1(conststd::string&d)=0; virtualvoidbuildElement2()=0;protected: Product*p;};

structProductDirector{ voidsetData(conststd::string&d){ this->d=d; } voidsetBuilder(ProductBuilder*b){ this->b=b; } voidcreateProduct(){ b->createProduct(); b->buildElement1(d); b->buildElement2(); }private: ProductBuilder*b; std::stringd;};

///PrzykładC++

Page 117: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

structProductBuilderA:publicProductBuilder{ voidbuildElement1(conststd::string&d){ p->setElement1(d+d); }; voidbuildElement2(){ p->setElement2("ab"); };};

structProductBuilderB:publicProductBuilder{ voidbuildElement1(conststd::string&d){ p->setElement1("b"+d); }; voidbuildElement2(){ p->setElement2("bb"); };};

intmain(intargc,char*argv[]){ ProductBuilder*b; if(argc>1&&argv[1][0]=='B') b=newProductBuilderB(); else b=newProductBuilderA(); ProductDirector*d=newProductDirector(); d->setData("x"); d->setBuilder(b); d->createProduct(); Product*p=b->getProduct(); p->info(); deletep; deleted; deleteb;}

singleton

Singleton jest kreacyjnym wzorcem projektowym zapewniającym istnienie tylko jednej instancji(jednego obiektu) klasy go implementującej. Uzyskiwane jest to poprzez ukrycie konstruktorów izastąpienieichmetodąstatycznązwracającązawszetensamobiektdanejklasy.

#include<iostream>

classSingleton{private: //konstruktor,konstruktorkopiującyorazoperator //przypisaniasąprywatneabyuniemożliwićtworzenie //lubkopiowanieobiektówtejklasyzzewnątrz Singleton(); Singleton(constSingleton&){} Singleton&operator=(constSingleton&); //destruktorteżprywatny...dlazabezpieczeniaprzed //możliwościązrobieniadeletenauzyskanymwskaźniku ~Singleton(){} //klasazawieraprywatnystatycznywskaźniknasiebie //(naswojąjedynąinstancję) staticSingleton*objPtr;public: //atakżemetodęsłużącąpobraniutegowskaźnika //(iutworzeniuobiektugdynieistnieje) staticSingleton*getPtr(){ //alternatywniezamiastwskaźnikamożnaużyć //statycznegoobiektutejklasyzadeklarowanego //wewnątrztejfunkcji if(!objPtr) objPtr=newSingleton(); returnobjPtr; }

///PrzykładC++

Page 118: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

};

Singleton*Singleton::objPtr=0;

Singleton::Singleton(){ std::cout<<"konstruktorSingleton\n";}

intmain(){ Singleton*a=Singleton::getPtr(); Singleton*b=Singleton::getPtr(); std::cout<<a<<"=="<<b<<"\n";}

dekorator

jest strukturalnymwzorcemprojektowympozwalającymnarozbudowę funkcjonalności jakiejśklasybez ingerencji w nią, realizowany jest poprzez dziedziczenie po wspólnym z obudowywaną klasąinterfejsie i zawieranie w sobie wskaźnika na obudowywaną klasę. Dekorator reimplementujewybranefunkcjeklasyoryginalnejjednakwywołującwnichfunkcjeklasyoryginalnej,copozwalanawielokrotneobudowywaniepierwotnegoobiektu.

#include<iostream>

structProduct{ virtual~Product(){} virtualvoidinfo()=0;};

structProductA:publicProduct{ voidinfo(){ std::cout<<"Product:\n"; std::cout<<"ab\n"; }};

structDecoratorX:publicProduct{ DecoratorX(Product*p){ this->p=p; } voidinfo(){ p->info(); std::cout<<"xx\n"; }protected: Product*p;};

structDecoratorY:publicProduct{ DecoratorY(Product*p){ this->p=p; } voidinfo(){ p->info(); std::cout<<"yy\n"; }protected: Product*p;};

intmain(intargc,char*argv[]){ Product*p=newProductA(); Product*p1=newDecoratorX(p); Product*p2=newDecoratorY(p1); p1->info(); p2->info(); deletep2; deletep1; deletep;}

///PrzykładC++

Page 119: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

kompozyt

jest strukturalnym wzorcem projektowym pozwalającym na zapewnienie interfejsu zgodnego zinterfejsemobiektudlagrupyobiektów.

#include<iostream>#include<list>

structProduct{ virtualvoidinfo()=0; virtual~Product(){};};

structProductA:publicProduct{ virtualvoidinfo(){ std::cout<<"ProductA:a,b,c\n"; }};

structProductB:publicProduct{ virtualvoidinfo(){ std::cout<<"ProductB:a,f,g\n"; }};

classProductComposite:publicProduct{public: std::list<Product*>elements; virtualvoidinfo(){ for(autoe:elements) e->info(); } ~ProductComposite(){ for(autoe:elements) deletee; }};

intmain(intargc,char*argv[]){ ProductComposite*pc=newProductComposite(); pc->elements.push_back(newProductA()); pc->elements.push_back(newProductB()); pc->elements.push_back(newProductA()); pc->info(); deletepc;}

Komunikacjamiędzyobiektamilistener

Obserwator (określany też jako listener) jest czynnościowym wzorcem projektowym pozwalającymjednemu obiektowi powiadomić wiele innych obiektów o jakimś zdarzeniu, obiekty te powinny byćuprzedniozarejestrowanewklasiepowiadamiającej jakozainteresowanedanymzdarzeniem).Możebyć teżwykorzystywanydo realizacjiwzorca łańcuchzobowiązańwtedygdypowiadamianeobiektymają / mogą wykonać jakieś operacje i od kodu powrotu funkcji powiadamiającej zależypowiadamianiedalszychobiektów.

#include<iostream>#include<map>

structObserwator{ virtualboolonUpdate(inteventID)=0;};

structObserwowany{

///PrzykładC++

///PrzykładC++

Page 120: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

voidaddListener(Obserwator*l,intkey){ //sprawdźczyjestjużzarejestrowany autosubset=listeners.equal_range(key); for(autoiter=subset.first;iter!=subset.second;++iter) if(iter->second==l)return;

//zarejestruj listeners.insert(std::pair<int,Obserwator*>(key,l)); } voidremListener(Obserwator*l){ for(autoiter=listeners.begin();iter!=listeners.end();++iter){ if(iter->second==l){ listeners.erase(iter); return; } } } //klasycznywzorzeclistenera voidcallListenersAll(inteventID){ //mapazapewniawywoływanielistenerówwgkolejnościkluczy for(auto&l:listeners){ l.second->onUpdate(eventID); } } //wzorzeclistenerapołączonyzłańcuchemzobowiązań voidcallListeners(inteventID){ //mapazapewniawywoływanielistenerówwgkolejnościkluczy for(auto&l:listeners){ if(l.second->onUpdate(eventID)) break; } }protected: std::multimap<int,Obserwator*>listeners;};

structObserwatorA:publicObserwator{ virtualboolonUpdate(inteventID){ std::cout<<"ObserwatorAzid="<<eventID<<"\n"; if(eventID==4) returntrue; returnfalse; };};

structObserwatorB:publicObserwator{ virtualboolonUpdate(inteventID){ std::cout<<"ObserwatorBzid="<<eventID<<"\n"; if(eventID==7) returntrue; returnfalse; };};

intmain(intargc,char*argv[]){ Obserwowany*o=newObserwowany(); Obserwator*o1=newObserwatorA(); Obserwator*o2=newObserwatorA(); Obserwator*o3=newObserwatorB(); o->addListener(o1,30); o->addListener(o2,10); o->addListener(o3,20); std::cout<<"callAll:\n"; o->callListenersAll(7); std::cout<<"call:\n"; o->callListeners(7); deleteo; deleteo1; deleteo2;

Page 121: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

deleteo3;}

Mediator

jest czynnościowym wzorcem projektowy realizującym przekazywanie wiadomości pomiędzyobiektami poprzez pośrednika, w przypadku nie natychmiastowego wysyłania wiadomości przezmediatorapozwalatakżenarealizacjękolejkiwiadomości/pętlikomunikatów.

#include<iostream>#include<map>

structReceiver{ virtualvoidreceive(std::stringmsg)=0;};

structMediator{ voidaddReceiver(Receiver*l,intkey){ //sprawdźczyjestjużzarejestrowany autosubset=receivers.equal_range(key); for(autoiter=subset.first;iter!=subset.second;++iter) if(iter->second==l)return;

//zarejestruj receivers.insert(std::pair<int,Receiver*>(key,l)); } voidremReceiver(Receiver*l){ for(autoiter=receivers.begin();iter!=receivers.end();++iter){ if(iter->second==l){ receivers.erase(iter); return; } } } boolsend(std::stringmsg,intdstID){ //gdybyzamiastnatychmiastowegowywoływaniareceive()uadresatów //zaimplementowaćgromadzeniewiadomościwjakiejśstrukturze //iosobnąfunkcjęwysyłającąkolejnewiadomościztejstruktury //towzorzectenpozwoliłbynarealizacjękolejkiwiadomości //(pętlikomunikatów) // //strukturaprzechowującazakolejkowanedowysłaniawiadomościmoże //uwzględniaćkolejnośćichodebraniaprzezMediatoralubwartość //priorytetuzawartegowwiadomości(kolejkapriorytetowa) autosubset=receivers.equal_range(dstID); for(auto&iter=subset.first;iter!=subset.second;++iter){ iter->second->receive(msg); } }

protected: std::multimap<int,Receiver*>receivers;};

RegulatorPID

RegulatorPID jest to algorytm regulacji parametruprocesudziałającywpętli sprzężenia zwrotnegoposiadającyczłony:proporcjonalny(P),całkujący(I)iróżniczkujący(D).

Wyjściem algorytmu jest wartość zmiany jakiegoś sygnału sterującego - może być wykorzystanabezpośrednio przy sterowaniu krokowym lub akumulowana celem uzyskania stałej wartości sygnałusterującego.

Wejściemalgorytmujestwartośćmierzona(bądźodrazuróżnicawartościzadanejimierzonej).Jeżelikierunekzmianysterowania jestzgodnyzezmianąwartościmierzonej (zwiększeniewartościsygnałusterującego powoduje zwiększenie wartości mierzonej) to należy odejmować wartość mierzoną odzadanej,wprzeciwnymrazieodzadanejmierzoną.

///PrzykładC++

///PrzykładC++

Page 122: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

classPID{ //poprzedniaróżnicamiędzywartościązadanąaotrzymaną //(poprzednibłądregulacji/uchyb) floatlastDiff; //poprzedniawartośćotrzymana(zmiennaprocesu) floatlastVal; //częśćcałkująca,akumulowanapomiędzykrokami floatintegral;public: //nastawa-wartośćzadana floatsetPoint; //wartośćwyjściadlasterowaniakrokowego //(akumulacjawukładzierealizującym) floatoutStep; //wartośćwyjściadlasterowaniasygnałem floatoutValue; //parametryregulatoraPID floatKp,Ki,Kd; //limitywartościsterowanej floatoutValueMin,outValueMax; //konstruktor-inicjalizacjaparametrów PID( floatinitVal,floatsp, floatkp,floatki,floatkd,floatmin,floatmax ): lastDiff(0),lastVal(initVal),integral(0), setPoint(sp),outStep(0),outValue(0), Kp(kp),Ki(ki),Kd(kd), outValueMin(min),outValueMax(max) {} intdoStep(floatinputVal,floatstepTime){ //obliczmyaktualnybłądregulacji //(napodstawieodczytanejwartościwejściowej) floatdiff=setPoint-inputVal; //wyłączamyregulacjęgdyprowadziłbydoprzesterowania if(outValue>outValueMax&&diff>0) return1; if(outValue<outValueMin&&diff<0) return-1; //całkowanieprzybliżamyjakojakosumapóltrapezów integral+=(diff+lastDiff)/2*stepTime; //różniczkowanieprzybliżamyjakotangensnachylenia //prostejpomiędzypoprzednimkrokiemaobecnym //celemzłagodzeniaodpowiedzinazmianywartościzadanej //różniczkujemysygnałwejściowy floatderivative=-(inputVal-lastVal)/stepTime; //aniebłądregulacji:derivative=(diff-lastDiff)/stepTime; //obliczeniewartościsygnałusterującegonapodstawietegokroku outStep=Kp*diff+Ki*integral+Kd*derivative; //akumulacjasygnałusterującego outValue+=outStep; //zapamiętanieaktualnegobłęduregulacji //jakopoprzednidlanastępnegokroku lastDiff=diff; //zapamiętanieaktualnejwartościwejściowej //jakopoprzedniejdlanastępnegokroku lastVal=inputVal; return0; }};

Page 123: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

intmain(){ PIDpid(readInput(),21.0,1.0,0.0,0.0,-100.0,100.0); //okresdziałaniaalgorytmu[us] unsignedintstepTime=250000; //pętlaalgorytmu while(1){ //odczytwejścia floatcurVal=readInput(); //obliczeniewartościsterującejzużyciemPID pid.doStep(curVal,stepTime); //wystawieniewartościsterującej setOutput(pid.outValue); //odczekaniedonastępnegokroku usleep(stepTime); }}

SiecikomputeroweSieć komputerowa jest to zbiór hostów (urządzeń wykorzystujących sieć do komunikacji, takich jakkomputery,drukarkisieciowe,...)orazinfrastrukturysieciowej(okablowanie,urządzaniapośredniczącewkomunikacji).Wprzypadkubardziejabstrakcyjnegopatrzenianazagadnieniasieciowe(właśnieodstronyprotokołów wyższych warstw niż sprzętowa - takich jak IP) na sieć można patrzeć tylko jako na zbiórhostów (posiadających identyfikujące je numery). Dla funkcjonowania sieci konieczne jest zapewnieniedobrzeokreślonychzasad jejdziałania -właśniezbiorami takichzasadwymiany informacji sąprotokołysieciowe.

Siecikomputerowedziałająnazasadzieprzesyłaniainformacjiwpostaciporcji,zktórychkażdaposiadaco najmniej informację o adresie odbiorcy (zwykle też nadawcy), nazywanych ramkami lub pakietami.Kierowaniepakietówwodpowiedniemiejsceodbywasięnapodstawieadresupakietuiniejestzwiązanezfizycznymzestawianiemłączapomiędzynadawcąaodbiorcą-każdypakietjestkierowanyniezależnie,awramachpojedynczego łącza(kanałutransmisji)mogąbyćprzekazywanepakietyadresowanedoróżnychodbiorców.Nazywanejesttokomutacjąpakietów,wodróżnieniuodkomutacji łącza(którawystępowałanp.wklasycznej,analogowejtelefonii,gdzieprzekaźnikiwcentralachdokonywałyzestawieniapołączeńelektrycznychmiędzydwomaaparatamitelefonicznymi).

Komunikacjasieciowatypowoposiadastrukturęwarstwową.WmodeluOSIwyróżniasię7warstw:fizyczną (pierwszą) definiującą aspekty związane z fizycznym przesyłem sygnału takie jakczęstotliwościradiowe,poziomynapięć,etc.;określasposóbtransmisjikolejnychbajtówłącza danych (drugą) definiującą aspekty związane z formatem ramki, protokoły ustalania zasaddostępudomediumtransmisyjnego,itd.;określasposóbtransmisjiporcjidanychpomiędzyhostamiwjednejsiecisieciową (trzecią) definiującą aspekty związane z formatem pakietu, adresacją i zasady routinguumożliwiającezapewnieniełącznościpomiędzyróżnymisieciami;określasposobytransmisjiporcjidanychpomiędzysieciamitransportową (czwartą) odpowiedzialną za podział strumienia na porcje informacji, kontrolę nadpoprawnościątransmisji,adresacjęusługwramachhostasesji(piątą)prezentacji(szóstą)aplikacji(siódmą)

WmodeluTCP/IPwyróżniasię4warstwy:Dostępudosieci-obejmującąwarstwy1i2modeluOSIInternetu-obejmującąwarstwę3modeluOSITransportową-obejmującąwarstwę4modeluOSIAplikacji-obejmującąwarstwy5,6i7modeluOSI

ZpunktuwidzeniamodeluTCP/IPmożnapowiedziećoenkapsulacjidanychkolejnychwarstwwramachwarstwy niższej, czyli "surowe" dane (np. strona HTML) obudowywane są strukturą opisywaną przezwarstwęaplikacji (np.nagłówkamiHTTP), następnie całość taumieszczana jestwpoludanychpakietuwarstwy transportowej (np. TCP), ten z kolei w polu danych pakietu IP (warstwy sieciowej), na koniecpakiet IP jestumieszczanywpoludanych ramkiwarstwydostępudosieci (np. ramkiethernetowej).W

Page 124: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

ramachpodróżyprzezkolejnesiecipakietIPjestwyjmowanyiwkładanywkolejneramkiwarstwydostępudo sieci, na ogół tylko z niewielkimi ingerencjami w zawartość tego pakietu (prawie zawsze niedochodzącymidopoladanychpakietuTCPlubdatagramuUDP,czyliniewykraczającymipozawarstwę4OSI).

WarstwasprzętowaOdstronysprzętowejsiećskładaz:

hostówstanowiącychnadawcówiodbiorcówinformacjiurządzeń sieciowych pośredniczących w ich przekazywaniu, takich jak nadajniki, switche,mediakonwerteryokablowaniamiedzianegobądźświatłowodowego(jeżeliniejestsieciąbezprzewodową)

Ethernet

W przypadku sieci w standardzie Ethernet stosowane są 48 bitowe adresy MAC (pierwsza częśćidentyfikuje producenta karty) oraz wspólny dla wszystkich odmian (przewodowych ibezprzewodowych) format ramki (określający położenie w ramce adresów, informacji dodatkowychorazdanych).Pakietyprotokołuwarstwywyższej(np.pakietyIPwrazichstrukturązawierającąadresyitd)zpunktuwidzeniaramkiethernetowejsądanymi,wktóre tawarstwaniewnika.DomapowaniaadresówIPnaadresyMACwykorzystywanyjestprotokółARP(dlaIPv4)lubNeighborDiscovery(dlaIPv6)-odbywasiętopoprzezwysłanieramkiethernetowejnaadresrozgłoszeniowy(odbieranyprzezwszystkiehosty)zpytaniemotojakiMACadresmahostopodanymnumerzeIP.

Sieć ethernetowa typowo posiada strukturę wielokrotnej gwiazdy (drzewa), w węzłach którejstosowane są switche.Kierują one ramki do odpowiednichgałęzi napodstawie adresudocelowego iwpisów w tablicy adresów MAC, utworzonej w oparciu o źródłowe nadawców przechodzących przezdanyswitch ramek.Wprzypadkugdyadresudocelowegoniemaw tablicy ramkakierowana jestnawszystkieporty switcha zwyjątkiem tegona którymzostała odebrana.W taki sposób zawsze są teżprzesyłaneramkiwysyłanenaadresrozgłoszeniowy(bradcast).

Ethernet pozwala na wirtualne podzielenie pojedynczej sieci lokalnej na wiele niezależnych (niekomunikujących się ze sobą w warstwie ethernetu) sieci, nazywanych VLAN. Działanie tegomechanizmuopierasięnazastosowaniuzarządzalnychswitchy,któreprogramowomogąbyćdzielonena części zapewniające separację ruchu poszczególnych VLANów. Ponadto wybrane porty takiegoswitchamogąbyćprzypisanedoróżnychczęści(celemudostępnieniadoinnegoswitchalubhostakilkusieciwirtualnych),wtakimprzypadkudoramekethernetowychwysyłanychtymportemdodawanajestinformacjadoktóregoVLANunależą(dwubajtowynumer),awprzypadkuramekotrzymywanychnapodstawie tegonumeruodbywasię ichkierowaniedoodpowiedniej "części"przełącznika (mówimyoVLANachtagowanych).Możliwe jestaby jedenwybranyVLANna takimporciebyłnie tagowany (dojegoramekniebędziedodawanynumer,aotrzymywanepakietybeznumerubędąkierowanedoniego.

Ethernet pozwala również na grupowanie kilku portów w jeden port wirtualny (tzw port trunking /bonding)celemzwiększeniaprzepustowościlubniezawodnościłącza.Adziękizastosowaniuwróżnychtypach sieci ethernet tego samego formatu ramki możliwe jest też stosunkowo proste zmienianiemediumtransmisyjnego(np.zkablamiedzianegonaświatłowód)zużyciemmedia-konwerterów.

WprzewodowychsieciachEthernetwykrywaniemzajętościmediumtransmisyjnegoorazwykrywaniemkolizji zajmuje się protokół CSMA/CD (Carrier Sense Multiple Access with Collision Detection -wielodostęp z rozpoznawaniem stanu kanału oraz wykrywaniem kolizji). Przed rozpoczęciemnadawaniastacjamusisprawdzićczymediumjestwolne,jeżelitakmożezacząćnadawać,jeżelidwiestacje zaczną nadawać równocześnie zostaje to wykryte, obie przerywają nadawanie i wznawiają polosowymczasie. Jednak zewzględuna stosowaniegłówniepołączeńpunkt-punkt full-duplex (osobneprzewodydonadawaniaiosobnedoodbioru),coograniczatzw.domenękolizjidopojedynczegohosta,protokółtennieodgrywaobecnieszczególnieistotnejroli.

SieciIPProtokół IP (InternetProtocol)odpowiedzialny jestprzedewszystkimza sposóbadresacjihostóworazreguły komutacji pakietów (routing). Jest onwspomaganyprzez kolejnyprotokół z tej rodziny - ICMP(InternetControlMessageProtocol),któregozadaniemjestprzekazywanieinformacjikontrolnychnp.onieosiągalności hosta docelowego, odrzuceniu przetwarzania pakietu ze względu na zbyt dużą liczbęskoków (gdy wartość pola TTL z nagłówka IP wyniesie zero) a także pingi (zarówno żądanie jak iodpowiedź).

Adresacjairouting

Adresyhostów(nazywaneadresamiIP)sąto32-bitowe(wIPv4)lub128-bitowe(wIPv6)liczby.

AdresyIPv4zapisywanesąnajczęściejwnotacjikropkowo-dziesiętnej,gdziekażdybajt(ciąg8bitów)zapisywany jest jako liczbadziesiętnarozdzielanakropkąodpozostałych.AdresyIPv6zapisywanesązazwyczajwnotacji dwukropokowej, polegającej na zapisywaniu16bitowych części adresu liczbami

Page 125: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

szesnastkowymi oddzielanymi dwukropkiem, dodatkowo jeden ciąg zer (o długości będącejwielokrotnością16bitów)możebyćskompresowany(pominięty)codajewzapisiedwadwukropki::.

Długośćprefixuimaska

Adresyhostówgrupujesięwadresysieci,bazującnajednakowym(bitowo)początkutakiegoadresu(zwanym adresem sieci lub prefixem). Ilość bitów stanowiących adres sieci w danym adresie IPnazywana jestdługościąprefixu izapisywana jestzazwyczajpoukośniku.Np.zapis2001:db8::a17/48oznaczażepierwsze48bitystanowiąadressieciakolejne128-48=80bitówstanowiadreshostawtejsieci.

Długość prefixu jednoznacznie określa maskę danej podsieci, czyli liczbę odpowiadającą długościadresu(32bitylub128bitów),złożonązciągujedynekodługościprefixuorazciąguzer(odługościadresu hosta). W przypadku IPv4 spotykane jest także podawanie maski sieci w notacji kropkowo-dziesiętnejzamiastdługościprefixu.

Siećmożezostaćpodzielonanamniejszesieci(zwiększąwartościąprefixu),jakteżgrupasiecimożezostaćzagregowanawjednąwiększą(2nraza)sieć(zprefixemmniejszymon).Agregacjahostówisieci w większe całości jest wykorzystywana w mechanizmach routingu, co pozwala na redukcjęwielkościtablicroutingowych.

Przynależnośćdosieci

Adressiecizapisujesiętypowozwyzerowanymibitamistanowiącymiadreshosta(czylipodokonaniubitowego and z maską danej sieci) oraz podaną informacją o długości prefixu, dla powyższegoprzykładu będzie to 2001:db8::/48. Informacja taka jest wystarczająca do sprawdzenia czy dowolnyinnyadresIPnależydotejsieciczynie.

#adresacjaIPv6

fromipaddressimport*

a1=IPv6Address("2001:0db8::17:15")aa1=int(a1)print("adressIPv6jest128bitowąliczbącałkowitąnp.:"+str(a1)+"=="+hex(aa1))

n0=IPv6Network("::/112");m1=n0.netmaskmm1=int(m1)p1=n0.prefixlen

print("MaskapodsieciIPv6jest128bitowąliczbącałkowitąnp.:"+str(m1)+"=="+hex(mm1))print("Jakożemaskajestliczbą,którazapisanabinarnie,zawszezawieraciągłyciągbitów")print("owartości1,aponimciągłyciągbitówowartości0(mogąbyćzerowejdługości),to")print("częstostosowanyjestzapispolegającynapodawaniudługościprefiksu:/"+str(p1))print("jesttoilośćbitówowartości1wmasce,czyliimwiększyprefixtymmniejszasieć.")

n1=IPv6Network("2001:0db8::17:15/112",strict=False);nn1=int(n1.network_address)

print("Abyobliczyćadressieci(czyliwspólnądlawszystkichhostówwdanejsieciczęść")print("adresuIP)należywykonaćbinarnyANDpomiędzyadresemIPhostaamaskąpodsieci.")print("Dlapowyższegoprzykładu:")print(hex(mm1&aa1)+"=="+str(n1)+"=="+hex(nn1))

#abysprawdzićczyadresIPnależydodanejsiecitrzebaobliczyćadressiecitegohosta#woparciuomaskęsieciktórąsprawdzamydefsprawdzSiec(n,a): nn=int(a)&int(n.netmask) ifnn==int(n.network_address): print(str(a)+"należydosieci"+str(n)) else: print(str(a)+"NIEnależydosieci"+str(n))

sprawdzSiec(n1,IPv6Address("2001:0db8::17:ab13"))sprawdzSiec(n1,IPv6Address("2001:0db8::13:a"))

#adresacjaIPv4

fromipaddressimport*

a1=IPv4Address("192.168.34.17")aa1=int(a1)

###PrzykładPython

###PrzykładPython

Page 126: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

print("adressIPv4jest32bitowąliczbącałkowitąnp.:"+str(a1)+"=="+hex(aa1))

n0=IPv4Network("0.0.0.0/25");m1=n0.netmaskmm1=int(m1)p1=n0.prefixlen

print("MaskapodsieciIPv4jest32bitowąliczbącałkowitąnp.:"+str(m1)+"=="+hex(mm1))print("Jakożemaskajestliczbą,którazapisanabinarnie,zawszezawieraciągłyciągbitów")print("owartości1,aponimciągłyciągbitówowartości0(mogąbyćzerowejdługości),to")print("częstostosowanyjestzapispolegającynapodawaniudługościprefiksu:/"+str(p1))print("jesttoilośćbitówowartości1wmasce,czyliimwiększyprefixtymmniejszasieć.")

n1=IPv4Network("192.168.34.17/25",strict=False);nn1=int(n1.network_address)

print("Abyobliczyćadressieci(czyliwspólnądlawszystkichhostówwdanejsieciczęść")print("adresuIP)należywykonaćbinarnyANDpomiędzyadresemIPhostaamaskąpodsieci.")print("Dlapowyższegoprzykładu:")print(hex(mm1&aa1)+"=="+str(n1)+"=="+hex(nn1))

#abysprawdzićczyadresIPnależydodanejsiecitrzebaobliczyćadressiecitegohosta#woparciuomaskęsieciktórąsprawdzamydefsprawdzSiec(n,a): nn=int(a)&int(n.netmask) ifnn==int(n.network_address): print(str(a)+"należydosieci"+str(n)) else: print(str(a)+"NIEnależydosieci"+str(n))

sprawdzSiec(n1,IPv4Address("192.168.34.13"))sprawdzSiec(n1,IPv4Address("192.168.34.199"))

Routing

Router kieruje każdy z pakietów do kolejnego routera lub bezpośrednio do hosta docelowego napodstawie jego adresu docelowego i tablicy routingu. Tablica taka zawiera adresy sieci wraz zadresami następnych routerów do nich prowadzących bądź wskazaniem lokalnego interfejsusieciowego poprzez który powinny być osiągalne hosty z danej sieci. W tym celu korzysta zsprawdzania przynależności adresu do sieci, w celu ustalenia adresu następnego routera i/lubinterfejsusieciowegonaktórymazostaćprzekazanypakiet.

Tablica przeglądana jest od wpisów najbardziej precyzyjnych, czyli z największym prefixem dowpisównajbardziejogólnych(ostatnimwpisemjestnaogółtrasadomyślnaczylisieć::/0dlaIPv6lub0.0.0.0/0 dla IPv4). Dzięki czemu jeżeli kilka wpisów (sieci) z tablicy routingu pasuje do adresudocelowegoznagłówkapakietu,wybieranyjestwpisnajbardziejprecyzyjny(onajdłuższymprefixie),apasującadokażdegoadresutrasadomyślnawybieranajesttylkogdyniemażadnejlepszej.Możesięzdarzyćżekilkawpisów (nawetz tąsamąmaską)pasujedoadresudocelowegohosta,w takiejsytuacjidowyboruścieżkiużywanesąinnedaneztablicyroutingu(takiejakmetryka).

Tablice routingu mogą zawierać wpisy dodawane statycznie (wpisane do konfiguracji danegourządzenia), jak też wpisy dodawane dynamicznie w oparciu o protokołu wymiany informacjiroutingowych (protokoły routingu) takie jak: IGRP, OSPF, BGP. Protokoły routingu dynamicznegomogąbyćwykorzystywanem.in.dorozkładaniaobciążenianaróżnełącza,zapewnieniaredundancjiłącz,blokowaniaataków(D)DoS.

Takżekażdyzhostówmatabliceroutingu,typowoskładasięzdwóchpozycji–trasydosiecilokalnej(tej sieci z której adres posiada dany host) wskazującej bezpośrednio na urządzenie sieciowe oraztrasy domyślnej wskazującej na router zapewniający dostęp do innych sieci, nazywany bramką(gateway).Jeżelirouternieposiadaadresuwtejsamejsiecicohostkoniecznajestdodatkowatrasawskazującapoprzezjakieurządzeniedostępnyjestrouterdomyślny.

Opróczopisanegopowyżej routinguunicastowego (kierowaniado jednegoodbiorcy) realizowanesątakżetransmisje:

anycast – do dowolnego / najbliższego hosta o danym adresie; zasadniczo jest to transmisjaunicast, tyle żeadresdocelowynie jestunikalnywskaliglobalneja różne routerykieruje tepakietydoróżnychhostówdocelowych(typowowybierającnajbliższytakihost)multicast – do grupy hostów, w tym wypadku (multicastowy) adres IP identyfikuje "kanałnadawczy"anieunikalnyhostdocelowybroadcast – do wszystkich hostów (w ramach danej sieci – nie są routowne), transmisjerozgłoszeniowe można traktować jako szczególny przypadek transmisji multicastowych wktórychgrupamulticastowaobejmujewszystkiehosty(można jezastąpićtakimitransmisjami

Page 127: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

multicastowymi)

Klient-serwer

WoparciuoprotokółIPdziałająprotokoływarstwytransportowejtakie jakUDP,TCP,czyteż(mniejznane protokoły czasu rzeczywistego, transmisji strumieniowych): RTP, RTCP i SCTP. Najprostszymprotokołem warstwy transmisji wydaje się być UDP, protokół ten umożliwia przesłanie informacjipomiędzydwomahostamiIPiniekontrolujeontegoczyzostałaonaprzesłanapoprawnie.NatomiastTCP kontroluje to czy przesłana informacja dotarła do adresata i nie została uszkodzona, a wprzypadkuproblemówinformacjawysyłanajestponownie.TCPwzwiązkuztymwprzeciwieństwiedoUDP musi otworzyć połączenie i wykorzystywać je do kontroli poprawności przesłania informacji,wymagazatemprzesłaniawiększej liczbypakietów(comożeprowadzićdopewnychopóźnieńitp).Wzwiązku z tym TCP używany jest tam gdzie konieczna jest kontrola poprawności transmisji (orazponownewysłaniezgubionegopakietu),UDPtamgdzieniejesttopotrzebne(aliczysięczas).

Dodatkowo zarówno UDP jak i TCP na każdym z hostów wyróżniają numeryczny identyfikator dlaaplikacji/procesu/usługibędącegoodbiorcączyteżnadawcąinformacjizwanynumeremportu.

RTP często jest zaliczany jest do warstwy transportowej gdyż działa poniżej typowych protokołówwarstwyaplikacji, jednakdanektóre opisująnie są informacjami systemowymi/sieciowymi awłaśnieaplikacyjnymi, ponadto działa on powyżej protokołów transportowych (zazwyczaj nad UDP). Możeprzenosićw jednej sesji kilka strumieni, ale zazwyczaj dla każdego strumienia tworzona jest osobnasesja(zestawportów).Protokółtenumożliwiaidentyfikacjęzawartościpakietu,identyfikacjękolejnościpakietów w strumieniu. Pozwala także na przepuszczanie ruchu przez mostki maskujące oryginalneadresy,zmieniającemedium,replikującestrumień (replikowanyunicast,którywydajesiębyćbardzodobrym rozwiązaniem gdy z jakiś powodów multicast nie może zadziałać), czy też nawet łączącestrumieniezkilkuźródeł.WspółpracującyznimRTCPsłużydoprzesyłaniaraportówzinformacjamiostratach, opóźnieniach itp oraz wzajemnej synchronizacji mediów pomiędzy strumieniami - np.synchronizacjiaudiozwideo).

Popularneusługi

Wramachsiecimogąbyćrealizowaneróżneusługiwoparciuoróżneprotokoływarstwyaplikacyjnej.Standardowe usługi posiadają zdefiniowane domyślne adresy portów dla swoich protokołów. Wśródusługiprotokołówsieciowychnależywymienićprzynajmniej:

DNS (Domain Name System) - odpowiedzialny za system mapujący nazwy alfanumerycznehostównaadresyIP.mechanizmy auto konfiguracji hostów - DHCP, rozgłaszanie informacji routingowej poprzezICMPv6(protokółwarstwy3)WWW-udostępnianietreścizużyciemprotokołuHTTPpocztęelektroniczną-przesyłaniewiadomości(protokołySMTP,IMAP,POP)komunikacjęnatychmiastowąitelefonięIP(protokołySIP,XMPP,IAX)SSH-zdalny,szyfrowanydostępdosystemówIT,przesyłplikóworaztunelowanieinnychusług

Nauwagęzasługuje faktżewiększośćzwymienionychprotokołówwarstwyaplikacyjnej toprotokołytekstowe(istotnewyjątkistanowiąDNS,DHCPiSSH).

DomainNameSystem

DNS umożliwia mapowanie nazwy na adres IP (lub wiele adresów IP) oraz przechowywaniedodatkowychinformacjinatematdomenyiznajdującychsięwniejusług.Domenyposiadająbudowęhierarchiczną/drzewiastą:

precyzjarośnieodprawejdolewejkolejnepoziomyoddzielanesąkropkaminajwyższym poziomem jest kropka będąca ostatnim znakiem w pełnej nazwie domenowej (np.ciekawi.icm.edu.pl.),którąnajczęściejpomijasięwzapisiehierarchia ta jest niezależna od hierarchii routingu i wynika z faktu posiadania/użytkowaniadanej(pod)domeny)

RealizacjaodpowiedzinazapytanieDNSwyglądanastępująco:

1. host kieruje zapytanie do określonego w jego konfiguracji serwera "rozwijającego" DNS (DNSresolver),

2. serwertakisprawdzawswojejpamięcipodręcznejczyznaodpowiedźnatozapytanie(iniejestonaprzeterminowana-nieupłynąłczasTTLododnalezienia),jeżeliniemajejwswojejpamięcito

3. serwer taki znaadresygłównychserwerówDNS (root serwerów) zawierających informacjenatematserwerówobsługującychdomenynajwyższegorzęduikierujedojednegoznichzapytanieoserwerobsługującyskrajnieprawączęśćadresu(np..org),

Page 128: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

klient serwer rozwijający DNS (resolver)

root serwer DNS

ns- cc1 lub ns- cc2

ns- bb1 lub ns- bb2

zapytanie o rekord A (IPv4)dla aa. bb. cc. (1)

odpowiedź: aa. bb. cc.ma IPv4 x. y. z. q (8)

zapytanie o cc. (2)

cc. ma NS: ns- cc1 i ns- cc2 (3)

zapytanie o bb. cc. (4)

bb. cc. ma NS: ns- bb1 i ns- bb2 (5)

zapytanie o aa. bb. cc. (6)

aa. bb. cc. ma IPv4: x. y. z. q (7)

(X) oznacza kolejność wykonywanych operacj i. Przed wykonaniem zapytania resolver sprawdzaczy nie posiada w swoim cache zapamiętanej (i nie przeterminowanej) odpowiedzi na to zapytanie.

4. do otrzymanegoserwera kierowane jestzapytanie o większączęść adresu (np.eu.org),

5. itd. aż do uzyskaniaodpowiedzi o pytanyadres

DNSprzechowujeinformacjew postaci rekordówmających określony typ (wwiększości przypadków dladanej nazwy domenowejmoże być zdefiniowanychwielerekordów,tegosamegolub innych typów). Wśródnajważniejszych typówrekordównależywymienić:

NS – informacja oserwerachobsługującychDNSdanejdomenyA–mapowanienazwynaadresIPv4AAAA–mapowanienazwynaadresIPv6MX–informacjaoserwerachobsługującychpocztędanejdomenySRV– informacjeohościeświadczącymusługę(usługaokreślana jestwnazwiedomenyoktórąpytamy)PTR – mapowanie adresów IP na nazwy domenowe, realizowane w specjalnym drzewie in-addr.arpa (dlaIPv4) lubip6.arpa (IPv6),gdzieadresIPzapisywanyjestwodwróconejkolejnościpobajciedlaIPv4lubcyfrzeszesnastkowejdlaIPv6(zobaczwynikpoleceniahostzadresemIPv4iIPv6)TXT–informacjedodatkowe(np.jakieserwerypocztowe,sąupoważnionedowysyłaniapocztyztejdomeny)SOA–informacjepodstawoweostrefieopisującejdomenęCNAME – alias na inną domenę (domena którą aliasujemy nie może mieć innych wpisów, nawetSOA)

Translacjaadresów

Routeryopróczzwykłegokierowaniapakietównaodpowiedniełącze,mogątakżemodyfikowaćadresyIP i numery portów. Mechanizm ten określany jest mianem translacji adresów sieciowych (NetworkAddressTranslation).Modyfikowaniumogąulegać zarówno źródłowe (SNAT) jak i docelowe (DNAT)adresyIP,jakteżnumeryportówprotokołówwarstwytransportowej(takichjakTCP,czyUDP).

Translacjamożeodbywaćsięwoparciuostałereguły(danyadres,portlubzestawadres+portzawszemapowanyjestnatakiesamewartości)jakteżwsposóbdynamiczny,gdziemapowanieodbywasięnp.na grupę adresów lub pojedynczy adres i dynamicznie dobierane porty. Dynamiczne mapowaniewymaga od routera śledzenia przechodzących przez niego połączeń i ich stanu, celem umożliwieniaprzekazaniapakietuzodpowiedziąorazzwolnieniamapowaniapozakończeniupołączeniaTCP.

Filtracjapakietów

Względybezpieczeństwaczęstowymuszają filtracjęruchusieciowegodocierającegododanegohostalub przechodzącego przez router. Filtracja taka może odbywać się zarówno w oparciu o dane znagłówkówIP(np.adresyźródłoweidocelowe),daneznagłówkówwarstwytransportowej(np.numeryportówTCPlubUDP),jakrównieżinformacjęzsystemuśledzeniapołączeńczyteżzawartośćsamegopakietu.

TunelowanieiVPN

Możliwa jest enkapsulacja pakietów IP w pakietach innych protokołów (w szczególności także IP).PozwalatonarealizacjęróżnegorodzajutuneliIP.PrzykłademtakiegotunelujestVPNzapewniającyszyfrowanydostęp(wwarstwietrzeciej-IPlubnawetwwarstwiedrugiej-LAN)dojakiejśinnejsieci.

Multicast

Multicastjesttransmisjąjedendowielu,pozwalającąnauniknięciepowielaniaidentycznychpakietów(różniącychsiętylkoadresemodbiorcy).Metodatajestużytecznanp.przystreaminguaudio-videona

Page 129: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

żywo.MulticastowyadresIPidentyfikujedynamiczną(mogącązmieniaćsięwczasie)grupęodbiorcówi jest on przydzielany danej transmisji przez jej nadawcę, a nie przyznawany administracyjniekonkretnemu odbiorcy. W związku z tym często wszystkie pakiety adresowane do danej grupymulticastowej(mającetakisammulticastowyadresdocelowy)pochodząodtegosamegohosta(awięcmają taki sam unicastowy adres źródłowy). Zależność ta została wykorzystana w source-specificmulticast, który eliminuje problem przydzielania adresów multicastowych nadawcom – dowolnegoadresumulticastowegozpuliprzeznaczonejnapotrzebysource-specificmulticastmożeużyćkażdy,akanał multicastowy (grupa odbiorców) identyfikowana jest w oparciu o dwa adresy (unicastowynadawcyimulticastowyodbiorcy).

W celu obsłużenia transmisji multicastowych router musi posiadać informacje o aktualnie"zasubskrybowanych" przez jego klientów transmisjach multicastowych. Posiadając takie dane (czyliadres multicastowy na który kierowane są pakiety danej transmisji i ewentualnie unicastowy adresźródłowy z którego są wysyłane) może on pozyskać stosowne transmisje od routerów z którymi jestpołączonyiprzekazaćjeswoimklientom.Dopoinformowaniarouteraożądaniudostarczeniatransmisjimulticastowej (a także do przekazania informacji o zakończeniu odbioru takiej transmisji) hostywykorzystują protokół Internet Group Management Protocol (dla IPv4) lub Multicast ListenerDiscovery(dlaIPv6).Celemobsługizaprzestaniatransmisjigdyhostniepoinformowałozakończeniuodbioru, routerzwykorzystaniem tychprotokołówcopewienczaszadajepytanieczynadal sąhostyzainteresowanedanatransmisją.

QualityofService

QoSsątotechnikigwarantujące jakośćusługi.NajczęściejstosowanątechnikązaliczanądoQoSjestdynamicznypodziałprzepustowościłączazwykorzystaniemalgorytmówtakichjak:HTB(HierarchicalTokenBucket),CBQ(ClassBasedQueueing).NiejesttojednakprawdziwyQoS,gdyżmechanizmyteto coś więcej niż tylko prosty podział pasma. O QoS'ie możemy zaczynać mówić gdy systemkolejkowaniauwzględniapriorytetydlapewnychtypówruchu(m.in.napodstawiepolaToS-Typeofservice).Kolejkipriorytetowemogąbyćrealizowanejakowagowe-cykliczniezkażdejklasywysyłamyproporcjonalnie do wagi, lub bez-wagowy (klasa ważniejsza może zagłodzić klasy o mniejszympriorytecie, gdyż brany jest z ważniejszej dopóki są lub nie pojawią się jeszcze ważniejsze). IstniejądwiepodstawowearchitekturysystemówQoS:

DiffServ - nie ma ścisłych gwarancji dla jakiegokolwiek strumienia, na brzegu użytkowniknegocjujeSLAiruchjestkontrolowanypodwzględemtegoSLA(m.in.ustawianieikontrolapolaToS).Możewystępowaćtakżezarządcapasma(BandwidthBroker),zktórymkliencikomunikująsię przy pomocy protokołu RSVP (Resource Reservation Protocol) i negocjują z nim kontraktySLA, natomiast sam BB dokonuje rezerwacji zasobów w routerach i kontroluje ich stan(zazwyczajzwykorzystaniemprotokołuCommonOpenPolicyService).IntServ-odbiorcawoparciuoinformacjeuzyskaneodnadawcynatematparametrówtransmisjidokonuje rezerwacji zasobów w wszystkich routerach na ścieżce łączącej go z nadawcą(wykorzystuje do tego protokół RSVP), każdy z routerów decyduje czy może spełnić tewymagania(gdyjedenniemożecałaoperacjanieudajesię).Każdystrumieńnegocjowanyjestindywidualnie, poprzez mechanizm Addmision Control (podawane są specyfikacje filtru - jakidentyfikowaćtenruch,specyfikacjeprzepływu,itd),ponadtoinformacjeorezerwacjimusząbyćokresowoodnawiane.Wyróżniasięklasyruchu:BestEffort(standardowa),GuaranteedService(gwarancjadostępnościpasmaiopóźnienia),ControlLoadService(zapewniamymałoobciążonykanał,alebezgwarancji).

SystemyoperacyjneCorobisystemoperacyjny?

System operacyjny jest oprogramowaniem odpowiedzialnym za zarządzanie zasobami systemukomputerowego(sprzętem,alenietylko)orazuruchomionyminanimaplikacjami.Donajistotniejszychzadańsystemuoperacyjnegozaliczasiępodziałczasuprocesoraiszeregowaniezadańorazzarządzaniepamięcią - w szczególności obsługa pamięci wirtualnej, najczęściej z wykorzystaniem mechanizmustronicowania.

Oprócz tego system zajmuje się także zarządzaniem plikami, wejściem/wyjściem (najczęściej jest onorealizowane w oparciu o przerwania (IRQ), ale znane są także modele programowego we/wypolegającego na aktywnym czekaniu), obsługą urządzeń (wejście/wyjście, sterowniki, dostęp), obsługąsieci(stosprotokołówsieciowych),itd.Częśćzadańrealizowanajestzminimalnymudziałemprocesora(awięc także i systemu) jest tonaprzykład transferdanychw trybieDMApolegającyna tym iżdanekopiowane są całymi blokami bez udziału procesora do/z pamięci (system zajmuje się tylko inicjacjątransmisji). Należy tu jednocześnie zaznaczyć iż w przypadku nie stosowania tej technologii dane teżkopiowane są pomiędzy dyskiem a procesorem całymi blokami (minimum sektor) gdyż dysk (wodróżnieniuodpamięcioperacyjnej)niejestbezpośredniodostępnydlaprocesora.

Współczesne systemy korzystają z co najmniej dwóch poziomów pracy - uprzywilejowanego poziomu"nadzorcy" w którym działa jądro systemu operacyjnego oraz trybu użytkownika. Operacje I/O muszą

Page 130: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

odbywać się w trybie uprzywilejowanym. Również pamięć posiada obszar chroniony, w którymumieszczany jest m.in. tablica wektorów przerwań (inaczej zmiana adresu w tym wektorze mogłabydoprowadzićdoprzejęciasystemuwtrybieuprzywilejowanym).

Procesyiszeregowaniezadań

Istotnąroląsystemuoperacyjnegowzarządzaniuprocesami(obokczynnościadministracyjnychjakichtworzeniepowielanie,usuwanie,czyteżwstrzymywanieitp)jestzapewnienieochronypamięci(każdyprocesmożepisaćposwojej i ewentualniewspółdzielonejgdydostałdo tegoprawo)orazprocesora(przerwaniezegarowepowodujewywołanieplanisty,któryustalajakiprocesdostanienastępnykwantczasu procesora). Niektóre systemy wyróżniają obok procesów także wątki, które różnią się od nichwspółdzieloną(międzywątkamijednegoprocesu)pamięciąizasobami(np.otwartymiplikami).Systemoperacyjny zapewnia także zestaw usług i funkcji (wywołań) systemowych zapewniającychpośrednictwomiędzyinterfejsemtrybuużytkownikaasprzętem.

Istotnymzadaniemsystemuoperacyjnegojestprzeciwdziałaniemtzw.blokadom,czylisytuacjigdydwalubwięcejprocesówblokująsięwzajemniewoczekiwaniunazasoby(amazasóbX,któregopotrzebujeb aby zwolnić zasób Y, którego potrzebuje a do zwolnienia X). Realizowane to może być na kilkasposobów:

zapobieganie blokadzie (czyli niedopuszczenie do zajścia warunków koniecznych) - np. poprzezkonieczność deklarowania wszystkich zasobów na początku, zwalniania przydzielonych zasobówprzedzgłoszeniemzapotrzebowaniananastępneunikanie blokady (czyli określamy maksymalne zapotrzebowanie i tak przydzielamy zasoby abyuniknąćzajściablokady)-np.poprzezkontrolęczypospełnieniużądaniadalejbędziemydziałaćwstanie "bezpiecznym", tj takim że istnieje sekwencja (zwana bezpieczną) w której maksymalnezapotrzebowanie każdego procesu może być spełnione w oparciu o zasoby zwolnione przezprocesybędącewcześniejwtejsekwencjiorazzasobywolnewykrywanieiusuwanieblokadygdydoniejdoszło

Planistaprocesora,czylifragmentsystemuodpowiedzialnyzaprzydzielanieprocesoraprocesom,możepracować w trybie z wywłaszczaniem lub bez. W tym pierwszym wypadku proces otrzymuje kwantczasu procesora który może wykorzystać w całości (wtedy przejdzie z stanu wykonywania w stangotowości) lub z niego wcześniej zrezygnować (gdy np. czeka na I/O, wtedy przejdzie z stanuwykonywania w stan oczekiwania). W drugim przypadku proces wykonuje swój kod do momentu ażsamoddaprocesor.Formatazbliżonajestdowykorzystywanejwszeregowaniuczasurzeczywistego-procesbędziewywłaszczonytylkoprzezprocesowyższympriorytecieibędzietonatychmiastowe(przynajbliższymprzerwaniuzegarowym).Istniejewielealgorytmówszeregowaniatakichjak:

FCFS-pierwszyzgłoszony=pierwszyobsłużonySJF-najkrótszyzgłoszonybędziepierwszymwykonanym(wersjazwywłaszczaniem-SRTF-gdynowy najkrótszy pozostały), algorytm raczej nie do zastosowania praktycznego - trzeba byprzewidywaćdługośćwykonaniapriorytetowe - zawsze o najwyższym priorytecie (jak wspomniałem wyżej wykorzystywane wsystemachreal-timerotacyjne-każdypokawałku,potemnakonieckolejkikolejkiwielopoziomowe-systemzpriorytetami,podziałemczasupomiędzykolejki,przenoszeniemprocesówmiędzykolejkami,...

Zarządzaniepamięcią

Drugą podstawową funkcją systemu operacyjnego, wspomnianą na początku, jest zarządzaniepamięcią.Zarządzaniepamięciąpoleganaodpowiednimmapowaniuadresów logicznych (używanychprzezprocesy)naadresyfizyczne(używaneprzezprocesor),korzystaonozwsparciasprzętowegozestronyprocesora. Jesttonajczęściejrealizowanewoparciuowspomnianymechanizmstronicowania.Polega to na podziale pamięci dostępnej pamięci fizycznej na jednakowe bloki zwane ramkami orazpodzialepamięcilogicznejnajednakowebloki(otejcałejwielkościcoramki)zwanestronami.Stronyktóre są wykorzystywane przez program są mapowane na dowolne ramki pamięci fizycznej (wprzypadkugdydanastronaniezamapowana-wzależnościodokolicznościbłądbrakustronylubbłądochrony strony). Rozwiązuje to problem fragmentacji zewnętrznej, polegającej na braku spójnegoobszarupamięciożądanejdługościpomimoiżłącznailośćwolnejpamięcijestdostateczna,jednaknierozwiązujeproblemufragmentacjiwewnętrznej,polegającejnaprzydzielaniuzbytdużychfragmentówpamięcidlaprocesu (awręczmożnapowiedzieć żegopogłębia).Mechanizm tenwymaga trzymaniatablicy wolnych ramek, tablicy stron dla każdego procesu (zawierającej przypisania mapowań strondanegoprocesunaramki)orazwykonywaniatłumaczeniaadresówlogicznych(strona+przesunięciena stronie). Także sama tablica stron procesu procesu może być stronicowania (mamy tablicę którainformujenasżeprzypisaniastronwdanymzakresieadresówsąprzechowywanewjakiejśramce).

Stronyiramkimogąbyćwspółdzielonepomiędzyprocesami(np.przyrozgałęzianiuprocesustronysąkopiowane dopiero gdy zajdzie taka potrzeba). W przypadku braku miejsca w pamięci fizycznej

Page 131: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

wybrane strony nieaktywnego aktualnie procesu mogą być umieszczane na dysku (swap). Niekiedymożetopowodowaćszamotanieprocesupolegającenazbytdużejliczbiewymianstron.Zawszejednakprowadzitodokoniecznościustalaniaktórestronynajlepiejjestprzenieśćnadysk.Optymalnebyłobyprzenoszenie tych które najdłużej nie będą potrzebne (jednak z oczywistych względów jet topraktycznieniedozrealizowania).Stosujesięróżnealgorytmytegowyboru:

FIFO-usuwamynajdłużejbędącąwpamięciLRU - usuwanie tej do której najdawniej się odwoływano (licznik czasu, bit odniesienia, bitodniesieniawokreślonymczasie,bitmodyfikacji)LFU-usuwamyznajmniejsząliczbąodwołańMFU-usuwamyzdużąliczbąodwołań

Alternatywną (i mniej wymagającą) wobec stronicowanie metodą zarządzania pamięcią jestsegmentacja. W przypadku architektury x86 jest ona zawsze wykorzystywana jednak może byćprzykrytadużymsegmentemnaktórymwykorzystujemystronicowaniem.

ProcesuruchamianiakomputeraPo otrzymaniu sygnału resetu (także przy uruchamianiu systemu - "Power-on Reset") procesor poinicjalizacji rejestrów zaczyna wykonywanie kodu znajdującego się pod jakimś ustalonym adresem(typowo w wbudowanej lub zewnętrznej pamięci typu ROM lub Flash). W zależności od danejarchitektury / procesrora może to być m.in.: bezpośrednio kod programu użytkownika, wbudowanybootloader danego procesora umożliwiający dalsze ładowanie np. z karty SD, zewnętrznyniskopoziomowybootloader(np.u-boot).

Wprzypadkuarchitekturzgodnychzx86jesttoBIOS,którypozakończeniuprocesuinicjalizacjisprzętui testów rozruchowych ładuje do pamięci kod znajdujący się w pierwszym sektorze dysku twardego(sektorzerozruchowymrozpoczynającymsięodadresuzerowego)iuruchamiago(przekazujedoniegokontrolę).Znajduje się tamkod (lub tylkopoczątekkodu)programu rozruchowego, którego zadaniemjest załadowanie systemu operacyjnego. W przypadku współczesnych systemów linuxowych jest tozazwyczajGRUB.

W przypadku sektorów rozruchowych typu MBR (i kompatybilnych z nim), kod ten może liczyćmaksymalnie446bajtów(gdyżnakolejnychpozycjachznajdujesiętablicapartycji)ijegozadaniemjestzaładowanie i uruchomienie pozostałej części programu rozruchowego (musi znać jej położenie nadysku).PozostałaczęśćprogramurozruchowegomożeznajdowaćsiętużzaMBR(wprzerwiepomiędzyMBRapierwsząpartycją-dlatablicypartycjiMBR/msdos),wdedykowanejpartycjiBIOSbootpartition(dla tablicy partycji GPT) lub w partycji oznaczonej jako bootowalna. Część ta zawiera modułypozwalającenadostępdosystemuplikówzawierającegokonfigurację,obrazjądra,itporazinformacjęojegopołożeniu(dysk,partycja,ścieżka).

WprzypadkukomputerówopartychnaUEFI firmwareodpowiedzialny jestzazinterpretowanie tablicypartycji(GPT)izaładowanieprogramurozruchowegozplikuznajdującegosięnaspecjalnejpartycjiEFI(EFI System partition) z systemem plików FAT32. W pliku tym umieszczana jest całość (obie opisanepowyżejczęściprogramurozruchowego).

Start systemu rozpoczyna się od załadowania do pamięci obrazu jądra wraz z parametrami oraz(opcjonalnie)initrdiprzekazaniakontrolidojądraprzezprogramrozruchowy(np.GRUB).Wprzypadkujądra linuxowego i korzystania z initrd obraz ten przekształcany jest na RAM-dysk w trybie zapisu-odczytuimontowanyjakorootfszktóregouruchamianyjest/sbin/init(któregopodstawowymzadaniemjest zamontowanie właściwego rootfs). Po jego zakończeniu (lub od razu gdy nie używamy initrd)uruchamiany jest program wskazany w opcji init= jądra (domyślnie typowo /sbin/init) z rootfswskazanegowopcjiroot=jądra.Wopcjiinit=możnawskazaćdowolnyprogramlubskrypt(uruchomionyzostaniezprawamiroot'a).

Systemy"unix-owate"Jesttogrupasystemówoperacyjnych,będących(przynajmniejwjakimśstopniu)zgodnychzspecyfikacjąPOSIX / Single UNIX Specification. Charakteryzują się zbliżonym zbiorem wywołań systemowychdostępnych z poziomu jęzka C oraz funkcji biblioteki standardowej C, co ułatwia zapewnienieprzenośnościoprogramowania(wpostaciźródłowej).Zapewniająpodobnyzbiórpodstawowychkomendliniipoleceń(konsoli).

Systemyunix'oweposiadajądrzewiastysystemplikówzaczynającysięwkatalogugłównymoznaczanymprzezukośnik(/),wktórymzamontowanyjestgłównysystemplików(rootfs),innesystemyplikówmogąbyćmontowanewkolejnychkatalogach.Donajistotniejszychkatalogównależyzaliczyć:/bin

zawierającyplikiwykonywalnepodstawowychprogramów/sbin

zawierającyplikiwykonywalnepodstawowychprogramówadministracyjnych

Page 132: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

/libzawierającyplikipodstawowychbibliotek

/usrzawierającyoprogramowaniedodatkowe (wewnętrzniemapodobną strukturędogłównego - tzn.katalogi/usr/bin,/usr/sbin,/usr/lib,itd)

/etczawierającykonfiguracjeogólnosystemowe

/varzawierającydaneprogramówiusług(takiejakkolejkapoczty,harmonogramyzadań,bazydanych)

/homezawierającykatalogidomoweużytkowników(częstomontowanyzinnegosystemuplików,dlategoteżrootmaswójkatalogdomowyw/root,abybyłdostępnynawetgdytakiemontowanieniedoszłodoskutku)

/tmpzawierającypliki tymczasowe (typowoczyszczonyprzystarciesystemu);wLinuxiewystępuje też/run przeznaczonydo trzymaniadanych tymczasowychdziałającychusług takich jaknumerypid,blokady,itp

/devzawierającyplikireprezentująceurządzenia;wLinuxiewystępujeteż/syszawierającyinformacjeiustawieniadotyczącem.in.urządzeń

/proczawierającyinformacjeodziałającychprocesach(wLinuxietakżeinterfejskonfiguracyjnydlawieluparametrówjądra)

Plikiikatalogiktórychnazwarozpoczynasięodkropkitraktowanesąjakoplikiukryte.

Z punktu widzenia programisty czy też użytkownika (prawie) wszystko jest plikiem, których istniejąróżnerodzaje(zwykłyplik,katalog,urządzenieznakowe,urządzenieblokowe,linksymboliczny,kolejkaFIFO, ...);pewnymwyjątkiemsąurządzenia sieciowe (któreniemają reprezentacjiwsystemieplików(alegniazdazwiązaneznawiązanymipołączeniamiobsługujesięzasadniczotakjakpliki).

Najważniejszepolecenia

Wiele z poniższych komend stanowi standardowe polecenia określone w POSIX / Single UNIXSpecification,cogwarantujeichobecnośćnakompatybilnychsystemach(jednakniejesttopełnalistapoleceń wymaganych przez POSIX). Część z nich jest powszechnie dostępnym, wieloplatformowymoprogramowaniem dla systemów "unix-owatych". Niektóre (zwłaszcza związane z działaniamiadministracyjnymi)sąspecyficznedlaDebianalubLinuxa.

Uzyskiwaniepomocy

man[nazwapolecenia]wyświetlastronępodręcznikasystemowegonatematwskazanegopolecenia,funkcjisystemowej,plikukonfiguracyjnego

pinfo[nazwapolecenia]lubinfo[nazwapolecenia]wyświetlastronęnowegopodręcznikasystemowegonatematwskazanegopolecenia

apropos[tekst]wyszukiwaniewopisachstronpodręcznikasystemowegoapropos-s1''pozwalazapoznaćsięzspisemwszystkichstronwrozdzialepierwszym(cojestwktórymrozdzialemożnazobaczyćwmanman)

Większość poleceń obsługuje także opcje --help lub -h, które wyświetlają informację na temat ichużycia.Wtymmiejscuwartoteżzauważyćżetypowoopcjekrótkie(pojedynczalitera)poprzedzanesąpojedynczymmyślnikiem(ipojednymmyślnikumożewystąpićkilkakolejnychopcji),natomiastopcjedługiepoprzedzanesądwomamyślnikami.

Zarówno w tekstach pomocy jak i w tym dokumencie stosowana jest konwencja polegająca naoznaczaniu opcjonalnych argumentów poprzez umieszczanie ich w nawiasach kwadartowych (jeżelipodajemy ten argument do komendy nie obejmujemy go już tymi nawiasami) oraz rozdzielaniualternatywnychopcjiprzypomocy~|.Np.a[b]c|doznaczaiżpolecenieawymagaargumentupostacicalbod,którymożebyćpoprzedzonyargumentemb.

Powłoka(iokolice)

bashpopularna powłoka (interpreter poleceń) zgodna z sh, zapewnia m.in. obsługę zmiennych(zasadniczonapisowych)orazznakówuogólniającychtakichjak:?oznaczającydowolnyznak*oznaczającydowolny(takżepusty)ciągznaków[a-zAD]oznaczającydowolnyznakzwymienionychwzbiorzeujętymwnawiasachkwadratowych,

Page 133: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

zbiórmożebyćdefiniowanyzużyciemzakresów,np.a-zADoznaczadowolnąmałąliteręodadozwłącznie,spację,dużąliterąAlubD[!a-z] oznaczający dowolny znak z wyjątkiem znaków wymienionych w podanym zbiorze, zbiórmożebyćdefiniowanyzużyciemzakresów,np.a-zoznaczadowolnąmałąliteręodadozwłącznieArgumenty liniipoleceńprzekazywanedowywoływanychprzezpowłokępoleceńrozdzielanesądowolną ilością spacji. Jeżeli argument ma być napisem zawierającym spacje konieczne jestzabezpieczenieichprzypomocyodwrotnegoukośnika(\,np.aaa\bbb)lubujęciecałegonapisuwcudzysłowie pojedynczym (', np. 'aaa bbb') lub podwójnym (", np. "aaa bbb"). Oba typycudzysłowówzabezpieczająprzedrozwijaniemznakówuogólniających(zastępowaniemnapisuzeznakamilistąpasującychnazw/ścieżek).Cudzysłówpojedynczy(wodróżnieniuodpodwójnego)zabezpiecza także przed interpretacją umieszczonych wewnątrz innych znaków specjalnychtakichjakczyodwołaniadozmiennych.

ssh[user@]hostumożliwiauzyskaniepowłokizdalnegosystemupoprzezszyfrowanepołączenie,przydatneopcje:-L portLokalny:hostZdalny:portZdalny tworzy tunel przekierowujący dane kierowane na portLokalnykomputeranaktórymdziałaklientsshdoportuportZdalnynaserwerzehostZdalnypoprzezserwerSSH(przydatnegdyhostZdalnyjestosiągalnyzhostSSHaleniezkomputeralokalnego)-Dporttworzytuneldynamicznynawskazanymporcie(możeonbyćużytyjakoproxytypuSOCKSnp. w Firefoxie w celu zapewnienia dostępu do zasobów WWW dostępnych z serwera SSH aniedostępnyzkomputeralokalnego)-pportokreślainnyniżdomyślnyportserweraSSH-X aktywuje przekazywanie komend X serwera ze strony zdalnej do klienta (pozwala nauruchomienie po stronie zdalnej aplikacji z GUI, które zostanie wyświetlone na lokalnym Xserwerze)

tmuxlubscreenmultiplexer terminala - pozwala na uzyskanie wielu okien konsoli (także wyświetlanych jednoobokdrugiego)napojedynczymterminalu;ponadtopozwalająnaodłączanie ipodłączaniesesji,co pozwala na łatwe pozostawienie działającego programu po wylogowaniu i powrót do niegopóźniej

watch[opcje]polecenieokresowo uruchamia polecenie i wyświetla jego wynik, opcja -i pozwala na określenie co ilesekundmaaktualizowaćwynikpolecenia

scripttworzyzapissesji(stdin,stdout,...)

wyświetlanieiedycjaplików

vimlubvivi jest chyba najbardziej zaawansowanym edytorem, którego obecność gwarantuje standardPOSIX. vim jest mocno rozbudowanym jego klonem, oferującym bardzo zaawansowanefunkcjonalności, powszechnie stosowanym jako zamiennik oryginalnego vi. vim obsługuje 3podstawowe tryby pracy: komend (służący do wydawania opisanych niżej poleceń), wizualny(służący do zaznaczania i wydawania niektórych komend), edycji (wstawiania/nadpisywania -służącydowprowadzaniatekstu).Podstawowaklawiszologia:

przełączaniepomiędzytrybami:Escpowrótdotrybukomendi trybwstawiania; A trybwstawiania ze skokiemnakoniec linii, o / O trybwstawiania zewstawieniemnowejliniipo/przedbierzącąRtrybzastępowaniaInsertzmianatrybuwstawianiaizastępowaniav tryb wizualny (umożliwia zaznaczenie przy pomocy strzałek); ctrl+v tryb wizualnyblokowy,Vtrybwizualnyliniowy:set paste włącza :set nopaste wyłącza tryb wklejania (nie będzie działać automatyczneformatowanieitp.)gvponawiaostatniezaznaczenietrybuwizualnego

wycinanieikopiowanie:yskopiuj;d-wytnij(skopiujiusuń)poy,dmożnapodaćnp.20llub20[strzałkawprawo]cooznacza 20 kolejnych znaków, 2w oznacza dwa słowa (więcej o takich punktach skokuponiżej)xwytnij(skopiujiusuń)znak(możebyćpoprzedzoneilościąznakówdowycięcia);wielkieXdziałaanalogicznie,tyleżewtyłyyskopiujlinię;dd-wytnij(skopiujiusuń)wobuwypadkachmożebyćpoprzedzoneilościąliniidoskopiowania/wycięciapwklejapo;P-wklejaprzed

Page 134: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

komendykopiowania iwklejaniamogąbyćpoprzedzone jedno-znakowąnazwąrejestruwktórymumieszczanesądane(poprzedzamyjąznakiem" ipodajemyprzed licznikiem,np."a3ddwytniedorejestrua3linie),częśćrejestrówjestużywanaautomatycznie,aniektóresą tylko do odczytu, podgląd aktualnej zawartości rejestrów możliwy jest przy pomocykomendy:registers

wyszukiwanie,zastępowanie,skokdolinii:/szukaniewprzód,?szukaniewtył;*szukaniewprzódsłowapodkursorem,#szukaniewtyłsłowapodkursoremnwyszukanienastępnegowystąpienie;NwyszukaniepoprzedniegowystąpienieGprzejściedowskazanej linii,numerpodajemyprzedG,0oznaczaostatnią linięwpliku,więc0Gspowodujeprzejściedoniej:[zakres]s@regexp@napis@[g]wyszukaj izastąpwyrażenieregularneregexpprzeznapis;zakresmoże być: numerem linii, przedziałem z numerami linii postaci pierwsza,ostatnia, gdzie: .oznaczabieżącąlinię,$oznaczaostatniąlinięwpliku,wartośćnumerycznapoprzedzona+oznacza tyle kolejnych linii od bieżącej, a poprzedzona - przed bieżącą, znakiem % (cooznaczacałyplik), zakresemzaznaczonymw trybiewizualnym;podanieopcjig powodujezastępowaniewszystkichwystąpieńanie tylkopierwszego;znak@pełni rolęseparatora imożezostaćzamiastniegoużytyinnyznak

otwieranie,zapisywanie,zamykanieplików::eścieżkaotwarciewskazanegopliku:wzapis(możnatakżepodaćścieżkępodjakamazostaćzapisanyplik):qwyjście:q!wyjściebezzapisywania:wqzapisiwyjście

przełączaniesięmiędzyotwartymiplikamiioknami::nnastępnyplik;:Npoprzedniplik:split poziomy podział okna; :vs pionowy podział okna; Ctrl+W a następnie strzałka -przełączaniemiędzyoknami

cofanieiponawianieedycji:u,:undocofaostatniąoperacjęCtrl+r,:redoponawiacofniętąoperację

punkty skoku (mogą być używane jako polecenia do poruszania się lub jako adresy wpoleceniachtakichjakd,y):

l/h/k/jjedenznak/linięwprawo/lewo/górę/dół(działatakjakstrzałki)0/^/$począteklinii/początektekstuwlinii,koniecliniiw / b / e następne słowo / poprzednie słowo / koniec słowa; wielkie W / B / E działaanalogicznie,różnisiętraktowaniemspacjiprzysłowief / F następny /poprzedni znakpodanypo tej komendzie,włącznie znim (np.dfX usuniewszystkodonajbliższegowystąpieniaXwrazztymX);t/Tdziałaanalogicznie,tylewyłączapodanyznakpoprzedzeniepowyższychkomendliczbąpowodujepowtórzenieichtylerazy-np.10l-10znakówwprawo,3F:-trzecidwukropekwlewopunktemskokujestteżwyżejopisanepolecenieGpoprzedzanenumeremliniidoktórejmasięodbyćskokpunktem skoku mogą być także swobodnie umieszczane z dokumencie zakładkiidentyfikowanepojedynczymznakiem:

m i następie znak ją identyfikujący - utworzenie zakładkiwmiejscukursora (np. ma -utworzyzakładkęa)`(backtick)/'(apostrof)skokdozakładki/liniizzakładkąpodanąpotejkomendzie:marks-listazakładek;:delmarks/:delmarks!-usunięciezakładki/usunięciewszystkichnieautomatycznychzakładek

inne::rplik,wstawieniezawartościpliku:%!xxdpokazaniewartościnumerycznychiumożliwienieedycjiplikujakobinarnego;:%!xxd-rpowrótdonormalnejedycji>/<zwiększanie/zmniejszaniewcięciazaznaczonego(wtrybiewizualnym)tekstu

Page 135: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

zczwijabieżącyblok,zCzwijabieżącyblokażdonajwyższegopoziomu,zorozwijabieżącezwinięcie, zO rozwija rekurencyjnie bieżące zwinięcie, zR rozwija wszystkie zwinięcia wdokumencie:setwrapwłącza:setnowrapwyłączazawijanialiniiwpodglądzie

lesslubmoreprzeglądanietekstuekranpoekranie,less posiada większe możliwości od more (w szczególności posiada możliwość przeglądaniedokumentuwtył),przydatneopcje:-X nie czyści ekranu przy wychodzeniu z less'a (całość historii wyświetlania pliku pozostaje whistoriiterminala)-Fautomatyczniekończygdywyświetlanytekstmieścisięnajednymekranie

bviwzorowanynavim'ieedytorhexalny(binarny)

odlubxxdlubhexdumpwypisywanie plików interperowanych binarnie w postaci liczby oktalne, szesnastkowe, itd,przykłady:hexdump-e'1/4"%010d"1/2"%05d"2/1"%02x""\n"'plikkażdekolejne8bajtówplikuzostaniezinterpretowane jako: jedna liczba 32 bitowa liczba całkowita (4 bajty), 16 bitowowa liczbacałkowita(2bajty)idwieliczbyjednobajtowe(wyświetlaneszesnastkowo)

vbindiffporównujewizualnieplikibinarne(interfejsncurces)

Operacjenasystemieplików

katalogroboczy

cd[ścieżka]zmianabieżącegokatalogu,warto zauważyć, iż katalogi w ścieżce oddzielamy ukośnikami /, bieżący katalog oznaczamykropką.,nadrzędnyoznaczamydwiemakropkami..,ścieżki zaczynające się od ukośnika / oznaczają ścieżki bezwzględne (od korzenia systemuplików),pozostałeoznaczająścieżkęwzględną(wyrażonąwzględembierzącegokatalogu),katalogdomowyoznaczasiętyldą~

pwdwyświetlaścieżkędobieżącegokatalogu

listowanieiwyszukiwanieplików

ls[opcje][ścieżka]listowaniezawartościkatalogu,doważniejszychopcjinależyzaliczyć:-awyświetlajplikiukryte(zaczynającychsięodkropki)-l wyświetlaj pliki w formie listy z szczegółowymi informacjami (uprawnienia, rozmiar, datamodyfikacji,właściciel,grupa,rozmiar)-1wyświetlajplikiwformie1plikwjednejlinii(bezdodatkowychinformacji;stosowanedomyślnegdywynikkomendyprzekazywanyjeststrumieniemdoinnejkomendylubpliku)-hstosujjednostkitypuk,M,Gzamiastpodawaćrozmiarwbajtach-tsortujwgdatymodyfikacji-Ssortujwgrozmiaru-rodwróćkolejnośćsortowania-cużyjdatyutworzeniazamiastdatymodyfikacji(stosowanewpołączeniuz-li/lub-t)-dwyświetlajinformacjeokataloguzamiastjegozawartości

find[opcje][katalogstartowy][wyrażenie]wyszukiwanie w systemie plików w oparciu o nazwę/ścieżkę lub właściwości pliku, doważniejszychopcjinależyzaliczyć:-Pwypisujinformacjeolinkachsymbolicznychanieplikachprzezniewskazywanych(domyślne)-Lwypisujinformacjeowskazywanychprzezlinkisymboliczneplikachdoważniejszychelementówwyrażenianależyzaliczyć:-name "wyrażenie" pliki których nazwa pasuje do wyrażenia korzystającego z shellowych znakówuogólniającychkomendafind(wodróżnieniunp.odls)samodzielnieinterpretujewyrażeniazawierająceshelloweznaki uogólniające w argumentach tych opcji, w związku z czym konieczne może się okazaćzabezpieczenie ich przed interpretacją przez powłokę np. przy pomocy umieszczenia wewnątrzpojedynczychcudzysłowów-iname"wyrażenie"jak-name,tyleżenierozróżniawielkościliter-path"wyrażenie"plikiktórychścieżkapasujedowyrażeniakorzystającegozshellowychznakówuogólniających-ipath"wyrażenie"jak-path,tyleżenierozróżniawielkościliter-regex"wyrażenie"plikiktórychścieżkapasujedowyrażeniaregularnego-iregex"wyrażenie"jak-regexp,tyleżenierozróżniawielkościliter

Page 136: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

warunek-owarunekłączywarunkisumąlogicznąORzamiastdomyślnegoiloczynulogicznegoAND!waruneknegacjawarunku-mtime[+|-]nplikiktórychmodyfikacjaodbyłasięn*24godzinytemu-mmin[+|-]nplikiktórychmodyfikacjaodbyłasięnminuttemu-ctime[+|-]nplikiktórezostałyutworzonen*24godzinytemu-cmin[+|-]nplikiktórezostałyutworzonenminuttemu-size[+|-]n[c|k|M|G]plikiktórychrozmiarwynosin(c-bajtów,k-kilobajtów,M-Megabajtów,G-gigabajtów)wpowyższychtestach+oznaczawięcejniż,-oznaczamniejniż,uwaga:porównywaniupodlegająliczbycałkowite,np.+1oznacza > 1wliczbachcałkowitychtzn. ≥ 2-execpolecenie\{\}\;dlakażdegoznalezionegoplikuwykonajpoleceniepodstawiającścieżkędotegoplikupod\{\}(zastosowaneodwrotneukośnikisłużązabezpieczeniunawiasówklamrowychiśrednikaprzedzinterpretowaniemichprzezpowłokę)-execdirpolecenie\{\}\;,podobniejak-exectyleżepoleceniezostanieuruchomionewkataloguwktórymznajdujesięwyszukanyplik

tree[ścieżka]wyświetladrzewokatalogówiplików

statścieżkawyświetlainformacjeopodanymplikulubkatalogu

realpathścieżkawypisujeuproszczoną/rozwiniętąścieżkę(tzn.zezredukowanyminadmiarowymiodniesieniamiwzględnymi),standardowo wypisuje ścieżkę bezwzględną (opcja --relative-to=katalog powoduje wypisaniewzględnejwstosunkucodokatalog),standardowo zastępuje linki symboliczne wskazywaną przez nie ścieżką (opcja -s wyłącza tąfunkcjonalność),opcja-mpozwalanaoperowanienieistniejącymiścieżkami,standardowezachowanieodpowiadadziałaniukomendyreadlink

du[opcje]ścieżka1[ścieżka2[...]]wyświetlanie informacji o zajętej przestrzeni dyskowej przez wskazane pliki / katalogi, doważniejszychopcjinależyzaliczyć:-s podaje łączną ilość zajętego miejsca dla każdego argumentów (zamiast wypisywać rozmiarkażdegopliku)-cpodajełącznąilośćzajętegomiejscadlawszystkichargumentów-hstosujejednostkitypuk,M,Gpodawany rozmiar może się różnić (w obie strony) od wyniku ls: ls podaje rozmiar pliku (ilezawiera informacji lub ile zostało zadekarowane że może jej zawierać), a du to ile zajmuje nadysku

df[opcje]wyświetlanieinformacjiozajętościmiejscanaposzczególnychsystemachplików

kopiowanie,przenoszenie,usuwanie,...

cp[opcje]źródło1[źródło2[...]]celkopiujewskazanyplik(lubpliki)dowskazanejlokalizacji,wprzypadkukopiowaniawieluplikówcelpowinienbyćkatalogiem,doważniejszychopcjinależyzaliczyć:-rpozwalana(rekursywne)kopiowaniekatalogów-apodobniejak-r,dodatkowozachowującatrybutyplików-lzamiastkopiowaćtworzytwardedowiązania(hardlinks)-szamiastkopiowaćtworzylinkisymbolicznedoplików-fnadpisywaniebezpytania-izawszepytajprzednadpisaniem

lnźródło1[źródło2[...]]celtworzy link twardy do wskazanego pliku (lub plików) w wskazanej lokalizacji, w przypadkuwskazania wielu plików źródłowych cel powinien być katalogiem, do ważniejszych opcji należyzaliczyć:-stworzydowiązaniasymbolicznezamiasttwardych-rużywaścieżkiwzględnejzamiastbezwzględnejprzytworzeniudowiązańsymbolicznych

Page 137: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

katalog*

**)dokładniej„miejsca”wsystemieplikówokreślanezapomocąi-nodów

zawartośćdysku**

*)nakatalogpatrzymyjaknaplikzawierającyinformacjeozawartościtegokatalogu

plik1.txtplik2.txt

Alamakota

KotmaAlę

...

...

...link1.txtlink2.txt→./plik1.txt ln-s./plik1.txtlink2.txt

lnplik2.txtlink1.txtpowodujeutworzenielinkutwardegolink1.txt,czyliwpisuwkataloguwskazujacegonatesamedane(tensami-node)coplik2.txt

powodujeutworzenielinkusymbolicznegolink2.txt,czyliwpisuwkataloguwskazującegonapodanąścieżkę(./plik1.txt)

Link twardy jest innym uchwytem do tych samych danych i może być używany także poskasowaniu oryginalnego pliku. Liczbę dowiązań do danego pliku pokazuje m.in. komenda ls zopcją -l. Nie można utworzyć linków twardych do katalogów, ani do plików na innym zasobiedyskowym(innymsystemieplików).Link symboliczny wskazuje na konkretną ścieżkę (względną lub bezwzględną – co może miećznaczenie przy przenoszeniu takiego linku) do dowolnego (nawet nie istniejącego – wtedymówimyozerwanymlinku)plikulubkatalogu.

mv[opcje]źródło1[źródło2[...]]celprzenosi wskazane pliki / katalogi do wskazanej lokalizacji, w przypadku przenoszenia wieluplikówcelpowinienbyćkatalogiem,doważniejszychopcjinależyzaliczyć:-fnadpisywaniebezpytania-izawszepytajprzednadpisaniem

rm[opcje]ścieżka1[ścieżka2[...]]usuwawskazanepliki,doważniejszychopcjinależyzaliczyć:-rpozwalanana(rekursywne)kasowaniekatalogówwrazzzawartością-fusuwaniebezpytania-izawszepytajprzedusunięciem

touch[opcje]ścieżka1[ścieżka2[...]]zmianadatymodyfikacjipliku(wykorzystywanytakżedotworzeniaplików)

katalogi

mkdir[opcje]ścieżka1[ścieżka2[...]]tworzywskazanekatalogi,doważniejszychopcjinależyzaliczyć:-p pozwala na tworzenie całej ścieżki a nie tylko ostatniego elementu, nie zgłasza błędu gdywskazanykatalogistnieje

rmdir[opcje]ścieżka1[ścieżka2[...]]usuwawskazanekatalogi(musząbyćpuste)

zdalnekopiowanie

scp[opcje]źródło1[źródło2[...]]celkopiujewskazanyplik(lubpliki)dowskazanejlokalizacji,wprzypadkukopiowaniawieluplikówcelpowinienbyćkatalogiem,doważniejszychopcjinależyzaliczyć:-rpozwalana(rekursywne)kopiowaniekatalogów-PportokreślaportSSHW odróżnieniu od cp źródło lub cel w postaci [user@]host:[ścieżka] wskazują na zdalny systemdostępnypoprzezSSH.

rsync[opcje]źródłocelkopiuje (synchronizacjiuje) pliki i drzewa katalogów (zarówno lokalnie jak i zdalnie), doważniejszychopcjinależyzaliczyć:-rpozwalana(rekursywne)kopiowaniekatalogów-lkopiujelinkisymbolicznejakolinkisymboliczne(zamiastkopiowaniazawartościplikunaktórywskazują)-tzachowujeczasmodyfikacjiplików-ukopiujetylkogdyplikźródłowynowszyniżdocelowy-ckopiujetylkogdyplikźródłowyidocelowymająinnesumykontrolne--deleteusuwazdocelowegodrzewakatalogówelementyniewystępującewdrzewieźródłowym-e'ssh'pozwalanakopiowaniena/zzdalnychsystemówzapośrednictwemssh,źródło lubcelwpostaci[user@]host:[ścieżka]wskazująnazdalnysystem--partial--partial-dir=."-tmp-"zachowujeskopiowaneczęściowoplikiwkatalogu.-tmp-(pozwalanaprzerwanieiwznowienietransferupliku)--progresspokazujepostępkopiowania--exclude="wzorzec" pomija (w kopiowaniu i kasowaniu) pliki pasujące do wzorzec (wzorzec możezawieraćznakiuogólniającepowłoki)-nsymulujepracę(pokazujecozostałobyskopiowane,aleniekopiuje)

Page 138: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

sshfs[opcje]host:scieżkamontuje zdalny system plików z użyciem FUSE (filesystem in userspace) oraz SSH, doważniejszychopcjinależyzaliczyć:-pportokreślainnyniżdomyślnyportserweraSSH-oworkaround=rename,któryzapewniapoprawnemvnaistniejącyplik

Operacjenaarchiwach

tararchiwizujewieleplikówwpostacijednego,przykłady:tar -xf plik.tar - wypakowuje zawartość niekompresowanego archiwum plik.tar interpretujączapisanewarchiwumścieżkiwzględembieżącegokatalogutar -czf - ścieżka1 [ścieżka2 [...]] | ssh [user@]host 'cat > plik.tgz' - archiwizuje wskazanepliki/katalogibezpośrednionazdalnysystemzużyciemsshikompresjigzip

arpolecenie[modyfikatory]archiwum[pliki]archiwizuje wiele plików w postaci jednego (format wykorzystywany w plikach biblioteklinkowanychstatycznieiwpakietachDebiabna),przykłady:arrcslibAA.aaa*.o-tworzybibliotekęlibAA.azwszystkichplikówaa*.oarxpakiet.deb-wypakowujezawartośćpakietuDebianazplikupakiet.deb(będątodwaarchiwaiplikzwersjąformatupakietu)

7zarchiwizerobsługującewieleformatów,wtymformatyzsilnąkompresją

Operacjenaplikach(tekstowych)

cat[opcje][plik1[plik2[...]]]wypisywanieiłączenieplików

tac[opcje][plik]wypisywanieplikówzodwróceniemkolejnościlinii(odwróceniekolejnościwypisywania;możebyćużytenp.doodwrócenieporządkusortowania)

tail[opcje][plik]wyświetlaostatnieliniepliku,przydatneopcje:-nxokreślażemazostaćwyświetlonexostatnichlinii-furuchamiadopisywania(gdydoplikuzostanądopisanenowelinietailjewyświetli)

head[opcje][plik]wyświetlapoczątkoweliniepliku,przydatneopcje:-nxokreślażemazostaćwyświetlonexpierwszychlinii

multitailtaillepiejoperującynawieluplikachrównocześnie

rev[plik]wypisujeplikodwracająckolejnośćznakówwkażdymwierszu

wcliczylinie,słowa,znakiibajty

grep[opcje]wyrażenie[plik1[plik2[...]]]wyszukujepasującedowyrażeniaregularnegowyrażenieliniewplikach,przydatneopcje:-vzamiastpasującychwypiszniepasujące-iignorujwielkośćliter-aprzetwarzajplikibinarnejaktekstowe-EkorzystajzExtendedRegularExpressions(ERE)zamiastBasicRegularExpressions(BRE)-P korzystaj z Perl-compatible Regular Expressions (PCRE) zamiastBasic Regular Expressions(BRE)-rrekursywnieprzetwarzajpodanekatalogiwyszukującwwszystkichznalezionychplikach-Rjak-r,alezawszepodążazalinkamisymbolicznymi--exclude="wyrażenie"pomińplikipasującedowyrażenie(możezawieraćznakiuogólniającepowłoki)-lwypisujeplikizpasującymiliniami-Lwypisujeplikizbezpasującychlinii

diffścieżka1ścieżka2porównujeplikilubkatalogi(wprzypadkutychdrugichporównujezesobąplikiotakichsamychnazwachorazzgłaszafaktwystępowaniaplikutylkowjednymzkatalogów),przydatneopcje:-rrekursywnieprzetwarzajpodanekatalogi-uwypisujeróżnicewformacie"unified"-cwypisujeróżnicewformacie"context"

vimdiffścieżka1ścieżka2porównuje pliki wyświetlając je jeden obok drugiego (podobnie jak diff z opcją -y), pozwalającjednaknaedycjętychplików

patchstosujeplikłaty(wynikdiff'a)wceluzmodyfikowaniaplików,typowo:

Page 139: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

patch -pn < plik.diff co powoduje zastosowanie zmian opisanych w plik.diff na plikach wbieżącym katalogu, n określa ilość poziomów ścieżek podanych w pliku łaty które mają zostaćzignorowane

combinediff/splitdiffłączydwaplikiłat/dzieliplikłatzłożonyzprzyrostowychzmiannaosobne(pakietpatchutils)

flipdiffzmienia kolejność w której będą nakładane dwie łaty dotyczące tych samych plików (pakietpatchutils)

interdiffporównywaniedwóchplikówłat(pakietpatchutils)

lsdiffwyświetlanieplikówmodyfikowanychprzezłatę(pakietpatchutils)

filterdiffwyciągnięciezplikułatyzmiandotyczącychwybranychplików(pakietpatchutils)

grepdiffprzeszukiwanie pliku łat celem znalezienia plików w modyfikacja których pasuje do wyrażeniaregularnego(pakietpatchutils)

rediff/editdiff/recountdiffprzeliczanienumerówliniiwplikułaty(pakietpatchutils)

unwrapdiff/dehtmldiff/fixcvsdiffnaprawa pliku łaty uszkodzonego przez zawijanie linii, html-izację, błędy w generowaniu łatyprzezcvs(pakietpatchutils)

quiltnarzędzieułatwiająceutrzymywaniezmiandojakiśplikówwpostacizbiorułat

sort[plik]sortujeliniewwskazanympliku,przydatneopcje:-ntraktujliczbyjakowartościnumeryczneanienapisy-iignorujwielkośćliter-rodwróćkolejnośćsortowania-knsortujwgkolumnyn-tsepkolumnyrozdzielanesąprzypomocyseparatorasep

tr[opcje]zbiór1[zbiór2]zastępujeznakizzbiór1odpowiadającymiimpodwzględemkolejnościznakamizzbiór2,przydatneopcje:-dzamiastzastępowaćusuwaznakiwystępującewzbiór1uwaga:częstodziałapoprawniewyłączniedlaznakówjednobajtowych-możnawtedyzastosowaćsed-e'y#zbiór1#zbiór2#'lubtrs-f'zbiór1zbiór2'

trs(wchodzącywskładpakietukonwert)bardziej inteligentnyodtrprogramsłużydozamienianiaznakówz jednegozbiorunaznakizdrugiegozbioru(wodróżnieniuodtrnadajesiędoznakówkilku bajtowych - utf8, lepiej od sed'a sprawdza się przy zmianie kodowań - patrz przykład wmanualu)

sed[opcje][pliki]edytujeplikzgodniezpodanymipoleceniami,przydatneopcje:-e "polecenie" - wykonuj na pliku polecenie (może wystąpić wielokrotnie celem podania wielupoleceń)-f"plik"-wczytajpoleceniazplikuplik-E-używajrozszerzonychwyrażeńregularnych-i-modyfikujpodanyplikzamiastwypisywaćzmienionynastdout-n-wyłączadomyślnewypisywanielinii,wypisaniemusibyćwykonanejawniepoleceniempprzydatnepolecenia:s@regexp@napis@[g]-wyszukajdopasowaniadowyrażeniaregularnegoregexpizastąpjeprzeznapis,podanieopcjigpowodujezastępowaniewszystkichwystąpieńanietylkopierwszego,znak@pełnirolęseparatoraimożezostaćzamiastniegoużytyinnyznaky@zbiór1@zbiór2@ - zastąp znaki z zbiór1 znakami odpowiadającymi im pod względem kolejnościznakamizzbiór2,znak@pełnirolęseparatoraimożezostaćzamiastniegoużytyinnyznakmożliwejestteżm.in.adresowanieliniinaktórychmabyćwykonywanaoperacja,np:0,/regexp/s@regexp@napis@wykonapolecenie sna liniachodpoczątkuplikudo linii pasującej dowyrażeniaregularnegoregexp,czylizastąpitylkopierwszewystąpieniewpliku

cut[opcje][pliki]wybierazplikuzadanyzestawkolumn,przydatneopcje:-fnnnwypierzkolumnyokreśloneprzeznnn(np.1,3-4,6-oznaczakolumnę1,kolumnyod3do4iod6,a-3oznacza3pierwszekolumny)-dsepkolumnyrozdzielanesąprzypomocyseparatorasep(musibyćpojedynczymjednobajtowymznakiem,abyominąćtoograniczenienależyskorzystaćzawk)

Page 140: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

awkskryptowy językumożliwiającyprzetwarzanie tekstowychbazdanychpostaci linia=rekord,polaoddzielaneustalonymseparatorem(m.in.łączyfunkcjonalnośćgrep,cut,itp),szerzejomówionywprzykładzieprzetwarzanianapisówwbashu

pastełączy(odpowiadającesobiepodwzględemnumerów)liniezdwóchplików

joinłączyliniezdwóchplikówwoparciuoporównaniewskazanegopola

commporównuje dwa posortowane pliki pod względem unikalności linii (może wypisać wspólne lubwystępującetylkowjednymzplików)

uniqusuwapowtarzającesięliniezposortowanegopliku,przydatneopcje:-cwypiszliczbępowtórzeń-dwypisztylkoliniez2lubwięcejwystąpieniami-uwypisztylkoliniez1wystąpieniem

xmlstarletnarzędzie do przetwarzania, modyfikowania plików XML (można powiedzieć taki odpowiedniksed/awkdlaxml'a)

xsltprocnarzędziedoprzetwarzaniaXSLT1.0

Uprawnieniadoplików

Podstawowe unixowe uprawnienia do plików składają się z trzech członów: uprawnienia dlawłaściciela(u),grupy(g)ipozostałychużytkowników(o).Wkażdymzczłonówmogąbyćprzyznaneuprawnieniadoczytania(r),pisania(w)iwykonywania(x);w odniesieniu do plików jest to intuicyjne (uprawnienie do wykonywania jest potrzebne douruchomieniaprogramów),natomiastwstosunkudokatalogówwyglądatonastępująco:uprawnieniado czytania pozwalają na listowanie zawartości, do wykonania pozwalają na dostęp, do zawartościkatalogu (wejściadoniego)dopisaniana tworzenienowychobiektówwewnątrzniego i zmienianienazwistniejących.Wartozaznaczyćiżprogramwplikuniemającymprawwykonywalnościteżmożebyćwykonany(wprzypadkuskryptupoprzezuruchomienieinterpretatoraipodanietegoprogramujakoodpowiedniegoargumentu wywołania, w przypadku typowych binarek poprzez wywołanie /lib/ld-linux.so.2 z tymplikiemijegoopcjamijakoparametrem.

Rozszerzeniem podstawowych uprawnień opisanych powyżej jest mechanizm Filesystem AccessControlList(ACL,fACL).Jest on opcjonalnym mechanizmem który (na wspierających go systemach plików) pozwala nadefiniowanie indywidualnychuprawnieńdoplikudlaposzczególnychużytkownikówigrup-plikmanadalswojegowłaściciela,grupęiwszystkichpozostałych,aleprzedprawamidla"others"wchodząprawaużytkownikówigrupdefiniowanychwACL.Wypadkoweprawaobliczanesąjakosumawynikłazprawużytkownikaigrupdoktórychnależy.ACLpozwalaponadtodefiniowaćuprawnieniadomyślnedlanowopowstałychplikówwkatalogu(sąoneopcjąkatalogu).

Wszystkie poniższe komendy przyjmują opcję -R powodującą rekursywne wykonywanie zmian nadrzewkukatalogów/plikówrozpoczynającymsięwpodanejścieżce.

chown[opcje]właścicielścieżkazmianawłaścicielapliku

chgrp[opcje]grupaścieżkazmianagrupydoktórejnależyplikpliku

chmod[opcje]uprawnieniaścieżkazmianaprawadostępudopliku(ów)

getfacl[opcje][ścieżka]dczytuprawnieńzwiązanychzlistamikontrolidostępufACL

setfacl[opcje][ścieżka]ustawianieuprawnieńzwiązanychzlistamikontrolidostępufACL

Dodatkowonależywspomniećteżopoleceniachtakichjak:lsattr/chattr

wyświetla/modyfikujeatrybutyplikówzwiązanychzsystememplików(np.zabraniajakiejkolwiekmodyfikacjipliku)

getcap/setcapwyświetla / modyfikuje atrybuty plików związanych z właściwościami jądra (zasadniczo

Page 141: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

zwiększonymi uprawnieniami programów je posiadających, ale bardziej ograniczonymi niżwykonanienaprawachrootprzezSUID)

Użytkownicy

id[użytkownik]informacjaoużytkowniku(m.in.grupydoktórychnależy)

whoamiinformacjaoaktualnymużytkowniku

wlubwhoinformacjaozalogowanychużytkownikach

lastostatniologującysięużytkownicy

lastbostatnienieudanelogowania

lastlogostatnielogowaniaużytkowników

passwd[użytkownik]zmianahasła

su[użytkownik]przełącza użytkownika (aby przełączony użytkownik miał dostęp do "naszego" x serwerawcześniejwydajemyxhostLOCAL:użytkownik)

sudoprogram pozwalający na wykonywanie uprzywilejowanych komend przez wyznaczonychużytkowników

Procesyizasoby

ps[opcje]wyświetlaaktualniedziałająceprocesyiinformacjeonichnp.kombinacjaopcji-Afpowodujewyświetleniewszystkichprocesówwrozszerzonym formaciewypisywania

pgrepwyświetlafiltrowanąlistęaktualniedziałającychprocesów

pstreewyświetladrzewoaktualniedziałającychprocesów

pwdxpodajekatalogroboczypodanegoprocesu

topmonitorowanieprocesówobciążającychCPU,pamięć,itd

iotopmonitorowanieprocesówobciążającychI/O

fuserinformacjeoprocesachkorzystającychzplików

lsofinformacjeoplikachotwartychprzezprogram(możnapodglądaćtakżew/proc/PID/fd/)

socklistwyświetlalistęotwartychsocketów

vmstatinformacjeoobciążeniusystemu

ipcsinformacjeowykorzystaniupamięciwspółdzielonej

kill[opcje]pidprzesyłasygnałdoprocesówopodanychPID

killall[opcje]nazwaprzesyłasygnałdoprocesówopasującejnazwie

timeczasdziałaniaprogramu

nice/renice/ionice/cpulimitzarządzaniepriorytetamiilimitamiprocesu

tasksetzarządzanieprzypisaniemprocesudoCPU/rdzenia

free

Page 142: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

informacjaozajętościpamięci

Informacjeośrodowiskuisystemie

env/printenvzmienneśrodowiskowewypisywanieorazprzekazywaniedouruchamianegoprogramu

exportustawianieiusuwaniezmiennychśrodowiskowych

set/unsetustawianie,wyświetlanie,usuwaniezmiennych/funkcji/opcjiwśrodowiskupowłokibash

uptimeinformacjaotymjakdługodziałasystem...

unameinformacjaosystemie

lsb_releaseinformacjaosystemiezgodnymzLSB

getentinformacje z baz administracyjnych (typu użytkownicy, grupy, hosty), z uwzględnieniem ichkonfiguracjiw/etc/nsswitch.conf

Diagnostykasieci

Adresy

ipcalcorazsipcalckalkulatorIP(pozwalającynaobliczanieadresówsiecirozgłoszeniowych,zmianęnotacjiitd)

whoisinformacjezbazywhois(odomenielubadresieIP)

Dostępnośćitrasydohostów

ping[opcje]hostlubping6[opcje]hostsprawdzaniedostępnościhostazużyciemprotokołuICMP(obecniekomendaping6najczęściejjestrównoważna poleceniu ping z opcją -6 wymuszającą używanie jedynie IPv6, na starszychsystemachkomendapingmożenieobsługiwaćadresówIPv6iwtedykoniecznejeststosowaniedonichpoleceniaping6),ważniejszeopcje:-c n wykonaj n (domyślnie pyta do momentu przerwania przy pomocy np. Ctrl-C, lub sygnałuwysłanegozuzyciemkomendykill)-nniezamieniajadresuIPhostaktóryodpowiedziałnanazwędomenową

traceroute,traceroute6,tracepath,tracepath6,tcptraceroutelubtcptraceroute6sprawdzanieścieżkidohosta(wypisanielistyrouterówprzezktóreprzechodzipakietwdrodzedowskazanegohosta)Istnieją różne warianty tych poleceń (nawet pod tą samą nazwą), różnią się one stosowanymimechanizmami idomyślnymiopcjami.Generalniewszystkieuruchamiasięnazasadziepolecenie[opcje] host. Warianty z 6 na końcu nazwy będą używały jedynie adresów IPv6, natomiastpoleceniabez6nakońcunazwymogąpotrafićichużywaćlubnie.Wszystkiepopularnewariantypozwalają na podanie opcji -n wyłączającej zamienianie adresu IP hosta który odpowiedział najegonazwędomenową.Może zdarzyć się że śledzenie urwie się na jakimś hoście (np. z powodu jego konfiguracji lubbłędówwjegooprogramowaniusieciowym),możesięzdarzyćżeprzyużyciuinnejkomendyztejgrupy(lubzmianieopcji)udasięprześledzićdalszątrasępakietu.

mtr[opcje]hostsprawdzanie ścieżki do hosta (czyli podobnie jak traceroute i tracepath) w trybie ciągłym (zciągłym odświeżaniem) wraz z wypisywaniem informacji o stratach pakietów i opóźnieniach naposzczególnychodcinkach,ważniejszeopcje-nniezamieniajadresuIPhostaktóryodpowiedziałnanazwędomenową

nmapskanersieciowy-sprawdzaniedostępnychhostówwsieci,otwartychportów,itd

arpingnarzędziedopingowaniazwykorzystaniemzapytańARPzamiastICMPistnieją dwie zasadnicze odmiany: z iputils oraz z synscan; ta druga zawarta w debianowympakiecie"arping"umożliwiatakżepingowaniepoadresieMAC(alenieprzezRARP,boonniedotegosłuży),abytojednakdziałałohostdocelowyniemożeignorowaćpingówrozgłoszeniowych,metodaobejściaopisanajestwREADMEarping'a

arp-scanwyszukiwanie hostów w oparciu o zapytania ARP (można powiedzieć że jest to równoważneuruchamianiukomendyarpingwpętli)

Page 143: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

DNS

dig[opcje]nazwa[typRekordu]narzędzia do uzyskania informacji z DNS, pozwala na określenie poprzez @adres serwera którychcemyodpytaćoraznaokreślenie(poprzezdrugiargument)typurekorduktórychcemyuzyskaćzamiast typu rekordu można podać: ANY (powoduje odpytanie o wszystkie rekordy) lub AXFR(powodujewysłanieprośbyotransfercałejstrefy,działajeżelidanyhostmaprawotransferucałejstrefyzdanegoserwera)

host[opcje]nazwa|ip[server]narzędziadozamianyadresówdomenowychnaIPiodwrotnieorazwyciąganiainnychinformacjizDNS(np.rekordyMX)

nslookup[opcje]nazwa|ip[server]narzędziadozamianyadresówdomenowychnaIPiodwrotnieorazwyciąganiainnychinformacjizDNS(np.rekordyMX)

dnstracerśledzenietrasyzapytańDNS

dnswalkdebugerDNS

IPv6

ndisc6testowanieICMPv6NeighborDiscovery

rdisc6testowanieICMPv6RouterDiscovery

rltraceroute6trasapakietówdodanegohostaIPv6zużyciemUDP/ICMP

tcpspray6pomiarprędkościłączazużyciemTCP/IPDiscard/Echo

na6/ns6wysyłaniepakietówNeighborAdvertisement/Solicitation

ra6/rs6wysyłaniepakietówRouterAdvertisement/Solicitation

ni6/rd6wysyłaniepakietówICMPv6NodeInformation/Redirect

scan6skanowaniesieciIPv6

debugowaniełącznościsieciowej

netcatlubnclubnetcat6program pozwalający na wysyłanie pakietów TCP i UDP z definiowaną przez nas zawartością,oraz odbiór pakietów TCP i UDP (słuchanie na wskazanym porcie), umożliwia m.in. testowanieusług sieciowych (takich jak smtp, www, jabber, ...); uwaga: występuje w kilku wersjachróżniącychsięopcjami

telnetprogram umożliwiający zdalny (nieszyfrowany, łącznie z hasłem!) dostęp do powłoki, a także(podobniejaknetcat)m.in.testowanieusługsieciowych

swaksnarzędziedotestowaniaSMTP

tcpdumpprzechwytuje komunikację sieciową celem analizy nagłówków lub pełnej zawartości pakietów(wsparcie dla niektórych z protokołów warst wyższych wymaga doinstalowania - np. obsługęDHCPzapewniadhcpdump)

wiresharklubtsharkprzechwytuje komunikację sieciową celem analizy nagłówków lub pełnej zawartości pakietów,wspiera dekodowanie wielu protokołów warstwy aplikacyjnej, wireshark posiada graficznyinterfejsużytkownika,tsharkjestwersjąkonsolową

informacjeowykorzystaniuiprędkościsieci

netstatinformacjeosieci

iptrafmonitorIPLAN

nloadgraficzne(ncurses)pokazywaniewykorzystania(prędkości)interfejsówsieciowych

Page 144: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

ttcptestujeprędkośćpołączeniasieciowego(stronadomowa,najnowszawersjaorazmutacja)

iperfpomiarprędkościpołączeniasieciowego

Konfiguracjasieci

podstawowakonfiguracjainterfejsów

ipinformacjenatematinterfejsówsieciowych(adresówIP,etc)iroutingóworazichkonfiguracja

ifconfiginformacjenatematinterfejsówsieciowych(adresówIP,etc)orazichkonfiguracja

routekonfiguracjaroutingu

arpwyświetlanieimanipulowanietablicąprotokołuARP

dhclientkonfiguracjaautomatycznainterfejsuwoparciuoDHCP

konfiguracjamechanizmówjądrowychwLinuxie

vconfigkonfiguracja(tagowanych)VLANów

brctlkonfiguracjabridge'ów(softwarowegoswitchadziałającegowwarstwie2)

ifenslavekonfiguracjabondingu

iptablesjądroweregułyfiltrowaniairoutingupakietów

iptablesjądroweregułyfiltrowaniairoutingupakietówdlabridge'ów

iptablesjądroweregułyfiltrowaniairoutingupakietówwwarstwiedrugiejOSI

konfiguracjakartsieciowych(wtymWiFi)

ethtoolkonfiguracja kart ethernetowych pod względem takich parametrów jak prędkość transmisji,duplex,wakeonlan,etc

iwconfigkonfiguracja (większości - do części trzeba użyć wlanctl-ng) bezprzewodowych interfejsówsieciowych

wpa_supplicantkonfiguracjawiększościbezprzewodowychinterfejsówsieciowychzwsparciemdlaWPA

wpa_clikonfiguracjawiększościbezprzewodowychinterfejsówsieciowychzwsparciemdlaWPA

iwlistdodatkowe informacje z bezprzewodowych interfejsów sieciowych (przydatna zwłaszcza opcjascanpokazującadostępnesieci

Narzędziaprogramistyczne

clanglubgcckompilatorC

clang++lubg++kompilatorC++

ldlinker

python3lubpythoninterpreterPythona

cmakesystemgeneracjiplikówMakefile

makesystembudowaniaaplikacjiwoparciuoplikiMakefile

lddwyświetlaniewykorzystywanychprzezprogrambibliotekdynamicznych

Page 145: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

ldconfigkonfiguracjabibliotekdynamicznych(m.in.określanieścieżekwjakichsąwyszukiwane),refreshbazydostępnychbibliotek;patrzteż/etc/ld.so.conf

git,hg,svnsystemykontroliwersji

Narzędziaadministracyjne

shutdownwyłączanie i restartowanie systemu (komputera), podobnie do bezpośredniego operowania napoziomachinit

partedlubfdiskoglądanieimodyfikowaniepodziałudyskunapartycje

mount/umountmontowanie/odmontowywaniesystemuplikówwartozwrócićuwagęnaopcjęmontowania-obindumożliwiającąmontowaniekataloguwinnymkataloguorazna-oremountumożliwiającązmianęparametrówpodmontowanegosystemuplików

chroot/fakechroot/schrootnarzędziadouruchamianiaprogramu/programówzpodmienionymkatalogiemgłównym

dd/ddrescuetworzeniekopiurządzenia/plikuobrazu(ddrescuezlepszątolerancjąbłędówodczytu)

aptlubaptitudemenagerpakietówsystemachopartychoDebiana

dpkgniskopoziomowenarzędziedozarządzaniapakietamideb

adduser/deluserorazaddgroup/delgroupzarządzanieużytkownikami

dmesglogijądra

lspcilistowanie urządzeń podłączonych do magistrali PCI, PCI-express, ... (aktualizacjia bazyidentyfikacyjnejupdate-pciids)

lsusblistowanieurządzeńpodłączonychdomagistraliUSB

lsscsilistowanieurządzeńobsługiwanychprzezpodsystemSCSI(m.in.SATA,SCSI,FC)

dmidecodeodczytinformacjiosprzęcie

ddcprobeodczytinformacjiomonitorze

smartctlodczytinformacjiS.M.A.R.T.dotyczącychdyskutwardego

hdparm/sdparmustawieniaparametrówdyskówtwardych(np.opcja-Sustawiaczaspojakimusypianyjestdysk)

hddtempnardzędziedokontrolitemperaturydyskutwardego

mbmon/xmbmonmonitorowanieparametrówpracypłytygłównej

sensorsdanezczujnikówwkomputerze(takiejaknapięcia,temperatury,prędkościwentylatorów)

acpistanzasilania/baterii

Innenarzędzia

echo/printfwypisujeargumentynastandardowewyjście

xargspobierzargumentyzstdin

mkfifotworzy łącze nazwa (specjalny plik który może być wykorzystywany do komunikacji międzyprocesaminazasadziepodobnejdo|)

seq

Page 146: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

wypisujekolejneliczby(przydanenp.wfor)tee

zapisujestdindopodanegopliku,równocześniewypisującgonastdoutfile

rozpoznajetypplikuiconv

konwersjekodowańplikówtekstowychkonwert

konwersjekodowańplikówtekstowych–zarównopomiędzyróżnymikodowaniamidanegozbioruznaków, jak też pomiędzy kodowaniami nie pokrywającymi się czy też kodowaniami znaków 8bitowychnamniejszejilościbitów,naprzykład:konwertutf8-ascii"inteligentnie"usunieznakinieasciizplikukodowanegowutf-8(np.znaczkizpolskimiogonkamizamieninaodpowiednieznakiASCIIbeztychogonków);konwertqp-8bitpozwolizamienićkodowaniequotedprintablenanormalne8bitowe(rtf-8bitzrobitozkodowaniemrtf'u)

mewencode/mewdecodeprogram(stanowiącyczęśćpakieunarzędzidodatkowychdlakilentapocztowegoMew)doobsługikodowańmime(wtymQuoted-Printable,base64),m.in.zmieniakodowaniebase64na8bitowe

qprintprogramdokodowaniaidekodowania"Quoted-Printable"

base64programdokodowaniaidekodowaniabase64

stringswypisujesekwencjeznakówdrukowanych(określaniezawartościplikównietekstowych)

whichkomendazwracawykonywanąścieżkę/polecenieprzywykonywaniukomenda

datedataiczas,programtenpotrafitakżeprzeliczaćdatęiczas-np.date-d@847103830'+%Y-%m-%d %H:%M:%S', date -d '1996-11-04 11:37:10' '+%s', date -d '1996-11-04 11:37:10 +3week-2days'

calkalendarz

calcalboapcalczaawansowany kalkulator o składni podobnej do C umożliwiający wykonywanie mi.in. operacjilogicznych(wtymbinarnych)

bckalkulator(wartorozważyćutworzeniealiasualias'bc'='bc<(echoscale=3)'(abyzarazpostarciemieć3miejscapoprzecinku)lubalias'bc'='bc-l'(dlapełniejszejprecyzji)

numconvprogramdokonwersjisystemówliczbowychopróczsystemówpozycyjnychoróżnychpodstawachobsługujetakżeinnesystemyliczbowe-np.rzymski

gnuplotrysowaniewykresów

clearczyściterminal

resetprzywracaustawieniaterminala(np.gdypowyświetleniuplikubinarnegosądziwnekrzaczki)

sttykonfiguruje terminal (np. port szeregowy /dev/tyyS* , późniejmożemykorzystać z niegonp. zapomocącat,echo, ... iprzekierowańpotoków-np.cat/dev/ttyS0>~/serial.logbędzielogowałoinformacjezportudowskazanegopliku)

startxuruchamiaśrodowiskograficzne

xinituruchamia program w środowisku graficznym (wraz z startem środowiska), np. xinit -e__WYBRANY_PROGRAM__--:1uruchomiX'ynaekranie1(dawniejAlt+Ctrl+F8,obecnienaogółnabieżącymterminalu)awnichwskazanyprogram

xsetkonfigurowanie ekranu x-serwera, np. sleep 1; xset dpms force off spowoduje wyłączenie(uśpienie)monitora

Page 147: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

Standardoweusługi

Systemy operacyjne zapewniają także szereg usług. Znaczna część z nich dostępna jest z poziomubibliotekistandardowejC(np.obsługaplików,komunikacjisieciowej,zamianynazwdomenowychoraznazwusługnaadresynumeryczne).Inneznichrealizowanesąpoprzezdedykowaneprocesydziałającew tle (bez bezpośredniej interakcji z użytkownikiem), tzw. daemon-y. Poniżej omówione zostałyniektórezusługzapewnianychprzezsystemoperacyjny.

Zamiananazwnaadresynumeryczne

BibliotekastandardowazapewniamożliwośćzamianynazwhostównaichnumeryIP,zamianynazwusługnanumeryportów.Funkcjonalnośćtakorzystazm.in.następującychplikówkonfiguracyjnych:/etc/services-mapowanienazwyusługinanumerportu/etc/hosts-mapowanienazwhostównanumeryIP(lokalnabaza)/etc/resolv.conf-adresyserwerówDNSdoktórychmogąbyćkierowanezapytaniaoadresyhostów

Pocztaelektroniczna

Typowo system zapewnia obsługę (co najmniej lokalnego) dostarczania poczty elektronicznej. Dowysyłania listów można skorzystać z komend mail lub sendmail. Z kolei komenda sendEmail pozwalatakżenawysyłaniepocztyprzezwskazanyserwerSMTP.

Planowaniezadań

Typowosystemzapewniausługęuruchamianiazadańozadanymczasie.Zusługitejmożnaskorzystaćprzypomocypoleceń:crontabpozwalaoglądaćiedytowaćtablicezaplanowanychzadańcyklicznych(dlacron'a)atpozwalajednorazowozaplanowaćzadanie

Plikikonfiguracyjnecrona/obsługiwanecrontab-emmająpostać:minutygodzinadzienMiesiacamiesiacdzienTygodniapolecenie.Wpisoznaczażepoleceniemazostaćwykonanejeżeliwszystkiewarunkibędąspełnione, jeżeli jakiś warunek nie jest nam potrzebny można użyć gwiazdki *, z kolei */n oznaczawykonywaniejeżelidanawartośćjestpodzielnaprzezn.Np.:*/203**1lsoznaczawykonaniekomendylswkażdyponiedziałekogodzinie3:003:20i3:40

Standardowewyjście,wyjściebłęduorazpowiadomienieoniezerowymkodziepowrotudomyślniesąwysyłane na lokalny adres mailowy użytkownika będącego właścicielem danego contaba. Niekiedydostępnyjesttakżeanacronpozwalającynamniejprecyzyjneplanowaniezadań

Zdalnydostęp-SSH

SerwerSSHzapewniazdalny,szyfrowanydostępdokomputeranaktórymjesturuchomionyzinnychhostów.UsługaSSHpozwalanakopiowanieplików(sftp,scp,rsyncoverssh),montowaniezdalnychsystemówplików(sshfs),tunelowanieprotokołuX'ów(serweraśrodowiskagraficznego,dziękiczemumożna używać zdalnych aplikacji z GUI) oraz tworzenie szyfrowanych tuneli (nasłuchujących napołączeniaprzychodzącetakpostronieklientassh,serwerassh,jakteżpełnychtuneliVPN).

PodsumowanieWkontaktachztechnologią,byciudobrym"komputerowcem",elektronikiem,...najważniejszewydajesiębyć bawienie się technologią, eksperymentowanie, łączenie i integrowanie różnych systemów itechnologii,poznawanienowego,zagłębianiesięwszczegółyabynietylkowiedzieć jaktoobsłużyć,aleteż wiedzieć jak działa, traktowanie problemów jako wyzwań, ... oraz czerpanie z tego radości. Dookreślenia kogoś o takiej postawie, takim podejściu do techniki, najlepszym terminem byłby haker,pomimoiżjesttoterminróżnierozumiany,uwieluosóbwywołującynegatywneskojarzenia,wydajesięonjednaknajbliższytakiejpostawieżyciowej.

Zajmowanie się technologią (a szczególnie z takimnastawieniem)oznacza taknaprawdęciągłeuczeniesię-jeżelisięnierozwijasz,jeżelizostajeszwmiejscutotaknaprawdęsięcofasz.Zatemjużodsamegopoczątku poznawania świata elektroniki, programowania, komputerów, sieci komputerowych, itp., przynauce tych dziedzin bardzo istotne (jeżeli nie najistotniejsze) wydaje się bawienie się tym, otwartepodejściedostawianychproblemów,eksperymentowanieisamodzielneszukanierozwiązań.

Niemawiększegosensuuczeniasięszczegółów,konkretnychimplementacji,itpnazapas.Jeżelimożemysobie tylko na to pozwolić warto uczyć się na "żywych" zastosowaniach (rozwiązując problemy, któregdzieś w jakiś sposób samoistnie się pojawiły), przy takiej nauce warto też pamiętać o ogromnychzasobachInternetu.Przypoznawaniuobsługibądźkonfiguracjijakiegośnowegonarzędziarównieistotnejak zapoznanie się z dokumentacją, podręcznikiem jest wypróbowanie różnorakich opcji, ich różnychkombinacji w praktyce, poszukanie takiego sposobu konfiguracji, użytkowania (takiego stylu) jaki jestnajbardziejodpowiednidlanasidlarozwiązywanegoproblemu.Wrozwiązywaniukonkretnychzagadnieńnajistotniejszejestwiedziećjaksiędotegozabraćiumiećdaćsobieradę.

Wydajesiężewłaśniewtychdziedzinachczęstoodwiedzyszczegółowej,ważniejszajestszerokawiedzaogólna(orazoczywiścieodpowiedniepredyspozycjeichęci),wrazzumiejętnościamiszukaniainformacji(i

Page 148: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

wiedzągdzienależy jej szukać).Częstoniemanawetmożliwościposiadaniapełnejwiedzynapoczątkurozwiązywania jakiegoś problemu, istotniejsza jest ogólne zrozumienie "jak to działa", umiejętnośćkorzystania z dokumentacji, wyszukiwania i sprawdzania szczegółów oraz umiejętność kombinowania /informatyczny spryt. Ważna jest także sporą doza praktyki (rzeczywistość tworzy sytuacje które nieśniłyby się teoretykowi ...) i tak zwane obycie z techniką / technologią. Gdy napotka się jakiś problemnależy próbować go rozwiązać, eksperymentować, szukać porady (ale raczej na zasadzie "że chcemydostaćwędkęanierybę")inieżałowaćnatoczasu.

InformacjacyfrowaPodstawowym zadaniem chyba wszystkich systemów komputerowych i telekomunikacyjnych orazogromnej większości systemów elektronicznych jest przetwarzanie lub przekazywanie informacji.Obecnie jest to w znacznej większości informacja cyfrowa (w odróżnieniu od analogowej jest ona"skwantowana" - sygnałbędący jej źródłemzmieniającysięwsposóbciągłyzostałpoddanyprocesowipomiaruizamianynaliczbęoskończonejdokładności).Faktdyskretyzacjizbioruwartościoraz(możliwedo wprowadzenia dzięki postaci liczbowej) sumy kontrolne umożliwiają wierne kopiowanie informacji.Dziękiwprowadzeniutegododatkowegomatematycznegopoziomuwzapisieinformacjiodrywamysiępoczęści od ograniczeń naszej fizycznej rzeczywistości; "bity to nie atomy" i fizyka (w szczególnościkwantowa)ichniedotyczy.

Podstawową jednostką informacji jest bit, mogący przyjmować dwa rozróżnialne stany nazywanezazwyczajzero ijeden,będącyodpowiedziątyputak/nie.Przypomocymniejszejilościstanówniejestmożliweprzekazanieinformacji(pozorniemogłobywydawaćsiężeniekiedywystarczyjedenstan-np.podnosimynrazychorągiewkęiwtensposóbprzekazujemyliczbęn,jednaktutajteżjestukrytydrugistan - chorągiewka opuszczona). Z stanami tymi łatwo związać odpowiednie stany napięciowe nawejściach/wyjściachukładówelektronicznych-np.napięciepowyżejXvoltów("jestnapięcie")oznacza1,napięcie poniżej Y voltów ("brak napięcia") oznacza 0. Wydaje się że właśnie z tych dwóch powodówsystemdwójkowy (mający tylko dwie cyfry - 0 i 1) wraz z logikądwuwartościową zyskał tak dużezastosowaniewelektronicecyfrowejikomputerach.

ElektronikaElektronika (zarówno analogowa jak i cyfrowa) zajmuje się zasadniczo przetwarzaniem informacji wpostaci sygnałów elektrycznych. Podstawowymi pojęciami jest tutaj prąd (przepływ ładunku) oraznapięcie(różnicapotencjałówczylisiłatenprzepływwymuszająca).Elementyelektronicznepodzielićmożemynaelementybierne(oporniki,kondensatory,cewki,diody) -wpływającenaprzepływprąduwsposób nieregulowany oraz elementy aktywne (których działanie w odróżnieniu od biernych jestregulowane na drodze sygnałów elektrycznych). W elektronice (zwłaszcza cyfrowej) często dużoważniejszym pojęciem niż prąd jest napięcie, a dokładniej nawet tylko potencjał w odniesieniu doumownegopotencjałuzerowego-masy(GND).

Dlaprzetwarzaniadanychprzezwspółczesnąelektronikęnajważniejszymzpodstawowychjejelementówwydajesiębyćtranzystor-jesttoelementoregulowanympoprzezprzyłożenieodpowiedniegonapięciaoporze elektrycznym (może być zatem wykorzystywany jako elektronicznie sterowany przełącznik).Obecnie większość tranzystorów wchodzących w skład urządzeń znajduje się we wnętrzach układówscalonych,liczącychczęstotysiąceczynawetmilionytranzystorów.

Podstawowymidlatechnikicyfrowejukładamiscalonymisąbramkilogicznerealizująceposzczególnefunkcjelogicznenaprzetwarzanychsygnałachorazrejestrypozwalającenazapamiętaniestanu(jakiejśinformacji).Jednaktakżeibramkiustąpiłyjużmiejscaukładomprogramowalnymzłożonymztysięcytranzystorów, bramek i tym podobnych elementów - np. programowalnym układom logicznym,procesoromczyteżmikrokontrolerom(zawierającymtakżepamięćzmienną-dladanychprogramuorazpamięć do przechowywania samego programu); sprowadzając w zasadzie elektronikę opartą naelementachdyskretnychdorolipomocniczej.

Właśnieniczymmniejaniwięcejtylkotakimprogramowalnymurządzeniemelektronicznym,ozdolnoścido przetwarzania znacznych ilości informacji (w postaci liczb) w krótkim czasie (znacznej mocyobliczeniowej),jestwspółczesnykomputer.Złożonyonjestzasadniczozprocesora,pamięcioperacyjnej(wrazzukłademodpowiedzialnymzaumożliwieniedostępudoniejprocesorowi-kontrolerempamięci)ipamięcistałej (dysktwardy itp.)służącejdoprzechowywaniaprogramówidanych.Niezależnieodrolijakąpełni(maszynadopisaniaczygrania,serwerWWWczyteżserwernadzorującyprocesywreaktorzejądrowym,...)każdykomputertylkoiwyłączniewykonujejakiśprogram.

Poprzez powyższe twierdzenie, że komputer wykonuje tylko i wyłącznie program będący ciągieminstrukcji, nie twierdzę że nie może istnieć coś takiego jak sztuczna inteligencja, a nawet sztucznaświadomość. Obecnie istnieją systemy zdolne do samodzielnej nauki na podstawie historycznychdoświadczeń,istniejąsystemydecyzyjneorazwieleinnychrozwiązańktórewjakimśstopniumożnabyuważaćzainteligentne.Zproblememsztucznejinteligencjizwiązanajestgłównienieprecyzyjnośćtegoterminu (istnienie wielu sprzecznych definicji). Wydaje się, że nawet człowiek nie jest w stanieprzekonaćinnejosobyotymżejestistotąinteligentnąatymbardziejświadomągdytamtaprzyjmieinnezałożenie.

Page 149: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

B

C

E

T1

AK

D1R3

2k

+5V

R2

1k

1 2S1

R1

25k

U1

1 2C1

100uF

R4

1k

P1

+5V

W rozumieniu elektroniki ważna jestumiejętność przeanalizowania prostegoukładu, ustalenia / zrozumienia jak ondziała.Dla przykładu: obok przedstawiony jestukład wykorzystujący zarówno elementycyfrowe, jak i analogowe do uzyskaniajakiegośefektu.Jakijestceldziałaniategoukładu?Jakondziaławszczegółach?

1. U1 jest dwu wejściową bramkąlogiczną AND (na wyjściu zwraca stan logiczny 1 gdy na obu wejściach ma stan logiczny 1,któremuwtymwypadkuodpowiadastanwysoki+5V),do jednegozwejśćpodłączony jest jakiśsygnałsterującyzzewnątrz(P1)dodrugiegopodłączonyjestnatomiastprzełącznikS1zwierającydomasy.

2. RezystorR1podłączonydo+5Vzapewniaiżgdyprzełącznikniejestzwartytodowejściabramkiprzyłożony jest stan wysoki (niektóre z układów scalonych mają takie rozwiązaniezaimplementowanewewnętrznie),agdyzwieramyS1toograniczapłynącyprąd-wtensposóbnawejściebramkimożebyćpodanelogiczne1lubzerobezkoniecznościstosowaniaprzełączaniaibezobawyozrobieniezwarcia.

3. Wyjście bramki poprzez kolejny opornik (R2), który ograniczaprądpobierany zwyjściaukładu,steruje tranzystorem NPN T1 (przewodzi on gdy napięcie miedzy bramką (B) a emiterem (E)przekroczyokreślonąwartość).

4. Wprowadzenie tranzystora w stan przewodzenia powoduje przepływ prądu przez LED D1 orazrezystorR3,któryograniczatenprąddowartościodpowiedniejdlaD1(oczywiścietakżeT1musibyćdostosowanydowartościtegoprądu);wartotutakżezwrócićuwagęnapolaryzacjęD1(LEDjakkażdadiodaprzewodzitylkowjednąstronę).

5. Kondensator C1 wraz z rezystorem R4 (a także R3) powoduje spowolnione wygaszanie D1 -kondensatorrozładowujesięprzezR4gdyT1przewodzi,natomiastpozaprzestaniuprzewodzeniaprzez T1 kondensator ten ładuje się przez R3 i R4 podtrzymując przez pewien czas świeceniediody(diodaprzygasapowoli,gdyżspadananiejnapięciewskutekprocesuładowaniaC1).

ProgramowanieProgram jest to ciąg instrukcji (głównie operacji matematycznych i logicznych), zapisany w językuzrozumiałymdladanegoprocesora(kodmaszynowypowstającywwynikukompilacjikodustworzonegow języku wyższego poziomu). Wśród tych instrukcji szczególne miejsce zajmują instrukcje skoków(warunkowych i bezwarunkowych), one właśnie umożliwiają warunkową realizację fragmentówprogramu oraz warunkowe powtarzanie (iterację) fragmentów programu. Za szczególny przypadekinstrukcji skoku można uważać instrukcję wywołania procedury, powodującą przekazanie stosownychinformacji i rozpoczęcie wykonywania podprogramu (poprzez warunkowe wywoływanie tej samejprocedury z jej wnętrza możemy otrzymać "konkurencyjny" do iteracji sposób powtarzania fragmentuprogramu-rekurencję.

Podstawądziałaniakażdegoprogramujestjakiśalgorytm, jesttopojęcietrochębardziejabstrakcyjneniż program (zwłaszcza rozumiany jako kod maszynowy) - ogólnie mówiąc jest to skończony ciągczynności prowadzących do zrealizowania jakiegoś zadania. Jak już wspomniałem oprócz kodumaszynowego (złożonego z numerów rozkazów i ich parametrów) są również języki programowania.Najbardziej podstawowym jest asembler, który pozwala używać łatwiej zrozumiałych dla człowiekanazw zamiast numerów instrukcji, rejestrów (w których procesor przechowuje wartości którymioperuje), ... . Jednak jego instrukcje odpowiadają niemalże w 100% instrukcjom procesora (kodowimaszynowemu), dlatego też jest bardzo silnie zależny od danej architektury sprzętowej (modeluprocesora), powoduje to problemy z przenoszeniem programów pisanych w asemblerze na innearchitektury, to było jednym z powodów stworzenia językówwyższego poziomu. W językach takichtreść algorytmu wyraża się przy pomocy poleceń danego języka będących bytami bardziejabstrakcyjnymiodinstrukcjiprocesora(np.pojęciezmiennejioperowanienaniejanienamiejscachwpamięci irejestrach).Obecnieasembleraużywasięwzastosowaniachwymagającychdużejwydajności(zarówno w oddzielnych aplikacjach jak i fragmentach większych programów) bądź dla urządzeń oniewielkichrozmiarachpamięci.

TelekomunikacjaOpróczprzetwarzaniainformacjilicznesystemyzajmująsięjejprzekazywaniem.Abymógłzajśćproceskomunikacji musi istnieć jakieś medium transmisyjne, które będzie odpowiedzialne za fizyczneprzekazaniesygnałuzawierającegoinformację.Wtelekomunikacjiprzekaztenodbywasięzazwyczajzwykorzystaniem zjawiska przepływu prądu przez przewodnik (tradycyjna łączność kablowa), bądźrozchodzenia się fali elektromagnetycznej (łączność radiowa, światłowody, ...). Bardzo istotne jestdopasowanieparametrówmediumtransmisyjnego,urządzeńnadawczychiodbiorczychdosygnałuktóryzamierzamy transmitować, na przykład w przypadku kabli jest to częstotliwość którą są one w stanie

Page 150: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

przenosićbezzakłóceń(głównieonaodpowiadazaszybkośćtransmisji inajczęściej jestrzędukilkusetMHz) oraz impedancja (wyrażana w omach, sygnały które transmitujemy są sygnałami zmiennymidlategojestonaważnymparametremprzewodu...).Jednakpomimotozawszenależymiećświadomość,żetotylkokabel,któryprzewodzielektronyiniezależnieodparametrówjakośbędzietorobił....

Wtradycyjnychsystemachtelekomunikacyjnychsygnałbyłbezpośrednioinformacją,ajegodotarciedoodbiornika oznaczało że informacja jest przeznaczona dla niego (telefonia) bądź dla każdego (radio,telewizja - systemy rozgłoszeniowe). Obecnie coraz większą rolę odgrywają komutowane siecipakietowe, gdzie informacja nie jest tak ściśle związana z sygnałem. Dla przykładu w telefoniizrealizowanie każdego połączenia wymagało zestawienia go - odpowiedniego przełączenia styków wcentralach(komutacjiłączy);wInternecieinformacjapodążaćmożeróżnymidrogami(niejesttworzonadroga specjalnie dla danego połączenia) i na podstawie adresu odnaleźć host docelowy (jest tokomutacjapakietów).Wsieciachpakietowychwłaściwainformacja(jeżeli jestzbytdługa)dzielonajestna części, do każdej części dodawane są informacje kontrolne - nagłówek (zawierający m.in. adresodbiorcy). Tak utworzone pakiety podróżują niezależnie od siebie przez sieć do odbiorcy (bezzestawianiawtymceluspecjalnegofizycznegopołączenia).

Bardzoistotnymelementemjestadresacja(jestonaniezbędnaabyinformacjamogłabyćkierowanadokonkretnegohosta-inaczejmamysiećrozgłoszeniowa(np.telewizja)):każdyhostwsiecimusiposiadaćunikalny (w ramach tej sieci) adres (chyba zawsze o ustalonej długości - nie jestem w staniezagwarantować ze ktoś, gdzieś nie stworzył protokołu pakietowego z adresami zmiennej długości),częstowydzielasię równieżpodsieci,posiadająoneswójadres (naogół jest towspólnaczęśćadresuwszystkich hostów podsieci dopełniona zerami), adres określający ile adresów jest w podsieci () orazadresnaktóryreagowaćpowinienkażdyhostwtejpodsieci(adresrozgłoszeniowy).Wprzypadkuchybanajpopularniejszychobecniesieci IPwielośćpodsieci określana jestprzezmaskępodsieci, którapowykonaniu binarnego AND z dowolnym adresem hosta tej sieci da adres sieci. W związku z tym iżbinarnie maska składa się z nieprzerwanego ciągu jedynek oraz nieprzerwanego ciągu zer, jest onaczęstozapisywana jestwpostaciprefixowej, czyli liczbybitówmającychwartość jeden.Wsieciach IP(oprócz samego Internet Protocol - odpowiedzialnego za adresację itp) należy także wspomnieć oprotokołachtakichjak:ICMP-zapewniającymprzesyłkomunikatówtechnicznych,orazUDPczyTCP-umożliwiających przesył danych poprzez sieć IP (odpowiedzialne one są m.in. za adresację usług nadanymhościepoprzeznumeryportów,TCP czuwa takżenadpoprawnością transferu - kontroluje czydanedotarły i czydotarłynieuszkodzone).Protokół IPoprócznajbardziejdlaniego typowej transmisjijeden do jednego (unicast) umożliwia transmisję rozgłoszeniową (broadcast - jeden do wszystkich wsieci)imulticast(jedendowielu).

OczywiściesieciteleinformatycznetonietylkoIP-należykonieczniewspomniećoprotokołachwarstwwyższych - takich jakHTTP (siećWeb),SMTP (e-mail), ... - zapewniających realizację typowychusługsieciowychorazstandardachzwiązanychzkonkretnąrealizacjąsprzętowąsieci -np.ethernet (będącynajpopularniejszym standardem sieci lokalnych - LAN). Ze sprzętową realizacją sieci wiąże się m.in.pojęcietakiejaktopologiasieci-czylizasadałączeniahostów(gwiazda-wszystkiedojednegopunktu,drzewo - wiele gwiazd łączonych w gwiazdy, magistrala - od jednej linii każdy host, ...).Najpopularniejsząobecnietopologią(przekładającąsiętakżenainneinstalacje-np.elektryczną,gdziejednak dalej istotna jest magistrala) jest topologia gwiazdy, gdzie mamy doczynienia z punktamidystrybucyjnymi(wprofesjonalnympodejściurealizowanymiwoparciuoszafykrosowniczeispecjalnieprzeznaczonedotegocelupomieszczenia)odktórychodchodzątrasykablowe.Przyrealizacjisystemówtelekomunikacyjnych (i innych teleinformatycznych oraz elektrycznych) warto pamiętać o stosownejdokumentacjitakprzebiegutraskablowych,jakisamejinstalacjiorazpunktówdystrybucyjnychatakżeprzejrzystości i opisaniu samych instalacji. Warto tutaj także zwrócić uwagę na "nie informatyczne"bezpieczeństwo takich instalacji obejmujące takie zagadnienia jak zabezpieczenia przeciw pożarowe,przeciw przepięciowe oraz monitoring i kontrolę dostępu do pomieszczeń przeznaczonych nawspomnianeinstalacje.

OprogramowanieOczywiścieabysięzajmować,bawićkomputerami,elektroniką,sieciamitelekomunikacyjnymikoniecznajestwiedzanatematsamejobsługikomputerów-zwłaszczasystemówunix'owatych.Wtychsystemachposzczególne osoby pracują na własnych kontach (identyfikowanych loginem i chronionych hasłem),szczególnym przypadkiem jest konto super użytkownika "root" - służy ono do czynnościadministracyjnych i umożliwia zrobienie z systemem (niemalże) wszystkiego. Standardowo stosowanyjest też znany z adresów e-mail zapis z małpą - umożliwiający globalną identyfikację użytkownika [email protected]. Z użytkownikami związane są także uprawnienia - definiowane (w podstawowymwariancie) niezależnie dla właściciela, grupy i wszystkich innych w dziedzinach odczytu, zapisu iwykonania.

Powłoka tekstowaoparta jestnapoleceniach (będącychnajczęściejosobnymiprogramami)doktórychprzekazywane są opcje i argumenty (oddzielane są one - zarówno od siebie jak i od nazwy programuspacjami), opcje na ogół zaczynają się od myślnika (jednoliterowe) bądź dwóch myślników(wieloliterowe), ale są od tego wyjątki. Powłoka umożliwia także pracę w trybie wsadowym (nieinteraktywnym)-jesttojużjęzykskryptowysh/bash.Informacjeoprawiekażdymprogramie,większości

Page 151: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

plików konfiguracyjnych oraz funkcjach biblioteki standardowej C można znaleźć w podręcznikusystemowym(polecenieman).

EpilogWspółczesna technika umożliwia korzystanie z komputera, a nawet tworzenie oprogramowania bezznajomości niskopoziomowych mechanizmów działania tych urządzeń. Wydaje się jednak, że abyzrozumieć współczesną technikę, być dobrym programistą, administratorem, ... poznanie tychmechanizmówwydaje się niezbędne (a na pewno jest bardzo pomocne) i jest też niewątpliwiebardzoprzydatnegdychcemyzrobićcoś"bliżejsprzętu"....

Przyrobieniuczegokolwiekwartopamiętaćostandardachinormachtechnicznych,onenaprawdęsą(wzdecydowanejwiększości) tworzonepo toabyułatwićwszystkimżycie (jakbywyglądał Internetgdybykażdyportalużywałwłasnychstandardówe-mailiwww?).Należyteżtaktworzyć,abytocozrobiliśmy,napisaliśmybyłoprzejrzysteizrozumiałedlainnychoraz(zaparęmiesięcyczylat)dlanassamych-abykod był czytelny, dobrze skomentowany, a cały projekt posiadał dobrą i szczegółowądokumentację(wiem że często się nie chce, ale naprawdę warto ...). Należy się także wystrzegać rozwiązańprzekombinowanych, stanowiących przerost formy nad treścią (trzymać się reguły KISS). Należypamiętać,żezanimzaczniemycośpisaćwartoposzukaćczyniemaczegośopodobnejfunkcji,bądźniemajakiśbibliotek,którezrobiązanaspołowępracy-niezawszewartoodkrywaćAmerykęnanowo;-).

Wszystkich czytelników zachęcam także do zapoznania się oprócz samego "vademecum" także zdolinkowanymimateriałamiorazprzedewszystkimdodużejporcjiobyciaztechnologią,samodzielnegozgłębiania wybranych zagadnień oraz dużej ilościpraktyki - bo to właśnie ona w tym wszystkim jestnajistotniejsza(atoniestetywymagadużoczasu).Ważnejestabyrobićtocosięlubi-zawszelepiejbyćdobrymsieciowcemzpowołanianiżkiepskimkoderem(inaodwrót).Dokładnykierunekkształcenianiejest bardzo istotny - lepiej żeby nie był zbyt odległy, ale i tak masy rzeczy trzeba się uczyć samemu.Wartomiećszerszespojrzenienabranże-tożespecjalizujeszsięnp.wsieciachnieoznaczaiżpodstawyprogramowania (zarówno web-owego jak i systemowego) czy też elektroniki i innych pokrewnychzagadnieńsązbędne -wręczprzeciwniemogąbyćdodatkowymatutem(nie tylkowCVale iwsamejpracy).ToczegosięnauczyszjestTwoje,alezdobytąwiedzę,doświadczeniewartonotować(gdyżzdarzasię ponownie odkrywać Amerykę i ze zdziwieniem stwierdzać "to ja się tym zajmowałem 10 lattemu???").

Literaturazakres

tematyczny nazwa autor licencja opis link

Elektronika

Elektronika LessonsInElectricCircuits

TonyR.Kuphaldt

DesignScienceLicense

Rozbudowanypodręcznikdoelektronikiodpodstaw EN

Elektronika Electronics wikibooks.org CC-SA Podręcznikdoelektroniki EN

Podstawyelektroniki

ElectronicsFundamentals wikibooks.org CC-SA Podręcznikpodstawelektroniki EN

Podstawyelektroniki PracticalElectronics wikibooks.org CC-SA

Przewodnikrozumieniaitworzeniaobwodówelektronicznych

EN

Podstawyelektroniki CircuitIdea wikibooks.org CC-SA Zbiórwyjaśnieńzasaddziałania

popularnychobwodów EN

Teoriaobwodów CircuitTheory wikibooks.org CC-SA Podręcznikdoteoriiobwodów EN

Teoriaobwodów Metodyanalizyobwodówliniowych

WojciechMeller CC-NC-SA Podręcznikdoteoriiobwodów PL

Elektronikaanalogowa AnalogueElectronics wikibooks.org CC-SA Podręcznikelektroniki

analogowej EN

Elektronikacyfrowa DigitalCircuits wikibooks.org CC-SA Podręcznikdoelektroniki

cyfrowej EN

Page 152: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

Systemymikroprocesorowe MicroprocessorDesign wikibooks.org CC-SA Podręcznikprojektowania

systemówmikroprocesorowe EN

Systemymikroprocesorowe EmbeddedSystems wikibooks.org CC-SA Podręcznikdosystemów

wbudowanych EN

Automatyka ControlSystems wikibooks.org CC-SA Podręcznikdosystemówkontroliisterowania EN

Telekomunikacja CommunicationSystems wikibooks.org CC-SA Podręcznikdosystemówtelekomunikacyjnych EN

Podstawyinformatyki

Systemyoperacyjne PisanieOS Jarosław

Pelczariinni

CC-SA,oryginał:PD

Podręcznikprzybliżającyzagadnieniazwiązanezdziałaniemitworzeniemsystemówoperacyjnych

PL

Sterownikiurządzeń

LinuxDeviceDrivers,ThirdEdition

JonathanCorbet,AlessandroRubini,GregKroah-Hartman

CC-NC-SA

PodręcznikopisującyzagadnieniazwiązaneztworzeniemsterownikówurządzeńdlasystemuLinux

EN

Algorytmyistrukturydanych Algorithms wikibooks.org CC-SA Wprowadzeniedoalgorytmów EN

Algorytmyistrukturydanych DataStructures wikibooks.org CC-SA Wprowadzeniedostruktur

danych EN

Algorytmyistrukturydanych

AlgorithmImplementation wikibooks.org CC-SA Przykładyimplementacji

algorytmów EN

Językiprogramowania

C CProgramming wikibooks.org CC-SA PodręcznikprogramowaniawC EN

C ALittleCPrimer wikibooks.org CC-SA PodręcznikprogramowaniawC EN

C++ C++reference CC-SA PodręcznikreferencyjnydlaCiC++ EN

C++ C++Programming wikibooks.org CC-SA PodręcznikprogramowaniawC++ EN

CiC++ProgrammingLanguageConceptsUsingCandC++

wikibooks.org CC-SA Podręcznikwprowadzającydoprogramowania EN

Python ByteofPython/UkąśPythona SwaroopCH

CC-SA,przykłady:BSD

PodręcznikprogramowaniawPythonie

ENPL

Python DiveintoPython/ZanurkujwPythonie MarkPilgrim GNUFDL Podręcznikprogramowaniaw

PythonieENPL

PythonHowtoThinkLikeaComputerScientist:LearningwithPython

PeterWentworth,JeffreyElkner,AllenB.Downey,ChrisMeyers

GNUFDL PodręcznikprogramowaniawPythonie

ENEN

Page 153: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

Python Non-Programmer'sTutorialforPython3

wikibooks.org CC-SA KursprogramowaniawPythonie

EN

PHP PHPProgramming wikibooks.org CC-SA PodręcznikprogramowaniawPHP EN

Bash AdvancedBash-ScriptingGuide

MendelCooper PD Podręczniktworzeniaskryptów

wbashu EN

AWK GAWK:EffectiveAWKProgramming

ArnoldD.Robbins GNUFDL PodręcznikdlajęzykaAWKw

odmianieGNU EN

AWK OpisjęzykaAWK T.Przechlewski

CC-BY-SAtype

WprowadzeniedoprogramowaniawAWK PL

AWK AWKReferenceCard/ŚciągadoAWK

ArnoldD.Robbins

CC-BY-SAtype

KartareferencyjnadlajęzykaAWK

ENPL

AWK AnAwkPrimer wikibooks.org CC-SA PodręcznikdlajęzykaAWK EN

JavaScript ProgrammingAjax wikibooks.org CC-SA PodręczniktechnologiiAjax EN

językiopisusprzętu ProgrammableLogic wikibooks.org CC-SA Podręcznikprogramowania

układówlogicznych EN

językiopisusprzętu VHDLforFPGADesign wikibooks.org CC-SA Podręcznikprogramowania

układówFPGAwVHDL EN

językiopisusprzętu

VHDLquickreferencecard

QualisDesignCorporation

CC-ND-SAtype KartareferencyjnaVHDL EN

Siecikomputerowe

TCP/IPLinuxNetworkAdministrator'sGuide,2ndEdition

OlafKirch,TerryDawson GNUFDL

PodręcznikopisującyzagadnieniazwiązanezsieciamiTCP/IPwsystemieLinux

ENPL

TCP/IPLinuxNetworkAdministrator'sGuide,3ndEdition

OlafKirch,TerryDawson CC-NC-SA

PodręcznikopisującyzagadnieniazwiązanezsieciamiTCP/IPwsystemieLinux

EN

TCP/IPComputernetworktechnologiesandservices

LorenzoDavid,LucaGhio

CC_SA

PodręcznikopisującyzagadnieniazwiązanezsieciamikomputerowymiTCP/IPiusługamisieciowymi

ENEN

TCP/IP Routingprotocolsandarchitectures LucaGhio CC_SA

Podręcznikopisującyzagadnieniazwiązanezroutingiemwsieciachkomputerowych

ENEN

Ethernet(LAN) LocalAreaNetworkdesign LucaGhio CC_SA

Podręcznikopisującyzagadnieniazwiązanezlokalnymisieciamikomputerowymi

ENEN

Telekomunikacja CommunicationNetworks wikibooks.org CC-SA

Podręczniksiecikomunikacyjnych(nietylkokomputerowychaletakżeradiowych,telewizyjnych,itp)

EN

Linux/BSD/Posix

PoleceniasystemówtypuPosix

UnixToolboxColinBarschel CC-SA

ZbiórużytecznychpoleceńsystemówUnix/Linux/BSD EN

Page 154: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

Vim Ściągadovi T.Przechlewski

CC-SAtype

Kartareferencyjnadlaedytoravim PL

Vim Ściągadovi LaurentGrégoire GNUGPL Kartareferencyjnadlaedytora

vim EN

Debian DebianReference OsamuAoki GNUGPL PodręcznikDebiana EN

DebianTheDebianAdministrator'sHandbook

RaphaëlHertzog,RolandMas

CC-SA/GNUGPL

PodręcznikadministratoraDebiana EN

Debian DebianGNU/LinuxReferenceCard

W.MartinBorgert,HolgerWansing

GNUGPL KartareferencyjnadlaDebianGNU/Linux

ENPL

FreeBSD FreeBSDHandbook BSD-type PodręcznikdlasystemuFreeBSD

ENPL

Arch ArchLinuxWiki GNUFDL DokumentacjadlaArchLinux EN

PLDLinux Podręcznikużytkownika,administratoraitwórcy GNUFDL PodręcznikdlaPLDLinux

Distribution PL

Linux LinuxNetworking wikibooks.org CC-SA PodręczniksieciwśrodowiskuLinux EN

Językizapytańioznaczeń

SQL StructuredQueryLanguage wikibooks.org CC-SA Podręcznikdojęzykazapytań

bazdanychSQL EN

wyrażeniaregularne RegularExpressions wikibooks.org CC-SA Podręcznikwyrażeń

regularnych EN

XML XMLSchema wikibooks.org CC-SA PodręcznikSchcemyXML EN

LaTeX

TheNotSoShortIntroductiontoLaTeX/NiezakrótkiewprowadzeniedosystemuLaTeX

TobiasOetiker,HubertPartl,IreneHyna,ElisabethSchlegl

GNUGPL PodręcznikwprowadzającydosystemuskładutekstuLaTeX

ENPL

LaTeX LaTeX wikibooks.org CC-SA PodręcznikwprowadzającydosystemuskładutekstuLaTeX EN

Inne,ogólne,wielotematyczne

aparaturaprzemysłowa

LessonsInIndustrialInstrumentation

TonyR.Kuphaldt

DesignScienceLicense

Rozbudowanypodręcznikdoaparaturyprzemysłowejodpodstaw

EN

Wikipedia CC-SA Otwarta,wolna,wielojęzycznaencyklopedia

ENPL

opcode.eu.org RobertPaciorek

BSD/MIT-type

Serwisinternetowypoświęconyróżnymzagadnieniomzelektroniki,programowania,sieciiinstalacjibudynkowych

PL

Page 155: Vademecum informatyki praktycznejvip.opcode.eu.org/vademecum.pdfVademecum informatyki praktycznej (aktualizacja: 2021-06-08) W założeniu ma to być kompleksowy przegląd podstawowych

Licencja

Copyright(c)2003-2020,RobertRyszardPaciorek<[email protected]>

Tojestwolnyiotwartydokument/oprogramowanie.Redystrybucja,użytkowaniei/lubmodyfikacjaSĄDOZWOLONEnawarunkachlicencjiMIT.

Thisisfreeandopendocument/software.Redistribution,useand/ormodifyAREPERMITTEDunderthetermsoftheMITlicense.

TheMITLicense:

Permissionisherebygranted,freeofcharge,toanypersonobtainingacopyofthissoftwareandassociateddocumentationfiles(the"Software"),todealintheSoftwarewithoutrestriction,includingwithoutlimitationtherightstouse,copy,modify,merge,publish,distribute,sublicense,and/orsellcopiesoftheSoftware,andtopermitpersonstowhomtheSoftwareisfurnishedtodoso,subjecttothefollowingconditions:

TheabovecopyrightnoticeandthispermissionnoticeshallbeincludedinallcopiesorsubstantialportionsoftheSoftware.

THESOFTWAREISPROVIDED"ASIS",WITHOUTWARRANTYOFANYKIND,EXPRESSORIMPLIED,INCLUDINGBUTNOTLIMITEDTOTHEWARRANTIESOFMERCHANTABILITY,FITNESSFORAPARTICULARPURPOSEANDNONINFRINGEMENT.INNOEVENTSHALLTHEAUTHORSORCOPYRIGHTHOLDERSBELIABLEFORANYCLAIM,DAMAGESOROTHERLIABILITY,WHETHERINANACTIONOFCONTRACT,TORTOROTHERWISE,ARISINGFROM,OUTOFORINCONNECTIONWITHTHESOFTWAREORTHEUSEOROTHERDEALINGSINTHESOFTWARE.