DoubleBuffer

Programerska zajednica
It is currently Mon Apr 23, 2018 10:14 pm

Board index » Resursi za učenje » Za potpune početnike!

All times are UTC + 1 hour




Post new topic Reply to topic  [ 8 posts ] 
Author Message
PostPosted: Tue Feb 16, 2010 11:21 am 
Offline
Romulanski špijun na Zemlji
User avatar

Joined: Fri Sep 05, 2008 12:35 pm
Posts: 1583
Location: Njemacka
Kako uopce radi CPU? (prvi dio)


Mislim da se prije ikakvog objasnjavanja kako programirati treba prvo objasniti kako CPU radi, barem ono osnovno, da se vidi zasto se uopce upravo tako programira i kako se doslo do tih programskih jezika. Za pocetak da naglasim da ovdje necu pisat o nikakvoj konkretnoj arhitekturi nego cu sve generalizirati i pojednostaviti da se cim lakse svati kako radi CPU i kako se i zasto se tako programira. Sve sto pise u ovoj temi "Kako uopce radi CPU?" mozete preskociti ako je prenaporno i nije uopce potrebno znati da bi mogli programirati igre, ali definitivno pomaze u razumijevanju racunala i laksem svacanju samog programiranja.

Mozda malo cudan pocetak no krenimo od samog programa (nekog zamisljenog) koji se upravo izvrsuje u CPU. Zamislimo ga kao jednu veliku pokretnu traku sa paketima poredanim jedan za drugim i sa jednim covjekom koji radi na toj traci ali sa izuzetkom da se ne mice sama traka nego covjek, po redu od paketa do paketa dok se program ne ugasi. Svaki paket se sastoji od dva dijela, podatka (neki broj) i naputka sta sa tim podatkom radit i takoder svaki mjesto na kojem je paket ima svoj redni broj ili adresu. Taj covjek pokraj sebe ima jos i policu sa dva mjesta u koju moze staviti podatak iz paketa a na toj polici i kalkulator sa kojim moze racunati sa podacima iz paketa na polici i na traci. Znaci traka sa paketima + polica sa dva mjesta i kalkulatorom. Covjekova uloga je da uzme paket ispred sebe te procita naputak/instrukciju sta sa podatkom i izvrsi ga.

Recimo da se na traci nalazi program koji broj/podatak sa prve police mnozi sa 3 tako dugo dok ne postane veci od 50. Covjek uzima prvi paket koji kaze da broj iz prve police pomnozi sa tri, nakon sto to izvrsi pomocu digitrona broj u polici je 3 puta veci. Covjek prelazi na iduci paket u redu na kojem pise da oduzme broj iz prve police sa 50 i spremi rezultat u drugu policu. U trecem paketu pise: ako je broj iz druge police veci od 0 neka se vrati na prvi paket. Ako pozornije pogledate, nas covjek ce biti u petlji -> hodat izmedu ta tri paketa tako dugo dok broj u prvoj polici ne bude veci od 50. Tako se u biti program racunala u svom najosnovnijem obliku sastoji samo od niza instrukcija sa podacima (a nekad i bez podataka) koje se izvrsavaju jedna za drugom.

Da pojasnim sad malo konkretnije, CPU se sastoji od tri glavna dijela, upravljacke jedinice, ALU ili aritmeticko-logicka jedinica i registara. U onoj prici gore upravljacku jedinicu predstavlja covjek, ona je ta koja "prepoznaje" instrukciju i upravlja ostatkom CPU-a, odnosno nareduje ALU sto racunati, salje podatke izmedu registara i ALU-a i sl. sta vec zahtjeva instrukcija koju dobije. ALU je onaj digitron i on obavlja aritmeticka i logicka racunanja u CPU-u. A registre predstavljaju one police u koje se stavlja podatak, znaci vrsta memorije, tocnije najbrza i najvaznija u racunalu jer se iz nje salju podaci u ALU i u nju vracaju rezultati iz ALU-a, koji se onda dalje salju u cache CPU-a ili radnu memoriju i obratno. No nisu samo za to, imaju i druge specificne namjene u CPU-u ali da ne kompliciram nepotrebno. Jedan registar najcesce moze pamtit onoliko bita koliko je bitan sam CPU-u, znaci ako je procesor 64bitan onda su mu i registri veliki 64bit odnosno 8 bajta. Intelovi i AMD-ovi procesori u stolnim racunalima su bazirani oko x86 arhitekture i imaju 10-20 standardnih registara plus jos neke za FPU, MMX i SSE instrukcije. Radnu memoriju predstavlja ona traka koja sadrzava pakete.

