Punteros y asignación, ¿cómo funciona con diferentes tipos?

Estoy haciendo "Aprende C de la manera difícil" para el autoaprendizaje que viene de conocer un poco de Python. He leído varios tutoriales, pero no puedo entender cómo funcionan los punteros y la asignación. Entiendo que si no hace referencia al puntero, puede asignarle un valor directamente como en:

int *anint = 42;

Pero, ¿qué hay de hacer referencia específicamente a la ubicación de la memoria de una variable ya creada? Específicamente, lo intenté:

char *pointer_to_strlit;
char *strlit = "some stuff";
pointer_to_strlit = &strlit;

¿Por qué lo siguiente provoca una falla de seguridad después de hacer esto?

printf("I print strlit: %s\nI print it again by pointing to it: %s\nI print where the pointer is pointing: %p\n", strlit, *pointer_to_strlit, pointer_to_strlit);

Los tipos en C parecen realmente difíciles de decir cómo se comportarán y cómo usar los punteros para hacer referencia a los tipos específicos. ¿Existe una guía clara que describa específicamente la sintaxis para señalar cada tipo de datos diferente (char, *char, *char[], int, struct, void, null, funciones, etc.)? Incluso una lista de pasos que me ayude a entender el conjunto de reglas sería útil.

Respuestas a la pregunta(3)

Su respuesta a la pregunta