简述C语言变长参数及stdarg里的相应宏实现,以
printf()
函数为例,其参数个数和类型都是不定的,是如何保证执行过程中正常取参的?
int printf(const char * format, ...)
一、实现依赖
首先变长参数的实现依赖于cdecl调用惯例,因为其规定了出栈方为函数调用方,从而解决被调用函数无法确定参数个数,其次cdecl规定参数入栈顺序为从右到左。所以第一个不定参数位于栈顶。
二、stdarg相应va_宏
// va_宏&相应简单实现
#define va_list char *
#define va_start (ap, arg) (ap = (va_list)&arg+sizeof(arg))
#define va_arg (ap, t) (*(t*)( ap+=sizeof(t) - sizeof(t)))
#define va_end (ap = (va_list)0)
- va_list:参数指针,指向各个不定参数
- va_start:初始化va_list指向第一个不定参数
- va_arg:获取各个不定参数值,并根据参数类型大小将指针指向下一个不定参数
- va_end:将va_list 指针清零