PDA

Prikaži potpunu verziju : How to... C++


Strane : [1] 2

Ivan-94
26.1.2012, 3:44
Kako krenem da ucim jezik, tako pocinju teme How to.... :(

Kod:

// O-recnik.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>

using namespace std;

vector<string> split(const string& s, const string& delim, const bool keep_empty = true) {
vector<string> result;
if (delim.empty()) {
result.push_back(s);
return result;
}
string::const_iterator substart = s.begin(), subend;
while (true) {
subend = search(substart, s.end(), delim.begin(), delim.end());
string temp(substart, subend);
if (keep_empty || !temp.empty()) {
result.push_back(temp);
}
if (subend == s.end()) {
break;
}
substart = subend + delim.size();
}
return result;
}

string toLower(string strr)
{
char str[100];
string ret;
strcpy(str,strr.c_str());
int differ = 'A'-'a';
char ch;
int ii = strlen(str);
for (int i=0; i <ii;i++)
{
strncpy(&ch,str+i,1);
if (ch>='A' && ch<='Z')
{
ch = ch-differ;
memcpy(str+i,&ch,1);
}
}
ret = str;
return ret;
}

int _tmain(int argc, _TCHAR* argv[])
{
vector<string> words;
int n;
string temp;
bool flag = true;
bool nflag = true;
int counter = 0;

cin >> n;

for(int i = 0; i < n; i++){
cin >> temp;
vector<string> x = split(temp, " ");
flag = true;
counter = 0;

if(toLower(x[0]) == "add"){
for (int i = 0; i < words.size(); i++)
if(find(words.begin(), words.end(), x[1]) != words.end())
flag = false;

if(flag){
words.push_back(toLower(x[1]));
sort( words.begin(), words.end() );
}
}

if(toLower(x[0]) == "less"){
if(find(words.begin(), words.end(), x[1]) == words.end())
cout << "no such word" << endl;
else {
for (int i = 0; i < words.size(); i++)
if(words[i] != toLower(x[1]))
counter++;
else
break;
cout << counter << endl;
}
}
}

return 0;
}

I izlazi mi stalno problem "vector subscript out of range", a ja nemam pojma kako to da popravm.Video sam da ima neke veze sa indeksima elemenata, ali ja ne vidim problem.

NISAM NESTO SMART
26.1.2012, 14:42
Pogledao sam malo kod iako nisam najbolje ukapirao sta pokusavas, ali koliko vidim ti pravis ovakav input "less nekistring" ili "add nekistring" i u tom slucaju se desava error.
Problem je sto ti kad koristis >> on ne izvuce celu recinicu vec samo prvu rec do whitespace-sa i ti kad pristupas x[1] to je nepostojece i prekoracavas granice vektora i otuda ta greska ptistupas necemu sto nema, uglavnom kad imas takvu gresku znaci da si prekoracio granice vektora.

Mozes da koristis getline() da bi uzeo celu linuju, uostalom vidi da li je to greska pa se snadji :D

Ivan-94
27.1.2012, 13:58
E sad jos jedan program...

kod:
#include <vector>
#include <string>
#include <iostream>
#include <stdio.h>
#include <sstream>

using namespace std;


int counter[10];

int main(){
for(int i = 2; i <= 9; i++)
counter[i] = 0;

int in;
cin >> in;

for (int i = 9; i > 1;){
if(in % i == 0){
counter[i] = counter[i] + 1;
in = (int)(in / i);
}
else
i--;
}

if(in != 1){
cout << "-1" << endl;
return -1;
}

stringstream tst;

for(int i = 2; i <= 9;){
if(counter[i] > 0){
tst << i;
counter[i] = counter[i] - 1;
} else
i++;
}

cout << tst;

fflush(stdin);

cin.get();
}

I uvek dobijam neki cudni output kao: 0x28fe78.

Belphegor
27.1.2012, 14:18
cout << tst.str();

//#include <string.h>
// fflush(stdin)
#include <limits>
#ifdef max // glupavi M$ makro
#undef max
#endif
...
cin.ignore( numeric_limits< streamsize >::max(), '\n');
cin.get();

Geomaster
28.1.2012, 12:43
Možda sam zakasnio, ali @Ivan-94, prvi post: taj pristup će ti probiti vremenski limit u tom zadatku. (O-recnik, kvalifikacije za okružno 2012, ako se ne varam.) Probaj da razmisliš koju strukturu podataka da iskoristiš kako bi malo efikasnije tražio i dodavao reči :)

Luigi
9.2.2012, 13:41
Da ne otvaram novu temu a imamm pitanje vezano za C++. Kako biste u matricu 9x9, nasumično smestili 81 broj na što brži način?
Evo mog pokušaja, iz nekog razloga ne štampa ništa:
#include<iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
int randomBroj()
{
srand ( time(NULL) );
int random = rand() %9;
return random;
}
int main()

{
int indexi[9][9],i=0,x,y;
for(int a=0;a<9;a++)
{
for(int b=0;b<9;b++)
{
indexi[a][b]=0;
}
}
while(i<81)
{
x=randomBroj(); //funkcija koja vraca
y=randomBroj(); //nasumicni broj u intervalu 0-8
if(indexi[x][y]==0)
{
indexi[x][y]=i+1;
i++;
}
}
for(int a=0;a<9;a++)
{
for(int b=0;b<9;b++)
{
cout<<indexi[a][b];
}
}
getchar();
getchar();
}

EDIT: Problem je što treba previše vremena da "ubode" slobodne elemente.

Belphegor
9.2.2012, 15:31
Nije mi bas jasno tvoje pitanje?
Mslim da ti treba ovaj algo random_shuffle (http://www.cplusplus.com/reference/algorithm/random_shuffle/) ?

edit: Izbaci iz funkcije srand, jer je dovoljno samo jedanput pozvati, stavi je u "main".

Luigi
9.2.2012, 23:29
Da dobar je algoritam. Mada ovo sa pomeranjem srand dela rešava stvar. Gledao sam u dokumentaciju ali mi je taj deo promakao... :facepalm

Ivan-94
10.2.2012, 12:55
Deklarisi promenjive izvan main funkcije (automatski ce vrednosti da im se postave na 0), da ne bi morao da ih ti popunjavas sa nulama.

Belphegor
10.2.2012, 13:07
Nemoj da ga navlacis na globalne promenljive, od toga se tesko odvikava/skida. :dedica: :D
Ako ga mrzi da pise petlju, moze i ovako:

int main()
{
int indexi[9][9] = {0};
...ili
int indexi[9][9];
memset(indexi, 0, sizeof(int) * 9 * 9);
}

Geomaster
10.2.2012, 14:23
Ako ga mrzi da pise petlju, moze i ovako:
Ja kao svaka dobra cepidlaka za mikrooptimizacije moram da kažem da je sa memset obično i brže od pisanja petlje :D

ivan90BG
10.2.2012, 21:33
Imam pitanje života ili smrti. :D

Kako u C++-u može da se radi compound assignment nad promenljivom koje deklarisana kao enum tipa, a da mi kompajler ne baci drvlje i kamenje. Jel ima neki switch kompajlera koji će da mu naredi da samo proguta to jer je enum samo int. Ako nema, kako se ovo radi najlakše?

Ide ovako:


enum TehFlagz { Flag1 = 1, Flag2 = 2, Flag3 = 4, Flag4 = 8 };

class TehClass {
TehFlagz flagz;
public:
void setFlagz(TehFlagz someFlagz) {flagz |= someFlagz;}
void unsetFlagz(TehFlagz someFlagz) {(flagz |= someFlagz) ^= domeFlagz}
};

// i onda

int main(void) {

TehClass obj;
obj.setFlagz(Flag1 | Flag2);
obj.unsetFlagz(Flag3 | Flag4);
}



Takođe me interesuje da li ono što sam napisao u drugom metodu radi ono što ja očekujem (da li se izraz u zagradi evaluira u flagz LValue ili RValue), pod uslovom da ga kompajler proguta (u vezi sa prvim problemom).

Belphegor
10.2.2012, 22:06
Ne mozes te operatore na enumaraciju!
Koliko vidim po tvom kodu hoces da drzis flagove u enumaraciji, onda moras drugacije i koristiti:

enum TehFlagz { Flag1 = 1, Flag2 = 2, Flag3 = 4, Flag4 = 8 };
class TehClass {
int flagz;
public:
void setFlagz(TehFlagz someFlagz) {flagz |= someFlagz;}
void unsetFlagz(TehFlagz someFlagz) { flagz &= ~someFlagz; }
};
// i onda
int main(void)
{
TehClass obj;
obj.setFlagz(Flag1 | Flag2);
obj.unsetFlagz(Flag3 | Flag4);
}
EDIT: iskopirao sam kod od teba pa se pokarabasio format
Mozes samo da postavis na neki element koji ima:

TehFlagz f;
...
f = Flag2;//recimo
Ovo sam sad napamet pisao, mozda sam pogresio negde.

2.

...da li se izraz u zagradi evaluira u flagz LValue ili RValue...
Sve sto ima "ime", odnosno mozes da mu uzmes adresu je LValue. Mada ne vidim kakve veze ima sa ovim kodom?

Ovaj izraz je RValue:

Flag3 | Flag4

Ovo je LValue:

void foo(int i)
{
// mozes uzeti adresu od i
}

ivan90BG
10.2.2012, 23:54
Da, da , vidim šta je po sredi. Mora jednostavno promenljiva da se deklariše kao int, da bi članovi enum-a mogli da se koriste kao flag-ovi.

Srećom u međuvremenu sam otkrio da Qt biblioteka ima rešenje za ovo. QFlags tempalete klasu koja wrapuje bilo koji enum i omogućava sve ovo.


enum AFlag { Flag1 = 1, Flag2 = 2, Flag3 = 4, Flag4 = 8 };

typedef QFlags<AFlag> SomeFlags;
ili
Q_DECLARE_FLAGS(SomeFlags, AFlag)

i onda može

SomeFlags f = Flag1 | Flag2;
f |= Flag3;
(f |= Flag2) ^= Flag2

M.Silenus
11.2.2012, 10:24
Standardna biblioteka ima bitset (http://www.cplusplus.com/reference/stl/bitset/), koja bi mogla da ti koristi.

Primer:


#include <iostream>
#include <bitset>

enum { Flag1 = 0, Flag2, Flag3, Flag4 };

typedef std::bitset<4> Flags;


std::string printbool( bool value )
{
return (value ? "true" : "false");
}

std::ostream& operator << ( std::ostream& str, Flags const& value )
{
str << "Flags {" << std::endl;
str << "\tFlag1 = " << printbool(value[Flag1]) << std::endl;
str << "\tFlag2 = " << printbool(value[Flag2]) << std::endl;
str << "\tFlag3 = " << printbool(value[Flag3]) << std::endl;
str << "\tFlag4 = " << printbool(value[Flag4]) << std::endl;
str << "}" << std::endl;

return str;
}

int main()
{
Flags flags;

flags.set(Flag1, true);
flags.set(Flag2, false);
flags.set(Flag3, true);
flags.set(Flag4, false);

std::cout << flags << std::endl;

flags = Flags(std::string("1011"));

std::cout << flags << std::endl;

flags = Flags(0x3); // 0011

std::cout << flags << std::endl;

return 0;
}


Izlaz progama je:

Flags {
Flag1 = true
Flag2 = false
Flag3 = true
Flag4 = false
}

Flags {
Flag1 = true
Flag2 = true
Flag3 = false
Flag4 = true
}

Flags {
Flag1 = true
Flag2 = true
Flag3 = false
Flag4 = false
}


Uzmi u obzir da broj dozvoljenih flegova moraš da znaš u vreme kompajliranja. Ako ti treba promenljivi broj flegova, razmotri boost::dynamic_bit_set

Geomaster
11.2.2012, 12:44
Ukoliko ne želiš da uključuješ boost u celu priču, std::vector<bool> je specijalizovan tako da se ponaša kao dinamički bitset.

Ivan-94
12.2.2012, 4:12
Ucim c++ i pokusavam da napisem funkciju za split-ovanje stringa, to sam uradio ovako:

char* split(char *str, char *delimM)
{
char * temp;
char* part = strtok(str, delimM);

while(part != nullptr)
{
*temp++ = *part;
part = strtok(nullptr, delimM);
}

return temp;
}

char *g = split("Haha:GG:HH:HH:PP", ":");
cout << g[0] << endl;

Ali stalno mi izbacuje error.

EclipsE
12.2.2012, 4:21
Moraš da alociraš memoriju prvo pre nego što je koristiš.

M.Silenus
12.2.2012, 10:00
Jedan mali savet. Pošto radiš u C++-u izbegavaj raw pointere ako ikako možeš. Ovo naravno neće uvek biti moguće. Takođe, ako si učio C pre C++-a, probaj, ako ikako možeš, da se odvikneš od C stila. Pogledaj, recimo, Bjarne Stroustrup's C++ Style and Technique FAQ (http://www2.research.att.com/~bs/bs_faq2.html) za ideju šta bi to bio C++ stil.

U tvom slučaju, nemoj stringove da predstavljaš char* tipom, umesto toga koristi std::string.

Takođe, strtok modifikuje ulazni string, što može da ti napravi silne probleme ako ne paziš.

Elem, evo ga string splitter, C++ style.

#include <string>
#include <vector>

std::vector<std::string> split(std::string const& str, std::string const& delim)
{
std::vector<std::string> result;

unsigned last_pos = 0;
unsigned pos = 0;

while( ( pos = str.find(delim, pos) ) != str.npos ){
string current = str.substr(last_pos, pos-last_pos);
if(current.length() != 0)
result.push_back(current);
pos += delim.length();
last_pos = pos;
}

if(last_pos != str.length()){
string current = str.substr(last_pos, str.length()-last_pos);
result.push_back(current);
}

return result;
}


A evo ga i generički :dzavo: :

#include <string>
#include <vector>

template<typename CharType>
std::vector<std::basic_string<CharType> >
split(std::basic_string<CharType> const& str, std::basic_string<CharType> const& delim)
{
std::vector<std::basic_string<CharType> > result;

unsigned last_pos = 0;
unsigned pos = 0;

while( ( pos = str.find(delim, pos) ) != str.npos ){
string current = str.substr(last_pos, pos-last_pos);
if(current.length() != 0)
result.push_back(current);
pos += delim.length();
last_pos = pos;
}

if(last_pos != str.length()){
string current = str.substr(last_pos, str.length()-last_pos);
result.push_back(current);
}

return result;
}


Oba koristiš isto kao i svoj (C-ovski) split

Belphegor
12.2.2012, 12:12
Samo da dodam. Mislim da u tvom primeru mogu da se izbegnu extra kopije sa:

template<typename CharType>
std::vector<std::basic_string<CharType> >
split(std::basic_string<CharType> const& str, std::basic_string<CharType> const& delim)
{
std::vector<std::basic_string<CharType> > result;

std::size_t last_pos = 0;
std::size_t pos = 0;

while( ( pos = str.find(delim, pos) ) != str.npos ){
std::basic_string<CharType> current = str.substr(last_pos, pos-last_pos);
if(current.length() != 0)
result.push_back(std::move(current));
pos += delim.length();
last_pos = pos;
}

if(last_pos != str.length()){
std::basic_string<CharType> current = str.substr(last_pos, str.length()-last_pos);
result.push_back(std::move(current));
}

return result;
}
mislim da je ovde u redu da se "rip the guts out" od string-a (sto bi rekao Scott Meyers) posto se current ne koristi nigde posle push_back-a u tom scope-u?
Mada ovo zavisi od kompajlera ako podrzava "move semanitics".

Geomaster
12.2.2012, 13:32
"If you really hate someone, teach them to use std::move." :D

voodoo_
12.2.2012, 15:17
I ovaj jezik je dobar za šta tačno? :D

Belphegor
12.2.2012, 15:28
Molio bih dezurne moderatore za ovaj podforum da uklone post ovog trola flamewar-monger-a i da postave ovu temu kao sticky kao sto je i budjavi "How to...VB". :kreza: :a_bleh:

voodoo_
12.2.2012, 16:57
Učite deco C, C je uvek koristan, a ovaj coding horror zaobiđite :kreza:

Geomaster
12.2.2012, 18:27
I ovaj jezik je dobar za šta tačno? :D
Za dobar deo browsera koji si koristio da bi otkucao poruku? ;)

EclipsE
12.2.2012, 18:59
Učite deco C, C je uvek koristan, a ovaj coding horror zaobiđite :kreza:

Hope that was sarcasm...

voodoo_
12.2.2012, 19:14
Pa onako, u nekoj meri. C++ mi je bio OK dok nisam masterovao Javu i C# kada sam shvatio da je C++ školski primer kako jedan objektno-orijentisani jezik ne treba da izgleda. Ok, nastao je kao nabudženi C, star je skoro 30 godina itd itd, ali da imam jezik koji podržava sve mehanizme drugog jezika, a onda da mi autor savetuje da te mehanizme ne treba da koristim, to mi je potpuno van pameti. I još gomila drugih stvari, recimo kombinovanje klasičnih pokazivača i referenci, gde je pritom operator za pravljenje referenci predstavljen identičnim znakom kao adresni operator jezika na koji se naslanja, pa to je prosto grozno.

Lepo je što ste se zapalili za C++, al ja vam tvrdim da u praksi (tj u poslovima koje danas možete raditi) najčešće nećete imati potrebe da istovremeno pišete performance-critical aplikacije a da ćete pritom moći da koristite zilion pomoćnih klasa i struktura koje C++ biblioteka nudi, već će najčešće biti ili-ili. Lično se bavim ovim prvim slučajem (za pare, jelte) i tu koristim čist C.

Belphegor
12.2.2012, 20:03
U pravu si. Ne znam kako sam mogao biti tako slep. Sve je u parama. :tapsh:
Jos samo da pocnem da slusam narodnjake posto je ovo dosad bio idiotizam.

Geomaster
12.2.2012, 20:12
a da ćete pritom moći da koristite zilion pomoćnih klasa
Odgovorno tvrdim da neko ko koristi C++ samo zbog pomoćnih klasa nije reprezantativan primerak codera :)

voodoo_
12.2.2012, 20:13
Ne kažem da je sve u parama nego da je to nepotrebno mučenje.

Geomaster
12.2.2012, 20:22
Ti možeš u C++-u koristiti sve funkcije C-ove standardne biblioteke a isto tako koristiti objektno-orijentisane alternative iz C++-ove standardne biblioteke. Po mom mišljenju, C++ je pravi kompromis između "sirovosti" jezika kao što je C i nenametljive objektne orijentisanosti koju danas dosta iskvareno pružaju Java/C#. Jednostavno, možeš da koristiš šta god želiš, a objektna orijentisanost je nezamenljiva u većim projektima gde neće proći da program izgleda kao clusterfuck struktura i globalnih funkcija :)

Todors
12.2.2012, 20:33
Samo jedna ispravka.

Ne znam što neki ljudi stalno poistovećuju javu i C#.

Bitna razlika je što C# lagodno može da koristi biblioteke i iz drugih jezika (tipa: c/c++,java), a java to može samo da sanja.

Tako da se ti momče samo muči sa c++, a ja ću taj tvoj sklop opušteno da iskoristim kod sebe, kad mi zatreba.

voodoo_
12.2.2012, 20:37
Ja u poslu koristim kombinaciju Jave i C-a, objektni kostur i metode pišem u Javi, performance critical delove pišem u C-u, pošto Java podržava takozvani Java Native Interface (http://en.wikipedia.org/wiki/Java_Native_Interface). I ne žalim se, a nije ni da imam česte performance critical delove već za C-om uglavnom potežem kad moram da pristupam direktno hardveru (programi mi zavise od hardverske arhitekture).

C++ je krpež koji bi nestao čim bi neko napisao optimizovani Java ili C# kompajler koji bi izbacivao nativne izvršne fajlove umesto bajtkoda.

Bitna razlika je što C# lagodno može da koristi biblioteke i iz drugih jezika (tipa: c/c++,java), a java to može samo da sanja.
Mala ispravka - može. Moguće je određene module pisati u C ili C++ i biće prevedeni u .DLL ili .so biblioteke, a prototipe njihovih metoda odnosno funkcija samo deklarišeš sa "native" keywordom u Java klasama i možeš da ih pozivaš. Doduše nije ni izbliza elegantno kao ono što nudi C#, ali radi i naročito je korisno ako pišeš npr aplikacije za Android a treba ti direktan pristup hardveru preko Linux drajvera.

voodoo_
12.2.2012, 21:44
Ne žesti se, uvek možeš da pređeš na Objective-C!

Geomaster
12.2.2012, 21:56
Nije mi jasno zašto onda niko još nije napisao takav "optimizovani Java/C# kompajler koji izbacuje nativne izvršne fajlove". Javu i C# nisam poistovećivao već sam ih naveo u "paketu", jer je C# po mom mišljenju samo unakažena verzija Jave za koju imam ogromno poštovanje. A što se tiče C++-a, mislim da ga niko ne bi koristio kada bi bio takav horor i toliko loš. Na kraju krajeva, on je i dalje treći (neki izvori kažu i drugi) najkorišćeniji jezik a sigurno to ne bi bio da nije dobar, ako ne i idealan izbor za gomilu upotreba i scenarija. Koristio sam i Javu i C# u trenucima kada bi mi njihove prednosti bile potrebne i jednostavno kada bi bili dobar izbor sa priliku i smatram da nečija gotovo religiozna posvećenost programskom jeziku može ići samo na njegovu štetu. C++ je moj prvi izbor jednostavno zato što u oblastima kojima se bavim (mahom game development i algoritamski problemi ali u poslednje vreme sve više low level programiranje i networking) i jednostavno ne vidim sebe kako radim bilo šta od toga u nekom drugom/sličnom jeziku (dobro, za low level programiranje bi mi C poslužio bolje, ali i tu imam neki hibridni objektno-orijentisani pristup). A u flame warovima ne smem više da učestvujem :$

@voodoo_: Objective-C mu dođe kao bastard child C++-a i Smalltalka, a sve to začinjeno brainfuckom :D

Ivan-94
13.2.2012, 0:13
@M.Silenus
Hteo sam da izbegnem vector-e iz nekog razloga mi se ne svidjaju :)
Ali definitivno ima uticaja C-a