Svaki procesor ima neki fiksan broj instrukcija koje njegova upravljacka jedinica moze prepoznati i izvrsiti. Samom procesoru to su brojevi dok im mi dajemo imena da ih lakse upamtimo, pa recimo da je npr. broj 1 jedan za mnozenje izmedu registra A i B, i kad mi napisemo MUL A, B to je u samom programu zapisano kao broj 1. Ta imena instrukcija cine jedan programerski jezik kojeg zovemo assembler i on omogucuje "najnize" programiranje, tj. direktnu kontrolu nad CPU-om. Ako neki procesori imaju iste instrukcije pod istim brojevima i jednake registre onda se kaze da su kompatibilni i da pripadaju istoj porodici/arhitekturi i mogu izvrsavati jednake programe, kao sto naprimjer Pentiumi i Athloni pripadaju x86 arhitekturi.


Last edited by Danijel Korent on Tue Feb 16, 2010 9:57 pm, edited 5 times in total.

Top
 Profile  
 
 Post subject: Re: Uvod u programiranje
PostPosted: Tue Feb 16, 2010 11:21 am 
Offline
Romulanski špijun na Zemlji
User avatar

Joined: Fri Sep 05, 2008 12:35 pm
Posts: 1583
Location: Njemacka
Kako uopce radi CPU? (drugi dio)


Kao sto sam rekao ona spomenuta imena instrukcija cine jedan programerski jezik kojeg zovemo assembler i on omogucuje "najnize" programiranje, tj. direktnu kontrolu nad CPU-om. Da ponovo napomenem, poznavanje i razumjevanje ovog sta ste procitali i sta ce te sad procitati nije presudno za razvoj igara jer se vec dugo tako ne radi, ali ce vam pomoc u razumjevanju samog koncepta programiranja i zasto se to tako radi. Pa napisimo onaj nas program u assemblerskom jeziku. Kao prvo moramo definirati instrukcije koje cemo koristiti i koje registre imamo, pa krenimo redom, imamo registar A i B i instrukcije: MUL registar, podatak; SUB registar1, registar2, podatak; JP registar, adresa. Da pojasnim:

MUL registar, podatak - mnozi broj iz registra i podatak, te sprema rezulatat u registar
SUB registar1, registar2, podatak - uzima vrijednost iz registra2, uduzme ga sa podatkom i sprema rezultat u registar1
JP registar, adresa - ako registar sadrzi pozitivan broj skoci na adresu "adresa"

Registar, registar1/2 u ovom moje zamisljenom CPU-u mogu biti bilo koji registar, brojevi su tu samo da se u objasnjenju naredbe zna koji je koji.

Evo kako ce izgledati onaj nas program (onaj koji broj/podatak sa prvog registra mnozi sa 3 tako dugo dok ne postane veci od 50):

01. MUL A, 3
02. SUB B, A, 50
03. JP B, 1
04. ....

Pa secirajmo malo ovaj kod gore. Kao prvo, ovi redni brojevi predstavljaju adresu na kojoj se nalazi instrukcija u memoriji procesora (cacheu). Pa recimo da se prije izvadanja ovog programa u registru A nalazi broj 5 a u registru B se nalazi 0

Znaci:

A = 10
B = 0


i instrukcija koja je na redu:
01. MUL A, 3

-ova instrukcija mnozi sadrzaj A registra sa brojem 3, i rezulatat je snima nazad u registar A, preko stare vrijednosti, sada ovako izgleda situacija:
A = 30
B = 0


sljedeca instrukcija:
02. SUB B, A, 50


-ova instrukcija uzima vrijednost iz registra A umanjuje za 50 i rezultat sprema u registar B. Registar A ostaje nepromjenjeni:
A = 30
B = -20


sljedeca instrukcija:
03. JP B, 1

- instrukcija provjerava da li je vrijednost u registru B pozitivna, buduci da nije CPU se vraca na adresu broj 1
A = 30
B = -20


sljedeca instrukcija: (ona je opet 01. jer se CPU vratio na tu adresu kod prosle instrukcije)
01. MUL A, 3

A = 90
B = -20


sljedeca instrukcija:
02. SUB B, A, 50

A = 90
B = 40


sljedeca instrukcija:
03. JP B, 1
- buduci da je sad registar B pozitivan, CPU ne skace opet na addresu jedan nego nastavlja na sljedecu instrukciju:

04. ...

Kao sto se vidi program radi ono za sto je predviden, mnozi broj iz registra A sa 3 tako dugo dok ne bude veci od 50. Naravno da bi svo ovo puko racunanje imalo smisla postoje instrukcije koje citaju vrijednosti sa nekog ulaza (tipkovnice, misa, ...) i instrukcije koje salje vrijednosti tj. rezulatate izracuna u neki izlaz (graficku karticu, zvucna, printer, ...). CPU sa svih ulaza samo dobiva brojke, na sve ulaze salje samo brojke, i sve sto izmedu ulaza i izlaza radi je racuna i usporeduje te brojke, za bilo koju igru, program, OS, BIOS, ... sve sto on radi je barata sa brojkama, nista vise ni manje. Bilo sto vi radili na racunalu, makar i pomak misa, pritisak gumba, u konacnici se svodi na jednu veliku bezlicnu hrpu racunanja i usporedivanja brojeva kod koje se nemoguce normalno snaci. I kad bi rekli nekom developerskom timu da napravi (modernu) igru u ovom gore prikazanom asemblerskom jeziku, prvo bi poprimili cudne boje, pa pocupali kosu sa sebe i napravili kolektivno samoubojstvo.

