C C vodic / Patrick Surlan

Moj C vodic.

Pisao sam ovo dok sam ucio C u srednjoj skoli. Pomoglo mi je da slozim sve u glavi, mozda ti pomogne isto. Svaka linija koda objasnjenja od pocetka, nema preskakanja.

lekcija 01

Tvoj prvi program

Ovo je Hello World. Svi pocinju s ovim, bez iznimke. Pet linija koda koje ces znati napamet do kraja tjedna jer ces ih pisati sto puta. Kopiraj, pokreni, vidi da radi — pa cemo objasniti svaku liniju ispod.

C
#include <stdio.h>

int main() {
    printf("Zdravo, svijete!\n");
    return 0;
}
Objasnjenje — linija po linija
Linija 1
Uvozi biblioteku stdio.h bez koje printf ne radi. Stavljaj ovo na vrh gotovo svakog programa.
Linija 3
Svaki C program mora imati main — od tuda pocinje izvrsavanje. int ispred znaci da funkcija vraca broj. Sve unutar { } je tijelo funkcije.
Linija 4
printf ispisuje tekst. Tekst mora biti u navodnicima. \n je novi red. Na kraju obavezno ; — vrijedi za svaku naredbu u C-u.
Linija 5
return 0; govori OS-u da je program zavrsio bez gresaka. 0 = sve ok.
C — printf primjeri
#include <stdio.h>

int main() {
    // Ispis teksta
    printf("Ime: Ana\n");
    printf("Dob: %d godina\n", 17);
    printf("Visina: %.2f m\n", 1.68);
    printf("Slovo: %c\n", 'A');

    // Vise vrijednosti u jednom printf
    printf("%s ima %d godina i visoka je %.1f m\n", "Ana", 17, 1.68);

    // Escape sekvence
    printf("Red 1\nRed 2\nRed 3\n");
    printf("Stupac1\tStupac2\tStupac3\n");

    return 0;
}
Specifikatori formata
%d
Cijeli broj (int). Npr. printf("%d", 42) ispisuje 42.
%f
Decimalni broj (float/double). %.2f ispisuje s tocno 2 decimale.
%c
Jedan znak (char). printf("%c", 'A') ispisuje A.
%s
String (tekst). printf("%s", "Ana") ispisuje Ana.
Escape sekvence koje se cesto koriste:
\n — novi red  |  \t — tab  |  \\ — obrnuta kosa crta  |  \" — navodnik unutar stringa
lekcija 02

Varijable i tipovi podataka

Varijabla je kutija s imenom — u njoj spremasˇ podatak. C zahtijeva da unaprijed kazes kakav tip podatka stavljas (broj, decimalni, slovo...) i to se ne moze mijenjati nakon deklaracije.

TipVelicinaRaspon vrijednostiPrimjer
int4 bajta-2,147,483,648 do 2,147,483,64742, -7, 1000
float4 bajta~7 decimala preciznosti3.14, -1.5
double8 bajta~15 decimala preciznosti3.14159265358
char1 bajtjedan znak'A', 'z', '5'
long8 bajtaveci raspon od int9000000000
C
#include <stdio.h>

int main() {
    int godine = 20;
    float visina = 1.85;
    double pi = 3.14159265358979;
    char slovo = 'A';

    printf("Imam %d godina.\n", godine);
    printf("Visok sam %.2f metara.\n", visina);
    printf("Pi je otprilike %.10f\n", pi);
    printf("Prvo slovo: %c\n", slovo);

    return 0;
}
Objasnjenje — linija po linija
Linija 4
Deklariras varijablu int s imenom godine i odmah joj das vrijednost 20. = je dodjela, nije usporedba. Usporedba se pise ==.
Linija 5
float je decimalni broj. Za vecinu stvari sasvim ok.
Linija 7
char cuva jedan znak, uvijek u jednostrukim navodnicima. 'A' je drugacije od "A" — prvo je char, drugo je string.
Linije 9-12
Svaki tip ima svoj specifikator u printf: %d za int, %f za float/double, %c za char, %s za string. %.2f znaci ispiši s 2 decimale.
Kako imenovati varijable: koristi snake_case — sve malo, podvlaka između. Npr. broj_studenata, ukupna_cijena. Ne mozes poceti s brojem i nema razmaka.
lekcija 03

