PDA

Pogledaj cijelu verziju : Tečaj C-a za sve uzraste by cham3leon



cham3leon
20-01-2010, 10:16
Kao što je već Luka rekao, C i nije baš najidealniji programski jezik za početnike, ali čak i ako niste prije programirali, može ga se naučiti. Zato ću nastojati da objasnim i najmanje sitnice koje bi mogle zbunjivati potpune početnike kako biste zaista razumjeli kako ovaj jezik funkcionira. Između svakog dijela možete slobodno postavljati bilo kakva pitanja, past će možda i neki kratki zadačić i slično :D

1. OSNOVE

Ovdje sam odlučio ubacit i nešto o radu s DEV-C++ IDE-om. Naravno, možete koristiti bilo koji IDE kojeg nađete, samo da podržava C jezik. Inače radim na KDevelopu na Linuxu, ali pošto pretpostavljam da svi koristite Windows, uzet ćemo Dev C++ kao "službeni". Na jednom od prošlih VIDI diskova sam našao wxDEV C++, malo poboljšanu verziju gorespomenutoga koja će isto poslužiti svrsi.

http://wxdsgn.sourceforge.net/S- wxDEV C++

http://www.bloodshed.net/dev/devcpp.htmlS- DEV-C++

http://www.codecutter.net/tools/quincy/S- Quincy - jedan jednostavan IDE na koji sam jednom naletio, možda vam i to bude dosta.

Jedina stvar na koju morate paziti jest da nađete verziju IDE-a koja sadrži libraryje (biblioteke) i compiler (prevodioc) jer bez njih vam nijedan kod neće raditi.


Slijedi primjer kreiranja novog jednostavnog programa u wxDEV-C++-u:

Prvo morate otvoriti novi projekt koji će sadržavati vaš program. File -> New -> Project, kao na slici:
http://img301.imageshack.us/i/tut1y.png/

Zatim ćete na izbor dobiti nekoliko predložaka za projekte. Odaberite "Console Application", odnosno program koji će se izvoditi u konzoli. Također, ispod odaberite da vam projekt bude u C, a ne C++ jeziku. Nakon toga, (slika 2) morate dodati novi file u svoj projekt. U tom C fileu ćete zapravo pisati kod.
http://img301.imageshack.us/i/tut1y.png/


I sada možemo početi programirati. Možda vam se u fileu već otvorio i neki predložak, ali mi ćemo početi s vlastitim programom, za sada klasični početnički "Hello world", nešto najjednostavnije što u ovom jeziku možete napisati. Pomoći će nam da prikažemo nekoliko bitnih dijelova C koda.


#include <stdio.h>

int main ()
{
printf("Zdravo svijete!!");

system("pause");
return EXIT_SUCCESS;
}

Počnimo od početka - #include <stdio.h>
Ove naredbe većina IDE-ova označava zeleno iz preglednosti. Radi se o pretprocesorskim naredbama.
Funkcija ovih naredbi je da definiraju koje će biblioteke (libraryje) ovaj program koristiti. Biblioteke su zapravo zbirke funkcija, odnosno naredbi koje možemo koristiti u našem programu. stdio.h, odnosno Standard input/output sadrži naredbe za očitavanje i ispisivanje podataka. Naredba za ispisivanje printf (print function) je primjerice sadržana u ovoj datoteci.

Zatim, promotrimo naredbu - main ()
Main je glavna funkcija vašeg programa. Što je točno funkcija zasada nećemo detaljno objašnjavati, to će doći do izražaja kasnije, ali zasad je bitno znati da ova naredba označava sam kod vašeg programa. "Tijelo" vašeg programa, da budemo precizniji. Vitičaste zagrade su ovdje jako bitna stvar, označavaju što će se sve događati tokom izvođenja glavne funkcije main.

U ovom slučaju, sve što će se u programu izvesti jest jedna printf funkcija, koja, kao što rekoh, služi za ispisivanje nečega na ekran. To "nešto" može biti neka brojčana vrijednost, znak, ili u našem slučaju rečenica "Hello World!!" koju smo zapisali s navodnicima unutar zagrada funkcije printf. Općenito, printf će ispisati ono što zapišete u njegove zagrade s navodnicima. Više od toga zasad ne trebate znati.

Također uočite kako iza printf-a stoji i jedan ";". Ovaj znak je potrebno staviti poslije svake naredbe koju napišete u programu, a poslužit će kako bi računalo znalo da s time naredba završava, te da je ono što slijedi iduća naredba. Zapravo, mogli biste pisati sve naredbe u istom redu samo ih odvajajući točka-zarezima i dobili biste istu stvar, samo što bi to bilo kudikamo nepreglednije, ali shvaćate poantu - prelazak u novi red ne označava početak nove naredbe, za to služi ";".

return naredba označava što funkcija vraća, ali zasad je dovoljno znati da ako upišemo

return EXIT_SUCCESS;

program će ispisati poruku "Press any key to continue", i kad pritisnete tipku, zatvorit će se. Ovu naredbu ćemo na jednak način koristiti u gotovo svim daljnjim programima.

system ("pause"); je naredba koju inače nikad nisam koristio u kombinaciji s returnom, ali sam primijetio radeći u Dev-C++-u da bez nje program niti ne čeka da korisnik pritisne tipku, već samo izađe iz programa. Osnovno govoreći, ovo je jedna od system funkcija, u ovom slučaju čeka korisnikov "odgovor" kod izlaska iz programa.

To bi bio naš početnički program, idući puta ćemo preći na nešto korisnije i opipljivije, te ćemo po prvi put koristiti i varijable, čime počinjemo "stvarno" programirati. U međuvremenu, postajte sva pitanja koja vas muče.

Isprobajte sami. Napišite ovako nešto u vašem IDE-u i probajte pokrenuti. Za korisnike Dev-Cpp-a samo stisnite F9.

loo
20-01-2010, 14:14
Ovo nisi mogao napraviti u bolje vrijeme. Uskoro pišem test, a moj glupi profesor nezna ništa objasnit. Svaka čast :pray:

cham3leon
20-01-2010, 15:04
Pa šta ti je ovo od neke koristi? Jer mislim, nismo još ni počeli zapravo.

Nee Joe
20-01-2010, 15:29
Svaka čast, trebala bi mi pomoć oko C-a :D

loo
20-01-2010, 17:55
Pa šta ti je ovo od neke koristi? Jer mislim, nismo još ni počeli zapravo.

Vjerovao ili ne, ovo mi je od koristi (minimalne, ali ipak je). A i mislio sam i na uskorašnji (nadam se :) ) nastavak tečaja :D

SkunK
20-01-2010, 18:22
Sve pohvale na početku vodiča, takve stvari su uvijek dobre i konstruktivne.

No neznam čemu učenje (novaka) C-u kada je bolje odmah početi sa C++.

cham3leon
20-01-2010, 19:04
Pa evo onda i nastavka.

2. Pređimo na stvar

Možda prebrzo dajem idući dio tutoriala, ali očekujem da bi iz onog prvog gradiva trebalo ostati malo nejasnoća i pitanja, pa krenimo mi s nečim konkretnijim. Još uvijek smo na potpunim osnovama, pa ni ovo neće biti teško. Nadam se da ste isprobali primjer iz prošlog dijela. Nisam napomenuo, kako biste u DEV-Cpp pokrenuli vaš program, samo stisnite F9.

U ovom dijelu počet ćemo koristiti varijable. Varijable su jednostavno rečeno vrijednosti kojima smo dodali ime tako da ih možemo označiti. Dakako, njihove vrijednosti možemo mijenjati na razne načine, zavisno što želimo učiniti s njima.

Prije svega, moramo razumjeti kako u C jeziku, varijable dijelimo po tipovima podataka koje sadrže. Jako je važno kojeg je određena varijabla tipa, jer to znači da se u tu varijablu mogu pohraniti samo podaci tog oblika. Slijedi pregled najvažnijih tipova podataka koje ćete koristiti u C-u. Skraćenice služe pri deklaraciji varijabli:

Integer..................int - Cjelobrojni tip podataka
Floating point.........float - realni brojevi, dakle ovdje je moguće pohraniti i decimalne brojeve
Character..............char - Znakovi

Naravno, to nisu svi tipovi podataka koje C koristi, tu su i short integer, long, double i slično, međutim, za ovakav početnički tečaj nisu ni bitni. Od ostalog treba napomenuti kako i navedeni tipovi podataka mogu biti i signed ili unsigned, što znači da mogu ili ne moraju sadržavati predznak. Također imajte na umu da character tip podataka zapravo sadrži ASCII kod, odnosno broj koji odgovara nekom znaku. Budete li se puno bavili sa slovima i riječima, ponekad će vam dobro doći i ASCII tablica (http://www.asciitable.com/)Su kojoj možete točno vidjeti koji ASCII broj odgovara kojem znaku.

Prije svake radnje sa varijablama u programu potrebno ih je prvo deklarirati, odnosno rezervirati mjesto za njih u računalnoj memoriji. U deklaraciji navodite tip varijable, te njezino ime koje može biti bilo kakvo, samo mora početi slovom a ne brojem. Evo primjer:


int broj;
U ovom primjeru deklarirali smo varijablu koju smo u naletu kreativnosti nazvali "broj" i rekli da je cjelobrojnog tipa (integer) dodavanjem već navedene skraćenice ispred imena. Sad smo joj odredili sudbinu, i ona će moći spremati samo cijele brojeve, a nikako decimalne. Ako želite deklarirati više varijabli istog tipa podatka, kraće ćete to učiniti na ovakav način -

float a, b, y, x, lol, rofl, pcplay;
- čime u jednoj liniji definirate cjelobrojne varijable nazvane "a", "b", "y", "x", "lol", "rofl" i "pcplay". Samo nemojte zaboraviti ";" na kraju.

Pa počnimo s našim programom onda. Cilj ovaj put je program koji zbraja dva broja i ispisuje rezultat na ekran. Krajnje jednostavno.

Prvo počnimo od pretprocesorskih naredbi. #include-at ćemo <stdio.h> bez kojeg nema ništa, a ovaj put bih ubacio i <stdlib.h>. Iskreno, ne znam točno šta ova druga radi, ali kad god pišem program, i ona je includeana :>

#include <stdio.h>
#include <stdlib.h>

Slijedi main() funkcija koja sadržava naš program. Napisat ću je odmah, pa ćemo poslije analizirati.

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

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

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

c = a + b;
printf("Rezultat je %d", c);

system("pause");
return EXIT_SUCCESS;
}

E sad se po prvi put susrećemo sa nekim naoko čudnovatim stvarima, primjerice ovi postotci i ampersandovi, što je pa to?
Za početak, pogledajmo onu prvu scanf naredbu. Kao što printf služi za ispisivanje nečega na standardni izlaz (monitor), tako scanf služi za očitavanje sa standardnog ulaza ( tipkovnice) što znači, da će nakon printf naredbe pričekati da korisnik nešto napiše i stisne enter.
Zatim moramo raščistiti što znači "%d". Sve ove oznake koje sadrže znak % su tzv. format specifieri. Dakle, oni određuju format koji će se u ovom slučaju upisati u program. %d označava da se traži cjelobrojna dekadska vrijednost. Zapravo, evo odmah pregleda f. specifiera:

Integer.................%d (za dekadski brojevni sustav, za druge treba provjeriti, mislim da je oktalno %o, hexadekadski %h, itd.)
Floating point.........%f
Character..............%c

Ono što specifier %d govori scanf funkciji je "Kad korisnik unese jednu vrijednost, zapiši je kao cjeli broj", a onda ovaj dodatak izvan navodnika kaže "zapiši tu vrijednost u varijablu a". Znak & ispred toga je adresni operator, i tu mora biti zato jer scanf funkciji zapravo treba reći da zapiše vrijednost na memorijsku adresu varijable "a". Što to znači naučit ćete dosta kasnije, zasad je dovoljno samo da znate da morate stavljati taj & kod scanf funkcije.

Kako biste bolje razumjeli kako to funkcionira, recimo da kad bi stavili ovako nešto -

scanf ("%d %c", &a, &b)

to bi značilo da se očekuje od korisnika da unese jedan cijeli broj, stisne razmak, i unese neki znak, te da se broj sprema u varijablu a, i znak u b. Možemo staviti i "%d , %c", pa korisnik mora unijeti broj, stisnuti razmak, upisati zarez, opet razmak i upisati neki znak. Kako god zamislite.