Zato su napravljeni tzv. "visi" jezici koji tim bezlicnim nizovima instrukcija daju "ljudska" imena i priblizavaju jeziku kojeg lakse mozemo svatiti i prepoznati. O tim visim jezicima u iducim postovima.


Last edited by Danijel Korent on Fri Feb 19, 2010 12:03 am, edited 4 times in total.

Top
 Profile  
 
 Post subject: Re: Uvod u programiranje
PostPosted: Tue Feb 16, 2010 11:23 am 
Offline
Romulanski špijun na Zemlji
User avatar

Joined: Fri Sep 05, 2008 12:35 pm
Posts: 1583
Location: Njemacka
Visi programski jezici (uvod)


Da bi se olaksalo programiranje, prvenstveno ubrzalo i da bi kod bio citljviji i razumljiviji, uveli su se neki citljiviji izrazi koji "zamjenjuju" niz instrukcija odnosno niz strojnog koda. Tako se, kao sto sam napisao u proslom postu, programski jezici priblizavaju ljudskom jeziku, odnosno onom kojeg mozemo puno lakse razumjeti pa i time puno lakse i prije svatiti neki kod. To naravno nije bez svoje cijene, takvi programi se najcesce izvadaju sporije, uzimaju vise radne memorije i vise mjesta na HDD-u nego oni napisani u assembleru jer nisu toliko optimizirani. No to si u danasnje vrijeme mozemo dopustiti jer su procesori postali iznimno mocni i imamo dostupne ogromne kolicine radne memorije. No kad vidim kakve su se sve igre vrtile na komodorcu od 1 MHz i 64kb radne memorije ne mogu pobjec od osjecaja da smo se mozda i malo previse opustili.

Naravno kad napisemo program u takvom jeziku treba nesto sto ce te citljivije izraze pretvoriti nazad u strojni kod. Postoje dvije vrste programa za to, compileri i interpreteri. Oboje pretvaraju kod napisan u programskom jeziku u strojni kod sa razlikom da interpreter odma pokrene program te pretvara vas kod u "hodu", kako program radi, dok sa compilerom trebate pocekati da sav kod pretvori u strojni i zapise u neku izvrsnu datoteku, pa tek onda mozete program pokrenuti u obliku gotove datoteke. Dobra strana compilera je sto se program brze izvrsava naravno ta da dobijete gotovu izvrsnu datoteku vaseg programa koju mozete dalje distribuirati. Ali je problem sto kod svake promjene u kodu morate pocekati da se sav kod compilira u strojni, pa tek onda mozete provjeriti jel ta promjene dobro radi, sto moze bit frustrirajuce ako promjenite samo jedan red i morate provjeriti dal je ok napravljeno. Kod interpretera nemate te muke jer se program odma pokrece bez ikakvog cekanja ali je opet problem sto nemate izvrsnu datoteku koju mozete dalje snimati i djeliti, a i program se sporije izvada.

Ima jos jedan nacin, koji u odredenom stupnju smanjuje problem compilera ukoliko je projekt podjeljen na vise datoteka sa kodom. A to je da svaku dototeku sa kodom odvojeno compilira i snima strojni kod u posebnu datoteku koje se onda povezuju u izvrsnu datoteku, pomocu programa koji se obicno zove linker. Kada se promjeni neki dio koda u jednoj datoteci projekta dovoljno je samo tu datoteku kompilirati i onda u linkeru povezati sa ostatkom projekta koji je nepromjenjen.

Takoder neki compileri ne pretvaraju vas kod u pravi hardware-ski strojni kod nego u kod od neke od tzv. virtualnih masina, pomocu kojih se onda i pokrece taj compilirani kod (da napomenem, to nisu isti programi kao one virtualne masine koje omogucuju pokretenje vise OS-a na jednom racunalu) . Da bi objasnio cemu uopce te virtualne masine moram pokazati na jos jedan nedostatak compilera. Kad se neki kod compilira u izvrsnu datoteku postoje dva ogranicenja kod pokretanja te datoteke, na nivou hardware-a i na nivou OS-a.

Na nivou hardware-a zbog razlicitih arhitektura CPU-a (spomenutih u postu "Kako uopce radi CPU? (prvi dio)" ). Kao sto sam bio rekao svaka arhitektura ima razlicite instrukcije i pod razlicitim brojevima, pa bi isti strojni kod(koji je u biti hrpa brojeva) na dvije razlicite arhitekture pokretao potpuno razlicite instrukcije u CPU-u. Dok bi na ciljanoj arhitekturi pokretao tocno one instukcije koje i treba izvodit, te bi se pravilno izvodio, na bilo kojoj drugoj arhitekturi instrukcije bi se izvodile naizgled nasumicno i "bezveze" sto bi dovelo do neizbjeznog rusenja programa. Ovo je razlog zasto Macintoshi nakon prelaska na intelove x86 procesore odjednom mogu pokretati Windowse i zasto novi Macintoshi moraju preko emulatora pokretati stare programe napravljene za Macintosh sa PowerPC arhitekturom.

Na nivou OS-a zbog razlicitih OS API-a i razlicitih file header-a izvrsnih datoteka na razlicitim OS-ovima. Da pojasnim file header ili po nasem zaglavlje datoteke, je kao kratki "uvod" u datoteku koji se nalazi na nekom predefiniranom mjestu (obicno na samom pocetku datoteke) i koji sadrzi sve bitne i potrebne (i predefinirane) informacije za onog tko pokrece tu datoteku. Tako naprimjer header neke video datoteke najcesce sadrzi informacije kao sto su rezolucija filma, frame rate, duzina trajnja, koju vrstu video konpresije koristi, koju vrstu audio kompresije koristi, koliko video/audio kanala ima i sl. Bez tih vaznih informacija, software-u koji "otvara" tu datoteku ce imati jako velikih problema sa reproduciranjem njenog sadrzaja. Ako pokusate sa nekim programom pokrenuti/otvoriti datoteku koja nije namjenjena za reproduciranje na tom programu, pocet ce citat podatke na predefiniranoj adresi za header, i obicno odma na pocetku headera ima oznaka, zvani i "magicni broj", po kojem provjerava da li je pravilan header, na primjer kod .exe datoteka MZ ili kod .BMP datoteka BM. U nasem slucaju ce javit gresku, a ako i dodamo tamo taj magican kod, kod daljeg citanja headera ce dobiti nasumicne podatke i opet javiti gresku.

A API (Application programming interface) je najjednostavnije receno kao neki telefonski imenik sa popisom funkcionalnosti koje mozete pozvati i upotrijebiti iz nekog OS-a, DLL-a, servisa i sl (U iducem nastavku ove tebe ce biti to puno jasnije). Buduci da razliciti OS-evi imaju razliciti taj "imenik" sa razlicitim pozivima, funkcionalnostima i nacinima zvanja opet ne moze biti isti kod ni ista datoteka. Zbog svih tih problema, za svaku arhitekturu i za skoro svaki OS koji se na njoj pokrece potreban je posebni kompiler koji kompilira kod upravo za tu kombinaciju + drugciji sam programski kod za svaki OS. Buduci da su kod gamera x86 i Windows skoro potpuno dominantni to nije velik problem, ali za onog tko zeli raditi multi-platformska rjesenja bome je, ali i to se GNU projektima dosta olaksalo, no kasnije o tome, vratimo se sad tim virualnim masinama.

Sve te probleme rijesava virtualnih masina, kod kojih se upotrebljava jedan compiler, isti programski kod i ista izvrsna datoteka za bilo koju arhitekturu i bilo koji OS. To je postignuto tako da se programski kod prvo pretvara u "univerzalni" kod/jezik te virtualne masine, a onda dalje na programu virtulne masine zadatak da pravilno izvrsi taj kod na platformi na kojoj je pokrenuta, da ga pretvori u kompatibilni kod za upravo tu platformu. Tako da gdje se moze instalirati ta virtualna masina tog programskog jezika mose se i pokrenuti kod za njega, bez ikakvog modificiranja i sl, barem u teoriji. Ali naravno i ovaj pristup ima lose strane, a to je brzina izvadanja. Program se sprorije izvada nego na ostalim rjesenjima jer u hodu pretvara VM kod u strojni kod i pa tek onda izvrsava taj dobiveni strojni kod. Negdje je to vise izrazeno a negdje manje...


Last edited by Danijel Korent on Wed Feb 17, 2010 12:08 am, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: Uvod u programiranje
PostPosted: Tue Feb 16, 2010 11:34 am 
Offline
Romulanski špijun na Zemlji
User avatar

Joined: Fri Sep 05, 2008 12:35 pm
Posts: 1583
Location: Njemacka
Visi programski jezici (1. Varijable i racunanje pomocu njih)


Buduci da sam dovoljno pisao o teoriji u proslom postu ovdje cu odma skocit na praksu, pa evo opet onaj nas programcic iz posta "Kako uopce radi CPU? (drugi dio)" napisan u assembleru i taj isti napisan u nekom visem programskom jeziku:

Asm:

01. MUL A, 3
02. SUB B, A, 50
03. JP B, 1


i neki visi jezik:

Code:
while A < 50 do:
    (
    A = A * 3
    )


Naravno ocito je koji kod se lakse cita i prije skuzi odnosno razumije. Dok se kod asm-a treba "analizirati" kod programa da bi svatili sto radi, kod viseg programskog jezika dovoljan je jedan pogled na kod programa da bi ga svatili, odnosno da mnozi A sa 3 tako dugo dok je A manji od 50.

Kao sto vidimo, za razliku od assemblera ovdje se koriste jasne rijeci iz engleskog jezika (koje nisu tocno odredena instrukcija nego imaju vise "opcenito" znacenje - koje compiler pretvori u niz instrukcija ), te se koriste jasni "matematicki" pojmovi. Pod navodnicima jer matematicki ova formula gore nema smisla, ali u programskim jezicima to ima malo drugcije znacenje. Kod programskih jezika slova u formulama poput x, y (ili slovo A u nasem gornjem primjeru) ne predstavljaju nepoznanicu nego neku odredenu memorijsku lokaciju u koju se moze zapisati neki podatak. U CPU te su adrese numericke ali tko bi popamtio hrpu bezlicih brojeva, pa je dana mogucnost da se tim mem. adresama dade ime, kao npr. "Bodovi" ili ovo nase "A" u kodu - ta imena zovemo varijable. Takoder ovo jednako ne znaci da lijeva i desna strana trebaju biti jednake. U vecini jezika na desnoj strani se racuna neki izraz i rezultat tog izraza se zapisuje u memorijsku lokaciju, tj. varijablu, koja se nalazi na lijevoj strani. Sve sto vidite u igri, broj bodova, broj zivota, ime lika, x i y pozicija cudovista, sve su te informacije spremljena u varijablama i racunaju se pomocu tih varijabla. Pa evo nekoliko primjera:

A = 30
-> u memorijsku lokaciju koja se krije po imenom "A" zapisuje se broj 30

B = 20 + 5
-> zbrajaju se broj 20 i 5, te se rezultat zapisuje u varijablu "B"

Bodovi = A + 10
-> vrijednost koja se nalazi u varijabli "A" (znaci broj 30) se zbraja sa brojem 10. Dobivena vrijednost, 40, se zapisuje u varijablu "Bodovi" (btw varijablama na desnoj strani ostaju iste vrijednosti, znaci A je i dalje 30)

A = A * 3

-> vrijednost koja se nalazi u varijabli "A" (30) se mnozi sa 3. Dobivena vrijednost se zapisuje u varijablu "A" koja sada sadrzi vrijednost 90. (stara vrijednost varijable "A" je "izbrisana", nova vrijednost se jednostavno nasnima preko stare)

A = 3 * (A + 10)
-> bas kao i u matematici i ovdje postoji neki redoslijed racunanja, pa se varijable prvo mnoze a tek onda zbrajaju. Kada bi ovu formulu gore napisali ovako: 3 * A + 2 , prvo bi se 3 i A mnozili pa se rezultatu dodao 2. Ako prvo zelimo zbrojiti A i 2 pa tek onda mnoziti, stavimo ih u zagradu. Sadrzj u zagradi se prvi racuna pa tek onda mnozi sa 3. Ako nam je vrijednost varijable A broj 90, onda cemo dobiti rezultat 300. Ukoliko nebi bilo zagrade rezultat bi bio 280


I assembler moze imati takve varijble ali je razlika u tome sto se u asemblerskom jeziku moze baratati samo sa cijelim i realnim brojevima (ako platforma podrzava) ogranicenim sa velicinom registra. Da bi radili s nekim kompliciranijim tipovima podataka ili brojevima vecim od velicine registra morate si sami napisati kod za to. Kod visih programskih jezika varijable mogu sadrzavati i razne druge podatke, kao npr. niz slova, niz brojeva, cijele strukture podataka koje se sastoje od proizvoljnog broja varijabala pa i tipove podataka koje sami napravimo. Da bi compiler dodjelio varijabli neku memorijsku lokaciju i da bi znao koju vrstu podatka treba primat, tocnije da zna pravilno obraditi podatak kod racunanja, prije uporabe treba deklarirat varijable. Prvo da nabrojim neke osnovne tipove podataka koje su implementirane u vecini jezika i primjeri:

Integer
-> cijeli broj npr. 1, -2, 3 -> A = 2

Real

-> realni broj 1.5, 3.14, -0.1-> A = 1.5

Bool
-> za logicke operacije i kontrolu u petljama, ima dvije vrijednosti - True i False, odnosno istina ili neistina. Tko se nije susreo sa booleanovom algebrom bilo bi dobro da ju malo skicne (nije nista komplicirano) -> A = True

Char
-> neki znak (obicno iz ASCII tablice), npr. neko slovo -> A = "g"

String
-> niz znakova, pomocu njega se obicno zapisuju neka imena i recenice koje se ispisuju na monitor -> A = "Paladin"


Ima jos nekih koji su u gotovo svim jezicima ali o njima kasnije. Nastavimo sa deklariranjem, to u biti nije nista komplicirano, samo se napise varijabla i pokraj nje vrsta varijable, ili obratno. Koliko sam primjetio najcesci nacin izgleda otprilike ovako:

Integer A
-> u program se dodaje nova varijabla "A", compiler joj automatski dodjeljuje neku memorijsku lokaciju i rijec Integer mu govori za koju vrstu podatka je namjenjena ova varijabla.

Cesti su i ovakvi slucajevi:

Integer A, Broj, Bodovi
-> da se nebi moralo za svaku varijablu stavljati u poseban red i stalno iznova pisati vrsta podatka kojeg prima moze se ovako odjednom deklarirati vise varijabla (ako su naravno isti tip)

Integer A = 0
-> kod deklariranja varijable moze se odma i dodjeliti joj neki podatak. To je cest slucaj jer u nekim prog. jezicima deklarirana varijabla moze imati neku random pocetnu vrijednost (o tome kasnije)

Kod ostalih nenumerickih tipova podataka cesto su takoder moguca zbrajanja i sl. operacije, npr:

String Ime, Rijec - #deklariraju se string varijable Ime i Rijec

Ime = "Salian" - #varijabli ime se dodjeljuje niz znakova "Salian"

String Lik = "Paladin: " - #deklarira se string varijabla Lik i odma joj se dodjeljuje vrijednost


Rijec = Lik + Ime
- #ovdje se vrijednosti, tj. nizovi znakova iz varijabla Lik i Ime spajaju u jedan niz znakova (koji cu nadalje zvati samo string) i zapisuje u varijablu rijec
- nakon ove operacije varijabla Rijec sadrzi ovu vrijednost: "Paladin: Salian"


Top
 Profile  
 
 Post subject: Re: Uvod u programiranje
PostPosted: Tue Feb 16, 2010 11:42 am 
Offline
Romulanski špijun na Zemlji
User avatar

Joined: Fri Sep 05, 2008 12:35 pm
Posts: 1583
Location: Njemacka
Visi programski jezici (2. procedura, funkcija, library)


Procedura ili funkcija je najjednostavnije receno niz koda/naredba kojima je dano neko ime i moze se pozivati pomocu tog imena. Prvo ih treba definirati, najcesce tako da se napise njihovo ime nakon cega slijedi kod koje to ime predstavlja. Sam kod se na razlicite nacine "ograduje" da se zna gdje je pocetak i kraj koda koji se izvrsava u toj proceduri ili funkciji. Naprimjer u Pascalu sa BEGIN i END, u C/C++ sa vitlicastim zagradama {} a u Pythonu sa indentom, uvlacenjem retka - to ce te najlakse svatiti u primjerima. Nakon definiranja ta procedura se moze upotrijebiti, odnosno pozvati, prilikom cega se izvrsava onaj definirani kod. Procedura se poziva tako da se napise njeno ime.

Primjer_1: - primjeri su pisani u Pythonu

Code:
def Procedura(): # komanda za definiranje procedure i ime procedure (i zagrada koja mora biti, zasto vidjet cete u iducem primjeru)
    print "pozvana procedura"
    a = 5
    b = 3
    c = a + b
    print c
 
 
print "Pocetak programa:"
Procedura() # poziva se gore definirana procedura koja izvrsava onaj gore definirani kod
Procedura()
Procedura()


Izlaz koji vraca:
Code:
pozvana procedura
8
pozvana procedura
8
pozvana procedura
8



Takoder procedure ili funkcije mozu primati argumente. Argumenti su podaci/varijable koje ubacujemo u funkciju/proceduru te koje onda funkcija moze koristiti u svom kodu koji izvodi. U vecini slucajeva argumenti se definiraju u zagradi pokraj imena kao varijable koje onda mozete koristiti u toj proceduri. Kod pozivanja te procedure takoder je zagrada u koju pisemo vrijednosti koje zelimo dati proceduri kao argumente. Evo opet primjer:

Primjer_2:

Code:
def Suma(a, b): # definira se procedura Suma koja moze primiti dva argumenta, ta dva argumenta su definirana u zagradi
    c = a + b
    print c
 
 
print "Pocetak programa:"
Suma(5,4) #  zove se procedura i salju joj se dva argumenta, u nasem slucaju 5 ce biti doddjeljen varijabli a, 4 varijabli b
 
Broj = 4
Suma(2, Broj) # jos jedan poziv -> a = 2 i b = 4


Izlaz:
Code:
9
6



A koja je onda razlika izmedu funkcije i procedure? E ta da funkcija i vraca neku vrijednost, te se ta vrijednost moze koristiti umjesto nekog broja ili varijable, npr. unutar matematickih izraza i sl. mjestima gdje pisemo brojeve ili varijable.

Primjer_3:
Code:
def Umnozak(a, b):
    c = a * b
    return c  #a moze se i jednostavno stavit return a * b
 
 
print "Pocetak programa:"
 
Broj = Umnozak(3,2)
print Broj
 
print Umnozak(Broj,3)
 
print Umnozak( 3, Umnozak(2,2) )


Izlaz:
Code:
6
18
12



Oni library-i za laksu izradu igara koje sam spominjao su u biti hrpa vec napisanih takvih procedura i funkcija koje odraduju neki posao, npr. crtanje slike na ekran, i koje vi mozete pozivati u svom kodu bez da morate znati ili razumjeti kakvi kod izvode prilikom pozivanja.

Ovo gore primjeri se mogu ovdje skinuti i pokrenuti ako imate instaliran Python:

LINK

*Buduci da se program zatvori odma nakon izvrsavanja najbolje da se ubaci u onu shell skriptu (autor Byteslipper :D ) koja pauzira prozor nakon izvrsenja programa.


Last edited by Danijel Korent on Tue Feb 16, 2010 11:36 pm, edited 4 times in total.

Top
 Profile  
 
 Post subject: Re: Uvod u programiranje
PostPosted: Tue Feb 16, 2010 11:43 am 
Offline
Romulanski špijun na Zemlji
User avatar

Joined: Fri Sep 05, 2008 12:35 pm
Posts: 1583
Location: Njemacka
Visi programski jezici (3a. kontrola toka programa)


Mislio sam odma krenuti sa onim: prelja je ovo ono, pa grananje, itd.. ali bi netko netko sigurno pomislio, wtf? zasto to uopce treba, sta ce mi to? .. pa sam odlucio prvo malo razraditi problem kako napraviti neki interaktivni program sa funkcijama/procedurama i varijablama sa kojim raspolazemo, pa da vidimo za cime ce nam se sve ukazati potreba.

Kao prvo, evo popis funkcija sa kojima raspolazemo:

get_input()
- vraca broj tipke koja je pritisnuta

flip_buffer()

- crta sadrzaj igre na monitor - trenutno potpuno nebitno sto i kako.


Sto nam je cilj u programu i kako to postici?
Pa ako nam je cilj igra ili da ovdje pojednostavimo, program poput onoga sa micanjem kocke po ekranu sa tipkama na ovom pdf-u (koji se vrlo lako da pretvoriti u igru), znaci da:

1. trebamo redoviti citati sa ulaza (tipkovnica, mis)
- redovito? znaci dovoljno cesto da korisnik ne treba cekati da se nesto dogodi nakon sto pritisne tipku, cim cesce se provjerava tim brze reagira program - znaci po nasim svako malo u toku rada programa treba pozvati get_input()

2. kad dobimo neki input od get_input() naredbe (nesto je pritisnuto) trebamo provjeriti to sto dobimo i napraviti da ovisno o tome sto smo dobili (lilti koja je tipka pritisnuta) mijenjamo koordinate/poziciju kocke - znaci ako je pritisnuta tipka lijevo x- koordinata kocke se mora smanjiti za neki broj tj. da se nacrta vise lijevo - ilit za korisnika koji gleda u program da se kocka pomakne u lijevo

3.
trebamo redovito crtati na ekran, cim se cesce crta - animacija izgleda tecnije, odnosno igra ima veci FPS ( frames per second). Znaci opet svako malo treba pozvati flip_buffer()

Kako to postici? To nam omogucuju naredbe za kontrolu toka programa - razne petlje, grananja i sl.




IF grananje:

Idemo se prvo baviti brojem 2. Rjesenje ovog problema je naredba IF. Narebi if se dodaje neki uvjet i neki kod. Ako je uvjet tocan kod se izvrsi, ako uvjet nije tocan kod se ne izvrsi, i to je to, vrlo jednostavna stvar. Evo kako to izgleda:

C++:

Code:
if (uvjet)
{
neki_kod;
neki_kod;
}



Python:


Code:
if uvjet:
    neki_kod
    neki_kod


U uvjetu se obicno medusobno usporeduju varijable, konstante i rezultati funkcija, npr: (broj < 10), (slovo == "a"), (x > y), ( (a + 5) < zbroj(5,4) ) - u uvjetu mogu biti sve matematicke i logicke operacije ali rezultat uvijek mora biti True or False, istinito ili neistinito. BTW u jednom primjeru se nalazi '==', ono sluzi sa usporedivanje, a '=' sluzi za dodjeljivanje.


if (broj < 10): neki_kod
- ako je vrijednost varijable broj manja od 10 kod se izvrsava, ako nije kod se ne izvrsava i program nastavlja dalje sa kodom poslije if naredbe i njenog koda.

evo popis najcesce koristenih uvjeta:

== jednako
!= nejednako
> veće
< manje
>= veće ili jednako
<= manje ili jednako




A sad konkretno na nas problem. Funkcija get_input() vraca broj tipke koja je pritisnuta, recimo po ASCII tablici. I u stvarnim API-ima se najcesce vraca broj. Kako sad to? Tamo se uvijek pise nesto tipa if key = K_ESC. Da, da vi nebi morali pamtiti brojeve iza kojih se krije odredena tipka, obicno se u library-ima definiraju konstante za svaku tipku koje sadrze broj te tipke.

Recimo da je za pritisnutu tipku esc vraca broj 27, da nebi trebali pisati:

if get_input() == 27: napravi_nesto
- ovdje ne mozete na prvi pogled svatiti o cemu se radi