Operatori

Operatori su ono sto poznajes iz matematike plus jos neke. +, -, *, / rade kao sto mislis. Ali ima i onih koji te mogu zbuniti — posebno razlika između = i ==.

+
Zbrajanje
a + b
-
Oduzimanje
a - b
*
Mnozenje
a * b
/
Dijeljenje
a / b
%
Ostatak (modulo)
10 % 3 = 1
++
Inkrement
a++ (a = a+1)
--
Dekrement
a-- (a = a-1)
==
Jednako
a == b
!=
Nije jednako
a != b
>
Vece od
a > b
&&
Logicko I
a && b
||
Logicko ILI
a || b
C
#include <stdio.h>

int main() {
    int a = 10, b = 3;

    printf("%d + %d = %d\n", a, b, a + b);
    printf("%d - %d = %d\n", a, b, a - b);
    printf("%d * %d = %d\n", a, b, a * b);
    printf("%d / %d = %d\n", a, b, a / b);   // rezultat: 3, ne 3.33!
    printf("%d %% %d = %d\n", a, b, a % b);  // ostatak: 1

    int x = 5;
    x++;
    printf("Nakon x++: %d\n", x);  // 6

    return 0;
}
Objasnjenje
Linija 4
Mozesˇ deklarirati vise varijabli istog tipa u jednoj liniji, odvojene zarezom.
Linija 9
Dijeljenje dva int-a daje int10 / 3 = 3, ne 3.33. Ako hoces decimalni rezultat, castaj: (float)a / b.
Linija 10
% je modulo — vraca ostatak dijeljenja. Koristit ces ovo stalno, posebno za parnost: broj % 2 == 0 = parni broj.
Klasicna greska: = je dodjela, == je usporedba. Ako napises if (a = 5) umjesto if (a == 5), program se kompajlira ali radi krivo. Svaki pocetnik to napravi barem jednom.
lekcija 04

Citanje unosa — scanf

Do sada su svi programi imali unaprijed zadane podatke u kodu. U stvarnosti, program mora citati unos od korisnika. Funkcija scanf cita podatke s tipkovnice — odmah je korisna cim naucis varijable i operatore, pa dolazi ovdje, prije uvjeta i petlji.

C — osnovno citanje
#include <stdio.h>

int main() {
    int a, b;

    printf("Unesi prvi broj: ");
    scanf("%d", &a);

    printf("Unesi drugi broj: ");
    scanf("%d", &b);

    printf("\nZbroj: %d\n", a + b);
    printf("Razlika: %d\n", a - b);
    printf("Produkt: %d\n", a * b);

    if (b != 0) {
        printf("Kolicnik: %.2f\n", (float)a / b);
    } else {
        printf("Dijeljenje s nulom nije moguce.\n");
    }

    return 0;
}
Objasnjenje
Linija 7
scanf("%d", &a) — cita cijeli broj s tipkovnice i sprema ga u varijablu a. Zasto & (ampersand)? Zato sto scanf mora znati gdje u memoriji da spremi podatak. Dajemo mu adresu varijable a putem &a. Bez & program se rusi!
Linije 16-20
Provjera dijeljenja s nulom — uvijek provjeri da dijelilac nije nula. Dijeljenje s nulom je undefined behavior u C-u.
C — mini kalkulator
#include <stdio.h>

int main() {
    float a, b;
    char operacija;

    printf("=== Mini kalkulator ===\n");
    printf("Unesi racun (npr. 5 + 3): ");
    scanf("%f %c %f", &a, &operacija, &b);

    printf("%.2f %c %.2f = ", a, operacija, b);

    switch (operacija) {
        case '+': printf("%.2f\n", a + b); break;
        case '-': printf("%.2f\n", a - b); break;
        case '*': printf("%.2f\n", a * b); break;
        case '/':
            if (b != 0) printf("%.2f\n", a / b);
            else printf("Greska: dijeljenje s nulom\n");
            break;
        default:
            printf("Nepoznata operacija.\n");
    }

    return 0;
}
scanf s vise vrijednosti + switch
Linija 9
scanf("%f %c %f", &a, &operacija, &b) — cita tri vrijednosti odjednom: float, char i float. Format stringa definira sto se ocekuje.
Linije 13-23
switch — elegantnija alternativa dugom if-else if lancu kad usporedujemo jednu varijablu s vise mogucih vrijednosti. break izlazi iz switch bloka, default hvata sve ostalo.
scanf specifikatori:
%d — int  |  %f — float  |  %lf — double  |  %c — char  |  %s — string (bez razmaka)
Uvijek stavljaj & ispred varijable, osim kod stringa!
lekcija 05

Uvjetni iskazi — if / else

if / else je kako program donosi odluke. Ako je uvjet tocan, izvrsi jedno — inace drugo. U C-u nema pravog bool tipa: 0 je false, sve ostalo (1, -5, 42...) je true.

C
#include <stdio.h>

int main() {
    int rezultat = 75;

    if (rezultat >= 90) {
        printf("Odlican (5)\n");
    } else if (rezultat >= 75) {
        printf("Vrlo dobar (4)\n");
    } else if (rezultat >= 60) {
        printf("Dobar (3)\n");
    } else if (rezultat >= 50) {
        printf("Dovoljan (2)\n");
    } else {
        printf("Nedovoljan (1)\n");
    }

    int broj = 7;
    if (broj % 2 == 0) {
        printf("%d je paran broj.\n", broj);
    } else {
        printf("%d je neparan broj.\n", broj);
    }

    return 0;
}
Objasnjenje
Linije 6-16
C provjerava uvjete redom odozgo. Cim nade prvi koji je tocan, izvrsi ga i preskoce ostatak. else na kraju hvata sve sto nije proslo ni jedan uvjet.
Linija 19
broj % 2 == 0 je standardni nacin provjere parnosti. Koristit ces ovo cesto.
C — logicki operatori
#include <stdio.h>

int main() {
    int dob = 22;
    int ima_vozacku = 1;  // 1 = true, 0 = false

    // && = I (oba uvjeta moraju biti istinita)
    if (dob >= 18 && ima_vozacku) {
        printf("Moze voziti.\n");
    }

    // || = ILI (barem jedan uvjet mora biti istinit)
    int je_vikend = 0;
    int je_praznik = 1;
    if (je_vikend || je_praznik) {
        printf("Ne radi se!\n");
    }

    // ! = negacija
    int je_zatvoren = 0;
    if (!je_zatvoren) {
        printf("Ducan je otvoren.\n");
    }

    return 0;
}
Logicki operatori
&& (AND)
I jedan I drugi uvjet moraju biti tocni. Tocan samo ako su oba zadovoljena.
|| (OR)
Dovoljno je da jedan uvjet bude tocan. Vikend ili praznik (ili oboje) — sve prolazi.
! (NOT)
Obrice true/false. !je_zatvoren = nije zatvoren = otvoren je.
lekcija 06

for petlja

Petlja ponavlja blok koda. Bez petlji, za ispis 100 redova trebas 100 linija. S petljom, trebas 3. for koristis kada znas tocno koliko puta ponavljati.

1
Postavi brojac — jednom, na pocetku. Npr. int i = 0
2
Provjeri uvjet — radi li se jos? Ako ne, stani. Npr. i < 10
3
Izvrsi kod — ono sto hoces ponoviti, unutar { }
4
Pomakni brojac — npr. i++ — pa nazad na korak 2
C — osnovni for
#include <stdio.h>

int main() {
    // Ispis brojeva od 1 do 5
    for (int i = 1; i <= 5; i++) {
        printf("Broj: %d\n", i);
    }

    printf("---\n");

    // Zbrajanje od 1 do 100
    int suma = 0;
    for (int i = 1; i <= 100; i++) {
        suma += i;
    }
    printf("Suma 1 do 100 = %d\n", suma);  // 5050

    return 0;
}
Objasnjenje
Linija 5
Tri dijela odvojena s ;: 1) int i = 1 — postavi brojac, jednom. 2) i <= 5 — provjera pred svaki prolaz. 3) i++ — pomak nakon svakog prolaza.
Linija 14
suma += i je skraceni zapis za suma = suma + i. Nakon svakog prolaza dodamo trenutni i na ukupnu sumu.
C — napredni for
#include <stdio.h>

