ho usato parte della tua funzione, dato che la mia lista nn puo' mai essere NULL, cmq ora mi interessa solo capire

questo è il codice - spero di nn averlo modificato

codice:
#include <stdio.h>
#include <stdlib.h>

struct hello {
	int n;
	struct hello *next;
};

typedef struct hello hello;


/* Funzione che crea il primo elemento */
hello *crea(hello *p, int ins)
{
	p = malloc(sizeof(hello));
	p->n = ins;
	p->next = NULL;
	return p;
}

/* Crea elementi successivi */
hello *aggiungi(hello *p, int ins)
{
	hello *paus;
	if (p->next == NULL) {
		paus = malloc(sizeof(paus));
		paus->n = ins;
		paus->next = p;
	} else {
		p = aggiungi(p->next, ins);
	}
}

/* Funzione ricorsiva che stampa la lista */
void stampa(hello *p)
{
	if (p == NULL)
		printf("NULL\n");
	else {
		printf("%d -> ", p->n);
		stampa(p->next);
	}
}


main()
{
	hello *puntLista;
	int ins;
	printf("Inserisci il primo elemnto - 0 per finire\n");
	scanf("%d", &ins);
	puntLista = crea(puntLista, ins);
	while (ins != 0) {
		printf("Inserisci elemento successivo\n");
		scanf("%d", &ins);
		puntLista = aggiungi(puntLista, ins);
	}
	stampa(puntLista);
}
questo è l'output
codice:
bash-2.05b$ gcc ll.c -o ll
bash-2.05b$ ./ll
Inserisci il primo elemnto - 0 per finire
1
Inserisci elemento successivo
2
Inserisci elemento successivo
3
Inserisci elemento successivo
0
1 -> NULL