nav_dugme codeBlog codeBlog
  • početna Početna stranica
  • Sačuvani članci Sačuvani članci
  • Članci
     (spisak)
  • Kontakt
Povratak na vrh stranice

Info & povezani članci Info o članku - dugme

Info

trejler_sat Datum objave: 27.05.2021.

trejler_dokument Jezici: C
Python

trejler_teg_narandzasti Težina: 5/10

C
Python
računari
programiranje
optimizacija
teorija
saveti
zanimljivosti

Povezani članci

Postfiksna notacija - kako računari računaju?Klase složenosti algoritama (O notacija)Strukture podatakaOperacije sa bitovima u programskom jeziku CCallback funkcije i lambda izraziŠablonske niske u programskim jezicimaASCII, Unicode i UTF - Predstavljanje znakova na računarimaUNIX Time - Predstavljanje datuma i vremena na računarimaKako napraviti syntax highlighterGNU/Linux - 1. deo - Uvod
Svi članci
Complexity kills. It sucks the life out of developers, it makes products difficult to plan, build and test, it introduces security challenges, and it causes end-user and administrator frustration.
Ray Ozzie

Izbor prvog programskog jezika

Facebook LinkedIn Twitter Viber WhatsApp E-mail
zoom_plus zoom_minus bookmark
početna > Članci > Saveti

Uvod

Na početku bavljenja programiranjem često se javljaju pitanja koja se tiču opštih odlika programskih jezika koji su pogodni za savladavanje osnova programiranja, odnosno, u praktičnom smislu, postavlja se pitanje koji od postojećih programskih jezika predstavlja (ili ne predstavlja) dobar izbor u prethodno navedenom kontekstu.

U opštem smislu, moglo bi se reći da odgovor zavisi od: uzrasta polaznika, količine vremena na raspolaganju i (pre svega) od toga da li neko želi da se bavi programiranjem iz hobija ('usputno'), ili zapravo želi da od programiranja napravi 'karijeru', i pri tom takođe deluje da postoji veliki broj opcija kada su u pitanju sami programski jezici (s obzirom na to da je u "svetu programiranja" trenutno u opticaju između 10 i 20 programskih jezika visokog nivoa, visokog kvaliteta i velike zastupljenosti u industriji), međutim, pošto se diskusija pred nama odnosi na sam početak bavljenja programiranjem, situacija je ipak "ponešto kompleksnija".

U nastavku (osim kada je drugačije navedeno), većina primedbi odnosiće se na to kako problematici treba da pristupe - polaznici koji imaju sklonost prema programiranju, žele da nauče programiranje sa namerom da se programiranjem (profesionalno) bave "na duže staze", shodno svom uzrastu već imaju prirodnih sposobnosti da savladaju bilo koji od uobičajenih programskih jezika i - što je najvažnije - žele da steknu što bolju osnovu za dalji razvoj.

Još nekoliko napomena

Ako ste čitalac koga zanima veoma kratak odgovor na glavno pitanje iz uvoda, mogli bismo reći da većina relevantnih, kvalitetnih programskih jezika (koji se trenutno koriste u industriji), nisu jezici koji su pogodni za savladavanje osnova programiranja (neki od njih - ni iz daleka :)), i mogli bismo navesti da su C i Python jedini pravi kandidati (pri čemu vam dužina članka verovatno može sugerisati koji od dva navedena jezika zapravo smatramo pravim izborom).

Ako vas zanima samo kraća diskusija (ali ipak malo duža od prethodnog pasusa), napisali smo o svemu nekoliko reči u završnim poglavljima uvodnog članka o Python-u.

Međutim, ako vas zanima nešto opširnija (ali, nadamo se, za vas korisna), diskusija o tome šta je prava svrha programskih jezika visokog nivoa, šta se dešava pri prevođenju programskog koda i zašto neki programski jezici mogu biti bolji izbor od drugih - u fazi učenja - nastavljamo ....

Opšta uloga programskih jezika visokog nivoa

Prvo pitanje kojim se treba pozabaviti je sledeće: šta je (uopšte) svrha programskih jezika tj. kompajlera koje koristimo, odnosno - šta kompajleri rade sa programskim kodom koji programeri napišu?

Počnimo od toga da je jedini jezik koji računari zapravo razumeju - jezik mašinskih naredbi, iz čega (u velikoj meri) proizilazi da je jedini suštinski način "obraćanja čoveka računaru" - pisanje programa preko mašinskih naredbi.

Ipak, u današnje vreme (u ~99% slučajeva), programeri ni ne pomišljaju na to da koriste mašinski jezik za razvoj programa, već se oslanjaju na programske jezike visokog nivoa, ali - to nikako nije moderan trend ....

Programski jezici visokog nivoa zapravo su uvedeni u upotrebu još u ranim fazama razvoja računarske industrije, * budući da je već tada postalo jasno da direktno zadavanje mašinskih naredbi (bez obzira na to što verovatno jeste u pitanju "jedini suštinski način obraćanja čoveka računaru"), u praktičnom smislu ne omogućava kreiranje većih i ozbiljnijih projekata.

.... jer ljudska svest (čast veoma, veoma retkim izuzecima), ni iz daleka nije u stanju da (dovoljno brzo) procesira ogromnu količinu informacija koju bi trebalo uzeti u obzir pri pokušaju da se iole veći i ozbiljniji projekat (pogotovo prema modernim standardima), realizuje direktno preko mašinskog jezika. :)

Konstatacija iz gornje napomene ne odnosi se (u praktičnom smislu) na projekte sa samog početka razvoja računarske industrije, kada su programi (tj. projekti) ** bili znatno jednostavniji (bar iz današnje perspektive :)) - i zato je "nekako" bilo moguće pisati ih preko mašinskog jezika, ali (naravno), odmah je bilo i ambicioznijih planova za budućnost, i stoga je postalo jasno da je potrebno osmisliti mehanizam koji će "posredovati" između ljudske logike i mašinskih naredbi.

I upravo to je uloga programskih jezika: prevođenje programskih kodova koji približno odgovaraju ljudskoj logici - u nizove mašinskih instrukcija, a da bismo još bolje razumeli "raskol" između ljudske logike i računarske logike, u nastavku ćemo detaljno razmotriti jedan jednostavan primer.