ivan90BG
13.2.2012, 0:21
C++ je stradao od umnih poremećaja Bjarna Stroustrupa, koje sa se manifestovale u C++ standardnoj biblioteci u čiji dizajn je on uključio pomoć svog "prijatelja", nikog drugog do gremlina (onog što vadi štrafove avionima, koji je izabrao strategiju da pomuti konce čovečanstvu tako što će naterati autora sledećeg najpopularnijeg programskog jezika da ga skroz na skroz upropasti, dodavanjam jeziku mogućnosti diskutabilne korisnosti, ali sa dobrim potencijalom za zakukuljivanje, i onda terati te mogućnosti do kraja u celoj standardnoj biblioteci).

1. Standardna biblioteka je skoro cela templejt, ugnježden tri puta, a uz to nema ni O od organizacije.
2. Bjorbnorgnorn Storoupstrenosorentsopsen je verovatno bio na avganistansoj travi kad je odlučio da mu se neizmerno sviđaju mala slova i donje crte (verovatno su na istoj travi bili i Majkrosoftovci kad su pravili Win32 biblioteku) i da je svakome dovoljan jedan namespace import od jednom.

Ali on i dalje nastavlja da sisa vesla i podaruje nam C++11 koji donosi neke nebuloze od dodataka koje samo komplikuju stvari još.

A onda nam je gremlin tako krknuo u plećku jer je ljudima koji su se namerili da isprave greške C++-a ubacio u glavu fobiju od native izvršnih fajlova i manuelnog upravljanja memorijom. Srećom uspeo je neko i pored gremlinovih napora da uradi ono pravo. To su bili Brad Cox i Tom Love (koja imena :D) koji su napravili Objective-C. Ali gremlin se za to pobrinuo tako što se postarao da Objective-C ne izađe iz domena "fenserskog" Apple sveta.

Osim Objective-C-a postoji jiš jedan kompjalirani OO jezik, a to je D, odlična stvar, ko C# ili Java, samo što može da se radi i kao u C-u, nema višestruko nasleđivanje, ima interfejse, ima garbage collection, samo što je naš gremlin posetio i Walter-a Bright-a, tako da je sad D vrlo zavistan od GC-a (iako se kaže da on može da se isključi), stringovi u D-u su ništa drugo nego D nizovi karaktera, a templejti nisu samo po std-u nego su i deo operator overloading mehanizma. Vidi se da je čovek malo zastranio.


I eto, gremlin nas je pobedio, uspeo je da sabotira sve pokušaje ispravljanja C++-a.

Tako da evo sad pozivam ljude dobre volje da se suprotstavimo napasti i konačno napravimo OO jezik koji će se nativno kompajlirati, imati mogućnosti C-a, a standardnu biblioteku kao C# ili Java.

A dok se to ne završi preporučujem vam da STL i boost bacite u Dunav i koristite Qt biblioteku. Takođe pustite niz WC šolju donje crte i mala slova, CamelCase je zakon.

Nije problem u jeziku koliko u lošem koiršćenju jezika. With great power comes great responsibility. :D

voodoo_
13.2.2012, 0:39
Možemo da napravimo nešto kao što su bili rani C++ "kompajleri" koji su rearanžirali izvorni kod u C, a onda ga prosleđivali C kompajleru - napravimo "prevodilac" Java izvornog koda u C++ i onda ga propustimo kroz C++ kompajler! E sad još samo neko da prepiše Java klase u C++ i dobri smo :D

Geomaster
13.2.2012, 0:49
zašto_je_ovo_na_bilo_koji_način ManjeČitljivoOdOvog pošto_ja_ne_vidim_nikakvu PrednostJednogNadDrugim?

voodoo_
13.2.2012, 0:55
Bogami, kad skroluješ kroz sors u jeziku koji koristi isključivo mala slova za ključne reči, CamelCase imena se i te kako bolje primećuju od imena koja su takođe mala slova.

NISAM NESTO SMART
13.2.2012, 1:27
Hmm da..... :eek:
Pošto su očito veliki eksperti na ovom forumu dali dijagnozu da je kreator C++ mentalno nestabilan(ili je možda čovek glup pa nije znao bolje) i zato je i upropastio jezik, koji očigledno samo idioti koriste koji ne znaju za bolje.

Pošto ima dosta takvih idiota na forumu nek bude ova tema sticky(a nek moderator izbrise ove nebitne postove)...

ivan90BG
13.2.2012, 11:58
Ne, ne, nisam rekao da je Bjarn poremećen sam po sebi, nego da neka sila (koju sam nazvao gremlin) konstantno sabotira sve pokušaje pravljenja dobrog skupa jezik-bilblioteka-runtime. ODkud ja znam šta je po sredi, možda bad luck. Ja mislim da je C# odličan jezik, .NET biblioteka je super, coding standardi koje nameće dobri, ali virtuelna mašina...; isto i sa Javom.

Znači pun pogodak bi bio jezik kao C# sa mogućnostima C-a, nativno kompajliran, sa velikom bibliotekom kao što su .NET i Java standardna, i da mu ne trebaju header fajlovi, odnosno da se sveinformacije sadrže u binarnim fajlovima, kao što je to kod .NET assembly-a ili Java fajlova.

Belphegor
13.2.2012, 12:16
....NET biblioteka je super, coding...
...sa velikom bibliotekom kao što su .NET i Java standardna
Vidi se da se dosta oslanjas na te biblioteke koje su ti servirane na tacni i ne bi mogao bez njih da se snadjes. Sa C++-som mozes sam da pravis te pomocne biblioteke, organizujes stvari kako tebi odgovaraju, a ako naidjes na neku "prepreku" kao sto je ono sa enum konstantama uvek mozes sam da napravis da se ponasa tako kako ti zelis a ne da kmecis kako to fali jeziku a u stvari i ne treba da bude deo jezika. A to sto spominjete C nije vam od neke pomoci, jer se vidi i da se tu ne snalazite.
Ajd' onda neka neko od vas napravi split string funkciju u C-u i pomogne Ivanu umesto da bez veze trolujete ovu temu.
Ako vam se ne svidja C++ ne morate da ga koristite!


...i da mu ne trebaju header fajlovi...
Sa ovim su obicno pocetnici isfrustrirani kad naprave vise od jednog izvornog fajla i ne mogu da povezu 2 klase koje zavise jedna od druge pa za to krive jezik.

Circular dependency. (http://en.wikipedia.org/wiki/Circular_dependency)


Takođe pustite niz WC šolju donje crte i mala slova...
Joj, koliko je ovo pateticno. :rofl:
Ako ne umes da ga procitas "nadeni" mu drugo ime:

typedef glupavo_ime superCoolIme;

voodoo_
13.2.2012, 13:29
A to sto spominjete C nije vam od neke pomoci, jer se vidi i da se tu ne snalazite.
Koji mi? Ja C razbijam, fala na pitanju.

Belphegor
13.2.2012, 13:52
Ja C razbijam, fala na pitanju.

Your kung-fu is the best. :n_klanja: :tapsh:

Geomaster
13.2.2012, 14:04
Ja C razbijam, fala na pitanju.
http://alltheragefaces.com/img/faces/png/misc-got-a-badass-over-here.png

Kosinus
13.2.2012, 20:38
@Ivan-94:
char** explode( const char delim, char* src )
{
char * start = src;
char * ptr = src;
char ** tab;
int i = 0, pos = 0, len = 0;
int items = 0;

while( *src )
{
if( *src == delim )
items++;
src++;
}

if( !items )
return NULL;

items++;

src = start;
tab = new char * [items];

while( *ptr && i < items )
{
if( *src == delim || *src == 0 )
{
len = 0;
ptr = start;

while( ptr < src )
{
len++;
ptr++;
}

tab[ i ] = new char [len + 1];
pos = 0;

while( start < ptr )
{
tab[ i ][pos] = *start;
start++;
pos++;
}

tab[ i ][pos] = 0;
start = ptr + 1;
i++;
}

src++;
}

tab[ i ]= NULL;

return tab;
}Funkcija nije moje delo - nasao sam je negde na internetu pre koju godinu.

Koristis ovako:
char ** Bla = explode( ':', "1.1.1.1:28960" );

Bla[ 0 ] // Pokazivac na prvi niz karaktera
Bla[ 1 ] // Pokazivac na drugi niz
// Itd...Mala funkcija koju sam napravio da ti pomogne da izbrojis na koliko delova je tekst podeljen:
int count( char ** tabsrc )
{
int i = 0;
while( tabsrc[ i ] != NULL )
i++;

return i;
}Ne zaboravi da posle koriscenja oslobodis memoriju:
int c = count( Bla );

for( int i = 0; i < c; i++ )
delete [ ] Bla[ i ];

delete [ ] Bla;

Belphegor
13.2.2012, 21:44
More C++ :a_bleh:


#include <iostream>
#include <string>
#include <regex>
#include <iterator>
#include <limits>

int main()
{
std::string str = ".HEHE:.HOHO.HIHI,HAHA,.:";
std::string delim = ":.,";
std::regex pattern("[^" + delim + "]+");
std::vector<std::string> result;

const std::sregex_token_iterator end;
std::sregex_token_iterator i(str.begin(), str.end(), pattern);
for(; i != end; ++i)
{
result.push_back(*i);
}

std::ostream_iterator<std::string> out(std::cout, "\n");
std::copy(result.begin(), result.end(), out);

std::cout << "Press enter to exit..." << std::endl;
std::cin.ignore( std::numeric_limits< std::streamsize >::max(), '\n' );
return 0;
}


out:

HEHE
HOHO
HIHI
HAHA

EclipsE
13.2.2012, 22:14
Mislis regex :p

Luigi
14.2.2012, 16:37
Dali bi mi neko znao reći is kog razloga kada random funkciju inicijaizujem na sledeći način uvek dobijam istu listu nasumičnih brojeva? :confused:
srand (NULL);
ako probam proslediti time funkciju kao parametar program ko da je u beskonačnoj petlji:
srand ( time(NULL) );

EclipsE
14.2.2012, 17:03
Zato što "random" nije stvarno random... Zavisno od implementacije random funkcija može da varira, ali se uglavnom implementira kao:
(note: brojevi su ovde samo proizvoljni)

unsigned seed = 0;

unsigned rand()
{
seed = seed * 123456789 + 12345;
return (seed / 12345) % 54321;
}

A srand:

void srand(unsigned s)
{
seed = s;
}

Kao što možeš da vidiš iz rand funkcije, svaki sledeći broj zavisi od prethodnog seed-a. Ako ne pozoveš srand sa nekom unikatnom vrednošću, dobićeš uvek istu sekvencu brojeva. Ako pozoveš srand(0), opet ćeš dobiti istu sekvencu random brojeva, jer se uvek računaju iste vrednosti.

Razlog zašto time(0) daje uvek drugačije vrednosti je zato što se time menja svake sekunde, tako da u svakoj sekundi imaš drugačiju sekvencu random brojeva.

Razlog zašto se tebi program vrti beskonačno je jer uvek pozivaš srand( time(0) )! Obzirom da je izvršenje programa veoma brzo (milijarde operacija po sekundi), tebi se seed uvek postavlja na istu vrednost, pa rand() računa istu vrednost u toku jedne sekunde.

TLDR: pozovi samo jednom srand( time(0) ) na početku programa i uživaj.

Luigi
14.2.2012, 18:30
Tako i radim, pozovem samo jednom... Zanimljivo je da kad uradim ovaj test kod:
#include<iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
int indexi [9][9];
//------------------------------------------------------------
//funkcija koja vraca random broj u intervalu 0 - 8
//------------------------------------------------------------
int randomBroj()
{
int random = rand() %9;
return random;
}
//------------------------------------------------------------
void popunaKombinacija()
{
int k=0,x,y;
for(int a=0;a<9;a++)
{
for(int b=0;b<9;b++)
{
indexi[a][b]=0;
}
}
while(k<81)
{
x=randomBroj(); //funkcija koja vraca
y=randomBroj(); //nasumicni broj u intervalu 0-8
if(indexi[x][y]==0)
{
indexi[x][y]=k+1;
k++;
}
}
}
//---------------------------------------------------------------
int main()
{
srand( time(0) );
popunaKombinacija();
for(int i=0;i<9;i++)
{
cout<<" "<<endl;
if(i%3==0)
cout<<" "<<endl;
for(int j=0;j<9;j++)
{
if(j%3==0)
cout<<" ";
if(indexi[i][j]==0)
cout<<". ";
else if(indexi[i][j]<10)
{
cout<<0;
cout<<indexi[i][j];
cout<<" ";
}
else
{
cout<<indexi[i][j];
cout<<" ";
}
}
}
getchar();
getchar();
}
radi bez problema. Istu inicijalizaciju i obe funkcije koristim u većem programu gde se najpre dešava upravo ono što u test kodu, tamo ne radi skuca se i samo vrti. :confused:

EclipsE
14.2.2012, 18:40
Onda nije problem u random brojevima, već u tom drugom kodu...

Belphegor
14.2.2012, 19:07
Ne razumem zasto nasumicno biras indexe niza kad bi isto dobio i ovako:


#include <iostream>
#include <algorithm>
#include <ctime>
#include <iterator>

int main()
{
srand((unsigned int)time(0));
int indexi[9][9];
int i = 0;
std::for_each(&indexi[0][0], &indexi[0][0] + 81, [&i](int& inx) { inx = ++i; });
std::random_shuffle(&indexi[0][0], &indexi[0][0] + 81, [](const int& num){ return rand() % num; });

std::ostream_iterator<int> out(std::cout, "\n");
std::copy(&indexi[0][0], &indexi[0][0] + 81, out);

std::cin.get();
return 0;
}
Evo ti i "duze" verzije ako ti kompajler ne podrzava lambada funkcije:

#include <iostream>
#include <algorithm>
#include <ctime>
#include <iterator>

int moj_random(const int& num)
{
return rand() % num;
}

int main()
{
srand((unsigned int)time(0));
int indexi[9][9];
int k = 0;
for(int i = 0; i < 9; ++i)
{
for(int j = 0; j < 9; ++j)
{
indexi[i][j] = ++k;// 1-82
}
}

std::random_shuffle(&indexi[0][0], &indexi[0][0] + 81, moj_random);

for(int i = 0; i < 9; ++i)
{
for(int j = 0; j < 9; ++j)
{
std::cout << indexi[i][j] << std::endl;
}
}



std::cin.get();
return 0;
}

Andross
4.4.2012, 13:48
Da li std::list brise sve elemente iz liste ako obrisem instancu neke klase koja sadrzi listu, i.e. da li u destruktoru klase treba da pozivam mojaLista.clear() ili ne? (jbg navikao sam na garbage collector u c# :D)

M.Silenus
4.4.2012, 14:39
Ne, u destruktoru klase ne moraš da zoveš clear() metod. Destruktor liste uništava sve elemente liste.

Napomena, ako su elementi liste pokazivači, onda moraš ručno da obrišeš objekte na koje ti pokazivači, je li, pokazuju (videti primer):


std::list<int*> ints;

ints.push_back(new int);
ints.push_back(new int);
ints.push_back(new int);

// brisanje
for(auto iter = begin(ints); iter != end(ints); ++ iter)
delete *iter;

// a evo i fensi načina ;)
std::for_each(begin(ints), end(ints), [](int* pi) { delete pi; });



Napomena, ovo je C++11.

Ako hoćeš da automatizuješ ovo malo, možeš da koristiš pametne pokazivače:


std::list<std::shared_ptr<int>> ints;

ints.push_back(std::make_shared<int>());
ints.push_back(std::make_shared<int>());
ints.push_back(std::make_shared<int>());



Ne moraš ništa da brišeš, shared_ptr brine o tome.

Belphegor
4.4.2012, 14:45
Zavisi sta ti je u listi.
Ako drzi pokazivace na objekte kreirane na heap-u onda moras rucno da brises pre nego ubijes tu klasu

class Foo
{
private:
std::list<Bar*> lb;
...
};

Foo::~Foo()
{
const auto& end = lb.end();
auto it = lb.begin();
for(; it != end; ++it)
{
Bar* p = *it;
delete p;
p = nullptr;
}
}
ili jednostavno:

#include <memory>
typedef std::shared_ptr<Bar> sp_bar;
...
class Foo
{
private:
std::list<sp_bar> lb;
...
};

...
lb.push_back(sp_bar(new Bar(...));
i ne moras nista da mislis. :D

A evo ti i pomocna biblioteka za detektovanje curenja memorije.
http://www.windows7download.com/win7-visual-leak-detector/myvcnzgr.html

EDIT: Ninja M.Silenus :n-cc2: :D

Geomaster
4.4.2012, 15:01
Upravo tako, samo da pojasnim, kad se std::list uništi (izađe van scope-a ili pomoću delete) on briše svoje elemente. To znači da ako lista sadrži pokazivače, pokazivači će biti uništeni, ali ne i objekti na koje oni pokazuju. U suštini, pravilo važi - o dealokaciji memorije brine onaj ko ju je alocirao. Ako si ti pozvao new kako bi alocirao neku memoriju, moraš pozvati i delete da tu istu memoriju dealociraš. Ostalo sve nije tvoja briga.

Belphegor
4.4.2012, 16:11
Lets get crazy. :D

Ako ces da brises rucno evo genericke funkcije, bazirano na M.Silenus for_each funkciji:

template< typename T >
typename std::enable_if< std::is_pointer< typename T::value_type >::value, void >::type
delete_container(T& c)
{
std::for_each(std::begin(c), std::end(c), [] ( typename T::value_type v) { delete v; } );
}
...
std::list<int*> ints;
std::vector<Foo*> foos;
...
delete_container(ints);
delete_container(foos);

Andross
4.4.2012, 17:05
Da da, sad se secam. Sta cu proslo je 5 godina od kako sam zadnji put pipnuo C++, zaborave se neke stvari :)

Andross
4.4.2012, 19:21
Elem jos jedno pitanje.

Imam recimo ovo:

BYTE* data = ilGetData();
delete data;ilGetData vraca pokazivac na podatke ucitane slike. Ako obrisem ovaj moj trenutni pokazivac na ovaj nacin brisem samo taj pokazivac a ne i podatke (koji su vec referencirani negde)? Tipa imam klasu za teksturu i ona ima pokazivac na tu datu a slika se brise pomocu ilDeleteImage funkcije, da li u destruktoru kada uradim delete data brisem te podatke ili samo taj pokazivac? U prevodu da li samo "originalni" pokazivac (onaj napravljen sa new) unistava podatke? (ne racunajuci da uradim delete *data, kolko se secam to direkt unistava podatke).

P.S. Takodje ako imam neki takav pokazivac (npr. mCurrentGameState = mGameStates[0]), da li njega treba da brisem u destruktoru ili on to sam resava, s'obzirom da sam obrisao podatke gde treba.

Belphegor
4.4.2012, 19:55
Ne brisu se pokazivaci, oni samo "pokazuju" na odredjeno mesto u memoriji. :D
Sa delete brises/oslobadjas samo sto kreiras sa new!!!

U tvom slucaju treba da brines samo da ne koristis data pokazivac posle poziva na ilDeleteImage().

Posto vidim da si zaboravio:


int* p = new int[3];// rezervisan blok memorije za 3 int
p // ovaj izraz je vrednost koju drzi pokazivac a to je adresa bloka memorije koju si kreirao sa new
&p // i sam pokazivac oduzima memoriju, ovaj izraz je njegova adresa
delete [] p; // oslobadjamo onaj blok memorije
p = nullptr;// posto 'p' i dalje pokazuje na taj blok memorije postavljamo njegovu vrednost na 0 da se ne bi desila katastrofa ako se kojim slucajem zaboravi

Andross
4.4.2012, 20:52
Nisam lepo formulisao mozda.

Ako imam vise pokazivaca koji pokazuju na isto i obrisem jednog, podaci su obrisani i svi su invalidirani?

Creep* c1 = new Creep();
Creep* c2 = c1;
Creep* c3 = c2;
delete c3;
// c1 i c2 pokazuju na neko mesto u memoriji koje nije inicijalizovano?

Belphegor
4.4.2012, 20:56
Svi su "invalid" i bilo bi veoma opasno ako bi posle koristio jedan od njih.


http://www.dodaj.rs/f/3K/oj/3U4e3s0J/ptr.jpg

Kad pozoves delete onda oslobadjas onu kocku gde pise new Creep() a pokazivaci su i dalje zivi i pokazuju na isto mesto.


EDIT: Evo ti prost primer:

int* p1 = new int(666);
int* p2 = p1;
int* p3 = p1;

std::cout << "Adresa gde pokazuje p1 = " << p1 << std::endl;
std::cout << "Adresa gde pokazuje p2 = " << p2 << std::endl;
std::cout << "Adresa gde pokazuje p3 = " << p3 << std::endl;

std::cout << "Adresa pokazivaca p1 = " << &p1 << std::endl;
std::cout << "Adresa pokazivaca p2 = " << &p2 << std::endl;
std::cout << "Adresa pokazivaca p3 = " << &p3 << std::endl;

std::cout << "Vrednost sa adrese p1 = " << *p1 << std::endl;
std::cout << "Vrednost sa adrese p2 = " << *p2 << std::endl;
std::cout << "Vrednost sa adrese p3 = " << *p3 << std::endl;
...
delete p1;
p1 = nullptr;
p2 = nullptr;
p3 = nullptr;

ozzytheking
4.4.2012, 21:27
Je l' ima neka fora da prilikom citanja fajla otvorenog pomocu fopen() funkcije, skocim u sledeci red odnosno nakon procitanog <necega> predjem u novi red ignorisuci ostatak karaktera koji se nalazu u tom redu?

Belphegor
4.4.2012, 21:43
fgets (http://www.cplusplus.com/reference/clibrary/cstdio/fgets/) i fseek (http://www.cplusplus.com/reference/clibrary/cstdio/fseek/)

Andross
5.4.2012, 23:13
1. Da li mogu elemente u unordered_map da brisem isto kao elemente u listi?

std::unordered_map<std::string, Texture*> mTextures;
// ...
for(auto iter = begin(mTextures); iter != end(mTextures); iter++)
delete *iter;

2. Kako bih npr. iz istog unordered_map obrisao element "Data/tex1.png", posto imam pokazivac na teksturu?

M.Silenus
5.4.2012, 23:49
1. Brisanje bi izgledalo ovako:


std::unordered_map<std::string, Texture*> mTextures;

for(auto iter = begin(mTextures); iter != end(mTextures); iter++)
{
std::pair<std::string, Texture*>& current = *iter;
delete current.second;
}



Sa jednim typedefom ;)


typedef std::unordered_map<std::string, Texture*> MStrTexture;

MStrTexture mTextures;

for(auto iter = begin(mTextures); iter != end(mTextures); iter++)
{
MStrTexture::value_type& current = *iter;
delete current.second;
}



2.

typedef std::unordered_map<std::string, Texture*> MStrTexture;

MStrTexture mTextures;

Texture* toBeDeleted;

auto iter = begin(mTextures);
for(; iter != end(mTextures); iter++)
{
MStrTexture::value_type& current = *iter;
if(current.second == toBeDeleted)
break;
}

if(iter != end(mTextures))
mTextures.erase(iter);



Napomena: ovde se ne vrši brisanje toBeDeleted objekta! Samo se unos koji sadrži taj objekat briše. Takođe, može da se desi da dva ili više unosa u mapi imaju iste vrednosti (ie. različiti ključevi, ali iste vrednosti). U ovom slučaju samo prvi nađeni unos će biti obrisan.

Još jedna stvar. Ako imaš potrebu za operacijama ovog tipa, možda mape nisu dobro rešenje za problem koji pokušavaš da rešiš.

ivan90BG
6.4.2012, 0:04
Prošlo je skoro dva meseca od kako sam napisao onaj post (http://www.sk.rs/forum/showthread.php?p=1506184). Red je da se osvrnem i malo razmislim.

Pogledao sam svež snimak govora Bjarna Stroustrupa o C++11. I sada sam siguran da su svi nedostaci C++-a loša sreća.

Vreme u kome je Bjarn donisio važne odluke po jezik je bilo takvo da se nije moglo pretpostaviti kakve bi posledice to moglo da ostavi, jer je sve to bilo samo dodavanje novih stvari na C koji se već dokazao kao dobar. Računari su bili takvi da je previše pametovanja samo trošilo resurse procesora i memorije. Sa okolnostima kavi su bile i ciljevima postavljenim, bila je istorijska nužnost da ispadne ovako kako je ispalo. Šta da se radi. Brajn je uradio najbolje što je mogao u to vreme. Tek posle godina korišćenja su se videli neki nedostaci, koje su drugi ispravljali, ali Bjarn nije mogao da ih otkrije tada. Ispostavilo se da su ovo neke stvari koje moraju manje više da ostanu zakovane u jeziku i eto.

Kudos Brajnu, i nadam se da će mi oprostiti.

Ali ipak mislim da C++ nije baš kompletan. Za velike projekte pogodniji su C# ili Java, a za sistemsko prigramiranje C.

Belphegor
6.4.2012, 0:12
@Andross
Koristi shared_ptr i nema da te boli glava.

Andross
6.4.2012, 0:28
for(auto iter = begin(mTextures); iter != end(mTextures); iter++)
{
std::pair<std::string, Texture*>& current = *iter;
delete current.second;
}Kaze:
D:\Development\MedievalSlaughterGame\TextureManage r.cpp|12|error: invalid initialization of reference of type 'std::pair<std::basic_string<char>, Texture*>&' from expression of type 'std::pair<const std::basic_string<char>, Texture*>'|

Belphegor
6.4.2012, 1:11
Govori ti da ti fali const u:

for(auto iter = begin(mTextures); iter != end(mTextures); iter++)
{
std::pair<const std::string, Texture*>& current = *iter;
delete current.second;
}
ili jednostavno:

...
delete (*iter).second;
Takodje mislim da ti ovde ne odgovara map/unordered_map jer kad ubacujes elemente moras da kreiras Texture da bi napravio pair, pa tek posle ce da proverava da li vec ima u listi.


map.insert( pair( string, new Texture) );


Osim ako konstruktor ne ucitava texturu i mora da se pozove naknadno neka metoda?

Belphegor
6.4.2012, 1:40
Evo ti primer sa std::shared_ptr, i zamenio sam unordered_map za list (isto unikatne texture) posto ionako ovde nije brzina bitna a list je dobar kad se brisu elementi random.


#if defined(_MSC_VER)
#include <vld.h> // Visual Leak detector
#endif

#include <iostream>
#include <list>
#include <string>
#include <memory>
#include <algorithm>

class Texture;
typedef std::shared_ptr<Texture> sp_texture;
typedef std::list<sp_texture> l_texture;

class Texture
{
private:
std::string name;
int* data;
public:
Texture()
: name(""), data(new int(666))
{
}
~Texture()
{
delete data;
}
bool loadFromFile(const std::string& n)
{
name = n;
return true;
}
const std::string& getName() const { return name; }
};

class TextureManager
{
public:
static l_texture ltex;
sp_texture load(const std::string& name)
{
Texture* tex = nullptr;
try
{
const auto& end = ltex.end();
auto it = ltex.begin();
for(; it != end; ++it)
{
if((*it)->getName() == name)
{
return *it;
}
}
tex = new Texture;
if(!tex->loadFromFile(name))
{
std::string errStr = "Failed to load texture: " + name;
throw std::runtime_error( errStr );
}
ltex.push_back(sp_texture(tex));
}
catch( const std::runtime_error& e)
{
delete tex;
throw e;
}
return ltex.back();
}
};

l_texture TextureManager::ltex;

void print_textures()
{
std::cout << "=========================" << std::endl;
std::for_each(TextureManager::ltex.begin(), TextureManager::ltex.end(), [] (sp_texture t)
{
std::cout << t->getName() << std::endl;
});
}

void remove_texture(const std::string& name)
{
auto it = std::find_if(TextureManager::ltex.begin(), TextureManager::ltex.end(), [&name] (sp_texture t)->bool
{
return name == t->getName();
});
if(it != TextureManager::ltex.end())
{
TextureManager::ltex.erase(it);
}
}

int main()
{
try
{
TextureManager tm;
tm.load("AbC");
tm.load("ABBC");
tm.load("ACC");
tm.load("ABBB");
tm.load("ABBB"); // duplikat, ali ga nece ucitati

print_textures();

remove_texture("AbC");

print_textures();

remove_texture("ABBB");

print_textures();

{
sp_texture tex = tm.load("Foo");
remove_texture("Foo"); // tex pokazuje na Foo ali je sigurno
Texture& t = *tex.get();
std::cout << "t name = " << t.getName() << std::endl;
}
}
catch(const std::runtime_error& e)
{
std::cerr << e.what() << std::endl;
}

return 0;
}

EDIT: Sad sam probao i sa g++ izgleda da mora da se doda za njega:

#include <stdexcept>
zbog std::runtime_error

Andross
6.4.2012, 14:04
Resio sam to ovako (doduse ovo bi trebalo teoretski da radi, jos uvek nemam kod koji bi ovo testirao):

#ifndef TEXTUREMANAGER_HPP_INCLUDED
#define TEXTUREMANAGER_HPP_INCLUDED

#include <IL/il.h>
#include <string>
#include <unordered_map>
#include "Texture.hpp"

class TextureManager
{
public:
// Destructor
~TextureManager();

// Public methods
static bool Initialize();
static void Shutdown();

bool LoadTexture(std::string filename);
void UnloadTexture(std::string filename);
Texture* GetByFilename(std::string filename);

static TextureManager* GetInstance() { return mInstance; }

private:
// Member variables
std::unordered_map<std::string, Texture*> mTextures;

static TextureManager* mInstance;
};

#endif // TEXTUREMANAGER_HPP_INCLUDED#include "TextureManager.hpp"

// Initialization of static members
TextureManager* TextureManager::mInstance = nullptr;

// Destructor
TextureManager::~TextureManager()
{
// Delete all textures
for(auto iter = begin(mTextures); iter != end(mTextures); iter++)
delete (*iter).second;
}

// Method implementation
bool TextureManager::Initialize()
{
// Abort if instance is already created
if(mInstance != nullptr)
return false;

// Create the instance
mInstance = new TextureManager();

// Initialize DevIL
ilInit();

// Check the version of the library
if(ilGetInteger(IL_VERSION_NUM) < IL_VERSION)
return false;

return true;
}

void TextureManager::Shutdown()
{
// Delete the instance
delete mInstance;
mInstance = nullptr;
}

bool TextureManager::LoadTexture(std::string filename)
{
// Check if the filename is empty string
if(filename.empty())
return false;

// Texture is already loaded
if(mTextures.find(filename) != mTextures.end())
return true;

// Generate one image name
ILuint texId;
ilGenImages(1, &texId);

// Bind the image name
ilBindImage(texId);

// Try to load the image
if(!ilLoadImage(filename.c_str()))
return false;

// Get the width and height
int width = ilGetInteger(IL_IMAGE_WIDTH);
int height = ilGetInteger(IL_IMAGE_HEIGHT);

// Create our texture
Texture* texture = new Texture(width, height, filename);

// Copy pixel data into our texture
ilCopyPixels(0, 0, 0, width, height, 1, IL_RGB, IL_UNSIGNED_BYTE, texture->GetData());

// Unbind the image and delete its data
ilBindImage(0);
ilDeleteImage(texId);

// Store our texture
mTextures[filename] = texture;

return true;
}

void TextureManager::UnloadTexture(std::string filename)
{
// Try to find the texture
auto iter = mTextures.find(filename);

// Return if texture is not found
if(iter == mTextures.end())
return;

// Delete the texture and remove it
delete (*iter).second;
mTextures.erase(iter);
}

Texture* TextureManager::GetByFilename(std::string filename)
{
// Try to find the texture
auto iter = mTextures.find(filename);

// Return nullptr if texture is not found
if(iter == mTextures.end())
return nullptr;

return (*iter).second;
}

Nikola Stankovic
27.4.2012, 15:40
Da ne bih lutao po forumu, imam jedno pitanje:
Imam nekog pocetnog iskustva sa C++ programskim jezikom. Da li mogu naci dovoljno teorije na internetu, ili da kupim neku knjigu a sa neta da upotpunjujem???

voodoo_
27.4.2012, 15:53
Ja mislim da je bolje učiti po knjizi sistematično i redom, nego iz ko zna kakvih tutorijala bez plana.

Ivan-94
2.5.2012, 2:31
Imam pitanje, koristio sam:

void UpdateBullets(Bullet bullets[])

da li to znaci da kad koristim array kao parametar da u stvari 'dajem' adresu array-a

kad pozivam f-ju: UpdateBullets(bullets); ??

M.Silenus
2.5.2012, 8:11
Bullets bullets[] je ekvivalent Bullets * bullets, tako da je odgovor na tvoje pitanje: da, niz šalješ po adresi.

GrimReaper
3.6.2012, 6:15
Zašto mi nasleđivanje klase vraća LNK2019 grešku pri linkovanju? class ElementI : public Element i kaže "unresolved external symbol "public: __thiscall Element::Element(void)" (??0Element@@QAE@XZ) referenced in function "public: __thiscall ElementI::ElementI(void)" (??0ElementI@@QAE@XZ)"

M.Silenus
3.6.2012, 8:41
Verovatno nisi definisao podrazumevani konstruktor u klasi Element.
Podrazumevani konstruktor je konstruktor bez argumenata, u tvom slučaju Element::Element(void). Ako ne definišeš nijedan kostruktor, podrazumeva se da on postoji - aka, kompajler ga automatski definiše. On the other hand, ako definišeš neki ne-podrazumevani konstruktor, onda da bi imao i podrazumevani, moraš i njega da definišeš.

Na primer:


class Element
{
public:
Element(int i); // vise nema podrazumevanog konstruktora
};

class ElementI : public Element
{
double x;
public:
ElementI(double x_)
: x(x_) {}
};


Pošto ovde nije eksplicitno pozvan konstruktor za Element, kompajler ubacuje poziv Element::Element() ispred poziva konstruktora za polja klase ElementI.

Tj. kompajler generiše ovo:


class ElementI : public Element
{
double x;
public:
ElementI(double x_)
: Element(),
x(x_)
{}
};


Ali, Element::Element() ne postoji, pa dobijaš linkersku grešku. Čudi me da je ne dobijaš ranije.

Rešenje: definiši Element::Element(), ili eksplicitno pozovi neki od definisanih konstruktora za Element. Čak bih ti predložio da uvek sam pozivaš kostruktore bazne klase, tako si uvek znaš šta se poziva - pogotovo ako nisi baš načisto sa tim šta je podrazumevana akcija u tom slučaju.

BTW. ako ti kompajler podržava C++11, i ako ti je podrazumevana implementacija podrazumevanog konstruktora odgovarajuća (ona samo poziva podrazumevane konstruktore svojih polja), onda možeš da uradiš ovo:


class Element
{
public:
Element() = default;
Element(int i); // vise nema podrazumevanog konstruktora
};


Ovako ne moraš da definišeš taj konstruktor, dovoljna je deklaracija.

GrimReaper
3.6.2012, 14:55
Ali imam default konstruktor, to je problem. Izgleda mi kao da nasumično izbacuje ove greške, jer sad više nije to problem, nego neke druge 2 funkcije. :facepalm

M.Silenus
3.6.2012, 15:43
That's weird... da nemaš kojim slučajem 2 izvorna fajla sa istim imenom? U zavisnosti od razvojnog okruženja, to bi mogao da bude problem.

Pretpostavljam da koristiš Visual Studio (poruke mi nekako liče na njega), a on (makar u verziji 10) ima naviku da objektne fajlove trpa u jedan dir - ma možda prepiše neki...

GrimReaper
3.6.2012, 15:50
Jeste VC10 i shvatio sam u čemu je problem. Ako napravim sitne izmene u kodu, kompajler ih ne detektuje i samo pređe preko toga (kaže no significant changes detected, skipping :confused: ). Ovo prvi put u životu vidim, kako to da zaobiđem? Zeza me jedna mašina, ne mogu da verujem.

GrimReaper
3.6.2012, 16:41
Ok, našao sam - Project Properties/Configuration Properties/C, C++/Enable Minimal Rebuild postaviti na No, za slučaj da nekome bude trebalo.

GrimReaper
4.6.2012, 19:25
Ok, imam još jedan problem. Imam jednu apstraktnu klasu i 7 izvedenih klasa iz nje. Treba mi da imam niz od 7 elemenata od kojih je svaki tipa druge klase (od ovih izvedenih) i da nasumično odaberem jedan i postavim ga kao neku promenljivu koju ću dalje da koristim. E, sad, problem je što ne mogu da kreiram promenljivu koja je tipa apstraktne klase, niti mogu da napravim niz tipa apstraktne klase. Jel postoji neki drugi način da ovo uradim?

Belphegor
4.6.2012, 19:53
class B
{
public:
virtual ~B() {};
virtual void foo() = 0;
};

class D1 : public B
{
public:
void foo() { std::cout << "D1 foo" << std::endl; }
};

class D2 : public B
{
public:
void foo() { std::cout << "D2 foo" << std::endl; }
};

class D3 : public B
{
public:
void foo() { std::cout << "D3 foo" << std::endl; }
};
...
B* niz[3];
niz[0] = new D1;
niz[1] = new D2;
niz[2] = new D3;
...

niz[1]->foo();

...
delete niz[0];
delete niz[1];
delete niz[2];

GrimReaper
4.6.2012, 20:35
Znači, trebalo je samo da bude niz pokazivača. Glup sam. :facepalm Hvala.

AmigAdi
17.7.2012, 10:39
Imate li C++ kodove za SiLabs c8051f132, buzzer i 8-segmentne displeje?

virtuoz pavle
24.7.2012, 12:48
vidim da ne postoji tema za paskal, pa sam resio ovde da pitam. Zelim da sortiram niz integera,

{Sortiraj Niz}

Uses Crt;
var
a : array [1..100] of Integer;
i, j, n, tmp, i_tmp : integer;

Begin
ClrScr;
Write('ucitaj broj clanova niza: ');
Readln(n);
For i := 1 to n Do
Begin
Readln(a[i]);
End;
tmp := a[1];
For i := 1 to n Do
tmp := a[i];
For j := i + 1 to n Do
If a[j] > tmp then
begin
tmp := a[j];
i_tmp := j;
write(a[i]);
readln;
end;
write(a[i]);
readln;
End.

Ovo je bila moja zamisao, imam u glavi algoritam, ali sam se negde ocigledno zeznuo. moze pomoc?
hvala

PeTkO
24.7.2012, 14:47
Imas ovde: http://www.sk.rs/forum/showthread.php?t=81855 vise resenja kako sortirati niz, jes' da je u C++, ali mislm da ti nece biti problem da "prevedes" u pascal.

Futuristic
20.8.2012, 18:49
Zasto poslednje dve adrese imaju te vrednosti i koja je razlika u linijama koda u crvenom, posto daju razlicite rezultate?
int main()
{
int abc[10],*p;
for(int i=0; i<10; i++) abc[i]=i;

cout << "vredonsti elemenata niza: "<< endl;
for(int i=0; i<10; i++) cout << abc[i] << ' ';
cout << endl;

cout << "adresna mesta elemenata niza: "<< endl;;
p=abc;
for(int i=0; i<10; i++) cout << &p[i] << endl;
cout << endl << p;
cout << endl << &p;
cin.get();

return 0;
}

Evo i jedan output programa:
vredonsti elemenata niza:
0 1 2 3 4 5 6 7 8 9
adresna mesta elemenata niza:
0xbff691f8
0xbff691fc
0xbff69200
0xbff69204
0xbff69208
0xbff6920c
0xbff69210
0xbff69214
0xbff69218
0xbff6921c

0xbff691f8
0xbff69220

MG-RAY
20.8.2012, 18:58
Druga vrednost je adresa na kojoj je smešten sam pointer u memoriji.

Futuristic
22.8.2012, 12:05
Zelim da napravim dvodimenzinzionalni niz (array) cije ce dimenzije biti unete tokom runtime-a. Trazio sam po internetu i vidim spominje se neki vector, ali nisam uspeo da to podesim...

Geomaster
22.8.2012, 12:21
Napravi jednodimenzionalni niz i pristupaj mu dvodimenzionalno, kao recimo

#define mat2D(y,x,w) ((x)+(y)*(w))

size_t sirina, duzina;
std::cin >> sirina >> duzina;

int* niz = new niz[sirina * duzina];
niz[mat2D(0, 0, sirina)] = 111;
niz[mat2D(4, 2, sirina)] = 222;
...

Futuristic
22.8.2012, 12:36
Ima li neki drugi nacin? Ne znam sta znaci ta keyword "new" niti operacije sa njom

Geomaster
22.8.2012, 12:42
Ima li neki drugi nacin? Ne znam sta znaci ta keyword "new" niti operacije sa njom
new ti je način da alociraš memoriju u C++-u. Bez new-a svejedno ne možeš da postigneš da unosiš dimenzije tokom runtime-a. (Možeš da koristiš neku klasu, ali i ona će svejedno na nekom nivou koristiti new ili malloc(), mada opet, new uglavnom koristi malloc() :D.) Može i vektorima, mada to nisu nizovi u najklasičnijem smislu:

#include <vector>
using namespace std;

....

size_t sirina, duzina;
vector< vector< int > > niz;
cin >> sirina >> duzina;

niz.resize(sirina);
for (int i = 0; i < sirina; ++i)
niz[i].resize(duzina);

niz[4][2] = 222;
niz[0][0] = 111;
...

irreal
22.8.2012, 12:46
Ima li neki drugi nacin? Ne znam sta znaci ta keyword "new" niti operacije sa njom

kada nisi upoznat sa nekim osnovnim elementima jezika u kojem zelis da programiras, neces daleko dogurati trazenjem nacina da resis svoj problem izbegavajuci taj element, vec potrazi po netu tekstove/tutorijale/primere/knjige na tu temu i nauci nesto novo.

to ti je moj iskren savet, e sad ti kako oces :)

ivan90BG
22.8.2012, 18:15
@Geo
Minimalna implementacija 2D matrice u C++-u bez vector-a i veselih macro-a. :D



//Mat2D.h

#ifndef MAT2D_H
#define MAT2D_H

template<typename T>
class Mat2D
{
private:
int width;
int height;
T* data;

public:
Mat2D(int height, int width)
{
this.width = width;
this.height = height;
this.data = new T[width*height];
}
~Mat2D()
{
delete[] data;
}
T& operator()(int x, int y)
{
return data[x*width+y];
}
};

#endif

//main.cpp

int main(int argc, char const *argv[])
{
Mat2D<int> mat(5,10);

mat(0,0) = 42;
int var = mat(4,8);
}

MG-RAY
22.8.2012, 18:38
^ jedna mala napomena za primer:


~Mat2D()
{
delete[] data;
}

Geomaster
22.8.2012, 18:46
@ivan:
A može i indeksiranje kao kod običnih :)

T* operator[](const int y)
{
return data + y * width;
}

ivan90BG
22.8.2012, 21:01
@MG-RAY, popravljeno.

@Geo, jes može, ali onda korisnik ove klase mora da zna da mora da uradi još nešto osim golog poziva operatora da bi koristio objekat pravilno (mora još jednom da indeksira). Operator () je zaokružen interfejs. :D

Geomaster
22.8.2012, 21:24
@Geo, jes može, ali onda korisnik ove klase mora da zna da mora da uradi još nešto osim golog poziva operatora da bi koristio objekat pravilno (mora još jednom da indeksira). Operator () je zaokružen interfejs. :D
Ne shvatam, šta bi još trebao da zna? I običnoj matrici se pristupa s dva indeksa...

Belphegor
23.8.2012, 11:48
@Ivan90BG


...
Mat2D(int height, int width)
{
this.width = width;
this.height = height;
this.data = new T[width*height];
}
...
Tako mozda mozes sa C#-om a u C++-u this je pokazivac, sintaksa za dereferenciranje ide ovako:

(*this).width;
//ili
this->width



template < typename T >
class Array2D
{
std::size_t rows, columns;
T** data;
public:
Array2D(std::size_t r, std::size_t c)
: rows(r), columns(c)
{
data = new T*[rows];
for(std::size_t i = 0; i < rows; ++i)
data[i] = new T[columns];
}
~Array2D()
{
for(std::size_t i = 0; i < rows; ++i)
delete [] data[i];
delete [] data;
}
T& operator () (std::size_t r, std::size_t c) const
{
return data[r][c];
}
};

ivan90BG
23.8.2012, 13:58
Šta ću kad mi je mozak na sve strane (učenje, seminarski, projekat), i kad Qt Creator automatski menja tačku u sterlicu ako se otkuca posle pointera. (i onda ja onako lenjo C#-ovski samo lupam tačke :D)

Ivan-94
17.9.2012, 1:35
Pokusavam da uradim najednostavniju multithreaded aplikaciju:

#include <iostream>
#include <thread>
#include <chrono>

using namespace std;

void f()
{
while(1)
{
cout << "From SIDE thread." << endl;
this_thread::sleep_for(chrono::seconds(2));
}
}

int main(int argc, _TCHAR* argv[])
{
thread t1(f);
t1.join();

while(1)
{
cout << "From MAIN thread." << endl;
this_thread::sleep_for(chrono::seconds(2));
}
return 0;
}


Ali izgleda da se scope prebaci u tu f-ju i ne vrati se u main, i dalje izvrsavajuci tu f-ju, kao bi ja hteo.

Tj. hocu da output bude, malo iz jedne f-je malo iz main.

Sta radim pogresno?

EclipsE
17.9.2012, 2:32
t1.join();

Čekaš da se thread t1 završi, što se nikad neće desiti.

Ivan-94
17.9.2012, 11:14
Ok ali kako da ne cekam da se zavrsi, nego da odmah posle pokretanja nastavi?

Geomaster
17.9.2012, 11:21
Pa nemoj da pozivaš join() na tom objektu :)

Ivan-94
17.9.2012, 11:33
Joj, cek, mozda nisam lepo formulisao pitanje. :)
Kako da pokrenem dve f-je odjednom i da jedna malo dobije vreme procesora malo druga?

