Как объявить указатель на структуру?

Тема в разделе "LANGS.C", создана пользователем Magnum, 6 янв 2012.

  1. Magnum

    Magnum New Member

    Публикаций:
    0
    Регистрация:
    29 дек 2007
    Сообщения:
    925
    Редактирую гавно-код.
    Вместо того, чтобы сделать вот так:

    Код (Text):
    1. typedef struct _BLABLASTRUCT
    2. {
    3.  //....
    4. } BLABLASTRUCT, *PBLABLASTRUCT, **PPBLABLASTRUCT;
    5.  
    6. BLABLASTRUCT Bla;
    Программист делал вот так:
    struct
    {
    // ...
    };

    Что заставило его так сделать я не знаю. Т.к. данная структура встречается очень часто, где-то около 1000 раз.
    И вот мне понадобилось объявить указатель на подобную структуру.


    Как сделать указатель на стуктуру, которая находится внутри другой структуры и объявлена просто
    struct
    {
    // ...
    }

    ??
     
  2. GRRRLPower

    GRRRLPower New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2010
    Сообщения:
    46
    Сделай указатель на первый мембер этой безымянной структуры. Код не обязательно говно только лишь потому, что в нем есть безымянные вложенные структуры :)
     
  3. Monogen

    Monogen New Member

    Публикаций:
    0
    Регистрация:
    5 сен 2008
    Сообщения:
    90
    В коде должно быть место, где такие структуры используются. Посмотри как сделано там. Не стал же бы программист просто объявлять такие структуры и нигде их не использовать.
     
  4. GRRRLPower

    GRRRLPower New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2010
    Сообщения:
    46
    Простой пример, где такое есть, прямо из WinNT.h:

    Код (Text):
    1. typedef union _LARGE_INTEGER {
    2.     struct {
    3.         DWORD LowPart;
    4.         LONG HighPart;
    5.     } DUMMYSTRUCTNAME;
    6.     struct {
    7.         DWORD LowPart;
    8.         LONG HighPart;
    9.     } u;
    10. #endif //MIDL_PASS
    11.     LONGLONG QuadPart;
    12. } LARGE_INTEGER;
    DUMMYSTRUCTNAME - это дефайн без значения.
     
  5. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Magnum

    В C++0х это можно было бы сделать через auto / decltype. В прерыдущих версиях, включая плоский си - никак. Начать хотя бы с того, что безымянные структуры запрещены в C++ (насчет си не уверен). Ну а локальные типы не видны вне выражения. Безымянную структуру скорее всего можно отнести к такому типу. Я про что-то вроде

    Код (Text):
    1. class foo { ... };
    2.  
    3. typedef std::shared_ptr<class foo> foo_ptr; // В данном случае foo будет взят не внешний, а свой собственный, локальный, видимый в пределах выражения.
     
  6. Dmitry_Milk

    Dmitry_Milk Member

    Публикаций:
    0
    Регистрация:
    20 ноя 2007
    Сообщения:
    540
    Кстати, попутно задам вопрос.

    В чем преимущество или правильность объявления структурного типа
    Код (Text):
    1. typedef struct _MyStructType
    2. {
    3.   ...
    4. } MyStructType;
    или
    Код (Text):
    1. typedef struct
    2. {
    3.   ...
    4. } MyStructType;
    по сравнению с
    Код (Text):
    1. struct MyStructType
    2. {
    3.   ...
    4. };
    ?
    Еще с институтских времен сложилась привычка использовать именно последний вариант (фактически, аналогично использованию class, тем более что class и struct отличаются вроде бы только умолчанием относительно private и public).

    Причем использовал последний вариант даже вроде бы просто в чистом C (тогда еще борландский TurboC), и ни компилятор, ни преподы не ругались.
     
  7. Ezrah

    Ezrah Member

    Публикаций:
    0
    Регистрация:
    22 мар 2011
    Сообщения:
    411
    Dmitry_Milk
    Тут всё просто. Если в C вы используете третий вариант, в коде придётся писать
    Код (Text):
    1. struct MyStructType first_struct;
    2. struct MyStructType *some_func(struct MyStructType *ps);
    и т.д.
    Чтобы опустить использование ключевого слова struct, применяют typedef. Чтобы еще больше сократить количество печатаемых символов, объявление структуры и использование typedef совмещают, хотя можно было сделать так:
    Код (Text):
    1. struct _MyStructType {
    2.   ...
    3. };
    4. typedef struct _MyStructType MyStructType;
    Следующие строки попарно эквивалентны, если используется первый вариант:
    Код (Text):
    1. struct _MyStructType first_struct;
    2. MyStructType first_struct;
    3. struct _MyStructType *some_func(struct _MyStructType *ps);
    4. MyStructType *some_func(MyStructType *ps)
    Использование второго варианта исключает возможность использовать определения переменных с помощью ключевого слова struct, т.е. первую и третью строки в вышеприведенном участке кода.

    Есть, кстати, четвёртый вариант:
    Код (Text):
    1. struct {
    2.   ...
    3. } my_struct;
    Тут объявление и определение объединены; такую конструкцию удобно использовать, чтобы соблюсти порядок локальных переменных.
    Код (Text):
    1.   struct {
    2.     uint32_t data_offset;
    3.     uint32_t data_size;
    4.     uint32_t next_record;
    5.   } file_record;
    6.  
    7.   uint32_t next_record = first_record;
    8.   while (next_record) {
    9.     fseek(f, next_record, SEEK_SET);
    10.     fread(f, &file_record, sizeof(file_record);
    11.     next_record = file_record.next_record;
    12.     // ...
    13.   }
    Но, конечно, если требуется многократное использование такой структуры, следует объявить её другим вариантом.
     
  8. Psionic

    Psionic Member

    Публикаций:
    0
    Регистрация:
    25 сен 2008
    Сообщения:
    156
    Обьявит гдето такуюже точно структуру но с именем и юзать указатель ее типа - кастыль Аднако, но рабочий.
     
  9. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    Dmitry_Milk
    В структуре - адрес на свой собственный тип (связный список).
    Код (Text):
    1. typedef struct _TLinkListNode
    2. {
    3.     BYTE    m_Data [124];
    4.     struct _TLinkListNode*  m_pNext;
    5. }
    6. TLinkListNode;