K& R和ANSI功能输出之间的差异

时间:2009-02-23 10:01:24

标签: c

我运行了以下代码,发现了一些奇怪的输出。


int
mean_ansi (int num1, int num2)
{
  printf ("In %s\n", __FUNCTION__);
  printf ("num1,num2 is %d,%d\n", num1, num2);
  return (num1 + num2) / 2;
}

int
mean_K_and_R (num1, num2)
     int num1, num2;
{
  printf ("In %s\n", __FUNCTION__);
  printf ("num1,num2 is %d,%d\n", num1, num2);
  return (num1 + num2) / 2;
}


int
main ()
{
  int i = 6;
  double f = 1.0;

  printf ("In %s\n", __FUNCTION__);
  printf ("[f,i] = [%f,%d]\n", f, i);

  /* deliberate mistakes */
  mean_ansi (f, i);
  mean_K_and_R (f, i);

  return 0;
}

输出:

主要

[f,i] = [1.000000,6]

在mean_ansi

num1,num2是1,6

在mean_K_and_R

num1,num2是0,1072693248

任何人都可以解释这种行为。

我看到了集会,但结果不是很多。

在这两种语法中,函数参数在堆栈上的推送方式是否存在差异?

3 个答案:

答案 0 :(得分:4)

Dan Olson有正确的想法,Slartibartfast解释了价值观来自哪里:

mean_K_and_R()的定义被视为如此定义

int mean_K_and_R();

即该函数接受任何参数,除了默认参数提升之外不进行任何转换。

如果使用cdecl调用约定,这意味着mean_K_and_R(f, i)将首先将i推送到堆栈,然后是f的高位,然后是f的低位}。

但该函数认为它需要两个整数参数,这意味着num1现在将fnum2的低位引用到f的高位。< / p>

答案 1 :(得分:2)

我做了一些挖掘并找到了一个thread,表明K&amp; R样式函数声明不会创建原型,因此如果没有单独的原型,编译器可以根据需要自由地处理参数。

我不确定这是多么真实,您可以通过快速插入原型并查看函数是否生成相同的值来验证它。

在任何情况下,K&amp; R风格的声明都非常过时,因为我相信你知道,并且应该避免。如果有什么问题就是一个例子。

答案 2 :(得分:2)

我的猜测是,在第一种情况下,存在doubleint的隐式转换。在第二个中,表示1.0的64位被解释为两个整数。编号1072693248表示为binnary为

00111111111100000000000000000000 

但是如果你看看this page,你会发现这实际上是数字1的双重表示的上半部分。第一个0是符号,01111111111是指数,其余零是上限分数。我唯一没有得到的是1分数去了哪里?说完所有这些后,我希望输出为1,1072693248。