免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 9266 | 回复: 12
打印 上一主题 下一主题

[C] 宏里面可不可以定义变量?? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-01-16 10:05 |只看该作者 |倒序浏览
10可用积分
1如果可以的话,那么该变量的空间分配实在什么时候进行的?其生存期和作用域有如何?是否就局限在调用该宏的函数空间内?
2如果从宏定义就是个简单的替换来理解对不对?

最佳答案

查看完整内容

预处理不对变量进行处理.空间分配是在编译阶段,在函数的栈空间中分配的.你完全可以只进行预处理后就把代码输出,得到的还是C格式的代码.还是文本的.gcc -E 试试.补充:如果没记错的话,函数中定义的任何变量的生存期都是到函数执行结束,只是各个变量的作用域不同而已.[ 本帖最后由 cugb_cat 于 2008-1-16 10:26 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2008-01-16 10:05 |只看该作者

回复 #3 ruoyisiyu 的帖子

预处理不对变量进行处理.空间分配是在编译阶段,在函数的栈空间中分配的.
你完全可以只进行预处理后就把代码输出,得到的还是C格式的代码.还是文本的.
gcc -E 试试.

补充:
如果没记错的话,函数中定义的任何变量的生存期都是到函数执行结束,只是各个变量的作用域不同而已.

[ 本帖最后由 cugb_cat 于 2008-1-16 10:26 编辑 ]

论坛徽章:
0
3 [报告]
发表于 2008-01-16 10:09 |只看该作者
确定变量的作用域生存期是在编译阶段确定的,这时已经过了预处理阶段了.

论坛徽章:
0
4 [报告]
发表于 2008-01-16 10:19 |只看该作者
原帖由 cugb_cat 于 2008-1-16 10:09 发表
确定变量的作用域生存期是在编译阶段确定的,这时已经过了预处理阶段了.

按照阁下的说法,说说我的理解:
1、宏替换是在预处理阶段进行的
2、变量的作用域生存期是在编译阶段进行的(这两条地球人都知道的)
那么,在宏中定义一个临时变量可不可以呢,如果可以的话,那么在预处理阶段对于这个变量又做过什么处理呢?其空间又是何时分配的呢

论坛徽章:
0
5 [报告]
发表于 2008-01-16 10:29 |只看该作者
可以把宏处理当作另外一种与c完全不相关的语言,它的作用是把源代码中有关宏方面的东西进行处理,然后把得到的结果给编译器。因此预处理和编译实质上一点关系都没有。
宏中定义的临时变量只是预处理时使用,这个变量并不是我们通常说的语言里面的变量,两个完全不是一回事,预处理完毕后这个临时变量压根就不存在了。

论坛徽章:
0
6 [报告]
发表于 2008-01-16 10:30 |只看该作者
原帖由 cugb_cat 于 2008-1-16 10:22 发表
预处理不对变量进行处理.空间分配是在编译阶段,在函数的栈空间中分配的.
你完全可以只进行预处理后就把代码输出,得到的还是C格式的代码.还是文本的.
gcc -E 试试.

补充:
如果没记错的话,函数中定义的任何 ...

谢谢,基本明白了

论坛徽章:
0
7 [报告]
发表于 2008-01-16 10:32 |只看该作者
原帖由 Sorehead 于 2008-1-16 10:29 发表
可以把宏处理当作另外一种与c完全不相关的语言,它的作用是把源代码中有关宏方面的东西进行处理,然后把得到的结果给编译器。因此预处理和编译实质上一点关系都没有。
宏中定义的临时变量只是预处理时使用,这 ...

那我如下定义宏:
#define macro(a,b)\
do{                         \
         char *p          \
                  ........     \
}while(0)
可不可以呢

论坛徽章:
0
8 [报告]
发表于 2008-01-16 10:34 |只看该作者
xuchm@xuchm:/test$ cc -E test.c
# 1 "test.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "test.c"

int main(int argc, char *argv[0])
{
int a = 0;
if (argc > 1)
  a = atoi(argv[1]);
a = ({typeof(a) c=a;c+=1;});
printf("%d\n", a);
}
xuchm@xuchm:/test$ cat test.c
#define M(a) ({typeof(a) c=a;c+=1;})
int main(int argc, char *argv[0])
{
        int a = 0;
        if (argc > 1)
                a = atoi(argv[1]);
        a = M(a);
        printf("%d\n", a);
}

论坛徽章:
0
9 [报告]
发表于 2008-01-16 10:36 |只看该作者
预处理只是对文本的处理而已.

论坛徽章:
0
10 [报告]
发表于 2008-01-16 10:37 |只看该作者
原帖由 Sorehead 于 2008-1-16 10:29 发表
可以把宏处理当作另外一种与c完全不相关的语言,它的作用是把源代码中有关宏方面的东西进行处理,然后把得到的结果给编译器。因此预处理和编译实质上一点关系都没有。
宏中定义的临时变量只是预处理时使用,这 ...

一个例子:
  1. #define AAA(a) ({ \
  2.         int b;\
  3.         b = a;\
  4.         b;\
  5. })
  6. int main(int argc, char *argv[])
  7. {
  8.         int a = 0, c = -1;
  9.         c = AAA(a);
  10.         return 0;
  11. }
复制代码

gcc -E test.c

  1. # 1 "test73.c"
  2. # 1 "<built-in>"
  3. # 1 "<command-line>"
  4. # 1 "test73.c"





  5. int main(int argc, char *argv[])
  6. {
  7. int a = 0, c = -1;
  8. c = ({ int b; b = a; b;});
  9. return 0;
  10. }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP