c语言自定义常量,怎么修改#define 定义的常量中的参数

如何修改#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

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值