C语言细节:va_list,...,##, #等

来源:互联网 发布:淘宝哪家零食店好 编辑:程序博客网 时间:2024/06/05 01:28

c语言中细节问题

  • c语言中细节问题
    • va_list
    • __VA_ARGS__
    • __FILE__ 和 __LINE__


va_list

c语言中va_list用于参数可变的函数中,提供了读取每个参数的方式.

#define _VALISTtypedef char *va_list;/* Storage alignment properties */#define  _AUPBND                (sizeof (acpi_native_int) - 1)#define  _ADNBND                (sizeof (acpi_native_int) - 1)/* Variable argument list macro definitions */#define _bnd(X, bnd)            (((sizeof (X)) + (bnd)) & (~(bnd)))#define va_arg(ap, T)           (*(T *)(((ap) += (_bnd (T, _AUPBND))) - (_bnd (T,_ADNBND))))#define va_end(ap)              (ap = (va_list) NULL)#define va_start(ap, A)         (void) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND))))

va_list实际上是一个字符型的指针,va_start会将ap指向A的下一个位置,而va_arg会返回一个T类型的变量,va_end会将ap赋值为NULL.


c语言中用…来取消编译器对函数参数个数和类型的检查,这时就利用到了va_list

int sprintf(char *buf, const char *fmt, ...){    va_list args;    int i;    va_start(args, fmt);    i = vsprintf(buf, fmt, args);    va_end(args);    return i;}

##,#等

在c语言的预编译阶段,编译器会对##,#进行替换,替换的规则是
(1) #define P(A) printf("%s: %d\n",#A,A)
(2) #define XNAME(n) x##n如果调用XNAME(0)就是x0
具体来说,#将一个变量名变为字符串,##将一个字符串和变量值拼接起来.

##__VA_ARGS__

在gcc中存在扩展#define debug(fmt,...) printk(fmt,##__VA_ARGS__ ) 其中__VA_ARGS__代表…的参数,加上##是为了防止__VA_ARGS__为空导致编译出错.
#define debug(...) printf(__VA_ARGS__)

__FILE__ 和 __LINE__

__FILE__表示所在文件
__LINE__表示所在文件的行数
__ FUNCTION__表示当前函数
一般用于打印出错消息.
#define dprint(fmt,...) printk("%s,%d,%s:"fmt,\__FILE__\,__LINE__,\__FUNCTION__,##\__VA_ARGS__)
两个连续的”会被消除

0 0
原创粉丝点击