2009-11-22 66 views
3

如果我有一個短無符號整數的數組。C無符號整型數組和位移

將陣列[k + 1]左移8位,將8位置於陣列[k + 1]的下半部分?

或者他們是否因爲他們超出了元素的分配空間而退出?

+0

你是不是指'把數組[k]左移? – 2009-11-22 11:56:28

回答

4

他們放棄。你不能以這種方式影響其他位。嘗試:

#include <stdio.h> 

void print_a (short * a) 
{ 
    int i; 
    for (i = 0; i < 3; i++) 
     printf ("%d:%X\n", i, a[i]); 
} 

int main() 
{ 
    short a[3] = {1, -1, 3}; 
    print_a (a); 
    a[1] <<= 8; 
    print_a (a); 
    return 0; 
} 

輸出是

 
0:1 
1:FFFFFFFF 
2:3 
0:1 
1:FFFFFF00 
2:3 
3

它們完全脫落的數據類型,而不是攜帶到下一個數組元素。

如果你想那樣的行爲,你必須自己喜歡的東西(由四位左移整個陣列)的代碼,它:

#include <stdio.h> 
int main(void) { 
    int i; 
    unsigned short int a[4] = {0xdead,0x1234,0x5678,0xbeef}; 

    // Output "before" variables. 

    for (i = 0; i < sizeof(a)/sizeof(*a); i++) 
     printf ("before %d: 0x%04x\n", i, a[i]); 
    printf ("\n"); 

    // This left-shifts the array by left-shifting the current 
    // element and bringing in the top bit of the next element. 
    // It is in a loop for all but hte last element. 
    // Then it just left-shifts the last element (no more data 
    // to shift into that one). 

    for (i = 0; i < sizeof(a)/sizeof(*a)-1; i++) 
     a[i] = (a[i] << 8) | (a[i+1] >> 8); 
    a[i] = (a[i] << 8); 

    // Print the "after" variables. 

    for (i = 0; i < sizeof(a)/sizeof(*a); i++) 
     printf ("after %d: 0x%04x\n", i, a[i]); 

    return 0; 
} 

此輸出:

before 0: 0xdead 
before 1: 0x1234 
before 2: 0x5678 
before 3: 0xbeef 

after 0: 0xad12 
after 1: 0x3456 
after 2: 0x78be 
after 3: 0xef00 
0

移位一個由8位剩下的無符號整數將用零填充低8位。前8位將被丟棄,它們在數組中並不重要。

順便提一下,8位是無符號整數的一半取決於您的系統,但在32位系統上,8位通常是無符號整數的四分之一。

unsigned int x = 0x12345678; 
// x is 0x12345678 

x <<= 8; 
// x is 0x34567800 
0

請注意,int數據類型的C定義沒有指定它包含的位數,並且依賴於系統。一個int最初是爲了處理器的「自然」字大小,但這並不總是如此,你可以發現int包含16,32,64甚至一些奇數如24位。

唯一保證的是無符號整數可以包含0和UINT_MAX之間的所有值,其中UINT_MAX必須至少爲65535 - 所以int類型必須包含至少16位以保存所需的值範圍。

因此,通過8個比特移位整數的陣列將改變每個單獨INT,但請注意,這種轉變將不一定是

2

考慮這個問題的方法「的陣列的一半」是,在C(對於大多數編程語言),array[k] << 8的實現涉及將數組[k]加載到寄存器,移位寄存器,然後將寄存器存回數組[k]。因此array [k + 1]將保持不變。

作爲一個例子,foo.c

unsigned short array[5]; 

void main() { 
    array[3] <<= 8; 
} 

將生成以下操作的指令:

movzwl array+6(%rip), %eax 
sall $8, %eax 
movw %ax, array+6(%rip) 

此負荷陣列[3]到%eax中,修改它,並將其存儲回。