我只是想知道如何将联合与其他整数进行比较,我的目的是编写一种类似于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);
我想在我的联盟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);
}
假设这个函数能够正确打印我的数据,事实是我无法做到这一点,因为我将一个联合与一个int进行比较,即使我尝试在我的函数中做另一个联合并给出newunion.nb = 0表示将union int与union int进行比较,我无法使用此消息进行编译:二进制表达式的操作数无效(&#39; union my_union&#39;&#39; union my_union&# 39)。 所以我很确定我误解了关于工会的一些事情,但我在其他话题中没有找到类似的问题,所以我误解了某些事情或者可能以错误的方式解决了问题? 谢谢你的代表!
答案 0 :(得分:1)
是的 - 你对工会是什么感到困惑。
联盟占用的内存与其中最大的项目一样多;当你试图将它的值与&gt;;进行比较时编译器不知道该怎么做;因为int = 0的表示和long = 0的表示可能不同(因为int之后的字节可能没有0&#39;)
在printf中使用你的联合也很有趣;因为%d告诉printf接受参数中的下一个sizeof(int)字节并假设它是一个int。因为你还有额外的数据;它将被读取为printf的下一部分 - 让它非常困惑并且可能会打印一些垃圾(但它会因为您正在阅读有效内存而崩溃)。
答案 1 :(得分:0)
您的要求不明确。
然而,编译器在两种情况下都会给出错误是正常的。对于比较联合,你必须写一些像这样的代码:
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
中的建议操作答案 2 :(得分:0)
我认为你正在尝试使用&#34; union&#34;因为错了。在编译时,必须解决所有类型,因此您无法将联盟与其活动成员进行不可知对比。
对我来说,这里最简单(但非常干净)的解决方案是用最大可能的整数(在你的情况下为unsigned long long int)解析你想要打印的数字,例如你的&#34;%d& #34;:
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可以是通用的,你只需要管理转换为&#34; unsigned long long int&#34;和signed变量的值取决于类型。