【问题标题】:Evaluating a struct inside of a conditional statement in C在 C 中评估条件语句内的结构
【发布时间】:2015-02-10 16:36:58
【问题描述】:

有没有办法在一个整体的条件语句中评估一个结构变量,这样每个元素都不需要写出?例如给定以下结构:

typdef struct
{
    int a;
    int b;
    int c;
} number;

number foo = {1, 2, 3};

我想评估 if 语句中的元素,例如:

if (foo.a == 1 && foo.b == 2 && foo.c == 3)
{
    ...
} 

但是,我想评估整个结构,而不必列出单个元素。我知道这是不正确的,但这符合我想要完成的目标:

if (foo == {1, 2, 3})
{
    ...
}

非常感谢您的帮助。谢谢。

【问题讨论】:

    标签: c if-statement struct conditional-statements


    【解决方案1】:

    你可以通过复合文字来表示一个临时结构

    (number) { 1, 2, 3 }
    

    所以更合乎逻辑的尝试看起来像

    if (foo == (number) { 1, 2, 3 })
      ...
    

    但它不起作用,因为 C 语言不提供用于比较结构对象的内置运算符。你可以改用memcmp

    if (memcmp(&foo, &(number) { 1, 2, 3 }, sizeof foo) == 0)
      ...
    

    但不幸的是,由于您的结构对象中可能包含的任何填充字节的内容不可预测,因此无法保证这样做。

    在这种情况下,最好的做法可能是手动编写比较函数

    inline bool is_same_number(const number *lhs, const number *rhs)
    {
      return lhs->a == rhs->a && lhs->b == rhs->b && lhs->c == rhs->c;
    }
    

    然后结合复合字面量特征使用

    if (is_same_number(&foo, &(number) { 1, 2, 3 }))
      ...
    

    【讨论】:

    • 哇,现在我相信你读懂了我的想法。然而,填充虽然是实现定义的,但不会在同一结构的实例之间改变。编辑:从头开始,我看错了。
    • 感谢您的帮助安德烈。该结构将通过“attribute__((__packed))”打包。如果是这样,我如何确保复合文字也遵循打包属性以在 memcmp 中使用?
    • @quant:在所有编译器中,我都知道该属性适用于结构 type,而不适用于特定对象。这会自动确保该结构类型的 所有 对象都以相同的方式打包和打包,包括作为复合文字创建的对象。
    • @AndreyT 很好的信息。这很有帮助。我很乐意为您的回复投票,但我需要至少 15 个声誉点。非常感谢您的帮助。
    • 非常好的观察(我几乎误读了昆汀可能做的同样的方式)。但是——由于int 旨在为给定的机器提供“自然”大小,因此这种特殊结构不太可能有任何填充。为了确保可以编写断言测试sizeof(number) == 3*sizeof(int)。这对于其中包含较短元素的结构非常有用,以确保它们不包含孔,例如因为编译器被指示打包它们。
    【解决方案2】:

    不确定您是否需要结构,但无论哪种方式都只是转换为 unsigned char * 并使用文字,其中 0x000000010002 将是表示 3 个整数 {0 1 2} 的文字的格式。

    为了避免字节序问题,只需在运行时将积分声明为一个值,然后表示将匹配系统字节序。

    如果不允许运行时定义,您也可以使用宏。

    我不会浪费 memcpy。

    【讨论】:

    • 一直是,而且永远都是,直到这个概念被废除:-D
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-29
    • 2019-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-01
    相关资源
    最近更新 更多