#include<stdio.h>
int f();
int main()
{
f(1);
f(1,2);
f(1,2,3);
}
f(int i,int j,int k)
{
printf("%d %d %d",i,j,k);
}
Run Code Online (Sandbox Code Playgroud)
它运行正常(没有任何错误)...你可以解释它是如何执行的吗?f(1)和f(1,2)如何链接到f(int,int,int)?
pax*_*blo 14
你必须对我有一个不同的"错误"定义:-)你打电话给你的f功能前两次打印什么?我明白了
1 -1216175936 134513787
1 2 134513787
1 2 3
Run Code Online (Sandbox Code Playgroud)
我的三个函数调用.
你所看到的是从C的早期阶段开始的延续,当人们通过他们的函数调用时,他们玩得很自由,没有花哨.
所有发生的事情都是你正在调用一个函数f并且它从堆栈中打印出三个值(是的,即使你只给它一两个).当你没有提供足够的东西时会发生什么,你的程序最有可能只是使用那里的东西,通常会在阅读时导致数据问题,写作时会导致灾难性的失败.
这是完全可编译的,虽然非常不明智,C.我的意思是在一个非常真实的,"未定义的行为"中,对该词的意义(具体指C99:"如果表示被调用函数的表达式具有不具有的类型包括原型,...如果参数的数量不等于参数的数量,则行为是未定义的").
你应该提供完全形成的函数原型,例如:
void f(int,int,int);
Run Code Online (Sandbox Code Playgroud)
确保编译器解决了这个问题,并...在变量参数函数中使用省略号().
顺便说一下,通常在封面下发生的事情是调用函数以如下堆栈开头:
12345678
11111111
Run Code Online (Sandbox Code Playgroud)
并将(例如)两个值推送到堆栈上,以便它最终如下:
12345678
11111111
2
1
Run Code Online (Sandbox Code Playgroud)
当被调用函数使用堆栈上的前三个值时(因为它就是它想要的),它会发现它有1,2和11111111.
它执行它必须做的事情然后返回并且调用函数清除堆栈中的这两个值(这称为调用者制造良好策略).任何试图用callee-make-good策略尝试这一点的人都有祸了:-)虽然这在C中很不寻常,因为它使得变量参数函数printf有点难以做到.