struct Student
{
string ime;
string prezime;
string upisna;
int ocjena;
};
struct SortPoImenu
{
bool operator()(const Student& ls, const Student& rs) const
{
return ls.ime < rs.ime;
}
};
int main(void)
{
Student s1;
s1.ime = "fana";
s1.prezime = "tikos";
s1.upisna = "ne znam sto je to";
s1.ocjena = 3;
Student s2;
s2.ime = "Ivica";
s2.prezime = "Ivic";
s2.upisna = "opet ne znam sto je to";
s2.ocjena = 1;
std::vector<Student> studenti;
studenti.push_back(s1);
studenti.push_back(s2);
// Prije sortiranja po imenu
std::cout << "Prije sortiranja po imenu:\n";
std::cout << "--------------------------\n";
std::cout << "1. student, ime: " << studenti[0].ime << '\n';
std::cout << "2. student, ime: " << studenti[1].ime << '\n' << std::endl;
// Sortiranje
std::sort(studenti.begin(), studenti.end(), SortPoImenu());
//Poslije sortiranja po imenu
std::cout << "Poslije sortiranja po imenu:\n";
std::cout << "--------------------------\n";
std::cout << "1. student, ime: " << studenti[0].ime << '\n';
std::cout << "2. student, ime: " << studenti[1].ime << '\n' << std::endl;
return 0;
}
Ovo je samo za sortiranje po imenu, isti functor se moze upotrijebiti i za sortiranje po prezimenu, dok za sortiranje po ocjeni i upisnoj treba implementirati nove.
Programiranje u C++-u - pitanja i odgovori
- poruka: 7.284
- |
- čitano: 1.966.832
- |
- moderatori:
XXX-Man
- +/- sve poruke
- ravni prikaz
- starije poruke gore
Imam jednu vrstu problema: Poznajem proceduralno programiranje jako dobro te osnove OOP, ali kada se susretnem sa konkretnim problemom/zadatkom vrlo rijetko znam šta da upotrijebim, odlično postavim problem i znam šta da činim, ali ne primjenjujem stečeno znanje.
Ne znam što da činim, čini se da je problem podsvjesni?
Nije nikakav podsvjesni problem u pitanju, nego se programiranje ne svodi na memoriziranje sintaktičkih pravila i poznavanje funkcija iz standardne biblioteke. Programiranje u svojoj srži jest razbijanje nekog problema na sitne korake i objašnjavanje računalu korak po korak što da radi kako bi moglo obaviti neki traženi zadatak. Odnosno kreiranje i uporaba algoritama.
Kako to misliš ne znaš što da upotrijebiš? Ako ne znaš što bi upotrijebio to onda znači da ne poznaješ dovoljno jezik koji koristiš. Često imaš više načina za obaviti neku stvar, od kojih će neki biti prikladniji od drugih u nekoj situaciji. Primjera radi, ako trebaš pročitati cijeli broj sa tipkovnice možeš koristiti:
scanf
scanf + atoi
scanf + sscanf
scanf + vlastita funkcija za konverziju stringa u broj
fscanf
fscanf + atoi
fscanf + sscanf
fscanf + vlastita funkcija za konverziju stringa u broj
gets + atoi
gets + sscanf
gets + vlastita funkcija za konverziju stringa u broj
fgets + atoi
fgets + sscanf
fgets + vlastita funkcija za konverziju stringa u broj
Eto, jednostavna radnja čitanja cijelog broja sa tipkovnice, a koliko mogućnosti (neke od kojih su malo i besmislene, i tu su čisto "zato što se i tako može").
Kada vladaš jezikom, znaš koje tipove podataka podržava, koje operatore ima za rad sa tim tipovima podataka, te otprilike kakve sve funkcije ima u standardnoj biblioteci, imat ćeš sve lego kockice koje su ti potrebne za "izgradnju" programa. Dalje trebaš samo znati kako ih "slagati" da bi postigao ono što želiš.
Daj neki primjer zadatka koji još nisi riješio a na kojem si zapeo, pa da malo bolje vidimo gdje točno zapinje.
Imam ja odlične ideje, ali se često desi da ne mogu da prepoznam šta od znanja treba primjeniti.
Znam šta treba uraditi, ali ne znam kako to da učinim iz znanja koje posjedujem.
Razumijem i divide&conquer i brute force i turbo sort, ali kad konkretan problem ne kaže nešto tipa "e, koristi operacije nad stringovima za ovo, koristi 3D nizove itd." ili to ne sugeriše onda nastaje problem.
struct Student
{
string ime;
string prezime;
string upisna;
int ocjena;
};
struct SortPoImenu
{
bool operator()(const Student& ls, const Student& rs) const
{
return ls.ime < rs.ime;
}
};
int main(void)
{
Student s1;
s1.ime = "fana";
s1.prezime = "tikos";
s1.upisna = "ne znam sto je to";
s1.ocjena = 3;
Student s2;
s2.ime = "Ivica";
s2.prezime = "Ivic";
s2.upisna = "opet ne znam sto je to";
s2.ocjena = 1;
std::vector<Student> studenti;
studenti.push_back(s1);
studenti.push_back(s2);
// Prije sortiranja po imenu
std::cout << "Prije sortiranja po imenu:\n";
std::cout << "--------------------------\n";
std::cout << "1. student, ime: " << studenti[0].ime << '\n';
std::cout << "2. student, ime: " << studenti[1].ime << '\n' << std::endl;
// Sortiranje
std::sort(studenti.begin(), studenti.end(), SortPoImenu());
//Poslije sortiranja po imenu
std::cout << "Poslije sortiranja po imenu:\n";
std::cout << "--------------------------\n";
std::cout << "1. student, ime: " << studenti[0].ime << '\n';
std::cout << "2. student, ime: " << studenti[1].ime << '\n' << std::endl;
return 0;
}
Ovo je samo za sortiranje po imenu, isti functor se moze upotrijebiti i za sortiranje po prezimenu, dok za sortiranje po ocjeni i upisnoj treba implementirati nove.
Bolje sa lambdom, ali i ovo je ok...
Cao. treba mi resenje hitno!
Da se napise program u koji binarno ce da se traziprisutnost nekog elementa. Niza moze da se deklarise kao konstanta(unapred zadatih clanova) a element da se unosi kao promenljiva. Da se napise resenje u kom ce da se koristi REKURIJA.
Hvala puno onome ko pomogne :-)
Mozda je lako al ja tek pocinjem :-)
Cao. treba mi resenje hitno!
Sretno ti s takvim pristupom
Bok ljudi :) hitno mi je...pokušavam naučiti programiranje pa bih krenuo od jednostavnih zadataka tipa kako napraviti smile pa ako bi mi netko mogao napisati kod bio bih jako zahvalan.
I zašto je to hitno ako pokušavaš sam učiti programiranje? Osim toga programiranje se ne uči tako. I što uopće podrazumijevaš pod "napraviti smile"?
Svima je uvijek nešto "hitno", i onda takve upite postavljaju baš na forumu, gdje se odgovori mogu čekati i mjesecima 
Ako je stvarno hitno, traženje odgovora na nekakvom IRC kanalu bi bilo puno prikladnije.
Može pomoc??
Trebam izracunati zbroj dvaju jedinicnih matrica koristeci jednu friend funkciju zbroji koja prima kao parametre dvije matrice!!
Nezz sto mi je krivo u kodu, volio bih ako bi mi netko objasnio
#include <iostream>
#include <string>
using namespace::std;
class matrix{
private:
string ime;
int row,col;
int* element;
public:
matrix(string ime, int col, int row);
~matrix(){cout<<"Matrica "<<ime<<" je unistena! "<<endl; delete [] element;}
void ispis();
friend matrix zbroji(matrix a, matrix b);
};
matrix::matrix(string ime,int row, int col){
this -> ime = ime;
this -> row = row;
this -> col = col;
element = new int [row * col];
for(int i = 0; i < row; i++)
for(int j = 0; j < col; j++){
*( element + col * i + j ) = 1;
}
}
matrix zbroji(matrix a, matrix b){
matrix c = a;
c.element = new int [a.row * a.col];
c.ime = c.ime + " + " + b.ime;
for(int i = 0; i < a.row; i++)
for(int j = 0; j < a.col; j++){
*( c.element + a.col * i + j ) += *( b.element + a.col * i + j );
}
return c;
}
void matrix::ispis(){
cout<<"Matrica "<<ime<<endl;
for(int i = 0; i < row; i++){
cout<<endl;
for(int j = 0; j < col; j++){
cout<<*( element + col * i + j )<<" ";
}
}
}
int main(){
matrix a("a", 3, 3), b("b", 3, 3);
a.ispis();
cout<<endl<<endl;
b.ispis();
cout<<endl<<endl;
matrix d = zbroji(a,b);
d.ispis();
return 0;
}
Znas li kada se destruktor poziva?
Ako "iskljucis" destructor, onda imas memory leak, to nije rjesenje.
Ono sto tebi fali je copy-constructor: matrix(const matrix& other);
C++ salje parametre po vrijednosti: zbroji(a,b) ce kopirat a,b iz main u lokalne a,b. 'matrix c=a' je isto poziv copy-constructora kao i 'd=zbroji(a,b)'.
I u funkciji zbroji:
matrix c = a;
c.element = new int [a.row * b.col];
Ova druga linija potpuno prebrise c.element. A kasnije u petlji samo nadodajes elemente iz b, kao da je ono iz a vec unutra. Nisam pokrenuo program, ali ne vidim kako bi ovo moglo radit ako i iskljucis destructor...
Iako ne znam koliko ce ovo objasnjenje biti jasno, jer mi se iz pitanja "zasto treba iskljucit destruktor" cini da imas nejasnoca oko nekih fundamentalnih koncepata.
Uglavnom hvala na odgovoru.. ubiti novi sam u ovomu... al sto mi je najsmijesnije ... ovo mi je zadatak od profesora... kao stavljeno .....destruktor iskljucujemo zbog greske pri vracanju matrice iz funkcije Zbroji() ... pa sam se zapitao vamo na forumu...... u biti kad se iskljuci uistinu ih zbroji.. al samo prepise u matricu a zbroj koliko ja shvaćam!!
Znas li kada se destruktor poziva?
Pa kad odeđeni objekt nije potreban tj. kako bi se oslobodila memorija!!! zar nije zbog toga??? Sorry sto ovak pitam ali uci se na greskama ! ;)
Znas li kada se destruktor poziva?
Pa kad odeđeni objekt nije potreban tj. kako bi se oslobodila memorija!!! zar nije zbog toga??? Sorry sto ovak pitam ali uci se na greskama ! ;)
Imas 3 tipa objekata (kao i varijabli).
1. Globalni objekti
definicija ovih objekata je izvan funkcija i oni traju do kraja programa, tj. po izlasku iz programa se implicitno pozivaju destruktori
2. Lokalni objekti
ovo su objekti koji se nalaze na stacku, i oni traju sve do kraja funkcije u kojoj su stvoreni, tj. kada se funkcija zavrsi, onda se implicitno poziva destruktor
3. Objekti na heapu
ovo su objekti koje si stvori preko operatora new, njihov destruktor se implicitno poziva prilikom koristenja operatora delete
P.S. osim implicitnih poziva destruktora postoje i eksplicitni, ali oni nemaju smisla
Znas li kada se destruktor poziva?
Pa kad odeđeni objekt nije potreban tj. kako bi se oslobodila memorija!!! zar nije zbog toga??? Sorry sto ovak pitam ali uci se na greskama ! ;)
Imas 3 tipa objekata (kao i varijabli).
1. Globalni objekti
definicija ovih objekata je izvan funkcija i oni traju do kraja programa, tj. po izlasku iz programa se implicitno pozivaju destruktori
2. Lokalni objekti
ovo su objekti koji se nalaze na stacku, i oni traju sve do kraja funkcije u kojoj su stvoreni, tj. kada se funkcija zavrsi, onda se implicitno poziva destruktor
3. Objekti na heapu
ovo su objekti koje si stvori preko operatora new, njihov destruktor se implicitno poziva prilikom koristenja operatora delete
P.S. osim implicitnih poziva destruktora postoje i eksplicitni, ali oni nemaju smisla
Malo si pomiješao.
Postoje statički i dinamički alocirani objekti. Statički su ovi koje spominješ pod 2, a dinamički ovi pod 3. I statički i dinamički objekti mogu biti globalni i lokalni. U pravilu, globalne objekte treba izbjegavati zbog narušavanja koncepta crne kutije (funkcije koje koriste globalne objekte ovisne su o vanjskim varijablama i stoga se ne mogu direktno koristiti u drugim projektima gdje te vanjske varijable ne postoje). Umjesto toga, te varijable treba koristiti kao parametre (lokalne varijable) funkcije.
Malo si pomiješao.
Postoje statički i dinamički alocirani objekti. Statički su ovi koje spominješ pod 2, a dinamički ovi pod 3. I statički i dinamički objekti mogu biti globalni i lokalni. U pravilu, globalne objekte treba izbjegavati zbog narušavanja koncepta crne kutije (funkcije koje koriste globalne objekte ovisne su o vanjskim varijablama i stoga se ne mogu direktno koristiti u drugim projektima gdje te vanjske varijable ne postoje). Umjesto toga, te varijable treba koristiti kao parametre (lokalne varijable) funkcije.
Ispravi me ako grijesim.
Globalni objekti - memoriju za njih rezervira kompajler
Lokalni - memorija za njih se zauzima za vrijeme izvrsavanja, i oni se nalaze na stacku
Objekti na heapu - memorija za njih se takoder zauzima za vrijeme izvrsavanja pomocu operatora new i oni se nalaze na heapu
Malo si pomiješao.
Postoje statički i dinamički alocirani objekti. Statički su ovi koje spominješ pod 2, a dinamički ovi pod 3. I statički i dinamički objekti mogu biti globalni i lokalni. U pravilu, globalne objekte treba izbjegavati zbog narušavanja koncepta crne kutije (funkcije koje koriste globalne objekte ovisne su o vanjskim varijablama i stoga se ne mogu direktno koristiti u drugim projektima gdje te vanjske varijable ne postoje). Umjesto toga, te varijable treba koristiti kao parametre (lokalne varijable) funkcije.
Ispravi me ako grijesim.
Globalni objekti - memoriju za njih rezervira kompajler
Lokalni - memorija za njih se zauzima za vrijeme izvrsavanja, i oni se nalaze na stacku
Objekti na heapu - memorija za njih se takoder zauzima za vrijeme izvrsavanja pomocu operatora new i oni se nalaze na heapu
Ovo što si napisao pod "globalni" i "lokalni" su zapravo opisi statički alociranih objekata, dok objekti na heapu su dinamički alocirani.
Primjerice, možeš imati i dinamički objekt deklariran globalno, no on nije na stacku već na heapu.
Odnosno, po svom smještaju i trajanju postoje samo statični i automatski objekti. Statični idu u posebnu sekciju (bolje rečeno sekcije, jer se i to dijeli na inicijaliziranu Data sekciju i neinicijaliziranu BSS sekciju) u izvršnoj datoteci koja pri učitavanju programa u memoriju može graničiti sa heap memorijom ili sa stack memorijom (ovisno o operacijskom sustavu), dok objekti sa automatskim trajanjem završe na stacku.
Eksplicitna alokacija memorije se uglavnom obavlja na heapu, ili u nekim posebnim slučajevima na stacku (alloca). Pri čemu se adresa tako dobivenog bloka memorije opet pohranjuje u varijablu (pokazivač) koja ima ili statično ili automatsko trajanje.
Prikaz razmještaja određenih sekcija u adresnom prostoru pod Linuxom.
Prikaz razmještaja određenih sekcija u adresnom prostoru pod Windowsima CE (velika sličnost sa WinXP minus par detalja)
Odnosno, po svom smještaju i trajanju postoje samo statični i automatski objekti.
Statički i automatski su zapravo jedno-te-isto jer automatski postoje samo kada se uđe u neki blok i traju dok taj blok ne završi. Jedina je razlika što statički globalni objekti traju sve dok program radi. C++ standard isto tako kaže:
An object declared without a storage-class-specifier at block scope or declared as a function parameter has automatic storage duration by default.
S druge strane dinamički postoje u trenutku alociranja i nisu nužno ovisni o tom bloku već se mogu i negdje drugdje dealocirati.
Primjerice, možeš imati i dinamički objekt deklariran globalno, no on nije na stacku već na heapu.
Tehnicki gledano bas i ne: mozes imat globalni pointer koji pokazuje na objekt dinamicki alociran na heapu, ali sam objekt nije globalan, vec je pointer na njega globalan. A sam pointer je staticki alociran kao i sve ostale globalne varijable, ili u data ili u bss segmentu na slici gore.
I staticki i automatski nije jedno-te-isto - nije isto da li je alocirano na stacku (lokalna varijabla) ili u data segmentu (globalna).
Primjerice, možeš imati i dinamički objekt deklariran globalno, no on nije na stacku već na heapu.
Tehnicki gledano bas i ne: mozes imat globalni pointer koji pokazuje na objekt dinamicki alociran na heapu, ali sam objekt nije globalan, vec je pointer na njega globalan. A sam pointer je staticki alociran kao i sve ostale globalne varijable, ili u data ili u bss segmentu na slici gore.
Upravo to. Pointer je statički, no kako se njime zapravo predstavlja taj dinamički alocirani objekt i doseg do tog objekta je onda globalan.
Primjerice, možeš imati i dinamički objekt deklariran globalno, no on nije na stacku već na heapu.
I staticki i automatski nije jedno-te-isto - nije isto da li je alocirano na stacku (lokalna varijabla) ili u data segmentu (globalna).
Ovo se više može reći da je language/compiler specific. Nemaju svi programski jezici isti stav/mogućnosti glede ovoga. U C++u je sada već kao dio standarda gotovo sve automatski objekt. Iako, i sami principi danas nalažu izbjegavanje direktnog korištenja globalnih varijabli.
Statički i automatski su zapravo jedno-te-isto jer automatski postoje samo kada se uđe u neki blok i traju dok taj blok ne završi. Jedina je razlika što statički globalni objekti traju sve dok program radi. C++ standard isto tako kaže:
I statični lokalni objekti traju sve dok program radi, baš kao i statični globalni objekti. Svi statični objekti su unaprijed alocirani smještajem u posebnu sekciju i odatle se ne mrdaju tako dugo dok se program izvršava. Svi globalni objekti su u biti implicirano statični.
Ne razumijem što misliš pod jedno te isto kada jedni idu na stack, a drugi ne. Jedni postoje cijelo vrijeme, a drugi ne.
Ovo što si citirao u biti kaže da svi objekti koji su deklarirani unutar nekog bloka implicitno imaju automatsko trajanje (odnosno nije potrebno koristiti automatic keyword jer su te varijable po defaultu automatske), da bi imali statično trajanje potrebno je to eksplicitno zatražiti pomoću keyworda static.
Jedan drugi dio iz C standarda objašnjava ovo ponašanje, nažalost nepotrebno je zakompliciran sa utrpavanjem koncepta linkagea u sve to:
"An object whose identifier is declared with external or internal linkage, or with the storage-class specifier static has static storage duration. Its lifetime is the entire execution of the program and its stored value is initialized only once, prior to program startup."
Za buduću referencu:
external linkage: svi objekti deklarirani sa ključnom riječi extern. Objekti koji imaju doseg unutar cijele datoteke imaju external linkage (ako pri deklaraciji nije upotrijebljena ključna riječ static) iako nisu vidljivi iz drugih datoteka.
internal linkage: svi objekti koji imaju doseg unutar cijele datoteke a koji su deklarirani sa static ključnom riječi.
no linkage: svi objekti koji imaju doseg samo unutar nekog bloka, a koji nisu deklarirani sa static ili extern ključnom riječi
Primjerice, možeš imati i dinamički objekt deklariran globalno, no on nije na stacku već na heapu.
I staticki i automatski nije jedno-te-isto - nije isto da li je alocirano na stacku (lokalna varijabla) ili u data segmentu (globalna).
Ovo se više može reći da je language/compiler specific. Nemaju svi programski jezici isti stav/mogućnosti glede ovoga. U C++u je sada već kao dio standarda gotovo sve automatski objekt. Iako, i sami principi danas nalažu izbjegavanje direktnog korištenja globalnih varijabli.
Ne znam bas koliko je compiler/language, prije bih rekao X86 specificno. I ne bi bas rekao da je gotovo sve automatski objekt: losa je praksa koristit globalne varijable, ali static na file scopeu kao i u klasi su prilicno ceste, i nesto rjedje, static varijable na nivou funkcije, a one ne mogu na stack ni s kojim compilerom. Znacenje kljucne rijeci static je da varijabla nije automatska, to ne bi smjelo ovisit o compileru hoce li postovat to ili ne.
Statički i automatski su zapravo jedno-te-isto jer automatski postoje samo kada se uđe u neki blok i traju dok taj blok ne završi. Jedina je razlika što statički globalni objekti traju sve dok program radi. C++ standard isto tako kaže:
I statični lokalni objekti traju sve dok program radi, baš kao i statični globalni objekti.
Kad se pozove neka funkcija tek tada njeni lokalni objekti zažive na stacku i postoje samo dok ta funkcija radi. Nakon toga više ne postoje. Globalni postoje stalno.
Statički i automatski su zapravo jedno-te-isto jer automatski postoje samo kada se uđe u neki blok i traju dok taj blok ne završi. Jedina je razlika što statički globalni objekti traju sve dok program radi. C++ standard isto tako kaže:
Ne razumijem što misliš pod jedno te isto kada jedni idu na stack, a drugi ne. Jedni postoje cijelo vrijeme, a drugi ne.
Mislim da smo se od početka krivo razumijeli. Ja sam govorio o statički alociranim objektima a ti o statičkim objektima. Statički alocirani su na stacku dok statički deklarirani (ključna riječ static) su u data segmentu. Usto, statički deklarirani unutar funkcije nemaju isto značenje kao npr. i statički članovi neke klase
. Vrlo lako se zabuniti.
Da dodatno zakompliciram ako je slučajno itko pratio diskusiju dosad
, objekti mogu biti i ni na heapu ni na stacku, nego u odvojenoj fizičkoj ili virtualno mapiranoj memoriji. Posebno u embedded sustavima gdje koješta može biti mapirano u adresni prostor procesora. Ovisno kakva je memorija, sadržaj može preživjeti i gašenje programa i cijelog uređaja, može se promjeniti bez da program napravi išta, a može biti i zauvijek nečitljiv.
Čisto iz znatiželje, što točno podrazumijevaš pod "statički alociran objekt"? Primjer? Odnosno kako ta statička alokacija izgleda u programu.
Čisto iz znatiželje, može li objašnjenje ovog koncepta? Jer sam do sada mislio da je to jedno te isto. Odnosno za objekt koji je deklariran kao statički se memorija alocira statički, odnosno onako kako sam ja to objasnio (memorija iz data segmenta).
Kako izgleda ta statička alokacija u praksi (jednostavan primjer)?
void f(){
int a;
static int b = 0;
// ...
}
Varijabla 'a' je statički alocirani objekt koji postoji samo dok se izvršava blok u kojemu se nalazi. Kada se ulazi u blok ta varijabla se stavlja na stack, dok kada blok završava tada ju se skida sa stack-a.
Varijabla 'b' je statički objekt čiji životni vijek ne ovisi o bloku u kojemu se nalazi jer nije na stack-u već u data segmentu. Stoga se mogu čuvati vrijednosti u među-pozivima funkcije.
Varijabla 'b' je statički objekt koji čiji životni vijek ne ovisi o bloku u kojemu se nalazi jer nije na stack-u već u data segmentu. Stoga se mogu čuvati vrijednosti u među-pozivima funkcije.
Aha, kužim. Ti pod statičku alokaciju u biti ubrajaš ono što se u C terminologiji zove automatska alokacija (automatsko trajanje).
Pričamo o istoj stvari samo koristimo drukčiju terminologiju. Sve pet. ;)
To sam ovdje i pokušao objasniti no očito sam trebao naglasiti da je riječ o alokaciji a ne objektu.
Da statička alokacija prolazi po tom pitanju. Dok su statičko i automatsko trajanje dvije različite stvari (posebno razdvojene u standardu).
To me je zbunilo, kako sada odjednom tvrdnja da su jedno te isto 
Izgubljeni u prijevodu -.-'