int main() {
    // Odbrojavanje
    for (int i = 5; i >= 1; i--) {
        printf("%d... ", i);
    }
    printf("Start!\n\n");

    // Korak od 2 (samo parni)
    printf("Parni od 2 do 10: ");
    for (int i = 2; i <= 10; i += 2) {
        printf("%d ", i);
    }
    printf("\n");

    return 0;
}
break i continue:
break — odmah izlazi iz petlje.
continue — preskace trenutni prolaz i ide na sljedeci.
Npr. if (i == 3) continue; — sve normalno osim broja 3 koji se preskace.
lekcija 07

while petlja

while koristis kad ne znas unaprijed koliko ponavljanja treba — samo znas uvjet. Npr. ponavljaj dok je igrac ziv, citaj dok ima podataka, pitaj korisnika dok ne unese nesto ispravno.

1
Provjeri uvjet — odmah na pocetku. Ako je false od starta, unutrasnjost se ne izvrsi ni jednom.
2
Izvrsi kod — sto je unutar { }
3
Vrati se na korak 1 — provjeri uvjet opet i ponavljaj.
C — while petlja
#include <stdio.h>

int main() {
    // Dijeli broj s 2 dok ne postane manji od 1
    int broj = 100;
    printf("Pocetni broj: %d\n", broj);

    while (broj >= 1) {
        printf("%d -> ", broj);
        broj = broj / 2;
    }
    printf("kraj\n\n");

    // Digitalna suma broja (zbroj znamenki)
    int n = 12345;
    int suma = 0;

    while (n > 0) {
        int znamenka = n % 10;  // izvuci zadnju znamenku
        suma += znamenka;
        n = n / 10;             // ukloni zadnju znamenku
    }
    printf("Suma znamenki broja 12345: %d\n", suma);  // 15

    return 0;
}
Objasnjenje
Linija 10
broj = broj / 2 — ovo je korak koji mijenja stanje. Bez ovoga, broj se nikad ne bi promijenio i dobili bismo beskonacnu petlju. Uvijek se pitaj: "Sto mijenjam unutar petlje da bi uvjet jednom postao lazan?"
Linija 19
n % 10 je trik za izvlacenje zadnje znamenke. 12345 % 10 = 5. Zatim n / 10 = 1234 brise zadnju znamenku.
C — do-while
#include <stdio.h>

int main() {
    int broj;

    // Trazi unos dok korisnik ne unese pozitivan broj
    do {
        printf("Unesi pozitivan broj: ");
        scanf("%d", &broj);
        if (broj <= 0) {
            printf("Krivo! Mora biti > 0.\n");
        }
    } while (broj <= 0);

    printf("Unio si: %d\n", broj);
    return 0;
}
do-while vs while
Kljucna razlika
do {} izvodi tijelo barem jednom bez obzira na uvjet. Savrseno za validaciju unosa — uvijek moraš pitati korisnika barem jednom.
Linija 12
} while (uvjet); — jedina petlja u C-u koja zahtijeva ; iza zatvorene zagrade.
Kada koristiti koje?
for — znas tocan broj ponavljanja (petlja N puta)
while — ne znas broj ponavljanja, provjera je na pocetku
do-while — tijelo mora izvesti barem jednom, provjera na kraju
lekcija 08

Kombinacije petlji

Petlje postaju puno mocnije kad ih kombiniras — petlja unutar petlje, uvjeti unutar petlji, for i while zajedno. Ovo su uzorci koje ces koristiti stalno na testovima i u prakticnom radu.

C — tablica mnozenja
#include <stdio.h>

