Strukture podataka i algoritmi 1

SPA1 - Vežbe 1

O Linux-u

Linux je besplatan operativni sistem otvorenog koda (open source), koji se temelji na Unix filozofiji. Osnovan je 1991. godine od strane Linusa Torvaldsa i od tada je postao jedan od najpopularnijih operativnih sistema, posebno među entuzijastima, programerima i organizacijama koje cene slobodu i fleksibilnost.

Ono što čini Linux tako jedinstvenim je njegova distribuirana priroda. Postoji mnogo verzija ili distribucija Linuxa, svaka sa svojim karakteristikama, ciljevima i zajednicom korisnika. Ove distribucije mogu varirati od veoma stabilnih i sigurnih, do onih koje su prilagođene specifičnim potrebama ili koje su fokusirane na određene vrste korisnika.

Neke od najpoznatijih distribucija Linuxa uključuju:

  1. Ubuntu: Jedna od najpopularnijih distribucija, poznata po svojoj jednostavnosti upotrebe i širokoj podršci zajednice. Ubuntu je često izbor za početnike.

  2. Debian: Stabilna i pouzdana distribucija koja se koristi kao osnova za mnoge druge distribucije. Početci Ubuntu-a su u Debianu.

  3. Fedora: Ova distribucija se često koristi za razvoj softvera i tehnološke inovacije. Poznata je po brzim ažuriranjima i podršci novim tehnologijama.

  4. CentOS: Osnovana na temelju izvornih izvora Red Hat Enterprise Linux-a (RHEL), CentOS je stabilna distribucija često korišćena u serverskom okruženju.

  5. Arch Linux: Distribucija koja naglašava minimalizam i kontrolu nad sistemom. Namijenjena je naprednim korisnicima koji vole prilagođavanje sistema prema svojim potrebama.

  6. Linux Mint: Fokusirana na jednostavnost upotrebe i estetiku, Linux Mint je popularan među korisnicima koji traže sličnost sa tradicionalnim operativnim sistemima poput Windows-a.

Ove distribucije su samo neki od primera bogatog ekosistema Linuxa. Bez obzira na to koje distribucije koristite, Linux pruža pouzdanost, sigurnost i slobodu koja omogućava korisnicima da prilagode svoje iskustvo prema svojim potrebama i preferencijama.

Terminal

Terminal je program koji omogućava korisniku interakciju sa operativnim sistemom putem tekstualnog interfejsa.

Kroz terminal, korisnici mogu izvršavati komande i komunicirati sa operativnim sistemom koristeći tekstualne komande. Terminal omogućava korisnicima da pokreću aplikacije, manipulišu fajlovima i direktorijumima, pristupaju mrežnim resursima, pokreću procese i još mnogo toga, sve putem komandne linije.

Terminal pruža fleksibilnost i moć korisnicima koji su vešti u korišćenju komandne linije, i često se koristi u programiranju, administraciji sistema, istraživanju i razvoju softvera.

Iako su graficki korisnički interfejsi postali dominantni, posebno među početnicima, terminal i dalje ostaje važan alat za naprednije korisnike koji cene njegovu efikasnost i moć.

Osnovne Linux komande

man komanda

man komanda je skraćenica za “manual” (uputstvo) i koristi se na Linux operativnim sistemima, kako bi se dobila dokumentacija o različitim komandama i sistemskim funkcijama.

Kada se koristi man komanda, korisnik može dobiti detaljne informacije o korišćenju i opcijama za bilo koju drugu komandu ili sistemsku funkciju. Na primer, ukucavanjem man ls, korisnik dobija priručnik koji opisuje sve opcije i argumente koji se mogu koristiti sa komandom ls (koja se koristi za listanje sadržaja direktorijuma).

Priručnici koji se prikazuju pomoću man komande obično su organizovani u sekcije, pri čemu svaka sekcija sadrži dokumentaciju za određeni aspekt sistema ili komponente. Na primer, prva sekcija obično sadrži opšte komande, dok sekcija pet obično sadrži informacije o konfiguracionim datotekama.

man komanda je ključni alat za svakog korisnika Linux sistema koji želi da sazna više o različitim sistemskim funkcijama i komandama direktno iz terminala, bez potrebe za traženjem online dokumentacije.

help opcija

--help je opcija koja se često koristi uz različite komande i programi na Linux operativnim sistemima. Kada se ova opcija dodaje uz komandu prilikom njenog korišćenja, program obično prikazuje kratku pomoćnu poruku koja opisuje kako koristiti tu komandu, koje su dostupne opcije i kako ih koristiti.

Opcija --help obično pruža korisniku osnovne informacije o korišćenju komande, uključujući sintaksu, argumente, opcije i njihova značenja. Ovo je korisno za brzo upoznavanje sa funkcionalnostima komande ili programu bez potrebe za pregledanjem detaljne dokumentacije.

