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 を使用しているため、16 進数を見ています。また、%d 出力形式で printf をテストして使用すると、値 16843008 (= 16^6 + 16^4 + 16^2)、これは 0x01010100 と同等の 10 進数表現です。'bad value' 1010100 出力は、私の printf チェック ステートメントの存在によって影響を受けません)。

bytes2bits: bad value 1010100

switch ステートメントが 1010100 を最後から 2 番目のケース (つまり、0x01010100: a = 0xe0) として認識しないという事実をどのように理解できますか?

4

3 に答える 3

5

ここでの唯一の合理的な推測は、プラットフォーム上でu_long分析するものが実際に印刷しているものswitchよりも長いint/ということです。unsigned int

たとえば、u_longが64ビット型でint32ビット型の場合、はに*l++評価される可能性があります0xBAADF00D01010100。これは明らかにcase 0x01010100:ラベルと一致しません。ただし、指定子を使用してprintfsを実行している場合は、末尾部分%xのみを印刷します。0x01010100

将来そのような混乱を避けるために、フォーマット指定子(など)lでプレフィックスを使用して値を出力します(に基づいていると仮定します)。%lx%ldlongu_longlong

于 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 に答える