Geomaster
17.9.2012, 12:29
Joj, cek, mozda nisam lepo formulisao pitanje. :)
Kako da pokrenem dve f-je odjednom i da jedna malo dobije vreme procesora malo druga?
Pa rekoh ti. Napravi novi thread i nemoj da joinuješ s njim i on će raditi uporedo. To je definicija threadova.
#include <iostream>
#include <thread>
#include <chrono>

using namespace std;

void f()
{
while(1)
{
cout << "From SIDE thread." << endl;
this_thread::sleep_for(chrono::seconds(2));
}
}

int main(int argc, char* argv[])
{
thread t1(f);

{
cout << "From MAIN thread." << endl;
this_thread::sleep_for(chrono::seconds(1));
}
return 0;
}

Belphegor
17.9.2012, 19:52
@Ivan-94
Zanimljiv link. (http://www.devx.com/SpecialReports/Article/38883)

voodoo_
17.9.2012, 20:51
Ladno postoji std::thread, a ja seljak koristim pthread-ove još uvek

Ivan-94
17.9.2012, 23:48
Doslo uz C++11.

Sheldon Cooper
21.9.2012, 16:38
Kako da uzimam random number ( 0-100 ) odredjen broj puta ( verovatno for ciklus ) i da izvucem kojih se, recimo, 5 brojeva najvise puta izvlacilo i ispisem ih na ekranu? Ne treba mi cist kod, nego neka ideja kako bi to izgledalo.

RaKuN_s_NeOnKoM
21.9.2012, 17:38
Kako da uzimam random number ( 0-100 ) odredjen broj puta ( verovatno for ciklus ) i da izvucem kojih se, recimo, 5 brojeva najvise puta izvlacilo i ispisem ih na ekranu? Ne treba mi cist kod, nego neka ideja kako bi to izgledalo.

Evo ideja. Radis upravo to sto si napisao [random u petlji] a pratis tako sto napravis niz[101] (101 iz prakticnih razloga) i radis niz[random_izvuceni_broj]++
E sad trenutno nemam ideju kako da ispises bas 5 koji su se najvise pojavili ali imaces uvid koliko se puta koji broj pojavio pa smisli nesto.

Moglo bi i da imas niz struktura koje sadrze { broj, brojac } pa bi kasnije samo sortirao i ispisao 5 sa najvecim brojacem, ali ova prva ideja mi je zanimljivija samo je treba doraditi ako je moguce.

ivan90BG
21.9.2012, 18:49
void main()
{
int niz[101];
memset(niz, 0, 101*sizeof(int));
srand(time(NULL));
for (int i = 0; i < 40000; i++)
{
niz[rand() % 100]++;
}

TopLista lista(5);
for (int i = 0; i <= 100; i++)
{
lista.probajDaDodaš(i, niz[i]);
}

for (int i = 1; i <= 5; i++)
{
printf("%d: %d se pojavio %d puta\n", i, lista.ključPozicije(i), lista.vrednostPozicije(i));
}
}


Klasu TopLista ostavljam tebi da napišeš. Ako baš ne može viči. :) Hint: pri svakom ubacivanju će se lista možda menjati, a možda i neće.

Belphegor
22.9.2012, 17:02
@ivan90BG


void main()
...
void main is evil!

C++ resenje, valjda nisam prevideo nesto:



#include <iostream>
#include <iterator>
#include <limits>
#include <random>
#include <ctime>
#include <algorithm>
#include <functional>

class random
{
private:
static std::mt19937 mt;
random() {}
random(const random& o) {}

public:

template< typename TNum >
static typename std::enable_if< std::is_floating_point<TNum>::value, TNum >::type
get(TNum nmin = std::numeric_limits< TNum >::min(), TNum nmax = std::numeric_limits< TNum >::max())
{
std::uniform_real_distribution<TNum> treal(nmin, nmax);
return treal(mt);
}

template< typename TNum >
static typename std::enable_if< std::is_integral<TNum>::value, TNum >::type
get(TNum nmin = std::numeric_limits< TNum >::min(), TNum nmax = std::numeric_limits< TNum >::max())
{
std::uniform_int_distribution<TNum> tint(nmin, nmax);
return tint(mt);
}
};

std::mt19937 random::mt = std::mt19937(static_cast<unsigned int>(std::time(nullptr)));

// N - ukupno izvucenih brojeva
// F - prvih n brojeva koji se ponavljaju
template < std::size_t N, std::size_t F >
class TopLista
{
private:

typedef std::pair<std::size_t, std::size_t> tpnum;
std::vector<tpnum> numbers;

public:
TopLista()
{
static_assert(N > F, "ERROR!");

numbers.resize(N);

std::for_each(std::begin(numbers), std::end(numbers), [](tpnum& e){
e = std::make_pair(0u, random::get(0u, 100u));
});

for(auto& it : numbers)
{
it.first = std::count_if(std::begin(numbers), std::end(numbers), [&it](const tpnum& e){
return it.second == e.second;
});
}

std::sort(std::begin(numbers), std::end(numbers), [](const tpnum& l, const tpnum& r){
return l.second > r.second;
});

auto end = std::unique(std::begin(numbers), std::end(numbers), [](const tpnum& l, const tpnum& r){
return l.second == r.second;
});

std::sort(std::begin(numbers), end, [](const tpnum& l, const tpnum& r){
return l.first > r.first;
});

std::find_if(std::begin(numbers), end, [](const tpnum& e){
static std::size_t i = 0;
std::cout << "Broj " << e.second << " se ponavlja " << e.first << " puta." << std::endl;
return ++i >= F;
});
}

};

int main()
{
TopLista<60, 5> tl;
return 0;
}

Geomaster
22.9.2012, 17:41
STL je bio lep sve dok se nisu pojavile zle konstrukcije kao ove što je Belphegor koristio. :D

ivan90BG
23.9.2012, 19:21
@Belphagor, ako bi mogao malo da objasniš kako radi ovo tvoje sokoćalo. :D Gde vodiš koliko se svaki broj od 0 do 100 pojavio.

Elem, ja sam do sada debagovao i modifikovao implementaciju TopListe (one koja se uklapa u moj gornji kod), dok mi nije maločas puklo pred očima, i evo:


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

struct Par
{
int key;
int value;
};

int uporedi(const void* l, const void* r)
{
return -(((Par*)l)->value - ((Par*)r)->value);
}

int main()
{
Par niz[101];
memset(niz, 0, sizeof(niz));

for (int i = 0; i < 101; ++i)
niz[i].key = i;

srand(time(NULL));
for (int i = 0; i < 40000; i++)
{
niz[rand() % 101].value++;
}

qsort(niz, 101, sizeof(Par), uporedi);

for (int i = 0; i < 101; ++i)
{
printf("%d: (%d, %d)\n", i, niz[i].key, niz[i].value);
}
return 0;
}


Jbg, C++ megalomanija se ne isplati. :D

M.Silenus
23.9.2012, 21:00
Hi, folks! Vau, ova top lista je stvarno nešto popularna. Pa, evo i mog rešenja ;) Napomena: ovo rešenje nije najefikasnije, mrzelo me da izvlačim top 5, pa umesto toga vršim sortiranje. Takođe, pošto koristim dosta stvari iz C++11 biblioteke, ovo mu dođe kao demonstracija korišćenja tih... stvari...

Evo rešenja:


#include <iostream>
#include <random>
#include <chrono>
#include <vector>
#include <algorithm>
#include <numeric>
#include <functional>

int main()
{
auto now = std::chrono::high_resolution_clock::now();
auto seed = std::chrono::duration_cast<std::chrono::nanoseconds>
(now.time_since_epoch()).count();

// test uniformne raspodele
{
std::cout << "Uniformna raspodela (izvucen broj:broj izvlacenja):\n";

// svaki broj ima istu verovatnocu pojavljivanja
std::uniform_int_distribution<> u_dist(0,100);
std::mt19937 mt1(seed);
auto u_rand = std::bind(u_dist, mt1);

std::vector<int> counts(101, 0);
std::vector<size_t> indices(101);
std::iota(begin(indices), end(indices), 0);

for(size_t i = 0; i != 10000; ++i){
++ counts[u_rand()];
}

std::sort(begin(indices), end(indices),
[&counts](size_t a, size_t b) -> bool {
return counts[a] >= counts[b];
});

for(size_t i = 0; i != 5; ++ i)
std::cout << indices[i] << "\t" << counts[indices[i]] << "\n";
}
std::cout << "\n";
// test binomne raspodele
{
double p = 0.3;
std::cout << "Binomna raspodela, p = "
<< p
<< " (izvucen broj:broj izvlacenja):\n";

// vrsi se 100 eksperimenata, svaki ima verovatnocu uspeha 'p'; vraca broj uspelih
std::binomial_distribution<> b_dist(100, 0.5);
std::mt19937 mt2(seed);
auto b_rand = std::bind(b_dist, mt2);

std::vector<int> counts(101, 0);
std::vector<size_t> indices(101);
std::iota(begin(indices), end(indices), 0);

for(size_t i = 0; i != 10000; ++i){
++ counts[b_rand()];
}

// puca sa obicnim sort-om iz nekog razloga
// mozda zato sto je vecina elemenata 0?
std::stable_sort(begin(indices), end(indices),
[&counts](size_t a, size_t b) -> bool {
return counts[a] >= counts[b];
});

for(size_t i = 0; i != 5; ++ i)
std::cout << indices[i] << "\t" << counts[indices[i]] << "\n";
}

return 0;
}


PS: A da počnemo da koristimo Pastebin za ove stvari?

Belphegor
23.9.2012, 21:54
@Ivan

Ok. Mada mislim da je kod ocigledan.


class random
...
Dosadile mi srand i rand funkcije, a rek'o i da probam ovaj Mersenne Twister generator pa sam to lepo spakovao u klasu.
Klasa ima templejt metodu get overload-ovanu da bih u zavisnosti od tipa argumenata koristio odgovarajuce "distribucije".
Znaci samo integral i floating-point tipovi dolaze u obzir sve ostalo je compile time error.

http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution


typedef std::pair<std::size_t, std::size_t> tpnum;
std::vector<tpnum> numbers;
Imam vektor parova gde prvi element (first) oznacava koliko puta se ponovio neki broj i drugi element (second) oznacava sam taj broj.


numbers.resize(N);

std::for_each(std::begin(numbers), std::end(numbers), [](tpnum& e){
e = std::make_pair(0u, random::get(0u, 100u));
});
Prosirujem vektor na velicinu N (koliko brojeva se izvlaci) i inicijalizujem ga. first = 0, second = random 0 - 100.


for(auto& it : numbers)
{
it.first = std::count_if(std::begin(numbers), std::end(numbers), [&it](const tpnum& e){
return it.second == e.second;
});
}
Broji koliko se koji element ponavlja (tu su i "duplikati") i cuvam tu vrednost za svaki.


