这个函数什么意思?求每一步详解。
int rotate_l(unsigned int number, unsigned int bit)
{
unsigned int i;
unsigned int hign = 8 * sizeof(unsigned int);//最高位
for (i=0; i<bit; i++)
if( number&( 1<<(hign-1) ) ) number = (number << 1) | 1;
else number = number << 1;
return number;
} 展开
首先你要理解整数在内存中的存储方式。整数类型在内存中是以二进制(0 或 1)的形式存储的,每一位枯尺顷 0 或 1 都叫做一个 Bit(位元或比特困含)。Bit 是计算机存储中最小的容量单位。
接着,在 C 语言中,一个 int 整数类型(无论带不带符号)会占用 sizeof(int) 这么多 Byte(字节)没陆的内存空间,而一个字节等于 8 个 Bit 的大小(这是规定,就好比一米等于一百厘米一样),所以一个 C 语言整数类型占用的内存空间以 Bit 为单位来记的话,就是 8 × sizeof(int) 这么大。
在当今绝大部分平台上,一个 C 整形占用 4 Bytes 的空间(也就是 sizeof(int) == 4),也就是 8 × 4 = 32 Bits ,无论这个整数的值是多少。比如你通过 unsigned int a = 3 定义了一个无符号整数 a,它的十进制值为 3,那么它在内存中就会被存储为 00000000000000000000000000000011。(其中 11 是 3 的二进制值,而剩下的 30 位并未被使用,于是以 0 来填充)。
因此此函数 int rotate_l(unsigned int number, unsigned int bit) 的目的就是把一个无符号整数 number 的二进制形式中的所有 Bit 向左移 bit 个单位。如果左移过程中超过了整形 32 Bits 的长度限制,也就是说有一些 Bit 被挤下去了,那么这些 Bit 需要被接回到这个二进制数的末尾。
举个例子,number 和 bit 的值分别为 15 和 30,那么首先写出 15 的二进制表示形式 1111,然后将 32 个 Bit 中未使用的空余 28 位用零补满,也就是 00000000000000000000000000001111。接着,将这个数向左移动 30 个 单位(因为 bit 的值是 30)。过程如下:
00000000000000000000000000001111 -> 第 1 次移动
00000000000000000000000000011110 -> 第 2 次移动
00000000000000000000000000111100 -> 第 3 次移动
00000000000000000000000001111000 -> 第 4 次移动
...
11110000000000000000000000000000 -> 第 28 次移动
注意此时如果继续左移的话,位于最高位的 1 将被挤下这串二进制数,所以需要将它补到最低位去。也就是
11100000000000000000000000000001 -> 第 29 次移动
11000000000000000000000000000011 -> 第 30 次移动
可见,在经过这个函数移动 30 次之后,原来的 00000000000000000000000000001111(无符号十进制值 15) 变为了现在的 11000000000000000000000000000011(无符号十进制值 3221225475)。所以,如果你把 15 和 30 作为参数传递给 rotate_l 函数的话,得到的整数用 printf("%u") (打印无符号整数)打印出来,结果会是 3221225475。
了解了这个程序的运行原理,就可以看详细的程序设计了。这里有几个 C 语言二进制运算符号:
a << b:将 a 的二进制值向左移 b 位,超出整数位数的部分丢弃。
例:a = 3 (二进制 011), b = 5,则 a << b = 3 << 5 = 1100000 (十进制 96)
a & b:将 a 与 b 的二进制值进行逐位 and 操作 (1 & 1 = 1,其余皆为 0)。
例:a = 3 (二进制 011), b = 5 (二进制 101),则 a & b = 011 & 101 = 001 (十进制 1)
a | b:将 a 与 b 的二进制值进行逐位 or 操作 (0 | 0 = 0,其余皆为 1)。
例:a = 3 (二进制 011), b = 5 (二进制 101),则 a | b = 011 | 101 = 111 (十进制 7)
程序详细注释如下:
你也可以通过加上以下的 main 函数运行程序来测试一下传入参数 15 和 30 后程序的输出是不是如前面所说的 3221225475。