什么是匿名联合类型的使用场景?

3

我看到了一个包含以下代码的问题:

union
{
     float dollars;
     int yens;
}price;

price是一个没有名称的变量类型。 这种没有名称的类型有什么用处?Lambda表达式? 这在C和C++中都有效吗?


2
还有其他数据可以告诉你使用哪个联合成员。你真的应该展示更多的代码,并选择C和C++之间(它们是不同的语言)。因此,请提出一个新问题或者强烈编辑这个问题。 - Basile Starynkevitch
这是我想表达的意思,问题已经更新了;-) 感谢 angew。 - Philip Stuyck
1
我该如何展示更多的代码,因为我不知道这个未命名类型有什么用处,我基本上是在寻求一个例子。 - Philip Stuyck
1
@BasileStarynkevitch 我怀疑这个问题在C或C++中的答案是完全相同的。 - user253751
1
@PhilipStuyck 同意... :) 我也不明白为什么会对这样明智的问题投反对票。 - Gopi
显示剩余10条评论
6个回答

5
事实上,该类型没有名称对于price变量的使用影响非常小。这只意味着你不能(容易地)创建此类型的另一个对象。
如果price是函数内部的局部变量,则此结构最有意义。如果你只需要一个此类型的对象,那么就不需要为其命名,因此没有必要烦恼。它与以下代码完全相同:
union SomeNameIPromiseNotToUseAnywhereAndWhichDoesntConflictWithAnything
{
  float dollars;
  int yens;
} price;

注意,在C++11及以上版本中,您实际上可以创建另一个对象:

decltype(price) anotherPrice;

2

在C++中,这是有效的。该代码定义了一个名为price的局部变量,它可以存储yens中的整数值或dollars中的浮点数值。

如果没有看到它如何使用,我只能得出结论,该变量是一个局部/临时变量(可能在尝试做太多事情的函数中)。

示例:

union
{
     float dollars;
     int yens;
} price;

if(currency != "USD")
    price.yens = ConvertToYEN(fullPrice);
else
    price.dollars = GetUpdatedPriceInUSD(abc, currency);

if(currency == "YEN")
   std::cout << "Using price in yens: " << price.yens << "\n";

1
根据这个链接,在 C 中。

https://gcc.gnu.org/onlinedocs/gcc/Unnamed-Fields.html#Unnamed-Fields

你只需像这样访问联合体的成员:price.dollarsprice.yens,因为price已经是一个类型为联合体的变量,无需创建一个同类型的新对象。
union
{
     float dollars;
     int yens;
}price;

int main(void) {
    price.dollars = 90.5;
    printf("%f\n",price.dollars);
    price.yens = 20;
    printf("%d\n",price.yens);
    return 0;
}

1
我过去曾经使用联合体作为处理存储格式并在它们之间进行转换的机制。
例如,程序可能包括代码以浮点格式将金额存储到文件中,并且存储函数接受/返回浮点数。后来,我们发现需要使用整数,因此我们只需使用联合体以访问数据所知道的格式即可。例如:
price.dollars = load_from_file();
if (yen_flag)
    // use price.yen
else
    // use price.dollars

它还常用于实现独立于编程语言的整数存储。
union {
    int int_val;
    char as_bytes[4];
} int_store;

如果有语法错误,请见谅,毕竟已经有一段时间了...


0

我在很多用于2D/3D计算的数学库中看到了这样的代码:

struct Matrix3x3
{
    union
    {
        struct
        {
            float m00 , m01 , m02;
            float m10 , m11 , m12;
            float m20 , m21 , m22;
        };

        float m[ 3 ][ 3 ];
    };
};

另外还可以参考这个问题


如果我没记错的话,在某个地方我读到过使用这种方法会导致违反严格别名规则。


0
struct FooBar
{
    union
    {
        Foo foo;
        char dummy[128];
    };
    Bar bar;
};

我曾经看到人们使用无名联合来控制 struct 成员的偏移量。

没有简单的方法可以将 struct 成员对齐到特定边界,但有办法将 struct 的开头对齐到任意边界,然后将成员填充到下一个边界。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接