1.旧式无参声明
ANSI C是美国国家标准协会(ANSI)对C语言发布的标准。使用C的软件开发者被鼓励遵循ANSI C文档的要求,因为它鼓励使用跨平台的代码。
在ANSI C规范之前,我们在声明函数的时候只要声明其返回类型,这样就可能有如下问题产生:
#include<stdio.h>
int imax(); //旧式函数声明,没有参数
int main()
{
printf("The maximum of %d adn %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 max;
if(n>m)
max=n;
else
max=m;
return max;
}
可能输出如下:
The maximum of 3 adn 5 is 4273984.
The maximum of 3 and 5 is 1074266112.
由于操作系统的内部机制不同,上面的错误结果可能也不同。
第一个执行过程如下:
- 调用函数首先把参数放入堆栈临时储存
- 被调用函数从堆栈中读取这些参数
- 被调用函数是根据其形参的类型进行数据读取的。因此,函数调用imax(3)把一个整数放到堆栈中
- 当函数imax()执行时,会从堆栈中读取两个整数,但实际只有一个正确的整数在堆栈中,所以第二个数据是当时恰好在堆栈中的其它数这里是4273984
第二个执行过程如下:
- 调用函数时,传递的是float类型,这会将两个double类型的数值存放在堆栈中(float作为参数传递时会被转成double类型)。这意味着两个64位数值,也就是128位的数据被存储在堆栈中。
- 因为int是32位,那么imax()会从堆栈中读取两个int类型数据
2.解决方法
对于此的解决方案是在声明函数的同时为其指定参数类型。
我们可以使用如下声明:
int imax(int a,int b);
int imax(int,int);
使用这替代上面的声明后,我们重新编译程序,会发现第一种情况,也就是缺少参数的会提示错误信息:传递参数过少。修改过后,再编译,就能通过。
The maximum of 3 adn 5 is 5.
The maximum of 3 and 5 is 5.
这里我们在使用imax(3.0,5.0)的时候,编译没有错误提示,但是会有警告,提示double类型被转成int类型,这可能导致损失数据。
如
imax(3.9,5.4);
等价于
imax(3,5);
3.无参和不确定参
无参:int imax(void);
不确定参数:int imax(int b,…);