std::sort(std::begin(numbers), std::end(numbers), [](const tpnum& l, const tpnum& r){
return l.second > r.second;
});
Soriram po random brojevima koji su izvuceni da bih u sledecem koraku imao vektor spreman za unique-ifikaciju (std::unique (http://www.cplusplus.com/reference/algorithm/unique/)).


auto end = std::unique(std::begin(numbers), std::end(numbers), [](const tpnum& l, const tpnum& r){
return l.second == r.second;
});
Pozivam std::unique algo i cuvam end iterator da bih znao gde je kraj unikatima.


std::sort(std::begin(numbers), end, [](const tpnum& l, const tpnum& r){
return l.first > r.first;
});
Sortiram ponovo da bih dobio elemente koje se najvise ponavljaju prvo. Od pocetka do elementa gde pokazuje end iterator.

I na kraju ispisujem prvih F elemenata. Mada moze da se desi da broj unikata bude manji od F-a ali nece fejlovati.

ivan90BG
23.9.2012, 23:40
Pa dobro, jeste tačno, mada malo opskurno. Ali šta ako se traži veliki broj ponavljanja, koliki je i potreban da bi ispitivanje imalo statističku vrednost. Recimo nekoliko desetina hiljada. Uporedi performanse. Rakun_s_Neonkom je dao najbolji način za vođenje broja ponavljanja iz koga prirodno proizilazi samo jedno jedino sortiranje i kraj. :)

ivan90BG
5.10.2012, 21:21
Ima li neko predstavu zašto bi linker bacao grešku da ne može da nađe destruktor nadklase (pozvan je iz destruktora podklase), ako je pri tom taj destruktor označen sa "=0" (cela klasa je interfejs). Kompajler ne bi trebalo ni da ubacuje poziv za destruktor nad klase ako je pure virtual.

voodoo_
5.10.2012, 21:27
Da nije ovo?

http://stackoverflow.com/questions/2555033/linker-error-wants-c-virtual-base-class-destructor

ivan90BG
5.10.2012, 21:33
OK, razumeo, čak i ako je pure virtual destruktor mora da ima implementaciju. (:D koja koincidencija, i meni se ovo dešava na Mac OS X-u sa GCC 4.2).

voodoo_
5.10.2012, 23:06
To si ti i postavio, samo da proveriš naš googling skillz :D

voodoo_
20.10.2012, 21:22
Neke fore i fazoni za optimizaciju C i C++ koda (nije baš najsvežije, ali ima dosta toga korisnog):

http://www.tantalon.com/pete/cppopt/main.htm

Andross
29.10.2012, 17:01
Imam problem sa templejtima posto ne mogu nigde da nadjem krsten primer za ono sto meni treba. Elem imam Vec2D klasu koja je templejt i kod je sledeci:

#ifndef VEC2D_HPP_INCLUDED
#define VEC2D_HPP_INCLUDED

#include <cmath>

template <typename T>
class Vec2d
{
public:
// Constructor
Vec2d();
Vec2d(T x, T y);
Vec2d(const Vec2d& v);

// Methods
T GetLength();
Vec2d GetNormalized();

// Operators
Vec2d& operator=(const Vec2d& v);
Vec2d& operator+=(const Vec2d& v);
Vec2d& operator-=(const Vec2d& v);
Vec2d& operator*=(const T s);
Vec2d& operator/=(const T s);
const Vec2d operator+(const Vec2d& v) const;
const Vec2d operator-(const Vec2d& v) const;
const Vec2d operator*(const T s)const;
const Vec2d operator/(const T s)const;
bool operator==(const Vec2d& v);
bool operator!=(const Vec2d& v);

// Member variables
T X;
T Y;

// Static members
static Vec2d Zero;
};

#endif // VEC2D_HPP_INCLUDED

#include "Vec2d.hpp"

// Static member initialization
template <typename T>
Vec2d<T>::Zero = Vec2d<T>();

// Constructor
template <typename T>
Vec2d<T>::Vec2d()
{
X = 0;
Y = 0;
}

template <typename T>
Vec2d<T>::Vec2d(T x, T y)
{
X = x;
Y = y;
}

template <typename T>
Vec2d<T>::Vec2d(const Vec2d& v)
{
X = v.X;
Y = v.Y;
}

// Method implementation
template <typename T>
T Vec2d<T>::GetLength()
{
return sqrt(X * X + Y * Y);
}

template <typename T>
Vec2d<T> Vec2d<T>::GetNormalized()
{
float len = GetLength();
return Vec2d<T>(X / len, Y / len);
}

// Operator implementation
template <typename T>
Vec2d<T>& Vec2d<T>::operator=(const Vec2d& v)
{
if(this != &v)
{
X = v.X;
Y = v.Y;
}

return *this;
}

template <typename T>
Vec2d<T>& Vec2d<T>::operator+=(const Vec2d& v)
{
X += v.X;
Y += v.Y;
return *this;
}

template <typename T>
Vec2d<T>& Vec2d<T>::operator-=(const Vec2d& v)
{
X -= v.X;
Y -= v.Y;
return *this;
}

template <typename T>
Vec2d<T>& Vec2d<T>::operator*=(const T s)
{
X *= s;
Y *= s;
return *this;
}

template <typename T>
Vec2d<T>& Vec2d<T>::operator/=(const T s)
{
X /= s;
Y /= s;
return *this;
}

template <typename T>
const Vec2d<T> Vec2d<T>::operator+(const Vec2d& v) const
{
return Vec2d<T>(*this) += v;
}

template <typename T>
const Vec2d<T> Vec2d<T>::operator-(const Vec2d& v) const
{
return Vec2d<T>(*this) -= v;
}

template <typename T>
const Vec2d<T> Vec2d<T>::operator*(const T s) const
{
return Vec2d<T>(*this) *= s;
}

template <typename T>
const Vec2d<T> Vec2d<T>::operator/(const T s) const
{
return Vec2d<T>(*this) /= s;
}

template <typename T>
bool Vec2d<T>::operator==(const Vec2d& v)
{
if(X == v.X && Y == v.Y)
return true;

return false;
}

template <typename T>
bool Vec2d<T>::operator!=(const Vec2d& v)
{
return !(*this == v);
}

Sada prilikom kompajliranja dobijam sledecu gresku: need 'typename' before 'Vec2d<T>::Zero' because 'Vec2d<T>' is a dependent scope

Ukoliko uklonim staticku promenljivu, kompajl prodje fino i prilikom linkovanja popijem gomilu undefined reference gresaka.

Moja pitanja:

1. Gde sve pisem <T>? Kod povratne vrednosti i imena klase ciji metod implementiram i nigde vise?

2. Kako inicijalizujem staticku promenljivu templejta? Jel potrebno da pravim specijalizaciju za int, float i ostale tipove koje budem nameravao da koristim (videh negde da se to radi)?

3. Zbog cega se pojavljuju undefined reference greske i kako ih ukloniti?

Belphegor
29.10.2012, 19:46
Dok ne budes dobio detaljniji odgovor od nekog da probam ja da pomognem.

2. Sintaksa je:

template < typename T >
typename Vec2d<T>::Vec2d Vec2d<T>::Zero = Vec2d<T>();


Da ne ulazim zasto (Google "c++ template class implementation"), obicno kod templejt klasa iplementacija metoda se pravi u samom telu te klase.

Evo ti recimo za operatore "uporedjivanja" (g++ 4.7), ovi operatori trebaju isto da budu const posto ne menjaju clanove klase.

#include <type_traits>
...
template < typename T >
class Vec2d
{
// primamo samo odredjene tipove templejta Vec2d
// ostalo je compile time error
static_assert( std::is_floating_point<T>::value || std::is_integral<T>::value, "Unacceptable type for Vec2d!");
public:
Vec2d() : x(0), y(0) {}
Vec2d(T _x, T _y) : x(_x), y(_y) {}

template < typename U >
typename std::enable_if< std::is_floating_point<T>::value || std::is_floating_point<U>::value, bool >::type
operator == (const Vec2d<U>& o) const
{
if((std::fabs(x - o.x) > 0.00001) || (std::fabs(y - o.y) > 0.00001))
{
return false;
}
return true;
}

template < typename U >
typename std::enable_if< std::is_integral<T>::value && std::is_integral<U>::value, bool >::type
operator == (const Vec2d<U>& o) const
{
return x == o.x && y == o.y;
}

bool operator != (const Vec2d<T>& o) const
{
return !(*this == o);
}

T x, y;
static Vec2d<T> Zero;
};


Overload operatora == zbog uporedjivanja floating point brojeva.

3. Daj celu poruku za sta kuka.

Andross
29.10.2012, 20:38
Hvala za ovo.
Linker errore sam resio instanciranjem templejt klasa posto mi je implementacija i dalje odvojena, a koristicu samo odredjene tipove za T:

template class Vec2d<int>;
template class Vec2d<float>;

Edit: Jos 2 pitanja:

1. Zasto si koristio typename U za operator ==
2. Koja je fora sa const pre i posle funkcije? Tipa const a(); b() const; const c() const;

Geomaster
29.10.2012, 21:30
Hvala za ovo.
Linker errore sam resio instanciranjem templejt klasa posto mi je implementacija i dalje odvojena, a koristicu samo odredjene tipove za T:

template class Vec2d<int>;
template class Vec2d<float>;Edit: Jos 2 pitanja:

1. Zasto si koristio typename U za operator ==
2. Koja je fora sa const pre i posle funkcije? Tipa const a(); b() const; const c() const;
Na ovo prvo pitanje ne umem da odgovorim, Belph je koristio gomilu onih ogavnih stvari iz standardne biblioteke, nije mi sve najjasnije.
2. Const pre funkcije označava da je povratna vrednost funkcije konstantna tj. da se ne može menjati. Const posle funkcije znači da funkcija ne može da menja stanje klase u kojoj se nalazi, pa može da se poziva i iz const objekata te klase. Na primer:

class cls {
public:
int member1, member2;

void do_something() { member1 = 40; member2 = 20; }
int do_something_const() const { return member1*member2; } /* ne menja stanje klase */
};

...
const cls a;
cls b;
int x = a.do_something_const(); /* može, jer je funkcija const */
b.do_something(); /* može, funkcija nije const ali nije ni objekat */
a.do_something(); /* greška, objekat je const a funkcija nije! */
...

Belphegor
29.10.2012, 21:52
1. Zato sto nisam mogao drugacije da overloadujem taj operator na kontu samo T-a, a usput side-effect je da sad mogu da se porede Vec2d razlicith tipova:


typedef Vec2d<double> vd;
typedef Vec2d<int> vi;
...
vd v0(0.2, 3.6);
vi v1(5, 1);
if(v0 == v1)
...
2. Ima slucajeva da se desi da moras menjati neki clan klase u "post const" metodi, onda ga oznacis kao mutable.

class Foo
{
mutable int data;
float data2;
...
float metod() const
{
data = 5;// sad je dozvoljeno
return data2;
}
};

Alek92
5.11.2012, 18:14
Pozdrav narode,

I nakon dugog pretrazivanja, nisam uspeo da nadjem ono sto me zanima:

da li postoji nacin (i koji je to nacin) da ispisem tekst na ekran u boji po zelji, na osnovu R,G,B vrednosti?

(Uspevao sam da nadjem razne enume i slicne nacine, ali to mi nije prakticno)

Hvala u svakom slucaju ! :ciao:

Belphegor
5.11.2012, 19:24
Evo ti za pocetak:


#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <string>

typedef std::basic_string<TCHAR> tstring;

const tstring helloStr = TEXT("hello");
const tstring worldStr = TEXT("world");

LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);

SetBkMode(hdc, TRANSPARENT);

SetTextColor(hdc, RGB(200,0,100));
TextOut(hdc, 10, 10, helloStr.c_str(), helloStr.size());

SetTextColor(hdc, RGB(0,100,50));
TextOut(hdc, 10, 30, worldStr.c_str(), worldStr.size());

EndPaint(hWnd, &ps);
return 0;
}break;
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}break;
};
return DefWindowProcW(hWnd, msg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASS wndClass;
memset(&wndClass, 0, sizeof(WNDCLASS));
wndClass.hInstance = GetModuleHandle(0);
wndClass.style = CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = WindowProc;
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.lpszClassName = TEXT("TextTestClass");
wndClass.hbrBackground = GetSysColorBrush(COLOR_3DFACE);

DWORD style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPSIBLINGS | WS_MINIMIZEBOX | WS_THICKFRAME;
style |= WS_VISIBLE;

if(0 == RegisterClass(&wndClass))
{
MessageBox(0, TEXT("RegisterClass() failed!"), 0, 0);
return 1;
}

RECT clientSize;
clientSize.top = 0;
clientSize.left = 0;
clientSize.right = 200;
clientSize.bottom = 100;
AdjustWindowRect(&clientSize, style, FALSE);
int realWidth = clientSize.right - clientSize.left;
int realHeight = clientSize.bottom - clientSize.top;
int windowLeft = (GetSystemMetrics(SM_CXSCREEN) - realWidth) / 2;
int windowTop = (GetSystemMetrics(SM_CYSCREEN) - realHeight) / 2;

HWND hwnd = CreateWindowEx(0,
TEXT("TextTestClass"), TEXT("Text test"), style,
windowLeft, windowTop, realWidth, realHeight,
NULL, NULL, GetModuleHandle(0), NULL);
if(nullptr == hwnd)
{
MessageBox(0, TEXT("CreateWindowEx() failed!"), 0, 0);
return 1;
}

ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);

MSG msg = {0};
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

return 0;
}

ivan90BG
8.11.2012, 0:13
A sada nešto neviđeno


class Foo
{
protected:
struct Data
{
int var;
};

Foo::Data* d;
private:
Foo(Foo::Data* dptr);
public:
static Foo New();
Foo(Foo& other);
};

Foo::Foo(Foo::Data *dptr): d(dptr) {}
Foo::Foo(Foo& other): d(other.d) {}

Foo Foo::New()
{
return Foo(new Foo::Data);
}

int main()
{
Foo foo = Foo::New();
return 0;
}


Kompajler (GCC) daje grešku:

main.cpp:26: error: no matching function for call to 'Foo::Foo(Foo)'
linija 26 je u funkciji New(), a istu grešku javlja i za main() funkciju.

Šta mu dođe ovo, copy constructor by value (što nema smisla). Ako stvarno dodam konstruktor Foo(Foo other) kompajler se buni. Izgleda kao da mu nešto fali, pa on prelazi na neki praistorijski default koga nema. Ima li neko ideju šta ovde nedostaje.

Da nije možda stvar u tome što pri vraćanju objekata mora da se pozove copy constructor koji uzima referencu, a reference se mogu napraviti samo na neprivremene objekte. Mada čisto sumnjam.

EDIT: Otkrio, copy constructor mora da uzima const& da bi mogao da radi sa privremenim objektima, šta ti je ovaj C++ :D

Night Walker
18.11.2012, 16:36
Ljudi, treba mi pomoc oko stringova.
Kako da uporedim string zapamcen u nizu od 15 karaktera sa nekim konstantnim stringom?
Skontao sam da mogu da uporedjujem skaki pojedinacni karakter
(if (ff[0]=='T' && itd... do '\0'))
Ali to je naporno jer ima mnogo konstantnih stringova sa kojim treba uporediti.
Moze tako da radi jedino ako napravim funkciju u koja ce da uporedjuje 2 stringa koja jos se posalju, ali sigurno postoji jednostavniji nacin, zar ne?

Teva
18.11.2012, 16:43
http://www.cplusplus.com/reference/clibrary/cstring/strcmp/

voodoo_
22.11.2012, 14:05
Radi sigurnosti, koristi strncmp (kao treći argument prosledi dužinu prvog stringa od 15 karaktera).

Ozzy
12.12.2012, 21:29
Jel bi mogao neko da mi za ovaj algoritam tj kod da mi napise ulaz i izlaz tj da program moze da cita sa standardnog ulaza i izbacuje resenje na standardni izraz. Ja bi to sam uradio al neki delovi mi nisu bas jasni pa ce mi ovako biti lakse da posmatram posle u kompajleru korak po korak sta program radi pa da razumem. Hvala unapred :)


#include <string>
#include <cctype>

using namespace std;

class Parser
{
string input;
bool isValid;

bool isEnd(size_t pos) const
{
return pos >= input.size();
}

bool readChar(size_t &pos, char c) const
{
if (isEnd(pos) || input[pos] != c) {
return false;
}

++pos;

return true;
}

bool readString(size_t &pos, const string &str) const
{
if (input.substr(pos, str.size()) != str) {
return false;
}

pos += str.size();

return true;
}

bool isLetter(size_t pos) const
{
return isEnd(pos) == false && isalpha(input[pos]);
}

bool isAlphanumeric(size_t pos) const
{
return isEnd(pos) == false && isalnum(input[pos]);
}

bool readPropositionalLetter(size_t &pos) const
{
if (isLetter(pos) == false) {
return false;
}

do {
++pos;
} while (isLetter(pos));

return true;
}

bool readSubformula(size_t &pos) const
{
if (isEnd(pos)) {
return false;
}

if (readChar(pos, '-')) {
return readSubformula(pos);
}

if (readChar(pos, '(')) {
return readSubformula(pos) && readChar(pos, '>') && readSubformula(pos) && readChar(pos, ')');
}

return readPropositionalLetter(pos);
}

bool findImplication(size_t &pos) const
{
int brackets = 0;

for (; isEnd(pos) == false; ++pos) {
if (brackets == 0 && input[pos] == '>') {
++pos;

return true;
}

if (input[pos] == '(') {
++brackets;
} else if (input[pos] == ')') {
--brackets;
}
}

return false;
}

public:
Parser(const string &input) :
input(input)
{
size_t pos = 0;

if (readSubformula(pos) == false) {
isValid = false;

return;
}

if (isEnd(pos)) {
isValid = true;

return;
}

pos = 0;

isValid = readSubformula(pos) && readChar(pos, '>') && readSubformula(pos) && isEnd(pos);
}

bool axiom1() const
{
if (isValid == false) {
return false;
}

if (input.size() >= 2 && input[0] == '(' && input[input.size() - 1] == ')') {
Parser tmp(input.substr(1, input.size() - 2));

if (tmp.axiom1()) {
return true;
}
}

size_t pos = 0;

if (findImplication(pos) == false) {
return false;
}

string a = input.substr(0, pos - 1);

return readChar(pos, '(') && findImplication(pos) && readString(pos, a + ")") && isEnd(pos);
}

bool axiom2() const
{
if (isValid == false) {
return false;
}

if (input.size() >= 2 && input[0] == '(' && input[input.size() - 1] == ')') {
Parser tmp(input.substr(1, input.size() - 2));

if (tmp.axiom2()) {
return true;
}
}

size_t pos = 0;

if (readChar(pos, '(') == false || findImplication(pos) == false) {
return false;
}

string a = input.substr(1, pos - 2);

if (readChar(pos, '(') == false || findImplication(pos) == false) {
return false;
}

string b = input.substr(a.size() + 3, pos - a.size() - 4);

pos = 0;

if (findImplication(pos) == false) {
return false;
}

string c = input.substr(a.size() + b.size() + 4, pos - a.size() - b.size() - 7);

return readString(pos, string("((") + a + ">" + b + ")>(" + a + ">" + c + "))") && isEnd(pos);
}

bool axiom3() const
{
if (isValid == false) {
return false;
}

size_t pos = 0;

if (readString(pos, "((")) {
Parser tmp(input.substr(1, input.size() - 2));

return tmp.axiom3();
}

if (readString(pos, "(-") == false || findImplication(pos) == false) {
return false;
}

string b = input.substr(2, pos - 3);

pos = 0;

if (findImplication(pos) == false) {
return false;
}

string a = input.substr(b.size() + 4, pos - b.size() - 6);

return readString(pos, string("(") + a + ">" + b + ")") && isEnd(pos);
}
};

M.Silenus
12.12.2012, 22:15
Ovako nešto:


#include <iostream>
#include <iomanip>
#include <iterator>

// ... parser kod ... //

int main()
{
std::string input(std::istream_iterator<std::string::value_type>(std::cin),
std::istream_iterator<std::string::value_type>());

Parser parser(input);

std::cout << std::boolalpha;

std::cout << parser.axiom1() << "\n";
std::cout << parser.axiom2() << "\n";
std::cout << parser.axiom3() << "\n";

return 0;
}



Ispišeš ulaz i lupiš Ctrl + Z i dobiješ rezultat.

Ozzy
12.12.2012, 22:31
Ovako nešto:


#include <iostream>
#include <iomanip>
#include <iterator>

// ... parser kod ... //

int main()
{
std::string input(std::istream_iterator<std::string::value_type>(std::cin),
std::istream_iterator<std::string::value_type>());

Parser parser(input);

std::cout << std::boolalpha;

std::cout << parser.axiom1() << "\n";
std::cout << parser.axiom2() << "\n";
std::cout << parser.axiom3() << "\n";

return 0;
}

Ispišeš ulaz i lupiš Ctrl + Z i dobiješ rezultat.

Hvala ti druze mnogo :D
Jel ovo Ctrl+Z moze da se promeni da radi na neku drugu komandu tipa da kad kliknes na tab da krene da radi?

M.Silenus
12.12.2012, 23:07
Ne znam za tab, ali, ako ti odgovara da ulaz obrađuješ liniju po liniju (tj. kad pritisneš enter, on pozove parser) onda možeš da uradiš ovako nešto:


#include <iostream>
#include <iomanip>
#include <iterator>

// ... parser kod ... //

int main()
{
std::string line;

while(std::getline(std::cin, line))
{
if( line == "exit" )
break;

Parser parser(line);

std::cout << std::boolalpha;

std::cout << parser.axiom1() << "\n";
std::cout << parser.axiom2() << "\n";
std::cout << parser.axiom3() << "\n";
}

return 0;
}


Ovaj program možeš da prekineš kada otkucaš "exit" + Enter ili Ctrl + Z, pa šta ti više odgovara.

Ne znam kako uraditi to sa tabovima bez neke GUI biblioteke, ali to mi je overkill za aplikaciju ovog tipa.

Ozzy
18.12.2012, 20:39
Jel moze neko da mi napise kako bi se mogao dotati neki text ispred ovoga true i false?

Ovako nešto:


#include <iostream>
#include <iomanip>
#include <iterator>

// ... parser kod ... //

int main()
{
std::string input(std::istream_iterator<std::string::value_type>(std::cin),
std::istream_iterator<std::string::value_type>());

Parser parser(input);

std::cout << std::boolalpha;

std::cout << parser.axiom1() << "\n";
std::cout << parser.axiom2() << "\n";
std::cout << parser.axiom3() << "\n";

return 0;
}

Ispišeš ulaz i lupiš Ctrl + Z i dobiješ rezultat.

Lucic Nemanja
15.1.2013, 15:49
#include <iostream>
using std::cout;

class O {};
class I : O {};

void m(int& x)
{
x=0;

try
{
x=1;
throw new O;
x=2;
}
catch(I* i)
{
x=3;
}

if (x!=3) x=4;
}

int main ()
{
int x;
m(x);
cout << x;
system("pause");
return 0;
}

Prijavljuje gresku kod linije "throw new O". Kada promenim catch da hvata O*, ili throw da baca I* radi normalno. Da li je ikako moguce zaobici ovaj problem i koristiti pokazivac na izvedenu klasu da hvatam pokazivac na baznu? Takodje ekspilictnim konvertovanjem pokazivaca kod throw operatora u tip I* program radi normalno.
Prvenstveno me buni jer je ovakvo pitanje doslo na ispitu iz C++ (bez main funkcije, nju sam ja napisao cisto da bi testirao u kompajleru, a zadatak je da se odredi vrednost promenljive x nakon zavrsetka funkcije m). Kontam da je greska, pa reko da l' da im prijavljujem to?

M.Silenus
15.1.2013, 19:55
Prvo, ako misliš da ti kod proradi, stavi


class I : public O {};


Podrazumevano nasleđivanje je private.

I je podklasa od O. Ne možeš da koristiš pokazivač tipa I* da ti pokazuje na objekat tipa O (ok, možeš sa recimo reinterpret_cast, ali to je već varanje :) ).

Kada bi bacao pokazivač na objekat tipa I (što je izvor memory leak-a, btw), a hvatao O*, sve bi bilo OK.

Please, nikada nemoj da radiš throw new nešto. Bolje uradi nešto ovako:


try
{
throw I();
}
catch(O const& i)
{
x=3;
}


Takođe bi bilo dobro da uvek stavljaš catch(...).

Pozz!

PS: sorry ako sam preterao, couldn't help it.

Lucic Nemanja
16.1.2013, 11:46
Hvala. Ma nisam ja ovo pisao, to je jedan od onih retardiranih pitanja koja su smisljena da provere znanje jezika, a ne kako treba programirati :). Samo ne vidim zašto program ne bi radio sa private nasleđivanjem. Ono samo menja mogućnost pristupa poljima nasleđene klase. Kakve to veze ima sa pokazivačima? Implicitna konverzija I* u O* bi trebalo da je dozvoljena uvek... Ili ne?

M.Silenus
16.1.2013, 13:13
I* u O* da, ne obratno, što je slučaj sa originalnim kodom.

Što se javnog nasleđivanja tiče, biću iskren, nisam siguran koja su tačno pravila - probao sam kod sa g++ 4.7 i ne radi bez javnog nasleđivanja, što ne znači da je tako u standardu.

Pogledaj recimo Protected/Private Inheritance Casting (http://stackoverflow.com/questions/5372070/protected-private-inheritance-casting) i C-Style upcast and downcast involving private inheritance (http://stackoverflow.com/questions/844816/c-style-upcast-and-downcast-involving-private-inheritance?rq=1) pitanja na StackOverflow-u.

PeTkO
26.1.2013, 20:38
Pozdrav,

Mozda ce moje pitanje da zvuci malo glupo, ali odavno sam "ispao" iz aplikativnog programiranja, pa su mi neke stvari nerazumljive...Na faxu ucimo trenutno C jezik, sintaksa mi je jasna jer sam radio u C++, relativno su slicni jezici, ali ono sto me buni su pokazivaci. Ne znam kako ali uopste ne mogu da shvatim njihovu svrhu i nacin upotrebe. Jako bi voleo ako bi neko mogao da mi objasni sta su pokazivaci, cemu sluze i njihova primena u praksi. Takodje me zanima i koja je razlika izmedju pokazivaca i adresa? Koliko sam shvatio kod adresa je potrebno da se prethodno tacno alocira memorija za odredjenu promenljivu dok to kod pokazivaca nije slucaj...jel tako?

MG-RAY
26.1.2013, 21:30
Ne postoje glupa pitanja. :D

Koncept pointera zna da bude dosta stran ljudima zbog toga što malo ko ume da ga pravilno objasni.

Po definiciji, pointer (pokazivač) je variabla u kojoj se nalazi adresa memorijske lokacije. Šta to znači? Poprilično podenostavljen primer i analogija jeste da imaš parče papira na kome je napisana adresa nečega (mesto, ulica, broj). Taj papir je pointer, a on pokazuje na kuću koja se nalazi na datoj adresi.

Koriste se za dosta stvari, pre svega zbog performansi, ali na primer, u C-u, da bi uradio neke stvari nemaš previše izbora? C je jezik jako niskog nivoa, samim tim nisi ograničen nekim paradigmama, radiš poprilično blizu nativnom nivou.

Na primer, C ne podržava stringove nativno, samim tim moraš da koristiš nizove znakova:


char[] yo = "yo!";
char *yo = "yo!";


Primeri iznad su potpuno ekvivalentni, ali evo nesto jednostavnije:


int a = 123;
int *b = &a;


Prva linija jednostavno dodeljuje varijabli a vrednost 123.
U drugoj liniji, b je zapravo pointer, kome smo koristeći operator (&) dodelili adresu od a, što znači, adresu memorijske lokacije u kojoj je smeštena vrednost 123.

Kada bi uradio sledeće:
printf("%d", b);

Ne bi se ispisalo 123, već sama adresa u memoriji na kojoj se 123 nalazi.

Da bi dobio vrednost sa te adrese (123), koristi se operator *
printf("%d", *b);

Za drugi deo tvog pitanja, pointeri mogu da pokazuju na gotovo sve, na primer, kada uradis malloc() (funkcija za alokaciju memorije), ona ti vraća pointer na novoalocirani memorijski blok. Analogno tome, free() funkcija uzima kao parametar pointer koji označava koji memorijski blok se dealocira.

Još jedan primer, pointere možeš da koristiš sa nizovima (kao char* od malopre), i da se samom inkrementacijom istog krećeš kroz niz, npr:


char *yo = "yoyoyoyo";
while(*yo) {
printf("%c", *yo);
yo++;
}


... jer sama variabla yo sadrži adresu prvog karaktera.

Pointere u C-u ćeš naći svugde, tako da bolje pogledaj dokumentaciju onoga šta te interesuje i videćeš.

Što se tiče tvog problema oko pointera i adresa, adresa je samo broj koji označava lokaciju nečega u memoriji, tako da baš i ne možeš da ih porediš, jer pointer sadrži adresu, koja je sama po sebi neka vrednost. Uvek možeš da imaš pointer, koji pokazuje na neki drugi pointer, a taj drugi pointer pokazuje na neku vrednost - sasvim legitimno. :)

Možda si mislio na razliku između pointera i referenci u C++?

voodoo_
26.1.2013, 21:43
Ukratko, pokazivač je adresa. Odnosno, promenljiva koja je tipa pokazivač na nešto sadrži samo i isključivo nekakvu adresu u obliku 32-bitnog unsigned integera, i ništa drugo (s tim što su u 64-bitnim programima automatski i pokazivači 64-bitni).

To što pokazivač u C-u može biti određenog "tipa" samo govori kompajleru šta se nalazi na adresi koju pokazivač sadrži. Dakle, int*, float*, void*, to su i dalje 32-bitni unsigned integeri koji sadrže memorijsku adresu, a ono ispred zvezdice samo kaže C-u kako da tretira to što je na adresi (u pogledu dozvoljenih operatora nad podatkom koji je na toj adresi, broja bajtova koje treba pročitati počev od te adrese, itd).

Uvek, uvek zapamti da je C samo jedan korak iznad asemblera i da se praktično sve iz C-a (uključujući pokazivače) direktno mapira na odgovarajuće "mehanizme" u asembleru.

ivan90BG
28.1.2013, 10:06
char[] yo = "yo!";
char *yo = "yo!";


Primeri iznad su potpuno ekvivalentni...

Nisu ekvivalentni. U prvoj liniji yo je pokazivač na niz karaktera na stacku (odnosno kada izvršenje dođe do te linije niz se kopira na stack iz read only dela memorije gde su skladišteni svi string literali), dok je u drugoj liniji yo pokazivač na niz karaktera koji se nalazi u read only memoriji (poseban deo memorijskog prostora gde se nalaze string literali, instance struct-ova čija su polja inicilazovana konstantama, string literalima ili drugim sličnim structovima (za globalne promenljive i struct literale u kodu), sadržaj ovog dela memorije se automatski povlači iz samog izvršnog fajla)

Markonije
28.1.2013, 21:15
'Skoro je nemoguce objasniti prostim recima sta je pokazivac i cemu sluzi' - moj profa sa vise

:D

Nego sad bez zezanja,jel oni sluze na primer: da se ustedi na samoj zahtevnosti aplikacije (manja potrosnja rama)?

ivan90BG
28.1.2013, 21:45
Ne, pointeri ne služe ničemu. :D

Odnosno pointeri nemaju jednu određenu svrhu. Postoji ono što pointeri jesu, a to kako će se koristiti zavisi od kreativnosti i znanja programera.

To što još uvek ne shvataš čemu služe pointeri znači samo da još ne znaš dovoljno o stacku i heap-u i osnovnim strukturama podataka i algoritmima. Ja sad ne mogu da ti objasnim kako pointeri doprinose efikasnosti aplikacije, jer bi to povuklo ovo što sam pomenuo, a kad to naučiš nećeš uopšte više pitati ovakva pitanja.

E sad ne znam da li ti znaš Javu ili C#. Ako znaš onda mogu da ti objasnim lako.

Markonije
28.1.2013, 22:04
Osnovno 'aplikativno znanje' C#

Pointer pokazuje na adresu koja sadrzi 'fizicki nesto' za razliku od njega...

Znak za Hotel pored puta nije hotel vec pokazuje na njega...

Lepo sam pitao,ako ne znas odgovor na konkretno pitanje,onda nista....

Cemu psiho-analiza umesto odgovora????

voodoo_
28.1.2013, 23:14
'Skoro je nemoguce objasniti prostim recima sta je pokazivac i cemu sluzi' - moj profa sa vise
Trebalo je da krenete od asemblera, pa bi vam pokazivači bili ko dobar dan.

Pokazivači su potpuno prirodni koncept, jer se memorija sastoji od ćelija u koje se nešto može upisati, i te ćelije imaju neke lokacije (adrese). E sad, moderni jezici su te adrese sakrili i podacima se pristupa preko imena promenljivih, ali uvek postoji potreba za pokazivačima jer ćeš imati programe gde nećeš u startu znati ni koliko ćeš imati podataka, niti kog će biti tipa. I onda ti ne preostaje ništa drugo nego da u toku izvršenja zauzimaš i oslobađaš memoriju po potrebi, a toj memoriji jedino preko pokazivača/adresa možeš da pristupiš.

Kao na primer, vrlo često korišćen koncept ulančane liste (http://en.wikipedia.org/wiki/Linked_list), koja je izuzetno pogodna za realizaciju nizova jako promenljivog sadržaja, jer se umetanje u niz svodi na kreiranje novog elementa i "prevezivanje" elemenata koji treba da dođu pre i posle novog. U slučaju običnog statičkog niza, kad bi hteo da umetneš nov element, morao bi prethodno sve posle njega da prekopiraš na jednu lokaciju ispred, što je sporije.

Ima i složenijih struktura koje se takođe oslanjaju na pokazivače, kao što su npr. stabla (http://en.wikipedia.org/wiki/B-tree) i veoma često se koriste u mnogim programima (recimo svi aktuelni fajl sistemi su izvedeni preko stabala) a da korisnici apsolutno nisu svesni toga.

ivan90BG
29.1.2013, 0:29
@voodoo

Zahvalnica zbog asemblera. ;)

@Markonije

Nikakva psihoanaliza, pa i profesor je rekao da se ne može objasniti normalnim rečima. :)

Elem, ako znaš C#, svaki put kad kreiraš novi objekat sa new, to je alokacija memorije i ti dobijaš pointer, samo što C# i .NET to prikrivaju.


List<string> lista1 = new List<string>();
List<string> lista2 = lista1;
Console.WriteLine(lista1.Count);
Console.WriteLine(lista2.Count);
lista1.Add("yo!");
Console.WriteLine(lista1.Count);
Console.WriteLine(lista2.Count);


Ovaj program će ispisati

0
0
1
1


Znači, lista1 i lista2 su jedan isti objekat, odnosno lista1 i lista2 su u stvari pokazivači koji pokazuju na isti objekat u memoriji (imaju u sebi istu adresu).

Teva
29.1.2013, 0:42
U javi postoje pokazivaci? :O


dodao bih jos:

Pokazivac kao sto su rekli pokazuje na neko parce memorije. U sustini nije nista drugo do adrese neke memorijske lokacije koja sadrzi neki podatak. (pokazivac je int ako se ne varam)

Pokazivaci se na jedan il na drugi nacin provlace u svakom aspektu.

Prva primena pokazivaca su nizovi podataka.

int a[10];

a je sam po sebi pokazivac na prvi clan tog niza, dok a[1] je ustvari pokazivac na sledecu poziciju sto je ekvivalentno *a +1 itd.

Dalja upotreba je kad obradjujes podatke u funkciji. Zbog zivotnog veka promenljive tebi rezultat funkcije mora da bude povratna vrednost il se promena nece desiti. Ukoliko mu ti prosledis pokazivac on nece praviti svoje kopije nego ce sve promene raditi na konkretnom parcetu memorije pa ces dalje upotrebljavati normalno.

Sad stizemo do dinamicke alokacije memorije. To je manje vise rekao sve voodoo gore iznad.

Generalno pokazivaci su jako mocan koncept. E sad kako sa velikom moci dolazi velika odgovornost, ako ih ne savladas kako treba bice ti nocna mora. :D

EDIT:

Zasto nema How to C tema? xD :D

Geomaster
29.1.2013, 0:55
Prva primena pokazivaca su
nizovi podataka.
int a[10];
a je sam po sebi pokazivac na
prvi clan tog niza, dok a[1] je
ustvari pokazivac na sledecu
poziciju sto je ekvivalentno *a +1
itd.

Ne. a[1] jeste drugi element tog niza, ne pokazivač. Pokazivač na drugi element niza bi bio a + 1. Isto tako a[1] nije ekvivalentno sa *a + 1 već sa *(a + 1). S obzirom da je * unarni operator on će se izvršiti pre + koji je binarni, pa bi to što si napisao značilo a[0] + 1, a to nije ono što nam treba :)

Teva
29.1.2013, 0:56
Ne. a[1] jeste drugi element tog niza, ne pokazivač. Pokazivač na drugi element niza bi bio a + 1. Isto tako a[1] nije ekvivalentno sa *a + 1 već sa *(a + 1). S obzirom da je * unarni operator on će se izvršiti pre + koji je binarni, pa bi to što si napisao značilo a[0] + 1, a to nije ono što nam treba :)

U pravu si :) Typo xD

Lucic Nemanja
29.1.2013, 16:29
Pokazivac kao sto su rekli pokazuje na neko parce memorije. U sustini nije nista drugo do adrese neke memorijske lokacije koja sadrzi neki podatak. (pokazivac je int ako se ne varam)

Jeste int i to 4 bajta na 32-bitnim, a 8 bajtova na 64-bitnim računarima. Logično, veća magistrala, više adresnog prostora, potrebno više memorije za prikazivanje jedne adrese.

MG-RAY
31.1.2013, 12:32
Nisu ekvivalentni. U prvoj liniji yo je pokazivač na niz karaktera na stacku (odnosno kada izvršenje dođe do te linije niz se kopira na stack iz read only dela memorije gde su skladišteni svi string literali), dok je u drugoj liniji yo pokazivač na niz karaktera koji se nalazi u read only memoriji (poseban deo memorijskog prostora gde se nalaze string literali, instance struct-ova čija su polja inicilazovana konstantama, string literalima ili drugim sličnim structovima (za globalne promenljive i struct literale u kodu), sadržaj ovog dela memorije se automatski povlači iz samog izvršnog fajla)

Iako se potpuno slažem sa tobom tu, pitanje se odnosilo na pointere a ne na to kako i gde C compiler smešta podatke. :D

Hteo sam da demonstriram ovo:


char a[] = "lolz";
char *b = "lolz";

printf("%c%c%c%c", a[0], b[1], *(a + 2), *(b + 3)); // lolz

Eris
1.2.2013, 11:06
Evo ovde nesto osnovno o pokazivacima i nizovima nadam se da ce kolko tolko pomoci :) http://www.acs.uns.ac.rs/sr/filebrowser/download/1007

pivonroll
1.2.2013, 17:45
Sto bre ne kupite neku knjigu iz C++ ko ljudi. Imate Thinking in C++, The C++ Programming Language, Effective C++ i udri.[/URL][URL="http://www.research.att.com/%7Ebs/3rd.html"] (http://www.research.att.com/%7Ebs/3rd.html)

ntrifunovic
24.2.2013, 1:01
Deo materijala o C++ -u koje sam prebacio u formu web-sajta.

Materijali su prvenstveno namenjeni pripremi za takmicenja iz programiranja, a mogu biti korisni za ucenje c++/c -a (teme Uvod u C++).

Materijali ce biti dopunjavani tokom vremena i novi materijali ce biti dodavani na sajt.

Nadam se da ce ovi materijali nekome ovde koristiti :)

http://ntrifunovic.github.com
http://ntrifunovic.herokuapp.com

Na oba linka je isti sajt (samo je drugi host).

Belphegor
24.2.2013, 2:00
Tema "Uvod u C++ IO".

U ovom kursu koristicemo C I\O (biblioteku stdio.h) za input i output
>> zato sto je znatno brza u odnosu na C++ ...


Zato sto je brza ili sto autor ne zna da koristi C++ IO mehanizme? A i ako je brze, kakve to sad veze ima kad tutorijal u stvari treba da uvede/upozna nekog sa C++ jezikom.
A koliko vidim i ostali tutorijali su ti isto u "C fazonu".
Tutorijali na ovom sajtu su mi necitljivi, pogotovo kad je pozadina tamna a jos slova sarena.

Geomaster
24.2.2013, 2:47
Kao što si već verovatno video, tutorijali su namenjeni učenicima dodatne nastave iz informatike, koji se spremaju za učešće na takmičenjima. Tamo je nemoguće koristiti C++ IO strimove u većini slučajeva, upravo zbog vremenskih ograničenja i ogromnog overhead-a koji one imaju. Slažem se da bi trebalo upoznati čitaoce i sa tim načinom za input/output, ali koliko vidim autor se ovde fokusira na praktičnu primenu na takmičenjima i sličnim nadmetanjima, dakle na čisto algoritamske probleme. I mislim da je autor više nego upoznat sa C++ IO mehanizmima :)

ntrifunovic
24.2.2013, 2:50
Belphegor, hvala ti sto si pogledao sajt i napisao par komentara.

Slazem se sa tobom u potpunosti, a evo i par objasnjenja zasto su neke stvari uradjene onako kako su uradjene.

Zato sto je brza ili sto autor ne zna da koristi C++ IO mehanizme? A i ako je brze, kakve to sad veze ima kad tutorijal u stvari treba da uvede/upozna nekog sa C++ jezikom.

Kao sto sam napisao u prethodnom postu materijali su prvenstveno namenjeni pripremi za takmicenja iz programiranja. U takmicarskim uslovima brzina citanja ulaza moze da bude veoma bitna.

A koliko vidim i ostali tutorijali su ti isto u "C fazonu".

Ovo je tacno i to iz 2 razloga
1) zbog razloga brzine izvrsavanja programa
2) na takmicenjima nije potrebno koriscenje svih mogucnosti c++ -a (npr. OOP) pa se te mogucnosti ne obradjuju u materijalima

Tutorijali na ovom sajtu su mi necitljivi, pogotovo kad je pozadina tamna a jos slova sarena.

Da li mislis samo na kod ili i na ostali tekst ?

Za kod se slazem da bi trebalo par boja promeniti da budu svetlije i samim tim citljivije, ali takodje mislim da je i ovako bolje nego bez "farbanja sintakse" - moguce da se varam :)

Ako bi postojalo interesovanje mogao bi dopuniti ove materijale ili napraviti nove koji su skroz u duhu c++ -a i principa OOP-a, naravno kada uspem da nadjem slobodnog vremena :)

voodoo_
24.2.2013, 11:07
1. Mislim da ne bi trebalo klasične funkcije da zoveš "metode". Metoda je funkcija koja je članica neke klase i operiše nad poljima te klase (osim ako joj se proslede pokazivači i reference, ali nije to poenta), a printf i scanf to definitivno nisu. Dakle reč metoda nije sinonim za funkciju. I generalno cela ideja učenja čistog C-a pod plaštom C++ mi se nimalo ne sviđa, al valjda znate šta radite u tom školstvu.

2. Ako je tutorial već formalno o C++, treba odvići đake da koriste .h zaglavlja, pa je sve ovo moglo biti opisano i koristeći #include <cstdio>, da bude u duhu C++.

3. ++x radi brže od x++, tako da treba izgraditi praksu da se uvek koristi prva varijanta ako se gađa na brzinu, osim u slučajevima kada nam je baš potreban bočni efekat uvećanja promenljive nakon njenog čitanja.

Geomaster
24.2.2013, 12:42
++x i x++ su, ako im se ignoriše povratna vrednost, sasvim ekvivalentni. U oba slučaja će se prevesti u ADD ili MOV-ADD-MOV set instrukcija. U suprotnom, ako im povratna vrednost nije ignorisana, ++x je zaista za nekoliko procesorskih ciklusa brže, ali ako je povratnu vrednost upotrebio za nešto, programeru je verovatno bilo potrebno upravo to ponašanje.

