C语言 结构体中的结构体和周围结构体中的命名匿名结构体有什么区别?

bfrts1fy  于 2023-04-29  发布在  其他
关注(0)|答案(3)|浏览(180)

示例:

#include <stdio.h>

struct not_inner {
    int a;
    int b;
};

struct outer {
    struct {
        int a;
        int b;
    } x;
    
    struct not_inner y;
};

int main()
{
    struct outer O = {1, 2, 3, 4};
    //x.a = 5;
    

    printf("%d %d %d %d", O.x.a, O.x.b, O.y.a, O.y.b);

    return 0;
}

主要是,我感兴趣的是x和y之间的区别:

  • C99标准
  • 存取速度
  • 范围
gzszwxb4

gzszwxb41#

适用范围:
xy仅作为struct outer对象的成员存在。
struct outerstruct not_inner的作用域为转换单元(.c文件)。
[C99§6.7.2.1¶7] struct-declaration-list在struct-or-union-specifier中的存在声明了一个新类型,在翻译单元中。[...]
速度:
类型在运行时不存在。O.x.aO.y.a都直接访问成员。因此,声明的细节对速度没有影响。即使有,你也不会在标准中找到这个。

s4n0splo

s4n0splo2#

结构体中的结构体和周围结构体中的命名匿名结构体有什么区别?
“[N]amed anonymous struct”是一个奇怪的短语,但我认为您指的是struct outer的成员x。我将其称为类型为未标记结构类型的成员。它绝对不是一个 * 匿名结构体 * --它有一个特定的、更自然的含义和不同的意义。
主要是,我感兴趣的是x和y之间的区别:

  • C99标准

这两种形式同样符合C99和C的所有后续版本。

  • 存取速度

没有理由期望由于是否标记结构类型而引起的访问速度的任何差异。结构标记没有运行时表示。

  • 范围

除非有typedef别名,否则不能在其出现的声明之外引用未标记的结构类型。但这并不影响对使用该类型声明的任何对象的访问,也不影响对它们的成员的访问,也不阻止声明 * 兼容 * 类型。您可以用outer.xouter.y可以做的任何事情,但是您可能想做的一些事情需要更多的x代码。
请注意,您为x提供的特定形式有点不寻常(尽管肯定不是未知的),但沿着这些路线的变化相对常见:

typedef struct {
    int a;
    int b;
} untagged_struct;

struct outer2 {
    untagged_struct x;
    
    struct not_inner y;
};

outer2.x的类型也是未标记的结构类型。使用typedef别名基本上解决了所有可能导致outer.x上的某些操作比outer.y上的类似操作需要更多代码的问题。
然而,作为一种风格,我个人倾向于避免使用typedef,尤其是结构类型。我宁愿写(并看到)struct my_struct而不是只写my_struct或类似的东西。

sqyvllje

sqyvllje3#

在C中没有“命名匿名结构”这样的概念。
匿名结构的概念定义如下(6.7.2.1结构和联合说明符)
13结构类型的未命名成员没有标记称为匿名结构;
在你的程序中没有匿名结构。
结构struct outer

struct outer {
    struct {
        int a;
        int b;
    } x;
    
    struct not_inner y;
};

声明了未命名结构的数据成员(没有结构标记名)。因此,与结构struct not_inner相反,您不能引用未命名的结构说明符。
标记名outernot_inner具有文件范围。
访问未命名结构和结构not_inner的数据成员的速度没有差异。

相关问题