用宏定义来完成位运算及复杂宏定义的解析方法
来源:互联网 发布:淘宝平台争议处理规则 编辑:程序博客网 时间: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)
*/
#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
- 用宏定义来完成位运算及复杂宏定义的解析方法
- 2.5.位运算实战演练2--技术升级:用宏定义来完成位运算
- 用宏定义来完成位运算(置位,复位,截取)
- 宏定义与位运算
- 用宏定义来完成运算(本文来自百度文库)
- 顺时针方法 解读 C 复杂宏定义
- php中函数的定义,调用,及获取参数的方法。和位运算等。
- 用宏定义加字符串运算为女朋友完成她没做好的程序,勿喷
- 宏定义,条件编译,共用体,位运算,位域
- 一个复杂宏定义的解读
- 指针的定义及运算
- 常用宏定义运算
- 结构体元素偏移量宏的定义及解析
- Visual C#类的定义及实现方法实例解析
- 用do while{0}定义宏来定义函数
- 用do while{0}定义宏来定义函数
- 宏定义浅谈 用宏定义交换数的奇偶位 用宏定义找出两个数最大值
- 位操作的一些常用宏定义
- 练习二 1003 多人分披萨问题
- AsyncQueryHander的用法
- 使用Zabbix中遇到的问题:snmp监控端口流量偶尔会断图
- 利用两个视图实现图片循环利用
- Linux 必备工具
- 用宏定义来完成位运算及复杂宏定义的解析方法
- Android API Guides---ListView
- SGU 140 Integer Sequences(扩展欧几里得)
- Java中的Stack栈和Heap堆的区别
- 最多有多少个点在一条直线上
- Class类中的一些方法
- Java中equals和==的区别
- 文章标题
- Linux内核分析——进程切换与系统一般执行过程