2009-11-22 33 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中,修改它,并将其存储回。