Ista fora je i sa drugim upisivanjem broja, a zatim najobičnijom matematičkom formulom izračunamo c koji nam je zbroj prva dva broja. Nakon toga printf funkcija ispisuje rezultat. Primijetite da koristi istu sintaksu kao i scanf. Format specifier %d kaže "tu gdje ja sad stojim neka se ispiše cjelobrojna vrijednost", a nakon navodnika se napiše i odakle, s time da primijećujete da ovdje nisam koristio &. Dakle, kod printf-a za razliku od scanf-a NE IDE adresni operator &. Zašto u scanf za razliku od toga ide i & ne bih znao reći, ali tako to jeste. Pazite da ne pobrkate!

Ostalo već znate, funkcija za izlazak iz programa, i slično. Eventualno u sadržaj printf-ova možete ubaciti i \n koji funkcionira slično kao format specifier, samo što govori da se na njegovom mjestu pređe u novi red. Čisto radi preglednosti. Možete probati i slične programe sa dijeljenjem (/), množenjem (*), oduzimanjem (-). Mislim da ovo zaista nije bilo teško, ako nešto nije jasno, pitajte.

@ReiKo: Zato jer ne znam C++ :>
Odnosno, možda bih ga znao da ne moram opet ove godine slušati programiranje u C-u koje, eto, kroz dvije godine koliko ga radim već dovoljno znam da mogu napraviti tutorial. btw, nisam imao pojma da je za početnike bolji C++...

wavefunct
20-01-2010, 20:44
/

jeste, ja sam počeo sa C raditi, ali kad sam kupio tracerovu knjigu vidio sam koliko je lakši C++, tamo nema format specifiera keke ^^

loo
20-01-2010, 21:45
I zato si kvouto cijeli post? -.-

Nee Joe
20-01-2010, 21:48
Pa evo onda i nastavka.

2. Pređimo na stvar

Možda prebrzo dajem idući dio tutoriala, ali očekujem da bi iz onog prvog gradiva trebalo ostati malo nejasnoća i pitanja, pa krenimo mi s nečim konkretnijim. Još uvijek smo na potpunim osnovama, pa ni ovo neće biti teško. Nadam se da ste isprobali primjer iz prošlog dijela. Nisam napomenuo, kako biste u DEV-Cpp pokrenuli vaš program, samo stisnite F9.

U ovom dijelu počet ćemo koristiti varijable. Varijable su jednostavno rečeno vrijednosti kojima smo dodali ime tako da ih možemo označiti. Dakako, njihove vrijednosti možemo mijenjati na razne načine, zavisno što želimo učiniti s njima.

Prije svega, moramo razumjeti kako u C jeziku, varijable dijelimo po tipovima podataka koje sadrže. Jako je važno kojeg je određena varijabla tipa, jer to znači da se u tu varijablu mogu pohraniti samo podaci tog oblika. Slijedi pregled najvažnijih tipova podataka koje ćete koristiti u C-u. Skraćenice služe pri deklaraciji varijabli:

Integer..................int - Cjelobrojni tip podataka
Floating point.........float - realni brojevi, dakle ovdje je moguće pohraniti i decimalne brojeve
Character..............char - Znakovi

Naravno, to nisu svi tipovi podataka koje C koristi, tu su i short integer, long, double i slično, međutim, za ovakav početnički tečaj nisu ni bitni. Od ostalog treba napomenuti kako i navedeni tipovi podataka mogu biti i signed ili unsigned, što znači da mogu ili ne moraju sadržavati predznak. Također imajte na umu da character tip podataka zapravo sadrži ASCII kod, odnosno broj koji odgovara nekom znaku. Budete li se puno bavili sa slovima i riječima, ponekad će vam dobro doći i ASCII tablica (http://www.asciitable.com/)Su kojoj možete točno vidjeti koji ASCII broj odgovara kojem znaku.

Prije svake radnje sa varijablama u programu potrebno ih je prvo deklarirati, odnosno rezervirati mjesto za njih u računalnoj memoriji. U deklaraciji navodite tip varijable, te njezino ime koje može biti bilo kakvo, samo mora početi slovom a ne brojem. Evo primjer:


int broj;
U ovom primjeru deklarirali smo varijablu koju smo u naletu kreativnosti nazvali "broj" i rekli da je cjelobrojnog tipa (integer) dodavanjem već navedene skraćenice ispred imena. Sad smo joj odredili sudbinu, i ona će moći spremati samo cijele brojeve, a nikako decimalne. Ako želite deklarirati više varijabli istog tipa podatka, kraće ćete to učiniti na ovakav način -

float a, b, y, x, lol, rofl, pcplay;
- čime u jednoj liniji definirate cjelobrojne varijable nazvane "a", "b", "y", "x", "lol", "rofl" i "pcplay". Samo nemojte zaboraviti ";" na kraju.

Pa počnimo s našim programom onda. Cilj ovaj put je program koji zbraja dva broja i ispisuje rezultat na ekran. Krajnje jednostavno.

Prvo počnimo od pretprocesorskih naredbi. #include-at ćemo <stdio.h> bez kojeg nema ništa, a ovaj put bih ubacio i <stdlib.h>. Iskreno, ne znam točno šta ova druga radi, ali kad god pišem program, i ona je includeana :>

#include <stdio.h>
#include <stdlib.h>

Slijedi main() funkcija koja sadržava naš program. Napisat ću je odmah, pa ćemo poslije analizirati.

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

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

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

c = a + b;
printf("Rezultat je %d", c);

system("pause");
return EXIT_SUCCESS;
}

E sad se po prvi put susrećemo sa nekim naoko čudnovatim stvarima, primjerice ovi postotci i ampersandovi, što je pa to?
Za početak, pogledajmo onu prvu scanf naredbu. Kao što printf služi za ispisivanje nečega na standardni izlaz (monitor), tako scanf služi za očitavanje sa standardnog ulaza ( tipkovnice) što znači, da će nakon printf naredbe pričekati da korisnik nešto napiše i stisne enter.
Zatim moramo raščistiti što znači "%d". Sve ove oznake koje sadrže znak % su tzv. format specifieri. Dakle, oni određuju format koji će se u ovom slučaju upisati u program. %d označava da se traži cjelobrojna dekadska vrijednost. Zapravo, evo odmah pregleda f. specifiera:

Integer.................%d (za dekadski brojevni sustav, za druge treba provjeriti, mislim da je oktalno %o, hexadekadski %h, itd.)
Floating point.........%f
Character..............%c

Ono što specifier %d govori scanf funkciji je "Kad korisnik unese jednu vrijednost, zapiši je kao cjeli broj", a onda ovaj dodatak izvan navodnika kaže "zapiši tu vrijednost u varijablu a". Znak & ispred toga je adresni operator, i tu mora biti zato jer scanf funkciji zapravo treba reći da zapiše vrijednost na memorijsku adresu varijable "a". Što to znači naučit ćete dosta kasnije, zasad je dovoljno samo da znate da morate stavljati taj & kod scanf funkcije.

Kako biste bolje razumjeli kako to funkcionira, recimo da kad bi stavili ovako nešto -

scanf ("%d %c", &a, &b)

to bi značilo da se očekuje od korisnika da unese jedan cijeli broj, stisne razmak, i unese neki znak, te da se broj sprema u varijablu a, i znak u b. Možemo staviti i "%d , %c", pa korisnik mora unijeti broj, stisnuti razmak, upisati zarez, opet razmak i upisati neki znak. Kako god zamislite.

Ista fora je i sa drugim upisivanjem broja, a zatim najobičnijom matematičkom formulom izračunamo c koji nam je zbroj prva dva broja. Nakon toga printf funkcija ispisuje rezultat. Primijetite da koristi istu sintaksu kao i scanf. Format specifier %d kaže "tu gdje ja sad stojim neka se ispiše cjelobrojna vrijednost", a nakon navodnika se napiše i odakle, s time da primijećujete da ovdje nisam koristio &. Dakle, kod printf-a za razliku od scanf-a NE IDE adresni operator &. Zašto u scanf za razliku od toga ide i & ne bih znao reći, ali tako to jeste. Pazite da ne pobrkate!

Ostalo već znate, funkcija za izlazak iz programa, i slično. Eventualno u sadržaj printf-ova možete ubaciti i \n koji funkcionira slično kao format specifier, samo što govori da se na njegovom mjestu pređe u novi red. Čisto radi preglednosti. Možete probati i slične programe sa dijeljenjem (/), množenjem (*), oduzimanjem (-). Mislim da ovo zaista nije bilo teško, ako nešto nije jasno, pitajte.

@ReiKo: Zato jer ne znam C++ :>
Odnosno, možda bih ga znao da ne moram opet ove godine slušati programiranje u C-u koje, eto, kroz dvije godine koliko ga radim već dovoljno znam da mogu napraviti tutorial. btw, nisam imao pojma da je za početnike bolji C++...

jeste, ja sam počeo sa C raditi, ali kad sam kupio tracerovu knjigu vidio sam koliko je lakši C++, tamo nema format specifiera keke ^^

Mogao si ga bar u spoiler stavit :D

Luka
20-01-2010, 22:38
/

jeste, ja sam počeo sa C raditi, ali kad sam kupio tracerovu knjigu vidio sam koliko je lakši C++, tamo nema format specifiera keke ^^

Osim što je poražavajuće vrsnost i kompleksnost jezika poput Ca i C++a srozavati na usporedbu korištenja ispisnih metoda; morat ću te ispraviti - C++, uz izlazne tokove, i dalje nudi printf i scanf. Također, globalno gledano, C je lakši jer ima manje mogućnosti. Želiš li savladati cijeli C trebat će ti manje vremena nego za obaviti istu radnju s C++om. Opet, želiš li savladati C++ samo u mjeri koja je dovoljna da zamijeni C, C++ će biti lakši.

wavefunct
20-01-2010, 23:15
/

jeste, ja sam počeo sa C raditi, ali kad sam kupio tracerovu knjigu vidio sam koliko je lakši C++, tamo nema format specifiera keke ^^

Osim što je poražavajuće vrsnost i kompleksnost jezika poput Ca i C++a srozavati na usporedbu korištenja ispisnih metoda; morat ću te ispraviti - C++, uz izlazne tokove, i dalje nudi printf i scanf. Također, globalno gledano, C je lakši jer ima manje mogućnosti. Želiš li savladati cijeli C trebat će ti manje vremena nego za obaviti istu radnju s C++om. Opet, želiš li savladati C++ samo u mjeri koja je dovoljna da zamijeni C, C++ će biti lakši.

znam da C++ nudi printf i scanf, ali C ne nudi cin :oops:

MasterOFDisaster
21-01-2010, 20:51
PIH za mene je C mačiji kašalj ili pseći lavež

Usput tko ce ici na info kup ove godine strašno me zanima :D

Ja i moj frend imamo svoj rad na C-u

Luka
21-01-2010, 21:33
PIH za mene je C mačiji kašalj ili pseći lavež

Usput tko ce ici na info kup ove godine strašno me zanima :D

Ja i moj frend imamo svoj rad na C-u

Činjenica da kažeš "imamo rad na C-u" mi uvodi sumnju na tvoju postavku o trivijalnosti Ca za tebe.

SkunK
22-01-2010, 08:26
PIH za mene je C mačiji kašalj ili pseći lavež

Usput tko ce ici na info kup ove godine strašno me zanima :D

Ja i moj frend imamo svoj rad na C-u

Činjenica da kažeš "imamo rad na C-u" mi uvodi sumnju na tvoju postavku o trivijalnosti Ca za tebe.


:pray:

cham3leon
22-01-2010, 14:10
Hajdehajde, idemo dalje. Jedino što sam zaboravio napomenuti u vezi prethodnog zadatka je da smo ga mogli izvesti i bez deklariranja varijable c, i bez linije gdje se u "c" zapisuje zbroj a i b. U tom slučaju, bilo bi dovoljno napisati (a+b) kao argument u printf naredbi, umjesto "c". Dakle, ovo:

printf("Rezultat je %d", (a+b))

