关键词不能为空

当前您在: 主页 > 英语 >

CC++ 中(两个井号)和(一个井号)用法

作者:高考题库网
来源:https://www.bjmy2z.cn/gaokao
2021-02-09 22:27
tags:

-

2021年2月9日发(作者:measure)


C/C++



##(


两个井号


)



#(

一个井号


)


用法



##(


两个井号


)



#(


一个井号


)


都是什 么意思



连接符



##(


两个井号


)


不知道什么符



#(


一个井号


)


##


连接符号由两个井号组成,其功能是在带参数的宏定义中 将两个子串


(token)


联接起来,


从而形成一个新的子串。


但它不可以是第一个或者最后一个子串。


所谓的子串


(token)


就是指


编 译器能够识别的最小语法单元。具体的定义在编译原理里有详尽的解释



#


符是把传递过来的参数当成字符串进行替代。



假设程序中已经定义了这样一个带参数的宏:



#define PRINT( n ) printf(



同时又定义了二个整形变量:



int token9 = 9;


现在在主程序中以下面的方式调用这个宏:



PRINT( 9 );


那么在编译时,上面的这句话被扩展为:



printf(


注意到在这个例子中,


PRINT(9);


中的这个


”9”


被原封不动的当成了一个字符串,与


”token”


连接在了一 起,从而成为了


token9


。而


#n


也被


”9”


所替代。

< br>


可想而知,上面程序运行的结果就是在屏幕上打印出



token9=9



还有点不明白


?!


再来一个例子


:


#define PRINT( n ) printf(



int token9 = 9;


int game9 = 99;


调用


:


PRINT(9);


屏幕上打印出


:


token9 = 99



///////////////////////// ////////////////////////////////////////////////// ///////////////////////////


//////////// ////////////////////////////////////////////////// ////////////////////////////////////////



C++



##(

< br>两个井号


)



#(


一个井号


)


用法(转)



C


(和


C++


)中的宏(


Macro


)属于编译器预处理的范畴,属于编译期 概念(而非运行期概


念)。下面对常遇到的宏的使用问题做了简单总结。







#



##




C


语言的 宏中,


#


的功能是将其后面的宏参数进行字符串化操作(


Stringfication


),简单


说就 是在对它所引用的宏



变量通过替换后在其左右各加上一个双引 号。比如下面代码中的


宏:




#define WARN_IF(EXP)



do{ if (EXP)



fprintf(stderr,



while(0)



那么实际使用中会出现下面所示的替换过程:




WARN_IF (divider == 0);




被替换为





do {



if (divider == 0)



fprintf(stderr,



} while(0);



这样每次


divider


(除数)为


0


的时候便会在标



准错误流上输出一个提示信息。



< /p>



##


被称为连接符


concatenator




用来将两个


Token


连接为一个


Token



注意这里连

< br>



的对象是


Token


就行,而不一定是宏的变量。比如你要做一个菜单项命令名和函数指针组


成的结构体的数组,并且希望在函数名和菜单项命令名之间有直观


< br>的、名字上的关系。那


么下面的代码就非常实用:




struct command



{



char * name;



void (*function) (void);



};




#define COMMAND(NAME) { NAME, NAME ## _command }




// < /p>


然后你就用一些预先定义好的命令来方便的初始化一个


comma nd


结构的数组了:





struct command commands[] = {



COMMAND(quit),



COMMAND(help),



...



}



COMMAND


宏在这里充当一个代 码生成器的作用,这样可以在一定程度上减少代码密度,


间接地也可


以减少不留心所造成的错误。我们还可以


n



##


符号连接



n+1



Token


, 这


个特性也是


#


符号所不具备的。比如 :




#define LINK_MULTIPLE(a,b,c,d) a##_##b##_##c##_##d




typedef struct _record_type LINK_MULTIPLE(name,company,position,salary);



//


这里这个语句将展开为:




// typedef struct _record_type name_company_position_salary;


< br>关于


...


的使用




...



C


宏中称为


Variadic Macro


,也就是变参宏。比如:




#define myprintf(templt,...) fprintf(stderr,templt,__VA_ARGS__)




//


或者





#define myprintf(templt,args...) fprintf(stderr,templt,args)



第一个宏中由于没有对变



参起名,< /p>


我们用默认的宏


__VA_ARGS__


来替代它。


第二个宏中,


我们显式地命名变参为


args


,那么我们在宏定义中就可以用


args


来代指变参了。




C



言的


stdcall

< p>
一样,变参必须作为参数表的最有一项出现。当上面的宏中我们只能提供第一


个参数


templt


时,


C


标准要求我们必须写成:




myprintf(templt,);





形式。这时的替换过程为:




myprintf(


-


-


-


-


-


-


-


-



本文更新与2021-02-09 22:27,由作者提供,不代表本网站立场,转载请注明出处:https://www.bjmy2z.cn/gaokao/624453.html

CC++ 中(两个井号)和(一个井号)用法的相关文章