可能重复:
这个 C++ 代码是什么意思?
在以下 C++ 代码中
# include <stdio.h>
int main()
{
struct clap
{
int i:2;
int j:2;
int k:3;
}x={1,2,3};
printf("%d %d %d",x.i,x.j,x.k);
return 0;
}
在运行以下代码时,我得到输出 1 -2 3
请参考上述代码解释“:”运算符的含义,以及出现这种奇怪输出的原因;
可能重复:
这个 C++ 代码是什么意思?
在以下 C++ 代码中
# include <stdio.h>
int main()
{
struct clap
{
int i:2;
int j:2;
int k:3;
}x={1,2,3};
printf("%d %d %d",x.i,x.j,x.k);
return 0;
}
在运行以下代码时,我得到输出 1 -2 3
请参考上述代码解释“:”运算符的含义,以及出现这种奇怪输出的原因;
这些表示位字段,其长度在冒号后表示
struct clap
{
int i:2; // length 2
int j:2; // length 2
int k:3; // length 3
};
位域节省空间。尝试计算sizeof(clap)
,你会发现它在 gcc 4.7 上是 4 个字节。它不是 1 字节(2 + 2 + 3 = 7 位 < 1 字节)的原因是编译器还会根据位域的底层类型在某些边界上对齐结构。例如,更改int
为short
或char
作为位域的基础类型将分别将总大小减少clap
到 2 和 1 个字节(再次在 gcc 4.7 上)。
这应该与存储 3 个完整整数通常需要 12 个字节(如果 int 是 4 个字节)相比。OTOH,位域会使您的代码变慢,因为寻址成员需要移动和解包位域。
出现符号问题是因为 2 的 2 位二进制补码等于 -2。将代码扩展到int j:3
将输出2
.
结构中的冒号表示成员是位域。也就是说,每个字段只使用指定的位数。
你得到-2
的字段j
可能是因为printf
Treats 是一个符号扩展整数。
就像其他答案一样,它是位域。关于它们的一个重要说明:
因此,C++0x 将连续位域序列中的所有(非零长度)位域视为单个内存位置的一部分;对一个人的分配与对其他任何人的分配冲突。这种连续的位域不应由不同的线程同时更新。通常这意味着它们应该受到单个锁的保护。
http://www.hpl.hp.com/personal/Hans_Boehm/c++mm/threadsintro.html#bitfields