Ako zanemarimo "hello world/zdravo svete" programe koji samo ispisuju poruke, teško se može zamisliti primer koji je jednostavniji od programa koji sabira dva unapred zadata broja, međutim, kada se ovakav program prevede na mašinski jezik, nije više 'skroz trivijalan' ....

* Mašinski jezik jeste objektivno "težak i komplikovan", i - sa jedne strane - u potpunosti razumemo da su "praočevi" računarske industrije praktično morali pronaći način za programiranje računara koji je efikasniji od korišćenja mašinskog jezika.

Međutim, smatramo da se pri kreiranju programa - u fazi učenja - mora uspostaviti svest o tome šta računari zapravo rade (a potrebno je, i kasnije - koliko god je moguće - očuvati svest o tome šta se dešava "ispod haube").

** Kada kažemo 'projekat', ne mislimo na specijalizovane programe za koje se i dan-danas koristi mašinski jezik, već mislimo na uobičajeniji poslovni i korisnički softver (odnosno, da pojasnimo dodatno: iako se softver koji pokreće specijalizovane industrijske alate i sl, i dalje vrlo često piše u asembleru, verujemo da nijednoj softverskoj kompaniji ne bi palo na pamet da preko asemblera projektuje (recimo) paket kancelarijskog softvera ili neki sličan softver).

Primer jednostavnog programa koji je preveden na mašinski jezik

Program za sabiranje dva broja, tipično podrazumeva: deklaraciju tri promenljive (a, b i c (dva sabirka i zbir)), i naredbu preko koje se računa zbir promenljivih a i b, nakon čega se zbir smešta u memorijsku lokaciju koja je vezana za promenljivu c.

Pre nego što se osvrnemo na to kako navedeni program "izgleda i funkcioniše" pošto se prevede na mašinski jezik, bitno je razumeti da računar ("ispod haube" / nakon prevođenja programskog koda), ne izvršava direktno one naredbe koje su zapisane u C-u, Python-u, ili nekom drugom sličnom jeziku, jer (u najvećem broju situacija), naredbe programskih jezika višeg nivoa ne odgovaraju direktno mašinskim naredbama.

Računar nije u stanju da direktno izvrši čak ni (naizgled) krajnje jednostavnu naredbu kao što je c = a + b; već se i ovakva instrukcija mora raščlaniti (preko prevodioca), na još jednostavnije mašinske instrukcije.

Pre svega, mašinske instrukcije su "elementarnije" od instrukcija programskih jezika visokog nivoa (najčešće bar malo, a ponekad i 'poprilično'), a postoje i "ne-baš-malobrojne" pripremne radnje i međuoperacije, o kojima mnogi programeri koji koriste bilo koji programski jezik visokog nivoa (da, čak i C :)), vrlo često ne razmišljaju.

Na sledećoj slici možemo videti (pomalo uprošćeni) asemblerski pseudokod * programa za sabiranje dva broja (u kome sabiranju prethodi deklaracija i inicijalizacija promenljivih a, b i c):

		
mov 0x0020, 10 # upis vrednosti u RAM
mov 0x0024, 15 # upis vrednosti u RAM
mov R1, 0x0020 # kopiranje u registar procesora
mov R2, 0x0024 # kopiranje u registar procesora
add R1, R2, R3 # sabiranje u procesoru
mov 0x0028, R3 # kopiranje rezultata iz
               # registra procesora (nazad) u RAM
		
	
Slika 1. - Asemblerski pseudokod programa za sabiranje dva broja.

Verujemo da mnogi stariji i iskusniji čitaoci mogu razumeti ovakav kod "na prvu loptu", ali, svakako ćemo napraviti kraću analizu.

* Pseudokod je naziv za kod koji podseća na programski kod iz nekog od programskih jezika (C, Python, Java ....), to jest, u pitanju je kod čiji delovi podsećaju na: naredbe, grananja, petlje, funkcije i sl, ali - za razliku od pravog koda - "šematski" kod se ne može (zapravo) kompajlirati i pokrenuti.

Detaljnija analiza asemblerskog (pseudo)koda

Deklaracija promenljivih (bilo da se tip podatka zadaje eksplicitno, kao u C-u, ili implicitno, kao u Python-u), tumači se pri prevođenju kao naredba preko koje treba rezervisati određeni memorijski prostor za navedene podatke (u primeru kojim se bavimo: treba rezervisati tri memorijska bloka od po četiri bajta, što je standardna veličina celobrojnih promenljivih u ovom trenutku i duži niz godina unazad).

Na početku izvršavanja programa, RAM memorija ne sadrži nikakve podatke, * a CPU je u neutralnom stanju (na slici: memorijske lokacije promenljivih a, b i c označene su belom bojom, dok su lokacije koje nemaju veze sa izvršavanjem programa zatamnjene).

asembler 01
Slika 2. - Sadržaj RAM memorije i CPU-a pre početka sabiranja.

* Da budemo precizni, zapravo mislimo na deo RAM memorije u koji se smeštaju promenljive koje program koristi, a dužni smo i nekoliko dodatnih napomena:

- U gornjem primeru, memorijske lokacije su uredno inicijalizovane nulama (što svakako 'deluje lepo'), međutim - u realnim uslovima, po pokretanju programa (pre inicijalizacije promenljivih), memorijske lokacije mogu sadržati "otpad" (eng. "garbage"), tj. bitove preostale od prethodnih programa koji su koristili iste memorijske lokacije.

- Takođe, zarad preglednosti, ne prikazujemo 32 bita za svaku int promenljivu (već samo 4).

Nakon deklaracije promenljivih, sledi inicijalizacija (vrednosti 7 i 3 upisuju se, jedna za drugom, * u memorijske lokacije koje su rezervisane za promenljive a i b).

asembler 02
Slika 3. - Upis vrednosti dve promenljive u RAM memoriju.

* Dakle, u pitanju su dve zasebne mašinske naredbe (koje se izvršavaju jedna za drugom), ali, prikazujemo ih na istoj slici, takođe zarad bolje preglednosti.

Nakon upisivanja u RAM memoriju, sledi priprema za sabiranje, što podrazumeva da se vrednosti iz RAM memorije prvo kopiraju * u registre ** procesora:

asembler 03
Slika 4. - Kopiranje vrednosti iz RAM memorije u registre procesora.

* Takođe su u pitanju dve nezavisne mašinske naredbe.

** Registar je naziv za memorijsku lokaciju unutar procesora u koju se smeštaju podaci koji direktno učestvuju u operacijama.

