【发布时间】:2017-07-06 20:49:26
【问题描述】:
最近,我尝试了解 printf 在 C 中的详细实现, 我已经了解 va_start、va_arg 和 va_end 的用法, 但我总是无法理解的一个问题是 printf 如何获取参数列表中每个参数的大小,尽管它知道输出格式(%d、%c 等)。举一个例子更直观地展示我的问题:
int a = 27;
char b = 19;
printf("%d, %c", a, b);
我知道的 printf 的详细实现是: 第一步:通过宏 va_start(args, format) 获取指向变量参数开始的指针,format 是指向下面字符串 "%d, %c" 的 char 指针,args 是指向变量参数开始的指针位于堆栈中; 第二步:通过宏va_arg(args, int)获取每个参数的值,然后根据格式字符串输出参数; 第三步:使用va_end(args),清除args指针;
我无法理解的关键点是,当函数要输出a的值时,为什么它可以知道使用“int”作为宏va_arg的第二个参数?宏va_arg的具体实现是根据args指向栈的指针来获取数据,获取数据的长度取决于第二个参数,这里是int,为什么要给va_arg注入“int”而不是“char”或者“long int”,什么条件让它知道注入“int”? 条件是格式字符串? 在上面的例子中,它不能得到a的大小,只依赖于“%d”。
非常感谢您提前解释。
【问题讨论】:
-
你知道 C 的默认参数提升的概念吗?我认为,这是拼图中缺失的部分。关键是很难将
char传递给代码中显示的函数。