省略号表示参数中参数的数量和类型是可变的.省略号只能出现在参数表的尾部.
<stdarg.h>中包含一组宏定义,他们对如何遍历参数表进行了定义.
va_list类型用于声明一个变量ap,该变量将依次引用各参数.宏va_start将ap初始化为指向第一个无名参数的指针.在使用ap之前,该宏必须被调用依次.参数表必须至少包括一个有名参数,va_start将最后一个有名参数作为起点.
每次调用va_arg,改函数都将返回一个参数,并将ap指向下一个参数.va_arg使用一个类型名来决定返回的对象类型,指针移动的步长.最后必须在函数返回之前调用va_end以完成一些必要的清理工作.
我一直在纠结到底要不要深究这些标准库中定义的函数或者宏的详细信息.或者只是了解他的功能就好?
最后想想暂时还是算了吧.
别的不说但是VA_ARG需要说一下,不然看不懂.
VA_ARG宏,获取可变参数的当前参数,返回指定类型并将指针指向下一参数(t参数描述了当前参数的类型):
define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
首先看ap += _INTSIZEOF(t)
ap是个指针,加上当前的参数a的长度就代表跳过当前参数指向下一参数b了.
然后再减去当前参数a的长度就又回到了当前参数a的位置.但是这个位置只作为返回值传递给调用者,而并没有赋值,所以说ap当前还是指向下一参数b.
等再次调用这个宏的时候ap自然指的是参数b,所以再一次ap指向下一参数c,然后返回当前参数b的地址
VA_START宏就是让ap指向第一个无名参数用的.
然后for循环检查的是minprintf的第一个参数(也就是那个双引号中的字符串.)
判断当前字符是不是'%'如果不是输出这个字符然后不进行后续判断.
如果是的话就继续判断紧跟的下一字符.
是其中的哪个转换说明.然后进行相应的输出,就这样.
当前参数是通过va_arg赋值给那几个变量的.
然后用printf函数输出这个变量,就相当于输出了那几个传入的参数.
网友评论