Newsgroup: it.comp.lang.c
Titolo: Creare una coda con i puntatori...

Ciao a tutti, qualcuno sa un modo per riuscire a creare una coda con i
puntatori?
Grazie 1000 a  tutti!!!
Enrico S.
--
Webmaster della Pagina NON Ufficiale del SonyCRX100
SonyCRX120,  SonyCRX140E/S, SonyCRX100EX, HP8100
HP8200, HP9100 & HP9200
http://www.freeweb.org/computer/SonyCRX100/

 ha scritto nel messaggio
news:93q6ii$lgg$1...@lacerta.tiscalinet.it...

Intendi una lista? Ma di che tipo (FIFO, LIFO , ecc...)?

Intendi una lista? Ma di che tipo (FIFO, LIFO , ecc...)?
No, intende una coda.
--
Andrea Laforgia (ICQ 87230455)
http://www.geocities.com/AndreaLaforgia
"ci sono tre tipi di persone nel mondo : quelli che
 sono bravi in matematica e quelli che non lo sono."

vorresti ad esempio creare una coda di dati tipo carattere?
dovresti in questo caso creare una nuova struttura di dati, ad esempio (per
una coda di caratteri):
struct elemento {
  char c;
  struct elemento*next
}
dove c č il tuo dato e next č un puntatore all'elemento seguente
a questo punto, sta a te creare le funzioni opportune per creare la coda,
inserire e togliere elementi, stamparla a video.
suggerimento : l'ultimo elemento della coda dovrebbe avere valore del
puntatore = NULL, cosě se la scorri sai quando finisce
se ti interessa, io ho implementato uno stack con lo stesso metodo, se vuoi
te lo mando
--
ciao da giovanni
icq # 44782559
togli "REMOVE" per rispondere privatamente

Mi faresti un favorone, grazie 1000! (così mi faccio una idea!)
la mia mail: 
enri...@libero.it


 Intendi una lista? Ma di che tipo (FIFO, LIFO , ecc...)?
La coda e' FIFO, se non sbaglio...
-- 
 Ciao, Bianco.
 Reply to luca.bianco (at) 
tiscalinet.it

Tanti messaggi e nessun programma come richiesto.
E' mia opinione che tale argomento possa prevenire altri messaggi, e
aiutare tutti coloro che si avvicinano a questo newsgroup per imparare
ed essere guidati al C.
La versione seguente e' solo a scopo didattico/esplicativo non vuole
essere perfetta ne' l'unica. E' ampiamente migliorabile per mano di
coloro che ne produrranno una versione personale.
Questa versione permette di trattare piu' code contemporaneamente
passandole per indirizzo alle comuni funzioni tipiche di gestione
(pop, push, inizializza, cancella).
E' necessario inizializzare (all'inizio), e cancellare (alla fine),
ogni variabile di tipo 'coda', con le funzioni opportune.
======================================================
#include "stdio.h"
#include "stdlib.h"
typedef struct elemento {
 char elemento;
 struct elemento *link;
} coda;
void inizializza(coda*c)
{ c->link = NULL;}
void cancella(coda*c)
{
 if (c->link)
  cancella(c->link);
 free(c);
}
void push(coda *c, char elemento)
{
 coda *nuovo_elemento;
 nuovo_elemento=(coda *)malloc(sizeof(coda));
 if (nuovo_elemento) {
  nuovo_elemento->elemento = c->elemento;
  nuovo_elemento->link = c->link;
  c->elemento = elemento;
  c->link = nuovo_elemento;
 } else {
  printf("\nNON HO PIU' MEMORIA!\n");
 }
}
int pop(coda *c)
{
 struct elemento * da_eliminare;
 char da_restituire;
 if (c->link) {
  da_restituire = c-> elemento;
  da_eliminare = c->link;
  c->elemento = da_eliminare -> elemento;
  c->link = da_eliminare -> link;
  free(da_eliminare);
 } else {
  printf("\nCoda vuota.\n");
  da_restituire=' ';
 }
 return(da_restituire);
}
void main(void)
{
 coda c1 , c2 ;
 char elemento;
 printf("\nusa:\n# pop\n@ esci\n(qualsiasi carattere) pop\n\n");
 inizializza(&c1);
 do {
  elemento=getchar();
  switch (elemento) {
   case '#': printf("\n%c",pop(&c1));
   case 10 : break;
   default : push(&c1,elemento);
  }
 } while (elemento!='@');
 cancella(&c1);
}

La coda e' FIFO, se non sbaglio...
Non sbagli 
Igor Rossetti
Senjin Omukae

Che dire ... grazie 1000 per la disponibilità!
Sei stato veramente gentilissimo.
Ciao
Enrico S.

 cancella(&c1);
