Vložení nové struktury do fronty – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

Vložení nové struktury do fronty – C / C++ – Fórum – Programujte.comVložení nové struktury do fronty – C / C++ – Fórum – Programujte.com

 

Toto vlákno bylo označeno za vyřešené.
Hledá se programátor! Plat 1 800 € + bonusy (firma Boxmol.com)
Qerts0
Duch
9. 3. 2012   #1
-
0
-

Dobrý den, 
byl mi zadán projekt, simulace obchodu. Jedná se o dynamické pole front(struktur), kde členy jsou struktury. Něco jsem spatlal, respektive začal patlat, ale narazil jsem na pro mně těžko překonatelný problém. V následujícím kódu, ve fci Put(), mi VS vypisuje undeclared identifier pro Head a Tail. Nutno říci, že jsem se dozvěděl co je to fronta a struktura zhruba dva týdny zpátky a nevím moc co a jak, ale než jsem si šel pro čaj, tak to běhalo :D Kdybyste mi někdo poradili, kde by asi mohla být chyba, byl bych velmi vděčný.


#include <iostream>
#include "i2.h" 

using namespace std;


void Put(int &ID);         //deklarace funkce vlozeni zakaznika do fronty
bool IsEmpty();          //deklarace zkousky plnosti vsech pokladen

void Put(int &ID)                                 //vlozeni noveho zakaznika
{
Zakaznik * newZakaznik = new Zakaznik;                          //nastaveni pointeru na dalsiho zakaznika
newZakaznik->ID = ID;                                   //nastaveni id noveho zakaznika
newZakaznik->PP = P - (ID%P);                      //nastaveni poctu polozek
newZakaznik->Next = NULL;                             //nastaveni ukazatele na NULL
ID--;
if(Head == NULL)                              //pokud je fronta prazdna
{
  Head=newZakaznik;                          //pak dej do headu novou polozku
  Tail=newZakaznik;                               //a do tailu taky, cimz ma fronta jednoho zakaznika
}
else                                                      //pokud ne,
{
  Tail->Next=newZakaznik;                              //tak dej do ukazatele na dalsi polozku novou polozku (???)
  Tail = newZakaznik;                                  //a do ocasu primo novou polozku (???)
}
}


bool IsEmpty()                                //zkouska plnosti
{
int a = 5;                                         //kontrolni promenna
for(int x = 0; x < N ; x++)                              //for na prochazeni pokladen
{
  if(Pokladny[x].Head==NULL)                      //pokud je head null
   if(Pokladny[x].Tail==NULL)                 //a tail null
    a--;                                                   //sniz kontrolni promennou

}       
return a == 0;                                      //vrat stav pokladen

}
void main (void)
{
cout << "Vitejte v simulaci obchodu." << endl;
cout << "Pocet pokladen:   " << N << endl;
cout << "Maximalni pocet polozek v kosiku:   " << P << endl;
cout << "Pocet zakazniku:   " << M << endl;
int ID = M;          //z const int na int

for(int x = 0; x < N ; x++)      //for na prochazeni polem pokladen
{
  Pokladny[x].Head=NULL;      //nacpe do headu pokladny NULL
  Pokladny[x].Tail=NULL;      //nacpe do tailu pokladny NULL
}

do
{
  //vygenwrovat noveho zakaznika s radym ID a vrazit ho do fronty s nejmensim poctem zakazniku
  //Put();
  //ubrat polozku zakaznikovi v kazde fronte
  //Dec();
  //zkontrolovat zakazniky a pokud ma nekdo v kosiku nulu, tak vyhodit
  //Check(); ve spojeni s Get();

  cout << "la";
  break;
}

while(IsEmpty()==1);

cout << "Simulace byla uspesne ukoncena. Dosli zakaznici i trpelivost programatora.";

getchar();
}





i2.h:



const int N = 5;         //pocet pokladen
const int P = 10;         //max pocet polozek v kosiku
const int M = 100;         //pocet zakazniku

struct Zakaznik
{
int ID;           //cislo zakaznika
int PP;           //pocet polozek v kosiku
Zakaznik * Next;        //pointer na dalsiho zakaznika
};

struct Pokladna
{
Zakaznik * Head;        //head fronty
Zakaznik * Tail;        //tail fronty
};

Pokladna * Pokladny = new Pokladna[N-1];  //dynamicke pole pokladen