Potom se poziva naredba za sabiranje unutar procesora, a rezultat izvršavanja smešta se u treći registar. *

asembler 04
Slika 5. - Sabiranje vrednosti iz dva registra i smeštanje rezultata u treći registar (unutar CPU-a).

Na kraju, vrednost iz registra R3 kopira se u memorijsku lokaciju koja je rezervisana za promenljivu c.

asembler 05
Slika 6. - Kopiranje vrednosti iz registra CPU-a u RAM memoriju.

Kroz prethodnu analizu jasno se može razumeti situacija koju smo ranije opisali: iako instrukcije programskih jezika visokog nivoa bar približno odgovaraju ljudskom načinu razmišljanja, sa mašinskim jezikom to (očigledno) nije slučaj - što znači da se mnogo toga "ne vidi" kada se programi pišu u programskim jezicima koje odlikuje visok nivo apstrakcije.

Kada su u pitanju obimniji i komplikovaniji kodovi, dolazi do još izraženijeg "skrivanja kompleksnosti", međutim, iako je svrha primera bila da se prikažu razlike, jasno je da u svemu (naravno) ima i mnogo sličnosti: u oba slučaja jasno se prepoznaju naredbe za sabiranje brojeva, poslednji korak odgovara naredbi dodele promenljivoj c i sl.

* Unutar procesora, sabiranje se tipično izvodi preko dva registra (tako da zbir na kraju ostaje upisan u prvi registar), ali, hteli smo da primer bude što jednostavniji za praćenje (pogotovo zarad čitalaca koji nemaju prethodno iskustvo sa programiranjem i računarima).

Ako prethodni mašinski pseudokod uporedimo sa pseudokodom visokog nivoa (koji se može implementirati u bilo kom konkretnom programskom jeziku koji podržava proceduralno programiranje) ....

		
a = 7
b = 3
c = a + b
		
	
Slika 7. - Pseudokod za sabiranje dve celobrojne vrednosti.

.... nije teško uvideti zašto mašinski jezik nije praktično koristiti: ni u projektima iole većeg obima (nije nemoguće, ali je veoma, veoma teško, komplikovano i nepraktično) - niti kao prvi jezik preko koga se polaznici upoznaju sa programiranjem.

Ipak, sam po sebi, asembler je izuzetno zanimljiv i, ako se osvrnemo na to da postoje pojedinci koji uče latinski jezik da bi čitali dela klasične literature u originalu (ili ruski jezik, da bi čitali dela F.M. Dostojevskog u originalu; nemački zarad dela J.V. Getea i sl), moglo bi se reći da iza nečije želje da se upozna sa asemblerom - verovatno stoji srodna ideja.

(Doduše .... 'bivši i sadašnji' govorni jezici koje smo pomenuli, ipak su lakši za razumevanje i učenje od asemblera.) :)

Svrha prvog programskog jezika

U širem kontekstu, dalja diskusija se svodi na pitanje: koliko tehnologija treba da pomaže programerima pri kreiranju programa?!

Smatramo da pre svega treba razlikovati, sa jedne strane, programiranje u procesu učenja i, sa druge strane, produkcijsko programiranje kojim se bave profesionalci koji su već savladali osnove, i stoga ćemo kontekst diskusije svesti na prvu situaciju.

.... jer profesionalni programeri tipično ne čitaju članke o izboru 'prvog' programskog jezika, budući da već poznaju više programskih jezika i koriste onaj koji u datom trenutku predstavlja optimalan izbor. :)

Moglo bi se reći ('hipotetički'), da bismo o izvršavanju računarskih programa najviše naučili kada bismo sve programe pisali na mašinskom jeziku (od samog početka, pa sve do trenutka kada prestanemo da se bavimo pisanjem programa), međutim, to nećemo raditi (ne zato što zaista ne želimo, nego zato što je izrazito komplikovano), i stoga treba naći "zlatnu sredinu" između dve krajnosti:

  • mašinskog koda, koji je za ljude izuzetno komplikovan (i, takođe - budimo iskreni - prilično neprirodan) :)
  • programskih jezika (suviše) visokog nivoa apstrakcije, u kojima programski kod deluje jednostavnije, ali je ipak (previše) udaljen od računarske logike (tj. od svega onoga što računar zapravo radi)

Tražimo, dakle, programski jezik koji početnike neće odmah "ubiti u pojam" svojom kompleksnošću, * ali ih takođe - što je još važnije - neće navoditi na netačan zaključak da je programiranje "jednostavnije nego što jeste".

* Asembler je vrlo zanimljiv, sam po sebi, ali, za ogromnu većinu polaznika, ipak predstavlja "prevelik zalogaj".

Međutim ....

Negde između veoma mladih polaznika (za koje je asembler ipak objektivno pretežak), i iskusnih programera (koji uglavnom poznaju asembler, ali ga ne koriste, budući da bi to "dodatno zakomplikovalo ionako komplikovane projekte"), postoji i kategorija ljudi koju tradicionalno niko "ne štedi" (u pitanju su studenti). :)

Mašinski jezik, odnosno asemblerski jezik, proučava se na fakultetima na kojima se odvija nastava iz programiranja, što znači da ćete se sa asemblerom (verovatno) susresti u prvim godinama akademskih studija.

Takođe, da bismo bili precizni, dužni smo i sledeću napomenu: kada govorimo o mašinskom jeziku (i u ovom članku, i inače), gotovo uvek mislimo na asembler.

Striktno govoreći, asembler nije mašinski jezik u doslovnom smislu, jer prave mašinske naredbe su nizovi nula i jedinica (kako jedino i može biti), međutim, asembler nije ni 'proizvoljan jezik', već, jezik čije su naredbe mnemoničke oznake za mašinske naredbe (mov, add i sl), odnosno, tekstualne skraćenice koje direktno odgovaraju mašinskim naredbama.

U literaturi i u govoru, dva navedena pojma se upotrebljavaju kao sinonimi (jer, u praktičnom smislu, asembler jeste mašinski jezik), i kada se kaže "mašinski jezik", tipično se misli na asembler.

Predstavljanje kandidata

Kao što smo još na početku naveli, smatramo da su programski jezici C i Python najbolji "kandidati" kada je u pitanju izbor prvog programskog jezika (i manje-više jedini koje zapravo treba uzeti u obzir). *

