#14 vitamin
Pochopil jsem, že jsem to v podstatě pochopil.
Příspěvky odeslané z IP adresy 89.103.156.–
#5 vitamin
To, že se n-krát volá konstruktor, souvisí s tou neměnnou velikostí. Operátor = má každá třída přetížená defaultně a to tak že provádí mělkou kopii, pokud toto nevyhovuje a nechceš či nemůžeš operátor přetížit, pak bys musel do stacku ukládat pouze adresy objektů nebo reference na ně. Co se týče zbytečných kopií v Push a Pop, tak to máš pravdu, mélo by tam být:
void Push(const type &) throw(const char*);
const type & Pop() throw(const char*);
template <typename type, int n>
class Stack //sablona tridy Stack, n urcuje pocet prvku
{
private:
type stackArray[n]; //pole stacku
type* stackPointer; //ukazatel na vrchol stacku, resp. na prvek do ktereho bude ulozena dalsi hodnota
public:
Stack(){stackPointer = stackArray;} //konstruktor nastavujici stackPointer na zacatek stacku
bool IsEmpty(){return stackPointer == stackArray;} //vraci true pokud je stack prazdny
bool IsFull(){return stackPointer == stackArray + n;} //vraci true pokud je stack plny
void Push(type) throw(const char*); //prida prvek na vrchol stacku
type Pop() throw(const char*); //odebere prvek z vrcholu stacku a vrati jeho hodnotu
};
template <typename type, int n>
void Stack<type,n>::Push(type val) throw(const char*) //prida prvek na vrchol stacku
{
if(IsFull())
throw "The stack is full."; //pokud je stack plny vyhodi vyjimku typu const char*
*stackPointer = val; //zkopíruje val na místo kam ukazuje stackPointer
stackPointer++; //posune stackPointer o jeden prvek smerem k vrcholu
}
template <typename type, int n>
type Stack<type,n>::Pop() throw(const char*) //odebere prvek z vrcholu stacku a vrati jeho hodnotu
{
if(IsEmpty())
throw "The stack is empty."; //pokud je stack prazdny vyhodi vyjimku typu const char*
stackPointer--; //posune stackPointer o jeden prvek smerem k zacatku
return *stackPointer; //vrati vrati prvek ktery byl odebran
}
Stačí nějak takhle?
Nestačilo by operator [] přetížit jednou tak, aby vracel pointer? S pointerem pak půjde podruhé tento operátor použít normálně.
class CMatrix
{
public:
double ** pole;
int delka_X, delka_Y;
double* operator[](int i){return pole[i];}
CMatrix(int,int);
};
CMatrix::CMatrix(int x, int y)
{
pole = new double*[x];
for(int i = 0; i < x; i++)
pole[i] = new double[y];
for(int i = 0; i < x; i++)
for(int j = 0; j < y; j++)
pole[i][j] = 0;
}
int main()
{
const int x = 6;
const int y = 4;
CMatrix matrix = CMatrix(x,y);
matrix[0][0] = 4;
matrix[4][2] = 7;
matrix[5][3] = 1;
for(int i = 0; i < y; i++)
{
for(int j = 0; j < x; j++)
cout<<matrix[j][i];
cout<<endl;
}
getchar();
Mimochodem, ten tvůj konstruktor fungoval nějak divně, tak jsem tam udělal svůj.
#3 Dejv
Metoda Name třídy CIterator má ten řetězec vracet, ne vypisovat.
V metodě zapis třídy neco2, musíš pointeru bla přiřadit adresu (CIterator* bla = new CIterator;) a na konci musíš ten pointer vrátir (return bla;).
Pak ještě třída CIterator by měla mít destruktor dealokující paměť (~CIterator(){delete [] struktura;}).
#10 vitamin
#9 KIIV
Tam o ten kód ani tak moc nejde, ten rozdíl v rychlosti platí všeobecně, já sem to jenom testoval konkrétně na quick sortu, ale stejný výsledek bude třeba u nějaké dlouhé smyčky která ani nic nedělá. Nebo třeba jenom deklaruje proměnnou, kdyby nic nedělala tak je dost možné že jí kompilátor přeskočí.
#6 vitamin
Jsou kompatibilní s Céčkovými knihovnami které dost používám. Psal jsem to hlavně proto abych se na tom pořádně naučil jak fungujou třídy, šablony a přetěžování operátorů, pak jsem do toho tak nějak pořád přidával věci a když to funguje tak proč to nepoužívat. STL nepoužívam, zatim jsem jí nikdy nepotřeboval a třeba standardní třída string se mi moc nelíbí, kvuli tomu jsem s tím částečně začal, chtěl jsem si napsat vlastní třídu pro práci s řetězci, takovou která bude umět třeba i zpracovat wxString z wxWidgets, abych si nemusel pamatovat její metody (pro wx mám jinou verzi). Všechny ty 4 třídy jsou kompatibilní mezi sebou a fungujou tak jak mě to vyhovuje. Až na List která je při velkém počtu prvků poněkud pomalá, ale tak dlouhej List jsem snad nikdy nepoužil.
#4 Tom
Výsledný kód vypadá takhle:
#include <iostream>
#include "C++ Basics/Basics.hpp"
using namespace std;
using namespace Basics;
int main()
{
Array<double> arr(10000000);
for(int i=0;&arr[i];i++)
arr[i] = rand() % 100;
arr.sort();
cout<<"...";
getchar();
}
A potřebuješ ve stejné složce mít tohle:
http://leteckaposta.cz/434137979
Je to jakási moje vlastní knihovna.
Zdravím, mám čistě technickou otázku. Čím to je že stejný algoritmus mi při zkompilování v různých prostředích běží různě rychle? Zkoušel jsem to na quick sortu pole o 10 milionech prvků. Dev-Cpp - 3 vteřiny, Code::Blocks - 6 vteřin, VS2010 - 9 vteřin (cca stejně jako Java v NetBeans). Optimalizaci mám u všech nastavenou na maximální rychlost. U VS ta optimalizace nebyla znát vůbec, u Code::Blocks trochu a u Dev-Cpp hrozně moc (před ní cca 12 vteřin). Jenom mě zajímá jestli je to kompilátorem a nebo jestli je ještě něco co se u VS a Code::Blocks dá nastavit aby se rychlost zvedla. Ne že bych to potřeboval ale zajímá mě to.
#4 ingiraxo
ten String sem dělal už dávno a tak průběžně do něj přidávam co potřebuju, mam takových tříd víc, tvořim si takovou vlastní knihovnu. Používat na tyhle věci standradní knihovny mě nebaví, tak bych se nic nenaučil a takhe si aspoň můžu tu třídu vytvořit podle toho jak to mě vyhovuje. Řekl bych že psaním podobných knihoven se člověk nejlíp naučí jak v C++ fungujou třídy a když už jsem to napsal tak proč to i nepoužívat když to funguje.
#1 ingiraxo
Já sem to upravení řetězce vyřešil takhle:
#include <iostream>
#include "String.hpp"
using namespace std;
using namespace Basics;
int main()
{
String str = "jedno.slovo";
for(int i=0;i<str.get_length();i++)
if(str[i] == '.')
{
String temp;
temp.reserve(strlen((const char*)&str[i+1]));
strcpy((char*)temp, (const char*)&str[i+1]);
str[i+1] = '\0';
if((int)temp[0] >= 97 && (int)temp[0] <= 122)
temp[0] -= 32;
str += (String)" " + temp;
}
cout<<str;
getchar();
}
...ale použil jsem k tomu svojí vlastní třídu String. Kdybys jí chtěl, tak si ji můžeš stáhnout tady:
#8 Ondra
Najdi si tutorial na youtube
http://www.youtube.com/watch?… - z tohohle sem se to učil já, akorát to má hroznej zvuk
Dobrý den.Nevíte někdo jak nainstalovat knihovnu Boost pro Dev-C++. Našel sem jsem jenom návod na instalaci pro Visual studio. Předem díky za odpověď.
#4 Dutch77
Nějak nechápu, pole se vždycky předává jako pointer takže ti stačí jedna úroveň, alespoň u vypsání. U nastavení velikosti potřebuješ pointer na ten pointer kterýmu přiřazuješ paměť a nebo podle mě jednodušeji a přehledněji použít referenci int* & pole. Pak nemusíš předávat adresu a pracovat s dvojitym pointerem, protože pole je odkaz na to co funkci předáš.
#1 Dutch77
Proč funkci vypis předáváš adresu pointeru a proč ta funkce přebírá jako parametr pointer na pointer, jako kdyby si jí měl předávat dvourozměrný pole, ale pokud chápu správně předáváš pointer na pole jednorozměrný? Vypisuješ pole přes adresu adresy, čímž si to děláš zbytečně složitý a máš v tom chybu, musíš použít *(pole)[i].
#45 Ilhvm
Já bych to udělal takhle
float* HledejPrvek(float pp[], int dolni, int horni)
{
int i;
int max = 0;
if (pp && dolni >= 0 && horni < N)
{
for (i = dolni; i < horni; i++)
{
if (pp[i] > pp[max])
max = i;
}
}
return &pp[max];
}
Netestoval sem to, ale mělo by to fungovat. Jenom do max neukládáš hodnotu nejvyššího prvku ale jeho index a pak vrátíš &pp[max].
Do tý podmínky bych ještě možná pro jistotu přidal "&& pole" nebo pro lepší viditelnost "&& pole != NULL". Pokud by ta funkce nemusela bejt void tak by bylo dobrý udělat aby vracela bool - true pokud všechno bude v pořádku a false pokud bude nějakej parametr chybně zadanej.
#28 Ilhvm
Jelikož indexy máš funkci předat tak pochybuju že vstup má bejt uvnitř tý funkce, takže jak velikost tak indexy budeš nejspíš zadávat v main a jelikož funkci nemáš předávat velikost pole tak se obávam pro ní budeš potřebovat globální proměnnou.
#25 ingiraxo
Jo ještě k tomu jak ses ptal k čemu strukturu. Myslel sem to tak že by se vytvořila struktura která by v sobě měla pointer na pole a jeho velikost a ta funkce by vrátila instanci tý struktury. Pokud by se ta velikost nesměla předat parametrem a zároveň nebyla globální a určila se uvnitř funkce tak nevidim jinej způsob jak by se dala dostat ven z tý funkce :D ...ale jak řikam, je to přehnaný a jak řikáš ty, zadání neznáme a bez něj to nemá cenu řešit. Pochybuju že by ve škole dělali zadání tak aby se to muselo řešit timhle způsobem.
#23 ingiraxo
Osobně si myslim že ta část programu kde uživatel zadává velikost pole a indexy by neměla bejt uvnitř tý funkce pro naplnění ale v main. Takhle mi to nějak nedává smysl. Pak by se jenom parametrem předala velikost a indexy a ty parametry by ani nemuseli bejt pointery, velikost budeš znát i mimo funkci a pointer na vytvořený pole funkce vrátí.
#21 ingiraxo
Asi tak nápodobně, možná by bylo dobrý kdyby sem hodila celý zadání. Tohle je moc vytržený z kontextu :D
Když bude funkce vracet pole a velikost se určí vevnitř tak už zas tu velikost nebudeš znát mimo tu funkci což nejspíš bude potřeba. Leda udělat aby ta funkce vracela s polem i jeho velikost, ale to už bys musel dělat strukturu a to je imho trochu přehnaný :D
#18 ingiraxo
Špatně si mě pochopil. Říkala že nechce velikost předávat parametrem. Ta tvoje funkce určuje velikost pole uvnitř. Pokud by ale velikost byla určena v main a nesměla by se předat jako parametr funkci vyplňující pole (ať už z jakýhokoliv důvodu ale takhle to bylo řečeno) tak jak jinak chceš udělat aby se ta velikost dala použí uvnitř tý funkce.
#11 Ilhvm
#11 Ilhvm
Některý překladače spolknou nastavení velikosti pole za běhu, třeba int pole[n]; ale to je imho prasárna. Měla bys použít dynamickou alokaci pomocí funkce malloc.
int* pp = malloc(sizeof(int) * n); //n je pocet prvku
pokud pak použiješ sizeof(pp) nedostaneš velikost pole ale velikost pointeru v bytech což by mělo bejt vždycky 4 pod win.
Zjistit velikost pole ke kterýmu přistupuješ přes pointer nejde. Jelikož tý funkci pro naplnění předáváš dolní i horní index tak to ani nepotřebuješ. Jenom nesmíš dolní index zadat menší než 0 a horní větší než index posledního prvku. Pokud tohle chceš ošetřit musíš si udělat proměnnou a do ní uložit velikost pole ve chvíli kdy jí zadáš. V tvym případě je to n.
Pokud je tohle na co ses ptala...
Zdravím. Rád bych se zeptal jestli tady někdo má zkušenosti s programováním aplikací pro Android, popřípadě iOS v C++. Jde mi hlavně o tvorbu her. Zkoušel jsem hledat ale nenašel jsem nic moc. Potřeboval bych nějaké IDE které běží pod windows, nejspíš nějakou knihovnu pro psaní aplikací v grafice a hlavně poradit nějaký zdroj informací ze kterého by se to dalo naučit. Předem děkuji.
#8 vitamin
Otázka je jak moc neefektivní by bylo ukládat pointery na jednotlivé bloky do dvojrozměrného pole. (První rozměr bloky, druhý rozměr prvky bloků). Pak by to spojování nebylo tak složité.
Kdybych měl něco lepšího na práci tak bych s tím ani nezačínal. Nemám co dělat a na tomhle se aspoň něco naučím. Nikdy jsem spojový seznam nepsal.
#2 vitamin
Pokud to chápu správně tak tak po vytvoření seznamu by se měl alokovat blok o řekněme 1000 prvcích a z něj by se měly přiřazovat jednotlivé prvky do seznamu. Pokud počet prvků přesáhne 1000 vytvoří se další blok. Ty bloky by mohli mít různou velikost, záleží na tom jaký chci mít poměr mezi rychlostí alokace a spotřeby paměti, tohle by teoreticky mohlo být nastavitelné. Chápu to správně? :D
Zdravím. Snažím se vytvořit šablonu třídy pro spojový seznam. Každý prvek seznamu je objekt obsahujicí data a pointer na následující prvek, vytvoření probíha tak že se vezme první objekt, jemu se příkazem new alokuje paměť a pak smyčkou for se vždy přes předchazející prvek alokuje operátorem new paměť pro další. Blok smyčky obsahuje pouze dva příkazy pro přiřazení a vytvoření objektu operátorem new. Všechno funguje jak má ale je to na můj vkus neuvěřitelně pomalé. Vytvoření seznamu o 10 milionech prvcích trvá cca 3 vteřiny. Došel jsem k závěru že alokace jednotlivého objektu operátorem new trvá daleko déle než jsem si myslel, jelikož bez tohoto příkazu proběhne cyklus v podstatě okamžitě i při mnohem větším počtu průchodů. Rád bych tedy věděl jestli existuje nějaký efektivnější (rychlejší) způsob jak vytvořit spojový seznam. Napadlo mě vytvořit celý blok paměti pomocí new[] a pak každému objektu přiřadit adresu jednotlivých prvků tohoto bloku. Potíž ale je v dealokaci protože pokud vím tak jednotlivé prvky bloku vytvořeného operátorem new[] nejdou dealokovat operátorem delete. Předem děkuji za rady.