Qui si sta passando a cancella l'indirizzo di una istanza
di coda che non e' stata allocata con malloc(). Come fatto
notare in precedenza questo comportera' chiamare free() su
un puntatore non tornato da malloc con risultati imprevedibili.
Come nota conclusiva si potrebbe inoltre notare che quella
implementata nel sorgente non e' una "coda" (FIFO) ma una
"pila" (LIFO); qualcosa di decisamente diverso.
Restano altri appunti meno essenziali e opinabili sullo stile
che pero' tengo per me.
HTH
Andrea
--
Andrea Griffini, Programmer
http://www.netservers.com/~agriff

Lieto di esserti stato di aiuto.
Devo scusarmi con te per averti dato solo un mezzo aiuto. Come
giustamente fatto notare, la funzione cancella non e' concettualmente
corretta. Eccoti la versione corretta, con l'aggiunta che una volta
cancellata una coda, puoi riutilizzarla nuovamente senza invocare la
funzione inizializza();
void cancella(coda*c)
{
 if (c->link) {
  cancella(c->link);
  free(c->link);
  inizializza(c);
 }
}
Ma l'abbaglio piu' grande e' che ho letto male cio' che desideravi. Ti
ho mandato una pila e tu volevi una coda. Eccotela con le mie scuse.
Come al solito questa e' solo una delle infinite implementazioni, e
non vuole essere neanche la migliore. In particolare da questa
versione, con pochissime modifiche, puoi ottenere una "lista doppia".
typedef struct elemento {
 char elemento;
 struct elemento *testa;
 struct elemento *coda;
} lista;
void inizializza(lista *c)
{
 c->testa = NULL;
 c->coda  = NULL;
}
void cancella(lista *c)
{
lista *da_eliminare;
 da_eliminare=c->testa;
 while (da_eliminare) {
  c->testa = da_eliminare->coda;
  free(da_eliminare);
  da_eliminare=c->testa;
 }
 inizializza(c);
}
void stampa_lista(lista *c)
{
 printf("\ncontenuto della lista:");
 while (c->testa) {
  printf("\n<%c>",c->testa->elemento);
  c->testa = c->testa->testa;
 }
}
void push(lista *c, char elemento)
{
 lista *nuovo_elemento;
 nuovo_elemento=(lista *)malloc(sizeof(lista));
 if (nuovo_elemento) {
  inizializza(nuovo_elemento);
  nuovo_elemento->elemento = elemento;
  if (c->testa==NULL || c->testa==NULL) {
   /* e' il 1' elemento */
   c->testa = nuovo_elemento;
  } else {
   c->coda->testa=nuovo_elemento;
   c->coda->coda =nuovo_elemento;
  }
  c->coda = nuovo_elemento;
 } else {
  printf("\nNON HO PIU' MEMORIA!\n");
 }
}
char pop(lista *c)
{
 lista * da_eliminare;
 char da_restituire;
 if (c->testa) {
  da_restituire = c->testa->elemento;
  da_eliminare = c->testa;
  c->testa = da_eliminare -> testa;
  free(da_eliminare);
  if (c->testa==NULL)
   inizializza(c);
 } else {
  printf("\nLista vuota.\n");
  da_restituire=' ';
 }
 return(da_restituire);
}