Također vas molim da ne spamate temu nepotrebnim komentarima o vašem programerskom znanju i raspravi koji je jezik bolji. Ako se modovi slažu, mogu i pobrisati suvišne postove.

4. Grananje

Sad pomalo dolazimo i na logičke operacije poput grananja. Ponekad ćete htjeti da je vaš program u stanju izvršiti različite stvari, a ne samo jednu jedinu skriptu koja se izvršava u slijedu kao u prošlom zadatku. Recimo da nam treba program koji može zbrajati i oduzimati.

Grananje je ustvari dijeljenje programa na više paralelnih nizova naredbi, pri čemu će program prema zadanom kriteriju odabrati koja grana će se izvršiti, a koja neće. Najosnovnija naredba grananja koju ćete vjerojatno i najviše koristiti je "if" naredba. Ona izgleda ovako:

if (a==0)
{

}

U zagradu gore kod ključne riječi if pišemo kriterij (uvjet) po kojem ćemo granati, a u vitičaste zagrade pišemo slijed naredbi (isto kao što smo dosad naučili) koje će se izvršiti ako je kriterij zadovoljen. U ovom slučaju, naredbe koje bismo napisali u vitičaste zagrade izvršile bi se ako je varijabla a jednaka nuli, u suprotnom bi bile zanemarene. Primijetite kako sam malo uvukao vitičaste zagrade if-a, skupa sa naredbama koje bi tamo bile zapisane. Naravno da to nije potrebno, ali ovako je mnogo preglednije da znate kojoj naredbi pripadaju te zagrade, te što se unutar tog grananja dešava, pogotovo kad budete pisali malo duže programe. ";" se u ovoj funkciji ne stavlja na kraj, kao ni kod velike većine funkcija koje koriste vitičaste zagrade i imaju svoje pod-naredbe.

Vjerojatno ste također primijetili da je u uvjetu izraz zapisan sa dva znaka "=". To dakako, nije greška.
U C programskom jeziku, a=0 bi značilo da u varijablu a zapisujemo broj 0. Međutim, kad napišemo a==0, time ispitujemo JE LI a jednak nuli. (a==0) zapravo poprima neke vrijednosti. Ako je istina da je a jednak nuli, taj izraz u zagradi poprimit će vrijednost 1 (što znači "istinit"), a ako nije, poprimit će vrijednost 0 (neistinit).
Na taj način zapravo funkcionira if naredba kao i mnoge slične joj. Uvjet kod "if"-grananja, kao i kod sličnih naredbi, funkcionira tako da će se naredbe u if-u izvršiti ako je uvjet različit od nule, a ako je jednak nuli, sve to se neće izvršiti.

Da smo umjesto toga u zagradu za kriterij napisali a = 0, to bi postavilo uvjet na vrijednost nula, što znači da se naredbe nikad ne bi odvrtile. Isto bismo postigli da smo napisali if(0), dok bi if(1), ili bilo koji drugi broj različit od nule značilo da bi se te naredbe uvijek izvršavale. Zato pazite na tu duplu jednakost kod usporedbe brojeva, to je česta greška.

Dakako, ponekad će nam uz ispitivanje jednakosti trebati i ispitivanje nejednakosti, zatim je li nešto veće od nečeg drugog, i slično. Pa evo odmah kratke tablice:

==...........................ako je jednako...
!=............................ako nije jednako...
<=...........................ako je manje od, ili jednako...
>=...........................ako je veće od, ili jednako...
<.............................ako je manje od...
>.............................ako je veće od...

Ponekad ćete htjeti da vam se neke naredbe izvrše ako je ispunjeno više uvjeta. Tada vaša if naredba može izgledati ovako:

if ((a==0) && (b==0))
{

}

U ovom primjeru, dva uvjeta su povezana logičkim AND (I) operatorom (&&), što znači da će se naredbe u if funkciji izvršiti samo ako je ispunjen i prvi i drugi uvjet. Dakle, sad će se naredbe u if-u izvršiti samo ako su i a i b jednaki nuli. Osim I moguće je koristiti i ILI (OR) operator, evo tablice za brzu referencu:

&&.............AND............Izvrši samo ako su svi uvjeti ispunjeni
||..............OR..............Izvrši ako je ispunjen barem jedan uvjet

Primjerice, sljedeća if naredba će se izvršiti ako je ili a ili b jednako 10, a da pritom c mora biti nula:

if (((a==10) || (b==10)) && (c==0))
{

}

Tko se prije nije susretao sa logikom, ovo mu je možda malo preteško za shvatiti, ali ubuduće ćemo rijetko imati više od jednog uvjeta pa ovo nećemo koristiti dok ne ovladate if naredbom.

Pa riješimo onda slijedeći zadatak: Treba napisati program koji će izračunati zbroj dva broja ako korisnik napiše 1, ili razliku tih brojeva, ako korisnik upiše 2.

#include <stdio.h>
#include <stdlib.h>

int main
{
int a, b, c, x; //a je prvi broj, b drugi, c rezultat, a x služi za izbor rač. operacije

printf("Unesi prvi broj: ");
scanf("%d", &a);
printf("Unesi drugi broj: ");
scanf("%d", &b);
printf("Koja operacija? 1 (+) ili 2 (-)? ");
scanf("%d", &x)

if (x == 1) //Provjeravamo je li izbor računske operacije 1 za zbrajanje
{
c = a + b; //Ako jest, rezultat je zbroj tih brojeva
printf ("Rezultat je %d", c);
}

else if (x==2) //Ako izbor nije 1, provjeravamo je li možda 2, pa ako je, oduzimamo.
{
c = a - b;
printf ("Rezultat je %d", c);
}

else //ako nije ni to, onda ispisuje ovu poruku:
{
printf("Error. Unesite 1 ili 2.");
}
system("pause");
return EXIT_SUCCESS;
}

Ranije sam također trebao objasniti da dva sleša (//) prije teksta u nekom retku taj tekst označavaju kao komentar, pa će on ostati u kodu kako bi se ostavile zabilješke o radu pojedinih dijelova programa ili bilo čega drugoga koje će prevodioc za C ignorirati.
Vidjeli ste i else te else if naredbe na djelu. Kad se postave iza postojećeg if-a, ukoliko uvjet tog if-a nije zadovoljen, "else if" će provjeriti valja li neki drugi uvjet, pa onda izvršiti svoje naredbe. Možete nanizati koliko hoćete takvih naredbi iza if-a da pokrijete sve slučajeve koji vas zanimaju.
"Else" naredba će se pak izvršiti čim se ne zadovolji uvjet originalnog if-a bez ikakve dodatne provjere drugih uvjeta. Ako uz if imate i else if i else naredbe, svi else if-ovi moraju biti prije else-a (iz logičkih principa).

Još jedna stvar koju moram napomenuti - svaki if, else ili else if koji u svom bloku naredbi sadržavaju samo jednu naredbu, mogu se pisati bez vitičastih zagrada, a ta jedna naredba se piše odmah iza if-a sa ";" na kraju:

if (a==0) printf("Varijabla a je jednaka nuli.");
Upamtite da se ovako može pisati samo kad if pokreće jednu jedinu naredbu. Inače vam vitičaste ne ginu :D

Probajte if-ovima izvesti razne algoritme, uspoređivanje brojeva i slične egzibicije, postajte pitanja i nedoumice, a nakon toga možemo dalje na megazabavne petlje.

SkunK
22-01-2010, 14:23
Lijepo, lijepo samo tako naprijed.

wavefunct
24-01-2010, 09:16
oodlično napravljeno, al mi je nešto upalo u oko...

"megazabavne petlje" ???

haha koji g33k keke ^^

pehlinac
25-01-2010, 20:24
Svaka cast na tutorialu, treba imat volje i znanja za tako nesto :pray: ... Treba pomoc nadobudnim programerima :) . Zanima me kako ces pokazivace objasnit, s obzirom da su pokazivaci takorec najvazniji i najtezi dio c jezika za shvatiti. Enivej, keep up the good work :thumbs2:

cham3leon
25-01-2010, 20:36
A čuj, primila me volja kad je bilo nekoliko zainteresiranih ljudi, sad više nisam siguran prati li ovo tko. S time da sam išao od totalne nule nastojeći objasniti što razumljivije. Nadam se da pokazivači neće bit problem...

Idući nastavak možete očekivati negdje krajem radnog tjedna. Na faxu nas upravo jebu sa 2 ispita ovaj tjedan, + treba se pripremat za završne idući tjedan, valjda stignem te petlje :(

cham3leon
27-01-2010, 18:07
Prije megazabavnih petlji ipak treba odraditi nešto što nisam ugurao u gornji post sa grananjem, a to je još jedna naredba kojom možemo granati naš program. Ime joj je switch/case, a namjena ista kao i kod if-a: da obilježi određene naredbe koje želimo izvoditi samo ako je ispunjen neki logički uvjet, međutim switch je praktičan tamo gdje if nije.

Konkretno, naći će se situacija kada ćemo imati kontrolnu varijablu koja će služiti za odabir daljnjih procesa koje će program izvesti (primjerice kalkulator sa više mogućih računskih operacija gdje je za svaku potrebno napisati neki kod koji se izvodi ako je ta operacija odabrana) i gdje će među mnogo operacija odlučiti o operaciji koju treba izvesti ovisno o stanju jedne kontrolne varijable.
U takvom slučaju trebalo bi kod if funkcije napisati jedan if za prvo stanje, a onda čitavu vojsku else if-ova za ostala stanja gdje bi svaki put nanovo u zagradama napisali koju to varijablu provjeravamo. Za takve stvari postoji switch. Evo primjera njegove sintakse:

switch (a)
{
case 1 :
printf("Odabrali ste broj jedan");
break;
case 2 :
printf("Odabrali ste broj dva");
break;
case 3 :
printf("Odabrali ste broj tri");
break;
}
Pa krenimo redom. Odmah na početku kod naredbe switch u zagradi ne stoji uvjet poput if-a, već ovdje upisujemo varijablu koju želimo da program provjerava, a zatim za svaki slučaj njene vrijednosti napišemo jedan "case" blok u kojem navodimo naredbe koje će se izvršiti ukoliko varijabla koju ispitujemo ispunjava taj uvjet u trenutku provjere. Case riječi koje slijede označavaju različite slučajeve koje želimo ispitati. U ovom trenutku zanima nas je li "a" jednak 1, 2, ili 3. Jednostavno za svaki od slučaja napišemo case, razmak, vrijednost od "a" za neki slučaj, te dvotočku, a nakon nje nižemo blok naredbi koje želimo da se izvrše u tom slučaju, a kraj tih naredbi označavamo naredbom "break".

Prvi put se susrećemo sa breakSnaredbom koja je praktički dio sintakse ove naredbe jer bez nje bi vam se osim npr. slučaja 2 izvršio i slučaj 3. Dakle, break naredbom kažete programu da iskoči iz switch naredbe nakon što obavi sve za taj slučaj. Koristit ćemo je i u petljama za istu namjenu.

Također, nakon svih case-ova obično se (po potrebi, nije nužno) dodaje i default. Kad napišete default, to je kao da ste upisali jedan case i umjesto vrijednosti varijable koja se ispituje naredili mu da ovo što slijedi čini ako se ne ispuni niti jedan od gornjih uvjeta. Dakle, isto kao što ste pisali case, napišete i default, ovaj put bez ikakve vrijednosti, već samo nakon riječi dodate dvotočku i pišete naredbe, te završavate taj blok ponovo break naredbom. pazite i na to da cijelu switch naredbu, dakle sve caseove i default smjestite u vitičaste zagrade kako biste označili da to sve pripada gore spomenutom switchu.

To bi bila sva mudrost vezana za switch/case. Ako tko uopće prati ovu seriju tutoriala, molim vas da se javite, mogu usput pokazat neki kratki praktičan primjer ili zadatak prije nego krenem(o) na petlje. I naravno, ako ima problema, poteškoća i nedoumica, pitajte.

la50
13-02-2010, 03:23
E evo mene počelo zanimat programiranje,pa da nešto i naučim.Skinuo sam Dev Cpp od ovdje http://wxdsgn.sourceforge.net/?q=node/4Sa kad idem pokrenut sa #include <stdio.h> onda mi neće pokrenut a kad mi je #include <cstdlib>;#include <iostream> onda oće,možeš objasnit zašto.Jesam ja nešto krivo skinuo?

Mihael
13-02-2010, 08:50
Dok kreiraš novi projekt naići ćeš u čarobnjaku na jednom screenu na kružić koji moraš označiti vjerojatno ti je označeno na C++ ti označi C

Luka
13-02-2010, 10:34
E evo mene počelo zanimat programiranje,pa da nešto i naučim.Skinuo sam Dev Cpp od ovdje http://wxdsgn.sourceforge.net/?q=node/4Sa kad idem pokrenut sa #include <stdio.h> onda mi neće pokrenut a kad mi je #include <cstdlib>;#include <iostream> onda oće,možeš objasnit zašto.Jesam ja nešto krivo skinuo?

stdio.h je zastario header. Iako ga po standardu svi kompajleri moraju ponuditi, dobar dio njih ga ne nudi. (umjesto "stdio.h" sad možeš koristiti "cstdio", s tim da on koristi imenike pa ćeš morati dodati liniju "using namespace std;" negdje prije main()-a)

la50
13-02-2010, 14:23
Evo prošao sam drugi dio tečaja uspješno xD.I sad me zanima dal se može napisat kvadratna jednadžba sa ± tj bez da moram pisat forumulu za svaki x pojedinačno,nije problem pisat formulu jer ionako se treba promjenit samo plus odnosno minus u formuli.Ovako sam napisao taj način.


#include <cstdlib>
#include <iostream>
#include <cmath>

int main()
{
int a, b, c, x1,x2;

printf("Upisi vrijednost a: ");
scanf("%d", &a);

printf("Upisi vrijednost b: ");
scanf("%d", &b);

printf("Upisi vrijednost c: ");
scanf("%d", &c);

x1=-b-sqrt(b*b-4*a*c)/2*a ;
x2=-b+sqrt(b*b-4*a*c)/2*a ;
printf("Vrijednost x1 je %d " , x1);
printf("Vrijednost x2 je %d " , x2);

system("pause");
return EXIT_SUCCESS;
}

Luka
13-02-2010, 15:20
Predlažem da kasnije otvaraš posebne teme, kako ne bismo previše zatrpali tutoriale netematskim komentarima. :)

