2012-05-15 31 views
0

我前幾天在查看散列函數,發現有一個例子的網站。大部分代碼很容易掌握,但是這個宏觀功能我不能真正包裹我的頭。散列函數中的get16bits宏

有人可以分解這裏發生了什麼?

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

那麼,宏參數'D'被視爲char數組,第一個和零個字符組合成一個16位整數。 – wildplasser

+0

是的,這個宏把'd'指向little-endian的內存(可能是因爲它假設內存包含little-endian數據,即使系統本身可能是big-endian)。 –

回答

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 

首先我們必須通過一個地址到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 
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。