更新
在阅读答案时,我觉得我的问题不够明确,我为此道歉。
令我感到困惑的是,在第一次调用" disp_binary(sb.ch [1]);" " u"的价值函数内部将为15(这将使它在if条件下始终为TRUE,因为它是非零值)和" t"在循环内总是为真,因为(t> 0)但输出是:
0 0 0 0 1 1 1 1
这些零来自哪里?输出不应该是:
1 1 1 1 1 1 1 1
因为两者都是" u"和" t"在这次电话会议中总是如此?
顺便说一下,整个程序的输出是:
Original bytes: 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1
Exchanged bytes: 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0
我从一本书中学习了C ++中的工会,我遇到了一个我无法理解的例子。
我理解工会的基本思想,我在示例中没有得到的东西(参见下面的例子)是" void disp_binary(unsigned u)"功能,更具体地说是什么是" u"那是传递给函数的? sb.ch [1]不是15,sb.ch [0]是0吗?因为我很困惑为什么我们使用"你"在if语句中的条件?
这是一个例子:
// Use a union to exchange the bytes within a short integer.
#include <iostream>
using namespace std;
void disp_binary(unsigned u);
union swap_bytes {
short int num;
char ch[2];
};
int main()
{
swap_bytes sb;
char temp;
sb.num = 15; // binary: 0000 0000 0000 1111
cout << "Original bytes: ";
disp_binary(sb.ch[1]);
cout << " ";
disp_binary(sb.ch[0]);
cout << "\n\n";
// exchange the bytes
temp = sb.ch[0];
sb.ch[0] = sb.ch[1];
sb.ch[1] = temp;
cout << "Exchanged bytes: ";
disp_binary(sb.ch[1]);
cout << " ";
disp_binary(sb.ch[0]);
cout << "\n\n";
return 0;
}
// Display the bits within a byte.
void disp_binary(unsigned u)
{
register int t;
for(t=128; t>0; t=t/2)
if(u & t) cout << "1 ";
else cout << "0 ";
}
答案 0 :(得分:3)
根据C ++标准,它是一个灰色区域,在写入另一个字段后,可以获得union字段的值。 技术上从一个从未被初始化的联盟领域读取并且是UB。联合领域是不同的对象。由于历史原因,大多数编译器允许通过联合进行类型惩罚,即使它在C ++标准中定义为UB。如果可能,建议尽量避免使用它。这里出现的一个问题是一个字段很短,而另一个字段是两个字节,某些平台不能处理写入short的内存中的单独字节。结果可能依赖于系统的endiannes,例如,GCC会改变字节顺序,以便在little-endian和big-endian平台上允许相同的结果(tada,你不能通过union来测试系统的字节顺序)。
关于你的问题
void disp_binary(unsigned u)
{
register int t;
for(t=128; t>0; t=t/2)
if(u & t)
cout << "1 ";
else
cout << "0 ";
}
&安培;不是逻辑(布尔)操作,它是二进制(按位)操作。设u等于15,t等于8,运算结果为
00001111&amp; 00001000 = 00001000。
该值将被转换为布尔值。
事实上,关键字register
不再具有任何意义,您可以简化代码,通过强制转换摆脱分叉的if()。
void disp_binary(unsigned u)
{
for(unsigned t = 128; t>0; t=t>>1)
{
std::cout << int(bool(u & t)) << " ";
}
}
而不是这个可以使用std :: bitset类的C ++库。
答案 1 :(得分:0)
我从未看到sb.ch
被分配到任何地方,你怎么确定它的15或0?它是垃圾,因为你没有在任何地方初始化它。已分配sb.num
但从未使用过的地方。
函数的参数是unsigned
,即unsigned int
,你继续向它传递一个字符,该字符将被更改为值的整数表示。例如:字符“0”在参数中表示为48,“0”的二进制表示为110000,在这种情况下应为000000。
答案 2 :(得分:0)
unsinged u
实际上是unsigned int u
,因此函数disp_binary(sb.ch[0])
接收转换为unsigned int的char implicity。
是的,你是对的:
如果是disp_binary(sb.ch[0])
(交换前),则为0。
如果是disp_binary(sb.ch[1])
(交换前),则为15。
答案 3 :(得分:0)
Union是一个定义变量的结构,它们在内存中共享相同的空间。因此,在分配sb.num时会自动分配sb.ch 。 sb.ch [0]是前8位,sb.ch [1]是最后8位。 所以是的,sb.ch [0]将为0而sb.ch [1]将为1.
if(u&amp; t)如果按位返回true,则返回0以外的任何值