《2022年c语言宏定义详解 .pdf》由会员分享,可在线阅读,更多相关《2022年c语言宏定义详解 .pdf(8页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。
1、?c 语言宏定义详解1,防止一个头文件被重复包含#ifndef COMDEF_H#define COMDEF_H/头文件内容#endif2,重新定义一些类型,防止由于各种平台和编译器的不同,而产生的类型字节数差异,方便移植。typedefunsigned charboolean;/*Boolean value type.*/typedefunsigned long intuint32;/*Unsigned 32 bit value*/typedefunsigned short uint16;/*Unsigned 16 bit value*/typedefunsigned charuint8;/
2、*Unsigned 8bit value*/typedefsigned long intint32;/*Signed 32 bit value*/typedefsigned short int16;/*Signed 16 bit value*/typedefsigned charint8;/*Signed 8bit value*/下面的不建议使用typedefunsigned char byte;/*Unsigned 8bit value type.*/typedefunsigned shortword;/*Unsinged 16 bit value type.*/typedefunsigne
3、d long dword;/*Unsigned 32 bit value type.*/typedefunsigned char uint1;/*Unsigned 8bit value type.*/typedefunsigned shortuint2;/*Unsigned 16 bit value type.*/typedefunsigned long uint4;/*Unsigned 32 bit value type.*/typedefsigned char int1;/*Signed 8bit value type.*/名师资料总结-精品资料欢迎下载-名师精心整理-第 1 页,共 8
4、页 -typedefsigned shortint2;/*Signed 16 bit value type.*/typedeflong intint4;/*Signed 32 bit value type.*/typedefsigned long sint31;/*Signed 32 bit value*/typedefsigned shortsint15;/*Signed 16 bit value*/typedefsigned char sint7;/*Signed 8bit value*/3,得到指定地址上的一个字节或字#defineMEM_B(x)(*(byte*)(x)#defineM
5、EM_W(x)(*(word*)(x)4,求最大值和最小值#defineMAX(x,y)(x)(y)?(x):(y)#defineMIN(x,y)(x)field)/*lint+e545*/6,得到一个结构体中field 所占用的字节数#define FSIZ(type,field)sizeof(type*)0)-field)7,按照 LSB 格式把两个字节转化为一个Word#defineFLIPW(ray)(word)(ray)0)*256)+(ray)1)8,按照 LSB 格式把一个Word 转化为两个字节#defineFLOPW(ray,val)(ray)0=(val)/256);(ra
6、y)1=(val)&0 xFF)名师资料总结-精品资料欢迎下载-名师精心整理-第 2 页,共 8 页 -9,得到一个变量的地址(word 宽度)#defineB_PTR(var)(byte*)(void*)&(var)#defineW_PTR(var)(word*)(void*)&(var)10,得到一个字的高位和低位字节#defineWORD_LO(xxx)(byte)(word)(xxx)&255)#defineWORD_HI(xxx)(byte)(word)(xxx)8)11,返回一个比X 大的最接近的8 的倍数#define RND8(x)(x)+7)/8)*8)12,将一个字母转换为
7、大写#defineUPCASE(c)(c)=a&(c)=0&(c)=0&(c)=A&(c)=a&(c)(val)?(val)+1:(val)16,返回数组元素的个数#defineARR_SIZE(a)(sizeof(a)/sizeof(a0)17,返回一个无符号数n 尾的值 MOD_BY_POWER_OF_TWO(X,n)=X%(2n)#define MOD_BY_POWER_OF_TWO(val,mod_by)名师资料总结-精品资料欢迎下载-名师精心整理-第 3 页,共 8 页 -(dword)(val)&(dword)(mod_by)-1)18,对于 IO 空间映射在存储空间的结构,输入输
8、出处理#define inp(port)(*(volatile byte*)(port)#define inpw(port)(*(volatile word*)(port)#define inpdw(port)(*(volatile dword*)(port)#define outp(port,val)(*(volatile byte*)(port)=(byte)(val)#define outpw(port,val)(*(volatile word*)(port)=(word)(val)#define outpdw(port,val)(*(volatile dword*)(port)=(dw
9、ord)(val)19,使用一些宏跟踪调试A N S I 标准说明了五个预定义的宏名。它们是:_ L I N E _ _ F I L E _ _ D A T E _ _ T I M E _ _ S T D C _ 如果编译不是标准的,则可能仅支持以上宏名中的几个,或根本不支持。记住编译程序也许还提供其它预定义的宏名。_ L I N E _ 及_ F I L E _ 宏指令在有关#l i n e的部分中已讨论,这里讨论其余的宏名。_ D AT E _ 宏指令含有形式为月/日/年的串,表示源文件被翻译到代码时的日期。源代码翻译到目标代码的时间作为串包含在_ T I M E _ 中。串形式为时:分:
10、秒。如果实现是标准的,则宏 _ S T D C _ 含有十进制常量1。如果它含有任何其它数,则实现是非标准的。名师资料总结-精品资料欢迎下载-名师精心整理-第 4 页,共 8 页 -可以定义宏,例如:当定义了 _DEBUG,输出数据信息和所在文件所在行#ifdef _DEBUG#define DEBUGMSG(msg,date)printf(msg);printf(“%d%d%d”,date,_LINE_,_FILE_)#else#define DEBUGMSG(msg,date)#endif20,宏定义防止使用是错误用小括号包含。例如:#define ADD(a,b)(a+b)用 dowhi
11、le(0)语句包含多语句防止错误例如:#difne DO(a,b)a+b;a+;应用时:if(,.)DO(a,b);/产生错误else 解决方法:#difne DO(a,b)doa+b;a+;while(0)宏中#和#的用法一、一般用法我们使用#把宏参数变为一个字符串,用#把两个宏参数贴合在一起.用法:#include#include using namespace std;#define STR(s)#s 名师资料总结-精品资料欢迎下载-名师精心整理-第 5 页,共 8 页 -#define CONS(a,b)int(a#e#b)int main()printf(STR(vck);/输出字符
12、串 vck printf(%dn,CONS(2,3);/2e3 输出:2000 return 0;二、当宏参数是另一个宏的时候需要注意的是凡宏定义里有用#或#的地方宏参数是不会再展开.1,非#和#的情况#define TOW(2)#define MUL(a,b)(a*b)printf(%d*%d=%dn,TOW,TOW,MUL(TOW,TOW);这行的宏会被展开为:printf(%d*%d=%dn,(2),(2),(2)*(2);MUL 里的参数 TOW 会被展开为(2).2,当有#或#的时候#define A(2)#define STR(s)#s#define CONS(a,b)int(a#
13、e#b)printf(int max:%sn,STR(INT_MAX);/INT_MAX#include 这行会被展开为:printf(int max:%sn,INT_MAX);printf(%sn,CONS(A,A);/compile error 这一行则是:printf(%sn,int(AeA);INT_MAX和 A 都不会再被展开,然而解决这个问题的方法很简单.加多一层中间转换宏.加这层宏的用意是把所有宏的参数在这层里全部展开,那么在转换宏里的那一个宏(_STR)就能得到正确的宏参数.#define A(2)#define _STR(s)#s#define STR(s)_STR(s)/转
14、换宏#define _CONS(a,b)int(a#e#b)#define CONS(a,b)_CONS(a,b)/转换宏名师资料总结-精品资料欢迎下载-名师精心整理-第 6 页,共 8 页 -printf(int max:%sn,STR(INT_MAX);/INT_MAX,int型的最大值,为一个变量#include 输出为:int max:0 x7fffffff STR(INT_MAX)-_STR(0 x7fffffff)然后再转换成字符串;printf(%dn,CONS(A,A);输出为:200 CONS(A,A)-_CONS(2),(2)-int(2)e(2)三、#和#的一些应用特例1
15、、合并匿名变量名#define_ANONYMOUS1(type,var,line)typevar#line#define_ANONYMOUS0(type,line)_ANONYMOUS1(type,_anonymous,line)#defineANONYMOUS(type)_ANONYMOUS0(type,_LINE_)例:ANONYMOUS(static int);即:static int _anonymous70;70表示该行行号;第一层:ANONYMOUS(static int);-_ANONYMOUS0(static int,_LINE_);第二层:-_ANONYMOUS1(stati
16、c int,_anonymous,70);第三层:-static int_anonymous70;即每次只能解开当前层的宏,所以 _LINE_ 在第二层才能被解开;2、填充结构#defineFILL(a)a,#a enum IDDOPEN,CLOSE;typedef struct MSG IDD id;const char*msg;MSG;MSG _msg=FILL(OPEN),FILL(CLOSE);相当于:MSG _msg=OPEN,OPEN,CLOSE,CLOSE;3、记录文件名#define_GET_FILE_NAME(f)#f#defineGET_FILE_NAME(f)_GET_F
17、ILE_NAME(f)static charFILE_NAME=GET_FILE_NAME(_FILE_);4、得到一个数值类型所对应的字符串缓冲大小#define_TYPE_BUF_SIZE(type)sizeof#type#defineTYPE_BUF_SIZE(type)_TYPE_BUF_SIZE(type)charbufTYPE_BUF_SIZE(INT_MAX);-charbuf_TYPE_BUF_SIZE(0 x7fffffff);-charbufsizeof 0 x7fffffff;名师资料总结-精品资料欢迎下载-名师精心整理-第 7 页,共 8 页 -这里相当于:charbuf11;名师资料总结-精品资料欢迎下载-名师精心整理-第 8 页,共 8 页 -