c - C中的printf函数如何获取可变参数列表中每个参数的大小?

标签 c logging printf

最近想了解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/

相关文章:

java - 如何设置 JUnit 测试的日志级别

c - 在 C 中打印前导 0

c - 如何在函数内打印指向字符数组的指针?

c++ - 给定两个二进制数,将一个子集从一个复制到另一个

C缓冲区溢出攻击

java - 扩展 log4j2.xml 并在它变得很长时将其拆分

c - 在 Windows 中,如何阻止 fprintf 将\r 与\n 一起打印到文件

c - 如何在c中输出char数组

c - 这个结构的大小是多少?为什么?

python - 如何抑制正在导入的模块的标准输出日志输出?