RISOLTO!
oltre il problema di cui ho appena parlato, rileggendo la tua frase..

prima facevi p->next con p=NULL
ora fai p->next , dove next ESISTE
..ho capito che l'errore fondamentale era che p lo utilizzo sì come puntaore, ma ho bisogno che sia un nodo, non solo un puntatore, in quanto gestisco i campi p->next e p->dato, che in un semplice putatore non esistono. che io sappia un puntatore di tipo nodo *p è semplicemente una cella di memoria che può contenere l'indirizzo di un nodo, e non presenta campi!
infatti ovunque appena nominavo p->next o p->dato (che non esistevano) andava in crash tutto (a 'sto punto strano però che non mi abbia dato l'errore!).
Ho risolto semplicemente allocando p come nodo con la malloc, come ho fatto per nuovo.
il codice dell'intera procedura è il seguente, e finalmente, funziona a meraviglia!!!

codice:
void inscoda() // operazione di inserimento in coda
{
     int n;    // dato da inserire
     nodo *nuovo;  // nuovo nodo
     nodo *p;   // puntatore d'appoggio
     nuovo = (nodo*)malloc(sizeof(struct nodo)); // alloca nuovo nodo
     p = (nodo*)malloc(sizeof(struct nodo)); // alloca il nodo d'appoggio

     printf ("\n Nuovo inserimento: ");
     scanf ("%d", &n); // legge dato da inserire
     
     nuovo->dato=n; // nel campo del dato inserisci n
     nuovo->next=NULL; // il nodo punta a NULL
     
     if(head==NULL)// se la lista è vuota 
     head = nuovo;// collega nuovo direttamente a head

     else
     {
       for ( p = head; p->next != NULL; p = p->next ); // scorri la lista finché p non punta all'ultimo nodo
       p->next = nuovo; //assegnazione dell'indirizzo del nuovo nodo al puntatore  
     }   
     return;
}
ti ringrazio ancora, credo di aver finalmente risolto... a risentirci!