используя ключевое слово struct в объявлении переменной в C ++ - PullRequest
24 голосов
/ 11 октября 2011

У меня такое чувство, что это может быть связано с синтаксисом Си, но я начал программировать с C ++, поэтому я не уверен.

В основном я видел это:

struct tm t;
memset( &t, 0, sizeof(struct tm) );

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

tm t;
memset( &t, 0, sizeof(tm) );

В чем разница между ними и почему вместо них используется первый?

Обновление

Структура tm, на которую я ссылаюсь, находится в wchar.h, и определение таково:

struct tm {
        int tm_sec;     /* seconds after the minute - [0,59] */
        int tm_min;     /* minutes after the hour - [0,59] */
        int tm_hour;    /* hours since midnight - [0,23] */
        int tm_mday;    /* day of the month - [1,31] */
        int tm_mon;     /* months since January - [0,11] */
        int tm_year;    /* years since 1900 */
        int tm_wday;    /* days since Sunday - [0,6] */
        int tm_yday;    /* days since January 1 - [0,365] */
        int tm_isdst;   /* daylight savings time flag */
        };

Ответы [ 6 ]

15 голосов
/ 11 октября 2011

Простой ответ заключается в том, что ключевое слово struct присутствует там, чтобы ограничить поиск идентификатора tm только определяемыми пользователем типами классов . Вероятно, он оставлен для совместимости с C, где это требуется.

Вопреки тому, что говорят другие, не существует такой вещи, как auto-typedef , и при этом C и C ++ не отличаются в зависимости от того, как управляются идентификаторы для пользовательских типов. Разница только в поиске.

Вы можете прочитать больше здесь

11 голосов
/ 11 октября 2011

В C имена тегов struct не образуют идентификаторы в глобальном пространстве имен

struct not_a_global_identifier { /* ... */ };

Чтобы обратиться к этой структуре, вы должны использовать ключевое слово struct (чтобы указать пространство имен)

struct not_a_global_identifer object;

или создайте новый идентификатор в глобальном пространстве имен с typedef

typedef struct not_a_global_identifer { /* ... */ } global_name_space_identifier;

В C имеется 4 пространства имен, см. 6.2.3 в C99 Standard :

  • названия этикеток
  • теги структур, союзов и перечислений
  • члены структур или союзов (ни одно пространство имен ... столько, сколько определено структур или союзов)
  • global пространство имен, для всех остальных идентификаторов

Это легальная программа на C: -)

int main(void) {
  typedef struct foobar { int foobar; } foobar;
  foobar boo;
  boo.foobar = 42;
  if (boo.foobar) goto foobar;
foobar:
  return 0;
}
1 голос
/ 11 октября 2011

В вашем примере tm может быть типизированной структурой.

например.

typedef struct tm_t
{
  int x; 
}tm;

и тогда вы можете сделать

tm t; 
1 голос
/ 11 октября 2011

Использование struct tm t; для совместимости с C, в котором объявление структуры с именем "tm" определяет тип с именем "struct tm", но не тип с именем "tm" (в отличие от C ++, в котором оба имени для типа объявлены).

1 голос
/ 11 октября 2011

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

Когда вы ссылаетесь на tm, компилятор C (какC ++ one) будет искать этот идентификатор в глобальном пространстве идентификаторов.Затем компилятор C ++ выполнит поиск в пространстве идентификаторов пользовательских типов, если он не обнаружил символ раньше.

По сути, если вы хотите вести себя так же, как в C ++, добавьте эту строку:

typedef struct tm tm;

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

typedef struct tm { int field } tm;

Или используя анонимную структуру:

typedef struct { int field } tm;

То же поведение применимо к enum иunion:

typedef enum { VALUE } myEnum;
typedef union { int integer; char charArray[4]; } myUnion;
0 голосов
/ 11 октября 2011

Вы можете увидеть ссылку, приведенную ниже, и цитату оттуда: «В C вы должны явно использовать ключевое слово struct для объявления структуры. В C ++ это не нужно после определения типа». Смотрите ссылку для получения дополнительной информации и примеров.

http://msdn.microsoft.com/en-us/library/64973255%28v=vs.80%29.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...