Problem za koji pitaš je više umne prirode, problem organizacije i lijepoga kôda; a ne programerski problem (iako bi se to jednom moglo promijeniti).

Najjednostavnije rješenje bi bilo stvoriti dodatne varijable koje bi držale dijelove formule koji su isti (poput diskriminante), pa će kod biti pregledniji. Nešto egzotičnije rješnje bi bilo pokazivačima na funkcije, ili čak kombinacijom klasa i overloadanja operatora...

la50
13-02-2010, 15:33
Ok neću više temu krcat svojim postovima jer ovo je ipak tutorial.
Kameleone tebe moram pohvalit za ovo :bravo: i puno hvala.

cham3leon
14-02-2010, 18:51
O fala Isusu, ovo netko i prati. Kao što je Luka lijepo rekao, ovo je više problem same matematičke, a ne programerske logike, ali nađe se uvijek načina da se takve stvari malo skrate, uvođenje varijable za diskriminantu je jedini logičan potez koji bi se napravio da se ovako nešto skrati, ali kod ovako jednostavnih zadataka, mislim da nema potrebe.

Petlje očekujte idući tjedan, vjerojatno već u ponedjeljak :)

cham3leon
15-02-2010, 18:25
Idemo dalje. Usput da kažem da možete postati slobodno svoja pitanja ovdje, kao i probleme s kojima se susrećete pa da ih svi zajedno riješimo. To bi bila i poanta tutoriala u forumskom threadu, inače sam mogao jednostavno prepisati skripte iz FER-a i malo ih doraditi da budu razumljivije. Samo nastojte ne postati nekakve nevezane ili nepotrebne komentare.

5. Petlje

Kao što ćete sigurno često trebati odvojiti neki kod koji će se izvršavati samo pod određenim uvjetima uz pomoć grananja, tako ćete često trebati natjerati neke dijelove programskog koda da se izvrše više puta. Takav kod zove se petlja.

Krenut ćemo sa whileSpetljom jer je nekako bliža if - naredbama pa će vam možda biti lakša za razumjeti.
Poput if-a, while naredba za petlju se sastoji od ključne riječi while, zatim zagrada u kojima stoji uvjet za izvršavanje petlje, te vitičastih zagrada koje sadrže kod petlje.
Slično kao kod if-a, ali s jednom razlikom - dok god je uvjet ispunjen, petlja se nanovo izvršava, tj. izvršavaju se sve njezine naredbe koje ste nanizali u vitičastim zagradama, i prestat će s iteriranjemS(kružnim ponavljanjem) tek kada uvjet gore više ne bude bio ispunjen. Evo jednostavnog primjera while petlje koja nam broji do pet. Koristit ćemo varijablu b koja će biti brojač.


b = 1;
while (b <= 5)
{
printf("%d\n", b);
b++;
}

Prvo smo b postavili na vrijednost jedan, tako da brojenje počne od 1. Uvjet jest da se brojanje prestane izvršavati kad b postane veće od 5, odnosno da se izvršava dok god je b manje ili jednako pet.
printf naredba ima u argumentu samo jedan format specifier, koji kaže da će na njegovo mjesto biti ispisan cijeli broj, a nakon njega sam dodao \n koji možda nisam spominjao ranije. To je "znak" za novi red, odnosno, kao što biste napisali bilo kakva slova u argument printf funkcije, možete upisati i specijalne znakove poput ovog. \n kao da kaže (nemojte to shvatiti baš skroz doslovno) printf funkciji "tu sad stisni enter" kako bi prešla u novi red. Osim navedenog, postoji i \t znak, ako se ne varam, koji služi za pomicanje tabulatora, odnosno kao da stisnete TAB.

b++; je skraćeni oblik naredbe b = b + 1. Ovime bismo inače rekli da nova vrijednost b postane stara vrijednost uvećana za jedan, ili kraće rečeno, da se vrijednost b poveća za jedan. U narodu poznato kao inkrementiranjeSvarijable. Isto tako možete koristiti i b-- za dekrementiranje, odnosno smanjivanje za jedan. Imajte na umu ipak da morate pisati puni oblik ako želite in/dekrementirati broj za više (ili manje) od 1.

Dakle, ono što se u ovoj petlji događa, jest slijedeće:
Nakon što se provjeri uvjet, te utvrdi da je b doista manji ili jednak 5, petlja se po prvi put izvršava. Na ekran se ispisuje broj 1 i prelazi u novi red. Zatim se varijabla b povećava za jedan. Petlja kreće isponova, i ponovo se provjerava je li uvjet ispunjen. Uvjet jeste ispunjen, jer je b trenutno 2, što je još uvijek manje od 5. Na ekran se ispisuje broj 2, prelazi u novi red, a b se sad povećava na tri.
Tako se izvrši i treća iteracija, i četvrta, te na kraju peta gdje se ispiše broj 5, pređe u novi red i poveća b na 6, a tada se šesta iteracija neće više izvršiti jer uvjet petlje više nije zadovoljen, odnosno b nije više manji ili jednak 5.

Osim ovakvog oblika, ova petlja postoji i u do - whileSobliku. U pravilu izgleda ovako:

do
{

}
while (b <= 5);

Kao što vidite, uvjet se sada piše na kraju, kod while naredbe, te poslije dolazi ";". Razlika je u tome što će se sada uvjet ispitati na kraju, a petlja će se bar jednom izvršiti bez obzira na uvjet, pa tek na kraju početne iteracije provjeriti treba li se izvršiti ponovo. Manje ćete ju koristiti nego običnu while petlju, ali katkad jako dobro dođe.

Nadalje, petlja koja će vam možda biti najpraktičnija, iako u nekim primjerima ne može zamijeniti while petlju, zgodnija je za korištenje kod uobičajenih radnji. Ime joj je for petlja.


for (b = 1 ; b <= 5 ; b++)
{
printf("%d\n", b);
}

Radi se o petlji koja radi apsolutno isto što i prvi primjer s while petljom, brojanje do pet, ali ovaj put preko for petlje.
Primjećujete da je uvjet nekako kompliciraniji. Kod for petlje, uvjet ima tri dijela odvojena točka-zarezima:

1. Postavljamo varijablu za koju želimo da nam bude brojač na neku početnu vrijednost
2. Određujemo uvjet koji mora biti zadovoljen da bi se petlja izvršavala
3. Određujemo kako će se povećavati brojač u svakoj iteraciji. U ovom slučaju za jedan.

Također vidite kako nismo unutar petlje nigdje morali povećavati brojač. To je zato što for petlja radi sa brojačem, odnosno morate imati brojač kako biste napisali for petlju. Petlja će ga sama povećavati u svakoj iteraciji.

Još jedna stvar koju treba spomenuti u vezi petlji. Ukoliko uvjet bude stalno zadovoljen, petlja će nastaviti unedogled. U narodu poznato kao beskonačna petlja, ako je program sadrži, morat ćete ga prekidati na silu. Osim neispunjavanja uvjeta, petlju može prekinuti i naredba break;Skoju ste već vidjeli. Primjerice, ako u petlji tražite od korisnika da upiše nekoliko brojeva za redom, možete ponuditi opciju da upisivanje prestaje kad korisnik upiše, ne znam, nulu, pa unutar petlje napišete nešto kao

if(a = 0) break;

što će pod uvjetom da a postane nula prekinuti petlju i dopustiti da se ostatak koda izvrši.

Nadam se da će vam ovo biti shvatljivo. Pa da izmislimo neki zadačić za vježbu, nešto kratko. Bilo bi možda prelagano da radim varijacije na temu ove brojalice, pa ajmo ovako: Probajte napisati program koji će tražiti od korisnika da unese dva broja, zatim ispisati njihov zbroj, i tada ispočetka, a ako korisnik unese nulu kao bilo koji od ta dva broja, izlazi se iz programa.
Ako ne bude išlo, provajdam rješenje uskoro.

