用宏定义来完成位运算及复杂宏定义的解析方法

来源:互联网 发布:淘宝平台争议处理规则 编辑:程序博客网 时间:2024/05/22 15:29
用宏定义来完成位运算及复杂宏定义的解析方法


#include <stdio.h>


// 第一题:用宏定义将32位数x的第n位(右边起算,也就是bit0算第1位)置位
//注意:1.宏名要大写 2.宏要放外面  3.参数加()  4.常数也要加()规范
#define SET_BIT(N , X) (X | (1U<<(N-1)))  //U表示unsigned


// 第二题:用宏定义将32位数x的第n位(右边起算,也就是bit0算第1位)清零
#define CLEAR_BIT(N , X) (X & (~(1U<<(N-1)))) 


//第三题:用宏定义将32位数x的第n位到第m位(右边起算,也就是bit0算第1位,m是高位)置位
// 分析:加入n=3,m=6,题目就是要把bit2到bit5置位
// 我们需要一个算式来得到(m-n+1)个1
//方法: 第一步 ~0U   得到32个1
//第二步32个右移移32-(m-n+1) ,得到(m-n+1)个1
#define SET_BIT_NM(N , M, X) (X | ((~0U)>>(32-(M-N+1)))<<(N-1))
//总结:此宏有缺陷,只能用于32位
//更优解为((x & ~(~(0U)<<(m-n+1))<<(n-1)) >> (n-1))


//第四:用宏定义将32位数x的第n位到第m位(右边起算,也就是bit0算第1位,m是高位)清零
#define CLEAR_BIT_NM(N , M, X) (X & (~(((~0U)>>(32-(M-N+1)))<<(N-1))))


// 第五题:截取变量x的第n到第m位
#define GET_BITS(X, N, M) (X & ~(~(0U)<<(M-N+1))<<(N-1)) >> (N-1))


int main(void)
{
/*
//第一题代码
unsigned int a = 0;
//局部变量不初始化结果是随机的,所以定义局部变量最好在定义时初始化
unsigned int b = 0;   
b = SET_BIT(4 , a);
printf("b = %x.\n", b);
*/

/*
//第二题代码
unsigned int a = 0xff;
//局部变量不初始化结果是随机的,所以定义局部变量最好在定义时初始化
unsigned int b = 0;   
b = CLEAR_BIT(4 , a);
printf("b = %x.\n", b);
*/

/*
//第三题代码
unsigned int a = 0;
//局部变量不初始化结果是随机的,所以定义局部变量最好在定义时初始化
unsigned int b = 0;   
b = SET_BIT_NM(1 , 4, a);
printf("b = %x.\n", b);
*/


/*
//第四题代码
unsigned int a = 0xff;
//局部变量不初始化结果是随机的,所以定义局部变量最好在定义时初始化
unsigned int b = 0;   
b = CLEAR_BIT_NM(5 , 8, a);
printf("b = %x.\n", b);
*/


//第五题代码
unsigned int a = 0xabff;
//局部变量不初始化结果是随机的,所以定义局部变量最好在定义时初始化
a &= GET_BITS(X, N, M)
printf("a = %x.\n", a);


}


/*复杂宏定义分析:
该题目类比于4.2.4的6题:给定一个整形数a,取出a的bit3~bit8
第一步:先将这个数bit3~bit8不变,其余位全部清零。
第二步,再将其右移3位得到结果。

((X & ~(~(0U)<<(M-N+1))<<(N-1)) >> (N-1))
思路:按()拆解,去()
(X & ~(~(0U)<<(M-N+1))<<(N-1))       >> (N-1)
左移,相当于第二步,在拆解(X & ~(~(0U)<<(M-N+1))<<(N-1))  
X &~(~(0U)<<(M-N+1))<<(N-1)
相当于第一步,在拆解 ~(~(0U)<<(M-N+1))<<(N-1)
 ~(~(0U)<<(M-N+1))<<(N-1)
此时要注意~和<<d的优先级,
解法:第一,查C语言优先级表
 第二,自己实际写个代码测试。
结论:~优先级高于<<
故拆为~(~(0U)<<(M-N+1))<<(N-1)


*/
0 0
原创粉丝点击