1)tu considera la struct (SList)come uno scatolotto formato da un campo carattere e un campo puntatore allo scatolotto stesso.
Quindi L è un puntatore a questo "scatolotto".
Quando dichiari SList **pL dichiari un puntatore a puntatore di "scatolotto"(doppio puntatore)
-quindi quando fai pL = &L assegni a pL l'indirizzo del puntatore allo scatolotto.
Poichè * è l'operatore indirezione che se viene applicato ad un oggetto puntato restituisce il contenuto dell'oggetto stesso, *pL restituisce il valore del puntatore allo scatolotto cioè l'indirizzo al primo elemento della lista.(che poi naturalmente viene incrementato ).
**pL è semplicemente l'indirizzo del puntatore a puntatore di "scatolotto"...
bella "scatolotto" vero???
2)non è vero quello che dici, infatti c'è l'istruzione *pL = elem->next, cioè il puntatore viene spostato in avanti, poi viene free-ato il valore temporaneo elem.
3)restituisce uno short int... un intero. infatti fa un controllo.
se (L != NULL) restituisce 1 altrimenti 0.

non ho il tempo di provarla ma "purtroppo" a spanne la soluzione funziona...

ciao ciao