如何在C中比较两个不同联合

xghobddn  于 2023-03-28  发布在  其他
关注(0)|答案(3)|浏览(168)

我只是想知道如何将一个联合体与另一个整数进行比较,我的目的是编写一种类似于printf的代码,并且我正在管理简单的情况,如%d/%u/%i,考虑大小转换:ll/l/hh/h/j/z,所以基本上我有以下联合:

union all_integer
{
    char                        c;
    signed int                  nb;
    short int                   snb;
    long int                    lnb;
    long long int               llnb;
    size_t                      posnb;

    unsigned char               uc;
    unsigned int                unb;
    unsigned short int          usnb;
    unsigned long int           ulnb;
    unsigned long long int      ullnb;
};

因为我不知道在此之前我需要接收哪种类型,以及在此之后当我有类似的东西时,如果我使用%d:

union all_integer u_allint;
u_allint.nb = va_arg(ap, int);

我想打印我的union u_allint中的数据,所以我将我的union交给一个简单的putmydata函数,例如:

putdata(union all_integer u_allint)
{
     if (u_allint < 0)
     {
          return (ft_numlen_neg(u_allint));
     }
     if (u_allint > 9)
         return (1 + ft_numlen(u_allint / 10));
     if (u_allint > 0 && u_allint < 10)
          return (1);
     if (u_allint == 0)
        return (1);
     return (0);
}

假设这个函数能够正确地打印我的数据,事实是我不能这样做,因为我将一个union与一个int进行比较,即使我尝试在我的函数中执行另一个union,并给予newunion.nb = 0,让union int与union int进行比较,我也不能编译:二进制表达式(“union my_union”和“union my_union”)的操作数无效。
所以我很确定我误解了关于联合的一些东西,但是我没有在其他主题中发现类似的问题,那么我是误解了什么,还是用错误的方式理解了这个问题?

kpbwa7wx

kpbwa7wx1#

是的-你搞不清什么是工会。
联合所占用的内存与其中最大的项一样多;当你试图比较它的值与〉;编译器不知道该怎么做;因为int = 0的表示和long = 0的表示可能不同(因为int之后的字节可能不为0)。
在printf中使用联合也会很有趣;因为%d告诉printf接受参数中的下一个sizeof(int)字节,并假设它是一个int。它将被printf的下一部分读取--这会使它非常混乱,并且可能打印一些垃圾(但它不会崩溃,因为您正在阅读有效内存)。

pzfprimi

pzfprimi2#

我认为你试图用“union”来表示的是错误的。在编译时,所有类型都必须被解析,所以你不能将union与其活跃成员进行比较。
对我来说,这里最简单(但相当干净)的解决方案是解析你想要打印的最大整数(在你的例子中是无符号long long int),例如你的“%d”:

unsigned long long int mask = ~((unsigned long long int) 0);
unsigned long long int container;
bool signed = true;
...
int num1 = -548375;
container = (unsigned long long int) (((long long int) num1) & mask); //"long long int" instead of "unsigned long long int" to propagate the bit of sign

然后你可以将容器作为参数和符号传递:

void my_print(unsigned long long int container, bool signed) {
    if (signed) {
        // Print as long long int
    } else if (!signed) {
        // Print as unsigned long long int
    }
}

这样,函数my_print可以是泛型的,你只需要管理到“unsigned long long int”的转换和根据类型的有符号变量的值。

i7uaboj4

i7uaboj43#

你的要求不清楚。
然而,编译器在这两种情况下都给予你错误是正常的。对于比较联合,你必须写一些像这样的代码:

all_integer union1;
all_integer union2;

/*To ensure all the unused data of the unions are the same, it's
necessary to set unions, before to use it, at the same value (0 in this case).*/
memset(&union1,0,sizeof(all_integer));
memset(&union2,0,sizeof(all_integer));

...

if(!memcmp(&union1,&union2,sizeof(all_integer))
{
    //Unions are equal.
    ...
}
else
{
    //Unions aren't equal.
    ...
}

编辑:遵循此link中的建议

相关问题