la50
19-02-2010, 16:24
Evo moje zadaće,ali nepotpuna je(nadam se da je za dva barem) jer nisam baš skužio kako bi napravio da nakon što izračuna normalno(da su a i b>0) opet zbraja tako u nedogled dok su a i b>0.Slika (http://www.imagesforme.com/show.php/980630_zadaca.jpg)

cham3leon
19-02-2010, 17:47
Pa uporabom petlji. Očito je :D Da demonstriram jedan primjer:


#include <stdio.h>
#include <stdlib.h>


int main()
{
int a, b;

do
{
printf("Upisi prvi broj: ");
scanf("%d", &a);
printf("Upisi drugi broj: ");
scanf("%d", &b);

if (a == 0 || b == 0) break;

printf("\nRezultat je: %d\n", a + b);
}
while (1);


system("pause");
return EXIT_SUCCESS;
}

Dakle, sve ovo od upisivanja brojeva do ispisivanja rezultata potrpaš u jednu petlju, tako da se to nanovo izvrši. A ako je a ili b jednako nuli (to provjerava ovaj if nakon upisa brojeva), break naredba izbacuje iz petlje, i izvršava se ono što slijedi poslije, a to je kraj programa i izlaz. Ne znam zašto si stavio da ti se samo ispis vrti u petlji, možda nisi skužio zadatak. Uglavnom, nije komplicirano, ne?

Ovo se inače moglo izvršiti na nekoliko načina. Recimo, ja sam sad u uvjet do-while petlje stavio 1, a to sam možda i objasnio prije - logički uvjeti u C-u funkcioniraju tako da 1 ili bilo koji drugi broj osim nule znači "da", odnosno "true", dok je nula logičko "ne", ili false. Kada stavimo npr. a == 0 u uvjet, ako a jeste jednako nula, taj izraz će imati vrijednost jedan, tako da će automatski vrijednost u uvjetu postati jedan. Sad kad sam stavio baš broj jedan u petlju, to znači da ja želim da se ona vrti beskonačno, a da ju može prekinuti samo break naredba koja će se aktivirati ako je a ili b jednako nuli (ona if naredba).
To isto se moglo postići na više različitih načina, recimo, mogli smo napraviti jednu kontrolnu varijablu t koju bismo u početku stavili da je 1, a ako bi onaj if koji provjerava je li bar jedan od brojeva 0, onda bi ju on postavio na 0, a uvjet u petlji bi bio:

while(t!=0), što bi značilo da bi nam se petlja nastavila vrtjeti sve dok ne dođe do nule. Jedino što bi tako u ovom slučaju ispisalo i rezultat prije izlaska, a to možda ne želimo. Također, mogla je to biti obična while petlja, samo što bi i onda trebalo paziti na neke logičke probleme.

la50
19-02-2010, 20:57
E super si mi sad pojasnio,bilo je ono do mene jer sam rookie al i zato jer nisam skužio zadatak kako valja.

cham3leon
22-02-2010, 13:04
6. Nizovi i matrice

A sada ćemo naučiti nešto malo interesantnije gdje ćemo uvidjeti i pravu korisnost petlji. Dosada smo imali posla samo sa najobičnijim varijablama kao memorijskim jedinicama u koje se može pohraniti neka vrijednost unaprijed određene veličine. Nizovi i matrice, mislim da se to sve skupa zovu polja (ali nije bitno) su skup vrijednosti. Možemo ih zamisliti kao varijable koje sadržavaju više različitih vrijednosti istog tipa.

Prvo krenimo od niza, najjednostavniji je za shvatiti. Sastoji se od određenog broja elemenata (broj elemenata definiramo kad deklariramo niz), i svaki od tih elemenata je zasebna vrijednost koja ima i svoj indeks, ilitiga redni broj. Najjednostavniji primjer koji mi pada na pamet je kratak niz od pet elemenata gdje bi se upisivale ocjene iz nekog predmeta, svaka kao jedan element, tako da nakon što se te ocjene upišu, raspolažemo sa nizom ocjena posloženim od 0. elementa (Da, pazite, kreće se od nule, dakle niz od pet elemenata ima te elemente indeksirane od 0 do 4 npr.) pa do 4.
Prije svega - deklaracija. Deklariramo slično kao svaku drugu varijablu, bar što se tiče imena varijable i tipa podatka, međutim, ovaj put moramo definirati i broj članova. Imajte na umu da broj članova polja i veličina memorije koja će se rezervirati za njih poslije ne mogu biti promijenjeni. Odnosno mogu, ali ne na ovakav način, ali to ćemo raditi mnogo kasnije. Broj članova definiramo u uglatim zagradama nakon imena varijable:


int ocjene[5];

...Čime smo upravo rekli prevodiocu da rezervira niz "ocjene" koji će imati pet članova u memoriji.

I sad na raspolaganju imamo niz od pet elemenata u koji možemo zapisivati ocjenu u bilo koji element, iz istog možemo čitati, i slično. Nekom određenom elementu niza pristupamo navodeći ime niza i u uglatoj zagradi redni broj elementa. Primjerice, ako želimo ispisati drugu po redu ocjenu (Pazite, to je ocjena pod indeksom 1!), napisat ćemo ovakvu printf naredbu:


printf("Ocjena broj dva: %d", ocjene[1]);

Znamo već kako rade format specifieri u printf funkciji, ali ovaj put umjesto da smo mu rekli da na svoje mjesto ispiše vrijednost neke varijable, rekli smo mu da ispiše drugi (pod rednim brojem 1) član niza "ocjene". Sad ćemo vidjeti kako se manipulirati nizovima ne može bez petlji. Evo primjera programa koji vrši uzastopno upisivanje elemenata:


int b, ocjene[5];

int main()
{

for (b = 0 ; b < 5 ; b++)
{
printf("Upisi ocjenu broj %d: ", b);
scanf("%d", &ocjena[b]);
}

system("pause");
return EXIT_SUCCESS;
}

Dakle, mislim da je tu sve poprilično jasno: napravili smo petlju (i za njene potrebe brojač b) koja se vrti od početne vrijednosti brojača, odnosno 0, dok se taj brojač ne popne na 4, što je indeks našeg zadnjeg elementa. Kad se poveća na pet, petlja staje jer tada b više nije manji od 5, što nam je uvjet u for petlji. U svakoj iteraciji traži se upis ocjene broj b (printf funkcija), zatim scanf koji zapisuje unesenu vrijednost na b-to mjesto u nizu. Kako će se petlja nanovo vrtjeti, brojač će se povećavati i tako će svaki put printf ispisivati poruku koja traži iduću vrijednost, a scanf ju zapisati u idući element niza "ocjene", sve dok petlja ne završi.
Mislim da biste sad znali napraviti i ispis elemenata na sličan način u još jednoj petlji, najbolje for. Imajte na umu da sad za drugu petlju ne treba deklarirati još jedan brojač, nego možete koristiti opet b jer ćete ga u for petlji ionako na početku postaviti na nulu, a gornja petlja se već izvršila, pa njoj brojač ne treba.

Toliko za sada, jer moramo biti sigurni da tkogod sve prati ovu temu, nizovi mu budu jasni prije nego što pređemo na druge oblike polja. A i moram na fax :D

C
02-03-2010, 22:11
#include <stdio.h>

int main ()
{
printf("Zdravo svijete!!");

system("pause");
return EXIT_SUCCESS;
}
system ("pause"); je naredba koju inače nikad nisam koristio u kombinaciji s returnom, ali sam primijetio radeći u Dev-C++-u da bez nje program niti ne čeka da korisnik pritisne tipku, već samo izađe iz programa. Osnovno govoreći, ovo je jedna od system funkcija, u ovom slučaju čeka korisnikov "odgovor" kod izlaska iz programa.

Sorry, da ti dam jedan hint, koji ti je puno bolji od ovog tvojeg glede pauze. ;)

Naime, bez te pauze, program se toliko brzo builda, pokrene i ugasi, da naše oko ne vidi tu brzinu, pa nam izgleda da se nije ništa pokrenulo. Ne znam dali u funkciji pause C# podržava >nul komande, ali kako god, probaj ovako:

Znači, ispod #include <stdio.h>, dodaj još jedan file #include <conio.h>, i onda ispod desi po main-u.
S time, da pri kraju cijele te funkcije, znači red prije nego li zatvoriš tu funkciju s "}", ubaci komandu getch();, i biti će ti puno bolje.

Evo, ja ću samo u ovo što sam rekao editirati tvoje, znači ispalo bi ovako:


#include <stdio.h>

int main ()
{
printf("Zdravo svijete!!");

system("pause");
return EXIT_SUCCESS;
}



#include <stdio.h>
#include <conio.h>
main()
{
printf("Zdravo svijete!!");
getch();
}

Probaj, pa javi dojmove. Isto je kao pauza, ali u biti nije pauza, i nema texta press any key to continue i sl. :)

I BTW, ne znam šta će ti int funkcija za printf. :)

cham3leon
02-03-2010, 22:32
Dakako, mogla je biti void, ali to je samo stvar navike... Osim toga, funkcije još nisam spominjao pa da ne kompliciram bezveze.

Dobar hint, osobno sam mnogo više programirao u linuxu gdje mi nikad nije trebao nikakav system("pause"), ali kužim i što postižeš sa getch(). U C-u se zna dogoditi dosta poteškoća i bugova s tim pauziranjem, odnosno kad program ne čeka unos tamo gdje bi trebao, ali to je kako gdje.

cham3leon
20-04-2010, 15:52
Matrice

... su jednostavno rečeno također nizovi, samo što su predstavljeni u dvije dimenzije. Što to znači? Ukratko, umjesto da imamo ovo:

1 2 3 4 5 6 7 8 9

Imamo ovo:

1 2 3
4 5 6
7 8 9

Dakako, matrica vam može imati dimenzija koliko god hoćete, ali ako ćete i koristiti matrice, uglavnom će to biti dvodimenzionalne koje su ujedno i najlakše za zamisliti u glavi. Dobro bi bilo spomenuti kako je računalu potpuno svejedno radi li se o jednodimenzionalnom ili dvodimenzionalnom polju, zapisuju se na isti način, ali to sad i nije toliko bitno.

Matrice definiramo ovako:


int matrica[3][3];

Primjećujete da smo stavili dva parametra u uglatim zagradama. Dok je kod nizova parametar označavao duljinu niza, njegovu jedinu dimenziju, kod matrice dva parametra određuju njezine dvije dimenzije, nazovimo ih duljina i širina, kako već volite.

Odmah je jasno da se elementima pristupa na isti način u kodu. Evo jednog primjera algoritma za upisivanje elemenata u matricu 3 x 3:


#include <stdio.h>
#include <stdlib.h>


int main()
{
int a[3][3], b1, b2;

for (b1 = 0 ; b1 < 3 ; b1++)
{
for (b2 = 0 ; b2 < 3 ; b2++)
{
printf("Upisi element broj %d-%d", b1, b2);
scanf("%d", &a[b1][b2]);
}
}

system("pause");
return EXIT_SUCCESS;
}


Dok je kod niza jednostavno samo provući naredbe za upisivanje vrijednosti kroz for petlju koja se vrti određeni broj puta, ovdje je nešto kompleksnije, ali i dalje ništa strašno. Za dvije dimenzije potrebna nam je dvostruka petlja. Pošto je matrica kvadratna, znači ima jednako redaka i stupaca, obje će se petlje odvrtjeti jednaki broj puta, tri, od nultog do drugog člana sa dva brojača b1 i b2. "Vanjska" petlja će se pomicati, recimo, po stupcima, i u svakom stupcu će se "unutarnja" petlja odvrtjeti po svim recima, nakon toga se vanjska pomiče, i tako dalje sve do zadnjeg stupca i retka. Unutar svega toga je klasičan par printf-scanf gdje smo u ovom slučaju naglasili o kojim se "koordinatama" unutar matrice radi, a scanf funkcija zapisuje korisnikov broj u zadani član.

Ako netko i dalje prati, probajte dodati još dvije petlje na isti način koje će ispisivati sadržaj matrice u čitku formu (dakle, kao tablicu).

C
21-06-2010, 09:23
Kameleon, treba mi nešto za jedan virus, a nemam blooda, niti jednog drugog alata pri ruci, a promet sam napunio, pa mi ajde please napiši kôd koji će ispisivati broj od 0000 do 9999 u svakom redu počevši s "<1024>" i završavajući s " >N".
Znači:

<1024>0000 >N
<1024>0001 >N
<1024>0002 >N
<1024>0003 >N
...
<1024>9996 >N
<1024>9997 >N
<1024>9998 >N
<1024>9999 >N
Kod je jako kratak, printf sa i-em, \n, "<1024>" i " >N", prije toga i=0000, if ako i nije jednak 9999, i++, i to je to. Nešto iskemijaj, pa uploadaj, ako može. :)

Edit: Nemam ideje za 0001, ako ne možeš nešto iskemijati s nulama, onda neka bude od 1 do 9999, najjednostavnije. :)

<1024>0 >N
<1024>1 >N
<1024>2 >N
<1024>3 >N
...
<1024>66 >N
<1024>67 >N
<1024>68 >N
<1024>69 >N
...
<1024>966 >N
<1024>967 >N
<1024>968 >N
<1024>969 >N
...
<1024>9996 >N
<1024>9997 >N
<1024>9998 >N
<1024>9999 >N

cham3leon
21-06-2010, 11:19
Znači, ovako nešto?



#include <stdio.h>
#include <stdlib.h>

int b;
int main()
{

for (b = 0 ; b <= 9999 ; b++)
{
printf ("<1024>%.4d >N\n", b);
}
system("pause");
return EXIT_SUCCESS;
}



To ti je ako ti treba da je svaki u novi red, ako to ne treba, onda makneš \n iz printf naredbe.

I prestani raditi viruse, ti zla osobo.

C
21-06-2010, 11:41
Da.

Problem je što mi treba kompajlirano, rekoh da nemam nikakav program uz sebe za programiranje (kompajliranje). :)

Ma ja sam jedan veliki virus. :D

Edit: Ajde neka mi netko to kompajlira i pošalje. Nisam lud da pišem brojeve od 0 do 9999 ručno.

cham3leon
22-06-2010, 10:02
Evo exe:

http://www.2shared.com/file/eaBybyya/Project1.html

