int main()
{
unsigned char ptr[9];
uint16_t dat = 128, s;
int i, j = 1, k;
ptr[0] = ptr[0] & 0;
j = -1;
for(i = 0;i <= 15;i++)
{
if(i % 8 == 0)
j++;
s = dat << i;
if (s & (1 << 15))
ptr[j] |= 1 << (7 - i%8);
else
ptr[j] |= 0 << (7 - i%8);
}
j = -1;
s &= 0;
for(i = 0;i <= 15;i++)
{
if(i % 8 == 0)
j++;
s |= (ptr[j] & (1 << (7 - i%8))) << (15 - i); // <-----------
s |= (ptr[j] & (1 << i%8)) << (15 - i); // Correction
}
printf("%d", s);
return(0);
}
我试图通过先转换为二进制然后将其一点一点地复制到数组中,将16个字节的整数包装到字符数组中。但是,我在标记行上遇到了麻烦。我得到16834作为输出。我在这里做错了什么?
如所写,输出是不确定的,因为您从未设置ptr[1]
为已知值。在我的Mac上,这是您的代码的次要变体(主要是添加了一些,标头,空格和printf()
语句):
#include <stdint.h>
#include <stdio.h>
int main(void)
{
unsigned char ptr[9];
uint16_t dat = 128, s;
int i, j = 1;
ptr[0] = ptr[0] & 0;
j = -1;
printf("0x%.2X 0x%.2X\n", ptr[0], ptr[1]);
for (i = 0; i <= 15; i++)
{
if (i % 8 == 0)
j++;
s = dat << i;
if (s & (1 << 15))
ptr[j] |= 1 << (7 - i % 8);
else
ptr[j] |= 0 << (7 - i % 8);
}
printf("0x%.2X 0x%.2X\n", ptr[0], ptr[1]);
j = -1;
s &= 0;
for (i = 0; i <= 15; i++)
{
if (i % 8 == 0)
j++;
s |= (ptr[j] & (1 << (7 - i % 8))) << (15 - i); // <-----------
}
printf("0x%.2X\n", s);
printf("%d\n", s);
return(0);
}
显示输出:
0x00 0xF4
0x00 0xF4
0x5510
21776
当修改成用ptr[0] = ptr[0] & 0;
与ptr[0] = ptr[1] = 0;
,所述输出为:
0x00 0x00
0x00 0x80
0x4000
16384
您很不幸,您的计算机将堆栈清零了。发现未初始化变量之类的错误会变得更加困难。
您选择128作为测试值会给您带来生活上的困难;仅设置一位。在测试中,我将使用一种独特的模式,例如0x3CA5(C ++ 14二进制表示法中的0b0011'1100'1010'0101)。当我将代码更改为使用0x3CA5时,我得到了输出:
0x00 0x00
0x3C 0xA5
0x5411
21521
好消息:第一个循环复制这些位,以使数字的高字节在in中ptr[0]
,而低字节在in中ptr[1]
。坏消息:第二个循环似乎使事情变得糟透了。
这是第二个循环的检测版本:
for (i = 0; i < 16; i++)
{
if (i % 8 == 0)
j++;
uint16_t s0 = s;
s |= (ptr[j] & (1 << (7 - i % 8))) << (15 - i); // <-----------
printf("i: %2d, j: %d, 7-i%%8: %d, ptr[j]: 0x%.2X, &val: 0x%.2X, "
"|val = 0x%.5X, s0: 0x%.4X, s: 0x%.4X\n",
i, j, 7 - i % 8, ptr[j], (1 << (7 - i % 8)),
(ptr[j] & (1 << (7 - i % 8))) << (15 - i),
s0, s);
}
输出为:
0x00 0x00
0x3C 0xA5
i: 0, j: 0, 7-i%8: 7, ptr[j]: 0x3C, &val: 0x80, |val = 0x00000, s0: 0x0000, s: 0x0000
i: 1, j: 0, 7-i%8: 6, ptr[j]: 0x3C, &val: 0x40, |val = 0x00000, s0: 0x0000, s: 0x0000
i: 2, j: 0, 7-i%8: 5, ptr[j]: 0x3C, &val: 0x20, |val = 0x40000, s0: 0x0000, s: 0x0000
i: 3, j: 0, 7-i%8: 4, ptr[j]: 0x3C, &val: 0x10, |val = 0x10000, s0: 0x0000, s: 0x0000
i: 4, j: 0, 7-i%8: 3, ptr[j]: 0x3C, &val: 0x08, |val = 0x04000, s0: 0x0000, s: 0x4000
i: 5, j: 0, 7-i%8: 2, ptr[j]: 0x3C, &val: 0x04, |val = 0x01000, s0: 0x4000, s: 0x5000
i: 6, j: 0, 7-i%8: 1, ptr[j]: 0x3C, &val: 0x02, |val = 0x00000, s0: 0x5000, s: 0x5000
i: 7, j: 0, 7-i%8: 0, ptr[j]: 0x3C, &val: 0x01, |val = 0x00000, s0: 0x5000, s: 0x5000
i: 8, j: 1, 7-i%8: 7, ptr[j]: 0xA5, &val: 0x80, |val = 0x04000, s0: 0x5000, s: 0x5000
i: 9, j: 1, 7-i%8: 6, ptr[j]: 0xA5, &val: 0x40, |val = 0x00000, s0: 0x5000, s: 0x5000
i: 10, j: 1, 7-i%8: 5, ptr[j]: 0xA5, &val: 0x20, |val = 0x00400, s0: 0x5000, s: 0x5400
i: 11, j: 1, 7-i%8: 4, ptr[j]: 0xA5, &val: 0x10, |val = 0x00000, s0: 0x5400, s: 0x5400
i: 12, j: 1, 7-i%8: 3, ptr[j]: 0xA5, &val: 0x08, |val = 0x00000, s0: 0x5400, s: 0x5400
i: 13, j: 1, 7-i%8: 2, ptr[j]: 0xA5, &val: 0x04, |val = 0x00010, s0: 0x5400, s: 0x5410
i: 14, j: 1, 7-i%8: 1, ptr[j]: 0xA5, &val: 0x02, |val = 0x00000, s0: 0x5410, s: 0x5410
i: 15, j: 1, 7-i%8: 0, ptr[j]: 0xA5, &val: 0x01, |val = 0x00001, s0: 0x5410, s: 0x5411
0x5411
21521
除了在价值观s0
和s
是不是你想要的东西,而忽略了|val
,值是我们期望的东西; 基本的迭代结构处于控制之下。但是,该|val
列表明存在问题-出乎意料的是,需要在输出格式中使用5个十六进制数字!该i - 15
转变是不是把你想要和需要它们放置位。
从这里开始,您需要自己解决问题。我希望这样做是为您提供有关如何调试此类问题的一些见解。
顺便提一句,该问题已更新为提供:
s |= (ptr[j] & (1 << i%8)) << (15 - i); // Correction
在以0x3CA5作为初始值的测试工具中dat
,产生输出:
0x00 0x00
0x3C 0xA5
i: 0, j: 0, 7-i%8: 7, ptr[j]: 0x3C, &val: 0x80, |val = 0x00000, s0: 0x0000, s: 0x0000
i: 1, j: 0, 7-i%8: 6, ptr[j]: 0x3C, &val: 0x40, |val = 0x00000, s0: 0x0000, s: 0x0000
i: 2, j: 0, 7-i%8: 5, ptr[j]: 0x3C, &val: 0x20, |val = 0x08000, s0: 0x0000, s: 0x8000
i: 3, j: 0, 7-i%8: 4, ptr[j]: 0x3C, &val: 0x10, |val = 0x08000, s0: 0x8000, s: 0x8000
i: 4, j: 0, 7-i%8: 3, ptr[j]: 0x3C, &val: 0x08, |val = 0x08000, s0: 0x8000, s: 0x8000
i: 5, j: 0, 7-i%8: 2, ptr[j]: 0x3C, &val: 0x04, |val = 0x08000, s0: 0x8000, s: 0x8000
i: 6, j: 0, 7-i%8: 1, ptr[j]: 0x3C, &val: 0x02, |val = 0x00000, s0: 0x8000, s: 0x8000
i: 7, j: 0, 7-i%8: 0, ptr[j]: 0x3C, &val: 0x01, |val = 0x00000, s0: 0x8000, s: 0x8000
i: 8, j: 1, 7-i%8: 7, ptr[j]: 0xA5, &val: 0x80, |val = 0x00080, s0: 0x8000, s: 0x8080
i: 9, j: 1, 7-i%8: 6, ptr[j]: 0xA5, &val: 0x40, |val = 0x00000, s0: 0x8080, s: 0x8080
i: 10, j: 1, 7-i%8: 5, ptr[j]: 0xA5, &val: 0x20, |val = 0x00080, s0: 0x8080, s: 0x8080
i: 11, j: 1, 7-i%8: 4, ptr[j]: 0xA5, &val: 0x10, |val = 0x00000, s0: 0x8080, s: 0x8080
i: 12, j: 1, 7-i%8: 3, ptr[j]: 0xA5, &val: 0x08, |val = 0x00000, s0: 0x8080, s: 0x8080
i: 13, j: 1, 7-i%8: 2, ptr[j]: 0xA5, &val: 0x04, |val = 0x00080, s0: 0x8080, s: 0x8080
i: 14, j: 1, 7-i%8: 1, ptr[j]: 0xA5, &val: 0x02, |val = 0x00000, s0: 0x8080, s: 0x8080
i: 15, j: 1, 7-i%8: 0, ptr[j]: 0xA5, &val: 0x01, |val = 0x00080, s0: 0x8080, s: 0x8080
0x8080
32896
这不是完整的答案。
我想获得的价值
dat
成s
。我需要它,因为我必须通过UDP套接字发送char数组。因此,我将在一端将整数作为二进制存储在字符数组中,然后在另一端将其重新组装为整数。
您无需进行按位运算即可获得所需的结果。字节操作正常。
ptr[0] = dat >> 8;
ptr[1] = dat & 0xFF; // You could get away without the '& 0xFF'
// Transmit over UDP
dat = (ptr[0] << 8) | ptr[1];
使用unsigned char
(正在执行)很重要;如果您使用纯色char
(或更糟的是signed char
),则必须担心符号位和符号扩展。
作为您进行位操作的练习,这有一些目的。值得您花一些时间来修复您的代码,以便它可以正常工作。作为一种处理数据以通过网络传输的方法,它不是一种很好的工作方式,一旦您了解了比特操作的所有知识,就应该抛弃它。
解决该问题的一种方法(按我的想象,不一定是最好的,但有效的一种方法)是修复
lhs << (15 - i)
移位的LHS,以使移位的LHS值为0或1。例如:
((ptr[j] & (1 << (7 - i % 8))) ? 1 : 0) << (15 - i)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句