Belphegor
24.2.2013, 14:24
U takmicarskim uslovima brzina citanja ulaza moze da bude veoma bitna.
Ne razumem kakvo je to takmicenje gde se stopuje vreme i za IO operacije?
Zar nije logicnije i pravednije da se u kodu ubaferuje unos i meri vreme/ispravnost samo za algo o kome je rec, nesto kao kao unit testing (http://en.wikipedia.org/wiki/Unit_testing)?


Da li mislis samo na kod ili i na ostali tekst ?
Ne znam za ostale, ja recimo posle nekog vremena osecam zamor u ocima kad citam nesto gde je pozadina tamna.
Sto se tice "obojenog sintaksa" mislim da ne bi smetao ako se postavi neka svetla pozadina.

Andross
24.2.2013, 15:34
Ne razumem kakvo je to takmicenje gde se stopuje vreme i za IO operacije?

Svako.

Geomaster
24.2.2013, 16:48
Bilo bi divno kada bi rešenja takmičara mogla da se testiraju kao unit-i, ali moraš razumeti da nisu svi takmičari na nivou znanja koji im omogućava da pišu autonomne unit-e poštujući neki već dati interfejs. S obzirom na to da na takmičenju mogu da se koriste različiti programski jezici, standardizacija tako nečega bi bila pravi pakao. Pogledaj i svetski poznate i korišćene onlajn judge sisteme, pa i svetska takmičenja iz informatike kao na primer IOI - svuda se podaci učitavaju iz nekog tekstualnog strima, a rezultati ispisuju na isti način.

ntrifunovic
24.2.2013, 22:48
Upravo tako, jedino topcoder radi tako sto se implementira dati interfejs. Svi ostali koriste standardni ulaz/izlaz ili fajlove.

Belphegor
25.2.2013, 0:24
Svi ostali koriste standardni ulaz/izlaz ili fajlove.


Mislis mogu da koriste fajl kao standardni ulaz i/ili izlaz.

Geomaster
25.2.2013, 1:01
Mislim da je mislio na to da se ili podaci učitavaju/ispisuju pomoću standardnog ulaza/izlaza ili u fajlove (tipa zadatak.in i zadatak.out).

Belphegor
25.2.2013, 1:07
Fajl moze biti ulaz/izlaz nije ili.

ntrifunovic
25.2.2013, 23:36
Izmenio sam "farbanje" sintakse da bude citljivije.

Primer: http://ntrifunovic.github.com/zadaci/ (http://ntrifunovic.github.com/zadaci/)

stepanov
3.3.2013, 12:12
Na faxu radimo u C-u, a kod kuce sam mislio da radim u Dev C++, pa me zanima da li postoje neke razlike koje bi mi pravile problem, ili je razlika samo u dodatim klasama, a da je ostatak sintakse nepromenjen?

Geomaster
3.3.2013, 12:40
Iako je C++ nastao od C-a, postoje neke razlike koje bi ti možda predstavljale problem. Za manje programe verovatno ne bi bilo problema ali kada bi uplovio u komplikovanije stvari i egzotičnije delove sintakse verovatno bi naišao na neke stvari koje se ne ponašaju isto. Za konkretne razlike, Wikica ima to lepo objašnjeno: en.m.wikipedia.org/wiki/Compatibility_of_C_and_C%2B%2B .

Andross
16.3.2013, 14:06
Petljam se opet sa templejtima nesto i zanima me kako da pozovem neku funkciju od T (recimo imam cache resursa i znam da ce svaki resurs tip imati tu funckiju implementiranu)?

//hpp
template <typename T>
class Cache
{
public:
T* loadFromFile(std::string filename);
}

//cpp
template <typename T>
T* Cache<T>::loadFromFile(std::string filename)
{
T* resource = new T();
resource->loadFromFile(filename); // KAKO OVO?
return resource;
}

Belphegor
16.3.2013, 14:45
Koji kompajler koristis?
Mislim da se to zove "Name resolution for dependant types" i koliko vidim kod mene je to automatski "disambiguated" ( kako da prevedem ovo :D ) kod VS-a 2010 kao i sa g++4.7.
Ako kod tebe prijavljuje gresku stavi ovako:


//cpp
template <typename T>
T* Cache<T>::loadFromFile(std::string filename)
{
T* resource = new T();
typename resource->loadFromFile(filename);
return resource;
}


EDIT: Nice article Dependant-Name-Hell (http://www.codeproject.com/Articles/229460/Dependant-Name-Hell)

Andross
16.3.2013, 16:05
Mogu samo reci "gremlini". Nista nisam dirao sada radi. Moving on... :paranoia:

EDIT: g++ 4.7.1 mislim da je.

Andross
22.3.2013, 23:58
Koji je najbolji tip kontejnera za skladistenje game objecta, gledajuci sa strane performansi naravno. Na netu nalazim mnogo oprecnih misljenja, pa rekoh ovde da se konsultujem :)

Belphegor
23.3.2013, 14:57
Ne moze se bas reci koji je najbolji jer zavisi od tipova podataka koje zelis da sadrzi, broja elemenata, nacina pristupa, koliko cesto se dodaju/oduzimaju elementi...
Ukratko, ja sam za std::vector jer je cache-friendly, osim ako recimo drzis pokazivace bez koriscenja nekog memorijskog pool-a za njihovu alokaciju, posto zelimo da podaci budu "contiguous" u memoriji. U svakom slucaju veoma je tesko tako organizovati podatke a da se ne izgubi neka fleksibilnost i lakoca odrzavanja koda, mozes samo malo da minimizujes problem. Moj ti je savet da se ne opterecujes mnogo sa ovim sve dok ne uvidis da li ti je to u stvari "bottleneck".

vector vs. list, neki kljucne tacke izmedju ova dva kontenera, iseceno sa StackOverflow foruma:

vector:


Contiguous memory.
Pre-allocates space for future elements, so extra space required beyond what's necessary for the elements themselves.
Each element only requires the space for the element type itself (no extra pointers).
Can re-allocate memory for the entire vector any time that you add an element.
Insertions at the end are constant, amortized time, but insertions elsewhere are a costly O(n).
Erasures at the end of the vector are constant time, but for the rest it's O(n).
You can randomly access its elements.
Iterators are invalidated if you add or remove elements to or from the vector.
You can easily get at the underlying array if you need an array of the elements.

list:


Non-contiguous memory.
No pre-allocated memory. The memory overhead for the list itself is constant.
Each element requires extra space for the node which holds the element, including pointers to the next and previous elements in the list.
Never has to re-allocate memory for the whole list just because you add an element.
Insertions and erasures are cheap no matter where in the list they occur.
It's cheap to combine lists with splicing.
You cannot randomly access elements, so getting at a particular element in the list can be expensive.
Iterators remain valid even when you add or remove elements from the list.
If you need an array of the elements, you'll have to create a new one and add them all to it, since there is no underlying array.

Andross
24.3.2013, 2:17
Sredio sam sve to, jos jedno pitanje - jel ima neka fora da npr:

std::vector<OsnovnaKlasa*> komponente;
komponente.push_back(new IzvedenaKlasa1());
komponente.push_back(new IzvedenaKlasa2());
komponente.push_back(new IzvedenaKlasa3());

// ...

std::vector<OsnovnaKlasa*>::const_iterator iter;
for(iter = komponente.begin(); iter != komponente.end(); ++iter)
if((*iter)->proveriAtribute(objekat))
objekat->dodajKomponentu(new IKN(objekat)); // Ovo me zanima

// ...

IKN bi bila izvedena klasa n, iliti tip klase trenutnog iterovanog elementa.

U principu imam klasu BaseComponent koja je abstraktna i onda bih izvodio ostale komponente iz nje (HealthComponent, MovementComponent, AIComponent itd.). Pri kreiranju GameObjecta se proveravaju atributi i kace odgovarajuce komponente na njega, pri tome svaka komponenta utice na samo jedan GameObject. Prvo sto mi je palo na pamet je da imam std::vector<BaseComponent*> koji ce da cuva sve komponente koje se mogu kaciti, pa preko njega da proveravam (otud kod i pitanje odozgore) mada nisam siguran da li se moze tako uradili i jel postoji neki bolji nacin za ovo?

M.Silenus
24.3.2013, 8:57
Verovatno možeš da uradiš nešto preko typeid operatora. Na primer:


if(typeid(*iter) == typeid(HealthComponent))
{
objekat->dodajKomponentu(new HealthComponent(objekat));
}
else if ...


Ili, sa dynamic_cast-om:


if(dynamic_cast<HealthComponent*>(*iter) != nullptr)
{
objekat->dodajKomponentu(new HealthComponent(objekat));
}
else if ...


Za sve ovo je neophodno da hijerarhija klasa bude polimorfna (čitaj, neki metod u BaseComponent treba da bude virtual - hint: destruktor uvek mora da bude virtuelan u polimorfnim klasama, kviz pitanje: zašto? ;) ).

U stvari pre nego što počneš da koristiš pomenute tehnike, dobro prouči kako one rade. Takođe, uzmi u obzir da znaju da budu spore.

Još jedno rešenje je da napraviš svoju podršku za RTTI. Pogledaj, na primer, kako je to urađeno u idTech 4 engine-u (http://fabiensanglard.net/doom3/index.php).

Takođe, pogledaj Open and Efficient Type Switch for C++ (https://parasol.tamu.edu/~yuriys/pm/).

Ili, dodaj u hijerarhiju virtuelni metod koji pravi novi objekat istog tipa... npr:


struct Base
{
virtual Base* makeNewSameType(args...)
{
return new Base(args...);
}
};

struct Derived: public base
{
virtual Base* makeNewSameType(args...)
{
return new Derived(args...);
}
};

// sada možeš da uradiš ovako nešto
objekat->dodajKomponentu((*iter)->makeNewSameType(objekat));

Andross
24.3.2013, 12:03
E vidis to sa pomocnom metodom za pravljenje objekta istog tipa je super resenje. Znao sam da mogu da kastujem ko blesav, ali sam hteo da izbegnem gomilu if/else/case slucajeva sto bi bilo neizbezno kako broj komponenti raste :)

Geomaster
24.3.2013, 12:09
Gledaj da izbegavaš korišćenje typeid, dynamic_cast i sličnih stvari jer ako si ispravno isprojektao ceo objektno-orijentisani sistem nećeš imati nikakve potrebe za njima.

pivonroll
24.3.2013, 12:28
Moja preporuka bi samo bila da ga preimenujes iz
makeNewSameType
u
clone
jer je ovako mnogo lakse i recimo jasnije.

Belphegor
29.3.2013, 14:21
Andross, mozda ce te ova biblioteka interesovati entityx (https://github.com/alecthomas/entityx) , ako nisi do sad video? :)

Andross
29.3.2013, 15:07
Ima nekih zanimljivih stvari koje bih mogao da iskoristim, u principu zavrsio sam osnovu moje implementacije (pravljenje i update objekata) i glavna razlika je sto je moj sistem "self-attached" - sistem na osnovu atributa sam dodeljuje komponente objektima.

stepanov
29.3.2013, 22:18
koji IDE bi bio najbolji za programiranje striktno u c-u, u windows-u? kompajler na faxu je gcc...

voodoo_
29.3.2013, 22:31
http://orwelldevcpp.blogspot.com/

Mogu da se prave čisto C projekti.

stepanov
30.3.2013, 12:51
juce mi je skroz ok radio i kompajlirao i sve, a sad izbacuje error 216, kao da kompajlirani program koji pokusavam da pokrenem nije kompatibilan sa verzijom windows-a koju koristim... :/
EDIT: sada sam namestio u raznim opcijama sve na 32 gde god je moglo, a bilo na 64, pratci uputstva sa dna sajta, asada pokrene program, ne izbaci error, ali nakon dva ili tri unosa podataka i entera, windows izbaci program stoped working
inace skinuo sam TDM GCC...

voodoo_
30.3.2013, 23:44
Skini MinGW verziju.

Andross
29.4.2013, 13:21
Cenim da svi vec znate, ali dobro je podsetiti se (pogotovo kada se opecete) - Ne raditi stvari ovog tipa nikako:

for(int i = 0; i < nekaKlasa->getNekiDjavo().nekiParametar; ++i) // ili slicno
// stuff

Normalno nekiParametar bi strpali u lokalnu promenljivu i zavrsili posao, ali uvek se nadje trenutak kad se napravimo pametni pa to iz nekog razloga ne uradimo. Na ovom primeru sam osetio koliko je samo pozivanje funkcija skupo kada sam uspeo da raycaster koji mi je radio na nekih ~850FPS skucam na konstantnih 15 :kreza:

Belphegor
29.4.2013, 14:04
Ja sam 3 dana ludeo, cupao kosu trazeci jednu gresku i to sve na pogresnim mestima.

Trebao sam da koristim index ugnezdene petlje, ovako nesto je bilo:

for( i = 0; i < xCnt; ++i)
{
...// mnooogo linija
for( j = 0; j < yCnt; ++j)
{
vYItems[i].doSomeWork(); // ovde, znaci izbi oci trazeci
}
...
}


Sto je najgore broj Y objekata je veci od X tako da nije moglo ni da prsne zbog "index out of bounds" pa bih i otkrio ranije. Od sad nikad ne koristim 'i' i 'j' kao imena indexa osim u veoma malim ili non-nested petljama. :mad:

Geomaster
29.4.2013, 15:24
Na ovom primeru sam osetio koliko je samo pozivanje funkcija skupo kada sam uspeo da raycaster koji mi je radio na nekih ~850FPS skucam na konstantnih 15 :kreza:
Sve je okej dok funkcija nije virtuelna, veruj mi :D

Andross
2.5.2013, 14:59
Jel moze neko da mi objasni zasto je ovo (paznja na bold):

for(int y = drawBegin; y < drawEnd; ++y)
{
int index = ((drawEnd - y + drawBegin - 1) * m_ScreenWidth + x) * 3;

// Shift bits to factor out floats; shift only by 1 since we have one decimal precision (.5f)
int d = (y << 1) - m_ScreenHeight + lineHeight;
int texY = ((d * texHeight) / lineHeight) >> 1;
int texIndex = (texY * texWidth + texX) * 3;

int r = (*wallImg)[texIndex];
int g = (*wallImg)[texIndex + 1];
int b = (*wallImg)[texIndex + 2];

// Make y side darker
if(side)
{
r /= 2;
g /= 2;
b /= 2;
}

m_ScreenBuffer[index] = r;
m_ScreenBuffer[index + 1] = g;
m_ScreenBuffer[index + 2] = b;
}

Sporije od ovog (paznja na bold):

for(int y = drawBegin; y < drawEnd; ++y)
{
// Shift bits to factor out floats; shift only by 1 since we have one decimal precision (.5f)
int d = (y << 1) - m_ScreenHeight + lineHeight;
int texY = ((d * texHeight) / lineHeight) >> 1;
int texIndex = (texY * texWidth + texX) * 3;
int index = ((drawEnd - y + drawBegin - 1) * m_ScreenWidth + x) * 3;

int r = (*wallImg)[texIndex];
int g = (*wallImg)[texIndex + 1];
int b = (*wallImg)[texIndex + 2];

// Make y side darker
if(side)
{
r /= 2;
g /= 2;
b /= 2;
}

m_ScreenBuffer[index] = r;
m_ScreenBuffer[index + 1] = g;
m_ScreenBuffer[index + 2] = b;
}

Belphegor
2.5.2013, 15:29
Kako si ustanovio da je sporije?
Profilisao si u "Release mod-u", odnosno iskljucene su sve debug opcije vezane za kompajler koji koristis?

Andross
2.5.2013, 15:49
Release build, prvobitno ustanovio frapsom, 10 merenja i u svakom merenju je gornji kod davao ~4 fps-a manje, pa sam merio mikrosekunde za render (razlika vremena posle i pre render poziva) i gornjem kodu treba u proseku ~100 vise nego donjem.

NOTE: Ovo je deo rendera za zidove, ista situacija u loopu za pod/plafon.

Geomaster
2.5.2013, 15:56
Otvori preko nekog disasemblera oba fajla pa pogledaj šta se tačno generiše, ili postuj ovde. Jedno off pitanje – šta tačno ti radiš tu pa C++ kôdom prolaziš kroz color buffer?

Andross
2.5.2013, 16:14
Pokusao sam preko 2 dissasemblera (pvdasm i boomerang) i oba pucaju u sred dekompajliranja. Radim Raycaster, pa crtam po lokalnom baferu koji posle uploadujem preko glDrawPixels - te mi je svaki frejm bitan.

Geomaster
2.5.2013, 16:16
Pokusao sam preko 2 dissasemblera (pvdasm i boomerang) i oba pucaju u sred dekompajliranja. Radim Raycaster, pa crtam po lokalnom baferu koji posle uploadujem preko glDrawPixels - te mi je svaki frejm bitan.
Ah, raycaster, mislio sam da je neka realtime aplikacija. Ako koristiš Visual C++ uradi ovo (http://stackoverflow.com/questions/1020498/how-to-view-the-assembly-behind-the-code-using-visual-c) i onda jednostavno pogledaj šta je iza te linije kôda kao što već spomenuh.

Belphegor
2.5.2013, 16:23
Nemoj gledati na FPS. (http://www.mvps.org/directx/articles/fps_versus_frame_time.htm)

Andross
2.5.2013, 16:47
^Znam kako funkcionise to zato sam i merio frametime i razlika je u proseku 100 mikrosekundi, sto je smesno ali za ovakav tip aplikacije u jednom trenutku moze da znaci + sam overhead se stvara od redosleda nevezanih instrukcija.

@Geomaster: MinGW ali sam nasao da sacuva assembly u build logu pa kad procackam postujem. Takodje raycasting je realtime, verovatno si mislio na raytracing. Evo videa da vidis o cemu je stvar (ovo je najprimitivnija verzija raycastera, dosta za pocetak):

Ik-WQcCYJIA

Belphegor
2.5.2013, 17:07
Svidja mi se taj medieval Wolfenstein 3d. :)
Mozes da implementiras taj algo sa SIMD instrukcijama, mada ces onda morati malo i da promenis strukturu podataka.

Geomaster
2.5.2013, 17:17
Takodje raycasting je realtime, verovatno si mislio na raytracing.
Jes, sa pola mozga radim od jutros, pogodi zašto... Ali i dalje mi nije jasno zašto bi, ako već radiš kroz GPU, radio ovakvu stvar kada možeš to isto postići kroz shadere. Ali ajd', odo da odspavam pa kad se vratim pogledaću ponovo, možda shvatim :D

Andross
2.5.2013, 17:28
Ukratko svodi se na "bajanje zrakova" (lol) i crtanje vertikalnih linija, otvoricu temu uskoro pa vise tamo.

Posle rvanja sa GDB-om koji odbija da radi sto mu se zapoveda, poredjenjem citavog assembly koda (naravno alatom) sam dosao do zakljucka da se generise mov viska.

Geomaster
2.5.2013, 17:34
^ Da, ali koliko vidim ovo što si ti postovao opušteno može da se uradi u šejderu. Ili grešim?

Belphegor
2.5.2013, 18:59
^Naravno da moze, samo sto bi algo bio malo drugaciji i bilo bi dosta brze, ali to mu verovatno nije bila poenta projekta?

Lucic Nemanja
7.5.2013, 14:57
Imam jedan problem. U pitanju je kombinacija ugnežđavanja klasa i njihovo nasleđivanje. Dakle neka imam klasu:


class List
{
protected:
class Node
{
friend class List;
//implementacija cvora
};

// Node *first, *last itd....
public:

//neke metode za upravljanje listama
};



E sad, recimo da hoću da napravim novi tip liste koji bi bio identičan kao i prethodna samo sa različitom implementacijom čvora kako bih to mogao da izvedem?
Ono što mi pada na pamet i što bi bilo najelegantnije rešenje jeste da nasledim listu i napišem u izvedenoj listi novu ugneždenu klasu Node, a da ne menjam metode same klase. Da li bi onda one pri pozivu imena Node pristupale klasi Node ugneždenoj u izvedenoj ili u baznoj klasi? Npr. ako neka metoda poziva Node(); koji konstruktor bi zapravo bio pozvan?
I naravno, da li je uopšte moguće definisati klasu istog imena ako je već ugneždena u baznoj klasi?

Belphegor
7.5.2013, 18:05
Zar nije bolje u ovom slucaju da Node bude templejt parametar List-i?

template< typename Node >
class List
{...};
Ovako imas cist izbor implementacije Node-a bez "djubreta" u baznoj klasi (mislim ne treba ti ni nasledjivanje).
S'tim da su imena metoda Node-a ista koje pozivas sa List-om.?

Lucic Nemanja
8.5.2013, 22:42
Pišem kernel za neki projekat na faksu. Korišćenje templejta je previše high level za tako nešto. Generalno trebalo bi da se piše u C-u, ali kao eto da nam olakšaju pošto nam je prvo susretanje sa sistemskim softverom radimo u c++u da ne moramo sami da realizujemo tabele virtuelnih funkcija za neke podsisteme, da vučemo gomilu pokazivača na funkcije i sl. U pitanju je borland c++, procesor 8086. Dosta često mora da se pribegava i asembleru za neke stvari tako da je sama pomisao na template nekako neadekvatna u ovom kontekstu :kreza:. Ne znam čak ni da li bi moglo da se koristi, ali da, definitivno bi bilo elegantno da je u pitanu neki aplikativni softver.
Konkretno liste koristim da bih pamtio koje su mi niti spremne za rad, a koje blokirane. Kod blokiranih mi je potrebno još po neko dodatno polje u čvoru i da redefinišem po koju metodu, pa mi je nekako nasleđivanje prirodno palo na pamet. Ako ništa drugo, napisaću potpuno dve različite nezavisne klase, što bi funkcionalno i bilo bolje, ali eto... volim objektnu logiku :D. Mada kažu da se ne treba mnogo navikavati na nju u ovakvom softveru.

Patrick
14.5.2013, 0:25
Konkretno liste koristim da bih pamtio koje su mi niti spremne za rad, a koje blokirane. Kod blokiranih mi je potrebno još po neko dodatno polje u čvoru i da redefinišem po koju metodu, pa mi je nekako nasleđivanje prirodno palo na pamet. Ako ništa drugo, napisaću potpuno dve različite nezavisne klase, što bi funkcionalno i bilo bolje, ali eto... volim objektnu logiku :D. Mada kažu da se ne treba mnogo navikavati na nju u ovakvom softveru.

Rade u BCC-u templates, ali samo malo nesto drugacije treba da se napise, ne secam se sta je bilo u pitanju, al radili su ljudi s njima, ja sam ih izbego.
Nsam bas razumeo sto bi izvodio klasu posebno za spremne i blokirane niti? Sto ne stavis da imaju ista polja i metode (potpuno iste klase da su) a da imas jednu listu svih niti i pored toga listu onih koje spavaju, spremne ionako idu u Scheduler, a blokirane pamti onaj ko ih je blokirao (nesto tipa "lista onih koji cekaju na mene") i samo dodas polje status u Thread koje kaze da li je READY, BLOCKED, RUNNIG... za sve to ti treba jedna lista koja prihvata klasu niti.

Lucic Nemanja
14.5.2013, 19:44
Rade u BCC-u templates, ali samo malo nesto drugacije treba da se napise, ne secam se sta je bilo u pitanju, al radili su ljudi s njima, ja sam ih izbego.
Nsam bas razumeo sto bi izvodio klasu posebno za spremne i blokirane niti? Sto ne stavis da imaju ista polja i metode (potpuno iste klase da su) a da imas jednu listu svih niti i pored toga listu onih koje spavaju, spremne ionako idu u Scheduler, a blokirane pamti onaj ko ih je blokirao (nesto tipa "lista onih koji cekaju na mene") i samo dodas polje status u Thread koje kaze da li je READY, BLOCKED, RUNNIG... za sve to ti treba jedna lista koja prihvata klasu niti.

Plan mi i jeste da imam listu svih i listu uspavanih niti, samo što u listi uspavanih treba da postoji i polje za svaku nit koje govori koliko još vremena treba da bude blokirana u umnožcima od 55ms (perioda javljanja timer prekida). Kada dođe timer prekid treba da dekrementiram vreme od svake i proverim da li je došlo do nule na nekoj i ako jeste da je probudim. To polje mi je nepotrebno u listi svih niti, pa ono... U krajnjem slučaju mogu da iskoristim listu sa poljem vremena i u listi svih niti, ali da ga uopšte nekoristim.

Patrick
14.5.2013, 23:16
E, bas tako! Nista se ne sekiraj sto se to polje nece koristiti osim kad nit ne spava. To je zanemarljivo. Ako ces da vodis racuna o resursima, pre svega o vremenu, onda ne zaboravi da listu niti koje spavaju odrzavas sortiranom kad god ubacujes neku novu nit u tu listu i tako da ti nit koja prva treba da se probudi bude na pocetku liste i ima to polje jos koliko joj je ostalo da spava i SAMO njega dekrementiras kad god ti otkuca tajmer, a za ostale niti pamtis u tom istom polju vremensku RAZLIKU u odnosu na ovu nit sa pocetka liste... pretpostavljam da si vec video negde slican algoritam i da znas na sta mislimm... :) To ce da bude bas efikasnije jer neces svaki otkucaj tajmera da prolazis kroz celu listu i da dekrementiras intervale, niti da proveravas da li je svaka dosla do nule, nego samo da li je prva dosla do nule i nikako ne zaboravi da ako jeste nula, proveris i da li su one do nje isto na nuli jer ako su imale isti period spavanja kao prva nit, onda ce njihova razlika u spavanju da bude isto nula pa i njih probudi.

Srecno!

Lucic Nemanja
15.5.2013, 1:38
Da, da, već sam obavešten na vreme o tom algoritmu :D. Hvala u svakom slučaju!

sistavac
25.5.2013, 16:10
Pozdrav, totalni sam pocetnik, od juce sam poceo da istrazujem c++ i uz pomoc interneta poceo sam da shvatam neke osnovne komande itd itd, i sad pokusavam da napravim program koji ce mi proveriti da li je broj koji unesem deljiv sa 2 ili nije, pa mi ne ide.. Ako moze neko da ispise kod na brzinu verujem da nije slozen postupak za vas znalce.
Pravim proste programe za izracunavanje, ispisivanje testa, isprobavam neke moje gluposti sa if, if else, svim tim kombinacijama ali nesto slozenije ne mogu da uradim.
I ako neko zna neki sajt sa pocetnickim problemima za resavanje i zadacima za vezbanje, prostim tutorijalima c++, ili pak ima neki savet za napredovanje u c++ bio bih zahvalan da okaci i podeli sa nama neznalcima.
Hvala

Andross
25.5.2013, 16:14
http://www.cprogramming.com/tutorial/modulus.html

Sinisa Cubrilo
2.6.2013, 9:59
//Napisati funkciju koja kao parametre ima dva niza znakova i kopira prvi u drugi
#include <string.h>
#include <iostream>
#include "stdafx.h"
#define MAX 50

void kopiranje (char prvi[], char drugi[])
{
int i=0;
while(prvi[i])
{
drugi[i]=prvi[i];
i++;
}
drugi[i]='\0';
}
void main()
{
int i=0, c;
char prvi[MAX], drugi [MAX];
printf("Unesite niz karaktera:");
c=getchar();
while(c!=EOF && i<MAX){
prvi[i]=c;
i++;
c=getchar();
}
prvi[i]='\0';
kopiranje(prvi,drugi);
printf("\nprvi: %s\n\ndrugi: %s", prvi, drugi);
system("pause");

}


Kada pokrenem program, unesem niz karaktera ali mi ne kopira jedan u drugi, vec mi prikaze isto ono sto sam i uneo. Gde je greska? :confused:

Belphegor
2.6.2013, 11:27
while(c != EOF && i < MAX) {
...
}
prvi[i] = '\0'; // overflow
U ovom primeru moze da ti se desi da i bude MAX pa onda nemas mesta za '\0'.

Najsigurnije ti je da uradis unos sa fgets funkcijom:

fgets(prvi, MAX, stdin);

Sinisa Cubrilo
2.6.2013, 12:03
A to ubacujem gde tacno?

Belphegor
2.6.2013, 12:23
U serious? :eek:
Koji deo koda ti je relevantan za unos u prvi niz?

Sinisa Cubrilo
2.6.2013, 12:46
U serious? :eek:
Koji deo koda ti je relevantan za unos u prvi niz?

printf("Unesite niz karaktera:");
c=getchar();
while(c!=EOF && i<MAX){
prvi[i]=c;
i++;
c=getchar();
}

Valjda?

P.s. nemoj zameriti, jako slabo znam c++

Belphegor
2.6.2013, 13:12
Moras ovo resiti sam. Idi liniju po liniju kroz kod i zapitaj se za svaku pojedinacno zasto ti treba.

Lucic Nemanja
2.6.2013, 14:50
//Napisati funkciju koja kao parametre ima dva niza znakova i kopira prvi u drugi
#include <string.h>
#include <iostream>
#include "stdafx.h"
#define MAX 50

void kopiranje (char prvi[], char drugi[])
{
int i=0;
while(prvi[i])
{
drugi[i]=prvi[i];
i++;
}
drugi[i]='\0';
}
void main()
{
int i=0, c;
char prvi[MAX], drugi [MAX];
printf("Unesite niz karaktera:");
c=getchar();
while(c!=EOF && i<MAX){
prvi[i]=c;
i++;
c=getchar();
}
prvi[i]='\0';
kopiranje(prvi,drugi);
printf("\nprvi: %s\n\ndrugi: %s", prvi, drugi);
system("pause");

}


Kada pokrenem program, unesem niz karaktera ali mi ne kopira jedan u drugi, vec mi prikaze isto ono sto sam i uneo. Gde je greska? :confused:

U uslovu za unos ti treba c != '\n', a ne EOF. Problem je što ti kada unosiš niz znakova na standardnom ulazu između ostalog pritisneš enter da bi mu naznačio da završavaš sa unosom. I taj enter se pamti kao i svako drugo slovo koje napišeš, i to kao simbol za novi red. Recimo da uneseš niz znakova "Neki string", on će ti biti u memoriji zapisan kao "Neki string\n". Dakle koristiš novi red kao indikator kraja niza :).

Twisterzemun
24.6.2013, 11:51
jel moze neko da mi pokaze kako ovaj deo koda: posl = (!prvi ? prvi : posl->sled) = novi;moze da se napise preko if-a?

mislim da je ovako, ali nisam siguran:
if(!prvi)
posl=prvi=novi;
else
posl=posl->sled=novi;

irreal
24.6.2013, 12:10
da, pravilno si napisao.

bitno je i da shvatis sta tu pise.

kod prvo proverava da li postoji prvi element liste.
(prvi je pokazivac ka elementu liste)

ako ne postoji ni jedan element, znaci da je lista prazna i da je taj objekat koji upravo dodajes u stvari prvi objekat.

u tom slucaju prvi = novi, jer smo dodali prvi

a ako nije prvi, nego vec imamo neki koji je u listi, onda na taj koji je DO SADA bio poslednji, dodamo da je ovaj koji ubacujemo sledeci.


dakle, ako imamo vec poslednji (nije prazna lista) onda radimo poslednji->sled = novi.


i na kraju, bez obzira da li si novi element dodao u praznu listu ili u listu koja vec ima clanove, svakako ce taj novi biti i poslednji, jer je poslednji ubacen.



mozda ti je jasnije ako se napise ovako:

if (!prvi) {
prvi = novi;
}
else
{
poslednji->sled = novi;
}

//ovo je izbaceno napolje jer se svakako izvrsava:
poslednji = novi;


P.S.
pozdravi mi lasla :D

Twisterzemun
24.6.2013, 12:38
P.S.
pozdravi mi lasla :D

:tapsh:
hahahahaha, kako si znao?

irreal
24.6.2013, 15:14
samo bi klaslo rado spakovao 8 linija u jednu sa ternary if operatorom na kolokvijumima i domacim zadacima studentima koji tek uce c++ :)