Nahlásit jako SPAM
IP: 193.179.175.–
Reklama
Reklama
pakr93
~ Anonymní uživatel
19 příspěvků
9. 3. 2012   #2
-
0
-

Problem bude ve funkci put :

void Put(int &ID)                                 //vlozeni noveho zakaznika

{
    Zakaznik * newZakaznik = new Zakaznik;                          //nastaveni pointeru na dalsiho zakaznika
    Pokladna * newPokladna = new Pokladna;
    newZakaznik->ID = ID;                                   //nastaveni id noveho zakaznika
    newZakaznik->PP = P - (ID%P);                      //nastaveni poctu polozek
    newZakaznik->Next = NULL;                             //nastaveni ukazatele na NULL
    ID--;
    if(newPokladna->Head == NULL) {                            //pokud je fronta prazdna
        newPokladna->Head = newZakaznik;                          //pak dej do headu novou polozku
        newPokladna->Tail=newZakaznik;                               //a do tailu taky, cimz ma fronta jednoho zakaznika
    } else {                                                  //pokud ne,
        newPokladna->Tail->Next=newZakaznik;                              //tak dej do ukazatele na dalsi polozku novou polozku (???)
        newPokladna -> Tail = newZakaznik;                                  //a do ocasu primo novou polozku (???)
    }
}

Promenne se deklarovaly pomoci operatoru new, ktery prideluje pamet, tu musite taky nejak smazat ... s tim si ale poradte sam ;) :-)

... funkce getchar() se nachazi v stdio.h, coz je klasicka cckovska knihovna ... analogicka fce v c++ je std::cin.get() ..

Nahlásit jako SPAM
IP: 212.79.110.–
pakr93
~ Anonymní uživatel
19 příspěvků
9. 3. 2012   #3
-
0
-

Omlouvam se, az ted jsem si precetl, ze vite, ze je problem ve funkci put    ... ach ta nepozornost :D

Nahlásit jako SPAM
IP: 212.79.110.–
Qerts0
Duch
9. 3. 2012   #4
-
0
-

Díky moc, tohle by mně asi hned tak nenapadlo. Mám se hold ještě hodně co učit :)

Nahlásit jako SPAM
IP: 193.179.175.–
vitamin+8
Grafoman
9. 3. 2012   #5
-
0
-

Mozno by nebolo odveci skusit pouzit triedy.

Hlavny problem je ze vo funkcii Put nevies do ktorej pokladne mas vlozit zakaznika.

Riesenie je napr pouzit pokladnu ako parameter funkcie put:

void Put(Pokladna &p, int &ID);   
//alebo:
void Put(Pokladna *p, int &ID);  

alebo vlozit funkciu Put do struktury Pokladna:

struct Pokladna
{
	Zakaznik * Head;        //head fronty
	Zakaznik * Tail;        //tail fronty

	void Put(int &ID);
};
	
	

Ak mozes pouzit stl tak si ulahci pracu pomocou queue

Nahlásit jako SPAM
IP: 178.143.60.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
Qerts0
Duch
9. 3. 2012   #6
-
0
-

třídy máme zakázané, ale s tím parametrem to určitě zkusím, zrovna jsem koumal jak na to

Nahlásit jako SPAM
IP: 193.179.175.–
vitamin+8
Grafoman
9. 3. 2012   #7
-
0
-

Podla mna je ID zakaznika nanic, v podstate ako ID mozes pouzit adresu strukury Zakaznik.

Ak ho tam musis mat, tak mozes pouzit staticku premennu vo funkcii Put:

void Put(Pokladna &p){
	static int ID = 0;

	//todo vytvorit zakaznika s id ID a vlozit ho do fronty

	ID++;
}

Pri prvom volani Put sa inicializuje ID na 0, ale v nasledujucich volaniach sa uz len inkrementuje. Budes mat zarucene ze zakaznici maju unikatne ID (ak ignorujeme pretecenie, viac vlakien ...   )

Nahlásit jako SPAM
IP: 178.143.60.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
Qerts0
Duch
10. 3. 2012   #8
-
0
-

Ještě jednou prosím o pomoc. Pár dlouhých hodin jsem ležel v teorii a naštudoval něco k tématu. Pokusil jsem se napsat program jak podle Vašich rad a toho, co jsem zjistil, ale stejně mám někde chybu. Nejspíše to bude opět ve funkci Put. Mám podezření, že funkce nevrací změny v poli Pokladny[], i když by mělo být deklarováno jako globální v .h souboru. VS nehází žádný error, ale program zbloudí pokaždé, když se snažím o nějakou akci s řečeným polem mimo funkci Put. Zkoušel jsem pole předávat jako argument, ale jediné, čeho jsem dosáhl bylo, že program zbloudil 'o strukturu výše'.

#include <iostream>
#include <stdio.h>
#include "i2.h"


using namespace std;

void Put();     //deklarace funkce vlozeni zakaznika do fronty
bool IsEmpty();    //deklarace zkousky plnosti vsech pokladen
void Dec();     //deklarace ubirani polozky
void Get();     //deklarace odebrani zakaznika
int MinPZ();    //zjisti, ktera zpokladen ma nemin zakazniku a vrati jeji index

void Put()            //vlozeni noveho zakaznika
{
int index = MinPZ();        //index pokladny s nejmensim poctem zakazniku
Zakaznik * newZakaznik = new Zakaznik;    //vytvornei noveho zakaznika
newZakaznik->PP = P - (ID%P);      //nastaveni poctu polozek od 1 do P
newZakaznik->ID = ID;        //nastaveni id noveho zakaznika
newZakaznik->Next = NULL;       //nastaveni ukazatele Next na NULL      
//cout << "pocet zakazniku u pokladny " << index << " je" << Pokladny[index].PZ << endl;
if(Pokladny[index].Head == NULL)     //pokud je fronta prazdna
{
  Pokladny[index].Head = newZakaznik;    //pak dej do headu novou polozku
  Pokladny[index].Tail = newZakaznik;    //a do tailu taky, cimz ma fronta jednoho zakaznika
}
else            //pokud ne,
{
  Pokladny[index].Tail->Next = newZakaznik;  //tak prirad do posledniho zakaznika ve fronte ukazatel na noveho zakaznika
  Pokladny[index].Tail = newZakaznik;    //a potom na konec fronty prirad primo noveho zakaznika
}
cout << "G" << ID << "[" << newZakaznik->PP << "]" << endl;
cout << "V" << newZakaznik->ID << "[" << index << "][" << Pokladny[index].PZ << "]" << endl;
Pokladny[index].PZ++;        //nastaveni poctu zakazniku na pokladne
ID++;            //navyseni ID
}
int MinPZ()
{
int index = 0, PZvalue = M;    //deklarace idexu a mezihodnoty pro pocet zakazniku
for(int x = 0; x < N ; x++)    //for na prochazeni pokladen
{
  if(Pokladny[x].PZ <= PZvalue)  //pokud je PZ mensi nez PZvalue, tak
  {
   PZvalue = Pokladny[x].PZ;  //presun PZ do PZvalue
   index = Pokladny[x].IDP;  //a zaroven pleskni do indexu cislo pokladny
  }
}
cout << "Pokladna s nejmensim poctem zakazniku je pokladna cislo " << index << "." << endl;
return index;
}
bool IsEmpty()        //zkouska plnosti
{
int a = N;        //kontrolni promenna
for(int x = 0; x < N ; x++)    //for na prochazeni pokladen
{
  if(Pokladny[x].Head==NULL)   //pokud je head null
   if(Pokladny[x].Tail==NULL)  //a tail null
    a--;      //sniz kontrolni promennou

}       
return a == 0;       //vrat stav pokladen
}
void Dec()
{
for(int x = 0; x < N ; x++)    //prochazeni pokladen
{
  //cout << "pred ubranim polozky" << Pokladny[x].Head->PP << endl;
  Pokladny[x].Head->PP--;    //ubrani polozky v kosiku
  cout << "K" << Pokladny[x].Head->ID << "[" << Pokladny[x].Head->PP << "]" << endl;
  //cout << "po ubrani polozky" << Pokladny[x].Head->PP << endl;
}
}
void Get()
{
for(int x = 0; x < N ; x++)       //pochazeni pokladen
{
  if(Pokladny[x].Head->PP == 0)     //kontrola kosiku na 0
  {
   int IDZak;         //ID odebiraneho zakaznika
   IDZak = Pokladny[x].Head->ID;    //prevedeni id odebiraneho zakaznika do mezipromenne
   Pokladny[x].Head->Next = Pokladny[x].Head; //prerazeni druheho zakaznika ve fronte na prvni pozici
   cout << "O"<< IDZak <<"[F"<< Pokladny[x].IDP << "][" << Pokladny[x].PZ << "]" << endl;
  }
}
}