Na primer, ukoliko korisnik želi da sazna kako koristiti komandu ls, može je pozvati sa opcijom --help tako što će ukucati ls --help u terminalu. Ovo će rezultirati prikazivanjem kratkog pregleda kako koristiti ls komandu, kao i spiska dostupnih opcija i njihovih opisa.

Opcija --help je korisna za brzo pronalaženje informacija o korišćenju komandi ili programa direktno iz terminala, što olakšava korisnicima da efikasno koriste različite alate i funkcije operativnog sistema.

pwd komanda

pwd je akronim za “print working directory”. To je komanda na Linux operativnim sistemima, koja se koristi za prikazivanje trenutnog radnog direktorijuma u terminalu. Kada se izvrši pwd komanda, terminal će prikazati putanju do trenutnog direktorijuma u kojem se korisnik nalazi. Ova informacija je korisna za orijentaciju u sistemu i za rad sa datotekama i direktorijumima.

ls komanda

ls je komanda na Linux operativnim sistemima, koja se koristi za listanje sadržaja direktorijuma. Kada se izvrši ls komanda u terminalu, sistem prikazuje popis svih datoteka i poddirektorijuma koji se nalaze u trenutnom radnom direktorijumu. Ova komanda omogućava korisnicima da vide koje datoteke i direktorijumi postoje u trenutnom direktorijumu, što je korisno za navigaciju po sistemu, pretraživanje fajlova ili rad sa njima. Opciono, ls komanda može biti korišćena sa različitim argumentima kako bi se prilagodio način na koji se prikazuju informacije, na primer, sortiranje po vremenu kreiranja ili veličini datoteke.

Opcije:

Putanje

Na Linux-u operativnim sistemima, putanje se koriste za lociranje datoteka i direktorijuma u sistemu fajlova. Postoje dva osnovna tipa putanja: relativne i apsolutne.

  1. Relativne putanje:
    • Relativne putanje se odnose na lokaciju datoteke ili direktorijuma u odnosu na trenutni radni direktorijum (cwd - current working directory).
    • Kada koristite relativnu putanju, oslanjate se na trenutni kontekst u kojem se nalazi terminal.
    • Na primer, ako se trenutno nalazite u direktorijumu /home/korisnik/, relativna putanja dokumenti/ ili dokumenti vodi do direktorijuma dokumenti unutar trenutnog direktorijuma.
  2. Apsolutne putanje:
    • Apsolutne putanje se odnose na tačnu lokaciju datoteke ili direktorijuma u odnosu na korenski direktorijum (/).
    • One počinju sa korenskim direktorijumom i navode potpunu putanju do ciljnog fajla ili direktorijuma.
    • Na primer, apsolutna putanja /home/korisnik/dokumenti/ vodi do direktorijuma dokumenti unutar korisnik direktorijuma u korenskom direktorijumu.

Određivanje da li je putanja relativna ili apsolutna može biti ključno, posebno kada koristite skripte ili kada se krećete između različitih direktorijuma. Korišćenje relativnih putanja može biti praktično za organizaciju datoteka unutar istog projekta ili direktorijuma, dok su apsolutne putanje korisne kada želite tačno odrediti lokaciju bez obzira na trenutni kontekst.

U Linux-u, pored relativnih i apsolutnih putanja, postoje i specijalne putanje koje se koriste za referenciranje trenutnog direktorijuma (.) i roditeljskog direktorijuma (..).

  1. . (trenutni direktorijum):
    • . se odnosi na trenutni radni direktorijum u kojem se nalazi korisnik.
    • Ova putanja se koristi kada želite da se odnosi na trenutni direktorijum u nekom kontekstu.
    • Na primer, ako se nalazite u direktorijumu /home/korisnik/, putanja ./dokumenti/ ili ./dokumenti vodi do direktorijuma dokumenti unutar trenutnog direktorijuma.
  2. .. (roditeljski direktorijum):
    • .. se odnosi na direktorijum koji je roditelj trenutnog radnog direktorijuma.
    • Ova putanja se koristi kada želite da se vratite jedan korak unazad u hijerarhiji direktorijuma.
    • Na primer, ako se nalazite u direktorijumu /home/korisnik/dokumenti/, putanja ../slike/ vodi do direktorijuma slike unutar roditeljskog direktorijuma /home/korisnik/.
  3. ~ (home direktorijum trenutno ulogovanog korisnika)
    • u njemu se čuvaju korisnikovi lični podaci, konfiguracione datoteke i direktorijumi
    • na fakultetu je Vaš home direktojijum /home/student, jer se logujete sa nalogom student

Korišćenje . i .. može biti korisno za navigaciju između različitih direktorijuma u terminalu, posebno kada se koristi u kombinaciji sa relativnim putanjama. Ovi simboli su deo standarda Linux fajl sistema i široko se koriste u interakciji sa direktorijumima i datotekama.

