Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 请解释prog是如何工作的 #包括 int f(); int main() { f(1); f(1,2); f(1,2,3); } f(整数i,整数j,整数k) { printf(“%d%d%d”,i,j,k); }_C - Fatal编程技术网

C 请解释prog是如何工作的 #包括 int f(); int main() { f(1); f(1,2); f(1,2,3); } f(整数i,整数j,整数k) { printf(“%d%d%d”,i,j,k); }

C 请解释prog是如何工作的 #包括 int f(); int main() { f(1); f(1,2); f(1,2,3); } f(整数i,整数j,整数k) { printf(“%d%d%d”,i,j,k); },c,C,它运行良好(没有任何错误)…u plz可以解释它是如何执行的吗? f(1)和f(1,2)如何链接到f(int,int,int)?您必须对“错误”有不同的定义:-)您调用f函数的前两次打印的是什么?我明白了 #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); } 对于

它运行良好(没有任何错误)…u plz可以解释它是如何执行的吗?
f(1)和f(1,2)如何链接到f(int,int,int)?

您必须对“错误”有不同的定义:-)您调用
f
函数的前两次打印的是什么?我明白了

#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);

}
对于我的三个函数调用

你看到的是C语言早期的遗留问题,当时人们在函数调用中自由发挥

所发生的一切就是调用一个函数
f
,它从堆栈中打印出三个值(是的,即使只给它一个或两个值)。当您没有提供足够的数据时,您的程序很可能只使用已有的数据,通常在读取时会导致数据问题,在写入时会导致灾难性的失败

这是完全可编译的,尽管非常不明智,C。我的意思是,在一个非常真实的“未定义的行为”中,这个词的意思是(特别指C99:“如果表示被调用函数的表达式的类型不包含原型,……如果参数的数量不等于参数的数量,则行为未定义”)

您应该提供完整的函数原型,例如:

1 -1216175936 134513787
1  2          134513787
1  2          3
为了确保编译器能够解决这个问题,请在变量参数函数中使用省略号(


另一方面,通常情况下,调用函数以堆栈开始,如:

void f(int,int,int);
并将(例如)两个值推送到堆栈上,使其最终类似于:

12345678
11111111
当被调用函数使用堆栈上的前三个值时(因为这是它想要的),它会发现它有
1
2
11111111

它做它必须做的事情,然后返回,调用函数从堆栈中清除这两个值(这称为调用方做好策略).wow betide任何尝试使用被调用方的人都是很好的策略:-)尽管这在C语言中很少见,因为它使得变量参数函数如
printf
有点难实现

在C中,它声明了一个函数,该函数接受可变数量的参数,即,它等价于C中的以下函数++

int f();
要检查这一点,请使用以下命令,而不是
int f();

这将导致编译器抱怨

请注意:这里还涉及C链接器的一个怪癖…C链接器在调用时不验证传递给函数的参数,只是链接到具有相同名称的第一个公共符号。因此允许在main中使用f(),因为声明了
int f()
。但是链接器绑定函数f(int,int,int)在调用站点的链接时间。希望这有意义(如果没有),请告诉我)

此声明:

int f(void);
…告诉编译器“
f
是一个函数,它接受一些固定数量的参数,并返回
int
”。然后尝试使用一个、两个和三个参数调用它-C编译器在概念上是一个过程(预处理后),因此在这一点上,编译器没有可用的信息与您争论


f()的实际实现
接受三个
int
参数,因此只提供一个和两个参数的调用调用未定义的行为-这是一个错误,意味着编译器不需要向您提供错误消息,并且在您运行程序时可能发生任何情况。

由于
int f()
表示其他答案已经说过的:它表示未指定数量的参数。这意味着您可以使用所需数量的参数(也超过3个)调用它,而无需编译器对其进行任何说明

它之所以“隐蔽”工作,是因为参数被推到堆栈上,然后从
f
函数中的堆栈“访问”。如果传递0个参数,则函数的
i,j,k
对应“到堆栈上的值,从函数PoV来看,这些值是垃圾。尽管如此,您仍然可以访问它们的值。如果您传递1个参数,则三个
i j k
中的一个访问该值,其他值则获取垃圾。依此类推

请注意,如果以其他方式传递参数,同样的推理也会起作用,但无论如何,这些都是使用中的约定。这些约定的另一个重要方面是被调用方不负责调整堆栈;由调用方决定推送多少实数参数。如果不是这样,则定义f的的on可能表示它必须“调整”堆栈以“释放”三个整数,这将导致某种崩溃

你所写的对于当前的标准来说很好(在gcc上编译时没有警告,即使使用
-std=c99-pedantic
;有一个警告,但它是关于
f
定义前面缺少的
int
),尽管许多人觉得它很恶心并称之为“过时的特性”.当然,您在示例代码中的用法没有显示出任何用处,而且它可能有助于消除bug—原型的更具约束力的用法!(但是,我还是更喜欢C而不是Ada)

添加

“特性”的更“有用”的用法不会触发“未定义行为”问题,可以是

int f();
#包括
int f();
int main()
{
f(1);
f(2,2);
f(3,2,3);
}
int f(int i,int j,int k)
{
如果(i==1)printf(“%d\n”,i);
如果(i==2)printf(“%d%d\n”,i,j);
如果(i==3)printf(“%d%d%d\n”,i,j,k);
}

使用g++编译器编译同一程序时,您会看到以下错误-

#include<stdio.h>
int f();

int main()
{

    f(1);
    f(2,2);
    f(3,2,3);
}

int f(int i,int j,int k)
{
  if ( i == 1 ) printf("%d\n", i);
  if ( i == 2 ) printf("%d %d\n", i, j);
  if ( i == 3 ) printf("%d %d %d\n", i, j, k);
}
将gcc与选项-std=c99一起使用只会给出一个警告

使用与g++相同的标准编译相同的程序
int f();
#include<stdio.h>
int f();

int main()
{

    f(1);
    f(2,2);
    f(3,2,3);
}

int f(int i,int j,int k)
{
  if ( i == 1 ) printf("%d\n", i);
  if ( i == 2 ) printf("%d %d\n", i, j);
  if ( i == 3 ) printf("%d %d %d\n", i, j, k);
}
g++ program.c
program.c: In function `int main()':
program.c:2: error: too many arguments to function `int f()'
program.c:6: error: at this point in file
program.c:2: error: too many arguments to function `int f()'
program.c:7: error: at this point in file
program.c:2: error: too many arguments to function `int f()'
program.c:8: error: at this point in file
program.c: At global scope:
program.c:12: error: ISO C++ forbids declaration of `f' with no type
gcc program.c -std=c++98
cc1: warning: command line option "-std=c++98" is valid for C++/ObjC++ but not for C
int f();
f(int i,int j,int k)
{

    printf("%d %d %d",i,j,k);
}
f(int,int,int);           //in your case
f(void);                  //if you have no parameters