Geomaster
24.6.2013, 15:33
Klaslo? Haha, priceless.
Inače, zašto

posl = (!prvi ? prvi : posl->sled) = novi;
kad možeposl = (prvi ? posl->sled : prvi) = novi;Jel on to pokušava da isteroriše ljude?

irreal
24.6.2013, 15:40
Uradio sam dosta kolokvijuma i domacih zadataka, (i ako licno nikada u zivotu nisam bio student kod klasla, ali dosta drugara jeste) i jos uvek ne mogu da se odlucim da li pokusava odmah da nauci studente efikasno i kvalitetno ili pokusava da im zagorca zivot.

tanka je linija tu, a on balansira po njoj :)


npr, u ovom slucaju, zamka je u tome sto je "prvi" naravno pointer ka clanu liste i postoji van konteksta ove funkcije (koja inace dodaje novi element u listu). Pocetnik u programiranju moze da procita
if (prvi) { }
i da pomisli da se taj kod izvrsava ako se trenutno dodaje prvi element, ne primecujuci da zapravo (!prvi) znaci da prvi dodajemo, jer prvi do sada nije ni postojao.

za pocetnike definitivno mala zamka kad se cita ako se ne razmisli dobro.

mislim da je obrnuo upravo da bi prvi deo if bloka bio slucaj kada jeste prvi a drugi kada nije.

Opet, ne znam kolko ce studenata razumeti zasto je to tako, a kolko cujem asistenti na predavanjima nisu od velike pomoci niti velikog razumevanja.

Greota...


Inace, kako drugacije, Laslo Kraus - Klaslo :D

Twisterzemun
24.6.2013, 16:17
Пројектовати и реализовати на језику c++ следеће класе:

Генерички низ може да садржи задат број података неког типа. Може да се дохвати капацитет низа, број попуњених места и податак задатог редног броја, да се ставља податак на прво слободно место, да се капацитет низа повећа за задат број места и да се низ упише у излазни ток. Ову класу треба користити за ускладиштавање скупова података у каснијим класама и доноси 10 бонус поена преко номиналних 100.

Предмет има једнословну ознаку врсте предмета. Може да се одреди запремина и тежина предмета, да се направи полиморфна копија предмета, да се испита да ли су два предмета једнака и да се предмет упише у излазни ток. Пише се ознака врсте предмета.

Тело је хомоген предмет одређене специфичне тежине. У излазни ток се пишу ознака врсте предмета и специфична тежина тела.

Сфера, ваљак и купа су тела. У излазни ток се пишу ознака врсте, специфична тежина и димензије.

Склоп је предмет састављен од произвољног броја предмета произвољне врсте. Ствара се празан, после чега предмети се додају појединачно. У излазни ток се пишу подаци о садржаним предметима.

Складиште може да садржи задат број предмета до задате укупне запремине и тежине. Предмети се стављају појединачно на прво слободно место. Може да се извади први предмет који је једнак задатом предмету као узорку. Списак садржаних предмета може да се упише у излазни ток.

Радник има име. Сви радници морају да имају различита имена. Не сме да се прави копија радника. Радник може да производи предмет копирањем задатог предмета и да га одмах стави у задато складиште (предмет и складиште се не задају у моменту производње). Предмет чија копија се прави и складиште у које се копија ставља може да се промени.

У радионици може бити запошљен задат број радника, садржи једно складиште и низ предмета који се користе као оригинали за производњу. Број радних места, величина складишта и низ предмета за производњу задају се приликом стварања радионице. Може да се запосли радник на прво слободно радно место, да се радник са задатим именом отпушта, да му се придружи предмет чије копије треба да производи и складиште у које треба да ставља своје производе. Може да се продаје предмет из складишта који је једнак задатом узорку. Сви подаци о радионици (списак запослених раднинка, списак предмета које производи и садржај складишта) могу да се упишу у излазни ток.
-------------------------------------------------------------
Ovo je domaci zadatak kod Klasla iz Objektnog Programiranja 1. Ja sam dosao do skladista, i imam problem sa dodavanjem, oduzimanjem i ispisivanjem skladista, izbacuje mi gresku: http://www.dodaj.rs/t/e/do/3sQJYsPH/untitled.jpg (http://www.dodaj.rs/?e/do/3sQJYsPH/untitled.png) i ceo dan pokusavam da sredim ovo i ne ide, zato molim za pomoc.

Twisterzemun
24.6.2013, 16:18
skladiste.h
#ifndef _SKLADISTE_H_
#define _SKLADISTE_H_
#include <iostream>
#include "predmet.h"
#include "tela.h"
#include "greske.h"
using namespace std;

class skladiste
{
predmet** niz;
int kap;
double V;
double Q;
double currV;
double currQ;
public:
skladiste(double V,double Q,int k);
skladiste(skladiste& s)
{
kap=s.kap;
V=s.V;
Q=s.Q;
for(int i=0;i<s.kap;i++)
{
niz[i]=s.niz[i];
}
}
~skladiste();
skladiste& operator+=(predmet& p);
predmet* uzmi(predmet& pp);
skladiste& operator-=(predmet& p);
friend ostream& operator<<(ostream& o, skladiste& s);
};

#endif
skladiste.cpp
#include <iostream>
#include "skladiste.h"
#include "predmet.h"
#include "tela.h"
using namespace std;

skladiste::skladiste(double V,double Q, int k)
{
niz=new predmet*[kap=k];
for(int i=0;i<kap;i++)
niz[i]=0;
this->V=V;
this->Q=Q;
currV=0;
}

skladiste::~skladiste()
{
for(int i=0;i<kap;i++)
delete niz[i];
}

skladiste& skladiste::operator+=(predmet& p)
{
if((currV + p.V())>V)
throw("\n***Prekoracenje Zapremine!!!***");
if((currQ + p.Q())>Q)
throw("\n***Prekoracenje Tezine!!!***");
int i = 0;
while (i<kap && niz[i])
i++;
if(i==kap)
throw("\n***Prekoracenje kapaciteta!!!***");
niz[i]=&p;
currV+=p.V();
currQ+=p.Q();
return *this;
}
predmet* skladiste::uzmi(predmet& pp)
{
int i=0;
while (i<kap && (!niz[i] || !niz[i]->isti(pp)))
i++;
if(i==kap)
throw("\n***Nema tog predmeta u skladistu!!!***");
predmet* p=niz[i];
niz[i]=0;
currV-=p->V();
currQ-=p->Q();
return p;
}
skladiste& skladiste::operator-=(predmet& p)
{
skladiste::uzmi(p);
return *this;
}
ostream& operator<<(ostream& o, skladiste& s)
{
for(int i=0;i<s.kap;i++)
o<<*s.niz[i]<<endl;
return o;
}

V je ukupna zapremina skladista, Q je ukupna tezina skladista, currV je trenutna zapremina, a currQ je trenutna tezina. kap je kapacitet niza.

Belphegor
24.6.2013, 17:28
Mrzi me da detaljisem pa cu u kratkim crtama reci ono sto vidim da ne valja

1. Pogresno alociras niz. 'si siguran da ti ne treba 1d niz?
How do I declare a 2d... (http://stackoverflow.com/questions/936687/how-do-i-declare-a-2d-array-in-c-using-new)
2. Ne valja ti kopi konstruktor, treba prvo da alociras prostor pre nego kopiras u niz.
3. Dodaj proveru da ne kopiras isti objekat (self assignment).
4. Koliko vidim nijedna metoda nije const-correct (http://www.parashift.com/c++-faq/const-correctness.html).
5. Koristi debugger, assert funkciju, postavi koji breakpoint...

Twisterzemun
24.6.2013, 17:49
Mrzi me da detaljisem pa cu u kratkim crtama reci ono sto vidim da ne valja

1. Pogresno alociras niz. 'si siguran da ti ne treba 1d niz?
How do I declare a 2d... (http://stackoverflow.com/questions/936687/how-do-i-declare-a-2d-array-in-c-using-new)
2. Ne valja ti kopi konstruktor, treba prvo da alociras prostor pre nego kopiras u niz.
3. Dodaj proveru da ne kopiras isti objekat (self assignment).
4. Koliko vidim nijedna metoda nije const-correct (http://www.parashift.com/c++-faq/const-correctness.html).
5. Koristi debugger, assert funkciju, postavi koji breakpoint...

Izgleda da je najveci problem kod mene bio do visual studija(ili zbog toga sto nisam radio const-correctness?). Uglavnom i pored toga sto sam alocirao memoriju kod konstruktora kopije i dalje nije hteo da radi program. Onda sam drugaru poslao projekat, on je kod sebe na windowsu 7 kompajlirao i sve je najnormalnije radilo. Poslao mi je njegov projekat sa windows-a 7 i sad i kod mene na xp-u radi kako treba. Jel zna neko zbog cega se ovakvi problemi desavaju?

1. Pogresno alociras niz. 'si siguran da ti ne treba 1d niz?
to sam deklarisao 1d niz pokazivaca tipa predmet, ako si na to mislio

Geomaster
24.6.2013, 18:32
Može jako često da se desi da slučajno radi kako treba, ali to nikako nije dobar znak. Ako ti program bez ikakvih promena prvo ne radi pa radi, to je znak da postoji problem.

Twisterzemun
24.6.2013, 19:15
Može jako često da se desi da slučajno radi kako treba, ali to nikako nije dobar znak. Ako ti program bez ikakvih promena prvo ne radi pa radi, to je znak da postoji problem.

Problem je jos bio u klasi za greske, kada npr prekoracim zapreminu ili tezinu skladista nece da mi izbaci poruku koju sam napisao da izbaci nego samo izbaci abort() i to je to, u tome je isto bio problem.

abcdefgh
7.7.2013, 16:30
Ukoliko zelis nauciti C/C++ mozes pogledati i ovaj uvod>

www.scribd.com/duskoKoscica

Kompletno besplatno.

laki1991
2.10.2013, 23:35
Da li je Dev-C++ dobar za koriscenje kao pocetniku ?

pivonroll
3.10.2013, 0:00
Ja preferiram Qt Creator.

Geomaster
3.10.2013, 0:30
^ Takođe. Još jedan jak glas za Qt Creator. Keva je.

mojdezanin
6.10.2013, 7:39
Juce sam ovo otkucao , problem je sto mi prijavljuje da nakon kreiranja objekta u main-u pomocu Complex klase , izbacuje mi da prije navodjenja imena objekta stavim tacka zarez , tj. ne mogu da kreiram objekat.

#include <iostream>
#include <Complex.h>
#include <Time.h>


using namespace std;
int main()
{

Complex c1;
Complex c2;
c1.setData(5,6);
c2.setData(8,7);
c1.print();
c2.print();



return 0;
}

i Complex.h

#include <iostream>

class Complex
{
private:
float re;
float im;
public:
void setData( float r , float i)
{
im = i;
re = r;

}

void print()
{
cout<<"Imaginarni dio je :"<<im<<"Realni dio je :"<<re<<endl;
}

};

Nisam isao da kucam u .cpp dio u .h , to cu poslje ovoga , vjerovatno sam ja napravio vise gresaka ako neko ima vremena da mi ukaze na njih bio bih zahvalan.

chaami
6.10.2013, 8:50
#include <Complex.h> // sa ovim si uključio header koji se nalazi u include direktorijumu kompajlera. Stavi Complex.h u navodnike

#include "Complex.h"

mojdezanin
6.10.2013, 11:41
To je to , zahvaljujem . :D

voodoo_
6.10.2013, 19:35
Je l Qt Creator traži da se Gcc/Mingw instalira odvojeno ili dolazi u paketu?

pivonroll
6.10.2013, 22:21
Qt Creator je IDE. MinGW, GCC, CL itd su kompajleri.

Andross
6.10.2013, 23:00
Dal je moguce :kreza:

pivonroll
6.10.2013, 23:09
Ako to zna onda ne treba da pita :kreza::kreza::kreza::kreza::kreza::kreza: