Já bych k tomu ještě dodal, že docela záleží na tom, o co ti vlastně jde. Jestli je to jenom takové cvičení, aby sis vyzkoušel pokročilejší C, ok, nic proti. Pokud jsi v C začátečník a snažíš se na něj naroubovat něco, co znáš z jiných jazyků (Java apod.), tak to mi nepřijde jako dobrej nápad - dřív nebo později se do toho imho zamotáš a stejně se ti nepodaří získat chování, na které jsi byl zvyklý. Jestli se chceš učit C, tak se ho snaž poznat takové, jaké je, jak se používá, nesnaž se na něj naroubovat něco cizího...
A pokud z nějakého důvodu fakt
na vážno potřebuješ objektový přístup a zároveň C, tak by možná stálo za zvážení jít cestou
http://cs.wikipedia.org/wiki/Vala_%28programovac%C3%AD_jazyk%29 nebo nějakou podobnou.
---
P.S.
Znovupoužitelnost kódu nespočívá jenom v "objektovosti" a dědičnosti. Ve funkcionálním programování bys viděl spoustu znovupoužitelného kódu a žádná dědičnost se tam nepoužívá

Zrovna snažit se abstrahovat společné vlastnosti double- a single-linked listu mi nepřijde úplně dobrý příklad, množina společných operací* tam bude minimální (např. pokud bys chtěl takový "zobecněný" list třídit, jak to budeš dělat? Přidáš do double-linked nějaký callback, který ex post opraví vazby? Nebo budeš uvnitř funkce pořád ifovat?

To by bylo přesně to peklo, do kterýho se dostat nechceš

).
* tj. operací, které bys mohl jedním způsobem implementovat nad oběma typy seznamů
A ještě jeden tip bych měl: ke zobecňování můžeš přistupovat i tak trochu "z druhé strany" - pomocí přístupu, který se v Elixiru jmenuje protokoly (
http://elixir-lang.org/getting_started/16.html). Podobně to má i Go (
http://golangtutorials.blogspot.cz/2011/06/structs-in-go-instead-of-classes-in.html) Princip spočívá v tom, že si nadefinuješ nějakou množinu operací nad strukturou, naimplementuješ pro každý typ struktury zvlášť (nejsi ničím omezený!), ale přistupuješ k nim pak jednotným způsobem. V C bys to mohl udělat třeba tak, že bys měl strukturu callbacků a pak bys volal nějaké makro třeba sort(my_linked_list) a přeložilo by se ti to třeba na "my_linked_list -> sorting -> sort(my_linked_list)", kde tvůj typ obsahuje pointer na strukturu obsahující pointery na jednotlivé operace. Strukturu s pointery máš pak jenom jednu a každý "objekt" na ni má jenom ukazatel. (pointa: v OOP se začala děsně zdůrazňovat dědičnost a zapomnělo se na skládání

Pořád je to ale "neCéčkovský" přístup, který bys měl volit jenom z hodně dobrých důvodů.