cd komanda

Komanda cd se koristi na Linux operativnim sistemima, kako bi se promenio trenutni radni direktorijum (cwd - current working directory). Radni direktorijum (engl. “working directory”) je direktorijum u kojem se trenutno nalazi korisnik ili proces u operativnom sistemu. Kada se izvršava neka komanda ili operacija koja uključuje rad sa fajlovima ili direktorijumima, operativni sistem će te operacije izvršiti u okviru trenutnog radnog direktorijuma, osim ako nije eksplicitno navedeno drugačije. “cd” je skraćenica od “change directory”.

Kada korisnik izvrši cd komandu sa odgovarajućim argumentom koji predstavlja ime ciljnog direktorijuma, sistem će promeniti trenutni radni direktorijum u taj direktorijum.

Na primer:

Kada se koristi samo cd bez ikakvog argumenta, sistem će promeniti radni direktorijum na korisnički matični direktorijum (obično /home/korisnik, gde je “korisnik” korisničko ime).

Ova komanda je osnovni alat za navigaciju kroz direktorijume u terminalu i koristi se često tokom interakcije sa sistemom fajlova.

mkdir komanda

mkdir [naziv_direktorijuma] komanda kreira novi direktorijum, ukoliko ne postoji.

rmdir komanda

rmdir [naziv_direktorijuma] komanda briše direktorijum samo ukoliko je prazan.

cp komanda

cp (skraćeno od copy) komanda se koristi za kopiranje fajlova i direktorijuma.

Primeri korićenja:

Napomena: fajl1 ne mora biti samo naziv fajla već može biti i putanja do fajla. Slično važi i za direktorijum1 i direktorijum2.

mv komanda

mv [izvor] [odrediste] (skraćeno od move) premesta fajl ili direktorijum u drugi direktorijum ili vrši preimenovanje fajla ili direktorijuma.

Primeri korićenja:

rm komanda

rm ime (skraćeno od remove) briše fajl ili direktorijum.

rm ime_fajla briše fajl ime_fajla.
rm -R ime_direktorijuma briše direktorijum ime_direktorijuma i sve njegove fajlove i poddirektorijume.

touch komanda

touch [ime-fajla] komanda kreira prazan fajl.

Vim editor

Vim je moćan tekstualni editor u terminalu. Počeo je kao poboljšana verzija editora “Vi” i postao je standardni alat za uređivanje teksta i programiranje u terminalu. Vim nudi mnoge napredne funkcije poput sintaksnog označavanja, automatskog dovršavanja, …

Ima više modova rada od, kojih ćemo napomenuti:

Kada otvorite Vim editor koristeći komandu vim naziv_fajla, editor će se prvo nalaziti u komandnom modu. U insert mod prelazite kada kliknete na dugme i. Klikom na dugme ESC prelazite iz insert moda u komandi mod.

Neke bitnije komande:

Razvojni put

Razvojni put slika

  1. Pisanje koda: Izvorni programski kod (engl. source code) je skup naredbi napisan u nekom od programskih jezika. Korisnik piše C kod koristeći tekstualni editor ili integrisano razvojno okruženje (IDE), gde definiše promenljive, funkcije, strukture podataka i logiku programa.

  2. Preprocesiranje: Korisnik koristi preprocesor (obično deo C kompajlera) koji obrađuje C kod pre samog kompajliranja. Ovo uključuje uključivanje zaglavlja, makroa, obradu direktiva #define i #include. O makroima će biti detaljnije pričano u nekoj od narednih skripti.

  3. Kompajliranje: Nakon preprocesiranja, korisnik koristi C kompajler (npr. GCC, Clang) kako bi preveo preprocesirani C kod u mašinski kôd. Ovo se obično postiže komandom poput gcc -c ime_fajla.c, koja generiše objektni fajl (ime_fajla.o). Ovaj fajl nije moguće izvršiti tj. pokrenuti ga kao proces.

  4. Linkovanje: Nakon što su svi objektni fajlovi generisani, korisnik ih linkuje zajedno kako bi formirao izvršni fajl. Ovo se obično postiže komandom poput gcc ime_fajla1.o ime_fajla2.o -o izvrsni_fajl, gde se svi potrebni objektni fajlovi dodaju kao argumenti komandi za linkovanje.

  5. Loadovanje: Kada se izvršni fajl pokrene, operativni sistem učitava njegov sadržaj u memoriju i počinje izvršavanje programa. Ovo uključuje alokaciju memorije, postavljanje pokazivača na početak izvršnog koda i izvršavanje instrukcija programa.

  6. Izvršavanje: Izvršni fajl je pokrenut i izvršava se na procesoru. Korisnik može da mu da neki ulaz, ukoliko je to predviđeno programom i da dobije neki izlaz, ukoliko je to predviđeno programom.

