2

我一直在尝试理解使用以下代码时遇到的错误

bytes2bits(p,q,pixels)
u_char *p, *q;
register u_int pixels;
{
  register u_char *r, a;
  register u_long *l;

   ...

switch (*l++) {
    case 0x00000000:    a = 0x00; break;
    case 0x00000001:    a = 0x10; break;
    case 0x00000100:    a = 0x20; break;
    case 0x00000101:    a = 0x30; break;

    case 0x00010000:    a = 0x40; break;
    case 0x00010001:    a = 0x50; break;
    case 0x00010100:    a = 0x60; break;
    case 0x00010101:    a = 0x70; break;

    case 0x01000000:    a = 0x80; break;
    case 0x01000001:    a = 0x90; break;
    case 0x01000100:    a = 0xa0; break;
    case 0x01000101:    a = 0xb0; break;

    case 0x01010000:    a = 0xc0; break;
    case 0x01010001:    a = 0xd0; break;
    case 0x01010100:    a = 0xe0; break;
    case 0x01010101:    a = 0xf0; break;

    default:
      (void) fprintf(stderr,"bytes2bits: bad value %x\n",*--l);
      exit(1);
}

    ......

}

我的问题在于这个代码块退出并显示错误消息

bytes2bits: bad value 1010100

我会认为 0x01010100 == 1010100 (注意:fprintf 使用 %x 作为输出格式,所以我正在查看一个十六进制数字。此外,当我测试并使用具有 %d 输出格式的 printf 时,我看到值 16843008 (= 16^6 + 16^4 + 16^2),这是 0x01010100 的等效十进制表示。“坏值”1010100 输出不受我的 printf 检查语句的影响)。

bytes2bits: bad value 1010100

我如何理解 switch 语句不将 1010100 识别为倒数第二个情况(即 0x01010100:a = 0xe0)这一事实?

4

3 回答 3

5

这里唯一合理的猜测是,在您的平台上,u_long您分析switch的时间比您实际打印的时间长。intunsigned int

例如,如果u_long是 64 位类型并且int是 32 位类型,那么您的*l++计算结果可能为0xBAADF00D01010100. case 0x01010100:这显然与标签不符。但是当你用说明符做你printf的 s 时%x,你只打印尾随0x01010100部分。

l在格式说明符(等)中使用前缀%lx来打印%ldlong以避免将来出现此类混淆(假设u_long基于long)。

于 2012-07-11T17:38:36.397 回答
3

也许您在一个 u_long 的大小与预期不符的平台上(例如 64 位字)。所以 *l 可能会采用比您正在测试的 32 位模式更大的值,并且“%d”和“%x”格式可能会将实际值截断为 32 位。我建议你打印 sizeof(*l)。

于 2012-07-11T17:29:00.400 回答
0

更新:(希望这次我做对了;-)

a= (*l &         1) << 4
 | (*l &     0x100) >> 3
 | (*l &   0x10000) >> 10
 | (*l & 0x1000000) >> 17
 ;
if ( *l & 0xfefefefe) {
   fprintf(stderr, "Badstuff: %lx\n", (unsigned long) *l);
   exit(EXIT_FAILURE);
   }
 l++;
于 2012-07-11T17:19:02.487 回答