Iz perspektive početnika koji se tek susreću sa programiranjem, C previše "naginje" prema kompleksnosti, dok, iskusniji programeri, koji se bave i pedagoškim radom, često zameraju Python-u na suviše visokom nivou apstrakcije, odnosno, na sklonosti ka "skrivanju" delova koda o kojima svaki programer (ipak) treba da razmišlja - pogotovo kada su u pitanju programeri koji tek savladavaju prve korake.

Međutim (kao što smo takođe ranije naveli), u pitanju je situacija koja zavređuje podrobniju analizu, i stoga ćemo se u nastavku pozabaviti najvažnijim karakteristikama dva navedena jezika.

* Naravno, budući da ne postoje "zvanična" pravila o tome koji se jezik "mora" koristiti na početku, u pitanju je savet koji dajemo na osnovu opšte procene stanja računarske industrije i na osnovu sopstvenih i tuđih iskustava u podučavanju.

Postoje i drugi jezici koji su inače 'u opticaju', u diskusijama o "prvom" programskom jeziku, ali, smatramo da ostale jezike treba zaobići na samom početku (naravno, posle početnog upoznavanja sa osnovama, i drugi jezici veoma (!) dobro dođu).

U zasebnom poglavlju pred kraj, navešćemo o kojim jezicima se radi i obrazložićemo zašto zauzimamo prethodno navedeni stav.

Kandidat #1 - programski jezik C

Programski jezik C pojavio se pre nešto manje od 50 godina, kao odgovor na pitanje kako premostiti jaz između: (dotadašnjih) programskih jezika visokog nivoa (BASIC, Fortran, Cobol ....), koji nisu bili pogodni za sistemsko programiranje, i (sa druge strane), različitih implementacija asemblera (tj. mašinskog jezika), koji jeste podoban za pisanje programa bilo kog nivoa kompleksnosti, ali (kao što smo već videli), takođe je i prilično komplikovan, kako za učenje, tako i za razvoj iole kompleksnijeg softvera.

Sintaksa C-a je bliska ljudima (to doduše nije bio nedostatak ni jezika kao što su Pascal, Fortran, Cobol i sl; njihova sintaksa je često bliža govornom engleskom jeziku u odnosu na C), ali, za razliku od prethodno navedenih jezika (i drugih sličnih jezika), C je omogućio upotrebu "pokazivača" - specijalizovanih promenljivih koje pružaju direktan pristup memorijskim lokacijama.

Nije bilo teško uvideti da jezik - moćan skoro kao asembler i ne mnogo kompleksniji od drugih tadašnjih jezika - predstavlja krajnje elegantno rešenje za pisanje operativnih sistema i drugog sistemskog softvera (kao i bilo kog softvera opšte namene).

Prosto rečeno, "to je bilo to" (što do tada nije postojalo i "što se čekalo"), i C je u godinama koje su dolazile postao svojevrstan standard, stekao je zasluženu popularnost, a dobio je i više objektno orijentisanih naslednika sa sličnom sintaksom (C++, Java, C# .... da pomenemo samo "najočiglednije").

Iz današnje perspektive , C nije "poslednja reč tehnike", ali, kao i svaka suštinski dobra zamisao koja je takođe i dobro izvedena: odoleva "zubu vremena", i dalje je "živ i zdrav", dobro se drži, i dalje se koristi u industriji, i naravno (što nas u ovom trenutku najviše zanima) - koristi se kao jezik za učenje.

Primer jednostavnog programa u programskom jeziku C

Da bismo se upoznali sa tim kako izgledaju programi u C-u, uzećemo za primer ("ponovo"), jednostavan program koji sabira dve zadate celobrojne vrednosti i ispisuje rezultat:

		
#include<stdio.h>

void main()
{
	int a, b, c;

	a = 10;
	b = 15;
	c = a + b;

	printf("%d", c);
}
		
	
Slika 8. - Primer jednostavnog programa za sabiranje dve celobrojne vrednosti u programskom jeziku C.

Iz perspektive početnika, instrukcije u C-u se okvirno mogu podeliti u dve kategorije:

  • instrukcije koje direktno služe "onome što treba uraditi" (sabiranje dva broja i prikaz rezultata)
  • instrukcije koje "mladim programerima nisu previše zanimljive, ali, 'eto', i one se moraju zapisati"

Sometimes I do what I want to do. The rest of the time, I do what I have to. poznati filmski citat

(Pustićemo vas da sami otkrijete koji film je u pitanju. :))

Instrukcije iz druge kategorije često "dosađuju" polaznicima svojom "nepotrebnom" pojavom, ali, takav utisak skoro u potpunosti izbledi već posle nekoliko nedelja bavljenja C-om (eventualno posle nekoliko meseci), a da bismo dodatno ubrzali proces početnog upoznavanja, osvrnućemo se na nekoliko "spornih" jezičkih konstrukcija.

Analiza programskog koda

Direktiva #include sugeriše prevodiocu da treba u program uvesti određenu biblioteku (da bismo mogli da koristimo naredbe koje navedena biblioteka sadrži).

Deklaracija int a, b, c; sugeriše da nabrojane promenljive pripadaju celobrojnom tipu.

Pored navedenog, prisutna je i obavezna upotreba funkcije main (sa zaglavljem void main() i vitičastim zagradama koje uokviruju telo funkcije).

Možda je u pitanju 'previše informacija' za sam početak, ali, kao što rekosmo, polaznici se veoma brzo i lako naviknu na C-ovski pristup, pri čemu postoji i prilika da se svašta nauči:

  • biblioteka stdio.h uvozi se zato što, u C-u, funkcije ulaza i izlaza nisu deo osnovne specifikacije jezika, već se nalaze u bibliotekama (što naprednim korisnicima koji imaju puno slobodnog vremena, daje mogućnost da (po potrebi) samostalno implementiraju čak i elementarne funkcije, i time prošire osnovne mogućnosti jezika)
  • podaci svakako pripadaju određenom tipu (i u jezicima sa dinamičkom tipizacijom, a pogotovo u jezicima sa strogom tipizacijom, u koje spada C), i stoga (pomalo slikovito) - nekako je "najpoštenije" da sami izaberemo tip podatka pri deklaraciji promenljivih (u gornjem primeru, za tip podatka je izabran int - celobrojna vrednost)
  • funkcije takođe postoje u većini programskih jezika (i Python spada u navedenu većinu), a specifičnost C-a je da ("eto") insistira na tome da se funkcije koriste uvek, čak i kada se pišu izrazito jednostavni programi koji koriste samo jednu funkciju

