18-另一个例子
15.3.9 另一个例子
我们来看另一个例子。这次要编写的函数用于切换一个值中的后 n 位,待处理值和 n 都是函数的参数。
~运算符切换一个字节的所有位,而不是选定的少数位。但是, ^ 运算符(按位异或)可用于切换单个位。假设创建了一个掩码,把后 n 位设置为 1 ,其余位设置为 0 。然后使用 ^ 组合掩码和待切换的值便可切换该值的最后 n 位,而且其他位不变。方法如下:
int invert_end(int num, int bits)
{
int mask = 0;
int bitval = 1;
while (bits–– > 0)
{
mask |= bitval;
bitval <<= 1;
}
return num ^ mask;
}
while 循环用于创建所需的掩码。最初, mask 的所有位都为 0 。第1轮循环将 mask 的 0 号位设置为 1 。然后第2轮循环将 mask 的1号位设置为 1 ,以此类推。循环 bits 次, mask 的后 bits 位就都被设置为 1 。最后, num ^ mask 运算即得所需的结果。
我们把这个函数放入前面的程序中,测试该函数。如程序清单15.2所示。
程序清单15.2 invert4.c 程序
/* invert4.c -- 使用位操作显示二进制 */
#include <stdio.h>
#include <limits.h>
char * itobs(int, char *);
void show_bstr(const char *);
int invert_end(int num, int bits);
int main(void)
{
char bin_str[CHAR_BIT * sizeof(int) + 1];
int number;
puts("Enter integers and see them in binary.");
puts("Non-numeric input terminates program.");
while (scanf("%d", &number) == 1)
{
itobs(number, bin_str);
printf("%d is\n", number);
show_bstr(bin_str);
putchar('\n');
number = invert_end(number, 4);
printf("Inverting the last 4 bits gives\n");
show_bstr(itobs(number, bin_str));
putchar('\n');
}
puts("Bye!");
return 0;
}
char * itobs(int n, char * ps)
{
int i;
const static int size = CHAR_BIT * sizeof(int);
for (i = size - 1; i >= 0; i--, n >>= 1)
ps[i] = (01 & n) + '0';
ps[size] = '\0';
return ps;
}
/* 以4位为一组,显示二进制字符串 */
void show_bstr(const char * str)
{
int i = 0;
while (str[i]) /* 不是空字符 */
{
putchar(str[i]);
if (++i % 4 == 0 && str[i])
putchar(' ');
}
}
int invert_end(int num, int bits)
{
int mask = 0;
int bitval = 1;
while (bits-- > 0)
{
mask |= bitval;
bitval <<= 1;
}
return num ^ mask;
}
下面是该程序的一个运行示例:
Enter integers and see them in binary.
Non-numeric input terminates program.
7
7 is
0000 0000 0000 0000 0000 0000 0000 0111
Inverting the last 4 bits gives
0000 0000 0000 0000 0000 0000 0000 1000
12541
12541 is
0000 0000 0000 0000 0011 0000 1111 1101
Inverting the last 4 bits gives
0000 0000 0000 0000 0011 0000 1111 0010
q
Bye!