int main() {
    printf("Tablica mnozenja (1-5):\n\n");
    printf("    ");
    for (int j = 1; j <= 5; j++) printf("%4d", j);
    printf("\n    --------------------\n");

    for (int i = 1; i <= 5; i++) {
        printf("%2d |", i);               // ispisi red-oznaku
        for (int j = 1; j <= 5; j++) {
            printf("%4d", i * j);         // unutarnja petlja: stupci
        }
        printf("\n");                     // kraj retka
    }

    return 0;
}
Kako rade ugnjezdene petlje
Vanjska petlja
Kontrolira redak (varijabla i). Za svaki i, unutarnja petlja prolazi kroz sve stupce.
Unutarnja petlja
Kontrolira stupac (varijabla j). Prolazi svih 5 vrijednosti za svaki jedan prolaz vanjske petlje. Ukupno: 5 x 5 = 25 izvrsavanja.
%4d
Ispisuje broj u polju od 4 znaka s desnim poravnanjem — koristno za poravnanje stupaca u tablicama.
C — trokut i piramida
#include <stdio.h>

int main() {
    int n = 5;

    // Desni trokut
    printf("Desni trokut:\n");
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= i; j++) {
            printf("* ");
        }
        printf("\n");
    }

    printf("\n");

    // Piramida (centrirana)
    printf("Piramida:\n");
    for (int i = 1; i <= n; i++) {
        // Ispis razmaka za centriranje
        for (int j = 0; j < n - i; j++) {
            printf(" ");
        }
        // Ispis zvjezdica
        for (int j = 0; j < 2 * i - 1; j++) {
            printf("*");
        }
        printf("\n");
    }

    return 0;
}
Logika uzoraka
Desni trokut
Red i ispisuje tocno i zvjezdica. Linija 1 → 1 zvjezdica, linija 2 → 2 zvjezdice, itd. Unutarnja petlja ide od 1 do i.
Piramida
Svaki red treba (a) razmake za centriranje i (b) zvjezdice. Red i ima n-i razmaka i 2*i-1 zvjezdica. Provjeri: red 1 = 4 razmaka + 1 zvjezdica, red 5 = 0 razmaka + 9 zvjezdica.
C — trazenje prostih brojeva
#include <stdio.h>

int main() {
    int gornja_granica = 30;

    printf("Prosti brojevi do %d:\n", gornja_granica);

    for (int n = 2; n <= gornja_granica; n++) {
        int je_prost = 1;  // pretpostavi da je prost

        // Provjeri sve djelitelje od 2 do n-1
        for (int d = 2; d < n; d++) {
            if (n % d == 0) {
                je_prost = 0;  // nasao djeljitelja, nije prost
                break;         // nema smisla dalje provjeravati
            }
        }

        if (je_prost) {
            printf("%d ", n);
        }
    }
    printf("\n");

    return 0;
}
Uzorak: zastavica (flag)
int je_prost
Zastavica (flag) — varijabla koja prati neko stanje. Postavljamo je na 1 (pretpostavljamo da je prost), a ako nademo djeljitelja, gasimo je na 0. Na kraju provjeravamo zastavicu.
break
Cim nademo jednog djeljitelja, mozemo stati — nije prost i nema smisla traziti dalje. break izlazi samo iz unutarnje petlje, vanjska se nastavlja.
C — pretraga i sortiranje
#include <stdio.h>

int main() {
    int ocjene[6] = {3, 5, 2, 4, 5, 3};
    int n = 6;

    // Ispis niza
    printf("Ocjene: ");
    for (int i = 0; i < n; i++) printf("%d ", ocjene[i]);
    printf("\n");

    // Pronalazak pozicije prve maksimalne ocjene
    int max = ocjene[0];
    int pozicija = 0;
    for (int i = 1; i < n; i++) {
        if (ocjene[i] > max) {
            max = ocjene[i];
            pozicija = i;
        }
    }
    printf("Maksimalna ocjena %d je na poziciji %d\n", max, pozicija);

    // Bubble sort (razvrstavanje od najmanjeg prema najvecem)
    printf("\nSortiranje (bubble sort):\n");
    int promjena = 1;
    while (promjena) {
        promjena = 0;  // pretpostavi da nema zamjene
        for (int i = 0; i < n - 1; i++) {
            if (ocjene[i] > ocjene[i + 1]) {
                // Zamjena elemenata
                int temp = ocjene[i];
                ocjene[i] = ocjene[i + 1];
                ocjene[i + 1] = temp;
                promjena = 1;  // bila je zamjena, treba jos jedan prolaz
            }
        }
    }

    printf("Sortirano: ");
    for (int i = 0; i < n; i++) printf("%d ", ocjene[i]);
    printf("\n");

    return 0;
}
Bubble sort — while + for zajedno
while (promjena)
while kontrolira "prolaze kroz niz" — ne znamo unaprijed koliko prolaza treba. Ponavljamo dok god u zadnjem prolazu bude barem jedna zamjena.
for unutar while
for prolazi kroz parove susjednih elemenata. Ako je lijevi veci od desnog, zamijeni ih. Nakon cijelog prolaza, ako nije bilo ni jedne zamjene, niz je sortiran.
Zamjena
Klasicni uzorak zamjene: treba privremena varijabla temp. Bez nje, izgubio bi jednu vrijednost.
Kad koristiti ugnjezdene petlje:
• Obrada 2D podataka (tablice, matrice, uzorci)
• Usporedba svakog elementa sa svakim (sortiranje, trazenje)
• Generiranje kombinacija ili permutacija
Paznja: dvije ugnjezdene petlje do N = N² operacija. Tri ugnjezdene = N³. Brzo raste!
lekcija 09