Kompajliranje i pokretanje izvršnog fajla

Način 1. - ovaj način ćete najčešće koristiti na vežbama i na kolokvijumu

gcc -o hello hello.c
./hello

Način 2. - neophodno je da znate ovaj način zbog testova

gcc -c hello.c # kompajliranje i kreiranje objektnog fajla
gcc -o hello hello.o # linokvanje objektnog fajla i kreiranje izvršnog fajla
./hello

Biblioteke

Linker je alat koji od jedne ili više datoteka koje sadrže objektni kod kreira jedinstveni izvršni file ili biblioteku.

Biblioteke (eng. library) su skupovi potprograma. Postoje statičke i dinamičke biblioteke.

Statičke biblioteke (najčešće imaju lib prefiks i ekstenziju .a) se koriste uprevođenju i njihov kod se neposredno ugrađuje u izvršni program.

Dinamičke biblioteke (najčešće imaju ekstenziju .so ili .dll) se ne ugrađuju u izvršni program, ali moraju biti dostupne kada se program izvršava.

Korisni linkovi

Static vs Dynamic Libraries
Static libraries in C

Podsećanje C-a

Primer 1

#include<stdio.h>

int main() {
    int x=4;
    float y=4.9;
    if((int)(y-x)) printf("%d",(int)(y+x));
    printf("%.2f\n",(float)(x+2)/x); 
    return 0;
}

Izlaz: 1.50

Objašnjenje:

4.9 - 4 = 0.9 . Kada se to kastuje u int, zaokružiće se na manji broj. Posto je u C-u 0 false, a sve različito od 0 true, uslov neće biti ispunjen i neće se ispisati (int)(y+x).

Da nije postojalo kastovanje u float ispis bi bio 1, jer bi se vršilo celobrojno deljenje. Pošto je izvršeno kastovanje (x+2) u float, biće izvršeno deljenje realnih brojeva i rezultat će biti 1.5. Pošto je u print definisano %.2f, realni broj će biti zaokružen na 2 decimale i te 2 decimale će biti ispisane.

Primer 2

#include<stdio.h>

int main() {
    int x=5,y;
    y=x++; // y = 5, x = 6
    if (y++==++x) printf ("Isti su"); // y = 5, x = 7
    else printf("Nisu isti"); 
    // y = 6, x = 7
    return 0;
}

Izlaz: Nisu isti

Objašnjenje:

y = x++; - dodeli y vrednost x i uvećaj x y++ - iskoristi vrednost y u if-u i nakon toga uvećaj y ++x - uvećaj x pa iskoristi njegovu uvećanu vrednost

Primer 3

#include <stdio.h>

int main() {
    int y = 10;
    printf("%d\n", y = 15);

    return 0;
}

Izlaz: 15

Objašnjenje:

Dodeli y vrednost 15 i odštampaj je.

Ternarni izrazi

Ternarni izrazi su izrazi u programiranju ili matematici koji uključuju tri operanda ili argumenta, obično u kontekstu ternarnog operatora. Ternarni operator je operator koji prima tri operanda i vraća vrednost zavisno od ispunjenosti nekog uslova.

U programiranju, najčešći primer ternarnog operatora je “uslovni operator” ili “ternarni operator”, koji ima oblik:

uslov ? izraz1 : izraz2

Ovde, ako je uslov tačan (true), vraća se vrednost izraz1, a ako nije, vraća se vrednost izraz2. Ovo omogućava pristup jednostavnom obliku if-else konstrukcije u jednoj liniji koda. Za razliku od if gde else deo može biti izostavljen, u ternarnom izrazu else deo ne sme biti izostavljen.

Na primer, u jeziku C:

int x = (a > b) ? a : b;

Ova linija koda postavlja vrednost promenljive x na vrednost promenljive a ako je a veće od b, a inače na vrednost promenljive b.

Ternarni izrazi mogu biti korisni kada se želi izbeći složenost ili kada je potrebno kratko izraziti logiku sa tri moguća ishoda. Međutim, preterana upotreba ternarnih izraza može dovesti do smanjenja čitljivosti koda, pa se treba koristiti sa umerenošću.

Primer 4

#include<stdio.h>

int main() {
    int k, num=30;
    k = (num>5 ? (num <=10 ? 100 : 200): 500);
    printf("%d\n", k);

    return 0;
}

Izlaz: 200

Objašnjenje:

Ovaj ternarni izlaz bi izgledao ovako kada bi se preveo koristeći if-else komandu.

if(num > 5) {
    if(num <= 10) {
        k = 100;
    } else {
        k = 200;
    }
} else {
    k = 500;
}

Pošto je vrednost num promenljive 30 ući će u then granu prvog if-a i else granu drugog if-a pa će k biti jednako 200.