|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Feb 2002
Messaggi: 906
|
[c++] struct e new
Ho una struttura così:
struct GAMEMSG_OKAY : public GAMEMSG_GENERIC { bool IF[8]; }; Nel caso sopra posso avere fino a 7 bool ho bisogno che bool IF[x] sia incrementato in modo automatico a runtime oppure decrementato. In pratica bool IF[x]; all'inizio non si conosce quanti indici può contenere quindi a runtime devo fare bool IF[0]; poi bool IF[1]; ecc ecc. anche decrementandolo. Credo che bisogna usare la new ma nella struct così formata non ne sono capace... |
|
|
|
|
|
#2 |
|
Member
Iscritto dal: Feb 2006
Messaggi: 134
|
Codice:
#define MAX_ITEMS 100
typedef struct struttura
{
int n_items;
bool *item;
public:
struttura (void)
{
n_items = 0;
item = new bool[MAX_ITEMS];
}
void add_item (bool _item)
{
if (n_items < MAX_ITEMS)
item[n_items++] = _item;
}
};
struttura *mStruttura = new struttura();
mStruttura->add_item(true);
mStruttura->add_item(false);
Ultima modifica di Volutomitra : 20-10-2006 alle 20:43. |
|
|
|
|
|
#3 | |
|
Senior Member
Iscritto dal: Feb 2002
Messaggi: 906
|
Quote:
ti ringrazio in pratica dici #define MAX_ITEMS 100 struct GAMEMSG_OKAY { int idN; bool IF[MAX_ITEMS]; }; void add_item (bool _item) { if (n_items < MAX_ITEMS) item[n_items++] = _item; } ... ok Ho aperto il 3d perchè volevo risparmiare sulle dimensioni della struttura. Come lo messa io all'inizio l'ho definita a [8] quindi la struttura ha sizeof(GAMEMSG_OKAY) di tot mentre pensavo di iniziare da 0 e mano a mano che incremento gli item la struttua aumentasse il suo sizeof(). La domanda e il metodo era per risparmiare sui byte della struttura facendo: bool IF[MAX_ITEMS]; la struttura ha un sizeof(GAMEMSG_OKAY) maggiore del mio [8]... o sbaglio!!! |
|
|
|
|
|
|
#4 | |
|
Member
Iscritto dal: Feb 2006
Messaggi: 134
|
Quote:
|
|
|
|
|
|
|
#5 | |
|
Senior Member
Iscritto dal: Feb 2002
Messaggi: 906
|
Quote:
fai un esempio... di lista per la struct postata per allocare e deallocare in modo dinamico. |
|
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Jan 2006
Messaggi: 2722
|
Codice:
struct GAMEMSG_OKAY
{
bool IF;
struct GAMEMSG_OKAY *next;
public:
GAMEMSG_OKAY (void)
{
IF = false; // Non è necessario...
next = NULL;
}
// Aggiunge un nuovo elemento in coda alla lista. Il valore ritornato
// è di comodo...
struct GAMEMSG_OKAY *addItem(bool value)
{
struct GAMEMSG_OKAY *newElem = new struct GAMEMSG_OKAY;
newElem->IF = value;
struct GAMEMSG_OKAY *ptr = this;
while (ptr->next != NULL)
ptr = ptr->next;
ptr->next = newElem;
return newElem; // Di comodo...
}
// Elimina l'elemento in coda alla lista.
// NOTA: se la lista contiene almeno un elemento (quello iniziale), nulla
// viene eliminato.
void removeItem(void)
{
struct GAMEMSG_OKAY *oldPtr = NULL;
struct GAMEMSG_OKAY *ptr = this;
while (ptr->next != NULL)
{
oldPtr = ptr;
ptr = ptr->next;
}
if (oldPtr != NULL)
{
oldPtr->next = NULL;
delete ptr;
}
return;
}
// Restituisce il valore booleano nella posizione specificata.
// Se l'elemento non esiste, ritorna -1.
short int getItem(unsigned int numItem)
{
struct GAMEMSG_OKAY *ptr = this;
while (numItem > 0)
{
ptr = ptr->next;
if (ptr == NULL)
return -1;
numItem--;
}
return ptr->IF;
}
// Setta il valore booleano nella posizione specificata.
// Se l'elemento non esiste, ritorna -1, altrimenti 0.
short int setItem(unsigned int numItem, bool value)
{
struct GAMEMSG_OKAY *ptr = this;
while (numItem > 0)
{
ptr = ptr->next;
if (ptr == NULL)
return -1;
numItem--;
}
ptr->IF = value;
return 0;
}
}; // END OF struct GAMEMSG_OKAY
// Esempio d'uso. Non controllo i possibili errori, per quanto i "metodi"
// lo permettano: comunque eventuali errori sono causati da
// errati parametri passati.
// NOTA: values rappresenta sempre il primo elemento (la testa della lista).
struct GAMEMSG_OKAY *values = new struct GAMEMSG_OKAY;
// NOTA: è come se facessi values->setItem(0, true);
values->IF = true;
values->addItem(true);
values->addItem(false);
values->setItem(0, false);
values->addItem(true);
values->setItem(2, true);
values->removeItem();
bool test = values->getItem(2);
test = values->getItem(0);
EDIT: stanotte non riesco a prendere sonno...
__________________
- Spesso gli errori sono solo i passi intermedi che portano al fallimento totale. - A volte penso che la prova piu' sicura che esiste da qualche parte una forma di vita intelligente e' il fatto che non ha mai tentato di mettersi in contatto con noi. -- Bill Watterson Ultima modifica di -fidel- : 21-10-2006 alle 04:25. |
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Feb 2002
Messaggi: 906
|
azz... hai fatto tutto!!
mi hai risparmiato un bel lavoro... grazie Codice HTML:
struct GAMEMSG_GENERIC
{
DWORD dwType;
};
struct GAMEMSG_OKAY : public GAMEMSG_GENERIC
struct GAMEMSG_OKAY : public GAMEMSG_GENERIC { bool IF; struct GAMEMSG_OKAY *next; giusto? anche io non prendo sonno Edit: Domani lo studio e cerco di integrarlo prossimamente il tuo code. - gli inserimenti vanno in testa si? - su 5 elementi tolgo il 3 e scalo gli altri ok? Ultima modifica di okay : 21-10-2006 alle 04:50. |
|
|
|
|
|
#8 | ||||
|
Senior Member
Iscritto dal: Jan 2006
Messaggi: 2722
|
Quote:
Quote:
Codice:
struct GAMEMSG_OKAY *values = new struct GAMEMSG_OKAY; values->dwType = 1; // Ad esempio... Mi sembra più opportuno, quindi, modificare il codice affinchè: 1) per settare un valore nella struttura, meglio avere il puntatore all'elemento e poi fare ad esempio: curElem->IF = FALSE; curElem->dwType = 2; ecc... 2) quindi la setItem e la getItem vanno modificate. La modifica la trovi tra poco Quote:
Quote:
Codice:
int main(void)
{
struct GAMEMSG_GENERIC
{
DWORD dwType;
// Mi permetto di aggiungere un costruttore, visto come usiamo la struttura.
public:
GAMEMSG_GENERIC (void)
{
dwType = 0;
}
};
struct GAMEMSG_OKAY : public GAMEMSG_GENERIC
{
bool IF;
struct GAMEMSG_OKAY *next;
public:
GAMEMSG_OKAY (void)
{
IF = false;
next = NULL;
}
// Aggiunge un nuovo elemento in coda alla lista. Il valore ritornato
// è di comodo...
struct GAMEMSG_OKAY *addItem(void)
{
struct GAMEMSG_OKAY *newElem = new struct GAMEMSG_OKAY;
struct GAMEMSG_OKAY *ptr = this;
while (ptr->next != NULL)
ptr = ptr->next;
ptr->next = newElem;
return newElem; // Di comodo...
}
// Restituisce un puntatore all'elemento richiesto.
// Se l'elemento non esiste, ritorna NULL.
struct GAMEMSG_OKAY *getItem(unsigned int numItem)
{
struct GAMEMSG_OKAY *ptr = this;
while (numItem > 0)
{
ptr = ptr->next;
if (ptr == NULL)
return NULL;
numItem--;
}
return ptr;
}
// Elimina l'elemento specificato dalla lista.
// Se l'elemento non esiste o la lista contiene un solo elemento,
// ritorna -1, altrimenti 0.
// NOTA: Non è mai possibile eliminare il primo elemento (quello in
// posizione 0, anche se la lista ne contiene di più).
short int removeItem(unsigned int numItem)
{
struct GAMEMSG_OKAY *oldPtr = NULL;
struct GAMEMSG_OKAY *ptr = this;
// Cerco l'elemento interessato.
while (numItem > 0)
{
oldPtr = ptr;
ptr = ptr->next;
if (ptr == NULL)
// L'elemento richiesto non esiste.
return -1;
numItem--;
}
if (oldPtr != NULL)
{
// Tutto ok, rimuovo l'elemento.
oldPtr->next = ptr->next;
delete ptr;
return 0;
}
else
// La lista contiene solo un elemento (non eliminabile...).
return -1;
}
}; // END OF struct GAMEMSG_OKAY
// Esempio d'uso. Non controllo i possibili errori, per quanto i "metodi"
// lo permettano: comunque eventuali errori sono causati da
// errati parametri passati.
struct GAMEMSG_OKAY *anItem;
// NOTA: values rappresenta sempre il primo elemento (la testa della lista).
struct GAMEMSG_OKAY *values = new struct GAMEMSG_OKAY;
values->addItem();
values->addItem();
// Ora abbiamo 3 elementi nella lista. Inizio a "divertirmi" :)
anItem = values->getItem(1);
// Nota l'importanza dei costruttori: se omettessi la seguente riga,
// wNum varrebbe poi 0 (e non un valore indefinito... - anche se
// normalmente i compilatori c++ settano automaticamente tutte le variabili
// non inizializzate esplicitamente a 0, ma noi facciamo i precisini, quindi... ;)
anItem->dwType = 5;
DWORD wNum = anItem->dwType;
bool bVal = anItem->IF;
values->removeItem(1);
// Nulla mi vieta di fare...
anItem = values->addItem();
// ...e settare direttamente (senza dover fare getItem()):
anItem->IF = true;
} // END OF main
Per essere precisi, bisogna prevedere un distruttore per la struttura GAMEMSG_OKAY (dal momento che alloca memoria che poi diverrebbe irraggiungibile, portando a memory leak). E' molto semplice da fare, lascio a te il compito, se poi hai problemi ti dò volentieri qualche suggerimento EDIT: comunque secondo me è rischioso poter cancellare un qualunque elemento dell'array dinamico, invece che solo l'ultimo, perché altrimenti perdi l'ordine dei valori. Se ad esempio crei 3 elementi (numerati quindi 0, 1 e 2), e poi rimuovi il secondo elemento (in posizione 1), quello in poizione 2 passa in posizione 1 ( quindi altri eventuali valori scalano di una posizione indietro). Conseguentemente, una getItem(1) ti darà il valore dell'elemento che prima era in posizione 2. Secondo me può portare ad incasinarsi nella scrittura del resto del tuo codice. Poi se ti serve così...
__________________
- Spesso gli errori sono solo i passi intermedi che portano al fallimento totale. - A volte penso che la prova piu' sicura che esiste da qualche parte una forma di vita intelligente e' il fatto che non ha mai tentato di mettersi in contatto con noi. -- Bill Watterson Ultima modifica di -fidel- : 21-10-2006 alle 13:24. |
||||
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: Feb 2002
Messaggi: 906
|
Innanzitutto grazie per il tut...
ti dico a cosa mi serve. Il tut che hai fatto è proprio ok ben fatto. Adopero un server e client e questo sotto sono le strutture per sapere: Codice HTML:
#define GAME_MSGID_DELETE 8
#define GAME_MSGID_CREATE 9
#define GAME_MSGID_OKAYIT 10
// bytes allineati pop
#pragma pack( push, 1 )
struct GAMEMSG_GENERIC
{
DWORD dwType; //numero del valore
};
struct GAMEMSG_OKAY : public GAMEMSG_GENERIC
{
int idN; // id del player
bool IF[8];
//...altri dati
};
struct GAMEMSG_CREATE_PLAYER : public GAMEMSG_GENERIC
{
int idN; // id del player
};
struct GAMEMSG_DESTROY_PLAYER : public GAMEMSG_GENERIC
{
int idN; // id del player
};
// Pop the old pack alignment
#pragma pack( pop )
come vedi bool IF[8]; l'ho messo fino ad un max di 7 player. il sizeoff della struttura è 980 bytes mi è stato richiesto e detto di togliere [8] per tutti i dati e iniziarlo a NULL e incremntare,o decrementare (uscita del player) a runtime per avere meno di 980 bytes da inviare (chiaro che incrementando i player > i bytes della struttura da inviare che possono essere anche maggiori di 980 bytes). Il sistema della lista è ottimo per questo ma come dici tu potrebbe incasinarsi in un sistema di client server con chiari problemi di non capirci + niente. Io per ora lo lascio come ho fatto cmq mi studio ciò che hai postato... poi vedo un pò cosa fare. i client che si loggano vanno in testa naturalmente e naturalmente possono uscire e può essere che su 3 esca il 2 quindi devo scalare il 3 al 2. Quando si rilogga il 3 non deve andare in coda ma in testa. cmq detto questo secondo te è meglio implementare ciò che hai scritto oppure è meglio lasciarlo come ho fatto, a titolo informativo, secondo il tuo punto di vista? ciao Ultima modifica di okay : 21-10-2006 alle 13:32. |
|
|
|
|
|
#10 |
|
Senior Member
Iscritto dal: Jan 2006
Messaggi: 2722
|
Il mio punto di vista è usare una lista, nel modo che ho postato prima (l'ultimo codice). Alla fine la differenza sta nell'aggiungere un elemento alla lista con addItem (se richiesto), e prenderlo con variabile->getItem[numero]->IF invece che con variabile[numero].IF...
Il casino a mio parere risiederebbe nella possibilità di eleminare un qualunque elemento della lista, invece che l'ultimo in automatico. Ti conviene, secondo me, usare l'ultimo codice da me postato, ma sostituendo il "metodo" removeItem(unsigned int) con la removeItem(void) del primo codice postato. Così sei tranquillo ed usi la struct in pratica come se fosse statica. Faccio un esempio di uso pratico. Metodo tradizionale: Codice:
struct GAMEMSG_OKAY values; values[0].IF = true; values[0].dwType = 3; values[1].IF = true; values[1].dwType = 7; values[2].IF = false; Codice:
struct GAMEMSG_OKAY *values = new struct GAMEMSG_OKAY; values->getItem(0)->IF = TRUE; // Caso particolare: essendo values la testa della lista, puoi fare anche "values->IF = TRUE", ma per farti capire un uso generico... values->getItem(0)->dwType = 3; values->addItem(); values->getItem(1)->IF = true; values->getItem(1)->dwType = 7; values->addItem(); values->getItem(2)->IF = false; // Ora se l'elemento 2 non ti serve più... values->removeItem(); // Però nessun casino, perchè la posizione degli elementi (ed i valori memorizzati) rimangono immutati! EDIT 2: Attenzione però se mandi la struttura via socket! Quello è solo un puntatore a memoria allocata sul tuo sistema, se mandi quello mandi solo e sempre 4 bytes (8 su sistemi a 64 bit) contenenti l'indirizzo... A questo punto, devi anche prevedere l'invio della struttura (ma è banale). EDIT 3: rileggo meglio le tue richieste e modifico la struttura di conseguenza.
__________________
- Spesso gli errori sono solo i passi intermedi che portano al fallimento totale. - A volte penso che la prova piu' sicura che esiste da qualche parte una forma di vita intelligente e' il fatto che non ha mai tentato di mettersi in contatto con noi. -- Bill Watterson Ultima modifica di -fidel- : 21-10-2006 alle 14:39. |
|
|
|
|
|
#11 |
|
Senior Member
Iscritto dal: Jan 2006
Messaggi: 2722
|
Cosa intendi quando dici che i client nuovi vanno in testa? nel senso che, ogni volta che un client si logga, tu devi prevedere un nuovo valore di IF e questo deve essere il primo della lista (per intenderci nel modo tradizionale, IF[0])?
__________________
- Spesso gli errori sono solo i passi intermedi che portano al fallimento totale. - A volte penso che la prova piu' sicura che esiste da qualche parte una forma di vita intelligente e' il fatto che non ha mai tentato di mettersi in contatto con noi. -- Bill Watterson |
|
|
|
|
|
#12 | |
|
Senior Member
Iscritto dal: Feb 2002
Messaggi: 906
|
Quote:
esempio (naturalmente sia il client che il server hanno le stesse struct identiche)... questo è chiaro - Il server è avviato tutto è a NULL. - Il cient si avvia ma ancora è tutto a NULL. si logga il primo client che viene accettato dal server che implementa IF[0]=true; il client riceve l'OK che è stato accettato, ora anche il client avrà IF[0]=true; si logga il secondo client che viene accettato dal server che implementa IF[1]=true; il client riceve l'OK che è stato accettato, ora anche il client avrà IF[1]=true; [2] poi [3] ecc ecc. su 4 client esce il n. 2 sul server la routine di logoff a [0] rimane il primo client a [1] rimane il secondo a [2] passa il terzo a [3] passa il quarto sui client stessa cosa se si rilogga qualcunaltro va in testa ovvero sarà il [4] |
|
|
|
|
|
|
#13 | |
|
Senior Member
Iscritto dal: Jan 2006
Messaggi: 2722
|
Quote:
Comunque vedo che abbiamo un'idea diversa di testa e di coda di una lista: a me hanno insegnato che, in una lista di ad esempio 4 elementi, l'elemento in posizione 0 è la testa, quello in posizione 3 è la coda Codice:
struct GAMEMSG_OKAY *values = new struct GAMEMSG_OKAY; ... // Aggiungo elementi... ... values->getItem(2)->IF = true; // Assegnazione. DWORD type = values->getItem(3)->dwType; // Lettura. Codice:
struct GAMEMSG_OKAY *values = new struct GAMEMSG_OKAY; struct GAMEMSG_OKAY item; ... // Aggiungo elementi... ... item = values->getItem(2); item->IF = true; item = values->getItem(3); DWORD type = item->dwType;
__________________
- Spesso gli errori sono solo i passi intermedi che portano al fallimento totale. - A volte penso che la prova piu' sicura che esiste da qualche parte una forma di vita intelligente e' il fatto che non ha mai tentato di mettersi in contatto con noi. -- Bill Watterson |
|
|
|
|
|
|
#14 | |
|
Senior Member
Iscritto dal: Feb 2002
Messaggi: 906
|
Quote:
ma ricordo di avere un piccolo listato didattico per le liste (devo vedere...) con inserimento (come a te hanno insegnato... la famosa pila forse intendi?) degli elementi in coda e facendo il for(++) per la stampa di 3 elementi inseriti mi ritrovavo 2 1 0. Al che lo rifeci con inserimento in testa quindi nel for(++) mi stampava 0 1 2 che era appunto cioò che volevo. |
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 22:40.



















