如何在C中正确使用bitoperations

时间:2016-05-01 12:57:46

标签: c enums

我是C的初学者,我在比特操作方面遇到了一些问题。已经搜索了bitoperations的explenations,我无法检测到我的代码中的任何错误。

任务是将两个枚举数据类型中的数据序列化和反序列化为16位int值。

typedef enum {
Stop = 0,
Start = 1,
Finish = 5,
Fail = 255
} Status;

typedef enum {
One = 1,
Fifteen = 15,
Last = 255
} Numbers;

来自枚举状态的数据应保存在低字节中,来自枚举的数据应保存在高字节中。 所以我的序列化函数看起来像这样:

void serialize(Status s, Numbers n, short int* data) {
*data = (unsigned) n<<8;
*data = (unsigned) (*data|s);
}

我的反序列化函数如下所示:

void deserialize(unsigned short int data, Status* s, Numbers* n) {
*s = (unsigned) data<<8;
*s = (unsigned) *s>>8;
*n = (unsigned) data>>8;
}

现在的问题是,当我运行此测试功能时,它总是调用失败。

void testSD(Status s, Numbers n) {
unsigned short int data;
Status s2;
Numbers n2;
serialize(s, n, &data);
deserialize(data, &s2, &n2);
if(s2 == s && n2 == n) {
printf("succsess \n");
}
else {
printf("fail \n");
}
}

测试功能是正确的,因为我从我的教授那里得到了。

2 个答案:

答案 0 :(得分:0)

serialize函数中,data指向的数据将类似于

+--------+--------+
|nnnnnnnn|ssssssss|
+--------+--------+

然后,deserialize函数的工作方式如下:

*s = (unsigned) data<<8;

     +--------+--------+--------+
*s = |nnnnnnnn|ssssssss|00000000|
     +--------+--------+--------+

*s = (unsigned) *s>>8;

     +--------+--------+
*s = |nnnnnnnn|ssssssss|
     +--------+--------+

*n = (unsigned) data>>8;

     +--------+
*n = |nnnnnnnn|
     +--------+

因此,*s的值会出错。

deserialize应该是这样的:

void deserialize(unsigned short int data, Status* s, Numbers* n) {
    *s = (unsigned) data & 0xff;
    *n = (unsigned) data>>8;
}

答案 1 :(得分:0)

您的反序列化功能不正确。

想象一下,status = 5,number = 1。

数据中的值为

0105(十六进制)

在反序列化中,您将数字设为n&gt;&gt; 8,因此较低的部分会被移出并且您的值为1,这是正确的。

对于状态,您当前正在将其移动8,因此它是010500(十六进制),然后将其向下移动0150(十六进制)

你真正想要的只是低8位,通常可以通过将值与0xFF进行AND运算来完成。

即:0105&amp; 0xFF = 05

因此,将for状态的反序列化部分更改为:

* s =数据&amp;为0xFF;