C Typedef и структура вопроса - PullRequest
10 голосов
/ 10 июля 2009

В чем разница между этими двумя декларациями, и одно из них предпочтительнее другого?

typedef struct IOPORT {  
    GPIO_TypeDef* port;  
    u16           pin;  
} IOPORT;  

typedef struct {  
    GPIO_TypeDef* port;  
    u16           pin;  
} IOPORT;  

Ответы [ 4 ]

15 голосов
/ 10 июля 2009

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

8 голосов
/ 03 ноября 2009

C имеет четыре различных пространства имен, где пространство имен тега структуры является одним из них. Следовательно:

struct foo { int bar; };

не определяет новый тип в общем смысле. Если у вас есть только тег структуры, вам необходимо добавить ключевое слово struct в объявлениях объектов, например:

foo b; /* error */
struct foo b; /* correct */

Кроме того, вы можете сразу создать новый объект в определении следующим образом:

struct foo { int bar; } baz;

Где baz - это объект типа структуры foo. Тем не менее, часто требуется определить структуру как новый тип, чтобы сохранить некоторые записи. Полный тип не ссылается на теги структуры, поэтому вы можете опустить префикс 'struct' во время объявлений.

typedef struct foo { int bar; } baz;

Тем не менее позволяет вам объявлять объекты с помощью 'struct foo', так как foo является тегом struct. Но теперь он превращается в полный тип в «пространстве имен» нормального типа, где он называется типом baz. Так что с typedef, поля (поля) 'baz' имеют различную семантику.

Если вам не нужно объявлять указатели на тип структуры внутри себя (связанные списки, древовидные структуры), пропустите его. Добавление того, которое не требуется, просто загрязняет пространство имен.

8 голосов
/ 10 июля 2009

Что касается того, какой стиль предпочтительнее, я предпочитаю первый стиль (с именем в теге struct и как typedef для структуры) просто потому, что в исходном файле нет недостатков, кроме нескольких символов. Фрагмент struct моей среды IDE удаляет имя в обоих местах, поэтому я всегда получаю имя структуры с определением типа вместе с именем тега структуры.

Вы получаете несколько небольших преимуществ:

  • "struct STRUCTNAME" может использоваться для объявления указателей на структуру внутри структуры
  • Вы можете обойтись, просто используя STRUCTNAME в коде C или C ++
  • вы предотвращаете потенциальную (даже очень редкую на практике) странность в C ++, связанную с использованием имени структуры, используемого для другого объекта без ошибок или предупреждений

Но, если мне удастся вручную ввести определение структуры, я часто лениво пренебрегаю объявлением одного или другого имени.

0 голосов
/ 10 июля 2009

Первый пример позволяет вам использовать объект внутри себя для вещей, лежащих связанных списков и деревьев (как Виктор указывает ). Второй пример анонимных типов, которые, как показал опыт, не очень хорошо работают со всеми компиляторами. Поэтому первый подход, вероятно, рекомендуется. Если вас не интересует возможность структуры ссылаться на себя, вы всегда можете дать ей имя, которое вряд ли будет конфликтовать, например, __SOMEPREFIX_IOPORT__.

...