C
22-06-2010, 10:19
Super, ali ima problem, dobijem ispisano samo zadnjih 300 redova, tj. od broja 9701 do 9999, plus pauza. Mislim, on sve ispiše, ali zadnjih 299 brojeva mi je jedino vidljivo, pa ih ne mogu sve obilježiti/selectati i kopirati. :(
Znaš li kako napraviti da taj printf ispisuje u file? Ili možda imaš neku drugu ideju? ^^

cham3leon
22-06-2010, 10:29
Ah, nisam se uopće sjetio toga! Smislim nešto pa napravim sad začas.

C
22-06-2010, 10:35
Čekaj, stani, ne moraš!
Evo, preko batcha (iz tvog Project1.exe fajla) sam izvukao sve. :D
http://www.2shared.com/document/7yFYe5or/save.html

Zahvaljujem ti. :)
Upravo si pridonio podzemnom svijetu virusa, jednog dana ćeš goriti u paklu s nama. :P

cham3leon
22-06-2010, 10:37
Napravio sam ja upravo jednu modificiranu verziju i uploadao, ali onda ok. Ako ti slučajno bude trebalo, this (http://www.2shared.com/file/H43TmZnZ/Project1.html).

C
22-06-2010, 10:47
THX, trebati će. :)
Virusa nikad' dosta.

Pomoću ovoga što si napravio, pomoću IZArc-ovog DLL-a, pomoću WinRAR-ovog DLL-a, pomoću mog starog virusa koji u arhivi zauzima 72 KB-a, a otpakiran zauzima 1024 MB-a (veoma se brzo otpakirava; otkrili su ga i nazvali "Bomber") ću sada napraviti da kreira 9999 takvih po 1024 MB-a, tj. zauzeti će 10 240 000 MB-a (1 TB) po folderu i to ultra brzo jer se brzo otpakirava (cca 10 sekundi za 1 GB), puniti će disk i nakon što ga se obriše/uništi (kao infekciju, jel'), a 1024.DLL fajlovi se neće moći tako lako pronaći i obrisati. Tako ću opravdati ime kojem su ga nazvali.
Pravo ime mu je "1024" (1000 MB = 0,99 GB; 1024 MB = 1,00 GB), a ne "Bomber." :kill:
Ako netko hoće biti tester, neka se javi. :D

cham3leon
22-06-2010, 10:51
Više ti ne pišem nikakve programe, pa makar ficleke od 10 linija koda kao ovaj.

C
22-06-2010, 10:55
He, he, pa ja ću ti prodati foru da mi je za fax DZ. :P
Da imam program, ne bi mi bilo teško sklepati nešto i kompajlirati, a ovi online kompajleri u koje napišeš ili paste-aš code i kompajliraš da ti pošalje file kojeg spremiš ne funkcioniraju sa svim kodovima, npr. ovaj gore code neće kompajlirati iz nekih svojih fora.

Edit: Evo, napisao sam virusa, ima 260 139 linija koda (ili ti ga 10 000 × 26), tj. 11 MB-a koda, plus ostali fajlovi nešto sitno (0,5 MB). ^^
To je glavni virus, sada mogu izvoditi kerefeke i napraviti backup, worma da se množi, start-upera, itd., ali ne da mi se, ovakav trojan mi je dovoljan. ^^

˘˘˘˘Angel˘˘˘˘
15-07-2010, 22:44
ajde c podjeli s nama source.. bas me zanima tih 11mb cistog koda.. ja kada sam radio na flash based mmou, radjen je preko godinu dana i imao sam svega 40 000 linija koda.. bas me zanima taj stil programiranja i kakva je to optimizacija ako ti za nesto tako jednostavno treba 250k linija djizus

C
16-07-2010, 03:15
Ne znam sada gdje mi je, ali to ti je ograničenje batcha, za svaku particiju trebam napisati code (jednostavni c/p/e), pa da on vidi koje particije ima (i da ju odere), a koje nema (pa da ju preskoči), i svakako, batchne podržava kodove poput X+1=X, pa da se to stalno vrti. Napisao sam 10 000 × 26, jer postoji 26 particija, od toga za svaku particiju je 10 000 linija bilo, pa možeš to idjeti i iz "260 139" linija koda, u biti nije bilo toga puno, eventualno ako se sastoji od 50 linija koda (izuzevši 9999, plus c/p/e).

˘˘˘˘Angel˘˘˘˘
16-07-2010, 12:22
a tek sam sad skuzio da je jezik dos :S to si moga puno jednostavnije i lakse napraviti u C++u
npr tamo ima podrska za dos (batch)

mogao si napraviti jednostavni loop
u kojem bi sa system("dos kod"); odradio dos dio, a loop bi odradio u C++u.. bilo bi max 11k linija koda. :P
edit : i nije x + 1 = x nego x = x + 1 :P

C
16-07-2010, 12:38
Da. Ali skužio sam da dosta toga on ne podržava od batcha u C-u.
I nije DOS jezik, nego Batch, razlika je velika. :P

˘˘˘˘Angel˘˘˘˘
16-07-2010, 14:35
a nezz nisam nikad radio u batchu..

majstoro
14-04-2011, 09:50
Kad probam ovaj kod u prvom postu uvijek pokazuje neku gresku

EDIT:nisam odabro console application sad je ok :D

majstoro
14-04-2011, 10:58
Posto mi je isteko edit,sry na dp-u,da pitam...
Pravim text based igru i zanima me kako da stavim ono da imaju opcije npr:
Raja te zove da igras lopte ti ces
1.pristati i igrati
2.ostati sjediti
nadam se da me kuzite

Gu$ht3r
14-04-2011, 11:59
objašnjeno ti je to na 2 strani tutoriala, sekcija grananje.

cham3leon
14-04-2011, 16:36
Plus, kad imaš više od 2 ili 3 grane svakako treba koristiti select - case grananje, koje sam koliko vidim iz nekog razloga na 2. stranici threada nazvao "switch - case", ne znam točno otkud mi to, možda iz VB-a ili nečeg. Dakle nije switch nego select. Isprike.

Kostolomac
14-04-2011, 16:53
Da nisi možda switch case pokupio iz VHDL-a na Digitalnoj Logici?

cham3leon
14-04-2011, 18:30
Teško jer taj VHDL nisam znao i neću znat, nije mi se dalo zajebavat s time, prošo sam i bez toga xD

Btw, krenut ću dalje uskoro sa tutorialom. Bio bi red.

Gu$ht3r
14-04-2011, 18:57
mozda switch-case ima neke veze s linuxom, jer su nas tako ucili switch case, ne select case.

cham3leon
14-04-2011, 20:02
7. Pointeri (pokazivači)

E sad, ako ste svladali sve ovo do sada, možda mislite da je C jezik mačji kašalj, ali zato su tu pointeri da vas uvjere u suprotno :>
Naravno, malo pretjerujem, ali ovo je već nešto malo napredniji koncept u programiranju za koji obično treba naučiti razmišljati na jedan drukčiji način.

Prije svega moramo se malo upoznati sa načinima manipuliranja računalnom memorijom koje nam C nudi i osnovnim principima funkcioniranja iste. Kad kažem "memorija" mislim na primarnu ili radnu memoriju, a to su kao što većina vas zna oni keksići utaknuti u matičnu ploču. Naime, radna memorija za razliku od hard diska ne pohranjuje trajno podatke, već samo dok je pod naponom, odnosno dok računalo radi. Njena funkcija je da se u nju privremeno pohranjuju svi podaci koji su potrebni dok se izvodi neki program, a to znači da se svaka varijabla koju ste deklarirali smješta na određeno mjesto u memoriji tokom izvođenja vašeg programa i zauzima određeni prostor u njoj. Koliko mjesta će zauzeti zavisi o tipu varijable. Tako će znak, odnosno character varijabla zauzeti jedan bajt u memoriji, a integer 4 bajta. Svaki character i integer kojima se tako rezervira mjesto u memoriji dobit će adresu za svoj dio memorije (bez obzira koliko je bajta taj dio velik).

Pointer je naime varijabla, ali čiji je sadržaj adresa neke druge varijable. Zbunjeni? Evo slič'ca:

http://i.imgur.com/wp3ke.png

Imajte na umu da se pointer p ne razlikuje od obične varijable, i on ima neku adresu i sadržaj, ali taj sadržaj je adresa neke druge varijable tog tipa (pointer također mora biti određenog tipa podataka i potom može pokazivati samo na taj isti tip podataka; ako je character tip pokazuje samo na varijable koje zauzmu jedan bajt, a ne na one koji uzmu primjerice 4 bajta).
I da, možete potom stvoriti još jedan pointer koji će pokazivati na pointer p, pa onda još jedan pointer koji će pokazivati na taj pointer... Inception. Ali počnimo mi od početka.

Pointer jest varijabla, ali svejedno morate označiti da se radi o pointeru, a to ćete učiniti dodavanjem asteriska (*) ispred imena pointera:

int *p;

Asterisk i ampersand (* , &) su dva operatora koja morate znati koristiti kad baratate s pointerima. Osim za deklaraciju, * će služiti u samom programu kad budemo htjeli iskoristiti ne sadržaj neke varijable, nego sadržaj druge varijable koja se nalazi na adresi sadržanoj u našoj varijabli. U ovom primjeru sa b i p u kojem p sadrži adresu od b, a b sadrži vrijednost 100, ako pozovemo ispis p, ispisat će se adresa varijable b, a ako pozovemo ispis *p, ispisat će se vrijednost 100.

& ispred varijable pak znači da umjesto sadržaja te varijable tražimo adresu, odnosno ako pozovemo ispis &b dobit ćemo rezultat 6, njegovu adresu.

Ispravan način da natjeramo p da pokazuje na b jest:

p = &b;
A ako hoćemo preko pokazivača p promijeniti b...

*p = 200;
Slobodno probajte i igrajte se s tim.

Ovo zasad zvuči doista glupo, previše komplicirano i nepotrebno, ali je jedini način za rješavanje nekih dosta kompleksnijih zadataka, pa svaki iole ozbiljniji C programer mora poznavati aritmetiku pokazivača. Budući da nismo još daleko došli, jedini koristan primjer kojeg možete razumjeti jest uporaba pointera kod matrica i nizova.
Naime, ako se vratimo na prikaz memorije kao niza kvadratića, dvije varijable uopće ne moraju biti jedna do druge u memoriji, ali array (niz/polje) i matrica je uvijek "na kupu", odnosno članovi niza/matrice su uvijek jedan do drugoga. To znači da ako imamo pokazivač p koji pokazuje na nulti element nekog niza, ako ga povećamo za 1...

p = &niz[0];
p = p +1; // (može i p++;)
... pokazivat će nam na prvi element niza. Zapravo, svaki niz i matrica su pokazivači, ovaj sistem sa navođenjem željenog elementa niza u uglatim zagradama je tu za programera da mu malo olakša stvar.

Ne mogu se sjetiti nekog konkretnog zadatka vezanog za pokazivače a da opet nema nizove i matrice jer je to prejednostavno. Njihovu pravu funkciju ćemo vidjeti uskoro. Ipak, možete probati kako pointeri funkcioniraju, šetati s njima po nizovima i matricama i tako dalje.


NAPOMENA: Izgleda da je ono ipak switch case. Select je valjda u C# i sličnim programskim jezicima. Ispričavam se, nebrojeno puta mi se dogodilo da ne znam je li switch ili select :/

Delirium
14-04-2011, 20:23
koji epski ress, GG anyway, do continue

majstoro
14-04-2011, 20:42
Đizs Krajst :shock: Svaka cast xD

Nego,napravio sam nesto od txt based igre i kako da ja napravim .exe file od toga da prijatelji mogu skinuti i probati to?

cham3leon
14-04-2011, 20:57
Nisam siguran, inače ne koristim DevC++, ali svakako prvo ono što si napisao mora biti dio nekog projekta. Kad napraviš projekt i dodaš u njega taj fajl koji si napisao (ako već nije u projektu), desni klik na projekt, properties i tamo na prvom tabu ti piše output file path - to je adresa za exe, vjerojatno ga napravi nakon compileanja.

majstoro
15-04-2011, 10:32
Samo mi se stvorilo u .exe fileu

Nego o5 ja sa pitanjima :D

u ovoj igri viewtopic.php?f=45&t=33610&start=0 (http://www.pcplay.hr/forum/viewtopic.php?f=45&t=33610&start=0)
Koji je kod da ako pogrijesi da ga vrati na to pitanje kao 2x2+2 =?,ti upises 8 da mu izbaci Sry,that's not correct,please try again!

druga stvar,kako da stavim(da se vratim na isti primjer),2x2+2=?,trazio sam na googleu ali on izbaci samo sa opcijama,to i ja znam napravit,nego zelim igru napraviti malo zabavnijom a ne da milijunaš napravim :D

cham3leon
15-04-2011, 11:52
Misliš, da te pita unedogled to pitanje dok točno ne odgovoriš? Najbolje bi bilo staviti pitanje unutar beskonačne petlje (while (1)) i onda u slučaju točnog odgovora da se izvrši naredba break; koja prekida petlju.

ovo drugo sad ne razumijem, šta želiš napravit?

majstoro
15-04-2011, 12:00
Vako,recimo stavim pitanje Sudjelujete u trci. Pretjecete drugu osobu. Na kojemu ste Vi mjestu? HINT:Napisi brojem
I normalno on ce napisati 2

Ja sam tu zagonetku napisao ali kako nisam znao kako da stavim da moras brojem upisat ja sam samo 1.prvi,2.drugi pa mi igra ispadne ko milijunas :D

Znaci zelim da postavim pitanje koje on mora bez opcija odgovorit

cham3leon
15-04-2011, 12:20
Pa... ne navedeš nijednu opciju nego napišeš taj broj ili riječ...

Aha, kužim, ti bi htio da korisnik može upisat neku riječ?

majstoro
15-04-2011, 20:32
Da to,evo u gamerovoj igri moras upisati www.google.com,tako (http://www.google.com,tako)Si ja zelim da rijec moras upisat

cham3leon
15-04-2011, 22:16
A ono što ti treba su stringovi, koje sam eto trebao ubaciti odmah poslije redova i matrica, ali nije problem, to ću staviti kao iduću lekciju, valjda ću je sutra napisat...

Sonic_Moronic
16-04-2011, 14:00
E onako, neznam gdje da pitam. Pretpostavljam da bi, kad pohvatam osnove u Qbasic-u, trebao prijeći na neki bolji programski jezik, što bi mi preporučili? Ovaj C+++ mi se čini dosta kompliciran, jel' ima nešto jednostavnije a ipak ne ograničeno kao Q?

cham3leon
16-04-2011, 15:11
Pa, zavisi koliko daleko želiš ići. Korisna stvar u svim ozbiljnijim primjenama danas je objektno orijentirano programiranje koje funkcionira nešto drukčije od ovog proceduralnog koje možeš naučiti u Qbasicu ili C-u. Ako budem radio još jednu ovakvu temu, vjerojatno ću staviti neki objektno orijentirani jezik. Filozofija OO programiranja je nešto drukčija i bilo bi dobro da se vješto snalaziš u "običnim" proceduralnim jezicima.

C i C++ se čine komplicirani jer su to relativno niski programski jezici, baš se sad u ovoj zadnjoj mini-lekciji vidi da se u C-u često manipulira memorijom, ne samo u vidu pointera nego je ponekad potrebno i određenim naredbama alocirati (rezervirati) memorijski prostor, osloboditi ga, i tako dalje. Većina današnjih popularnijih jezika je na dosta višoj razini pa tako obično te stvari rade automatski, čak kod deklaracije varijabli nije potrebno definirati tip varijable, a ponekad nije potrebna ni sama deklaracija. Vjerojatno je najinteresantniji Python koji je sve popularniji i predviđa mu se svijetla budućnost, ali ako se ne varam i on je objektno orijentirani jezik tako da treba prvo pohvatati neke principe OO programiranja.

I inače, tkogod se misli zaozbiljno baviti programiranjem ne bi trebao stalno mlatiti po istom, nego konstantno učiti neke druge nove stvari i razviti vještinu snalaženja u novim jezicima i tehnologijama, što i nije baš toliko teško jer uz kvalitetan pristup internetu i Googleu imaš na raspolaganju stotine tutoriala i manuala.

Sonic_Moronic
17-04-2011, 00:16
Oke, budem probao Python.

Ali evo recimo da bih htio napraviti oldskul textualnu igru, baziranu na komandama, što bi mi bilo najbolje za to?

majstoro
17-04-2011, 18:59
Koja je razlike izmedju printf i cout komande?

cham3leon
17-04-2011, 19:07
Mislim da cout nije dio stdio.h libraryja kojeg ovdje koristimo. Ne znam da li se uopće može koristiti u C-u. Naime, stdio.h je za ovo što mi radimo osnovni library jer sadrži printf, scanf itd. Koja je točno razlika ne znam, jer koristim isključivo printf funkciju.

@Sonic: Za text based igre bi trebalo biti dobro bilo što. Ali pretpostavljam da je iz određenih razloga bolji OO pristup pa tu opet uskače taj Python. Što se tiče nekakvih grafičkih igara, za to je prvo potreban neki engine koji će to iscrtavati i tako dalje, ali to neće biti dio ovog tutoriala.

majstoro
17-04-2011, 19:15
Aha,evo gledam malo po googleu o txt based igrama i pronadje ovako nesto

cout <<"\tWelcome to my text based game!\n";

cham3leon
17-04-2011, 19:28
Jednostavne txt based igre su dobar testni poligon za neke jednostavnije stvari koje smo obradili, ali ako se interesirate za pravljenje igara, morat ćete se dobro strpiti, jer ovo su tek osnove koje će trebati primjeniti negdje. Volio bih jednom napraviti i tutorial za neki engine ili python igre, ali nažalost nisam dovoljno iskusan u tom polju, nije to baš u mojem spektru interesa.

Gu$ht3r
17-04-2011, 19:33
zar nije cout za C++ sto je printf za C?

cham3leon
17-04-2011, 19:37
Vjerojatno. Nisam radio u C++ tako da ne znam.

Burek_fr0m_SPACE
17-04-2011, 22:29
zar nije cout za C++ sto je printf za C?
Moglo bi se reći. Oba služe za ispis na standardni izlaz, ali ispod haube rade dosta drugačije.

majstoro
18-04-2011, 09:09
Meni je najveci prolem kreativnost kako bi napravio nesto dobro.
Nikad nisam imao smisla za mastu da napravim nesto kreativno.
Sad igru krenem,super pocetak i zastanem jer mi ponestane ideja :D a inace sam vise VL nego RL tip :D draza mi je fantazija i tako...

majstoro
19-04-2011, 19:35
Da li je moguce napraviti da pise press any key to continue i da se nastavi text?Znaci ne da se izgasi igra nakon sto se to pokaze nego da se tekst nakon toga pokaze.

Burek_fr0m_SPACE
19-04-2011, 20:26
Ako si na Windozu :


#include <stdlib.h>
...
system("pause");
return 0;
}

Sonic_Moronic
19-04-2011, 21:03
E kak je ovo zakon, koristeći samo PRINT, INPUT, IF komande i par varijabli, napravio sam jednostavnu kockarsku igru. Imaš početnih 500 kredita, upišeš okladu, program baca 2 kocke, ako je zbroj jednak okladi, dodaje se 50 kredita u dobitak, inače se oduzima. Ako dobitak padne na 0, igra završava. Nisam ni znao da je ovak jednostavno :pray:

Sad dodajem nove oblike klađenja :)

Definitivno sad vidim gdje je čar u programiranju, mogao bih zapeti za ovo.

majstoro
19-04-2011, 21:06
De objasni te input i IF :D

Sonic_Moronic
19-04-2011, 21:11
Pa imaš to objašnjeno u ovom topicu... 4. stavak. Ja radim u QBasicu i ne znam u kojoj se mjeri to razlikuje, pa ti nemogu dat primjere.

majstoro
19-04-2011, 21:23
Ako si na Windozu :


#include <stdlib.h>
...
system("pause");
return 0;
}
nekontam to nikako,gdje da ja to stavim,kad usred igre stavim pise mi greska neka
probam same 3 tocke nece ,probam #include <stdlib.h>
...,greska opet

