2010-05-16 57 views
2

我发现了一些我无法解释的奇怪东西。如果某人在这里可以看到发生了什么或为什么,我想知道。我正在做的是含有高排列像这样的12位无符号短:C中的位移和指针奇怪,寻找解释

1111 1111 1111 0000

那么我想希夫位,这样在短期内保持7位与MSB作为垫每个字节。在什么上面给出的结果应该是这样的:

0111 1111 0111 1100

我所做的是这样的:

unsigned short buf = 0xfff; 
//align high 
buf <<= 4; 

buf >>= 1; 
*((char*)&buf) >>= 1; 

这让我有点像看起来就像是正确的,但前一次换档的结果叶位设置是这样的:

0111 1111 1111 1100

很奇怪。如果我使用一个unsigned char用作临时存储和转变,那么它的工作原理,这样的:

unsigned short buf = 0xfff; 
buf <<= 4; 

buf >>= 1; 
tmp = *((char*)&buf); 
*((char*)&buf) = tmp >> 1; 

这样做的结果是:

0111 1111 0111 1100

任何想法是怎么回事?

回答

4

是的,它看起来像char已在您的平台上签名。如果你做了*((unsigned char*)&buf) >>= 1,它会工作。

+0

是的!感谢您的解释,现在正在工作。这让我发疯。 – foo 2010-05-16 18:12:56

1

让我们打破这一点。我假定你的编译器认为16位内存很短。

unsigned short buf = 0xfff; 
//align high 
buf <<= 4; 

相当于:

unsigned short buf = 0xfff0; 

...和

buf >>= 1; 

应导致buf中具有值0x7FF8将(即第比特移位一位到右侧)。现在为您的花式线:

*((char*)&buf) >>= 1; 

很多事情在这里......第一个左侧需要解决。你所说的是将buf视为指向8位内存的指针(而不是自然的16位)。 buf最初提到的两个字节中的哪一个依赖于已知存储器的端节点(如果它是big-endian buf指向0x7f,如果little-endian buf指向0xf8)。我假设你在一个英特尔盒子上,这意味着它的小端,现在buff指向0xf8。然后您的语句表示分配给该字节,该字节的值向右移动(并且自char被签名后的符号扩展),或者0xfc。另一个字节将保持不变。如果你不需要任何符号扩展,请将buf加入(unsigned char *)。

+0

谢谢。这是没有'unsigned'让我:D。令人沮丧。 – foo 2010-05-16 18:24:06