关于C语言宏展开的一个问题
2014-06-02 16:16
435 查看
因为以前写的代码更多的是Java的代码,很少接触C或者C++语言,最近在阅读一个项目的C语言源代码的时候,
感觉到自己相当缺乏C语言的基础知识,于是给自己下了要好好学习一下C语言的指令,再于是,现在在学习《一站式学习C编程》这一本书。
在看到P310页关于宏展开的时候,有一个问题困扰了我一下,现在把他记录下来,以便自己以后的复习。
这是一个关于assert.h的自定义实现。
省略条件判断条件成立的说明。
假设main.c文件的第33行调用assert(is_sorted()),那么__FILE__是字符串"main.c",_LINE_是整数33,#test是字符串“is_sorted()”。
注意_STR(__LINE__)的展开过程:首先展开成_VAL(33),然后进一步展开成字符串“33”。这样,最后_Assert调用的形式是_Assert("main.c" ":" "33" " " "is_sorted()"),
传给_Assert函数的字符串是“main.c:33 is_sorted()”.
问题:请结合前面讲过的宏展开步骤思考一下,为什么不直接定义#define _STR(x) #x呢?
原因:C语言的宏展开有一条规则:除了带#和##运算符的参数之外,其他参数在替换之前要对实参本身做充分的展开。
因此如果直接定义为#define _STR(x) #x的话,在展开的时候__LINE__直接被当成“__LINE__”了,而无法得到当前的行号“33”。
而如上定义的话,根据前面所说的C语言宏展开的规则,会对编译器定义的特殊的宏__LINE__作充分的展开得到其表示的含义——行号“33”后,
再传给_VAL(x)进一步展开,从而才能得到正确的结果。
感觉到自己相当缺乏C语言的基础知识,于是给自己下了要好好学习一下C语言的指令,再于是,现在在学习《一站式学习C编程》这一本书。
在看到P310页关于宏展开的时候,有一个问题困扰了我一下,现在把他记录下来,以便自己以后的复习。
这是一个关于assert.h的自定义实现。
/*assert.h */ #undef assert #ifdef NDEBUG #define assert(test) ((void)0) #else void _Assert (char *); #define _STR(x) _VAL(x) #define _VAL(x) #x #define assert(test) ((test) ? (void)0 :_Assert(__FILE__ ":" _STR(__LINE__) " " #test)) #endif
省略条件判断条件成立的说明。
假设main.c文件的第33行调用assert(is_sorted()),那么__FILE__是字符串"main.c",_LINE_是整数33,#test是字符串“is_sorted()”。
注意_STR(__LINE__)的展开过程:首先展开成_VAL(33),然后进一步展开成字符串“33”。这样,最后_Assert调用的形式是_Assert("main.c" ":" "33" " " "is_sorted()"),
传给_Assert函数的字符串是“main.c:33 is_sorted()”.
问题:请结合前面讲过的宏展开步骤思考一下,为什么不直接定义#define _STR(x) #x呢?
原因:C语言的宏展开有一条规则:除了带#和##运算符的参数之外,其他参数在替换之前要对实参本身做充分的展开。
因此如果直接定义为#define _STR(x) #x的话,在展开的时候__LINE__直接被当成“__LINE__”了,而无法得到当前的行号“33”。
而如上定义的话,根据前面所说的C语言宏展开的规则,会对编译器定义的特殊的宏__LINE__作充分的展开得到其表示的含义——行号“33”后,
再传给_VAL(x)进一步展开,从而才能得到正确的结果。
相关文章推荐
- 关于自学C语言的一个问题
- 一个关于C语言编程的问题
- 关于C语言For循环的一个问题~!
- c语言的一个关于%用法问题
- 关于在Xcode中C语言的一个小问题:0x1
- c语言的一个问题 -关于怎么能改变实参
- C语言中的一个关于基本类型的输出问题
- 【C语言】关于宏定义中#和##符号的使用和宏定义展开问题
- C语言中的一个关于基本类型的输出问题
- 【C语言】一个关于if的小问题
- 关于《c语言的一个小问题》的补充
- 关于C语言的一个问题
- 一个关于C语言输入的问题
- 【C语言】关于宏定义中#和##符号的使用和宏定义展开问题
- 一个关于C语言二维数组问题
- 一个关于去除数组重复元素的问题(C语言实现)
- 关于C语言中printf函数的一个问题
- C语言中关于指针,二维数组等的问题,一个有趣的发现
- 【C语言】关于宏定义中#和##符号的使用和宏定义展开问题
- c语言由一个小问题引发的关于gets和scanf的探究