void main (void)
{

cout << "Vitejte v simulaci obchodu." << endl;
cout << "Pocet pokladen:   " << N << endl;
cout << "Maximalni pocet polozek v kosiku:   " << P << endl;
cout << "Pocet zakazniku:   " << M << "\n\n\n\n" << endl;
cout << "Vytvoreni pokladen:" << endl;

for(int x = 0; x < N ; x++)      //for na prochazeni polem pokladen
{
  Pokladny[x].Head = NULL;     //nacpe do headu pokladny NULL
  Pokladny[x].Tail = NULL;     //nacpe do tailu pokladny NULL
  Pokladna * newPokladna = new Pokladna;  //alokace pameti pro pokladnu
  Pokladny[x].IDP = x % N;     //prirazeni ID pokladne
  Pokladny[x].PZ = 0;       //prirazeni pocatecni hodnoty pokladny
  //cout << "ID pokladny je: " << Pokladny[x].IDP << endl;
  //cout << "Pocet zakazniku na pokladne je: " << Pokladny[x].PZ << endl;
}
do
{
  if(ID < M)         //pokud je vytvoreno mene zakazniku, nez je M, pak
  {
   Put();         //vloz zakaznika do pokladny s nejmensim poctem zakazniku
   //Dec();        //ubrani polozky vsem zakaznikum, kteri jsou zrovna na rade
   //Get();        //kontrola kosiku na 0 polozek a pripadne vyjmuti zakaznika z fronty
  }
}
while(IsEmpty()==0);       //1 je pln stav, 0 je prazdny stav

cout << "Simulace byla uspesne ukoncena. Dosli zakaznici i trpelivost programatora.";

cin.get();
}

i2.h

const int N = 5;         //pocet pokladen
const int P = 10;         //max pocet polozek v kosiku
const int M = 10;         //pocet zakazniku

struct Zakaznik
{
int ID;           //cislo zakaznika
int PP;           //pocet polozek v kosiku
Zakaznik * Next;        //pointer na dalsiho zakaznika
};

struct  Pokladna
{
int IDP;          //cislo pokladny
int PZ;           //aktualni pocet zakazniku
Zakaznik * Head;        //head fronty
Zakaznik * Tail;        //tail fronty

};

Pokladna * Pokladny = new Pokladna[N-1];   //dynamicke pole pokladen
static int ID = 0;         //staticke ID

Nahlásit jako SPAM
IP: 193.179.175.–
vitamin+8
Grafoman
11. 3. 2012   #9
-
0
-

Zdrojove kody vkladaj pomocou "Vložit zdrojový kód".

Skus to napisat bez globalnych premmennych (constanty mozu ostat), bude to prehladnejsie a mozno si najdes chyby sam .

Premenne ID a IDP su zbytocne, radej pouzi pointre.

Pokladna * Pokladny = new Pokladna[N-1];   //dynamicke pole pokladen

Toto je dynamicky alokovane pole, nie dynamicke pole. v podstate to mozes prepisat na toto a nic sa nezmeni:

Pokladna  Pokladny[N-1];

Preco vlastne nemozes pouzivat triedy ked programujes v c++?

edit: Vobec po sebe neodstranujesdynamicky  alokovanu pamet...

Nahlásit jako SPAM
IP: 178.143.60.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
Qerts0
Duch
11. 3. 2012   #10
-
0
-

V instruktáži k projektu bylo vstupní proměnné deklarovat jako globální. Ale přepsal jsem je tedy a chybu jsem stejně nenašel. Teď jdu na odstraňování dynamické paměti. Třídy máme výslovně zakázané. Nejspíše proto, že o nich byla teprve letmá zmínka na přednáškách a budou náplní zadání pro další skupinu. 

Nahlásit jako SPAM
IP: 193.179.175.–
Qerts0
Duch
11. 3. 2012   #11
-
0
-

Děkuji všem za pomoc :) Dynamicky alokované pole jsem změnil na dynamické. Nechal jsem vše nadeklarované globálně, tím pádem je ke všem strukturám přístup ze všech funkcí, ač je to nešťastné při hledání chyb. To a pár změn ve funkcích a program běží :)

Nahlásit jako SPAM
IP: 193.179.175.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 179 hostů

Podobná vlákna

Namnožení fronty — založil Shadow2334

Vložení do DB — založil turbo-snek

Vložení ID — založil savek

Vložení textury — založil Malirka

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032016 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý