如果编写程序需要用到数据在内存中如何存储,那么除非必要,否则不用,如果用,那么集中在程序中的某个模块,不要分散在各处。
20.1 移位运算符
c语言提供了6个位运算符。这些运算符可以对整数数据进行位运算。这里先讨论2个移位运算符。然后讨论其余4个位运算符。
20.1.1
<<(左移位)和>>(右移位),可以操作任何的整数类型(包括char类型)。
可移植行技巧 为了可移植行,最好仅对无符号数进行移位运算。
/*~可以使得我们的底层程序移植行更好*/
#include <stdio.h>
int main(void)
{
unsigned int a1 = ~0; // every bit is 1
unsigned int a2 = 0x1f; //five ones
printf("%lu\n",sizeof(a1));
printf("%u\n",a1);
printf("%u",a2);
return 0;
}
注意:
20.1.3用位运算符访问位
(1)位的设置:假设我们要设置第4位(注意:假设共有16位,最高位是15位,最低位是0位),那么我们可以用下面的方法设置:
i = 0x0000;
i |= 0x0010;
更通过的做法是:把要设置的位存储在变量j中,然后通过下面的代码实现:
(2)位的清楚
(3)位的测试
练习题
2.
//chapter20 exe2
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
unsigned int i = 18,j = 5;
unsigned int ret =
(i & (1 << j)) ? (i &= ~(1 << j)):(i |= (1 << j));
printf("%u",ret);
return 0;
}
3. 根据异或运算规律,可以知道,最后返回开始时候的y值。
//chapter20 exe3
#include <stdio.h>
#include <stdlib.h>
#define M(x,y) ((x)^=(y),(y)^=x,(x)^=(y))
int main(void)
{
unsigned int x = 8,y = 155;
printf("%u",M(x,y));
return 0;
}
结果也证实了自己的猜想。
本章需要用到预处理器指令
练习题
4.
#include <stdio.h>
#include <math.h>
#if 0
/* 下面这个宏就是本题的答案 */
#endif
#define MK_COLOR(x,y,z) \
(0l | x) | ((0l | y) << 8) | ((0l | z) << 16)
int main()
{
printf("%lu",sizeof(unsigned long));
unsigned long a = MK_COLOR(1,2,3);
printf("\n%lu",a);
unsigned long ret = pow(2,16) * 3 + pow(2,9) + 1;
printf("\n%lu",ret);
return 0;
}
运行结果:197121
5.
#include <stdio.h>
#include <math.h>
#define GET_RED(x) \
(x & (unsigned long)(pow(2,8) - 1))
#define GET_GREEN(x) \
((x >> 8) & ((unsigned long) (pow(2,8) - 1 )))
#define GET_BLUE(x) \
((x >> 8 >> 8) & ((unsigned long) (pow(2,8) - 1 )))
int main()
{
unsigned long x = GET_RED(197121);
printf("%lu",x);
unsigned long y = GET_GREEN(197121);
printf("\n%lu",y);
unsigned long z = GET_BLUE(197121);
printf("\n%lu",z);
return 0;
}
1
2
3
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)