在C++中的变量声明中使用struct关键字

voi*_*ter 25 c++ struct

我觉得这可能与C语法有关,但我用C++开始编程,所以我不确定.

基本上我已经看到了这个:

struct tm t;
memset( &t, 0, sizeof(struct tm) );
Run Code Online (Sandbox Code Playgroud)

我对这种语法有点困惑,因为通常我希望上面的内容看起来像这样:

tm t;
memset( &t, 0, sizeof(tm) );
Run Code Online (Sandbox Code Playgroud)

这两者之间有什么区别,为什么要使用前者呢?

更新

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 */
        };
Run Code Online (Sandbox Code Playgroud)

Dav*_*eas 16

简单的答案是存在struct关键字以限制标识符的查找tm仅限于用户定义的类类型.可能需要与C兼容.

与其他人所说的相反,没有auto-typedef这样的东西,C和C++在管理用户定义类型的标识符方面也不一样.唯一的区别在于查找.

你可以在这里阅读更多

  • C和C++在如何管理用户定义类型的标识符方面确实有两种不同.首先,在C中,`struct`s,`union`s和`enum`的名称位于一个单独的命名空间中,在查找这些关键字后面的名称时,使用它来代替普通命名空间.这样的名称永远不会与C中的其他名称冲突,除非他们遵循其中一个关键字,否则永远不会找到这样的名称.C++有特殊规则允许冲突并解决冲突,但前提是存在冲突. (2认同)

pmg*_*pmg 12

在C中,结构标记名称不在全局名称空间上形成标识符

struct not_a_global_identifier { /* ... */ };
Run Code Online (Sandbox Code Playgroud)

要引用该结构,您必须使用关键字struct(以指定名称空间)

struct not_a_global_identifer object;
Run Code Online (Sandbox Code Playgroud)

或者在全局名称空间中创建一个新标识符 typedef

typedef struct not_a_global_identifer { /* ... */ } global_name_space_identifier;
Run Code Online (Sandbox Code Playgroud)

C中有4个名称空间,参见C99标准中的 6.2.3 :

  • 标签名称
  • 结构,联合和枚举的标签
  • 结构或联合的成员(不是单个名称空间......定义了结构或联合的数量)
  • 全局名称空间,用于所有其他标识符

这是一个合法的C程序:-)

int main(void) {
  typedef struct foobar { int foobar; } foobar;
  foobar boo;
  boo.foobar = 42;
  if (boo.foobar) goto foobar;
foobar:
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • 所以基本上考虑到这一点,在 CI 中可以声明一个名为 `struct foo {};` 的全局结构,并且在它旁边还有一个具有相同名称的全局变量 `int foo;` 并且不会有冲突吗? (2认同)
  • 是.您可以在不同的名称空间中使用相同的标识符.在上面的代码中,`foobar`同时是一个类型(*global*name space),一个结构成员(*member*name space),一个结构标记(*tag name space*)和一个标签(*标签*名称空间). (2认同)