c 在结构中使用枚举

itm*_*ork 5 c enums struct

我想enumc. 但是,我需要enum在另一个内部struct(以避免重复名称)。像这样的东西:

#include <stdio.h>

// define structure as our enum namespace
typedef struct {
    typedef enum {
        Host,
        Cookie,
        Agent
    } Name;
} header_n;

typedef struct {
    header_n::Name key; // using top enum
    char value[128];
} header_t;

int main() {

    header_t header;
    header.key = header_n::Agent;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

事实上,我想使用structfor myenum然后将其enum用作另一个结构中的单独类型,然后将最后一个结构称为完整类型,但我收到以下错误:

error: expected specifier-qualifier-list before 'typedef'
     typedef enum {

error: expected expression before ':' token
     header_n::Name key; // using top enum

error: bit-field '<anonymous>' width not an integer constant
     header_n::Name key; // using top enum

error: bit-field '<anonymous>' has invalid type

error: 'header_t {aka struct <anonymous>}' has no member named 'key'
     header.key = header_n::Agent;

error: expected expression before 'header_n'
     header.key = header_n::Agent;
Run Code Online (Sandbox Code Playgroud)

Joh*_*ode 8

几件事:

  1. structC 中的 s 只不过是数据的集合——它们没有“智能”。
  2. 您不能typedefstruct定义中使用;
  3. structC 中的定义不会创建新的命名空间;
  4. C 提供了 4 个命名空间——一个用于struct,unionenum标签,一个用于structunion成员,一个用于语句标签,一个用于所有其他标识符(变量名、函数名、typedef 名称、枚举常量等)。没有用户定义的命名空间,也没有::C 中的范围运算符。

您必须将枚举类型与类型分开定义struct

typedef enum { Host, Cookie, Agent } Name;

typedef struct {
  Name key;
  char value[128]
} header_t;
Run Code Online (Sandbox Code Playgroud)

或者enumstruct定义中使用非 typedef :

typedef struct
{
  enum key_t { Host, Cookie, Agent } key;
  char value[128];
} header_t;

int main( void )
{
  header_t header;
  header.key = Agent;
  ...
}
Run Code Online (Sandbox Code Playgroud)

即使我们在类型内定义了类型header_tenum key_t也可以在类型外使用;C不限制使用的key_t标签只是 header_t(再次,struct定义不创建一个新的命名空间)。所以可以这样做:

typedef struct
{
  enum key_t { Host, Cookie, Agent } key;
  char value[128];
} header_t;

int main( void )
{
  header_t header;
  header.key = Agent;
  enum key_t some_other_key = Cookie;
  ...
}
Run Code Online (Sandbox Code Playgroud)

你可以去掉key_t标签:

typedef struct
{
  enum { Host, Cookie, Agent } key;
  char value[128];
} header_t;
Run Code Online (Sandbox Code Playgroud)

所以你不能定义枚举类型之外的一个新实例struct,但你仍然可以使用枚举常量HostCookie以及Agent这个定义后,并将它们分配到一个整数对象:

int keyval = Host;
Run Code Online (Sandbox Code Playgroud)

由于枚举常量共享“所有其他标识符”命名空间,因此没有两种enum类型可以在它们之间使用相同的枚举常量;你不能做这样的事情

typedef enum { foo, bar, bletch } EnumType1;
typedef enum { bletch, foo, bar } EnumType2;
Run Code Online (Sandbox Code Playgroud)

编译器会抱怨说,每一个bletchfoo以及bar在第二enum定义已经被定义。如果要在两种不同的枚举类型之间使用相同的名称,则必须为它们创建唯一的前缀或后缀:

typedef enum { T1_foo, T1_bar, T1_bletch } EnumType1;
typedef enum { T2_bletch, T2_foo, T2_bar } EnumType2;
Run Code Online (Sandbox Code Playgroud)


klu*_*utt 7

这根本不可能。C 语言不支持它。C 要求您在全局空间中进行所有类型声明。或者更准确地说:C标准并没有要求类型声明,以工作-global空间。

因此,您只需为它们选择不同的名称。您可以通过以某种方式命名类型来模拟 C++ 中的命名空间功能,以完成基本相同的事情。像这样的东西:

typedef enum {
...
} foo_name;

typedef struct {
    foo_name name;
} foo;

typedef enum {
...
} bar_name;

typedef struct {
    bar_name name;
} bar;

typedef struct {
    bar_name name;
    foo_name name;
} foobar;
Run Code Online (Sandbox Code Playgroud)

  • 底线基本上是这样的:如果这个特性对你来说非常重要,那么不要使用 C。 (2认同)