# —— 字符串
##——连接两个参数
#include <iostream>
using namespace std;
#define TEST(pid) (cout<<para##pid<<endl);
#define TEST2(p) (cout<<#p<<endl);
int main()
{
int para3 = 3;
int para2 = 2;
TEST(2); //<==>cout<<para2<<endl;
TEST(3); //<==>cout<<para3<<endl;
TEST2(test) //<==>cout<<"test"<<endl;
TEST2("test2"); //<==>cout<<""test2""<<endl;
system("pause");
return 0;
}
输出宏的打印内容
宏在C/C++程序中使用的非常之多,是代码自动化生成的利器,但在跟踪调试时宏却又成了负担,宏展开的代码很多时候都出人意料。把展开后的宏输出,是分析宏的好方法。
下面先介绍宏的“#”操作符
define MACRO_(x) #x
这个MACRO_宏就是把参数x转化为字符串,看下面的例子
1 #define MACRO_(x) #x
2 int main(int argc ,char* argv[] )
3 {
4 printf("%s",MACRO_(printf));
5 return 0;
6 }
输出:
printf
如果参数x是个宏呢,那么输出的会是什么呢,是宏的名字还是展开后的宏代码
1 #define MACRO_(x) #x
2 #define HELLO "Hello World"
3 int main(int argc ,char* argv[] )
4 {
5 printf("%s",MACRO_(HELLO));
6 return 0;
7 }
上面这段代码是输出:HELLO,还是Hello World呢?
如果是Hello World那么我们的目的也就达到了,输出了展开后的宏代码
但事与愿违,上面代码输出的是HELLO,因为#操作符会把后面的参数强制转为字符串,遇到宏是不会展开的。
这个方法失败,既然#可以把它后面的参数变为字符串,那么我们必须保证在宏遇到#操作符之前就是展开的。这样我们还需要定义一个辅助的宏,用来用来让参数宏展开。
1 #define MACRO_(x) #x
2 #define HELLO "Hello World"
3 #define SHOWMACOR(mac) MACRO_(mac)
4 int main(int argc ,char* argv[] )
5 {
6 printf("%s\n",SHOWMACOR(HELLO));
7 return 0;
8 }
这样输出的就是展开后的:"Hello World"了
我们来分析SHOWMACOR展开的过程
第一步变为:MACRO_(HELLO)
上面的表达式中没有出现#,那么先是括号中的HELLO展开
第二步变为:MACRO_("Hello World")
最后MACRO_展开变为:#"Hello World"
所以输出为:"Hello World"
宏的调试
如果我们需要调试宏定义的话,就需要更高级别的调试信息,-g3(-g也和-O类似,是有级别的,默认-g就是-g2)
gcc –g3 test.c
gdb a.out
这样我们就能调试宏定义了。
调试宏定义我们主要使用几个gdb命令如下:
1) macro define -- 定义一个新的的宏定义 如:macro define a 3
2) macro expand macroname 展开宏定义 如: macro expand min(a, b)
3) macro list macroname 列出所有用macro define -- 这条命令定义宏定义 如:macro list a
4) macro undef macroname 撤销macroname宏定义
5) info macro macroname 显示宏定义,包括在哪里定义,怎么定义。 如info macro min
##——连接两个参数
#include <iostream>
using namespace std;
#define TEST(pid) (cout<<para##pid<<endl);
#define TEST2(p) (cout<<#p<<endl);
int main()
{
int para3 = 3;
int para2 = 2;
TEST(2); //<==>cout<<para2<<endl;
TEST(3); //<==>cout<<para3<<endl;
TEST2(test) //<==>cout<<"test"<<endl;
TEST2("test2"); //<==>cout<<""test2""<<endl;
system("pause");
return 0;
}
输出宏的打印内容
宏在C/C++程序中使用的非常之多,是代码自动化生成的利器,但在跟踪调试时宏却又成了负担,宏展开的代码很多时候都出人意料。把展开后的宏输出,是分析宏的好方法。
下面先介绍宏的“#”操作符
define MACRO_(x) #x
这个MACRO_宏就是把参数x转化为字符串,看下面的例子
1 #define MACRO_(x) #x
2 int main(int argc ,char* argv[] )
3 {
4 printf("%s",MACRO_(printf));
5 return 0;
6 }
输出:
printf
如果参数x是个宏呢,那么输出的会是什么呢,是宏的名字还是展开后的宏代码
1 #define MACRO_(x) #x
2 #define HELLO "Hello World"
3 int main(int argc ,char* argv[] )
4 {
5 printf("%s",MACRO_(HELLO));
6 return 0;
7 }
上面这段代码是输出:HELLO,还是Hello World呢?
如果是Hello World那么我们的目的也就达到了,输出了展开后的宏代码
但事与愿违,上面代码输出的是HELLO,因为#操作符会把后面的参数强制转为字符串,遇到宏是不会展开的。
这个方法失败,既然#可以把它后面的参数变为字符串,那么我们必须保证在宏遇到#操作符之前就是展开的。这样我们还需要定义一个辅助的宏,用来用来让参数宏展开。
1 #define MACRO_(x) #x
2 #define HELLO "Hello World"
3 #define SHOWMACOR(mac) MACRO_(mac)
4 int main(int argc ,char* argv[] )
5 {
6 printf("%s\n",SHOWMACOR(HELLO));
7 return 0;
8 }
这样输出的就是展开后的:"Hello World"了
我们来分析SHOWMACOR展开的过程
第一步变为:MACRO_(HELLO)
上面的表达式中没有出现#,那么先是括号中的HELLO展开
第二步变为:MACRO_("Hello World")
最后MACRO_展开变为:#"Hello World"
所以输出为:"Hello World"
宏的调试
如果我们需要调试宏定义的话,就需要更高级别的调试信息,-g3(-g也和-O类似,是有级别的,默认-g就是-g2)
gcc –g3 test.c
gdb a.out
这样我们就能调试宏定义了。
调试宏定义我们主要使用几个gdb命令如下:
1) macro define -- 定义一个新的的宏定义 如:macro define a 3
2) macro expand macroname 展开宏定义 如: macro expand min(a, b)
3) macro list macroname 列出所有用macro define -- 这条命令定义宏定义 如:macro list a
4) macro undef macroname 撤销macroname宏定义
5) info macro macroname 显示宏定义,包括在哪里定义,怎么定义。 如info macro min