1.旧式无参声明
ANSI C是美国国家标准协会(ANSI)对C语言发布的标准。使用C的软件开发者被鼓励遵循ANSI C文档的要求,因为它鼓励使用跨平台的代码。
在ANSI C规范之前,我们在声明函数的时候只要声明其返回类型,这样就可能有如下问题产生:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
可能输出如下:
- 1
- 2
- 1
- 2
由于操作系统的内部机制不同,上面的错误结果可能也不同。
第一个执行过程如下:
- 调用函数首先把参数放入堆栈临时储存
- 被调用函数从堆栈中读取这些参数
- 被调用函数是根据其形参的类型进行数据读取的。因此,函数调用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);
使用这替代上面的声明后,我们重新编译程序,会发现第一种情况,也就是缺少参数的会提示错误信息:传递参数过少。修改过后,再编译,就能通过。
- 1
- 2
- 1
- 2
这里我们在使用imax(3.0,5.0)的时候,编译没有错误提示,但是会有警告,提示double类型被转成int类型,这可能导致损失数据。
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
3.无参和不确定参
无参:int imax(void);
不确定参数:int imax(int b,…);