Finalmente due sole inopinabili sviste su cui concordiamo:
1) il funzionamento non ortodosso della funzione "cancella"
2) il criterio di valutazione di un prodotto non solo attraverso un
soggettivo gusto estetico, ma anche tramite altri canoni quali la
sintassi, la semantica e la pragmatica.
Evidentemente, per le altre tue notazioni, anticipandoti che sono
piuttosto sicuro che scampero' dalla tua plausibile accusa di
correlazione del disastro di Pompei, pur riconoscendoti una innata
carica umoristica e un fine eloquio dialettico, glisserei
volontariamente per una serie di evidenti motivazioni, prima tra tutti
il rischio (non desiderato) di aggravare la tua probabile ulcera
gastro-intestinale.
Sono infinitamente grato ad Internet, che ti offre la possibilita' di
parlarmi con i toni usati finora, e ti pregherei di non lasciarti
condizionare neanche il giorno che scoprirai i miei titoli, la mia
professione, ..
Purtroppo, in passato, non sono riuscito bene a capire i tuoi pensieri
(forse perche' espressi formalmente come storielle di Fred), ma ti
confesso di essere sinceramente attratto dall'idea di conoscere quelli
che possono essere i tuoi convincimenti
algoritmici/programmatici/analitici, ed anelo il momento in cui tu
possa esplicitarli un po' meglio, in newsgroup idonei
(it.scienza.informatica;it.comp.programmare) o magari attraverso
qualche tuo applicativo del metodo di Newton con esplicazioni in serie
di Taylor, come chiesto nel messaggio "zeri di funzione".
Forse, piu' semplicemente asserisci (con parole tue) cio' in cui siamo
d'accordo.
Detto questo .... solo tu potresti trovare una continuazione polemica.

Detto questo .... solo tu potresti trovare una continuazione polemica.
Hmmm... questa non l'ho capita. Credo che la lascero' come
materiale di studio per gli appassionati di psichiatria.


  if (c->testa==NULL || c->testa==NULL) {
Interessante doppio confronto... saranno stati testa e coda
oppure una ridondanza voluta nel caso che un raggio cosmico
provocasse una alterazione di un registro della CPU proprio
durante l'esecuzione di questa istruzione ?
testa puo' essere NULL senza che sia NULL anche coda ?
Quale era il senso profondo dietro questo "or logico" ?
A parte queste insensatezze mi sembra che l'implementazione
fornita sia scadente... Se un nodo deve contenere un
carattere (supponiamo per un attimo che sia una cosa
ragionevole) perche' anche la coda ne deve contenere uno ?
Era proprio necessario avere due puntatori per ogni nodo ?
Io proporrei qualcosa di completamente diverso:
   #include <assert.h>
   #include <stdlib.h>
   #include <stdio.h>
 
   /*
   **                Coda
   **    _______ primo  ultimo ______
   **   |                            |
   **   |                            |
   **   V                            V
   **  Nodo --succ--> ... --succ--> Nodo
   **
   */
   typedef struct CODA
   {
     struct NODO *primo,*ultimo;
     int num_nodi;
   } Coda;
 
   typedef struct NODO
   {
     struct NODO *succ;
     char valore;
   } Nodo;
 
   /* Torna NULL se non basta la memoria */
   Coda *NewCoda(void)
   {
     Coda *c=malloc(sizeof(Coda));
     if (c)
     {
       c->primo=c->ultimo=NULL;
       c->num_nodi=0;
     }
     return c;
   }
 
   /* Elimina tutti gli elementi */
   void SvuotaCoda(Coda *c)
   {
     Nodo *n;
     assert(c);
     while ((n=c->primo)!=NULL)
     {
       c->primo=n->succ;
       free(n);
     }
     c->primo=c->ultimo=NULL;
     c->num_nodi=0;
   }
 
   /* Stampa gli elementi in coda */
   void StampaCoda(Coda *c)
   {
     Nodo *n;     
     assert(c);
     printf("La coda ha %i elementi:\n",c->num_nodi);
     for (n=c->primo; n!=NULL; n=n->succ)
       printf("'%c'\n",n->valore);
   }
   /* Elimina la coda; FreeCoda(NULL) == NOP */
   void FreeCoda(Coda *c)
   {
     if (c)
     {
       SvuotaCoda(c);
       free(c);
     }
   }
 
   /* Torna NULL se non basta la memoria */
   Nodo *Accoda(Coda *c,char valore)
   {
     Nodo *n;
     assert(c!=NULL);
     n=malloc(sizeof(Nodo));
     if (n)
     {
       n->valore=valore;
       n->succ=NULL;
       if (c->ultimo) c->ultimo->succ=n;
                 else c->primo=n;
       c->ultimo=n;
       c->num_nodi++;
     }
     return n;
   }
 
   /* Estrae un carattere dalla coda */
   char Estrai(Coda *c)
   {
     char v;
     Nodo *n;
     assert(c!=NULL && c->num_nodi>0);
     n=c->primo;
     v=n->valore;
     c->primo=n->succ;
     c->num_nodi--; free(n);
     if (c->primo==NULL)
     {
       c->ultimo=NULL;
     }
     return v;
   }
 
   /* Esempio d'uso */
   int main(void)
   {
     Coda *c1=NewCoda();
     if (c1)
     {
       if (Accoda(c1,'6') &&
           Accoda(c1,'5') &&
           Accoda(c1,'0') &&
           Accoda(c1,'2'))
       {
         StampaCoda(c1);
         putchar(Estrai(c1)); 
         putchar(Estrai(c1)); 
         putchar(Estrai(c1)); 
         putchar(Estrai(c1));
         puts("!");
       }
       else
       {
         fputs("Poca memoria...\n",stderr);
         exit(1);
       }
       FreeCoda(c1);
     }
     else
     {
       fputs("Comprami della RAM, tirchio!\n",stderr);
       exit(1);
     }
     return 0;
   }
HTH


Scusate. Correggo una inesattezza  di questa (estenuante) discussione.
la funzione proposta "stampa_lista" non doveva essere postata; il suo
uso era diretto ad altri scopi personali estemporanei.
Ovviamente deve essere:
void stampa_lista(lista *c)
{
 lista *scan;
 scan=c->testa;
 while (scan!=c->coda) {
  printf("%c",scan->elemento);
  scan=scan->testa;
 }
 if (c->coda)
  printf("%c",c->coda->elemento);
}
oppure per i cultori della ricorsione, in modo piu' libero dalla
applicazione:
void stampa_lista(lista *c)
{
    static unsigned long n_ordine=0;
 if (n_ordine++)
  printf("%c",c->elemento);
 if (c->testa)
  stampa_lista(c->testa);
 else
  n_ordine=0;
}
Domando nuovamente scusa della svista, ma come si dice: "anche
Michelangelo fece le sue cappelle!"
:-))