如何修改#define 定义的常量中的参数
形容起来比较麻烦
由于特殊情况 不能直接将数据的参数传入一个函数中 只能将保存该数据的变量名字传入函数中
例如
#include
#include
#define NAME a
int main(){
int a,b,c;
a = 1;
b = 2;
c = 3;
//这之间有什么办法能将NAME 的a改成其他的参数呢?
printf("%d\n",NAME);
}
这个想法是LINUX内核中实现的 具体代码已经忘记了 具体的作用就是给你一个变量的名字 我能通过这个字符串知道这个变量代表的是哪个参数 变量名可以任意选择 也就是事先不知道我有那些变量也不知道他们所对应的字符串是什么
可能实现的方式不一定就要使用#define
可是define是我唯一能想到的方法
------解决思路----------------------
说得糊里八涂的。你的意思就是传入字符串呗:
void f (const char *);
/* …… */
f ("name");
f ("gender");
f ("age");
语文太差了,现代的大学生们!
------解决思路----------------------
#include
#define name(i) (#i)
void printwithoutret(char *v_name,int v_value)
{
printf("%s=%d\n",v_name,v_value);
}
char* printwithret(int * v_back)
{
int d = 4;
*v_back = d;
return name(d);//你可以把这个地址strcpy到一个堆上
//意义不大
}
int main(void)
{
//我以数组为例
int a=1,b=2,c=3;
char *p;
int e;
int *x= &e;
//第一种 直接打印 变量名=变量值
printf("%s=%d\n",name(a),a);
//第二种 使用字符指针保存变量名 打印
p = name(b);
printf("%s=%d\n",p,b);
//第三种 将这个字符指针传递到子函数里面打印
p = name(c);
printwithoutret(p,c);
//第四种 接收子程序传来的变量名 然后打印
p = printwithret(x);
printf("%s=%d\n",printwithret(x),*x);
return 0;
}
------解决思路----------------------
上面的“以数组为例 ”注释 实际上不是这个程序的
------解决思路----------------------
#define varname(x) #x
#define print_int(a) printf("%s =%d",varname(a),(a))
print_int(a);
print_int(b);
print_int(c);
------解决思路----------------------
#与##在宏定义中的--宏展开
#include
#define f(a,b) a##b
#define g(a) #a
#define h(a) g(a)
int main()
{
printf("%s\n", h(f(1,2))); // 12
printf("%s\n", g(f(1,2))); // f(1,2)
return 0;
}
宏展开时:
如果宏定义以#开头,不展开参数,直接替换。
故g(f(1,2))--->#f(1,2)--->"f(1,2)";
如果宏定义不以#开头,展开参数,直接替换,由外层向里层,如果碰到的是#开头的宏,不继续往里层展开,往外层展开。
由外层向里层,如果碰到的是以非#开头的宏,继续往里层走,直至最里层,开始一层层往外层展开。
故h(f(1,2))--->h(12)--->g(12)---->#12----->"12"。
PS:
##在宏中定义,是字符连接符
如a##b##c 等同于 "abc"
#在宏开头出现,是表示宏展开的方式不同
#a 等同于"a"
#abc 等同于 "abc"
复杂的:
#include
#define f(a,b) a##b
#define g(a) #a
#define h(a) g(a)
int main()
{
char a = 'a';
cout<
cout<
printf("%s\n", h(f(1,2))); // 12
printf("%s\n", g(f(1,2))); // f(1,2)
printf("%s\n", g(h(f(1,2)))); // h(f(1,2))
printf("%s\n", h(g(f(1,2)))); // "f(1,2)"
printf("%s\n", h(h(f(1,2)))); // "12"
system("pause");
return 0;
}
预处理后的:(在编译选项中添加/EP /P后编译生成的.i文件。gcc加-E)
int main()
{
char a = 'a';
cout<
cout<
printf("%s\n", "12");
printf("%s\n", "f(1,2)");
printf("%s\n", "h(f(1,2))");
printf("%s\n", "\"f(1,2)\"");
printf("%s\n", "\"12\"");
system("pause");
return 0;
}
---------------------------------------------------
宏解析
1. ##操作符
##操作符它的作用是在替代表中将其前后的参数连接成为一个预处理符号,它不能出现于宏替代表的开端和末尾。
例:
#define concat(s,t) s##t
#define AAA ABC
concat(A, AA)
将被替换成
ABC
2. 重新扫描和替换
在替换列表中的所有参数替换过之后,预处理器将对结果token序列重新扫描以便对其中的宏再次替换。
当正在替换的宏在其替换列表中发现自身时,就不再对其进行替换。在任何正在嵌套替换的宏的替换过程中遇到正被替换的宏就对其不再进行替换(防止递归)。
例:
#define ROOT AAA CCC
#define AAA ROOT
ROOT
将被替换成
ROOT CCC