最近想了解C语言中printf的具体实现, 我已经了解 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)获取变量参数开始指针,格式为char指针,指向下面字符串"%d, %c",args为变量参数开始指针位于堆栈中; step 2:通过宏va_arg(args, int)获取各个参数的值,然后按照格式字符串输出参数; 第三步:使用va_end(args),清除args指针;
我无法理解的关键是,当函数要输出a的值时,为什么它可以知道使用“int”作为宏va_arg的第二个参数?宏va_arg的具体实现是根据args指向栈的指针获取数据,获取数据的长度取决于第二个参数,这里是int,为什么va_arg注入(inject)int而不是char或者“long int”,什么条件让它知道注入(inject)“int”? 条件是格式字符串? 在上面的例子中,它无法获得a的大小,只取决于“%d”。
非常感谢您提前的解释。
最佳答案
... to output the value of a, why it can knows using "int" as the second parameters of macros va_arg ?
因为你是这么说的。
%d
转换需要一个int
作为输入,因此printf
假定您传递了正确的类型。
如果您弄错了(即,您为 %d
转换说明符传递了一个字符),它就会崩溃,这是您的错。
我本地联机帮助页中的相关文本是:
The arguments must correspond properly (after type promotion) with the conversion specifier.
和this reference有一个详细的表格,描述了每个转换说明符所需的参数类型。如果您的参数类型与您的格式字符串不匹配,一些编译器或静态分析器会警告您,但最终您有责任正确编码。
关于c - C中的printf函数如何获取可变参数列表中每个参数的大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42296031/