结构体位域在内存中存储的问题

oncreating 2015-08-12 10:58:20
想将一个按位域存储的结构体按位流(bit stream)的方式存储在内存中,试了好几次都不是我预期的,以下是我的代码,不是我预期想要的:


struct Header
{
unsigned char version:3;
unsigned char offset:2;
unsigned char reserve:2;
unsigned char flag:1;
};

int _tmain(int argc, _TCHAR* argv[])
{
Header header;
header.version = 3;
header.offset = 2;
header.reserve = 0;
header.flag = 1;

unsigned char buffer[sizeof(Header)];
memcpy((void*)buffer, (void*)&header, sizeof(Header));

return 0;
}


以上代码buffer在内存中的值是93(二进制:1011101),我的预期是113(二进制:01110001),该如何修改呢?
...全文
149 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
oncreating 2015-08-12
  • 打赏
  • 举报
回复
引用 2 楼 adlay 的回复:
首先, 93 是十六进制的,所以二进制的话是 10010011 而不是 1011101! 想得到十进制的 113 定义结构的时候换下顺序就行了 struct Header { unsigned char flag:1; unsigned char reserve:2; unsigned char offset:2; unsigned char version:3; };
是我发昏,把十六进制搞成十进制了,感谢。 也感谢另外两位,结贴。
fefe82 2015-08-12
  • 打赏
  • 举报
回复
Allocation of bit-fields within a class object is implementation-defined. Alignment of bit-fields is implementation-defined. Bit-fields are packed into some addressable allocation unit. [ Note: Bit-fields straddle allocation units on some machines and not on others. Bit-fields are assigned right-to-left on some machines, left-to-right on others. — end note ] 位域(bitfield)的实现依赖于编译器和系统环境。 所以如果想得到确定的输出(比如需要在网络上传输啥的)需要使用 位运算符( | & ^ ~)自己拼
www_adintr_com 2015-08-12
  • 打赏
  • 举报
回复
首先, 93 是十六进制的,所以二进制的话是 10010011 而不是 1011101! 想得到十进制的 113 定义结构的时候换下顺序就行了 struct Header { unsigned char flag:1; unsigned char reserve:2; unsigned char offset:2; unsigned char version:3; };
赵4老师 2015-08-12
  • 打赏
  • 举报
回复
仅供参考:
#include <stdio.h>
#pragma pack(push,1)
union U {
    unsigned char byte;
    struct BF {
        unsigned int b0:1;//a
        unsigned int b1:1;//b
        unsigned int b2:1;//c
    } bf;
} u;
#pragma pack(pop)
unsigned char bt;
int a,b,c;
int main() {
    for (bt=0;bt<8;bt++) {
        u.byte=(unsigned char)bt;
        a=u.bf.b0;
        b=u.bf.b1;
        c=u.bf.b2;
        printf("byte 0x%02x -- c:%d b:%d a:%d\n",bt,c,b,a);
    }
    for (c=0;c<2;c++)
    for (b=0;b<2;b++)
    for (a=0;a<2;a++) {
        u.bf.b0=a;
        u.bf.b1=b;
        u.bf.b2=c;
        bt=u.byte;
        printf("c:%d b:%d a:%d -- byte 0x%02x\n",c,b,a,bt);
    }
    return 0;
}
//byte 0x00 -- c:0 b:0 a:0
//byte 0x01 -- c:0 b:0 a:1
//byte 0x02 -- c:0 b:1 a:0
//byte 0x03 -- c:0 b:1 a:1
//byte 0x04 -- c:1 b:0 a:0
//byte 0x05 -- c:1 b:0 a:1
//byte 0x06 -- c:1 b:1 a:0
//byte 0x07 -- c:1 b:1 a:1
//c:0 b:0 a:0 -- byte 0x00
//c:0 b:0 a:1 -- byte 0x01
//c:0 b:1 a:0 -- byte 0x02
//c:0 b:1 a:1 -- byte 0x03
//c:1 b:0 a:0 -- byte 0x04
//c:1 b:0 a:1 -- byte 0x05
//c:1 b:1 a:0 -- byte 0x06
//c:1 b:1 a:1 -- byte 0x07

