Ti spiego al volo il metodo "typedef":_
typedef [tipo] [nuovotipo]
quindi se io dichiaro
typedef int intero
vorrà dire che intero è come int.
Dunque se io scrivo
typedef struct mystruct {.....} miastruttura
significa che miastruttura è struct mystruct.
Questo semplifica anche molto la programmazione e velocizza la scrittura.
Volendo puoi non modificare il nome come ho fatto io e modificare con number al posto di struct list_book.Solo semplicità di lettura e scrittura o buona programmazione.
Veramente usi il puntatore nella char, o meglio tu non hai char ma un vettore di char,che soddisfa le prerogative di un puntatore e quindi lo puoi passare senza usare il riferimento,che altrimenti avresti dovuto scrivere:
scanf("%s",&book->title[0]);
invece scrivi
scanf("%s",book->title);
proprio perchè il c vede un vettore come se fosse un puntatore a dati contigui.
se avevi invece un semplice carattere char allora avresti dovuto passarlo tramite indirizzo:
char charval;
scanf("%c",&charval);