Страницы

Поиск по вопросам

среда, 27 ноября 2019 г.

Зачем typedef объвлять с одним и тем же типом

#c #структуры #объявление #typedef


Наверно какие-то C-шные ухищрения. Навроде их классов. Вроде бы и объявление тут
уже есть. Может поэтому? Вот такая строка например (из OpenCV):

typedef struct CvFileStorage    CvFileStorage;


Зачем же так писать? Не нашел никак, сходу, ответ на это. Когда-то (несколько лет
назад), помню что читал об этом. Тогда чистый C был в моде наверное, а сейчас такое
позабыто получается. Еще подобное видел в коде от Windows CE6 и др. Это запомнил:),
а для чего нужно не помню никак. Если еще какие-то доп. куски кода надо привести, то
скажите. Эта строка стоит перед структурой, которая у себя где-то в поле использует
тип из этого typedef-а. Но зачем так писать, а не просто объявить его? Спасибо.
    


Ответы

Ответ 1



Имеется по крайней мере две веские причины объявить этот typedef. typedef struct CvFileStorage CvFileStorage; Первая причина заключается в том, что в C программах вы должны указывать ключевые слова struct или enum перед именем структуры или перечисления. Это выглядит обременительно при вводе кода. Очень часто программисты забывают указать эти слова, что приводит к появлению ошибки компиляции. Поэтому этот typedef упрощает жизнь программистам, позволяя им не писать эти ключевые слова перед именем структуры или перечисления. Вторая причина состоит в том, что имена структур и другие идентификаторы находятся в различных пространствах имен. Поэтому одно и то же имя можно использовать для объявления структуры и обычной переменной. Например, следующий фрагмент кода является корректным struct CvFileStorage { //... }; int CvFileStorage; В этом фрагменте кода объявляется структура с именем CvFileStorage и переменная типа int с тем же самым именем. Эти объявления не конфликтует друг с другом, так как, как уже было написано, перед именем структуры обязательно должно следовать ключевое слово struct . В C вы можете записать, к примеру struct CvFileStorage { int CvFileStorage; } CvFileStorage; Это объявление корректно, так как эти три совпадающих идентификаторs находятся в различных пространствах имен. Однако это может вводить в заблуждение читающих код, так как если программист по ошибке опустит ключевое слово struct перед именем структуры, то может оказаться, что код по-прежнему с точки зрения синтаксиса языка будет корректным, хотя на самом деле имелась в виду структура, а не переменная с таким же именем. Например, в данном выражении программист по невнимательности забыл указать ключевое слово struct, и тем не менее получил корректное выражение, так как имеется переменная с таким же именем sizeof( CvFileStorage ) Чтобы избежать такой путаницы также целесообразно резервировать это имя без ключевого слова struct для имени структуры, используя typedef.. В С++ ключевое слово struct можно опускать при обращении к структуре. Тогда возникает вопрос: а как быть с тем, что в C можно объявлять переменную или функцию с таким же имеенем как имя структуры? Этот вопрос решается следующим образом: имя переменной или имя функции скрывает объявление структуры с тем же самым именем. Поэтому при обращении к структуре надо указывать уточненное имя. Например, struct CvFileStorage { //... }; void CvFileStorage(); В этом фрагменте кода объявление функции скрывает объявление одноименной структуры. Поэтому если, например, вы хотите объявить объект этой структуры, то надо будет указывать уточненное имя структуры. struct CvFileStorage obj; Или, например, можно написать такие объявления struct CvFileStorage { //... }; void CvFileStorage( struct CvFileStorage ); Эти имена не будут конфликтовать друг с другом, так как для структуры используется ее уточненное имя.

Ответ 2



В с++ если нужно объявить переменную типа структуры, нужно просто написать имя типа и переменную. В чистом си это не так. И нужно всегда писать struct. Это все потому, что типы для структур и остальные типы как бы находятся в разных областях видимости. Но так как программисты существа ленивые, то лучше один наз написать typedef struct CvFileStorage CvFileStorage; и потом не задумываться, почему оно не компилируется (потому что забыли struct) или почему оно работает как то странно (потому что забыли struct, а кто то объявил свой тип не структуру с таким же именем). Но часто пишут ещё интереснее: typedef struct { // тут объявление структры } struct_name; В этом случае создается сразу все так, как привычно в обычном с++.

Ответ 3



Без этого typedef при любом упоминании структуры CvFileStorage надо писать полностью: struct CvFileStorage cv; void func(struct CvFileStorage* cv); и так далее. При наличии объявления typedef слово struct можно выбрасывать: CvFileStorage cv; void func(CvFileStorage* cv);

Комментариев нет:

Отправить комментарий