4

如果我有一个短无符号整数数组。

将 array[k+1] 左移 8 位,将 8 位放入 array[k+1] 的下半部分?

或者他们只是因为超出了为元素分配的空间而放弃了?

4

5 回答 5

5

他们下车。你不能以这种方式影响其他位。尝试一下:

#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
于 2009-11-22T11:37:14.597 回答
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
于 2009-11-22T11:37:37.390 回答
2

考虑这一点的方法是,在 C(以及大多数编程语言)中,实现array[k] << 8涉及将 array[k] 加载到寄存器中,移位寄存器,然后将寄存器存储回 array[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)

这会将 array[3] 加载到 %eax 中,对其进行修改,然后将其存储回来。

于 2009-11-22T12:12:22.213 回答
0

将 unsigned int 左移 8 位将用零填充低 8 位。前 8 位将被丢弃,它们是否在数组中并不重要。

顺便说一句,8 位是否是 unsigned int 的一半取决于您的系统,但在 32 位系统上,8 位通常是 unsigned int 的四分之一。

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

x <<= 8;
// x is 0x34567800
于 2009-11-22T11:42:19.017 回答
0

请注意,int 数据类型的 C 定义没有指定它包含多少位,并且取决于系统。int 最初旨在成为处理器的“自然”字长,但并非总是如此,您可能会发现 int 包含 16、32、64 甚至一些奇数,如 24 位。

唯一可以保证的是 unsigned int 可以保存 0 到 UINT_MAX 之间的所有值,其中 UINT_MAX 必须至少为 65535 - 因此 int 类型必须包含至少 16 位以保存所需的值范围。

因此,将整数数组移位 8 位将单独更改每个 int,但请注意,这种移位不一定是“数组的一半”

于 2009-11-22T11:58:02.433 回答