C - 匿名结构有哪些优势?

时间:2018-01-17 21:19:57

标签: c

我想知道为什么以及何时明确选择使用匿名结构:

typedef struct my_struct_t my_struct_t;

struct my_struct_t
{
    int a;
    int b;
};

int main()
{   

    my_struct_t obj1 =
    {
        .a = 33,
        .b = 44
    };

    return 0; 
}

而不是:

typedef struct my_struct_t my_struct_t;

struct my_struct_t
{
    int a;
    int b;
};

int main()
{   

    my_struct_t obj2;
    obj2.a = 55;
    obj2.b = 66;

    return 0; 
}

前者对后者和/或副词有何优势? 感谢

4 个答案:

答案 0 :(得分:2)

当您想要嵌套结构/联合而不指定特定的"含义时,匿名结构非常有用。到内部结构。它允许您访问内部结构的成员,就好像它们是封闭结构的直接成员一样。请参阅以下从cppreference.com获取的示例:

  

与union类似,是类型为结构的struct的未命名成员   没有名称被称为匿名结构。每个成员   匿名结构被认为是封闭结构的成员   或者工会。如果封闭的struct或union是递归的,则这适用   也是匿名的。

struct v {
   union { // anonymous union
      struct { int i, j; }; // anonymous structure
      struct { long k, l; } w;
   };
   int m;
} v1;

v1.i = 2;   // valid
v1.k = 3;   // invalid: inner structure is not anonymous
v1.w.k = 5; // valid

您展示的代码实际上与匿名结构无关。它是使用具有指定成员的初始化列表的示例。

希望它有所帮助:-)

答案 1 :(得分:1)

这是一个使用。在使用工会时,它的实现定义了在读取最后写入的工会成员时将获得的内容。但是,在结构的情况下,您可以检查常见的初始字段序列。这是一个例子来说明:

#include <assert.h>

struct S1 {
  int  type;
  char value;
};

struct S2 {
  int   type;
  float value;
};

union U {
  struct S1 s1;
  struct S2 s2;
};

int main() {
  union U un;
  un.s1.type = 1;
  un.s1.value = 'c';
  assert(un.s2.type == 1);
}

正如您在上面所看到的,C标准保证无论我写给un.s1.type什么,我都可以从un.s2.type读取。到现在为止还挺好。但是如果我尝试做这样的事情就会出现问题:

union U {
  struct S1 s1;
  int type;
};

现在无法保证。我们无法在标准的保护下从un.s1.type阅读un.type。但希望不会丢失,我们可以再次将它作为一个结构领域,一个匿名结构,如下:

union U {
  struct S1 s1;
  struct {
    int type;
  };
};

匿名结构的字段被“注入”封闭结构或联合,因此我们可以通过访问type来引用un.type。而现在又回到了标准的热烈拥抱。从现在开始,我们又有两个具有共同初始字段序列的结构。

答案 2 :(得分:1)

您的示例与匿名结构无关,但仅与初始化与分配有关。主要是当对象被声明为const时才重要:

const  my_struct_t obj1 =
{
    .a = 33,
    .b = 44
};

是正确的,而不是:

const my_struct_t obj2;
obj2.a = 55;   // error: try to assign to const object

匿名结构和联合允许使用子结构/联合的成员,就像它们是包含子/联合的成员一样。

C11的n1570草案在6.7.2.1中说明结构和联盟说明者§13说:

  

一个未命名的成员,其类型说明符是一个没有标记的结构说明符,称为   匿名结构;一个未命名的成员,其类型说明符是一个联合说明符   没有标签被称为匿名联盟。匿名结构或联合的成员   被认为是包含结构或联合的成员。这适用   如果包含的结构或联合也是匿名的,则递归地进行。

甚至给出一个(非规范的)例子:

struct v {
    union { // anonymous union
        struct { int i, j; }; // anonymous structure
        struct { long k, l; } w;
    };
    int m;
} v1;
v1.i = 2; // valid
v1.k = 3; // invalid: inner structure is not anonymous
v1.w.k = 5; // valid

答案 3 :(得分:0)

这不是一个匿名结构,只是使用指定的初始值设定项,特别是当您不需要为复杂结构的所有成员提供值时,就会使用它们。