C中的隐式结构定义 [英] Cryptic struct definition in C

查看:200
本文介绍了C中的隐式结构定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了以下迷宫定义代码:

typedef struct mazeNode {
    int hasCheese;
    int tag;
    struct mazeNode *left;
    struct mazeNode *right;
} maze_t;

maze_t maze = {
    .tag = 1,
    .left = &(maze_t) {
        .left = &(maze_t) {
            .left = &(maze_t) {},
            .right = &(maze_t) {}
        },
        .right = &(maze_t) {
            .right = &(maze_t) {}
        }
    },
    .right = &(maze_t) {
        .tag = 8,
        .left = &(maze_t) {},
        .right = &(maze_t) {
            .tag = 10,
            .left = &(maze_t) {
                .tag = 11,
                .left = &(maze_t) {
                    .hasCheese = 1,
                    .tag = 12
                }
            },
            .right = &(maze_t) {}
        }
    }
};

从链接的博客文章中,我了解到他们正在尝试定义二进制文件图中带有奶酪的树.

From the linked blog post I understand that they are trying to define the binary tree with the cheese in the diagram.

但是,我似乎无法从C代码应该做的事情中脱颖而出.如果有人可以向我解释一下,那就太好了.

However I can't seem to make head or tail out of what the C code is supposed to do. It would be great if someone could explain it to me.

推荐答案

此代码使用了指定的初始化程序复合文字,它们都是 C99功能,我链接到其他答案,其中我为这两个功能提供了标准引号.

This code is using a combination of designated initializers and compound literals, which are both C99 features, I linked to other answer where I provide standard quotes for both of these features.

指定的初始化程序允许您使用指定的特定字段使用.fieldname =进行初始化,链接文档中的示例为:

Designated initializers allow you to use specify a specific field to initialize using .fieldname =, an example from the linked document is:

 struct point { int x, y; };

以下初始化

struct point p = { .y = yvalue, .x = xvalue };

等同于

struct point p = { xvalue, yvalue };

正在使用的另一个功能是复合文字,用于创建未命名的静态对象,然后代码获取该对象的地址并为其分配相应的指针leftright.然后,它将在未命名对象中递归使用此功能来设置它们各自的leftright指针.

The other feature being used is compound literals which is being used to create unnamed static objects and then the code takes the address of this object and assigns it the respective pointers left and right. It then uses this feature recursively within the unnamed objects to set their respective left and right pointers.

 .left = & (maze_t) { .... }
           ^^^^^^^^^^^^^^^^
           unnamed static object

这些未命名的对象只有在函数体之外使用时才是静态的,否则它们将具有自动存储期限,并且一旦退出该函数就将不复存在,因此像代码那样使用它们的地址可能是不明智的

These unnamed objects are only static if they are used outside the body of a function otherwise they will have automatic storage duration and would cease to exist once you exit the function and so taking their addresses like the code is doing would probably be unwise.

作为参考,我在在此处答复中提供了有关复合文字的标准报价.

For reference I provide a standard quote on compound literals in my answer here.

重要的一点是,使用指定的初始化程序时,任何未显式初始化的字段都会初始化为零,这实际上很重要在这种情况下,例如hasCheese将设置为0,除非另有明确设置.

Important to note that when using designated initializers any field not explicitly initialized will be initialized to zero, which is actually important in this case, for example hasCheese will be set to 0 unless it is specifically set otherwise.

尽管这些是C99功能,但并非所有编译器都支持或完全支持C99,但我在 Visual Studio 上进行的测试表明我们需要替换空的复合文字,例如:

Although these are C99 features not all compilers support or fully support C99, my tests on Visual Studio show that we need to replace the empty compound literals, for example:

left = &(maze_t) {}

NULL进行编译.我提交了错误报告.

with a NULL to get it to compile. I filed a bug report.

对错误报告的响应如下,但是基本上这是一个正在工作的gcc/clang扩展:

The response to the bug report was as follows, but basically this is a gcc/clang extension at work:

这是GNU扩展. Clang支持它作为扩展(请参阅 clang选项-Wgnu-empty-initializer).

This is a GNU extension. Clang supports it as an extension (see the clang option -Wgnu-empty-initializer).

编写此代码的标准方法是{0},它将全部初始化为零 字段.

The standard way to write this is {0}, which will zero initialize all fields.

这篇关于C中的隐式结构定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