U lekciji "Logički tip i logičke operacije" imali smo zadatak sa papirom i kovertom. Ovde cemo rešiti nešto složeniji zadatak. Date su dimenzije tri pravougaona lista papira. Potrebno je odrediti veličinu najmanje koverte u koju sva tri lista mogu da stanu bez savijanja, tako da im ivice budu paralelne ivicama koverte.
Neka su dimenzije papira redom a1_X_b1, a2_X_b2 i a3_X_b3. Pretpostavimo za trenutak da je a1≥b1, a2≥b2 i a3≥b3. Ako sada najveći od brojeva a1, a2, a3 označimo sa najveci_a, a najveći od brojeva b1, b2, b3 sa najveci_b, tada su dimenzije tražene koverte upravo najveci_a x najveci_b.
Ispitivanje bi moglo prilično da se zakomplikuje ukoliko nejednakosti a1≥b1, a2≥b2 i a3≥b3 nisu ispunjene.
Kod ovakvih papira morali bismo da proveravamo više slučajeva sa različito okrenutim papirima, na primer kao što je prikazano ispod.
Ovaj problem bismo najlakše rešili ako postignemo da navedene nejednakosti postanu ispunjene. Da bismo obezbedili, na primer, da a1 ne bude manje od b1 možemo da izvršimo sledeće:
if (a1 < b1) { int pomocna = a1; a1 = b1; b1 = pomocna; }
Ovim naredbama postižemo da promenljive a1 i b1 razmene vrednosti ako je bilo a1<b1.
Posle ove if naredbe, promenljive a1 i b1 i dalje sadrže ista dva broja kao i pre (papir je i dalje istih dimenzija), ali sada sigurno važi a1≥b1 (papir je postavljen vodoravno, kao što će biti i koverta). Uradimo isto i za ostala dva papira i dobijamo program koji rešava zadatak.
using namespace std; #include <iostream> #include <algorithm> void main() { int a1, b1, a2, b2, a3, b3, pomocna, najveci_a, najveci_b; cout << "Unesite dimenzije prvog papira: "; cin >> a1 >> b1; if (a1 < b1) { pomocna = a1; a1 = b1; b1 = pomocna; } cout << "Unesite dimenzije drugog papira: "; cin >> a2 >> b2; if (a2 < b2) { pomocna = a2; a2 = b2; b2 = pomocna; } cout << "Unesite dimenzije treceg papira: "; cin >> a3 >> b3; if (a3 < b3) { pomocna = a3; a3 = b3; b3 = pomocna; } najveci_a = max(a1, max(a2, a3)); najveci_b = max(b1, max(b2, b3)); cout << "Najmanja koverta u koju mogu da stanu sva tri papira je " << najveci_a << " x " << najveci_b << "." << endl; system("pause"); }
Da bismo mogli da koristimo funkciju max, potrebno je na početku programa da uključimo onaj deo biblioteke funkcija u kome je funkcija max definisana.
#include <algorithm>
Funkcija max kao rezultat vraća veći od dva broja koja joj prosledimo kao parametre, na primer max(5,3) daje rezultat 5. Kombinovanjem dva poziva funkcije max, kao u max(a1, max(a2, a3)), dobijamo najveći od tri broja.
Vidimo da se ovde deo programa koji uređuje dva broja po veličini pojavljuje tri puta. Ranije smo ovakva ponavljanja izbegavali uvođenjem funkcija. Međutim, ukoliko bismo ovde napisali sledeću funkciju, ona ne bi radila onako kako očekujemo.
static void Uredi(int a, int b) { int pomocna; if (a < b) { pomocna = a; a = b; b = pomocna; } }
Razlog leži u tome što, kada se parametri funkcije ovako zadaju, funkcija napravi svoje kutije za parametre, i u te kutije prepiše vrednosti iz naših kutija sa mesta poziva funkcije. Kada funkcija završi sa radom, ona svoje kutije baci, a u našim kutijama vrednosti ostaju kakve su na početku i bile. Ispričano jezikom programera, funkcija napravi svoje privatne kopije parametara, i koristi te kopije pri izvršavanju. Po završetku, funkcija prostor koji je zauzela za kopije oslobađa i vrednosti kopija se pri tome gube, a originalne promenljive ostaju nepromenjene.
Potrebno je da dodamo znak & ispred tipa i imena parametra ako hoćemo da funkcija radi sa originalnim promenljivama.
void Uredi(int& a, int& b) { int pomocna; if (a < b) { pomocna = a; a = b; b = pomocna; } }
Ova mala razlika omogućava da promene koje funkcija napravi na parametrima budu trajne, to jest da se dogode na originalnim promenljivama sa mesta poziva funkcije.
Pomenimo uzgred da za parametre bez znaka "&" još kažemo da se u funkciju prenose po vrednosti (engl. pass by value), jer se vrednost parametra kopira u novu kutiju (promenljivu) u okviru funkcije. Nasuprot tome, za parametre obeležene znakom "&" kažemo da se prenose po referenci (engl. pass by reference) jer se funkciji samo kaže gde je parametar, tj. daje joj se referenca na kutiju (promenljivu) koja sadrži parametar.
Program bi na kraju mogao da izgleda ovako:
using namespace std; #include <iostream> #include <algorithm> void Uredi(int& a, int& b) { int pomocna; if (a < b) { pomocna = a; a = b; b = pomocna; } } void main() { int a1, b1, a2, b2, a3, b3, najveci_a, najveci_b; cout << "Unesite dimenzije prvog papira: "; cin >> a1 >> b1; Uredi(a1, b1); cout << "Unesite dimenzije drugog papira: "; cin >> a2 >> b2; Uredi(a2, b2); cout << "Unesite dimenzije treceg papira: "; cin >> a3 >> b3; Uredi(a3, b3); najveci_a = max(a1, max(a2, a3)); najveci_b = max(b1, max(b2, b3)); cout << "Najmanja koverta u koju mogu da stanu sva tri papira je " << najveci_a << " x " << najveci_b << "." << endl; system("pause"); }