当我们在printf中使用%d而不传递要打印的值时,实际发生了什么?代码给出了一个意想不到的输出



下面的程序给出了一个意外的输出:

#include<stdio.h>
int main()
{
    int a=10,b=20;
    printf("a=%d",a);
    printf(" b=%d");
    printf(" %d");
    return 0;
}

为什么上面的代码输出:A =10 b=10

即使我在a之前声明b,或者使'a'成为寄存器变量,输出也是相同的。

根据这个post - printf在打印%d而不提供变量名时的行为,从当前堆栈中打印一个随机值。但是如果是这样的话,那么改变声明样式将会导致不同的结果。

那么,这里到底发生了什么?

函数调用的设计使参数始终位于预定义的位置。一些旧的体系结构将参数放在堆栈上,大多数新体系结构将参数放在寄存器中。

这里发生的事情是,您覆盖了所有函数调用printf的第一个参数,但第二个参数恰好保持不变。不过这只是运气,任何东西都可能覆盖堆栈或寄存器中第二个参数所在的位置。

这是c语言中未定义行为的核心。任何事情都有可能发生,但通常你可以推断出实际发生了什么。这就是为什么未定义行为如此危险的原因。通常情况下,您最终的行为似乎是可以预测的,然后一个小的操作系统更新或编译器更新将完全改变行为。

把指向"a=%d"的指针放到堆栈上,把a放到堆栈上,调用printf(),减少堆栈指针。然后把指针指向堆栈上的" b=%d",调用printf(),瞧,a还在堆栈上

最新更新