C中移位运算符的确切用法是什么?

时间:2011-10-12 22:29:19

标签: c bit-shift

我认为移位操作符会移动整数或应用它的字符的内存,但下面代码的输出让我感到惊讶。

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

int main(void) {
    uint64_t number = 33550336;

    unsigned char *p = (unsigned char *)&number;
    size_t i;
    for (i=0; i < sizeof number; ++i)
        printf("%02x ", p[i]);
    printf("\n");

    //shift operation
    number = number<<4;

    p = (unsigned char *)&number;
    for (i=0; i < sizeof number; ++i)
        printf("%02x ", p[i]);
    printf("\n");

    return 0;
}

它运行的系统是little endian并产生以下输出:

00 f0 ff 01 00 00 00 00 
00 00 ff 1f 00 00 00 00 

有人可以提供一些参考移位运营商的详细工作吗?

5 个答案:

答案 0 :(得分:6)

我想你已回答了自己的问题。机器是 little endian ,这意味着字节存储在内存中,左边是最低有效字节。所以你的记忆代表:

00 f0 ff 01 00 00 00 00 => 0x0000000001fff000
00 00 ff 1f 00 00 00 00 => 0x000000001fff0000

如您所见,第二个值与第一个值相同,向左移动了4位。

答案 1 :(得分:2)

一切都是对的:

(1 *(256 ^ 3))+(0xff *(256 ^ 2))+(0xf0 * 256)= 33 550 336

(0x1f *(256 ^ 3))+(0xff *(256 ^ 2))= 536 805 376

33 550 336 *(2 ^ 4)= 536 805 376

向左移动4位与乘以2 ^ 4相同。

答案 2 :(得分:2)

我认为你打印混淆了你。以下是值:

     33550336 = 0x01FFF000
33550336 << 4 = 0x1FFF0000

你现在能看到你的输出吗?

答案 3 :(得分:2)

它不会移动内存,而是移位。所以你有这个号码:

00 00 00 00 01 FF F0 00

将此数字4位(一个十六进制数字)向左移动后,您有:

00 00 00 00 1F FF 00 00

当转换为小端时,这正是你得到的输出。

答案 4 :(得分:2)

你的循环按照它们存储在内存中的顺序打印字节,并且在big-endian机器上输出会有所不同。如果要以十六进制打印该值,请使用%016llx。然后你会看到你的期望:

0000000001fff000
000000001fff0000

第二个值左移4。