Funkcije

Funkcija je imenovan blok koda koji radi odredenu zadacu. Umjesto da isti kod pises na 10 mjesta, napises ga jednom kao funkciju i pozoves je gdje god trebas. Dobar program je skup malih, jasnih funkcija.

C
#include <stdio.h>

// Funkcija koja prima dva broja i vraca njihov zbroj
int zbroji(int a, int b) {
    return a + b;
}

// Funkcija bez povratne vrijednosti (void)
void ispisi_liniju(int duljina) {
    for (int i = 0; i < duljina; i++) {
        printf("-");
    }
    printf("\n");
}

// Rekurzivna funkcija za faktorijel
int faktorijel(int n) {
    if (n <= 1) return 1;
    return n * faktorijel(n - 1);
}

int main() {
    int x = 8, y = 3;
    printf("%d + %d = %d\n", x, y, zbroji(x, y));

    ispisi_liniju(20);

    printf("5! = %d\n", faktorijel(5));
    printf("7! = %d\n", faktorijel(7));

    return 0;
}
Objasnjenje
Linija 4
int zbroji(int a, int b) — anatomija funkcije: int = povratni tip, zbroji = ime, (int a, int b) = parametri s tipovima.
Linija 9
void ispisi_linijuvoid znaci da funkcija ne vraca nikakvu vrijednost. Koristi se za funkcije koje samo "rade nesto".
Linije 17-19
Rekurzija — funkcija koja poziva samu sebe. faktorijel(5) = 5 * faktorijel(4) = ... dok ne dode do faktorijel(1) = 1. Svaka rekurzija mora imati bazni slucaj koji zaustavi pozivanje!
lekcija 10

Nizovi (Arrays)

Niz je kolekcija varijabli istog tipa smjestena uzastopno u memoriji. Umjesto 5 zasebnih varijabli ocjena1, ocjena2, ..., imas jedan niz ocjene[5]. Svi elementi su dostupni putem indeksa koji pocinje od 0.

C
#include <stdio.h>

int main() {
    int ocjene[5] = {4, 3, 5, 4, 5};

    // Ispis svakog elementa
    for (int i = 0; i < 5; i++) {
        printf("Ocjena %d: %d\n", i + 1, ocjene[i]);
    }

    // Pronalazak maksimuma
    int max = ocjene[0];
    for (int i = 1; i < 5; i++) {
        if (ocjene[i] > max) max = ocjene[i];
    }
    printf("Maksimalna ocjena: %d\n", max);

    // Izracun prosjeka
    int suma = 0;
    for (int i = 0; i < 5; i++) suma += ocjene[i];
    printf("Prosjek: %.1f\n", (float)suma / 5);

    return 0;
}
Objasnjenje
Linija 4
int ocjene[5] = {4, 3, 5, 4, 5}; — deklaracija i inicijalizacija. Elementi su: ocjene[0]=4, ocjene[1]=3... Indeks pocinje od 0! Zadnji element je ocjene[4], ne ocjene[5].
Linije 12-15
Nalazenje maksimuma — pretpostavi da je prvi element max, zatim prodi kroz ostale i azuriraj ako nades nesto vece. Klasican algoritam.
Linija 21
(float)suma / 5 — cast pretvara suma u float przed dijeljenjem, da dobijemo decimalni rezultat. Bez toga: 21 / 5 = 4, ne 4.2.
lekcija 11

Stringovi

U C-u ne postoji poseban tip za tekst — string je zapravo niz znakova (char array) koji zavrsava specijalnim znakom '\0' (null terminator). To je jedini nacin da funkcije znaju gdje string zavrsava.

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

int main() {
    char ime[50] = "Ana";
    char prezime[50] = "Kovac";
    char puno_ime[100];

    // Spajanje stringova
    strcpy(puno_ime, ime);      // kopiraj "Ana" u puno_ime
    strcat(puno_ime, " ");      // dodaj razmak
    strcat(puno_ime, prezime);  // dodaj "Kovac"

    printf("Ime: %s\n", puno_ime);
    printf("Duljina: %zu znaka\n", strlen(puno_ime));

    // Usporedba stringova
    char lozinka[20] = "tajno123";
    char unos[20] = "tajno123";

    if (strcmp(lozinka, unos) == 0) {
        printf("Lozinka tocna!\n");
    } else {
        printf("Pogresna lozinka.\n");
    }

    return 0;
}
Objasnjenje
Linija 2
#include <string.h> — biblioteka s funkcijama za rad sa stringovima. Bez nje ne mozemo koristiti strcpy, strcat, strlen, strcmp.
Linija 10
strcpy(odrediste, izvor) — kopira string. Ne mozes koristiti = za kopiranje stringova. Uvijek koristi strcpy.
Linija 21
strcmp(s1, s2) — usporeduje dva stringa. Vraca 0 ako su jednaki. Nikad ne koristi == za usporedbu stringova!
lekcija 12

Pokazivaci (Pointers)

Pokazivac je varijabla koja cuva memorijsku adresu neke druge varijable, umjesto same vrijednosti. Ovo je tema koja zbunjuje mnoge pocetnike — ali je temelj C-a. Operativni sustavi, driveri i sve visoko-performantne strukture podataka ovise o pokazivacima.

42
0x7ffd1234
int broj
0x7ffd1234
0x7ffd5678
int *ptr

Varijabla ptr cuva adresu varijable broj, ne njenu vrijednost.

C
#include <stdio.h>

int main() {
    int broj = 42;
    int *ptr = &broj;  // ptr cuva adresu varijable broj

    printf("Vrijednost broja:      %d\n", broj);
    printf("Adresa broja:          %p\n", (void*)&broj);
    printf("Vrijednost ptr-a:      %p\n", (void*)ptr);
    printf("Dereferenciranje ptr:  %d\n", *ptr);

    // Promjena vrijednosti PUTEM pokazivaca
    *ptr = 100;
    printf("\nNakon *ptr = 100:\n");
    printf("broj = %d\n", broj);  // ispisuje 100!

    return 0;
}
Objasnjenje — dva kljucna operatora
Linija 5
int *ptr = &broj;
& = address-of operator — daj mi adresu varijable broj.
int * = tip "pokazivac na int". ptr sada sadrzi memorijsku adresu gdje zivi varijabla broj.
Linija 10
*ptr = dereferenciranje — "idi na adresu koju ptr cuva i procitaj vrijednost tamo". Zvjezdica ovdje znaci nesto drugo nego pri deklaraciji.
Linija 13
*ptr = 100 — pisi 100 na adresu gdje ptr pokazuje. Budući da ptr pokazuje na broj, ovo mijenja broj. Linija 15 ispisuje 100 iako smo mijenjali putem pokazivaca.
NULL pointer: Uvijek inicijaliziraj pokazivac koji ne pokazuje nista na NULL: int *ptr = NULL;. Dereferenciranje NULL pokazivaca uzrokuje crash programa (Segmentation fault). Provjeri: if (ptr != NULL) { ... }
Cestitamo — prosao si sve lekcije!
Sada znas: printf, varijable, tipove, operatore, scanf, uvjete, petlje (for/while/do-while), kombinacije petlji, funkcije, nizove, stringove i pokazivace. To su temelji C-a — sve ostalo (strukture, dinamicka alokacija, datoteke) gradi se na ovome.