cham3leon
19-04-2011, 21:24
Unutar main funkcije u svakom slučaju. Poslije ispisivanja teksta.

Burek_fr0m_SPACE
20-04-2011, 00:02
#include <stdio.h>
#include <stdlib.h>

int main()
{
int a, b, c;
printf("Blablabla");
if(nesto > nestoDrugo)
printf("nesto trece");

system("pause");
return 0;
}

Princip if-ova je isti u svim jezicima, ali se sintaksa C-a i QBasic-a osjetno razlikuju. Daj primjere, prevešće neko.

Tegla Ajvara
20-04-2011, 09:07
jel ko od vas html-aš?

Delirium
20-04-2011, 16:14
Koji mi library treba za primitivne oblike tipa kvadrat neke boje koji se miče po ekranu?

Lord Ragnarok
19-05-2011, 14:19
kameleonce, jel ima di na netu kakv tut za c za rad s datotekama (sad smo pocli sa .txt fajlovima raditi)? malo bi htjel si to procitati/provjezbat jer nisam bas u toku sa predavanjima (citaj: nejdem na njih)

cham3leon
19-05-2011, 14:28
Hm, ne znam ni za jedan na netu. Nisam ni ja dugo radio s datotekama pa se moram prisjetit nekih stvari, ali u pravilu sa txt fajlovima ne bi smjelo bit problema. Napisao bih dio tutorijala za to, ali to je baš daleko od ovoga gdje smo sada, tako da...

Burek_fr0m_SPACE
20-05-2011, 04:08
Mislim da sam nešto od ovoga već kačio, ali evo ovdje (http://www.sendspace.com/file/u55r9d)Stekstovi koje sam kucao za svoje studente koji ne dolaze na vježbe. Između ostalog, tu je i sažetak rada sa fajlovima. Idi na predavanja, biće ti od koristi.

Lord Ragnarok
20-05-2011, 13:19
fala burek, bit ce dosta to materijala za pocetak. shvatio sam po vjezbama di je sta i sto je sta, a na predavanja mi se ne isplati ici jer profesor preveliku kolicinu teorije i svega prolazi u sat vremena sto ima za predavanje. jos da ne spominjem da dolazi dosta ekipe kaj nista ne prati i sam buci po ucioni.

majstoro
24-05-2011, 13:30
Kako da stavim da odabires u kojem ces smijeru ici,ono mozes da odaberes NORTH,WEST,EAST,SOUTH?

bonez
26-07-2011, 23:29
Jel mi moze neko reci kako pokrenuti program koji napises ? koristim Dev-C++.

MasaKrisT
26-07-2011, 23:35
ctrl+F9 kompajliranje
ctrl+F10 pokretanje

bonez
26-07-2011, 23:51
Fala :)

cham3leon
20-11-2011, 10:40
8. Stringovi

Eto, nakon velike pauze, uspio sam se odmaknuti od Skyrima i skupiti volje za nastavak tutoriala. Predugo nisam ništa postao ovdje. Još ovo moramo odradit u sklopu tih nizova i sličnog, jer je dosta bitno.

Dakle, string je samo najobičniji jednodimenzionalni niz kakav smo već prošli u ranijim koracima, jedino što nije definiran kao integer ili floating point, dakle nije kao što smo dosad radili:


int niz[10];

...nego je definiran kao character:


char niz[10];

Dakle, da - nema razlike, jedino što char polja odnosno nizove zovemo stringovi. Postat će nam pogotovo zanimljivi jer je to jedini način da se u programu pohrani neki tekst, riječ, čak i rečenica. Kao niz znakova. No, prije nego što se bacimo na neke praktične stvari sa stringovima postoje neke činjenice koje moramo pojasniti što se tiče character tipa varijable.

Integer tip varijable u memoriji uzima četiri bajta, a character samo jedan bajt, što će reći da character tip varijable za razliku od integera može pohraniti mnogo manje informacija. Budući da se jedan bajt sastoji od 8 binarnih znamenki, to znači da u njega stane 2^8 brojeva, odnosno od 0 do 255.
Da, brojeva. Zbunjeni? Kako se sad u character varijablu spremaju brojevi, a rekao sam da služi za pohranjivanje slova i drugih znakova? Jednostavno. Kao što znamo, u računalnoj memoriji spremaju se isključivo brojevi, i to u binarnom obliku, što znači da ne možemo u memoriju fizički zapisati neko slovo. Stoga i naša character varijabla ne može sadržavati ništa drugo doli brojeva. I kako ćemo mi sada u nju spremiti slovo, pitate se. Kao što ste možda već i zaključili, spremat ćemo ih kao brojeve, ali sa nekim kodom koji će nam govoriti koji broj odgovara kojem znaku. Gdje i kako ćete saznati koji broj znači koji znak?

http://www.asciitable.com/index/asciifull.gif

ASCII standard definira koji broj se pridružuje kojem znaku, a ovo gore je uobičajena ASCII tablica koju treba imati kraj sebe svaki put kad radite sa stringovima.
Naravno, da biste pisali u char varijablu ili čitali iz nje, ne trebate gledati u tablicu i pisati/čitati isključivo brojeve. Kako biste zapisali veliko X u jednu char varijablu, obje naredbe koje slijede napravit će isto:



c = 88;
c = 'X';


S obzirom na to da smo c prethodno deklarirali kao char c; naravno.
Stavljanje slova u jednostruke navodnike je zamjena za njegovu ascii vrijednost, pa je ovako mnogo jednostavnije raditi sa znakovima. Naravno, ovu istu foru možete iskoristiti kad znakove uspoređujete, dakle, možete raditi ovakve stvari:


if (c == 'X')
{
nesto;
}

Sad je već mnogo jasnije, zar ne? Krenimo onda reći ponešto o stringovima.
Jedna stvar koju treba zapamtiti što se stringova tiče jest da ih se ne zapisuje baš ovako kao i svaki drugi niz. Naime, string mora završavati jednim specijalnim znakom koji se piše ovako: '\0' (beksleš-nula). Taj znak se zove terminator stringa, ili nul-terminator, a možda ima i još nekih naziva. Njegova ascii vrijednost je nula, a uz pomoć njega možemo odrediti gdje je stringu kraj, tako da kod čitanja, funkcija koja čita string može odrediti gdje prestaje smisleni dio i informacija koju treba očitati i počinje ono što ju ne bi smjelo zanimati, a nalazi se na idućim memorijskim adresama.
Zbog terminatora stringa uvijek moramo računati da ostavimo mjesto za jedan znak više, zato jer kad budemo htjeli u neku varijablu napisati "kameleon", zapravo će se u nju zapisati "kameleon\0". Pogledajte sada ovo:


#include <stdio.h>
#include <stdlib.h>

int main ()
{
char c [9]S= "kameleon";
char *pokazivac;

pokazivac = c;

while(*pokazivac != '\0')
{
printf("%c", *pokazivac);
pokazivac++;
}
printf ("\n");
return EXIT_SUCCESS;
}



Ovo se mislim moglo i elegantnije riješiti, ali možda bi vas neke stvari zbunile, pa da ne zapinjemo na tome. Recimo, niz (pa tako i string) je zapravo isto što i pokazivač. U ovom slučaju c je zapravo samo pokazivač ispred kojeg je rezervirano još 9 mjesta u memoriji u kojima će slovo po slovo pisati "kameleon\0", a kad kažemo da želimo dohvatiti c[5], kompajler će srediti da se pokazivač c pomiče do petog elementa niza i dohvati slovo sa te adrese. Iz tog razloga sam jednostavno mogao napraviti pokazivač "pokazivac" i samo napisati da je jednak c-u. To znači da "pokazivac" sada pokazuje na početak stringa "c".
U petlji smo jednostavno napisali da se ispisuju slova u formatu %c%c%c... i tako dalje, dakle bez razmaka, tako da doista dobijemo riječ, i u svakoj turi se pokazivač miče za adresu naprijed, na iduće slovo. Ovaj printf na kraju nam je samo ubacio novi red nakon ispisane riječi da to sve djeluje nekako urednije.

A sada ćete vidjeti da je to moglo mnogo jednostavnije.


#include <stdio.h>
#include <stdlib.h>

int main ()
{
char c [9]S= "kameleon";

printf("%s", c);

printf ("\n");
return EXIT_SUCCESS;
}



Iznenađenje, ne? Ne trebamo petlju i ne trebamo ispisivati znak po znak, nego jednostavno u printf funkciji koristimo format specifier %s, što znači string. Taj će nam pročitati cijeli znakovni niz do string terminatora, razmaka, ili novog reda.

Uf, toliko za sada, popodne ću još napisati nastavak, ima još stvari koje treba proći oko stringova.

Napomena: Ovaj put sam programirao sve u Linuxu, tako da tu i tamo možda fali neka system("pause") komanda, ali znat ćete već gdje bi se to trebalo nalaziti, ne?

cham3leon
20-11-2011, 17:23
Okej, nastavak.

Ako probate nešto slično ovome i napišete neki svoj kod koji će očitavati rečenice, primijetili ste da će vam

scanf("%s", &mojstring)

u vaš string zapisati samo prvu riječ rečenice. To je zato jer će scanf na ovaj način očitati tek slova do prvog razmaka. Postoje neke finte kako preko scanf pročitati i razmake koje korisnik upiše, ali nije preporučljivo, jer kad radite takve stvari često se može dogoditi da vam je prostor koji ste rezervirali za znakovni niz premalen u odnosu na ono što bi korisnik mogao upisati, pa bi se moglo dogoditi da se prepišu adrese koje dođu iza toga što se nikako ne smije dogoditi.

Umjesto toga, postoji primjerice fgets funkcija koja izgleda ovako:


fgets(niz, DULJINA, stdin);

...gdje je "niz" neki znakovni niz u koji ćemo spremiti pročitani string, DULJINA označava veličinu tog niza (mora unaprijed biti dovoljno velik za sve što bi korisnik mogao upisati), a stdin znači "standardni ulaz", a to je upis na konzoli, dakle, svaki put kad ovu funkciju pišete da biste očitali ono što je u komandnoj liniji korisnik napisao, ovdje vam mora stajati stdin.

Također, pošto se većina ljudi koji čitaju ovaj tutorijal zabavljaju sa tekstualnim avanturama, neke bi posebno moglo zanimati i ovakvo dohvaćanje stringova:


scanf("%s %s", &string1, &string2)

Da, ovdje koristimo ponovo scanf, ali na malo drukčiji način. Ovdje smo rekli scanf funkciji da čita korisnikov input u formatu riječ, razmak, riječ, i to onda povučemo kao dva odvojena stringa. To je za tekstualne igre vjerojatno najbolja metoda jer se obično od igrača traži da napiše neki glagol da označava radnju koju želi napraviti, što će se spremiti u prvi string, i objekta na kojoj se ta radnja vrši što će se spremiti u drugi string.

Isto tako postoje neke stvari koje često želimo raditi sa stringovima, a za koje već postoje napisane funkcije. Te funkcije se nalaze u libraryju string.h koji morate includeati na početku programa ako hoćete koristiti njegove funkcije.

A to su:

strcpy (string1, string2) - kopirat će string 2 u string 1
strlen (string) - vratit će duljinu stringa ( o funkcijama i kako one vraćaju vrijednosti, pričat ćemo kasnije)
strcmp (string1, string2) - dosta korisno - usporedit će string 1 i string 2 i vratiti nulu ako su isti
strcat (string1, string2) - dodat će sadržaj od string2 na kraj string1

... i još nekoliko drugih koje možete vidjeti ovdje:

http://www.cs.cf.ac.uk/Dave/C/node19.html

Imajte na umu da na programiranju na fakultetima obično budu zadaci da se napiše funkcija koja uspoređuje stringove, ili dodaje string na kraj drugog stringa, a zabrani se korištenje libraryja string.h, što znači da praktički ove strcmp, strcpy i druge morate pisati sami. Ako bude potrebe za tim, možemo i neki takav primjer napraviti.

Falus
26-10-2012, 22:45
Sumnjam da itko jos prati ovo ali ajmo probat. Koristim se Ms Visual studiom 2010, unutar kojeg biram c++ ali koristim <stdio.h>, printf, scanf... pa ne znam u kojem sam programu :D Ugl. Pitanje u vezi struktura, koja je razlika u:

typedef struct student
{
char ime[32];
char prezime[32];
int brojBodova;
};

i


struct student
{
char ime[32];
char prezime[32];
int brojBodova;
};

ili pak


typedef struct student
{
char ime[32];
char prezime[32];
int brojBodova;
}student1;

ili na kraju


typedef struct
{
char ime[32];
char prezime[32];
int brojBodova;
}student;

Pretpostavljam da sam neke mozda i krivo napisa, ali sam po internetu, pdf.ovima, knjigama nasa vise razlicitih nacina zapisivanja tako da mi se sve skupa izmijesalo :D

cham3leon
26-10-2012, 23:00
typedef nije zapravo potreban kod definicije struktura. To je ključna riječ kojom definiraš "novi" tip podatka od nečega. Može se kasnije u kodu za svaku novu varijablu iznova navoditi "struct student", ali da bi bilo urednije, obično se napravi typedef pa nazoveš taj "struct student" nekako drukčije. E sad, ja sam ga uvijek radio tako da sam prvo napisao struct student, pa ova definicija polja i sve, pa onda:

typedef struct student učenik;

...čime dobijem tip varijable učenik koji će bit zapravo struktura "student". Ne znam što bi se točno dogodilo ako napišeš ovako ko u prvom slučaju, da li bi student onda automatski postao type pa bi se varijable s njim mogle odmah definirati kao "student nešto;" bez ključne riječi struct. Trebalo bi probat. Ako se ne varam, zadnji primjer ti je isto to, samo što možeš navesti ime strukture na kraju. Međutim, slučaj #3, odnosno kad si već dao gore ime strukture, a staviš još nešto poslije vitičaste zagrade, znači da želiš odmah instancirati neke varijable nakon definicije strukture. U ovom slučaju imat ćeš odmah varijablu student1 koja je tipa strukture student.

Falus
26-10-2012, 23:09
A ako napisem shemu po drugoj opciji, znaci struct student, i kasnije ovo sta si navea typedef... jel mi se moze isto zvat tip varijable u prvom i drugom slucaju? Znaci jel mogu stavit struct student {...}; pa onda typedef struct student student; ? I mnogo hvala na brzom odgovoru :D!

cham3leon
26-10-2012, 23:13
Ne možeš. O tome treba vodit računa da znaš kako ćeš nazvat strukturu, a kako type.

Falus
26-10-2012, 23:23
Neizmjerno hvala na kratkom i jasnom objasnjenju :thumbs2: Izgleda da moze i sa typedef struct student {...}; I napokon da uvidim razliku izmedju typa i strukture. Znaci u tvom slucaju sta si navea Ucenik bi bija type a student ime strukture? Samo cu to jos pitat :D

cham3leon
26-10-2012, 23:49
Da, tako je.

Falus
26-11-2012, 17:02
Jedno kratko pitanje o prioritetima operatora.

++ -- Suffix/postfix increment and decrement Left-to-right

++ -- Prefix increment and decrement Right-to-left

Što ovo točno znači glede prioriteta operatora? Općenito me to bunilo oduvijek, a sad se opet vraća :D

cham3leon
26-11-2012, 17:49
Pa iskreno to meni nije ni dan danas sjelo. Trebalo bi se raditi o razlici ako operator ++ staviš prije imena varijable ili poslije njega. Na primjer prema tome a++ nije isto što i ++a, iako oba naravno rade istu stvar - inkrementiraju varijablu. Ovaj prefiksni tip bi trebao inkrementirati varijablu prije drugih operacija, a sufiksni obratno, ali sad nisam ziher da li for petlja koja ima u koraku prefiksni tip prvo inkrementira broj pa izvrši kod unutar zagrada, ili je svejedno koji tip se koristi. Ali uglavnom, postoje sigurno neki slučajevi gdje ćeš dobiti različite rezultate zavisno gdje staviš ++.

SharpDressedChevap
26-11-2012, 20:38
Cham, očekuj neka pitanja kroz slijedeću godinu, počinje mi programiranje :)
Jel uopće bitna razlika C i C++, nešto mi je i Del govorio o tome?

cham3leon
26-11-2012, 20:50
C++ je "samo" nadogradnja na C koja donosi neke dodatke, naprednije tipove podataka, i ono najvažnije, objektno orijentirano programiranje.
Mada ono što Carp radi na faksu u C++ nema prevelike veze sa OOP, oni rade iste stvari koje bi se mogle napraviti u C-u, samo što koriste funkcije koje su sastavni dio C++.