
C语言宏的高级应用.doc
7页关于#和##在C语言的宏中,#的功能是将其后面Stringfication#defineWARN_IF(EXP)\do{if(EXP)\fprintf(stderr,"Warning:"#EXP"\n");}\while(0)WARN_IF(divider==0);do{if(divider==0)fprintf(stderr,"Warning""divider==0""\n");}while(0);divider0Token##concatenatorToken接的对象是Token就行,而不一定是宏的变量比如你要structcommandchar*name;void(*function)(void);};#defineCOMMAND(NAME){NAME,NAME##_command}//commandstructcommandcommands[]={COMMAND(quit),COMMAND(help),}COMMANDn##n+1Token##defineLINK_MULTIPLE(a,b,c,d)a##_##b##_##c##_##dtypedefstruct_record_typeLINK_MULTIPLE(name,company,position,salary);//这里这个语句将展开为://typedefstruct_record_typename_company_position_salary;VariadicMacro#definemyprintf(templt,...)fprintf(stderr,templt,__VA_ARGS__)//#definemyprintf(templt,args...)fprintf(stderr,templt,args)VA_ARGSargsargsstdcalltempltCmyprintf(templt,);myprintf("Error!\n",);fprintf(stderr,"Error!\n",);GNUCPPmyprintf(templt);fprintf(stderr,"Error!\n",);c99GNUCPP#definemyprintf(templt,...)fprintf(stderr,templt,##__VAR_ARGS__)这时,##这个连接符号充当的作用就是当__VAR_ARGS__为空的时候,myprintf(templt);fprintf(stderr,templt);templtMisnestingOperatorPrecedeneeProblem#defineceil_div(x,y)(x+y-1)/ya=ceil_div(b&c,sizeof(int));a=(b&c+sizeof(int)-1)/sizeof(int);//由于+/-的优先级高于&的优先级,那么上面式子等同于:a=(b&(c+sizeof(int)-1))/sizeof(int);#defineceil_div(x,y)(((x)+(y)-1)/(y))SemicolonSwallowing通常情况下,为了使函数模样的宏在表面上看起来像一个通常的CMY_MACRO(x);#defineMY_MACRO(x){\/*line1*/\/*line2*/\/*line3*/}//...if(condition())MY_MACRO(a);else{...}MY_MACRO(x);#defineMY_MACRO(x)do{/*line1*/\/*line2*/\/*line3*/}while(0)DuplicationofSideEffectsSideEffect#definemin(X,Y)((X)>(Y)?(Y):(X))//...c=min(a,foo(b));foo()#definemin(X,Y)({\typeof(X)x_=(X);\typeof(Y)y_=(Y);\Evaluationmin(X,Y)(x_
