简体   繁体   English

如何在C中比较两个不同的并集

[英]how to compare two different union in C

i'm just wondering how can i compare a union with other integer, my purpose is to code a sort of printf like and i'm managing the simple case like %d/%u/%i considering the size conversion : ll/l/hh/h/j/z, so basically i've the following union : 我只是想知道如何将一个联合与其他整数进行比较,我的目的是编写一种类似于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;
};

because i can't know before which type i'll need to receive, and after that when i've something like that in case i use %d : 因为我不知道我需要先接收哪种类型,在那之后,如果我有类似的东西,以防万一我使用%d:

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

i want to print my data wich's in my union u_allint so i give my union to a simple function for putmydata for exemple : 我想在我的联合u_allint中打印我的数据,所以我给我的联合一个简单的函数,例如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);
}

just suppose that this function is capable to print correctly my data and the fact is i can't do that because i compare an union with an int and even if i try to do an other union in my function and give newunion.nb = 0 for have an union int compare with an union int, i can't compile with this message : invalid operands to binary expression ('union my_union' and 'union my_union'). 只是假设此函数能够正确打印我的数据,事实是我无法做到这一点,因为我将一个联合与一个int进行了比较,即使我尝试在我的函数中进行另一个联合并给出newunion.nb = 0因为有一个union int与union int比较,所以我无法使用以下消息进行编译:对二进制表达式(“ union my_union”和“ union my_union”)无效的操作数。 so i'm pretty sure that i misunderstand something about union, but i didn't find a similar problem in other topic, so am i misunderstand something or maybe taking the problem by the wrong way ? 因此,我敢肯定我会误解一些有关工会的知识,但是我没有在其他主题中找到类似的问题,所以我误会了某些事情还是以错误的方式解决了这个问题? thank for your rep ! 谢谢您的代表!

Yes - you're confused what a union is. 是的-您对工会是什么感到困惑。

The union takes up as much memory as the largest item in it; 联合占用的内存与其最大的内存一样多。 and when you attempt to compare the value of it with >; 当您尝试将其值与>进行比较时; the compiler doesn't know what to do; 编译器不知道该怎么办; since the representation of the int = 0 and the representation of long = 0 may be different (since the int may not have 0'ed the bytes after it). 因为int = 0的表示形式和long = 0的表示形式可能有所不同(因为int后面的字节可能没有0'ed)。

Using your union in a printf will be interesting too; 在printf中使用并集也会很有趣。 as the %d tells printf to take the next sizeof(int) bytes that's in the arguments and assume it's an int. 因为%d告诉printf接受参数中的下一个sizeof(int)字节,并假定它是一个int。 As you've got extra data left over; 由于您还有剩余的数据; it will be read for the next part of printf - leaving it very confused and printing likely some rubbish (but it won't crash, as you're reading valid memory). 它将在printf的下一部分中读取-使其非常混乱,并且可能会打印一些垃圾(但不会崩溃,因为您正在读取有效的内存)。

Your request isn't clear. 您的要求不清楚。

However it's normal that compiler give you error in both case. 但是,两种情况下编译器都会给您错误是正常的。 For compare union you have to write some code like this one: 为了进行比较联合,您必须编写一些类似以下的代码:

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.
    ...
}

Edit: follow the suggestions in this link 编辑:按照此链接中的建议

I think what you are trying to use "union" for is wrong. 我认为您尝试使用“联盟”的目的是错误的。 At compile time, all types must be resolved and so you can't compare unions with their active member being agnostic. 在编译时,必须解析所有类型,因此您无法将并集与其活动成员不可知的状态进行比较。

For me, the easiest (yet quite clean) solution here is to parse the numbers you want to print in the largest possible integer number (unsigned long long int in your case), for instance for your "%d": 对我来说,这里最简单(但还算干净)的解决方案是将您要打印的数字解析为最大可能的整数(在您的情况下为unsigned 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

Then you can pass your container as argument as well as the 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
    }
}

This way, the function my_print can be generic, you only need to manage the conversion to "unsigned long long int" and the value of signed variable depending on the type. 这样,函数my_print可以是泛型的,您只需要管理对“ unsigned long long int”的转换,并根据类型来管理带符号变量的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM