질문이 정확하게 이해되지 않습니다.
778쪽의 예제는 구조체를 포인터로 할당하고, void 포인터에 할당해서도 접근하는 것을 보여주는 것입니다.
void 포인터 자체에는 접근할 수 없습니다. 따라서 접근하려면 반드시 먼저 변환을 해야 합니다.
779쪽에서 ((struct Data*)ptr)->c1로 접근하는 것은 ptr이 void 포인터이기 때문입니다.
심사문제는 void 포인터에 구조체를 할당하고, 전혀 다른 구조체의 값을 void 포인터로 할당한 구조체에 복사한 후에 출력하는 문제입니다. ptr이 void 포인터이므로 값을 출력하기 위해 변환을 합니다.
778쪽은 구조체 포인터 d1을 할당했고, ptr은 d1에 접근하기 위해 사용했습니다. 따라서 d1과 ptr은 같은 메모리 공간을 가리킵니다.
58.13의 심사문제는 구조체 포인터를 void 포인터 ptr에 할당했고, 포인터가 아닌 구조체 st를 선언했습니다. st 구조체의 값을 ptr에 있는 구조체에 복사했습니다. 메모리 그림을 그려보면 ptr과 st는 각자 다른 메모리 공간을 사용합니다. st.mana = 0처럼 초기화해버리는 이유이기도 합니다.
질문의 요지가 이해가 안 되는데, 최대한 정리하자면
1. 두 예제는 메모리를 그림으로 그려보면 전혀 다릅니다.
778쪽은 같은 메모리 공간을 공유하는 그림입니다.
심사 문제는 다른 메모리 공간을 사용하는 그림입니다.
2. void 포인터는 접근하려면 항상 변환해야 합니다.
778쪽처럼 간접 참조하는 형태여도 멤버에 접근하려면 변환해야 합니다.
심사문제처럼 직접 할당해서 참조하는 형태여도 멤버에 접근하려면 변환해야 합니다.