Когда я должен набрать определение структуры против указателя на структуру? - PullRequest
8 голосов
/ 15 февраля 2012

Я не эксперт по низкоуровневым не объектно-ориентированным языкам программирования, и я нахожусь в процессе написания кода на C для проекта на работе. Я пытаюсь создать несколько приличных абстрактных типов данных для работы, и поиск в Google заставил меня осознать, что люди используют ADT на основе структур двумя способами. Некоторые люди определяют тип данных как структуру:

typedef struct adt {
    //content here
} adt;

и представьте его миру в заголовочном файле.

Другие определяют тип данных как указатель на структуру:

// In .c file:
typedef struct adt_s {
    //content here
} adt_s, *adt;


// In .h file:
typedef struct adt_s *adt;

Я понимаю, что этот подход позволяет вам вводить определение структуры, не давая внешнему миру никаких сведений о том, что находится внутри этой структуры, поэтому программисты могут только использовать функции, предоставленные в одном и том же заголовочном файле, для работы с этими данными типа.

Есть ли другие причины, чтобы выбирать над другими? Существует ли общее эмпирическое правило для случаев, когда ADT определяются как структуры и когда мы определяем их как указатели на структуры?

Ответы [ 3 ]

6 голосов
/ 15 февраля 2012

Вы можете также объявить структуру без typedef - единственные различия:

  • выглядит ли интерфейс чище с ключевым словом или без него struct
  • выглядит ли интерфейс чище с явным указателем или без него *

Например.

struct S1;
typedef struct S2 S2;
typedef struct S3_s *S3;

void foo1(struct S1 *arg);
void foo2(S2 *arg);
void foo3(S3);

Очевидно, что это применимо только к заранее объявленным структурам в заголовке интерфейса.

Если вы не скрываете реализацию структуры в первую очередь, выбор между S1 и S2 является вопросом предпочтения (или согласованности). Я бы не стал использовать S3, если это действительно непрозрачный / скрытый тип.

Личным предпочтением будет использовать S1 (явное ключевое слово struct) для больших / сложных агрегатов и S2 для небольших структур, которые вы можете рассматривать как значения и не всегда передавать по указателю. YMMV.

1 голос
/ 22 мая 2013

прочитайте Линус Торвальдс сообщение Глава 5: Typedefs

1 голос
/ 15 февраля 2012

Решение о том, скрывать или не скрывать, целиком зависит от вас, как от дизайнера вашей библиотеки.Если вы хотите оставить за собой право изменить свой struct по желанию в будущем, вы не должны подвергать кого-либо из его членов «миру».Если вы предоставляете struct как средство для связи с вашей библиотекой в ​​первую очередь (например, struct, представляющий точку в 3D), то вы не сможете скрыть ее членов от мира, так как это нанесет ущерб цели.

...