再供参考:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
float f;
double d;
void showf() {
    char bs[65];
    char b[65];
    unsigned char *p;
    char e[12];
    char *t;
    int ex;

    printf("\nf=%.6f\n",f);
    p=(unsigned char *)&f;
    printf("hex=%02X %02X %02X %02X\n",p[3],p[2],p[1],p[0]);
    ltoa(*(long *)&f,b,2);
    sprintf(bs,"%032s",b);
    printf("bin=%s\n",bs);
    printf("bin=%.1s %.8s   %s\n",bs,bs+1,bs+9);
    strncpy(e,bs+1,8);e[8]=0;
    ex=strtol(e,&t,2);
    printf("    %c %-4d-127 1.%s\n",(bs[0]=='0')?'+':'-',ex,bs+9);
    ex-=127;
    printf("    %c %-8d 1.%s\n",(bs[0]=='0')?'+':'-',ex,bs+9);
}
void showd() {
    char bs[65];
    char b[65];
    unsigned char *p;
    char e[12];
    char *t;
    int ex;

    printf("\nd=%.15lf\n",d);
    p=(unsigned char *)&d;
    printf("hex=%02X %02X %02X %02X %02X %02X %02X %02X\n",p[7],p[6],p[5],p[4],p[3],p[2],p[1],p[0]);
    _i64toa(*(__int64 *)&d,b,2);
    sprintf(bs,"%064s",b);
    printf("bin=%s\n",bs);
    printf("bin=%.1s %.11s   %s\n",bs,bs+1,bs+12);
    strncpy(e,bs+1,11);e[11]=0;
    ex=strtol(e,&t,2);
    printf("    %c %-6d-1023 1.%s\n",(bs[0]=='0')?'+':'-',ex,bs+12);
    ex-=1023;
    printf("    %c %-11d 1.%s\n",(bs[0]=='0')?'+':'-',ex,bs+12);
}
int main() {

    for (f=0.0f;f<=2.2f;f+=0.2f) showf();
    printf("------------\n");
    f=2.0f;showf();
    printf("-----------------------------------\n");
    for (d=0.0 ;d<=2.2 ;d+=0.2 ) showd();
    printf("------------\n");
    d=2.0 ;showd();

    return 0;
}
//
//f=0.000000
//hex=00 00 00 00
//bin=00000000000000000000000000000000
//bin=0 00000000   00000000000000000000000
//  + 0   -127 1.00000000000000000000000
//  + -127     1.00000000000000000000000
//
//f=0.200000
//hex=3E 4C CC CD
//bin=00111110010011001100110011001101
//bin=0 01111100   10011001100110011001101
//  + 124 -127 1.10011001100110011001101
//  + -3       1.10011001100110011001101
//
//f=0.400000
//hex=3E CC CC CD
//bin=00111110110011001100110011001101
//bin=0 01111101   10011001100110011001101
//  + 125 -127 1.10011001100110011001101
//  + -2       1.10011001100110011001101
//
//f=0.600000
//hex=3F 19 99 9A
//bin=00111111000110011001100110011010
//bin=0 01111110   00110011001100110011010
//  + 126 -127 1.00110011001100110011010
//  + -1       1.00110011001100110011010
//
//f=0.800000
//hex=3F 4C CC CD
//bin=00111111010011001100110011001101
//bin=0 01111110   10011001100110011001101
//  + 126 -127 1.10011001100110011001101
//  + -1       1.10011001100110011001101
//
//f=1.000000
//hex=3F 80 00 00
//bin=00111111100000000000000000000000
//bin=0 01111111   00000000000000000000000
//  + 127 -127 1.00000000000000000000000
//  + 0        1.00000000000000000000000
//
//f=1.200000
//hex=3F 99 99 9A
//bin=00111111100110011001100110011010
//bin=0 01111111   00110011001100110011010
//  + 127 -127 1.00110011001100110011010
//  + 0        1.00110011001100110011010
//
//f=1.400000
//hex=3F B3 33 34
//bin=00111111101100110011001100110100
//bin=0 01111111   01100110011001100110100
//  + 127 -127 1.01100110011001100110100
//  + 0        1.01100110011001100110100
//
//f=1.600000
//hex=3F CC CC CE
//bin=00111111110011001100110011001110
//bin=0 01111111   10011001100110011001110
//  + 127 -127 1.10011001100110011001110
//  + 0        1.10011001100110011001110
//
//f=1.800000
//hex=3F E6 66 68
//bin=00111111111001100110011001101000
//bin=0 01111111   11001100110011001101000
//  + 127 -127 1.11001100110011001101000
//  + 0        1.11001100110011001101000
//
//f=2.000000
//hex=40 00 00 01
//bin=01000000000000000000000000000001
//bin=0 10000000   00000000000000000000001
//  + 128 -127 1.00000000000000000000001
//  + 1        1.00000000000000000000001
//------------
//
//f=2.000000
//hex=40 00 00 00
//bin=01000000000000000000000000000000
//bin=0 10000000   00000000000000000000000
//  + 128 -127 1.00000000000000000000000
//  + 1        1.00000000000000000000000
//-----------------------------------
//
//d=0.000000000000000
//hex=00 00 00 00 00 00 00 00
//bin=0000000000000000000000000000000000000000000000000000000000000000
//bin=0 00000000000   0000000000000000000000000000000000000000000000000000
//  + 0     -1023 1.0000000000000000000000000000000000000000000000000000
//  + -1023       1.0000000000000000000000000000000000000000000000000000
//
//d=0.200000000000000
//hex=3F C9 99 99 99 99 99 9A
//bin=0011111111001001100110011001100110011001100110011001100110011010
//bin=0 01111111100   1001100110011001100110011001100110011001100110011010
//  + 1020  -1023 1.1001100110011001100110011001100110011001100110011010
//  + -3          1.1001100110011001100110011001100110011001100110011010
//
//d=0.400000000000000
//hex=3F D9 99 99 99 99 99 9A
//bin=0011111111011001100110011001100110011001100110011001100110011010
//bin=0 01111111101   1001100110011001100110011001100110011001100110011010
//  + 1021  -1023 1.1001100110011001100110011001100110011001100110011010
//  + -2          1.1001100110011001100110011001100110011001100110011010
//
//d=0.600000000000000
//hex=3F E3 33 33 33 33 33 34
//bin=0011111111100011001100110011001100110011001100110011001100110100
//bin=0 01111111110   0011001100110011001100110011001100110011001100110100
//  + 1022  -1023 1.0011001100110011001100110011001100110011001100110100
//  + -1          1.0011001100110011001100110011001100110011001100110100
//
//d=0.800000000000000
//hex=3F E9 99 99 99 99 99 9A
//bin=0011111111101001100110011001100110011001100110011001100110011010
//bin=0 01111111110   1001100110011001100110011001100110011001100110011010
//  + 1022  -1023 1.1001100110011001100110011001100110011001100110011010
//  + -1          1.1001100110011001100110011001100110011001100110011010
//
//d=1.000000000000000
//hex=3F F0 00 00 00 00 00 00
//bin=0011111111110000000000000000000000000000000000000000000000000000
//bin=0 01111111111   0000000000000000000000000000000000000000000000000000
//  + 1023  -1023 1.0000000000000000000000000000000000000000000000000000
//  + 0           1.0000000000000000000000000000000000000000000000000000
//
//d=1.200000000000000
//hex=3F F3 33 33 33 33 33 33
//bin=0011111111110011001100110011001100110011001100110011001100110011
//bin=0 01111111111   0011001100110011001100110011001100110011001100110011
//  + 1023  -1023 1.0011001100110011001100110011001100110011001100110011
//  + 0           1.0011001100110011001100110011001100110011001100110011
//
//d=1.400000000000000
//hex=3F F6 66 66 66 66 66 66
//bin=0011111111110110011001100110011001100110011001100110011001100110
//bin=0 01111111111   0110011001100110011001100110011001100110011001100110
//  + 1023  -1023 1.0110011001100110011001100110011001100110011001100110
//  + 0           1.0110011001100110011001100110011001100110011001100110
//
//d=1.600000000000000
//hex=3F F9 99 99 99 99 99 99
//bin=0011111111111001100110011001100110011001100110011001100110011001
//bin=0 01111111111   1001100110011001100110011001100110011001100110011001
//  + 1023  -1023 1.1001100110011001100110011001100110011001100110011001
//  + 0           1.1001100110011001100110011001100110011001100110011001
//
//d=1.800000000000000
//hex=3F FC CC CC CC CC CC CC
//bin=0011111111111100110011001100110011001100110011001100110011001100
//bin=0 01111111111   1100110011001100110011001100110011001100110011001100
//  + 1023  -1023 1.1100110011001100110011001100110011001100110011001100
//  + 0           1.1100110011001100110011001100110011001100110011001100
//
//d=2.000000000000000
//hex=3F FF FF FF FF FF FF FF
//bin=0011111111111111111111111111111111111111111111111111111111111111
//bin=0 01111111111   1111111111111111111111111111111111111111111111111111
//  + 1023  -1023 1.1111111111111111111111111111111111111111111111111111
//  + 0           1.1111111111111111111111111111111111111111111111111111
//
//d=2.200000000000000
//hex=40 01 99 99 99 99 99 99
//bin=0100000000000001100110011001100110011001100110011001100110011001
//bin=0 10000000000   0001100110011001100110011001100110011001100110011001
//  + 1024  -1023 1.0001100110011001100110011001100110011001100110011001
//  + 1           1.0001100110011001100110011001100110011001100110011001
//------------
//
//d=2.000000000000000
//hex=40 00 00 00 00 00 00 00
//bin=0100000000000000000000000000000000000000000000000000000000000000
//bin=0 10000000000   0000000000000000000000000000000000000000000000000000
//  + 1024  -1023 1.0000000000000000000000000000000000000000000000000000
//  + 1           1.0000000000000000000000000000000000000000000000000000
//

64,664

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