【1】宏定义怎么理解?
关于宏定义,把握住本质:仅仅是一种字符替换,而且是在预处理之前就进行。
【2】宏定义可以包括分号吗?
可以,示例代码如下:
1 #include2 using namespace std; 3 4 #define PI 3.14; //宏定义可以包括“;” 5 6 void main() 7 { 8 double r=10,s; 9 s=r*r*PI //注意此处的语法10 cout< <
【3】宏定义一种新类型如何实现?
示例代码如下:
1 #include2 using namespace std;3 #define int int *4 void main()5 {6 int a,b;// int *a, b;7 }8 //理解此处的微妙:int *a,b; 这条语句同时定义了两个变量。一个指针:int *a; 一个变量:int b;
【4】宏定义一个函数如何实现?
示例代码如下:
1 #include2 using namespace std; 3 4 #define Begin() {int a;a=0;cout<<"a="< <
【5】宏定义如何取消?
示例代码如下:
1 #include2 using namespace std; 3 4 #define int int * 5 6 void main() 7 { 8 int a, p; // int *a,p; 9 a = &p;10 #undef int //取消宏定义11 int b = 10;12 a = &b;13 }
【6】对宏定义歧义现象怎么识别?
示例代码如下:
1 #define SUM(x,y) x*y2 #define SUMM(x,y) ((x)*(y))3 void main()4 {5 int a = 4, b = 5;6 cout<<
求一个数的平方正确的宏定义:
#define S(r) ((r)*(r))
这个宏定义注意事项:
(1)宏名和参数的括号间不能有空格
(2)宏替换只作替换,不做计算,不做表达式的求解
(3)函数调用在编译后程序运行时进行,并且分配内存。宏替换在编译前执行,不分配内存
(4)宏的哑实结合不存在类型,也没有类型转换
(5)函数只有一个返回值,利用宏则可以设法得到多个值
(6)宏展开使源程序变长,函数调用不会
(7)宏展开不占运行时间,只占编译时间,函数调用占运行时间(分配内存 保留现场 值传递 返回值)
何谓哑实结合?
示例代码及解释如下:
1 #define S(a,b) a*b2 void main()3 {4 int area = 0;5 area = S(3,2); //第一步:被替换为area = a*b; 第二步:被替换为area = 2*3;6 //类似于函数调用,有一个哑实结合过程7 }
【7】下面宏定义特例如何解析?
示例代码如下:
1 #define NAME "zhangyuncong" 2 //#define AB "liu //error!!编译错误 3 //#define 0x abcd //error!!编译错误 4 void main() 5 { 6 cout<<
也就是说,这种情况下记住:#define 第一位置 第二位置
(1)不替换程序中的字符串内的任何内容
(2)第一位置只能是合法的标识符(可以是关键字)
(3)第二位置如果有字符串,必须把“”配对
(4)只替换与第一位置完全相同的标识符
总之一句话:仅仅只是简单的替换而已,不要在中间计算结果,一定要替换出表达式之后再计算
【8】宏定义的特例有参形式如何解析?
示例代码如下:
1 #define FUN(a) "a" 2 void main()3 {4 cout<<
通过上例可以看到,如果这样写,不论实参是什么,都不会摆脱被替换为“a”的命运。也许,你会问,那么我要实现FUN(345)被替换为“345”??肿么办呢??
请看下面这个用法
【9】有参宏定义中#的有何作用?
示例代码如下:
1 #define STR(str) #str 2 3 void main() 4 { 5 cout<<
备注:代码编译环境为VS2010 那么相信“#”的作用也一目了然。在此不作赘述。
【10】有参宏定义中##有何作用?
示例代码如下:
1 #define SIGN( x ) INT_##x 2 #define WIDE(str) L##str 3 4 void main() 5 { 6 int SIGN(a); 7 // int INT_a; //error!! redefinition 8 char * WIDE(a); 9 // char *La; //error!! redefinition10 }
【11】当一个宏自己调用自己时,会发生什么呢?
例如:#define TEST(x) ( x + TEST( x ) )
TEST(1); 会发生什么呢?为了防止无限制递归展开,语法规定:当一个宏遇到自己时,就停止展开。
也就是说,当对TEST(1)进行展开时,展开过程中又发现了一个TEST,那么就将这个TEST当作一个
一般的符号。TEST(1)最终被展开为:1 + TEST(1)。
【12】可以举一个变参宏的例子吗?
示例代码如下:
1 #define LOG( format,... ) printf( format, __VA_ARGS__ )2 3 void main()4 {5 int a = 10;6 char *str = "abc";7 LOG("%d,%s",a,str); //10,abc8 }
【13】当宏作为参数被放进另一个宏体时,将会发生什么?
当一个宏参数被放进宏体时,这个宏参数会首先被全部展开(当然,没有绝对,也有例外)。当展开后的宏参数被放进宏体时,
预处理器对新展开的宏体进行第二次扫描。并继续展开。举例说明:
示例代码如下:
1 #define PARAM(x) x2 #define ADDPARAM(x) INT_##x3 4 void main()5 {6 int PARAM(ADDPARAM(1));7 // int INT_1; //error!! 编译错误 重复定义8 }
因为ADDPARAM(1)是作为PARAM的宏参数,所以先将ADDPARAM(1)展开为INT_1,然后再将INT_1放进PARAM。
也有例外,如果PARAM宏内对宏参数使用了# 或者 ## ,那么宏参数不再被展开。例如:
#define PARAM( x ) #x
#define ADDPARAM( x ) INT_##x PARAM( ADDPARAM( 1 ) ); 将被展开为"ADDPARAM( 1 )"。
Good Good Study, Day Day Up.
顺序 选择 循环 总结