library negdje definira ovu konstantu: const K_ESC = 27, pa onda vi mozete pisati ovako

if get_input() == K_ESC: napravi_nesto
- ovdje se odma vidi o cemu se radi


Natrag na nas primjer, znaci kod bi izgledao ovako

if get_input() == K_LEFT: X = X - 10
if get_input() == K_RIGHT: X = X + 10

Eto prilicno jednostavno, ako je pritisnuta lijeva tipka X se smanjuje za 10, a ako je pritisnuta desna X se povecava za 10. Varijabla X recimo predstavlja poziciju nekog objekta na ekranu.


Kod IF naredbe mozete upotrijebiti i ELSE sa kojim se definira koji kod da se izvrsi ako uvijet nije istinit. Takoder kod Pythona postoji i ELIF kojim mozete definitari vise uvjeta u istoj IF "grani", npr:

C++:

Code:
if (get_input() == K_LEFT)
    {
    X = X - 10;
    }
   
else
    {
    neki_kod;
    //izvrsi kod ukoliko uvjet (get_input() == K_LEFT) nije istinit
    }



Python:
Code:
if get_input() == K_LEFT: X = X - 10
       
elif get_input() == K_RIGHT: X = X + 10
       
else: neki_kod  #izvrsi neki_kod ukoliko uvjeti (get_input() == K_LEFT) i (get_input() == K_RIGHT) nisu istiniti





While petlja:
A sada idemo sa problemima 1. i 2. koji su prakticki isti. Trebamo redovito pozivati odredene naredbe i tu ce nam pomoci jedna petlja. Sto je "petlja" u programiranju? U osnovi to je blok koda (niz naredbi) koji se ponavlja stalno iznova: cim se niz naredbi izvrsi, CPU "otide" na pocetak niza i opet ispocetka ponavlja taj niz narebi i tako u krug. Obicno je "vrtenje" u pelji uvjetovano neki uvjetom koji mora biti ispunjeni da se ili petlja nastavi vrtjeti ili da se izade iz petlje.

Mi cemo upotrijebiti While naredbu. Ta naredba nam omogucava da izvrsavamo jedan te isti kod tako dugo dok je neki uvjet/izraz istinit, odnosno da se kod vrti u petlji. Uz while naredbu se naravno pise i kod i uvjet koji odreduje da li ce se kod izvrsavati ili ne. Evo kako to izgleda sa generalnim primjerom i konkretnim:

C++:

Code:
while (uvjet)
{
neki_kod;
}


Code:
while (X < 10)
    {
    A = A + 1;
    Ovca = Ovca * 2;
    }



Python:
Code:
while uvjet:
     neki kod



Code:
while X < 10:
    A = A + 1
    Ovca = Ovca * 2



Primjer sa nasim problemom 1. i 3. napisan u Pythonu:

Code:
glavna_petlja = True #deklarira se varijabla kojom cemo uvjetovati dal ce se petlja "vrtjeti" ili ne
 
while glavna_petlja == True:    # provjerava uvjet ako je istinit izvrsava kod ako nije nastavlja dalje kao da kod ne postoji
    input = get_input()         # cita ulaz u sprema u varijablu za provjeravanje
 
    if input == K_LEFT: kod     #izvrasava neki kod, mijenja stanje igre i sl.
    elif input == K_ESC: glavna_petlja = False
    else: neki_kod              #ako nije ni jedan uvjet istinit mozda treba nesto  napisati, nacrtati...
 
    flip_buffer()               # crta stanje na ekran i program se vraca na while naredbu


Nakon ovoga dovoljno znate Python da potpuno razumijete ovaj kod:
[Python + PyGame]PRVI KORAK- crtanje i micanje slike po ekranu

I dovoljno znate C++ da okvirno razumijete ovaj kod:
[C/C++ + SDL] PRVI KORAK - crtanje i micanje slike po ekranu
(bez znanja pointera i jos nekih sitnica jednostavno ga ne ne mozete potpuno razumjeti)


Last edited by Danijel Korent on Wed Feb 17, 2010 12:09 am, edited 3 times in total.

Top
 Profile  
 
 Post subject: Re: Uvod u programiranje
PostPosted: Tue Feb 16, 2010 11:43 am 
Offline
Romulanski špijun na Zemlji
User avatar

Joined: Fri Sep 05, 2008 12:35 pm
Posts: 1583
Location: Njemacka
Visi programski jezici (3b. kontrola toka programa 2)


Top
 Profile  
 
PostPosted: Tue Feb 16, 2010 12:18 pm 
Offline
Romulanski špijun na Zemlji
User avatar

Joined: Fri Sep 05, 2008 12:35 pm
Posts: 1583
Location: Njemacka
Ako imate kakva pitanja, nejasnoce za rijesiti ili bilokakve komentare stavite na sljedecem topicu:

[Uvod u programiranje] - Nejasnoce, pitanja, komentari


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

Board index » Resursi za učenje » Za potpune početnike!

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group