%*。* d如何在printf()中工作?

#include  int main() { printf("%*.*d\n", -6 , 7,20000); printf("%*.*d\n", 5, -6, 2000); return 0; } 

输出:

 0020000 2000 

我不明白printf如何解释格式说明符*。 *

在第一次调用printf() ,后面的7是否会覆盖前者-6 ? 那么输出宽度的大小变为7?

*之前的论点.字段宽度*之后的参数.精度

字段宽度是转换后输出的最小字节数; 如果将产生更少的字节,则输出将被填充(默认情况下,左侧带有空格,但左侧填充和右侧空间填充也是选项,由标志控制)。 *表示宽度的负参数被解释为带有-标志的相应正值,它将填充向右移动(即左对齐字段)。

另一方面, 精度具有根据所执行的转换而变化的含义。 负精度被视为根本没有指定精度。 对于整数,它是要生成的最小位数 (不是总输出); 如果生成的数字较少,则在左侧添加零。 显式精度为0会导致值为0时不生成数字(而不是生成单个0 )。 对于字符串,精度限制输出字节数,必要时截断字符串(并允许更长,非空终止的输入数组)。 对于浮点说明符,精度控制打印的位数,在小数点后(对于%f )或总有效位置(对于其他格式)。

在你的例子中:

 printf("%*.*d\n", -6 , 7,20000); 

这里的字段是左对齐的(右边是填充),最小宽度为6,但是字段最终会变宽,所以忽略宽度。 7的精度强制整数输出至少为7位,因此最终将0020000作为已转换的字段内容,已超出宽度。

在另一个:

 printf("%*.*d\n", 5, -6, 2000); 

字段宽度为5,默认右对齐; 填充左侧有空格。 否定精度被忽略,就像没有指定一样,因此转换后的字段内容为2000 ,只有4个字节,最多填充5个字节以通过单个前导空格填充宽度。

 printf("%*.*d\n", -6 , 7,20000); 

和…一样

 printf("%-6.7d\n, 20000); 

这只是为动态格式提供了一种方法。

这是glibc中printf的源代码

 /* VARARGS1 */ int __printf (const char *format, ...) { va_list arg; int done; va_start (arg, format); done = vfprintf (stdout, format, arg); va_end (arg); return done; 

}

正如您所见,printf从va_list获取参数

这是另一个例子,向您展示printf的工作原理:

 /* va_start example */ #include  /* printf */ #include  /* va_list, va_start, va_arg, va_end */ void PrintFloats (int n, ...) { int i; double val; printf ("Printing floats:"); va_list vl; va_start(vl,n); for (i=0;i