0

先日、ハッシュ関数を調べていたところ、その一例が掲載されているWebサイトに出くわしました。ほとんどのコードは簡単に理解できましたが、このマクロ関数は頭を悩ませることはできません。

誰かがここで何が起こっているのかを分析できますか?

#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) +(uint32_t)(((const uint8_t *)(d))[0]))
4

2 に答える 2

1

基本的に、32ビット整数dの下位16ビットを取得します

それを分解しましょう

#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) +(uint32_t)(((const uint8_t *)(d))[0]))
uint32_t a = 0x12345678;
uint16_t b = get16bits(&a); // b == 0x00005678

最初に to のアドレスを渡さなければなりget16bits()ません。そうしないと機能しません。

(((uint32_t)(const uint8_t *)(d))[1])) << 8

これは最初に 32 ビット整数を 8 ビット整数の配列に変換し、2 つを取得します。次に、値を8ビットシフトして、下位8ビットを追加します

+ (uint32_t)(((const uint8_t *)(d))[0]))

この例では、

uint8_t tmp[4] = (uint8_t *)&a;
uint32_t result;
result = tmp[1] << 8; // 0x00005600
result += tmp[0]; //tmp[0] == 0x78
// result is now 0x00005678
于 2012-05-15T15:14:26.940 に答える
1

このマクロは、次のものとほぼ同等です。

static uint32_t get16bits(SOMETYPE *d)
{
unsigned char temp[ sizeof *d];
uint32_t val;

memcpy(temp, d, sizeof *d);

val = (temp[0] << 8)
     + temp[1];
return val;
}

ただし、マクロ引数には型がなく、関数引数には型があります。

別の方法は、実際にキャストすることです:

static uint32_t get16bits(SOMETYPE *d)
{
unsigned char *cp = (unsigned char*) d;
uint32_t val;

val = (cp[0] << 8)
     + cp[1];
return val;
}

、これも弱点を示しています。1 でインデックス付けすることにより、コードは sizeof (*d) が少なくとも 2 であると想定します。

于 2012-05-15T15:09:53.913 に答える