用 char 覆盖 struct ,为什么在 Intel 处理器上得到以下结果?
我对以下代码感到困惑:
#include <iostream>
using namespace std;
struct bit
{
int a:3;
int b:2;
int c:3;
};
int main(int argc, char* argv[])
{
bit s;
char *c = (char*)&s;
*c = 0x99;
cout << s.a <<endl <<s.b<<endl<<s.c<<endl;
return 0;
}
由于 a 需要 3 位,b 2 位,c 3 位,当我将此结构转换为 char* 指针时,我是否采用了 first
8 个字节或最后
8 个字节?
在 Intel 32 位机器上,编译器将如何存储 32 位整数?
为什么我得到
1 , -1 , -4
结果?
I'm confused by the following code:
#include <iostream>
using namespace std;
struct bit
{
int a:3;
int b:2;
int c:3;
};
int main(int argc, char* argv[])
{
bit s;
char *c = (char*)&s;
*c = 0x99;
cout << s.a <<endl <<s.b<<endl<<s.c<<endl;
return 0;
}
Since a takes 3 bits , b 2 bits , c 3 bits , when i cast this struct to a char* pointer , did i took the first
8 bytes or the last
8 bytes ?
On a Intel 32 bit machine , how will the compiler store an 32 bit integer ?
Why i get
1 , -1 , -4
as a result ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
0x99 是 10011001 二进制是 100 11 001,看起来非常像 1,-1,-4(顺序相反)。是的,它是 8 个最低有效位。
我相信符号性让您感到困惑,因此您可能想在结构中使用
unsigned int
。如果不是签名,那么请更具体一些。0x99 is 10011001 binary is 100 11 001, which looks very much like 1,-1,-4 (in reverse order). And yes, it's 8 least significant bits.
I believe signedness has confused you, so you may want to use
unsigned int
in the struct. If it's not signedness, then please, be more specific.这里至少涉及三个问题。第一个(已经
提到的)是字节序。第二个是
bit
最终的大小存在。 (在很多编译器上这将是四个字节。)如果更多
如果不是单个字节,那么您的
char*
将无法访问所有内容。和最后,还有编译器如何布局这些位的问题,
以及它放置剩余位的位置。有些编译器会以
从高位开始放置它们,从低位开始放置其他的。
如果编译器仅使用一个 8 位
char
来表示bit
,那么根据顺序,您可能会得到 {[+-]4, 3 或 -1, 1} 或
对面的。更不用说当用作位字段时,普通的
int
可以可以是
signed int
或unsigned int
(因此 [+-]4 和 3 或 -1)。 (在在所有其他上下文中,普通
int
是signed int
,并且从 QoI 角度来看视图,这就是我在这里所期望的,如果只是为了一致性的原因。)
一般来说,如果你的唯一目标是将内存保存在内存中
结构、位域都很好。但一旦你
试图匹配一些外部表示。
There are at least three issues involved here. The first (already
mentionned) is endianness. The second is what the size of
bit
ends upbeing. (It will be four bytes on a lot of compilers.) If it's more
than a single byte, then your
char*
won't access all of it. Andfinally, there is the question of how the compiler lays out the bits,
and where it puts any left over bits. Some compilers will start by
laying them from the high order bit, and others from the low order bit.
If the compiler does only use one 8 bit
char
forbit
, thendepending on the order, you might get {[+-]4, 3 or -1, 1} or the
opposite. Not to mention that when used as a bit field, plain
int
canbe either
signed int
orunsigned int
(thus [+-]4 and 3 or -1). (Inall other contexts, plain
int
issigned int
, and from a QoI point ofview, that's what I'd expect here, if only for reasons of consistency.)
In general, if you're only goal is to save memory in an in-memory
structure, bit fields are fine. But they're worthless as soon as you're
trying to match some external representation.
首先,由于您使用 int ,因此对结构成员进行签名
取决于您是否拥有大端机或小端机。
First of all since you use int thus signing the struct members
Depending on whether you have a Big or Little Endian machine.
由于使用了
int
,您的结构体大小超过 1 个字节,但您正尝试为该结构体的整个内容分配一个 1 字节值。那是行不通的。更改您的结构以使用char
而不是int
,特别是因为您使用char*
指针来分配值。结构成员指定的总位数应与所使用的基础数据类型的字节大小相匹配,例如:在相关说明中,您可以使用
union
来避免char*< /代码> 指针:
Your struct is more than 1 byte in size because of your use of
int
, but you are trying to assign a 1-byte value to the entire contents of the struct. That will not work. Change your struct to usechar
instead ofint
, especially since you are using achar*
pointer to assign the value. The total number of bits specified by the struct members should match the byte size of the underlying data type used, eg:On a related note, you can use a
union
to avoid thechar*
pointer: