2013-07-18 12 views
6

Ho implementato una struttura di coda di base in C usando i puntatori void. La procedura è come segue:Implementazione della coda C usando void * - buona o cattiva pratica?

  • inizializzazione della struttura - ho impostato la dimensione del tipo variabile da memorizzare nella coda
  • spinta - passo il puntatore alla variabile da memorizzare, la coda afferra quindi una copia per sé
  • anteriore - la struttura restituisce un vuoto * all'elemento in primo piano. Potrei semplicemente prendere il puntatore o memcpy() per avere una copia locale.

La struct sé assomiglia a questo:

struct queue 
{ 
    void* start; //pointer to the beginning of queue 
    void* end;  //-||- to the end 
    size_t memsize; //size of allocated memory, in bytes 
    size_t varsize; //size of a single variable, in bytes 
    void* initial_pointer;  //position of the start pointer before pop() operations 
}; 

inizio e la fine sono solo puntatori void che puntano a una certa posizione all'interno del blocco di memoria attualmente allocata. Se spingo gli elementi in coda, incremento il puntatore finale di varsize. Se pop(), decremento del puntatore finale anche da varsize.

Non penso che dovrei pubblicare il codice delle funzioni qui, sono oltre 100 righe.

La domanda: è considerata una buona o una cattiva pratica? Perchè no)?

Nota: sono consapevole che ci sono molte altre opzioni per una coda in C. Sto solo chiedendo la qualità di questo.

EDIT: L'implementazione è disponibile qui: http: // 89.70.149.19 /stuff/queue.txt (rimuovere gli spazi)

+2

Usa size_t per la memoria di dimensioni –

+0

penso che il suo bene di scrivere codice generico utilizzando '' void * –

+0

@RanEldan Grazie, lo farò. Corretto qui – szczurcio

risposta

8

E 'OK per utilizzare void * se non si conosce il tipo e la dimensione degli oggetti da memorizzare nella coda (infatti, la libreria standard C segue lo stesso approccio, vedere le funzioni memcpy() e qsort() per alcuni esempi). Tuttavia, sarebbe meglio utilizzare size_t (o ssize_t se è necessario un tipo di dati firmato) per specificare la dimensione degli elementi memorizzati nella coda.

+1

Ran Eldan ha già detto che l'ho corretto. OK, grazie per la tua opinione. In realtà penso che sia intuitivo farlo, solo che ho visto alcune persone affermare che questo è "brutto". – szczurcio

+2

@szczurcio Il fatto è che non si può fare nient'altro se non si conosce il tipo in anticipo. Se lo fai, allora non usare 'void *' con qualsiasi mezzo per una migliore sicurezza del tipo. –

2

Davvero non ci mostrate abbastanza per essere sicuri della vostra implementazione. void* per gli elementi di dati utente va bene, non si può fare molto tuttavia in C.

Ma ho il forte sospetto che si dispone di un tipo di elenco elemento interno che consente di gestire le singole voci, qualcosa di simile

struct list_item { 
    struct list_item* next; 
    void* data; 
}; 

Se questo è il caso e le tue start e end puntatori stanno indicando a tali elementi, è definitivamente dovrebbe usare il tuo tipo di elemento nella dichiarazione struct queue:

struct queue 
{ 
    struct list_item* start; //pointer to the beginning of queue 
    struct list_item* end;  //-||- to the end 
    size_t memsize; //size of allocated memory, in bytes 
    size_t varsize; //size of a single variable, in bytes 
    struct list_item* initial_pointer;  //position of the start pointer before pop() operations 
}; 

Affinché ciò funzioni, non è nemmeno necessario esporre la definizione di struct list_item all'utente di struct queue.

+0

Non sono sicuro di cosa intendi. inizio e fine sono solo puntatori vuoti che puntano a qualche posizione all'interno del blocco di memoria attualmente assegnato. Se spingo gli elementi sulla coda, incremento il puntatore end varsize. Se pop(), decremento del puntatore finale anche per effetto di varsize. – szczurcio

+0

EDIT: Ho aggiunto un collegamento al codice nella mia domanda. – szczurcio

+0

@szczurcio, è un'implementazione molto anticonvenzionale di una coda, il solito sarebbe qualcosa con elementi dinamici come lo descrivo qui. Dovresti aggiungere la descrizione che hai nel tuo commento alla domanda, per riferimento. Vorrei quindi eliminare questa risposta, che non ti serve molto. –

Problemi correlati