当前位置:嗨网首页>书籍在线阅读

13-问题所在

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

9.2.1 问题所在

我们看看与 imax() 函数相关的一些示例,该函数与 imin() 函数关系密切。程序清单9.4演示了一个程序,用过去声明函数的方式声明了 imax() 函数,然后错误地使用该函数。

程序清单9.4  misuse.c 程序

/* misuse.c -- 错误地使用函数 */
#include <stdio.h>
int imax();      /* 旧式函数声明 */
int main(void)
{
     printf("The maximum of %d and %d is %d.\n",3, 5, imax(3));
     printf("The maximum of %d and %d is %d.\n",3, 5, imax(3.0, 5.0));
     return 0;
}
int imax(n, m)
int n, m;
{
     return (n > m ? n : m);
}

第1次调用 printf() 时省略了 imax() 的一个参数,第2次调用 printf() 时用两个浮点参数而不是整数参数。尽管有些问题,但程序可以编译和运行。

下面是使用Xcode 4.6运行的输出示例:

The maximum of 3 and 5 is 1606416656.
The maximum of 3 and 5 is 3886.

使用 gcc 运行该程序,输出的值是 13593794721359377160 。这两个编译器都运行正常,之所以输出错误的结果,是因为它们运行的程序没有使用函数原型。

到底是哪里出了问题?由于不同系统的内部机制不同,所以出现问题的具体情况也不同。下面介绍的是使用PC和VAX的情况。主调函数把它的参数存储在被称为栈(stack)的临时存储区,被调函数从栈中读取这些参数。对于该例,这两个过程并未相互协调。主调函数根据函数调用中的实际参数决定传递的类型,而被调函数根据它的形式参数读取值。因此,函数调用 imax(3) 把一个整数放在栈中。当 imax() 函数开始执行时,它从栈中读取两个整数。而实际上栈中只存放了一个待读取的整数,所以读取的第2个值是当时恰好在栈中的其他值。

第2次使用 imax() 函数时,它传递的是 float 类型的值。这次把两个 double 类型的值放在栈中(回忆一下,当 float 类型被作为参数传递时会被升级为 double 类型)。在我们的系统中,两个 double 类型的值就是两个64位的值,所以128位的数据被放在栈中。当 imax() 从栈中读取两个 int 类型的值时,它从栈中读取前64位。在我们的系统中,每个 int 类型的变量占用32位。这些数据对应两个整数,其中较大的是3886。