1. 1. Zdravo, svete!

Podeli svoje utiske o poglavlju na anketi OVDE.

Preduslovi za rad:

Nameštena platforma za rad (Ubuntu virtuelna mašina, sa instaliranim Visual Studio Code-om i gcc kompajlerom) - podrazumevani način rada u tekstu

Alternativa 1: onlajn C kompajler
Alternativa 2: Nameštanje sličnog okruženja na Windows platformi

1.1. Nameštanje direktorijuma za rad

Pre pravljenja prvog programa, potrebno je napraviti mesto gde će se oni nalaziti. Otvoriti terminal, zatim napisati komandu:

mkdir pjisp

Zatim ukucati komandu:

ls

Koja bi trebalo da pokaže u listi direktorijuma da se kreirao novi, sa imenom pjisp.

Ući u direktorijum pjisp pomoću komande:

cd pjisp

Na terminalu bi trebalo da se ukaže da se nalazi u direkorijumu sa imenom pjisp, nešto poput:

student@ftn~/pjisp

Visual Studio Code će biti korišćen tokom celog predmeta, stoga je dobro otvoriti ga na nivou pjisp direktorijuma:

code .

Izabrati opciju "Yes, I trust the authors" prilikom otvaranja. Nakon toga, moguće je zatvoriti terminal. Visual Studio Code (u daljem tekstu VS Code) ima ugrađeni terminal, koji se može otvoriti pomoću gornjeg menija Terminal -> New Terminal.

Rezultat ls komande će biti prazan, odnosno, još uvek ne postoji nijedna datoteka ili direktorijum. Dodati direktorijum v01 na sledeći način:

mkdir v01

Proveriti sa ls komandom da li se uspešno kreirao i potom ući u njega sa komandom:

cd v01

Sada je moguće napraviti novu tekstualnu datoteku unutar direktorijuma v01 pomoću komande:

code proba.txt

Otvoriće se novi tab sa imenom proba.txt. Upisati neki tekst u njega i sačuvati (pritiskom tastera Ctrl i S ili odabirom File -> Save u gornjem meniju).

Ako ste ispratili sve ovo, spremni ste da napišete svoj prvi program!

1.2. Prvi program

Da bismo mogli da objasnimo računaru šta želimo da on uradi, potrebno je napisati tekst poštujući određena pravila. U slučaju programskog jezika C, to znači da je potrebno napraviti novu datoteku sa ekstenzijom ".c". VS Code može pomoći u tome, tako što se u terminalu ukuca sledeće:

code zdravo.c

Unutar te datoteke, potrebno je upisati sledeće:

1#include <stdio.h>
2
3int main()
4{
5    printf("Zdravo, svete!\n");
6    return 0;
7}

Kod je potrebno sačuvati. Uveriti se da je sačuvano tako što neće biti bele loptice pored imena datoteke u njenom tabu. Ovo je samo pola posla, odnosno, ovakav tekst računar još uvek ne može da razume. Da bi mogao da shvati i da izvrši ono što od njega tražimo, potrebno je prevesti rešenje na njegov jezik. To se može uraditi na sledeći način:

gcc zdravo.c

gcc je program, koji će pokušati da ono što smo napisali na jeziku koji je ljudima razumljiv da prevede u jezik mašinskih komandi koje računar razume. Rezultat tog prevođenja je nova, izvršna datoteka, koju računar zna da pokrene. U našem slučaju, ona će imati ime a.out. Stvari koje mogu poći po zlu:

Ukoliko se datoteka a.out nije pojavila, pogledati da li je prethodna gcc komanda proizvela neki ispis.
Ukoliko jeste, verovatno je došlo do "sintaksne greške", odnosno kod nije napisan po pravilima koje traži programski jezik C.
Ovo se rešava tako što se datoteka zdravo.c ispravi na osnovu sugestija koje je ispisao gcc.

gcc neće proizvesti nikakav ispis ukoliko je kod napisan kako treba!

a.out se pokreće iz Terminala, na sledeći način:

./a.out

Rezultat koji bi trebalo nakon toga da se vidi na ekranu terminala je:

Zdravo, svete!

Napomena:

