4

短い符号なし整数の配列がある場合。

array[k+1] を 8 ビット左にシフトすると、array[k+1] の下半分に 8 ビットが入りますか?

それとも、要素に割り当てられたスペースの外に出たために、単にドロップオフするのでしょうか?

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

次の配列要素に持ち越さずに、データ型を完全に削除します。

そのような動作が必要な場合は、次のようなコードを自分でコーディングする必要があります (配列全体を 4 ビット左シフトします)。

#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は、配列 [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)

これにより、array[3] が %eax にロードされ、変更され、元に戻されます。

于 2009-11-22T12:12:22.213 に答える
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 に答える
0

unsigned int を 8 ビット左にシフトすると、下位 8 ビットがゼロで埋められます。上位 8 ビットは破棄されます。それらが配列内にあるかどうかは問題ではありません。

ちなみに、8 ビットが unsigned int の半分であるかどうかはシステムによって異なりますが、32 ビット システムでは、8 ビットは通常 unsigned int の 4 分の 1 です。

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

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