我们使用#把宏参数变为一个字符串,用##把两个宏参数贴合在一起.

 当宏参数是另一个宏的时候,需要注意的是凡宏定义里有用’#’或’##’的地方宏参数是不会再展开。

下面举两个实例:

1."#"

#define print(F,V)\
printf("the " #V " is :"F ,V) //加上#不会替换参数,只替换其所对应的字符;
int main()
{
char name[] = "li lei";
print("%s", name);
return 0;
}

输出:the name is :lilei

用来取函数名

#define NAME_STR(n) #n
#define STRCPY(a,b) strcpy(a##_p,#b) //把第一个参数后边加上字符_p,把第二个参数变成字符串
void testfun0()
{

}

int main()
{
printf("\n the fun name:%s\n", NAME_STR(testfun0));
return 0;
}


the fun name:testfun0

// 通过函数名调用函数

#include "stdafx.h"
#include <string>
#include <map>
using namespace std;


#define print(F,V)\
printf("the " #V " is :"F ,V) //加上#不会替换参数,只替换其所对应的字符;

bool testfun0(string name, int mode)
{
printf("testfun0\n ");
return true;
}

bool testfun1(string name, int mode)
{
printf("testfun1\n ");
return true;
}

bool testfun2(string name, int mode)
{
printf("testfun2\n ");
return true;
}

using TestFunc = bool(*)(string name, int mode);
using TestPair = std::pair<string, TestFunc>;

#define NAME_STR(n) #n
#define TEST_FUNC(x) TestPair( NAME_STR(x), x)

// 将函数保存,方便通过 key 方式调用函数
map<string, TestFunc> AllFunc = {
TEST_FUNC(testfun0), TEST_FUNC(testfun1), TEST_FUNC(testfun2)
};
int main()
{
char name[] = "lilei";
print("%s", name);
// adv
printf("\n the fun name:%s\n", NAME_STR(testfun0));

string funName = "testfun2";
auto x = AllFunc.find(funName);
if (x != AllFunc.end()) {
auto fun = x->second;
fun("test",0);
}
return 0;
}

2."##"

#include "stdafx.h"
#include <string>
#include <map>
using namespace std;

#define CAT(str1, str2) str1##str2

#define STRING(x) #x

#define STRCPY(a,b) strcpy(a##_p,#b) //把第一个参数后边加上字符_p,把第二个参数变成字符串
int main()
{
int aaff = 234;
printf("aaa%d\n", CAT(aa, ff)); //替换宏CAT,将aa和bb连接起来 就成一个参数;

char var1_p[20];
char var2_p[30];
strcpy(var1_p, "aaaa");
strcpy(var2_p, "bbbb");
STRCPY(var1, var2); //等于strcpy(var1_p,"var2");
STRCPY(var2, var1); //等于strcpy(var2_p,"var1");
printf("%s\n", var1_p);
printf("%s\n", var2_p);
return 0;
}

输出:

aaa234
var2
var1

一个比较实际的应用:

#define STRUCT(type) typedef struct _tag_##type type;\
struct _tag_##type

STRUCT(Student)
{
char * name;
int id;
};


int main()

{

Student s1;
Student s2;
s1.id = 0;
s1.name = "S1";
s2.id = 1;
s2.name = "S2";
printf("s1.name = %s\n",s1.name);
printf("s1.id = %d\n",s1.id);
printf("s1.name = %s\n",s1.name);
printf("s1.id = %d\n",s1.id);
return 0;

}

//上述 STRUCT(Student)根据宏展开即:

struct _tag_Student
{
char * name;
int id;
}
typedef struct _tag_Student Student;
//也等于
typedef struct _tag_Student
{
char * name;
int id;
}Student;

其实就是正常定义了一个结构体类型;这么写是以前的写法,写的比较精练;