#include <stdio.h> // IO
#include <stdlib.h> // 提供 EXIT_SUCCESS
#include <limits.h> // 这里不需要
#include <stdint.h> // 这里不需要
typedef unsigned int ElemType;
// 打印字节序列(我的电脑是小端法输出的)
void
show_bytes(unsigned char *start, size_t len) {
size_t i;
for ( i = 0; i < len; i++ )
printf(" %.2x", start[i]);
putchar('\n');
}
// 打印unsigned类型的二进制
void
show_binary(ElemType x) {
size_t len = sizeof(ElemType) * CHAR_BIT; // 元素x有len位
ElemType MASK = 0x1;
ElemType Barr[len]; // 保存二进制序列
for ( size_t i = len; i > 0; ) {
Barr[--i] = x & MASK;
x = x >> 1;
}
for ( size_t i = 0; i < len; ) {
printf("%u", Barr[i]);
if( !(++i % 4) )
printf(" ");
}
putchar('\n');
}
int
fun1(unsigned word) {
return (int) ((word << 24) >> 24);
}
int
fun2(unsigned word) {
return ((int) word << 24) >> 24;
}
int
main(int argc, char *argv[])
{
ElemType word1 = 0x00000076;
ElemType word3 = 0x000000C9;
/*
ElemType word2 = 0x87654321;
ElemType word3 = 0x000000C9;
ElemType word4 = 0xEDCBA987;
show_binary(word1);
show_binary(word2);
show_binary(word3);
*/
printf("word1:0x00000076\n");
printf("小端字节序列:");
show_bytes((unsigned char *) &word1, sizeof(ElemType));
printf("二进制:");
show_binary(word1);
puts("fun1(word1):");
show_binary((ElemType) fun1(word1));
puts("func2(word1):");
show_binary((ElemType) fun2(word1));
putchar('\n');
printf("word3:0x000000C9\n");
printf("小端字节序列:");
show_bytes((unsigned char *) &word3, sizeof(ElemType));
printf("二进制:");
show_binary(word3);
puts("fun1(word3):");
show_binary((ElemType) fun1(word3));
puts("func2(word3):");
show_binary((ElemType) fun2(word3));
return EXIT_SUCCESS;
}
运行结果:
我这里使用第一和第三个w为测试。
这里fun1函数是先将操作数左移24位之后再右移24位,然后结果转化成int类型返回;
我们先讨论word1、word3、fun1函数:
程序中我打印了word1、word3的字节序列和二进制序列,这样很清楚的可以想象移位操作。
左移24位之后,变为最后一个字节移到最前一个字节的位置,fun1函数中操作数始终是一个无符号的数(unsigned int),我们看到左移24位之后word1的最高有效位是0,word3的最高有效位是1,这里我们可以进行比较了。之后进行右移操作,也就是我们这题目要讨论的其中一点就是无符号整数右移是算数右移还是逻辑右移;我们看到输出的结果可以看到无符号整数右移是进行逻辑右移,也就是加0;
简单说之看之,有符号整数进行的右移是算术右移,因为我们可以看到word3右移之后补加的1。
思路不是很好,说得不是很好,我最近在自学深入了解计算机系统,我们可以一起讨论。