Ono što je potrebno da program ispiše prosleđuje se printf naredbi oivičeno navodnicima (").
Unutar njega moguće je dati posebne instrukcije, gde je najčešće korišćen prelazak u novi red, \n.
Kao što se vidi iz primera, neće se ispisati \n, već će se tad desiti prelazak u novi red.

Napomena:

main predstavlja funkciju koju svaki izvršni program mora da ima.
Piše se uvek na isti način, int na početku, obične, pa vitičaste zagrade, sa return 0 naredbom.
Sve navedeno ima svoje značenje, koje će biti navedeno u kasnijim poglavljima.

1.3. Standardni ulaz/izlaz

U prethodnom primeru korišćena je funkcija printf kako bi se tekst pod navodnicima ispisao na ekranu terminala. To je podrazumevano ponašanje prilikom ispisa teksta, stoga se ekran terminala zove standardni izlaz.

Postavlja se pitanje kakoje moguće uneti vrednosti na neki način u program. Podrazumevani način je putem tastature korisnika, odnosno, to predstavlja standardni ulaz. Funkcija koja se koristi u te svrhe naziva se scanf i koristi se na sledeći način:

 1#include <stdio.h>
 2
 3int main()
 4{
 5    int broj;
 6
 7    printf("Unesite broj: ");
 8    scanf("%d", &broj);
 9
10    printf("Uneti broj je: %d\n", broj);
11
12    return 0;
13}

Sačuvati datoteku i kompajlirati rešenje na isti način kao što je to navedeno iznad.

Nakon uspešnog kompajliranja, pokrenuti dobijenu izvršnu datoteku a.out. Program će se zaustaviti nakon ispisa "Unesite broj: " i čekaće. Uneti celobrojnu vrednost i pritisnuti enter kako bi se završilo izvršavanje programa.

Primer rada programa:

Unesite broj: 42
Uneti broj je: 42

Ono što se može primetiti u primeru je da se broj koristi i kod scanf i kod printf naredbe. broj predstavlja promenljivu u programu. One se mogu tretirati kao "kućice" u memoriji određene veličine (izražene u bajtovima). Svaka promenljiva ima svoje jedinstveno ime (u primeru broj) i svoj tip (u primeru je int, skraćeno od "integer", što je u prevodu celobrojni tip). Promenljive se koriste za skladištenje podataka u programu. U njih se mogu upisivati vrednosti, može im se dodeliti rezultat nekog izraza i po potrebi se mogu ispisati.

Funkcija scanf upisuje vrednost koju smo uneli preko tastature u promenljivu broj. Da bi to mogla da ostvari, potrebno je navesti adresu promenljive u memoriji u koju upisujemo vrednost, a ona dobija tako što stavimo & ispred imena promenljive.

Primećuje se %d i u scanf i u printf. Pošto nije poznato unapred koja će vrednost promenljive broj biti, ono služi kao umetak, koji govori da se na tom mestu očekuje celobrojna vrednost ("d" označava decimal, ostali tipovi imaju drugačiju vrednost).

Napomena:

printf i scanf su funkcije, koje su deo standardne biblioteke programskog jezika C.
Da bi one bile dostupne u programu, potrebno je uključiti zaglavlje gde su one definisane, što je urađeno pomoću #include <stdio.h>.

1.4. Program koji sabira dva broja

Iskoristićemo do sad stečeno znanje da napišemo jednostavan program, čija je svrha da sabere dva broja.

 1#include <stdio.h>
 2
 3int main()
 4{
 5    int prvi_broj, drugi_broj, zbir;
 6
 7    printf("Unesite prvi broj: ");
 8    scanf("%d", &prvi_broj);
 9
10    printf("Unesite drugi broj: ");
11    scanf("%d", &drugi_broj);
12
13    zbir = prvi_broj + drugi_broj;
14
15    printf("Zbir unetih brojeva je: %d\n", zbir);
16
17    return 0;
18}

Primer ispisa programa:

Unesite prvi broj: 3
Unesite prvi broj: 6
Zbir unetih brojeva je: 9

Za svaku vrednost koja se unosi sa tastature uvedene su po promenljiva (prvi_broj i drugi_broj) u kojoj će se skladištiti uneta vrednost. Pored njih, postoji i treća promenljiva, zbir, čija se vrednost ne dobija preko tastature, već kao zbir vrednosti koje se nalaze u prvi_broj i drugi_broj. Promenljiva zbir se, nakon dodele vrednosti, ispisuje na standardni izlaz pomoću funkcije printf.

Napomena:

Primetiti da se programi izvršavaju liniju po liniju iz main funkcije.
Jako je bitno da se promenljive prvo deklarišu, pa tek onda koriste.
Isto tako, ukoliko se vrednost promenljive koristi u nekom izrazu (ili za neki ispis), potrebno ju je prvo definisati.
Ukoliko se to ne učini, ponašanje programa će biti nepredvidivo.

Iz svih ovih razloga navedenih u napomeni iznad, prvo deklarišemo promenljive prvi_broj, drugi_broj i zbir. Zatim unosimo vrednosti sa tastature u prve dve promenljive i pre ispisa, postavljamo vrednost promenljive zbir.

1.5. Proveri svoje znanje

## Šta će se dogoditi ako ukucamo ```cd pjisp``` u terminalu? 1. [x] Ući ćemo u direktorijum pjisp, ukoliko on postoji u direktorijumu gde se trenutno nalazimo 1. [ ] Izlistaće se sve datoteke koje sadrže u svom imenu "pjisp" > Za ovakve stvari se koristi komanda ``ls``, na primer ``ls *pjisp*`` će izlistati sve datoteke i direktorijume u trenutnom direktorijumu koje sadrže u sebi "pjisp" 1. [ ] Napraviće se direktorijum pjisp ako ne postoji i ući će se u njega > Komanda za pravljenje direktorijuma je ``mkdir`` (skraćeno od "make directory), a ``cd`` za promenu direktorijuma (skraćeno od ``change directory``) 1. [ ] Napraviće se datoteka sa imenom "pjisp" > Za ovo se koristi komanda ``touch pjisp``, odnosno, napraviće praznu datoteku sa tim imenom, ukoliko već ne postoji ## Šta je minimalno potrebno da bi se napisani izvorni kod u programskom jeziku C smatrao izvršnim programom? 1. [x] Postojanje pravilno napisane ``main`` funkcije u izvornom kodu 1. [ ] Dovoljno je da se napiše bilo kakva naredba koja pripada C programskom jeziku > Izvorni kod bez ``main`` funkcije je biblioteka, koja može biti uključena u druge C programe 1. [ ] Barem jedna ``#include`` direktiva > Include direktiva nam služi da možemo da koristimo već napisane funkcionalnosti kako mi ne bismo morali da ih pišemo od nule (npr. funkcija za štampanje na ekran terminala, printf) 1. [ ] Sintaksno tačno napisan izvorni kod > Izvorni kod bez ``main`` funkcije je biblioteka, koja može biti uključena u druge C programe ## Kako računar "razume", odnosno, može da izvrši kod napisan u programskom jeziku C? 1. [x] Prevođenjem izvornog koda iz tekstualnog oblika u izvršnu datoteku pomoću programa koji se naziva kompajler 1. [ ] Uz pomoć posebnog programa koji se naziva interpreter, bez dodatnog prevođenja > Za čitavu klasu programskih jezika (npr. Pajton) ovo je tačna izjava, ali C se prevodi u binarni oblik pomoću kompajlera pre izvršavanja 1. [ ] Računar direktno razume i izvršava komadne iz datoteke sa izvornim kodom > Ovo nije moguće ni za jedan programski jezik, računar razume samo "nule i jedinice" 1. [ ] Pomoću terminala > Terminal nam samo pomaže da pokrenemo naš program, ništa više ## Poređaj gradivne elemente programa koji ispisuje "Zdravo svete" u redosledu u kom se pišu u datoteci sa izvornim kodom: 1. #include <stdio.h> 2. int main() 3. { 4. printf("Zdravo, svete!\n"); 5. return 0; 6. } ## Da li je sledeći kod sintaksno tačan i šta će se ispisati? ```c #include <stdio.h> int main() { int prvi_broj, drugi_broj, proizvod; proizvod = prvi_broj * drugi_broj; printf("Unesite prvi broj: "); scanf("%d", &prvi_broj); printf("Unesite drugi broj: "); scanf("%d", &drugi_broj); printf("Proizvod unetih brojeva je: %d\n", proizvod); return 0; } ``` 1. [x] Jeste, ali njegovo ponašanje je nedefinisano > Ponašanje je nedefinisano, jer u artimetičkom izrazu učestvuju promenljive bez prethodno dodeljene vrednosti 1. [ ] Sintaksno je tačan, program množi dva broja i ispisuje rezultat > Ovo bi bilo tačno, da množenje ide nakon što su ``prvi_broj`` i ``drugi_broj`` dobili vrednost (posle ``scanf`` naredbi) 1. [ ] Program je sintaksno netačan > Kompajlirati program. Ukoliko ``gcc`` naredba ne pokaže nikakav ispis i napravi datoteku ``./a.out``, program je sintaksno tačan 1. [ ] Sintaksno je tačan, ali će se preskočiti unos brojeva prilikom izvršavanja > Ovo nije tačno, jer se sve naredbe izvršavaju redom u ``main`` funkciji, ovako kako je program napisan