Důležité je to, aby každý header měl v sobě všechno, co potřebuje. To znamená, že by neměl být požadován jiný include před tímto headerem.
Výjimkou může být nějaká globální konfigurace, která se podle nějaké projektové konvence vždy includuje jako první. Další výjimkou je generický header, kterému se nadefinují nějaké symboly preprocesoru a pak se ten header includne, čímž se vygeneruje kus kódu. To se používá více v C než v C++, i když některé věci nejdou jinak obejít ani v C++.
Všechno by to ale měly být dobře zdokumentované výjimky a nemělo by jich být moc (aby zůstaly skutečně vyjímečné).
Příspěvky odeslané z IP adresy 194.138.12.–
Je potřeba si ujasnit, v jakém jazyce ten program je. Pokud se jedná o C, je třeba použít gcc. Pokud je to C++, používá se g++ (jde to sice i s gcc, ale není to tak triviální).
V případě překladu VisualC bych si dal pozor na to, jestli tam někde není nastavené, že všechno se překládá jako C++.
Pak už jenom zbývá uvědomit si, že
- struct zaznam a zaznam jsou v C různé typy (pokud to není typedefované na sebe)
- C++ je typově citlivější, takže výsledek malloc je třeba přetypovat na ukazatel na správný typ. Takže
int* x = malloc(sizeof(int) * 10);
Je správně v C, ale špatně v C++.
Pokud používáte C++, přikláním se k radě někoho výše - použít new a pro uvolnění delete.
Důležité je také řešit takový problém, který lze paralelizovat. Pokud se jedná o nějaký z principu sekvenční problém, tak nepomůže ani stojádrový procesor. Pokud se jedná o drobné neparalelizovatelné úlohy, kterých je větší množství, je obvykle jednodušší nechat dílčí úlohy jednovláknové a spouštět jich více najednou. Prostě něco na způsob
make -j 4
. Takže pokud například překódovávám 20 WAVů do MP3 a mám dvoujádrový procesor, je dobré spouštět aspoň dvě úlohy paraleleně. U překladu větších projektů se někde doporučovalo překládání v N+1 paralelních větvích, kde N je počet procesorů/jader. To +1 bylo z důvodu, že při čtení z disku může běžet i jiná aplikace a není nutné, aby ta čtoucí zablokovala celý procesor (ano, jsou OS, kde to takto skutečně funguje).
Pokud je zpracovávána nějaká úloha skutečně vícevláknově, je třeba si dát velký pozor na správnou synchronizaci a zároveň tu synchronizaci udělat tak, aby zůstal čas i na vlastní výpočet (aby se prostě jenom nesychronizovalo). Napsat a odladit takovou aplikaci je mnohem komplikovanější než napsat jednovláknovou. Chybu dost často není možné najít jinak, než čtením a analyzováním kódu. Chce to dost kázně.
Jinak si myslím, že v dnešní době už přibývá aplikací, které umějí více procesorů využít - např. střižny videa, různé překódovávače (tam se to vyloženě nabízí), programy na řešení velkých soustav rovnic apod.
Ono také záleží na tom, jak se to použití iterátorů napíše. Např. po výměně std::swap za std::iter_swap už to v mém případě (na std::vector<int>) běží rychleji s iterátory:
template <typename T>
void straightSelectionSort2(const T& begin, const T& end)
{
if (begin == end)
return;
// i je ukazatel na první položku nesetříděné části
for (T i = begin; i != end - 1; ++i)
{
T min = i;
// je je ukazatel na položku, se kterou se porovnává
for (T j = i + 1; j != end; ++j)
if (*j < *min)
min = j;
if (*min != *i)
std::iter_swap(min, i);
}
}
Ale stejně bych to napsal takto:#include <algorithm>
template <typename T>
void straightSelectionSort3(const T& begin, const T& end)
{
if (begin == end)
return;
// i je ukazatel na první položku nesetříděné části
for (T i = begin; i != end - 1; ++i)
{
std::iter_swap(i, std::min_element(i, end));
}
}
Při rozhodování o tom, jestli udělat tu výměnu vždy nebo tam nechat tu podmínku může záležet i na tom, co je obsahem kontejneru. Někdy je lepší tam nechat tu podmínku a někdy to prohodit vždy bez podmínky.
To zonda : string nezná, protože je to definováno v namespace std. Takže tam napiš std::string. A taky se hodí #include <string>
Jestli to chceš ve visual studiu, tak zkus toto:
#include <iostream>
#include <locale>
#include <locale.h>
int main()
{
setlocale(LC_ALL, "");
std::wcout.imbue(std::locale(""));
std::wcout << L"Příliš žluťoučký kůň úpěl ďábelské ódy\n";
}
1. možnost: Musíš ho mít nadeklarované venku jako globální a v té funkci ho jenom nainicializuješ.
2. možnost: Vytvoříš ho dynamicky přes new/malloc a vrátíš jako návratovou hodnotu nebo přes parametr
3. Možnost: Uděláš ho uvnitř funkce jako static a vrátíš ukazatel na něj. Takové pole je vlastně globální (zůstane stejné i po opuštění funkce), akorát není z venku funkce vidět. Ale pokud ta funkce vrátí nějaký ukazatel na takovou proměnnou, může si s tím každý dělat co chce i z venku.
To Anonymní uživatel : No vida, jak se to vložilo napoprvé, i když jako anonym.
To Clicker na klavesu : No nevím nevím, jsou tam dva nedeklarované identifikátory: click a window_close.
system("cls") bude někdy fungovat na windows. Obecně určitě ne.
Problém toho getch je taky v tom, že to nejspíš dostane až ve chvíli, kdy uživatel odentruje celý řádek.
I kdyby to fungovalo, tak to cls může být natolik pomalé, že ten napsaný znak stejně bude (chvilku) vidět.
A pořád to neřeší případ, kdy standardní vstup programu nebude klávesnice.
Zázrak - příspěvek se vložil. Tak tedy popis jako anonym (podotýkám, že jsem pořád přihlášený):
Takže jsou tam 4 varianty. Vybírá se mezi nimi přes define na řádku 7.
První varianta je zhovadilost, kterou nedoporučuji kvůli tomu přetypování. Možná pro nějaké malé triviální třídy by to bylo použitelné.
Druhá varianta je v pohodě z pohledu STL. Nepočítal bych ale moc s tím, že to pojede i ve Visual C++. Možná v nějaké nové verzi nebo s STL portem. To nemám vyzkoušené.
3. a 4. varianta jsou mými favority. Využívají boost. Jsou jasně čitelné (i když vypadají tak trošku magicky) a je hned jasné, co tím programátor myslel.
Ten cyklus nastavuje všechny znaky v řetězci p na indexech i až n na znak '\0'. Vzhledem k tomu, že se vždy i rovná tomu n, tak je ten while cyklus zbytečný a stačilo by ho nahradit
p[n] = '\0'
Jo, vložil to anonym. Ale jaktože přihlášený uživatel musí odpovídat na ty dotazy pod příspěvkem (že nespamuje apod.), ale nepřihlášený nemusí? Něco tady hrubě nefunguje...
- Na řádku 43 je špatně nspsané číslo - má tam být desetinná tečka, ne čárka.
- Na řádku 48 se neporovnává pocetpolozek s nulou, ale přiřazuje se nula do pocetpolozek (chybí tam jedno rovnítko). Takže pocetpolozek se vynuluje, výsledek je nula, podmínka tedy není splněna a přejde se do else větve.
- Řádek 53 je zbytečný
Jak otevíráš ty streamy pro zápis a jak pro čtení? Jsou opravdu obě varianty otevřeny v binárním modu? Pokud aspoň jeden z nich není a zkoušíš to na windows, tak to nepojede.
Pro metodu name() od typeid není ve standardu definováno, co musí vracet. Že je to nějaký unikátní název je jenom doporučení. Takže pokud bude překladač vracet prázdný řetězec, tak je to pořád v pořádku (pominu diskuse, k čemu ta metoda pak je).
Takže buď porovnat jedno typeid s druhým (jak má na konci funkce fun nikto, nebo použít dynamic_cast. Tím se sice neodhalí konkrétní instance, ale většinou to stačí.
Nějaké GUI ve wxWidgets lze docela dobře naklikat i v Code::Blocks v pluginu wxSmith.
Obecně to stejné není. Takže se používá obojí, podle potřeby. Záleží na tom, co je v těch podmínkách.
To jouda :
Operátor and je v C++ ekvivalentem &&. Je to zcela standardní záležitost (i když jsem to moc použité nikde neviděl). V některých překladačích se to musí extra zapnout, ale to není chyba C++. Je možné např. přetížit operátor && a pak ho používat jako and nebo obráceně. Nevím sice, k čemu je toto rozdvojení dobré, ale to je jiná věc.
exit prasácké není. Prostě to ukončí program s exit codem, který se tomu předá v parametru (a je jedno, jestli je program zrovna v nějaké funkci nebo v main()). Záleží samozřejmě na tom, jestli je úmyslem při chybě hned ukončovat celý program nebo dělat nějaké zotavení z té chyby.
Jestli to není třeba hodnota EXIT_FAILURE.
Jo, vlož to jako pole bajtů, např.:
static const char* efile = "\xFF\x56\xFA";