NAPOMENA: poslednja stavka koju smo naveli, zna da bude poveći "kamen spoticanja" za mnoge polaznike na samom početku, a prethodno smo pomenuli i to da neke (inače sasvim dobre) programske jezike, nikako ne smatramo dobrim izborom za sam početak (recimo, C# i Java).

Razlog tome je što, u pomenutim jezicima, čak i najosnovniji programi: ne samo da moraju biti zapisani u okviru funkcija (kao u C-u), već i u okviru klasa - što početnicima samo dodatno "komplikuje život".

Ovakvim temama posvetićemo više mesta pred kraj (kao što smo već pomenuli), a sada se vraćamo na C.

Ispis preko funkcije printf() jeste malo komplikovaniji za razumevanje na samom početku, i stoga ćemo instrukcijama za formatiranje ispisa posvetiti dodatnu pažnju u nastavku (pošto predstavimo način pisanja programa u Python-u).

U svakom slučaju, sve što smo do sada naveli "nije baš trivijalno" (iz perspektive početnika), ali, može se ipak zaključiti da C nije ni "previše komplikovan" (ni iz daleka). :)

Programski kod koji se direktno tiče zadatka koji rešavamo, potrebno je dopuniti i drugim (obaveznim) instrukcijama, međutim, takve instrukcije su prilično jednostavne za razumevanje (iza svega stoje krajnje logične ideje, kao što smo već videli), i stoga zaista nije teško navići se na "C-ovski" pristup.

Uskoro ćemo videti da 'skroz jednostavni' programi u Python-u zbilja izgledaju mnogo jednostavnije, ali, nakon toga ćemo videti i to da "početna prednost" prilično brzo i lako "izbledi" - kada kompleksnost zadataka poraste.

Kandidat #2 - Programski jezik Python

Programski jezik Python (takođe programski jezik visokog nivoa), pojavio se pre ~30 godina, pri čemu nije baš pokrenuo revoluciju kakvu je izazvala pojava C-a, ali, skrenuo je na sebe pažnju 'programerske zajednice' i postao je u međuvremenu jedan od najpopularnijih jezika.

Ako je C bio odgovor na pitanje: kako napraviti čitljiv programski jezik visokog nivoa koji je skoro na nivou asemblera po pitanju mogućnosti i brzine izvršavanja koda, Python je bio odgovor na pitanje: kako napraviti skriptni jezik (sa jednostavnom, preglednom sintaksom) - koji nudi većinu mogućnosti koje su svojstvene ozbiljnijim, 'kompajliranim' programskim jezicima kao što su C i C++.

Međutim, pored dobrih strana, upotreba programskog jezika koji ne podrazumeva kompajliranje programskog koda pre pokretanja, svakako povlači i pitanje brzine izvršavanja programa.

U početku, brzina izvršavanja skripti jeste bila jedna od glavnih "boljki" Python-a (tj. da budemo precizni - nedostatak brzine :)), ali, u praktičnom smislu, "brzina" već duže vreme ne igra iole bitnu ulogu u diskusijama koje se tiču mogućnosti ovog jezika.

Čitajući naše članke, mogli ste primetiti da nedostatak brzine Python-a (kao skriptnog jezika), nigde nismo do sada 'potencirali' (ni u dosadašnjim člancima o Python-u, ni u članku koji trenutno čitate).

Nekada ("davno"), programi napisani u Python-u (a slično važi npr. i za Javu), izvršavali su se osetno sporije nego što je to slučaj sa programima koji su pisani u jezicima C i C++, ali, brzina izvršavanja Python skripti, već duže vreme nije "sporna".

Razlika naravno postoji i dalje (programi pisani u C/C++-u su "i dalje" objektivno brži, ponekad i veoma primetno); razlika jeste bitna npr. u sistemskom programiranju (operativni sistemi, drajveri i sl), kao i u drugim "kritičnim" primenama (3D endžini i sl), međutim, u slučaju većine uobičajenih programa za svakodnevnu upotrebu (a pogotovo u slučaju jednostavnih programa koji se pišu u fazi učenja), razlika se skoro i ne oseti u praksi, i uglavnom se može zanemariti.

Pogledajmo kako izgleda jednostavan program za sabiranje dva broja, napisan u Python-u.

Primer jednostavnog programa u programskom jeziku Python

Ako tražimo 'suštu jednostavnost' (makar u kontekstu elementarnih programa :)), Python nas neće izneveriti:

		
a = 10
b = 15
c = a + b
print(c)
		
	
Slika 9. - Primer jednostavnog programa za sabiranje dve celobrojne vrednosti u programskom jeziku Python.

Kada smo napisali sličan program u C-u, usledila je analiza koda, a svrha analize bila je - da pomogne oko nejasnoća u programskom kodu.

Ovoga puta nema potrebe za detaljnom analizom (sav kod staje u nekoliko linija, nema vitičastih zagrada i (bar za sada), importovanja biblioteka).

.... a takođe bi se 'moglo reći' da programski kod koji smo prethodno videli "prilično podseća" na pseudokod koji smo videli na početku članka. :)

Umesto analize koda u Python-u, posmatraćemo šta se događa (u oba programska jezika), kada kompleksnost programa počne da raste.

Razlike između C-a i Python-a u implementaciji kompleksnijih kodova

Pre svega, ako zanemarimo obavezne, "uokvirujuće" delove koda u C-u, primetićemo da su programi koje smo već pisali u dva programska jezika koje proučavamo, gotovo istovetni, a kako kompleksnost programa raste - razlika uglavnom ostaje u granicama koje smo već 'dostigli', a ponekad postane i manja.

Prvo čime ćemo "zakomplikovati kodove", biće naredbe ulaza.

Dodavanje naredbe ulaza

I ovoga puta, prvo ćemo razmotriti (izmenjeni) C kod ....

		
#include<stdio.h>

void main()
{
	int a, b, c;

	scanf("%d", &a);
	scanf("%d", &b);
	c = a + b;

	printf("%d", c);
}
		
	
Slika 10. - Program za sabiranje kome je dodata naredba ulaza, zapisan u programskom jeziku C.

.... pri čemu ćemo napraviti i kratak osvrt na funkciju printf (što smo prethodno ostavili "za kasnije").

Razume se da ćemo se osvrnuti i na funkciju scanf koja u idejnom smislu ima dosta sličnosti sa funkcijom printf.

Funkcija printf, omogućava ispis podataka u terminalu (printf = "print formatted", ispis sa formatiranjem podataka).

Ako predamo nisku "Dobar dan! :)" ....

		
printf("Dobar dan! :)");
		
	
Slika 11. - Naredba printf u programskom jeziku C.

.... i pokrenemo program, u terminalu će biti ispisano "Dobar dan! :)".

Za ispis podataka kao što su vrednosti brojčanih i znakovnih promenljivih, naredba printf koristi tzv. specifikatore konverzije * ....

  • %c - za znakovne promenljive
  • %d - za celobrojne vrednosti
  • %f - za decimalne brojeve

.... što podrazumeva da se pojava navedenih niski (u okviru glavne niske koja je ograničena znacima navoda), tretira kao poziv za ispis vrednosti promenljivih, pri čemu se identifikatori promenljivih navode posle zareza. **

		
a = 54;
printf("%d", a);
		
	
Slika 12. - Naredba printf u programskom jeziku C, preko koje se ispisuje vrednost celobrojne promenljive (u drugim okolnostima, naredba printf se može koristiti za kombinovani ispis niski i vrednosti promenljivih).

Pokretanjem instrukcija sa gornje slike - dobija se ispis 54.

Naravno, programi moraju biti zapisani unutar funkcije main, kao i do sada (što je u prethodnim primerima izostavljeno isključivo zarad preglednosti).

* Takođe, napomenimo da postoje i drugi specifikatori konverzije koji se koriste u funkciji printf (za sada smo naveli samo nekoliko najbitnijih).

** Zarez sledi posle tzv. komandnog stringa (što je zvaničan naziv za "glavnu nisku" koja sadrži obične znakove i specifikatore konverzije).

U Python-u je situacija po pitanju jednostavnih naredbi ispisa - još bolja (kao što smo već videli) ....

		
a = 54
print(a)
		
	
Slika 13. - Naredba ispisa print (u programskom jeziku Python).

U praktičnom smislu, gornji kod predstavlja ceo program.

Što se tiče naredbe scanf() u programskom jeziku C (koju ste takođe mogli zapaziti u primeru na slici #10): u komandnoj niski navode se specifikatori konverzije, posle zareza dolaze adrese promenljivih (operator & predstavlja operator adresiranja u C-u), a adrese redom odgovaraju navedenim specifikatorima:

		
char  c;
int   a;
float f;

scanf("%c %d %f", &c, &a, &f);
		
	
Slika 14. - Specifikatori konverzije u naredbi printf, u programskom jeziku C.

U python-u se učitavanje obavlja preko naredbe input(), ali, kada se učitavaju celobrojne vrednosti, potrebno je koristiti i funkciju int() koja prihvata nisku (u svojstvu argumenta) i pretvara je u celobrojnu vrednost. *

		
a = int(input())
b = int(input())
		
	
Slika 15. - Naredba ulaza input, u programskom jeziku Python.

* U suprotnom (ako se ne koristi funkcija int), Python interpretator 'smatra' da učitavamo nisku (!), što vrlo lako dovodi do toga da "sabiranje" zapravo postane - spajanje niski ("2" + "24" = "224").

Kod za učitavanje vrednosti promenljivih u Python-u, u očima početnika i dalje (verovatno) deluje jednostavnije od programskog koda iz C-a (koji smo ranije prikazali), međutim, već na ovakvim jednostavnim primerima vidimo da nije više u pitanju 'skroz jednostavan kod', a vidimo i to da u Python-u takođe moramo voditi računa o tipovima podataka pri unosu (bez obzira na to što tip promenljivih nigde nije eksplicitno deklarisan).

Kombinovani ispis unapred zadatih niski i vrednosti promenljivih

Za kraj, poredićemo kodove za kombinovani ispis unapred zapisanih (tj. "hardkodiranih") niski, i vrednosti promenljivih.

Funkcija printf, koja možda jeste 'pomalo zbunjujuća' za sam početak (dok polaznik ne napiše cca. desetak programa), na ovom mestu će pokazati svoju pravu vrednost.

Kada je potrebno kombinovati unapred zadati ispis i vrednosti promenljivih, printf nudi elegantno rešenje (veoma nalik rešenjima koja smo predstavili u članku o šablonskim niskama): *

		
printf("Zbir brojeva %d i %d je %d", a, b, c);
		
	
Slika 16. - Kombinovani ispis unapred zadatih niski i vrednosti promenljivih u programskom jeziku C (preko naredbe printf).

* Naravno, funkcija printf pojavila se (godinama) pre šablonskih niski o kojima smo pisali.

Osnovni ispis u Python-u više nije toliko jednostavan (jer podrazumeva upotrebu dodatne funkcije str, preko koje se brojevi i drugi netekstualni podaci pretvaraju u niske), i takav ispis - u slučaju kada je u nisku potrebno uvrstiti veći broj promenljivih - u praksi ume da deluje prilično "nezgrapno" ....

		
print("Zbir brojeva" + str(a) + " i " + str(b) + " je " + str(c))
		
	
Slika 17. - Kombinovani ispis unapred zadatih niski i vrednosti promenljivih u programskom jeziku Python (preko naredbe print i pomoćne funkcije str).

Sa druge strane, Python nudi i alternativni način formatiranja podataka u ispisu ....

		
print("Zbir brojeva %d i %d je %d" % (a, b, c))
		
	
Slika 18. - Naredba print iz programskog jezika Python (naredba koristi komandni string i realne argumente, po ugledu na naredbu printf iz programskog jezika C).

.... koji (u idejnom smislu i po pitanju kompleksnosti), deluje gotovo istovetno kao zapis u C-u, i stoga (kao što vidimo), u pojedinim situacijama, razlike između C-a i Python-a u smislu kompleksnosti koda - gotovo da ne postoje. :)

Razlike između C-a i Pythona - i te kako postoje (naravno), međutim, sasvim često se programski jezici "približe" jedni drugima, u smislu konkretnih implementacija različitih algoritama - i upravo to smo hteli da potcrtamo preko prethodnog primera.

Zašto smo "preskočili" Javu, C# i JavaScript

Iako uvažavamo Javu, C# i JavaScript kao krajnje relevantne jezike, smatramo da ih (ipak) treba izbeći na samom početku.

JavaScript je jezik koji se izvršava u browseru (što nije najzgodnija okolnost za početnike), a pri tom je takođe u pitanju jezik koji "naginje" prema pojednostavljenim načinima za zapisivanje koda (po čemu 'podosta' podseća na Python).

Nasuprot navedenom, Java i C# "pretežu" na drugu stranu.

Java i C# nalažu obaveznu upotrebu klasa, * i pri tom postoji obaveza kreiranja programa preko projekata koji su smešteni u zasebne foldere (za razliku od C-a i Python-a koji dozvoljavaju kreiranje i pokretanje programa preko pojedinačnih izvornih datoteka).

* Pored navedenog, Java zahteva i to da svaka javna klasa bude u zasebnoj datoteci.

Usudili bismo se da pretpostavimo, da nijedan mlađi polaznik koji nema dovoljno prethodnog iskustva (a bogme ni stariji), nije u stanju da "na prvu loptu" zapravo razume sledeći kod ....

		
// Java:

package program1;

public class Program1 {

	public static void main(String[] args) {

		System.out.printf("Dobar dan! :)");

	}

}
		
	
Slika 19. - Program za sabiranje, kome je dodata naredba ulaza, zapisan u programskom jeziku Java.

.... kao ni sledeći kod ....

		
// C#:

using System;

namespace Program1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Dobar dan! :)");
            Console.ReadKey();
        }
    }
}
		
	
Slika 20. - Program za sabiranje, kome je dodata naredba ulaza, zapisan u programskom jeziku C#.

.... i to je sasvim u redu (ako se potrudite oko razvoja sopstvene programerske veštine i "ne preskačete gradivo", neće proći mnogo vremena do trenutka kada ćete razumeti, ne samo prethodno navedene kodove, već - i znatno kompleksnije kodove). :)

U pitanju je zanimljiv paradoks: naveli smo kod koji predstavlja (gotovo doslovno), prazne klase, međutim, takav kod za početak jeste 'legitimno komplikovan', i treba mu pristupiti sa pažnjom i uvažavanjem (i to - tek pošto je polaznik dobro savladao osnove proceduralnog programiranja).

Ako je sa C-om problem to što se od početnika zahteva da odmah usvoje veći broja ideja (#include, funkcije, printf i scanf sa specifikatorima konverzije i sl), jasno je da Java i C# pred početnike postavljaju još više zahteva.

Učenici koji žele da se odmah upuste u izučavanje Jave ili C#-a (što, da ponovimo - nikako ne preporučujemo), zahtevima koje pred njih na početku postavlja programski jezik C moraju dodati i sledeće zahteve:

  • ili moraju naprečac usvojiti principe OOP-a, da bi mogli razumeti šta rade
  • ili mogu nekritički prihvatiti da ("eto", "onako"), funkcije treba pisati unutar klasa

Usvajanje principa objektno orijentisanog programiranja naprečac - gotovo je nemoguće izvesti (najbolje je da ni ne pokušavate :)), odnosno, veoma je neprirodno i pedagoški štetno da prilično kompleksnu tematiku OOP-a savladavate pre nego što ste dobro savladali same osnove programiranja!

Što se tiče toga da prihvatite da neko vreme (u praksi, bar nekoliko meseci), pišete kodove koji moraju biti uokvireni telom klase, reći ćemo da takav pristup ponekad uspe, ponekom starijem polazniku (15+), ali, i dalje ne preporučujemo da pokušavate, jer, iako ponekad uspe, u velikoj većini slučajeva - navedeni pristup samo dovodi do velike zbrke.

Koncept obavezne upotrebe funkcija (koji je svojstven programskom jeziku C i njegovim naslednicima), nije "najjednostavnija stvar na svetu", ali, većina polaznika prihvata takav pristup prilično lako, budući da iza svega stoje vrlo jasni razlozi:

  • svaka funkcija namenjena je rešavanju određenog problema (to jest, rešavanju jednog zadatka)
  • glavna funkcija (main), namenjena je rešavanju glavnog problema
  • ostale funkcije su namenjene rešavanju potproblema i sporednih problema

Ako je glavni problem jednostavan, sav kod može se zapisati unutar funkcije main, ali - ako je glavni problem (dovoljno) kompleksan, potrebno je prepoznati obrasce u obradi podataka (pogotovo one koji se ponavljaju(!)) - i potom je potrebno definisati zasebne funkcije preko kojih se rešavaju (uočeni) potproblemi.

Recimo, u primerima nalik na: "unetu vrednost u evrima pretvoriti u dinare", sav kod može se pisati u funkciji main.

U nekim drugim, 'malo manje jednostavnim' programima, programski kod koji se tiče rutinskih zadataka potrebno je izdvajati u zasebne funkcije, koje se potom mogu pozivati u glavnoj funkciji (na primer, u programu koji treba da ustanovi koji od tri uneta broja ima najviše cifara, sav kod koji se tiče prebrojavanja cifara, najpraktičnije je izdvojiti u zasebnu funkciju, koja se zatim poziva u glavnom programu).

Međutim, za razliku od funkcija, klase i objekti nisu jednostavni za razumevanje ukoliko pojedinac (već) nema dovoljno prethodnog iskustva sa proceduralnim programiranjem.

Ima li još opcija?

Zarad opšte informisanosti, navešćemo 'još koji' programski jezik (iz skupa programskih jezika koji .... "ikako" * .... mogu doći u obzir).

Reklo bi se da su najočigledniji primeri iz kategorije 'ostalih kandidata' - BASIC i Pascal - jezici koji nisu igrali 'preveliku ulogu' u razvoju softvera koji se koristi u industriji, ** ali, u 'starija vremena' su veoma često bili korišćeni u obrazovne svrhe, i na izvestan način su i dalje deo 'kolektivnog sećanja' (upravo zbog nekadašnje uloge u obrazovanju starijih generacija programera).

BASIC je tipično bio namenjen najmlađim početnicima, a Pascal je bio namenjen učenicima i studentima (autor ovog članka načinio je svoje prve (prave) 'programerske korake' upravo uz Pascal, i svega se seća sa simpatijama :)).

Međutim, u današnje vreme, navedeni 'trenažni' jezici koriste se vrlo retko i smatraju se prevaziđenim.

* Hoćemo reći, u pitanju su jezici koji "nekome mogu pasti na pamet" (a ne - "jezici koje bi trebalo koristiti na početku"). :)

** Pascal se u izvesnoj meri i dalje 'provlači' kroz srednjoškolski obrazovni sistem (časovi informatike), a prisutan je, 'povremeno i mestimično', i u početnim fazama akademskih studija (kao alternativa Python-u).

Sa druge strane, postoje moderni jezici, kao što su (npr) Go, Rust, Zig i sl. koje takođe treba izbegavati na početku, ali - iz sasvim 'suprotnih' razloga - budući da sintaksa navedenih jezika (u iole praktičnom smislu), nije "blagonaklona prema početnicima".

U pitanju su jezici koji su namenjeni ozbiljnijim zadacima, kao što je (npr): sistemsko programiranje (drajveri za uređaje, komponente operativnih sistema i sl), ili kreiranje visoko optimizovanih backend komponenti web aplikacija, što, da ponovimo - nikako nisu poduhvati za početnike. :)

Vreme je da polako završimo diskusiju o izboru prvog programskog jezika ....

C vs. Python - "može biti samo jedan"

(.... na samom početku)

Pretpostavljamo da nije nimalo teško zaključiti koji od dva jezika, kojima smo posvetili najviše pažnje, predstavlja našu preporuku pri izboru prvog programskog jezika - u pitanju je C.

Verujemo da je to odavno jasno. :)

Međutim, želimo da dodatno pojasnimo (za svaki slučaj): 'navijamo' za C, a ne protiv Python-a (prema Python-u zapravo gajimo izvesne simpatije, iako smo i dalje svesni određenih realnih nedostataka ovog jezika).

Ako "baš mora" da bude Python za početak, i ako bi odricanje od Python-a ugrozilo vašu ljubav prema programiranju i želju da se ovom veštinom dalje bavite - nemojte se odreći Python-a i počnite učenje upravo uz Python.

Ali, vodite računa o sledećem ....

Python je programski jezik čiji se pravi smisao ogleda u tome da je u stanju da iskusnim programerima olakša (ili, neko bi možda rekao - ulepša), posao izrade skripti za rešavanje svakodnevnih zadataka (i mnogo šta još), a pri tom je pogodan i za najmlađe polaznike kojima C objektivno može predstavljati "preveliki zalogaj" na samom početku, pogotovo ako programiranje savladavaju sami (što se danas dešava mnogo češće nego ranijih godina).

Svrha Python-a nije, da stariju omladinu, koja može da savlada C ili bilo koji drugi jezik, "poštedi napora" - pogotovo ne pojedince koji razmišljaju o karijeri u programiranju.

Ako ste neko ko ima 9 ili 10 godina (recimo da bi to bila donja starosna granica za ulazak u svet programiranja), i pri tom zamišljate kako bi bilo lepo započeti upoznavanje sa programiranjem uz Python, kažemo - samo napred. :)

Ako ste malo stariji, smatramo da ćete najbolje rezultate postići (pod uslovom da ne želite odmah da se bacite na C, što i dalje preporučujemo), tako što ćete prve korake napraviti preko Python-a, i potom, već posle izvesnog broja nedelja (ili posle nekoliko desetina napisanih programa i sl), preći na izučavanje C-a.

Međutim, ako ste neko ko je skoro duplo stariji od prve kategorije (tj. neko čija se sposobnost da savlada osnove C-a ne dovodi u pitanje), pri tom već znate da želite da se bavite programiranjem, odnosno, učite programiranje da biste postali programer a ne iz puke razonode .... razmislite dobro o tome da li zaista želite da učite programiranje uz jezik koji će previše toga raditi umesto vas (odnosno, razmislite o tome koliko zapravo možete naučiti uz 'lakši pristup').

Primetili ste, verovatno, da (iole ozbiljniji) sportski treneri "vole da dosađuju" mladim sportistima time što insistiraju na napornim fizičkim vežbama i trčanju - pre nego što se uopšte započne sa razvojem sportske veštine (i pri tom osnovne vežbe (za)uvek ostaju deo treninga). "Možda" je tako - zato što je jasno da bez dobre kondicije nema uspešnog bavljenja sportom?!

Otkrićemo vam "tajnu" - za programiranje je takođe potrebna kondicija! Ne ista kondicija koja je potrebna sportistima (mada, ako nas pitate, i sportska kondicija sasvim dobro dođe :)), već mentalna kondicija, koja se stiče trudom, radom, sagledavanjem i pisanjem velikog broja programa (pri čemu se izazovi ne izbegavaju, već - savlađuju, i pri čemu se radnje ne obavljaju mehanički, već, sa razumevanjem) - što sve proističe iz ljubavi koju neko gaji prema programiranju.

Ako ne spadate u mlađe kategorije - nemojte sebe previše štedeti. Nikako se nemojte naprezati preko mere (nema svrhe; morate se takođe i 'odmarati i obnavljati'), ali - jednostavno rečeno - nemojte dozvoliti da vas lenjost prevlada! :)

Krajnji izbor (naravno) - ostavljamo vama.

Autor članka Nikola Vukićević Za web portal codeblog.rs
Napomena: Tekstovi, slike, web aplikacije i svi ostali sadržaji na sajtu codeblog.rs (osim u slučajevima gde je drugačije navedeno) predstavljaju intelektualnu svojinu autora sajta codeblog.rs i zabranjeno je njihovo korišćenje na drugim sajtovima i štampanim medijima, kao i bilo kakvo drugo korišćenje u komercijalne svrhe, bez eksplicitnog pismenog odobrenja autora.
© 2020-2026. Sva prava zadržana.
Facebook LinkedIn Twitter Viber WhatsApp E-mail
početna > Članci > Izbor prvog programskog jezika
codeBlog codeBlog
Sajt posvećen popularizaciji kulture i veštine programiranja.
Napomena: Tekstovi i slike na sajtu codeblog.rs (osim u slučajevima, gde je drugačije navedeno) predstavljaju intelektualnu svojinu autora sajta codeblog.rs i zabranjeno je njihovo korišćenje na drugim sajtovima i štampanim medijima, kao i bilo kakvo drugo korišćenje u komercijalne svrhe, bez eksplicitnog odobrenja autora.
© 2020-2026. Sva prava zadržana.
Facebook - logo
Instagram - logo
LinkedIn - logo
Twitter - logo
E-mail
Naslovna
   •
Uslovi korišćenja
   •
Obaveštenja
   •
FAQ
   •
Kontakt