C 如果我打印一个没有匹配参数的整数,具体是什么决定了输出?

C 如果我打印一个没有匹配参数的整数,具体是什么决定了输出?,c,printf,C,Printf,例如,当我的代码如下所示时,a=0得到-1301113336,a=1到99得到-1266657529 #include <stdio.h> int main() { int a; for (a = 0; a < 100; a++) { printf("\n%i"); } } #包括 int main() { INTA; 对于(a=0;a

例如,当我的代码如下所示时,a=0得到-1301113336,a=1到99得到-1266657529

#include <stdio.h>

int main()
{
    int a;
    for (a = 0; a < 100; a++)
    {
        printf("\n%i");
    }
}
#包括
int main()
{
INTA;
对于(a=0;a<100;a++)
{
printf(“\n%i”);
}
}
当行为因编译器而异时,这是某种未定义的情况吗?如果我使用gcc,这些数字从何而来,为什么每次迭代都不改变?

阅读您的实现和应用程序

实际上,打印的内容可能是与实现相关的ABI规范中提到的某些处理器寄存器的“随机”内容

Fpr Linux/x86-64请参阅和


如果您使用as C编译器,您可以使用
gcc-S-fverbose asm-Wall-O2 foo.C
编译
foo.C
代码,如果参数的数量与格式字符串的预期不匹配,则可以查看生成的汇编程序代码
foo.S

,或者,如果给定的参数不是相应格式说明符的正确类型,则调用

在x64 Linux机器上使用gcc而不进行优化,您可能会看到:


函数的整数参数通常被推送到堆栈上。因此,
%i
格式说明符将在堆栈上查找
sizeof(int)
字节。如果传入参数失败,它将读取堆栈上该参数所在的所有字节。

将换行符放在字符串的末尾。把它放在开头是不正常的,会引起问题。但是你真正的问题是你忘了在参数列表中包含
a
。您的编译器应该警告过您。@TomKarzes谢谢,但我的问题不是它为什么不打印“a”,而是它当时打印的内容。要了解更多关于幕后发生的事情,大多数函数(在Linux x86-64上)的寄存器都会传递整数参数。通过编译进行检查。