Professional Documents
Culture Documents
RLogozar UvodUProgIJezikeCCppVjezbe PDF
RLogozar UvodUProgIJezikeCCppVjezbe PDF
Uvod u programiranje
i
jezik C/C++
Vježbe
Uvod u programski jezik C/C++. Vježbe 1
Predgovor
Vježbe 1 iz programskog jezika C/C++ temelje se i sadržajno slijede udžbenički tekst Uvod u prog-
ramski jezik C/C++ [1]. Namijenjene su izvođenju vježbi na uvodnim kolegijima programiranja na
višim i visokim učilištima. Slijede uobičajeni pristup izlaganja gradiva u kojem se najprije savladava-
ju osnove proceduralnog (funkcijskog) programiranja, što se u bitnom izvodi primjenom jezika C
kao podskupa objektno orijentiranog jezika C++, ali koristeći sintaksu i specifičnosti jezika C++, te
suvremene razvojne okoline za rad s njima.
Osnovne ideje vodilje kod izbora zadataka obrazložene su u uvodu navedenog udžbeničkog teksta
[1]. Gdje god je to bilo moguće, pogotovo u kasnijim vježbama, nastojali smo privući čitatelja zanim-
ljivim problemima. Ponovimo ovdje ukratko da smo nastojali odabrati zadatke prikladne za određenu
temu, nastojeći ujedno da njihova rješenja budu i uzorna i primjenjiva u širem kontekstu.
Nadamo se da će upravo problemski pristup kojim se rukovodimo kroz ove primjere i zadatke, po-
nukati mnoge studente da dublje uđu u područje programiranja i računarstva.
i
ii
iii
Sadržaj
Uvod u programski jezik C/C++. Vježbe 1.......................................................i
Predgovor ..............................................................................................................i
I. Uvod ........................................................................................................... 1
I.1 Vježbe iz programiranja .......................................................................... 1
I.2 Samostalnost u radu ................................................................................. 1
I.3 Dnevnik vježbi ........................................................................................... 2
I.4 Pripreme za vježbe ................................................................................... 3
I.5 Citiranje literature.................................................................................... 4
I.6 Etički kodeks ............................................................................................. 4
Vježba 1. Osnovni pojmovi u programiranju. Organizacija rada na
računalu 6
1.1 Algoritmi, programski jezici, programi i programiranje ...................................... 6
1.2 Organizacija rada na računalu ................................................................................ 8
1.3 Rezime i zaključak vježbe Vježba 1......................................................................... 9
*
Engl. termin je “hands on”, dakle ruke su na računalu, programiramo koristeći prikladne softverske alate.
1
2
Prilikom samostalnog rada, student mora nove spoznaje usklađivati sa svojim temeljnim znanjima
usvojenim iz prethodnog školovanja. U tom procesu produbljuje i sređuje prethodna znanja, te omo-
gućuje da se na dobrim temeljima izgrađuje kvalitetna nadgradnja.
Dobro stručno i praktično znanje mora se temeljiti na dobrom razumijevanju teorije, bez obzira o
karakteru obrazovne institucije. Stoga svi usvojeni pojmovi moraju biti jasni, posebno ako se radi o
osnovama struke. Ako se radi o tehničkim detaljima, oni se moraju poznavati načelno, i na temeljima
osnovnih pojmova, a po potrebi se upoznaju podrobnije kroz tehničke specifikacije, dodatne upute, i
sl. Jasno je da obratni pristup ne važi: razumijevanje tehničkih detalja nemoguće je bez poznavanja
teorijskih osnova, odnosno dovodi do manjkavog znanja, punog rupa i nejasnoća.
Za stjecanje kvalitetnog znanja, studenti moraju uložiti napor da rabe dobru literaturu, odnosno
onu, koja, iako na prvi pogled teža, vodi do boljih rezultata. Moraju dobro poznavati „jezik struke“,
nazive i značenje pojmova, te uvijek nastojati proniknuti u bit stvari. U tehničkom i prirodoznanstve-
nom području, podrazumijevajuća zajednička disciplina je matematika, koja se često naziva i „jezi-
kom prirode“, a danas uvriježeni, i de-facto standardni jezik je engleski, što posebice vrijedi za ra-
čunarstvo kao relativno mladu znanost.
Navedeni samostalni pristup radu presudan je da se kod studenta stvori navika učenja i proučava-
nja, što će posebice biti važno u njegovom daljnjem profesionalnom radu. Cilj vježbi u obrazovnom
procesu, nije dobiti rezultat pošto poto, već dobiti rezultat kroz rad i zalaganje studenata kao aktivnih
učesnika tog procesa. Cilj je stjecanje znanja i vještina na putu od trenutka od suočavanja s proble-
mom zadataka, do njegovog uspješnog rješenja. Stoga, prije nego student potraži pomoć od kolega ili
nastavnika, nastoji izvršiti maksimalni intelektualni napor da do rezultata dođe samostalno. Ukoliko u
tome uspije, to će biti najučinkovitije i što se tiče stjecanja znanja i razvijanja sposobnosti, i što se tiče
zadovoljstva proisteklog od rezultata vlastitog rada. A ukoliko je, nakon neuspjelih napora, potrebno
potražiti pomoć drugih, to treba učiniti tako se razazna bit problema i način njegovo rješavanja, a ne
da se prepisuje i kopira puko rješenje (vidjeti također poglavlje I.6 o etičkom kodeksu).
*
Uvođenje rukom pisanog Dnevnika vježbi, potaknuto je, između ostalog, i potrebom za borbom protiv kopiraj
i zalijepi (engl. copy-paste) metode. Nedopušteno kopiranje i prepisivanje je odraz nesavjesnosti i nezaintere-
siranost, čime se izravno krši etički kodeks (vidi pogl. I.6).
3
− Svaka vježba započinje na novoj stranici, s navedenim brojem i naslovom vježbe, te datumom
kad je vježba odrađena.
− Svaka vježba ima sljedeće odjeljke: A. Teorijski uvod, B.Zadaci, C. Zaključak, D. Dodatna lite-
ratura (ako postoji).
A. Teorijski uvod. Sadrži kratak uvod u temu vježbe i zabilješke koje student izrađuje tijekom
pripremanja za vježbu, s naglaskom na teorijske osnove, iznesene npr. u [1], i drugoj dostupnoj
literaturi. Također, u ovom dijelu se odgovara na teorijska pitanja postavljena u uvodu vježbe.
O važnosti i načinu pripreme govori i sljedeći odjeljak.
B. Zadaci. U ovom dijelu student rješava zadane zadatke. Prije vježbe, u fazi pripreme, tu se mo-
gu izraditi skice rješenja zadataka koji će se prorađivati na vježbama, te bilježe konkretna pita-
nja i nejasnoće koje će student razriješiti konzultiranjem voditelja vježbi.
Svaki zadatak mora biti jasno naznačen svojim brojem i izvorištem, kao i tekstom (ukoliko je
tekst zadatka vrlo opširan, dovoljno je napisati njegove najbitnije dijelove). Ako se radi o za-
datku iz ovog teksta, dovoljno je napisati broj zadatka, npr. Zad. 2.1 (vježba 2, zad. broj 1), i
njegov (kratak) tekst, po točkama (A, B, C, itd…).
Nakon vježbi student korigira i sređuje rješenja svojih zadataka. Izvorne i izvršne datoteke
čuva u odgovarajućim mapama (vidi vježbu Vježba 1 , odjeljak 1.2.3 o organizaciji mapa i
podmapa), i na njih se referira u komentarima zadataka.
Rješenja zadataka nije potrebno u cijelosti prepisivati iz datoteka izvornog koda! Ako je to
svrsishodno, u Dnevnik vježbi se prepisuju ključni, ili tipični dijelovi programskog koda, te od-
govarajuće komentiraju.
C. Zaključak. U zaključku se sažeto komentiraju bitni dijelovi i rezultati vježbe (nekoliko pasu-
sa).
D. Dodatna literatura. Ukoliko je korištena literatura van standardne literature korištene u ovom
kolegiju (lit. [1], slikoklizne prezentacije lit. [1], i ovaj tekst), u zadnjem odjeljku se navode
podaci o njoj. Za način citiranja literature, vidjeti odjeljak I.5.
U Dnevnik vježbe, nije potrebno, odnosno ne smije se, unašati sljedeće:
− Ne smiju se doslovno prepisivati dijelovi teksta ili cjeline, bio iz literature uz koju se vežu ove vje-
žbe [1], niti iz druge literature. Svi dijelovi moraju biti ispričani vlastitim riječima (vidi odjeljak
I.6). To, naravno, ne vrijedi za navođenje teksta zadataka, u skladu s komentarom pod točkom B
gore.
− Ne smiju se prepisivati rješenja, te cjeline ili dijelovi iz Dnevnika drugih kolega (vidi odjeljak
I.6).
Pregled Dnevnika vježbi, i ocjenjivanje:
− Dnevnik vježbi predstavlja jednu od osnovnih elemenata ocjenjivanja.
− Na zahtjev voditelja, student predaje Dnevnik vježbi na pregled.
− Nakon ključnih dijelova vježbi, odnosno uspješno izvedenih zadataka, student poziva voditelja
vježbi da svojim parafom (u crvenoj boji), to potvrdi.
− Čitanje i studiranje teksta vježbe, te teorijskih poglavlja udžbeničkog teksta [1] na koje se vježba
odnosi.
− Odgovaranje na postavljena pitanja u pisanom obliku u Dnevniku vježbi, svugdje gdje se to traži,
i gdje je to svrsishodno. Obvezatno je navesti i tekst i izvorište pitanja, odnosno broj odjeljka
teksta i broj pitanja, ili broj zadatka.
− Proučavanje i samostalno rješavanje svih zadanih primjera, u nekoj od razvojnih programskih
okolina (vidi vježbu Vježba 1), uz odgovarajuće komentare u Dnevniku vježbi.,
− Na temelju znanja stečenog studiranjem riješenih primjera, vježbati preostale zadatke.
− U tijeku pripreme potrebno je insistirati na razumijevanju gradiva. Kod rješavanja primjera i za-
dataka potrebno je nastojati ugraditi najbolja teorijska rješenja.
− Pripremati se za pismene i usmene odgovore na pitanja u svezi teorijske cjeline koja se obrađuje
na vježbama, kao i u svezi rješenja zadataka, čime student pokazuje razumijevanje onoga što ra-
di.
Studenti koji ozbiljno pristupe pripremama vježbi, uspješno riješe zadane zadatke i odgovore na
postavljena pitanja, te zabilježe to Dnevniku vježbi, stječu uvjete da se nakon položenih kolokvija
oslobode polaganja pismenog i usmenog ispita.
U gornjem zadatku ilustrirana je uporaba uređivača teksta Notepad kao dijela operacijskog sus-
tava Windows, te C++ prevodioca cl koji se nalazi u sastavu Visual Studia 2005. U uporabi su i
drugi obradnici teksta (npr. vim), C++ prevodioci (npr. gcc) i otklanjači pogrešaka (gdb).
*
Naš naziv direktorij dolazi od engl. izvornika directory, ili imenik. Radi se o imeniku koji u sebi sadrži druge
podimenike i datoteke, s pomoću kojih se organizira struktura datoteka u operacijskom sustavu DOS (Disc
Operating System) na PC računalima prije pojave operacijskog sustava Windows s grafičkim okruženjem. Di-
rektorij u DOSu odgovara mapi u Windowsima.
13
Direktorije kreiramo komandom: mkdir ImeDirektorija , (od engl. make directory) a brišemo s:
rmdir ImeDirektorija (od engl. remove directory).
Da skratimo pisanje, već rabljene komande možemo izlistati, ponoviti ili modificirati uporabom
strelica ↑ i ↓ na tastaturi.
napisani programi, teško su čitljivi, teško se kontroliraju i održavaju, te lakše dovode do sintaktičkih i
logičkih pogrešaka.*
Uzimamo prvi primjer C4 / C++ programa iz [1], poglavlje 2:
*
Čak i ako je ispravan, nečitko napisani programski kôd smatrat će se inferiornim i bit će ocijenjen nižom ocje-
nom.
†
Uobičajeno je da se pod nazivom kompiliranja (engl Compile) podrazumijeva i radnja povezivanja (enlg.
Link), koju će program automatski izvršiti.
‡
Prilikom kopiranja teksta iz tekst procesora obratite pažnju da ne prenesete i neke posebne znakove koji ne
spadaju u osnovnu stranicu ASCII koda. Npr. pametni navodnici (engl. smart quotes), iz programa Word, pre-
neseni u okolinu Dev-C++ prelaze u obične navodnike i ne predstavljaju problem. Međutim, preneseni u Visual
Studio 2005 (vidi sljedeći odjeljak) ne moraju preći u obične navodnike, i mogu stvoriti probleme pri kompili-
ranju. Dovoljno ih je jednostavno obrisati i ponovo upisati u razvojnoj okolini.
15
using namespace std; // “imenski” prostor varijabli i objekata
int main() // glavna funkcija “main”
{
// program ispisuje znakovni niz na ekran računala:
cout << "Zdravo svijete, iz C++ programa!" << endl;
system("pause"); // funkcija za “pauzu” u prikazu konzol. apl.
return 0;
}
Izvršite naveden promjene u programskom kodu, te kompilirajte i izvršite program. Provjerite kako se
program izvršava iz komandne linije, a kako iz Windows okruženja.
Pošto je Bloodshed Dev-C++ vrlo kompaktna i besplatna inačica C++ IDE, možete ga instalira-
ti na svojem računalu i koristiti za učenje i vježbu programiranja.
gradnje (engl. build), odabirom: Build → Build ImeProjekta. Ukoliko je gradnja projekta prošla
bez grešaka, uz ključnu poruku kompilatora na dnu liste: "Build: 1 Succeeded, 0 Failed", tada mo-
žemo pokrenuti program: Debug → Start Without Debugging (Ctrl+F5). Ukoliko želimo kompili-
rati i odmah pokrenuti program za testiranje, možemo odmah odabrati ovu radnju (Ctrl-F5). Razvojna
okolina će automatski provjeriti je li bilo promjena u izvornim datotekama, te ako jest provesti kompi-
laciju i povezivanje, ta uz korektan ishod ovih radnji, pokrenuti i izvršenje programa.
Pospremanje izvorne .cpp datoteke vrši se standardnim odabirom File → Save ImeProjekta.cpp
(Ctrl+S). Prije zatvaranja projekta i razvojne okoline, potrebno je pospremiti i cijeli projekt, odabi-
rom File → Save All (Ctrl+Shif+S). Kod sljedećeg otvaranja projekta odabiremo File → Open →
Project Solution (Ctrl+Shift+O) ImeProjekta.sln unutar mape projekta.
Ukoliko prije zatvaranja razvojne okoline projekt nije pospremljen na gore opisani način, prilikom
njegovog ponovnog otvaranja, datoteka ImeProjekta.cpp se neće pojaviti u glavnoj plohi. Tada ju je
potrebno pronaći u mapi projekta i unijeti odabirom: File → Open → File ImeProjekta.cpp. Potom
je, naravno, uputno izvršiti pospremanje cijelog projekta na gore opisani način.
Slika 2.1 Dijaloški okvir za kreiranje projekta. Odabran je projekt tipa Visual C++
Win32, s predloškom za Win32 konzolnu aplikaciju, pod imenom ZdravoSvijete,
smješten u podmapu Zadatak_02_4, unutar mape Vjezba_2.
*
Uobičajeno je da se pod nazivom kompiliranja (engl Compile) podrazumijeva i radnja povezivanja (engl.
Link), koju će program automatski izvršiti.
18
19
20
//
int i = 0;
// ... ...
int i1 = 1;
int i2 = i1;
int i3 = i1 + i4;
int i4 = i2;
// ... ...
23
Zadatak 3.3 Provjera duljine cjelobrojnih tipova: short int, int, long int (long),
long long int (long long).
a) Po uzoru na primjer Primjer 3.1 sastavite C++ program (projekt pod nazivom Zadatak_03_03)
u kojem ćete deklarirati, učitati i potom ispisati šest varijabli cjelobrojnih tipova, i provjeriti im du-
ljinu u bajtovima: short int, int, long int (long), long long int (long long). Ovdje su nazivi
long int i long, te long long int i long long sinonimi (provjerite da i to vrijedi).
b) Napišite zaključke o duljinama tipova podataka u bajtovima (B) i bitovima (kratica: bit), prikazav-
ši ih pregledno u tablici.
c) Otklonite sve greške na način da minimalno mijenjate „logiku“ programa, i ponovite kompilaciju.
N min = −2 n − 1 , N max = 2 n − 1 − 1 .
b) Izračunajte na kalkulatoru najmanje i najveće brojeve za cjelobrojne tipove iz zadatka Zadatak
3.3.
Upišite za ulazni podatak vrijednosti npr. 1000, 10000, 10000, –10000, –100000, pa zatim +32767,
+32768, +32769, te –32767, –32768, –32769, i provjerite koji su rezultati ispravno zabilježeni u me-
moriju, te ispravno ispisani!
Ponovite sličan program za tip int, te unašajte vrijednosti reda stotinu milijuna i milijardi: npr.
100000000, 1000000000, 2000000000, 4000000000, –2000000000, –4000000000, i zaključite koji je
traženi opseg brojeva.
Za tip long long račun zahtijeva veću matematičku preciznost i brojeve reda veličine 263 = 9.22 ×
1018 , tj. za točan izračun kalkulator mora imati 19 znamenaka (provjerite funkcionalnost kalkulatora
u OS Windows).
N min = 0 , N max = 2 n − 1 .
Objasnite gornju formulu, te odredite maksimalne brojeve za tip char, unsigned short int, unsigned
int.
b) Modificirajte program iz zadatka Zadatak 3.3 i kreirajte projekt pod nazivom Zadatak_03_06,
tako da u njemu deklarirate nepredznačene tipove podataka unsigned short int, unsigned int,
unsigned long long. Koristite mađarsku notaciju, i označite ove varijable identifikatorima: uSInt,
uInt, uLLong.
c) Barem za prva dva tipa provjerite opseg testirajući unos i ispis, kao u prethodnom zadatku Zadatak
3.5. Što se događa kad unesete broj za 1 veći od maksimalnog? Pokušajte unijeti negativni broj i
pažljivo pogledajte što se pojavilo na ispisu. Ima li dobiveni broj ikakve veze s unesenim brojem i
nepredznačenim tipom podataka? Ako vam se čini da nema, razmislite ponovo. Unesite npr. broj
−1 i pogledajte što će biti ispisano. Koliko se ispisani broj razlikuje od maksimalnog broja danog
nepredznačenog tipa?
d) Ubacite gornji programski odsječak u testni program (unutar projekta odgovarajućeg imena). Do-
dajte linije za ispis da možete ispisati vrijednosti varijabli. Nakon kompilacije promotrite što javlja
prevodilac. Izvršite program i usporedite prijašnje odgovore s rezultatima ispisa.
četvorki bitova pretvaramo u jednu heksadekadsku znamenku, što je vrlo brz i jednostavan postu-
pak. Kao primjer dajemo pretvorbu dva 32-bitna binarna broja u heksadekadske ekvivalente:
0000 0001 0010 0011 0100 0101 0110 0111b = 01234567h ,
1000 1001 1010 1011 1100 1101 1110 1111b = 89ABCDEFh .
Detalje o brojevnim sustavima, prikazu brojeva u njima, i pretvorbi iz jednog sustava u drugi, pot-
ražite u računarskim i informatičkim udžbenicima, odnosno podrobnije u literaturi o arhitekturi raču-
nala.
c) Proučite donji primjer i napišite vrijednosti koje će biti ispisane na ekranu. Obratite pažnju na bro-
jevne sustave u kojima je varijabla zadana. Najprije zaključite općenito pravilo kako se zapisuje
baza brojevnog sustava u istom tom sustavu. Objasnite potom kako je varijabla pohranjena u me-
moriji.
d) Potom Kompilirajte donji programski kôd u okviru testnog programa, i provjerite svoje odgovore
iz prethodnog podzadatka. Koji je standardni brojevni sustav za prikaz na ekranu?
#include <iostream>
using namespace std;
int main()
{
// Zapis brojeva u dekadskom, oktalnom i heksadekadskom
// sustavu
int iBDec = 10; // Što predstavlja broj iBDec?
int iBOct = 010; // Što predstavlja broj iBOct?
int iBHex = 0x10; // Što predstavlja broj iBHex?
// Ispis vrijednosti baza sustava (u dekadskoj formi):
cout << "iBDec = " << iBDec << endl;
cout << "iBOct = " << iBOct << endl;
cout << "iBHex = " << iBHex << endl;
// Pridruživanje brojeva, N = 100 u raznim bazama:
int iDec = 100;
int iOct = 0100;
int iHex = 0x100;
/ Ispis dekadskog, oktalnog i heksadekadskog broja:
cout << "(100)Dec = " << iDec << endl;
cout << "(100)Oct = " << iOct << endl;
cout << "(100)Hex = " << iHex << endl;
// Pridruživanje istog niza znamenaka: "777" u raznim bazama:
iDec = 777;
iOct = 0777;
iHex = 0x777;
// Ispis vrijednosti dekadskog, oktalnog i heksadekadskog broja
// u dekadskoj formi:
cout << "(777)Dec = " << iDec << endl;
cout << "(777)Oct = " << iOct << endl;
cout << "(777)Hex = " << iHex << endl;
// Ispis istog broja u različitim sustavima
// (uporaba izlaznog manipulatora, vidi kasnije):
cout << "0x100 (Hex) = " << hex << 0x100 << endl;
cout << "0x100 (Oct) = " << oct << 0x100 << endl;
cout << "0x100 (Dec) = " << dec << 0x100 << endl;
return 0;
}
kodiraju znakovi ovog tipa. Može li se s tipom char vršiti aritmetičke operacije kao i s brojevi-
ma? Kako će se njegove vrijednosti ispisivati na ekranu? Ponovite kako se varijabla ovog tipa ini-
cijalizira na neku brojevnu vrijednost, a kako na brojevnu vrijednost koja odgovara nekom proiz-
voljnom znaku z.
b) b) Razmotrite sljedeći programski odsječak. Predvidite izlaz ako je kodna zamjena za znak praz-
nine: ASCII(' ') = 20h , znamenka 0: ASCII ('0') = 30h , znak @: ASCII ('@') = 40h , slovo A:
ASCII ('A') = 41h , slovo a: ASCII ('a') = 61h , itd. (vidjeti tablicu ASCII koda u dodatku). Ovdje
smo indeksom h označili da se radi o heksadekadskom prikazu broja.
c) Umetnite donji programski odsječak u testni program unutar zasebnog projekta izvršite ga. Provje-
rite svoja predviđanja usporedbom s rezultatima ispisa.
char cSpace = ' ', cA = 'A', cX1, cX2, cX3, cX4;
unsigned short int uInt1, uInt2, uInt3;
// Račun s tipom char (8-bitni):
cX1 = cSpace + 1; // cX1 = ?
cX2 = cSpace + 10; // cX2 = ?
cX3 = cSpace + 0x10; // cX3 = ?
cX4 = cSpace + 0x20; // cX3 = ?
// Ispis (znakovi ili njihove kodne zamjene?):
cout << "' ' + 1 = " << cX1 << endl;
cout << "' ' + 10 = " << cX2 << endl;
cout << "' ' + 10h = " << cX3 << endl;
cout << "' ' + 20h = " << cX4 << endl;
// Podrazumijevajuća prilagodba (promocija) sa char (8-bitni)
// na short int (16 bitni):
uInt1 = cSpace + 1; // uInt1 = ?
uInt2 = cSpace + 10; // uInt2 = ?
uInt3 = cSpace + 0x10; // uInt3 = ?
// Ispis (znakovi ili njihove kodne zamjene?):
cout << "ASCII( ' ' + 1) = " << uInt1 << endl;
cout << "ASCII( ' ' + 10) = " << uInt2 << endl;
cout << "ASCII( ' ' + 10h) = " << uInt3 << endl;
// Izravan izlaz na objekt cout!
// Ispis – znakovi ili njihove kodne zamjene?
cout << "' ' + 10h = " << cSpace + 0x10 << endl;
cout << "' ' + 11h = " << cSpace + 0x11 << endl;
cout << "' ' + 12h = " << cSpace + 0x12 << endl;
cout << "' ' + 19h = " << cSpace + 0x19 << endl;
// Izravan izlaz na objekt cout, uz prisilno pridjeljivanje
// (down-casting) na niži tip char.
// ASCII brojke:
cout << "' ' + 10h = " << (char) (' ' + 0x10) << endl;
cout << "' ' + 11h = " << (char) (' ' + 0x11) << endl;
cout << "' ' + 12h = " << (char) (' ' + 0x12) << endl;
cout << "' ' + 19h = " << (char) (' ' + 0x19) << endl;
// Izravan izlaz na objekt cout, uz odgovarajuće pridjeljivanje tipa.
// ASCII slova:
cout << "'A' + 1 = " << (char) (cA + 1) << endl;
cout << "'A' + 25 = " << (char) (cA + 25) << endl;
cout << "'A' + 20h = " << (char) (cA + 0x20) << endl;
cout << "'A' + 57 = " << (char) (cA + 57) << endl;
////////////////////////////////////////////////////
jednosti? Objasnite kako se u praksi implementira taj tip podataka, tj. uzima li se za njega mini-
malno potreban niz bitova ili što drugo?
b) Kako je implementiran logički tip podataka u jeziku C? Koje logičko značenje ima broj 0? Koje
logičko značenje imaju npr. brojevi: −1, 1, −13, 100, … ? Kako je implementiran logički tip u
jeziku C++. Jesu li promjene bitne, ili više kozmetičke naravi? Hoće li programski kôd s logič-
kim varijablama definiranim u C-stilu biti ispravan i u jeziku C++?
c) U sljedećem programskom odsječku deklarirane su dvije logičke varijable. Varijablama se pridje-
ljuje vrijednost na nekoliko načina (pridruživanjem vrijednosti logičkih konstanti false i true, te
cijelih brojeva). Također, provjeravamo duljinu logičkog tipa. Proučite program i predvidite ispis.
d) Umetnite donji programski odsječak u testni program koji ćete ugraditi u projekt odgovarajućeg
imena. Provjerite rezultate i usporedite sa svojim odgovorima.
e) Ustanovite koje pravilo vrijedi za pridjeljivanje cjelobrojnog tipa na tip bool.
f) Je li opravdano ignorirati upozorenja prevodioca? Predstavlja li strogo vođenje računa o tipu poda-
taka kao što je logički, tek puki formalizam? Ako jezik dopušta određene slobode u radu s tipovi-
ma, na kome preostaje da vodi računa o njihovoj pravilnoj uporabi?
Napomena: ukoliko vam komentari na engleskom jeziku nisu razumljivi, prevedite ključne riječi s
pomoću rječnika, i zatim dopišite komentare u hrvatskoj inačici.
// Logic Variables declaration:
bool bLogic0;
bool bLogic1;
// Size of bool type:
cout << "Size of bLogic0 = " << sizeof bLogic0 << "B\n"
<< "Size of bLogic1 = " << sizeof bLogic1 << "B\n"
<< "Size of (bool) = " << sizeof(bool) << "B\n"
<< endl;
// Formally correct initialization:
bLogic0 = false;
bLogic1 = true;
// Output values:
cout << "bLogic0 [= true] = " << bLogic0 << "\n"
<< "bLogic1 [= false] = " << bLogic1 << "\n" << endl;
// Formally incorrect initialization (automatic casting).
// Will there be compile-time warnings?
bLogic0 = 0;
bLogic1 = 1;
// Output values:
cout << "bLogic0 [= 0 ] = " << bLogic0 << "\n"
<< "bLogic1 [= 1 ] = " << bLogic1 << "\n" << endl;
// Formally incorrect initialization (truncation from
// int to bool). Will there be compile-time warnings?
bLogic0 = 256;
bLogic1 = 65536;
// Output values through bool type:
cout << "bLogic0 [= -256] = " << bLogic0 << "\n"
<< "bLogic1 [= 65536] = " << bLogic1 << "\n" << endl;
// Formally incorrect initialization (truncation from
// int to bool). Will there be compile-time warnings?
bLogic0 = 0;
bLogic1 = 65535;
// Output values through short int type:
cout << "(short) bLogic0 [= 0] = " << (short) bLogic0 << "\n"
<< "(short) bLogic1 [= 65535] = " << (short) bLogic1 << "\n"
<< endl;
28
// ... ... ...
(ustanovite koliko on iznosi u našem slučaju). Pored navedenih kontrolnih znakova postoji kontrolni
znak \0 = NULL s kodnom zamjenom ASCII (NULL) = 00h (vidi tablice ASCII koda).
d) Dopišite dijelove programa 2b, 3b i 4b u kojima ćete po uzoru na dio 1b ostvariti pravilno potpi-
sivanje cijelih brojeva. Također, promijenite varijablu kojom se mijenja vodeći znak (znak „ispu-
ne“) lijevo od broja, tako da umjesto zvjezdice on bude praznina ili razmak (engl. space, blank).
Učinite to i za dio programa 1b.
a) Proučite donji programski kôd. Uočite da se on, usprkos opsežnosti, svodi na ponavljanje sličnih
linija koda. Pažljivo proučite sve naveden komentare i odgovorite na pitanja postavljena u njima.
b) Odgonetnite specifičnosti u radu manipulatora setprecision(int) kad je on postavljen na inicijalne
(podrazumijevajuće) postavke izlaznog objekta cout, odnosno nakon što je djelovao manipulator
fixed. Objasnite o čemu se radi, i kako se to odražava na format ispisa.
c) Umetnite donji programski odsječak u glavnu funkciju C++ programa u projektu Zadatak_03_15 ,
te osigurajte potrebne uključne datoteke. Prevedite i izvršite program, povećajte prozor konzolne
aplikacije i proučite dobiveni ispis.
d) Što je karakteristično za ispise 1a i 2a? Što se događa s pomičnom točkom? Možemo li reći da ona
pluta, kroz broj znamenaka koji je određen za zadanu preciznost? Što je karakteristično za ispise
1b i 2b, te kako su oni dobiveni? Jesu li ispisi 1b i 2b pregledni s obzirom na položaj decimalne
točke? Navedite primjere područja u kojem bi takvo potpisivanje rezultata bilo obvezatno. Zatim
pažljivo provjerite jesu li ispisi 1b i 2b potpuno točni, s obzirom kako su varijable zadane? Potkri-
jepite svoje odgovore činjenicama o točnom broju dekadskih znamenaka za oba promatrana tipa s
pomičnom točkom.
e) Modificirajte program i provjerite rezultate ispisa. Najprije promijenite vrijednost znaka za ispunu
nepopunjenih mjesta u prazninu, što će ispis učiniti preglednijim. Mijenjajte vrijednosti za preciz-
nost i širinu polja. Koja je podrazumijevajuća preciznost tipova s pomičnom točkom, prije nego se
bilo što definira? Kako biste „resetirali“ postavke za preciznost na one podrazumijevajuće? Za
ideju pogledajte kako smo resetirali djelovanje manipulatora scientific i fixed.
////////////////////////////////////////////////////////////////////////////////
// Varijable tipa float: 7 točnih znamenaka
// Obratite pažnju što će biti točno zabiljezeno i ispisano!
float f0 = 0.1234567890f;
float f1 = 1.234567890f;
float f2 = 12.34567890f;
float f3 = 123.4567890f;
float f4 = 1234.567890f;
float f5 = 12345.67890f;
float f6 = 123456.7890f;
float f7 = 1234567.890f;
float fExMin2 = 0.01234567890f;
float fExMin3 = 0.001234567890f;
float fExMin4 = 0.0001234567890f;
// Varijable za definiranje izlaznih manipulatora tipa float:
unsigned short usPrec1 = 7;
unsigned short usW1 = 12;
char cFill1 = '*';
// 1a. Ispis varijabli tipa float:
cout
<< "1a. Ispis varijabli tipa float uz preciznost usPrec1 = " << usPrec1 << "\n"
<< " (sirina polja = " << usW1 << ", vodeci znak = '" << cFill1 << "')\n"
<< "==================================================================\n"
// Postavka preciznosti: broj signifikantnih (značajnih) znamenaka.
// Obratite pažnju: ulazi li tu i vodeća nula (lijevo od dec. točke)?
<< setprecision(usPrec1)
// Postavka znaka za vodeća mjesta lijevo od broja u rezerviranom polju:
<< setfill(cFill1)
// Širina polja rezervirana za varijablu postavlja se neposredno
// prije ispisa varijable operatorskom verzijom funkcije, setw(width):
<< " f0 (= 0.1234567890) = " << setw(usW1) << f0 << "\n"
<< " f1 (= 1.234567890) = " << setw(usW1) << f1 << "\n"
<< " f2 (= 12.34567890) = " << setw(usW1) << f2 << "\n"
<< " f3 (= 123.4567890) = " << setw(usW1) << f3 << "\n"
<< " f4 (= 1234.567890) = " << setw(usW1) << f4 << "\n"
34
<< " f5 (= 12345.67890) = " << setw(usW1) << f5 << "\n"
<< " f6 (= 123456.7890) = " << setw(usW1) << f6 << "\n"
<< " f7 (= 1234567.890) = " << setw(usW1) << f7 << "\n"
<< "\n"
// Ispis u "znanstvenoj notaciji":
<< scientific
<< "fExMin2 (1.234567e-2) = " << setw(usW1) << fExMin2 << "\n"
<< "fExMin3 (1.234567e-3) = " << setw(usW1) << fExMin3 << "\n"
<< "fExMin4 (1.234567e-4) = " << setw(usW1) << fExMin4 << "\n"
// Poništenje znanst. notacije i povratak na 1-komponentni zapis:
<< resetiosflags(ios_base::scientific)
// Završetak ispisa 1a, novi red:
<< endl;
// Varijable tipa double, 14-15 (uglavnom 15) tocnih znamenaka.
double d0 = 0.12345678901234567890;
double d1 = 1.2345678901234567890;
double d2 = 12.345678901234567890;
double d3 = 123.45678901234567890;
double d4 = 1234.5678901234567890;
double d5 = 12345.678901234567890;
double d6 = 123456.78901234567890;
double d7 = 1234567.8901234567890;
double dExMin2 = 0.012345678901234567890;
double dExMin3 = 0.0012345678901234567890;
double dExMin4 = 0.00012345678901234567890;
//
// Varijable za definiranje izlaznih manipulatora tipa double:
unsigned short usPrec2 = 15;
unsigned short usW2 = 20;
char cFill2 = '*';
// 2a. Ispis varijabli tipa double
cout
<< "2a. Ispis varijabli tipa float uz preciznost usPrec2 = " << usPrec2 << "\n"
<< " (sirina polja = " << usW2 << ", vodeci znak = '" << cFill2 << "')\n"
<< "==================================================================\n"
// Postavka preciznosti: broj signifikantnih (značajnih) znamenaka:
<< setprecision(usPrec2)
// Postavka znaka za vodeća mjesta:
<< setfill(cFill2)
// Postavka širine rezerviranog polja i ispis varijabli:
<< " d0 (= 0.12345678901234567890) = " << setw(usW2) << d0 << "\n"
<< " d1 (= 1.2345678901234567890) = " << setw(usW2) << d1 << "\n"
<< " d2 (= 12.345678901234567890) = " << setw(usW2) << d2 << "\n"
<< " d3 (= 123.45678901234567890) = " << setw(usW2) << d3 << "\n"
<< " d4 (= 1234.5678901234567890) = " << setw(usW2) << d4 << "\n"
<< " d5 (= 12345.678901234567890) = " << setw(usW2) << d5 << "\n"
<< " d6 (= 123456.78901234567890) = " << setw(usW2) << d6 << "\n"
<< " d7 (= 1234567.8901234567890) = " << setw(usW2) << d7 << "\n"
<< "\n"
// Ispis u "znanstvenoj notaciji":
<< scientific
<< "dExMin2 (1.2345678901234567890e-2) = " << setw(usW2) << dExMin2 << "\n"
<< "dExMin3 (1.2345678901234567890e-3) = " << setw(usW2) << dExMin3 << "\n"
<< "dExMin4 (1.2345678901234567890e-4) = " << setw(usW2) << dExMin4 << "\n"
// Povratak na "jednokomponentni" zapis broja:
<< resetiosflags(ios_base::scientific)
<< endl;
cout << "\n"
<< "Ispis uz fiksni polozaj decimalne tocke (manipulator: fixed)\n"
<< "*****************************************************************\n"
// Uporaba manipulatora fixed za fiksiranje dec. točke:
<< fixed // Nakon uporabe ovog izlaznog manipulatora, setprecision(n)
// postavlja BROJ ISPISANIH DECIMALA na n. Dakle, ne djeluje
35
// kao prije, da odredjuje broj signifikantnih znamenaka!
<< endl;
//
// Postavka novih vrijednosti preciznosti i širine polja:
usPrec1 = 4;
usW1 = 15;
// 1b. Ispis varijabli tipa float uz fiksni položaj točke
cout
<< "1b. Ispis varijabli tipa float uz preciznost usPrec1 = " << usPrec1 << "\n"
<< " (sirina polja = " << usW1 << ", vodeci znak = '" << cFill1 << "')\n"
<< "==================================================================\n"
36
// Postavka preciznosti: BROJ DECIMALA (vidi gornju napomenu)!
<< setprecision(usPrec1)
<< setfill(cFill1)
// Uporaba manipulatora setw(width) i ispis:
<< "f0 (= 0.1234567890) = " << setw(usW1) << f0 << "\n"
<< "f1 (= 1.234567890) = " << setw(usW1) << f1 << "\n"
<< "f2 (= 12.34567890) = " << setw(usW1) << f2 << "\n"
<< "f3 (= 123.4567890) = " << setw(usW1) << f3 << "\n"
<< "f4 (= 1234.567890) = " << setw(usW1) << f4 << "\n"
<< "f5 (= 12345.67890) = " << setw(usW1) << f5 << "\n"
<< "f6 (= 123456.7890) = " << setw(usW1) << f6 << "\n"
<< "f7 (= 1234567.890) = " << setw(usW1) << f7 << "\n"
<< "\n"
<< "fExMin2 (1.234567e-2) = " << setw(usW1) << fExMin2 << "\n"
<< "fExMin3 (1.234567e-3) = " << setw(usW1) << fExMin3 << "\n"
<< "fExMin4 (1.234567e-4) = " << setw(usW1) << fExMin4 << "\n"
<< endl;
//
// Postavka novih vrijednosti preciznosti i širine polja:
usPrec2 = 7;
usW2 = 20;
// 2b. Ispis varijabli tipa double uz fiksni polozaj tocke
cout
<< "2b. Ispis varijabli tipa float uz preciznost usPrec2 = " << usPrec2 << "\n"
<< " (sirina polja = " << usW2 << ", vodeci znak = '" << cFill2 << "')\n"
<< "==================================================================\n"
// Manipulator fixed vrijedi od zadnje postavke u 2a.
// NAKON fixed, OVO JE BROJ DECIMALA (vidi komentar pod 2a):
<< setprecision(usPrec2)
<< setfill(cFill2)
// Postavka širine polja i ispis:
<< " d0 (= 0.12345678901234567890) = " << setw(usW2) << d0 << "\n"
<< " d1 (= 1.2345678901234567890) = " << setw(usW2) << d1 << "\n"
<< " d2 (= 12.345678901234567890) = " << setw(usW2) << d2 << "\n"
<< " d3 (= 123.45678901234567890) = " << setw(usW2) << d3 << "\n"
<< " d4 (= 1234.5678901234567890) = " << setw(usW2) << d4 << "\n"
<< " d5 (= 12345.678901234567890) = " << setw(usW2) << d5 << "\n"
<< " d6 (= 123456.78901234567890) = " << setw(usW2) << d6 << "\n"
<< " d7 (= 1234567.8901234567890) = " << setw(usW2) << d7 << "\n"
<< "\n"
<< "dExMin2 (1.2345678901234567890e-2) = " << setw(usW2) << dExMin2 << "\n"
<< "dExMin3 (1.2345678901234567890e-3) = " << setw(usW2) << dExMin3 << "\n"
<< "dExMin4 (1.2345678901234567890e-4) = " << setw(usW2) << dExMin4 << "\n"
// Ponistenje djelovanja manipulatora fixed:
<< resetiosflags(ios_base::fixed)
<< endl;
////////////////////////////////////////////////////////////////////////////////
*
Zadatke sa zvjezdicom možete ispustiti ako ste u vremenskom tjesnacu. Oni su namijenjeni naprednijim stu-
dentima s ambicijama za višu ocjenu.
37
*
U različitim područjima osnovne logičke operacije pišu se na različite načine. Npr. u matematičkoj logici,
danas je za logičke operacije I, ILI i NE uobičajena uporaba simbola Λ , V i ¬ (ili ¯ ). Tako bismo C/C++
38
15. Kao podsjetnik na osnove računarstva: mogu li se prethodne logičke operacije povezati s aritme-
tičkima u aritmetici modulo 2? Koja logička operacija odgovara kojoj aritmetičkoj operaciji?
Objasnite?
16. Kako je logički tip bio prvobitno organiziran u jeziku C? Na što se svodi logička operacija I, a
na što logička operacija ILI? Objasnite i povežite s prethodnim zadatkom.
17. Glede logičkog tipa, što je dodano u jeziku C++? Jesu li uvedene promjene bitne? Što je to cje-
lobrojna promocija? Izračunavaju li se logičke operacije na isti ili različiti način u odnosu na je-
zik C?
18. Što je to kratkospojna provedba (engl. short-circuit evaluation)? Objasnite njezino značenje ko-
risteći gornje tablice istinitosti. Objasnite koja je kritična logička vrijednost za operaciju I, a
koja za ILI? (Natuknica. Ako je jedna logička varijabla F, treba li znati drugu varijabli da se
odredi rezultat operacije I ? Odnosno, ako je jedna logička varijabla T, treba li znati drugu da
se odredi rezultat operacije ILI ? Objasnite, i primijenite zaključke na kratkospojnu provedbu).
24. Je li uputno zlorabiti slobodu koja je dopuštena u pisanju izraza, nauštrb preglednosti i jasnoće?
Ako se previše izraza združi u jednu dugačku tvrdnju, mogu li se pojedinosti adekvatno komenti-
rati? Što je posljedica slabog komentiranja pojedinih dijelova programa?
ka: “Press any key to continue…” prije izlaska iz prozora konzolne aplikacije? Pronađite izvršnu
verziju programa u podmapi projekta (Zadatak_04_01_2). Pokrenite program izravno iz grafičke
okoline operacijskog sustava Windows i odgovorite na prethodno pitanje. Zatim uklonite poziv si-
stemske funkcije pauze, i ponovite pokretanje programa na dva načina: iz razvojne okoline VS
2005, te iz grafičkog sučelja OS Windows. Izvedite zaključke.
Zadatak 4.4 Program za izračun ukupne neto i bruto cijene za skup do 10 artikala.
Sastavite program u C++ koji će učitati bruto cijene do maksimalno 10 artikala, i njihove količine.
Ako artikla nema, cijena mu je 0.00 Kn. Kao rezultat, program mora ispisati ukupnu neto cijenu bez
poreza u iznosu od 22% (PDV), zatim iznos poreza, te ukupnu (bruto) cijenu svih artikala, sve popra-
ćeno odgovarajućim komentarima. Koristite modifikatore za kontrolu ispisa, koji mora biti s dvije
decimale i zadovoljavajućim brojem mjesta (vidjeti zad. Zadatak 3.15).
Napomene. Program je na razini početničkog primjera i ne rabi iteracije (vidi vježbu Vježba 5), kon-
trolu unosa i druge pogodnosti koje bi korisnik očekivao. Koristite dolje sugerirane tipove i nazive za
varijable. Slijedite naputke u komentarima i dodajte potrebne linije programskog koda. Pregledno or-
ganizirajte programski kôd i služite se kopiranjem istih i sličnih dijelova programa. Zatim funkcijom
find-replace zamijenite dijelove koji se mijenjaju (npr. broj artikla). Dodatno odgovorite na sljedeća
pitanja u svezi ovog programa.
a) Koje su mane ovog programa glede organizacije pohrane podataka? Je li program praktičan ako
imamo npr. svega nekoliko artikala? Je li uporabljiv za općeniti slučaj, npr. broja artikala većeg od
10? Jesu li to ozbiljne mane?
b) Kako je riješen slučaj kad artikala ima manje od 10? Što će korisnik morati unositi u tom slučaju?
// Konstantni iznos poreza:
const float fPDV = .22f;
/////////////
// Varijable za cijenu artikala:
double dCijArtkl_01, dCijArtkl_02, dCijArtkl_03, fCijArtkl_04,dCijArtkl_05,
dCijArtkl_06, dCijArtkl_07, dCijArtkl_08, dCijArtkl_09,dCijArtkl_10;
/////////////
// Varijable za ukupnu cijenu:
double dCijUkupna; // Po potrebi uvedite i druge varijable.
/////////////
// Varijable za količinu artikala:
unsigned short int
sKolArtkl_01, dKolArtkl_02, dKolArtkl_03, fKolArtkl_04,dKolArtkl_05,
sKolArtkl_06, dKolArtkl_07, dKolArtkl_08, dKolArtkl_09,dKolArtkl_10;
/////////////
// Izračun ukupne cijene
// ...
da biste ostvarili pregledan ispis (zad. Zadatak 3.15). Ukoliko ćete imati problema kod organizacije i
preglednosti ispisa, možete ga, za početak, pojednostaviti ispuštanjem nekih od navedenih veličina.
vrijednosti ispisuju i vidite što se događa. Na koncu razmislite, ima li, osim za vježbu, smisla pisati
izraze ovakvog tipa? Zadovoljavaju li oni načelo jasnoće i preglednosti pisanja?
///////////
int i = 5;
cout << "int i = " << i << "\n" << endl;
// ispis = ?, i = ?
cout << " -(--i)++ \tispis : " << -(--i)++ << endl;
cout << "\t\ti = " << i << "\n" << endl;
// ispis = ?, i = ?
cout << "( i -= - i++ ) \tispis : " << ( i -= - i++ ) << endl;
cout << "\t\ti = " << i << "\n" << endl;
// ispis = ?, i = ?
cout << "( i += - ++i ) \tispis : " << ( i += - ++i ) << endl;
cout << "\t\ti = " << i << "\n" << endl;
////////////
26. Kada je uputno koristiti while petlju, odnosno zašto je ona uvedena? Općenito uzevši, znamo li
kod nje „unaprijed“ broj iteracija koje će se izvršiti? Koliko se najmanje puta može izvršiti
while petlja?
27. Napišite općenitu sintaksu do – while petlje, i objasnite točno kako se ona izvršava: kako zapo-
činje, dokle se izvršava iteracija, što se mora desiti da se završi ponavljanje petlje, te kako se po-
tom nastavlja izvođenje programa.
28. Koliko se najmanje puta izvršava do – while petlja? Ilustrirajte u kojim se slučajevima to svoj-
stvo dade prikladno iskoristiti.
29. Može li se svaka do – while petlja svesti na while petlju, naravno uz dopušteno pisanje dodatnih
linija koda? A obrnuto – može li se svaka while petlja svesti na do – while petlju? Iskoristite
odgovore o najmanjem broju iteracija svake od ovih petlji, iz čega možete zaključiti o njihovoj
općenitosti, i svodljivosti jedne na drugu.
30. Napišite općenitu sintaksu for petlje. Objasnite značenje svakog od tri izraza u zagradi. Preciz-
no, u algoritamskom stilu objasnite kako se petlje izvršava.
31. Smije li se u prvom izrazu deklarirati varijabla, npr. novog brojača for petlje? Koliki je dogled
te varijable? Koliki je općenito dogled varijabli deklariranih u tri izraza unutar zagrade for
petlje?
32. S obzirom na odgovore na prethodno pitanje, razmotrite sljedeće: i) Možemo li varijable dekla-
rirane u for petlji koristiti u njoj ugniježđenoj petlji, tj. petlji koja se nalazi unutar njenog tijela?
ii) Možemo li te varijable koristiti u drugoj for petlji, otvorenoj van tijela prve?
33. Koja je standardna primjena for petlje? Što se standardno veže uz funkcioniranje for petlje —
varijabla koje namjene? Uz koje strukture podataka se ova petlja najčešće koristi?
34. Napišite reduciranu for petlju koja ima funkcionalnost while petlje. Sljedeći algoritamski prikaz
izvršavanja for petlje, dokažite da je njeno izvršavanje istovjetno while petlji.
35. *Za vježbu napišite for petlju koja ima funkcionalnost do – while petlje. Proširenjem uvjetnog
izraza potrebno je osigurati da je minimalan broj prolaza kroz petlju istovjetan kao i kod do –
while petlje. Na koncu, slijedeći algoritamski prikaz izvršavanja for petlje, dokažite da je njeno
izvršavanje istovjetno do – while petlji.
36. Napišite kako se for petlja može ostvariti s pomoću while petlje. Učinite to najprije za općeniti
slučaj, pišući apstraktnu sintaksu, a potom i za konkretan slučaj.
Primjer 5.3 Selekcija s pomoću tvrdnje if – else if . [Napomena: u novijoj inačici na ovo će
mjesto doći jednostavniji primjer, a numeracija ovoga će se povećati za 1.]
U sljedećem primjeru dana je if – else if tvrdnja u kojoj se kroz dva relacijska izraza uspoređuju dvije
varijable fVar1 i fVar2 tipa float , te se nakon toga ispisuje odgovarajuća poruka oblika: fVar1 rel
54
fVar2 , gdje je rel jedna od aritmetičkih relacija: < , = , > . Dakle, program će ispisati je li prva
varijabla manja, jednaka ili veća od druge varijable. U ovom stilu pisanja, s lijeve strane relacije je
uvijek prva, a s desne strane druga varijabla.
float fVar1, fVar2;
// ... ...
// ... ...
Zadatak 5.3 uz Primjer 5.3. [Napomena: u novijoj inačici na ovo će mjesto doći jednostavniji
zadatak, a numeracija ovoga će se povećati za 1.]
Uz Primjer 5.3 odgovorite na sljedeća pitanja:
a) Zašto nakon naredbi if, else if, i else nismo morali otvarati blok pisanjem vitičastih zagrada? U
kojem slučaju bi to bilo nužno? Što znači kontrolni znak \t u ispisu?
b) Diskutirajte kako se izvršava selekcija za sve moguće odnose dvije varijable ( fVar1 > fVar2,
fVar1 == fVar2 i fVar1 < fVar2 ).
Također, ispis mora biti ostvaren jednom, jedinom tvrdnjom. Usporedite to s prijašnjim
ostvarenjem ispisa!
Naputak. Iskoristite varijable uvedene u podzadatku b, te uvedite tri nove varijable tipa char,
kojima ćete opisati indeks manje i veće varijable (1 ili 2), te znak relacije između njih. Sva
pridruživanja je potrebno obaviti u već postojećim blokovima naredbe selekcije.
// Hrvatske ocjene
unsigned short int usOcjena;
cout << "Unesite ocjenu od 1 do 5 : ";
cin >> usOcjena;
cout << "\nOcjena: " << usOcjena << " = ";
switch (usOcjena)
{
case 5 : cout << "izvrstan" << "\n";
break;
case 4 : cout << "vrlo dobar" << "\n";
break;
case 3 : cout << "dobar" << "\n";
break;
case 2 : cout << "dovoljan" << "\n";
break;
case 1 : cout << "nedovoljan" << "\n";
break;
default : cout << "neispravna ocjena!" << "\n";
break; // Je li ovaj break neophodan?
}
cout << endl;
d)
ab =a +b ,
e) koje zapisano logičkim operatorima u jeziku C / C++ glasi:
f) !(a && b) = !a || !b .
a) Umetnite na kraj programskog odsječka aritmetički izraz kojim ćete izravno izračunati sumu prvih
n brojeva s pomoću gornje formule, i pohraniti je u već deklariranu varijablu uSumNA.
b) Zatim napravite ispis varijable prema uzoru na već postojeći, uz napomenu da se radi o sumi arit-
metičkog niza dobivenoj izravno preko formule.
c) Testirajte program i potvrdite istovjetnost rezultata dobivenih zbrajanjem u for petlji i preko for-
mule za sumu aritmetičkog niza.
59
d) Izvedite zaključke o brzini izračuna rezultata sumiranjem i preko formule – što je brže? Izvedite
opći zaključak: je li opravdano „programiranjem“ i nepotrebno dugotrajnim računom nadomje-
štavati nedostatak matematičkog znanja?
e) Prema pričanju, mladi Gauss je našao sumu prvih 100 brojeva za svega nekoliko minuta još u
osnovnoj školi, upravo s pomoću gornje formule. Nađite detalje o tome dostupnoj literaturi.
an = a1 + (n − 1) d .
Za sumu prvih n članova aritmetičkog niza vrijedi jednostavna formula (vidi dodatke u [1], [3xx]):
n
Sn = (a1 + a n ) .
2
a) Provjerite važenje gornje formule za prvih 5 i prvih 10 neparnih, i parnih, brojeva , izračunom na
papiru.
b) Po uzoru na Zadatak 5.13 i Zadatak 5.14 sastavite C++ program koji će nalaziti sumu prvih n
neparnih brojeva zbrajanjem u for petlji, te pored toga napisati isti rezultat uz korištenje gornje
formule.
c) Ponovite prethodni podzadatak za prvih n parnih brojeva.
se izračuna srednja vrijednost: fAve = fSum / uN , i ispisuje se na ekranu. Zadatak je potrebno riješiti
uporabom for petlje. Na koncu, osigurajte ponvaljanje programa tako dugo dok ga korisnik ne želi
prekinuti (vidi Zadatak 5.12).
A(i ) = A0 + t × i . (6.1)
Objasnite koncept višedimenzionalnog poretka. Nadovežite ovo razmatranje na podatkovni tip kazalj-
ki. Uočite odmah da se radi o tipu u kojem pohranjujemo adrese na kojima se nalaze varijable, objek-
ti, pa i funkcije proizvoljnih, drugih, tipova.
„znanstveni pogled“ (engl. Scientific View), te odabirom željene baze ostvariti pretvorbu. Za
usporedbu, promotrite i Primjer 6.1.
5. Napišite općenitu sintaksu za objavu poretka u jeziku C / C++. Redom objasnite svaki dio objave
i razmislite zašto se ni jedan od parametara ne može ispustiti.
6. Kakav mora biti broj kojim se objavljuje veličina strukture poretka prilikom njegove objave?
Može li njega unijeti korisnik naknadno, prilikom izvođenja programa? U kojoj fazi i tko (što)
mora znati ukupnu veličinu poretka i zašto? Objasnite temeljito svoj odgovor.
7. U svezi s prethodnim pitanjem, odgovorite kakva je struktura poretka glede promjenjivosti svoje
veličine? Diskutirajte mane i prednosti koje proizlaze iz toga.
8. Opišite kako se vrši inicijalizacija elemenata poretka odmah pri deklaraciji. Ako je sve elemente
potrebno postaviti na vrijednost 0 , treba li to napisati za svaki od njih? A ako se radi o nekoj
drugoj vrijednosti?
9. Deklarirajte poredak prikladnog imena tipa double s 500 elemenata, i odmah ih inicijalizirajte
prilikom objave tako da prvih deset poprime vrijednosti od 1.0 do 10.0 , a svi ostali da su 0.0 .
10. Kako se navodi pojedini element poretka u jeziku C / C++ ? U svezi s prethodnim zadatkom,
napišite izraze kojima ćete prvih pet elemenata podijeliti s 2.0 , a sljedećih pet pomnožiti s 2.0.
11. Podsjetite se iz osnova računarstva ili pronađite u literaturi kako je organizirana glavna memorija
računala, koja se često označava i kao RAM memorija, ili u slobodnom prijevodu memorija s iz-
ravnim pristupom. Njeno je svojstvo da se na osnovu adrese izravno pristupa sadržaju te memo-
rijske lokacije, jednako kao i to da je brzina pristupa do svake memorijske lokacije u osnovi jed-
nako brza*. Podsjeća li to na podatkovnu strukturu poretka? Obrazložite svoj odgovor.
*
Ovdje zanemarimo mehanizam priručne memorije (engl. cache memory)i utjecaj koji on može imati na doh-
vat memorijskog sadržaja.
65
18. Ako je početna adresa dvodimenzionalne matrice iz prethodnog zadatka A0 = 0080 0000h , skici-
rajte dio memorije u kojem je smještena. Navedite adrese i memorijski sadržaj na tim adresama,
odnosno vrijednosti elemenata matrice.
19. Objasnite što je deklarirano sljedećim izrazom: float fTensor [3][2] [4] ; // O kojoj i kakvoj
podatkovnoj strukturi se tu radi. Kojeg su tipa njeni elementi, koliko ih ukupno ima, te koju ko-
ličinu memorije zauzimaju. Navedite u kojem rasponu se kreću vrijednosti indeksa njenih ele-
menata. Ispišite redom sve elemente ovog poretka i navedite njihove relativne adrese naspram
adrese A0 početnog elementa.
20. Na što se odnosi pojam „dimenzija“ kod višedimenzionalnih poredaka? Je li to u izravnoj svezi s
veličinom ove programske strukture, odnosno s brojem njenih elemenata, ili s čime drugim. Ob-
jasnite!
Adresa poretka, odnosno adresa početnog elementa, neka je A0 = 0000h (adrese se uobičajeno pišu u
heksadekadskoj formi). Rješenje je dano na slici 4.1.
66
Uređaj elemenata slijedi formulu (6.1). Element s indeksom 0 je početni element fX[0] koji općenito ima
neku adresu A0 unutar glavne memorije računala. Radi jednostavnosti, za nju je pretpostavljen okrugli
iznos: A0 = 0012 0000h (za primjer ispisa konkretne vrijednosti vidi zad. xx). Sadržaj i-tog elementa
fX[i] pohranjen je na adresi A(i) = A0 + 4 × i , unutar četiri bajta B0 do B3, kojih su adrese redom: A( i
) + 0, A( i ) + 1, A( i ) + 2 i A( i ) + 3. Adresa posljednjeg elementa je:
A(100 ) = ( A0 + 4 × 99 ) d = ( A0 + 396 ) d = ( A0 + 18C ) h = 0012 018C h = 0x0012018c .
Zadnja vrijednost je napisana u „C / C++ stilu“, malim latinskim slovima A do F, na način kako adrese, od-
nosno općenito heksadekadske vrijednosti, ispisuju mnogi prevodioci. Gornji poredak ima 100 elemenata
duljine 4B i zauzima ukupnu memoriju od 400B. Označimo to kao njegov kapacitet C = 400d B =
= 190h B , gdje je drugi prikaz u heksadekadskoj formi. Iz gornjeg izlaganja slijedi da početni, nulti, bajt po-
lja ima adresu A0 = 0012 0000h , a zadnji, 399-ti A399 = 0012 018F h (primijetite: 190h – 1 = = 18Fh ). Isti
prikaz i razmatranje vrijedi za sve poretke s jednakim brojem i duljinom elemenata. Na gornjoj slici prika-
zano je i osam bajtova prije i poslije deklariranog poretka. Za njih, naravno, ne postoje „legalne“ vrijednos-
ti indeksa, pa nisu niti napisane. Radi se o dijelovima memorije u kojima su pohranjeni drugi sadržaji, kao
npr. druge lokalne varijable. Vrijednost ovih bajtova nevezana je uz poredak, te označena s ## Dva znaka
# sugeriraju dvije heksadekadske znamenke kojima je u potpunosti određen sadržaj jednog bajta.
b) Odredite koliko elemenata duljine 4B možemo pohraniti u poredak koje zauzima ukupnu duljinu
od 1KB, koliko u poredak duljine 16KB, 64KB i 1 MB.
c) Može li se struktura poretka primijeniti i na cijelu radnu memoriju računala? Objasnite! Usporedite
s odgovorom na pitanje 11 u odjeljku 6.1.1.
d) U svezi s potpitanjem c — ako se sve ostale strukture pohranjuju u memoriju računala, što zaklju-
čujete o važnosti strukture poretka? Mora li se onda bilo koja zamisliva programska struktura mo-
ći implementirati s pomoću strukture poretka?
d) Otklonite grešku u ovom dijelu programa. Izvedite zaključak o dozvoljenom broju elemenata liste
pri inicijalizaciji polja eksplicitno zadane veličine.
e) Dodajte ispise elemenata svih poredaka u dijelovima programa a, b i d, kako je to učinjeno u
dijelu programa označenom c.
Podatak P(j) =
Podatak P(j) =
ponovo uz konkretnu vrijednost indeksa j.
Zadatak 6.9 Dodatni zadatak uz Primjer 6.3. Ispis sadržaja 2-dim poretka.
a) Zamijenite nezgrapni „ručni“ ispis u prethodnom primjeru i zadatku s ispisom ostvarenim s pomo-
ću for petlje. Provjerite najprije kako je tekao prolaz kroz elemente 1-dim poretka, u prethodnim
zadacima. Koliko for petlji treba za prolaz kroz njegove elemente? Razmislite, koliko će for
petlji treba za ispis elemenata 2-dim poretka?
b) Ostvarite prolaz kroz 2-dim poredak tako da za svaki njegov indeks otvorite po jednu petlju, s time
da su one ugniježđene. Vanjska neka ima indeks unsigned int i ; , koji prolazi kroz sve vrijednos-
ti prve dimenzije (indeksi redaka matrice). Unutarnja petlja neka ima indeks unsigned int j , koji
prolazi vrijednostima druge dimenzije (indeksi stupaca matrice). Za jedan prolaz vanjske petlje,
unutarnja petlja se izvrši u cijelosti. Ispis organizirajte u unutarnjoj petlji. Unutar retka elemente
razmaknite tabulatorom. Nakon što je cijeli redak ispisan, tj. nakon cijelog prolaska unutarnje pet-
lje, pomaknite ispis u novi redak. Koristite ideje iz „ručnog“ ispisa.
72
c) Ukoliko se niste dosjetili kako organizirati dvostruku petlju, proučite programski kôd u sljedećem
zadatku (Zadatak 6.10), te se potom vratite na ovaj.
retka, najprije treba ispisati njegov indeks, napraviti odgovarajući razmak, i tek potom ispisivati
elemente retka.
b) Dodajte ovom programu i mogućnost inverznog ispisa, za slučaj da su elementi pohranjeni na sup-
rotan način od uobičajene matematičke konvencije. Npr. u poznatom tabličnom programu MS©
Excel, indeksi stupaca označeni slovima, pišu se prvi, a tek potom indeksi redaka (koji su brojča-
ni), što je suprotno od navedenog standarda.
c) Dodatno, napišite trostruko ugniježđenu petlju za ispis svih elemenata ovog poretka u obrnutom
redoslijedu, tj. tako da se najbrže vrti unutarnji indeks.
d) Dopišite vrijednosti elemenata u trećem redu u skladu sa započetim obrascem, i provjerite rezultate
ispisa.
int iTnsr[ ][3][4] = { { {111, 112, 113, 114}, {121, 122, 123, 124},
{131, 132, 133, 134} },
{ {0, }, } } ;
75
↓
… … Smjer pohrane
programa i
Adresni potprostor A
podataka
… … (prema većim
… … adresama)
… …
… … … … …
↑
Adresni potprostor B Smjer rasta
stogova --
… …
(prema manjim
… … adresama)
… …
… …
… … … … …
Amin + NA – 2 = FFFF FFFE XXh = sadržaj bajta FFFF FFFE
Amin + NA – 1 = FFFF FFFF XXh = sadržaj bajta FFFF FFFF
Slika 7.1 Programski model memorije. Svako memorijsko zrno (danas je to standardno
1B = 8bit) ima jedinstvenu adresu iz adresnog prostora. Adresni prostor se može dijeliti na
potprostore određene veličine, npr. za smještaj operacijskog sustava, za korisničke progra-
me itd… Standardno se programi i globalne varijable, uključujući i globalno deklarirane
poretke, pohranjuju u memoriju u smjeru od manjih adresa prema većima. Lokalne varijab-
le pohranjuju se na stog. Stogovi rastu u suprotnom smjeru. Sa XXh (dvije heksadekadske
znamenke) označen je heksadekadski ekvivalent sadržaja jednog bajta. Radi jednostavnosti, istom su
oznakom označeni općenito različiti sadržaji.
10. Kakva je sintaksa za deklaraciju kazaljke na neki tip u jeziku C / C++. Navedite sintaksu na op-
ćenit način, i zatim to potkrijepite primjerom deklarirajući kazaljke na nekoliko cjelobrojnih ti-
pova i na tipove s pomičnom točkom. Za kazaljke odaberite prikladna imena u skladu s Mađar-
skom notacijom.
11. Objasnite sintaksu i način djelovanja operatora „adresa-od“. Naglasite čemu on služi? Na koje
tipove podataka, odnosno općenito na koje programske entitete on može djelovati? Kakvom tipu
smijemo pridružiti rezultat djelovanja ovog operatora?
12. Objasnite sintaksu i način djelovanja operatora dereferenciranja. Na koje tipove podataka on
može djelovati? Kakvom tipu podatka smijemo pridružiti rezultat njegovog djelovanja?
13. Navedite koja sve različite operatore predstavlja isti znak * u jeziku C / C++ . Objasnite kako
razlučujete o čemu se radi, i kako će to učiniti kompilator?
77
14. Smijemo li dereferencirati rezultat djelovanja operatora adresa-od? Smijemo li djelovati opera-
torom adresa-od na rezultat djelovanja operatora dereferenciranja? Razmislite o odgovoru a po-
tom ga provjerite u testnom programu.
15. Deklarirajte nekoliko varijabli tipa float, te nekoliko kazaljki na taj isti tip. Kazaljkama pridije-
lite adrese varijabli. Zatim dereferencirajte kazaljke i komentirajte što se dobiva. Provjerite zak-
ljučke u testnom programu.
// A. Definiranje kazaljki:
pI1 = &i1; // Kazaljka pI1 ima značenje adrese koja pokazuje
// na tip int – pridružujemo joj vrijednost adrese
// varijable i1 s pomoću operatora & (address-of)
// Ispis A:
cout << " i1 = " << i1 << "\n"
<< " pI1 = " << pI1 << "\n"
<< " *pI1 = " << *pI1 << "\n"
*
Iskoristite kalkulator iz skupa priručnih programa OS Windows: All Programs\ Accessories\Calculator.
Odaberite znanstvenu (engl. Scientific) inačicu kalkulatora i podesite je da radi u heksadekadskom sustavu.
Izvršite oduzimanje pazeći da od većeg broja oduzimate manji. U protivnom ćete dobiti negativan rezultat koji
je prikazan kao potpuni komplement, tj. na istovjetan način kao što bi on bio pohranjen u memoriji računala.
80
<< " *&i1 = " << *&i1 << "\n"
<< "&*pI1 = " << &*pI1 << "\n"
<< endl;
// Ispis C:
cout << " char c1 = " << c1 << "\n"
<< "(int) c1 = " << (int) c1 << "\n"
<< " *pC = " << (int) *pC << "\n"
<< " pI1 = " << pI1 << "\n"
<< " *pI1 = " << *pI1 << "\n"
<< endl;
// Ispis A:
cout << "pS1 = sArr = " << pS1 << "\t *pS1 = " << *pS1 << "\n"
<< "pS2 = sArr + 1 = " << pS2 << "\t *pS2 = " << *pS2 << "\n"
<< endl;
// B.
pS1 = sArr; // Kuda pokazuje pS1?
pS2 = sArr + cN – 1 ; // Kuda pokazuje pS2?
// Ispis B:
cout << "pS1 = sArr = " << pS1 << "\t *pS1 = " << *pS1 << "\n"
<< "pS2 = sArr + cN – 1 = " << pS2 << "\t *pS2 = " << *pS2 << "\n"
<< endl;
// C.
pS1 = sArr + cN/2 ; // Kuda pokazuje pS1?
pS2 = sArr + cN/2 + 1; // Kuda pokazuje pS2?
// Ispis C:
cout << "pS1 = sArr + cN/2 = " << pS1 << "\t *pS1 = " << *pS1
<< "\n"
<< "pS2 = sArr + cN/2 + 1 = " << pS2 << "\t *pS2 = " << *pS2
<< "\n"
<< endl;
a) Objasnite sve vrijednosti ispisanih kazaljki. Skicirajte lokalni stog, odredite kolika je vrijednost
adrese AS prve i adresa ostalih varijabli u konkretnom slučaju, te smjestite varijable. Na kojoj je
adresi smješten navod rI? Što je upisano na toj adresi (za ispis sadržaja uporabljen je izlazni «ma-
nipulator» hex koji sav naknadni ispis mijenja u heksadekadsku formu, vidi pogl. 3).
Napomena: zaključke možete provjeriti i pokretanjem ispravljača (engl. “debugger”), uz prethod-
nu postavku stojnih točaka (engl. break point), te unutar izbornika pogleda (view) odabirom is-
pravljačkog prozora (debug window) kao zbirnog obratnika (disassembly).
b) Što se zaista promijenilo nakon pridruživanja rI = i2? Je li došlo do promjena sadržaja na adresi
na kojoj je pohranjena referenca rI? Kako to da se promijenila vrijednost od i1? Objasnite detalj-
no što se događa.
int i1 = 10, i2 = 20; // Lokalne varijable i1, i2, duljine 4B.
// A.
// Navodnički tip (reference type)
int& rI = i1; // Lokalna varijabla rI, tipa “int ref”.
int *pI1 = &i1, *pI2 = &i2; // Kazaljke na i1 i i2 respektivno.
int *prI = &rI; // Kazaljka prI pokazuje na što?
int *prA = pI2 - 1 ; // Kazaljka prA pokazuje na što?
// Ispis A:
cout << "a: int i1 = " << i1 << ", i2 = " << i2 << "; int& rI = i1;\n"
<< " int *pI1 = &i1, *pI2 = &i2; int* prI = &rI;\n"
<< " int* prA = pI2 – 1 ;\n"
<< "========================================================\n"
<< "i1 = " << i1 << "\t\ti2 = " << i2 << "\t\t rI = " << rI << "\n\n"
<< "pI1 = " << pI1 << "\n"
<< "pI2 = " << pI2 << "\n"
<< "prI = " << prI << "\n" // prI = ???
<< "prA = " << prA << "\n" // prA = ???
<< "*prA = " << hex << *prA << dec << "\n" // *prA = ???
<< endl;
// B.
rI = i2; // rI = ?, i1 = ?, i2 = ?
// Ispis B:
cout << "b: rI = i2;\n"
<< "========================================================\n"
<< "i1 = " << i1 << "\t\ti2 = " << i2 << "\t\t rI = " << rI << "\n\n"
<< "pI1 = " << pI1 << "\n"
<< "pI2 = " << pI2 << "\n"
<< "prI = " << prI << "\n" // prI = ???
<< "prA = " << prA << "\n" // prA = ???
<< "*prA = " << hex << *prA << dec << "\n" // *prA = ???
<< endl;
//////////////////////
88
int main()
{
const short int cNmax = 128; // Maksimalni eksponent.
short int iN; // Eksponent iN potencije iM^iN.
int iM; // Baza iM potencije iM^iN.
cout << "Racun potencije: m^n; int m, unsigned short int n.\n\n"
<< "(Stop = 'Ctrl+Break')\n"
<< "======================================================\n"
<< endl;
34, (−10)5. Potrebno je proći kroz sve tvrdnje funkcije ipow bilježeći sve međurezultate i konačne
rezultate.
d) Potencije u n rastu kao eksponencijalna funkcija, tj. vrlo brzo. Testirajte rezultate za 10n gdje je
n = 7, 8, 9, 10, pa zatim za 2n uz n = 10, 20, 30, 31, 32, … , te za (–2)n za iste vrijednosti od n.
Što primjećujete? Je li ova «jednostavna i elegantna» funkcija ujedno i robusna? Dojavljuje li se
kako pozivnoj funkciji da je rezultat pogrešan? Objasnite.
c) Na papiru provjerite kako radi gornja funkcija za sljedeće slučajeve stvarnih argumenata:
dpow(1.5, 0), dpow(1.5, -1), dpow(1.5, 2), dpow(1.5, -3), dpow(0.5, 5). Za provjeru izračuna
koristite se kalkulatorom.
d) Objasnite kako je ostvaren izračun negativne potencije? Čemu služi logička varijabla bSign? U
kojem slučaju i zašto se potencija n množi s −1 ?
Zadatak 8.5 *uz Primjer 8.2. Poziv i uporaba funkcije dpow. Uporaba funkcije scanf.
Proanalizirajte sljedeću glavnu funkciju koja poziva funkciju dpow. Podaci se unašaju preko funkcije
scanf koja omogućuje višestruki formatirani unos, a ispisuju preko funkcije printf koju smo već
susreli u pogl. 2.
a) U izborniku Pomoć potražite detalje o ove dvije funkcije. Naučite osnove o načinu formatiranja
ispisa i unosa. Primijetite da se taj format navodi u početnom C nizu. Na mjestu gdje se navede
znak % bit će redom ispisana (upisana) vrijednost varijable iz liste iza C niza. Broj znakova %
očito ne smije biti veći od broja varijabli (izraza) u listi. Iza znaka % se navode detalji formata,
npr. l za int i double, f za float, zatim slijede pobliže oznake ispisa, kao d za decimalni, o za
oktalni, x i X za heksadekadski ispis, itd.
b) Navedite gdje se u glavnoj funkciji poziva funkcija dpow.
c) Provjerite mnoge odlike formata ove funkcije unošenjem ključnog pojma «Format Specification
Fields” u tražilicu MSDN knjižnice.
d) Ugradite funkciju dpow i donju glavnu funkciju u testni program i provjerite njezin rad.
int main()
{
double dX;
short int n;
cout << "Racun potencije: x^n, doulbe x, short int n, n je el. iz Z\n"
<< "Stop = Ctrl+Break\n"
<< "======================================================\n"
<< endl;
// Beskonačna petlja:
while(true)
{
printf("\nx = ");
scanf("%lf", &dX);
printf("n = ");
scanf("%hd", &n);
printf("\n%le ^%hd = %le\n", dX, n, dpow(dX, n));
92
printf("=====================================\n");
}
return 0;
}
⎛n⎞
Binomni koeficijent ⎜⎜ ⎟⎟ označava k-ti koeficijent (k = 0, 1, 2, … … , n) u razvoju n-te potencije
k ⎝ ⎠
*
binoma :
⎛n⎞ ⎛n⎞ ⎛ n⎞ ⎛n ⎞ 2 n − 2 ⎛ n ⎞ 1 n −1 ⎛ n ⎞ 0 n
(a + b )n = ⎜⎜ ⎟⎟a n b 0 + ⎜⎜ ⎟⎟a n −1b1 + ⎜⎜ ⎟⎟a n − 2 b 2 + ... ... + ⎜⎜ ⎟⎟a b + ⎜⎜ ⎟⎟a b + ⎜⎜ ⎟⎟a b
⎝0⎠ ⎝1 ⎠ ⎝ 2⎠ ⎝ n − 2⎠ ⎝ n − 1⎠ ⎝n⎠
n(n − 1) n − 2 1 n(n − 1) n − 2 2
= a n + na n −1b1 + a b + ... ... + a b + na n −1b1 + b n .
2 2
C nk je ujedno i broj kombinacija k-tog reda od n-elementa, odnosno broj podskupova od k elemena-
6
ta koji se mogu sastaviti od skupa od n elemenata. Tako npr. C 45 predstavlja broj kombinacija «lo-
7
ta 6 od 45», a C 39 «lota 7 od 39». Za binomne koeficijente vrijedi simetrija, tj. C nk = C nn − k , pa je:
⎛ 45 ⎞ 45 × 44 × 43 × 42 × 41 × 40
6
C 45 = ⎜⎜ ⎟⎟ = ,
⎝6 ⎠ 1× 2 × 3 × 4 × 5 × 6
⎛ 39 ⎞ 39 × 38 × 37 × 36 × 35 × 34 × 33
C397 = ⎜⎜ ⎟⎟ = .
⎝7 ⎠ 1× 2 × 3 × 4 × 5 × 6 × 7
Program treba pozivati funkciju tipa int pod nazivom binomcoef(), koja računa binomne koefici-
jente tako da se pri računu ostvaruje maksimalno kraćenje. U programu je potrebno ostvariti pregle-
dan unos i kontrolu veličina k i n ( k ≤ n ), te omogućiti korisniku da ponavlja izračun proizvoljan
broj puta. Naputak. Pokušajte ostvariti vlastito rješenje. pažljivo proučite navedeno rješenje funkcije
*
Za detalje, te za obrazloženje kako se binomni koeficijenti za n-tu potenciju elegantno računaju s pomoću Pas-
calovog trokuta konzultirajte matematičku literaturu.
93
koju ćete pozivati iz programa. Odgovorite može li se zbog greške cjelobrojnog dijeljenja desiti da
funkcija vrati pogrešan rezultat? Razmotrite to na jednostavnijim primjerima, a zatim pokušajte izves-
ti opći zaključak.
// ... ...
// Poziv funkcije je oblika:
sort2(iA, iB);
c) Potrebno je ostvarite istu funkcionalnost kao pod (b), ali bez prijenosa po navodu.
// b) Pointer arguments:
94
void sort2(int* pI1, int* pI2);
{
int iTmp; // Temporary variable
if (*pI1 > *pI2) // Swap integers!
{
iTmp = *pI1;
*pI1 = *pI2;
*pI2 = iTmp;
}
}
// ... ...
// Poziv funkcije je oblika:
sort2( &iA, &iB );
// Poziv funkcije:
strangeArrayCallByRef(sX[0], cN);
short int *pS1, *pS2; // Kazaljke za pohranu adresa.
pS1 = &sX[0]; // Adresa početnog elementa.
pS2 = &sX[cN-1]; // Adresa zadnjeg elementa.
// Raspon adresa za poredak sX[0x100]
cout << "\n"
<< "pS1 = &sX[ 0] = " << pS1 << "\n"
<< "pS2 = &sX[cN-1] = " << pS2 << "\n"
<< endl;
return 0;
}
98
Primjer 9.2 Unos proizvoljnog niza znakova funkcijom getchar, ispis funkcijom
putchar.
Potrebno je napisati program koji sa tastature učitava jednu liniju znakova u znakovni poredak kao
standardni C-niz uz pomoć funkcija getchar za učitavanje ASCII znaka, te potom ispisuje tu istu
liniju uporabom funkcije putchar za ispis. Standardna linija sadrži maksimalno 80 znakova, što je
jednako standardnom broju znakova jednog retka na konzolnom prikazniku, odnosno na matričnom
printeru. Alternativno, korisnik može okončati liniju i kontrolnim znakom '\n' = new line.
// Prethodna uključenja:
// ... ...
#include <stdio.h>
// Unos teksta preko getchar(), ispis preko putchar(char c):
int main()
{
const unsigned int cN = 80; // Broj znakova u liniji
char c, cL[cN + 1]; // Znakovni poredak za jednu liniju teksta
cout
<< "Unos reda proizvoljnih znakova (za kraj ‘return’ ili ‘enter’):\n"
<< "================================================================"
<< endl;
unsigned int i = 0;
while( ((c = getchar()) != '\n') && (i < cN) )
cL[i++] = c;
cL[i] = '\0';
putchar('\n'); // Jedan red razmaka
cout
<< "Ispis reda teksta, kao C-niza iz znakovnog poretka cLine[81]:\n"
<< "================================================================"
<< endl;
i= 0;
while( (c = cL[i++]) != '\n' ) // Ispis do kraja C-niza(!?!)
putchar(c);
putchar('\n'); // Novi red
putchar('\n'); // Jedan red razmaka
}
101
Zadatak 9.4 Dodatni uvjet u petljama za unos i ispis s pomoću getchar i putchar
(Primjer 9.2).
a) U prethodnom programu poopćite uvjet u petljama za unos i ispis znakova tako da se petlja preki-
da i pri nailaženju na znak EOF (od engl. End Of File), ASCII(EOF) = FFh = −1(8bit). U prog-
ramu možete izravno koristiti i navedenu kraticu EOF, ili zamjenske oznake.
b) Podsjetite se na značenje ovog kontrolnog znaka i na njegov zapis u ASCII kodu. Nalazi li se on u
0.-toj ili 1.-voj stranici ASCII koda? Ima li taj znak zasebnu tipku na tastaturi s pomoću koje ga
možemo unijeti i prekinuti unos znakova? Postoji li kombinacija tipki s pomoću koje ga možemo
unijeti? Pokušajte provjeriti eksperimentom. Da biste bili sigurni da ste unijeli upravo znak EOF, u
uvjetu petlje za unos morate iskomentirati dio koji se odnosi na znak za novi red.
int main()
{
char cImeIPrez[30]; // Znakovni poredak dovoljne dimenzije
cout << "\nUnesite ime i prezime: ";
cin.getline(cImeIPrez, sizeof cImeIPrez);
Literatura
1. R. Logožar, Uvod u programiranje i jezike C/C++, VELV, interno izdanje, dostupno na
http://moodle.velv.hr/moodle/ .
2. B. W. Kernighan, D. M. Ritchie, The C Programming Language, 2nd ed., Upper Saddle River, NJ,
Prentice Hall, 1988.
3. B. Stroustrup: The C++ Programming Language, 3rd ed., Reading, Massachusetts, 1997.
4. C. S. Horstmann, Mastering Object-Oriented Design in C++, John Wiley & Sons, New York,
1995.
5. A. B. Tucker at al. Fundamentals of Computing I & II, C++ Edition, McGraw-Hill, New York,
1995.
6. Motik, Šribar: Demistificrani C++, 2. izdanje Element Zagreb, 2001.
7. L. Budin, Informatika 1, udžbenik za 1. razred gimnazije, Element d.o.o., Zagreb, 2001.
8. Wikipedia članak: www.wikipedia.org. – članak imena navedenog u tekstu.
9. Microsoft Developers Network (MSDN) Library, http://msdn.microsoft.com/en-us/library/ .