你有一些undefined behavior(所以任意坏事情可能happen,你不应该期待任何好的)。对于%f,printf 函数需要double(请注意,当作为参数传递时,float 会提升为double)但0 是int 类型的文字。此外,不同的编译器(甚至同一编译器的不同版本)或不同的优化标志可能会产生不同的不良影响。
请阅读 Lattner 在What Every C programmer should know about undefined behavior 上的博客。
(对未定义行为的良好态度是努力始终避免它;不要浪费时间试图理解具体发生的事情;但将 UB 视为非常肮脏的或者你总是避免的“sick”)
要解释观察到的行为,您需要深入了解特定实现的细节,特别是 ABI 和 calling conventions(对于可变参数函数 à la printf)。另外,查看生成的汇编代码(用GCC,用gcc -fverbose-asm -S -O1编译);有可能在寄存器(或某些call stack 插槽)中传递了一个双参数,而不是int 参数(因此printf 函数正在让垃圾发生在该位置或寄存器中);另请注意,sizeof(int) 通常可能是 4,但 sizeof(double) 可能是 8(因此数据量甚至不正确)。
为避免此类错误,请养成使用良好编译器编译的习惯(例如free software 领域中的GCC 或Clang/LLVM)并启用所有警告和调试信息(例如使用gcc -Wall -Wextra -g 和@ 进行编译987654332@)。编译器会警告你的。
顺便说一句,void main() 是非法的。它至少应该是int main(void),最好是int main(int argc, char**argv),并且您应该注意这些参数。
在您的示例中,gcc -Wall -Wextra(使用 GCC 7)告诉(对于您的源文件 april.c):
april.c:4:10: warning: return type of ‘main’ is not ‘int’ [-Wmain]
void main() {
^~~~
april.c: In function ‘main’:
april.c:5:14: warning: format ‘%d’ expects argument of type ‘int’,
but argument 2 has type ‘double’ [-Wformat=]
printf("%d\n", 1.5);
~^
%f
april.c:6:14: warning: format ‘%f’ expects argument of type ‘double’,
but argument 2 has type ‘int’ [-Wformat=]
printf("%f", 0);
~^
%d
注意:Dev-C++ 和 CodeBlocks 是不是编译器,而是IDEs。它们都运行一些外部compiler(可能GCC 在您的系统上作为MinGW)。