Ответ 1
Это наиболее часто используется для целей библиотеки. Основным принципом типа Opaque в c является использование данных, хотя его указатель, чтобы скрыть реализацию обработки данных. Поскольку реализация скрыта, вы можете изменить библиотеку, не перекомпилируя какую-либо программу, зависящую от нее (если интерфейс соблюден)
например: версия 1:
// header file
struct s;
int s_init(struct s **x);
int s_f(struct s *x);
int s_g(struct s *x);
// source file
struct s { int x; }
int s_init(struct s **x) { *x = malloc(...); }
int s_f(..) { ... }
int s_g(..) { ... }
версия 2
// header file
struct s;
int s_init(struct s **x);
int s_f(struct s *x);
int s_g(struct s *x);
// source file
struct s { int y; int x; }
int s_init(struct s **x) { *x = malloc(...); }
int s_f(..) { ... }
int s_g(..) { ... }
С вашей стороны программы ничего не изменилось! и, как говорилось ранее, нет необходимости перекомпилировать каждую отдельную программу, которая полагается на нее.