C函数不写return以及调用无参函数时传参会出现什么结果
2017-12-16 17:00
239 查看
1. 问题描述
偶然间重新拿起了三年前的C语言,遇到了以前没有遇到过的问题:1. C语言中普通函数声明了返回类型但是不用return返回结果,也能够编译通过,如下:
#include <stdio.h> int test1(int a) { return 10; } int test2(int a) { } int main() { int a = 1; test1(a); printf("%d\n", test2(a));//结果为1,如果不是传入变量而是直接传入数值,则结果为10 return 0; }
调用无参函数时传入参数,能够编译通过,如下:
#include <stdio.h> int test1() { } int main() { int a = 1; printf("%d\n", test1(a));//1,如果不传入变量而传入值,则结果无法理解 return 0; }
2. 问题分析
可以肯定的是执行时和使用的寄存器有关
1. 编译能够通过,说明gcc编译器为了效率不会检查是否有return关键字以及无参函数调用时是否传入了参数。
2. 没有return仍然能够拿到值,说明和寄存器有关,我们或多或少听说过eax寄存器,可以通过gdb反汇编查看究竟。
汇编代码太累赘,查看过程略过,下面直接记录结论。
3. 结论
通过查看函数调用的汇编代码,可以得出以下结论:C中函数调用的时候的会将实参从右向左依次入栈,这么做的好处是有利于可变参数实现,调用无参函数时可以传参,但是函数内取不到参数的值。而有参函数必须保证实参和形参数量一致,否则会报参数过多或过少的错误。
如果传入的参数是变量,则依次放在eax寄存器中,根据上面的入栈顺序,就是说eax中保存的是第一个参数的值;如果传入的参数是直接量,则不会使用eax寄存器,也就是说上面的test2(a)和test2(1)在传参的时候,只有前者会将1保存在eax中。
使用return关键字会将右边表达式的结果保存在eax寄存器中,如果不写return,则eax中可能是之前传入参数的值,也可能是上一次return的值,看情况分析。
请看下面的例子:
#include <stdio.h> int test1() { } int test2() { } int main() { int a = 1; test1(a); printf("%d\n", test2(2));//结果为1 return 0; }
两个test虽然都没有声明形参,但是仍然可以传参,只不过在函数内取不到参数。
调用test1,传入的是个变量,所以此时eax中的值为a的值1,之后调用test2,传入的是个直接量2,不会用到eax,所以eax还是1,由于test2声明了返回类型,但是又不写return,eax的值还是老样子,所以整个test2的结果就是eax的值1。
4. 思考
尽量不要这么玩,很危险!!!相关文章推荐
- python基础----函数的定义和调用、return语句、变量作用域、传参、函数嵌套、函数对象、闭包、递归函数
- 编写一函数,由实参传来一个字符串,统计此字符串中字母、数字、空格和其它字符的个数,在主函数中输入字符串以及输出上述结果。 只要结果,别输出什么提示信息。
- (c++)编写一函数,由实参传来一个字符串,统计此字符串中字母、数字、空格和其它字符的个数,在主函数中输入字符串以及输出上述结果。 只要结果,别输出什么提示信息。
- unity 所有碰撞器(触发器),碰撞条件、结果,触发条件、结果。。。以及碰撞函数、触发函数的调用。
- 编写一函数,由实参传来一个字符串,统计此字符串中字母、数字、空格和其它字符的个数,在主函数中输入字符串以及输出上述结果。 只要结果,别输出什么提示信息。
- 两个线程同时调用一个函数会出现什么情况?
- 装饰器1、无参数的装饰器 2、有参数的装饰器 3、装饰器本身带参数的以及如果函数带return结果的情况
- 两个线程同时调用一个函数会出现什么情况?
- 动态函数调用实现下列操作,输入2个数以及操作符计算结果。 @ 求最大公约数 $求最小公倍数 - 求差 + 求和 等等
- 编写一函数,由实参传来一个字符串,统计此字符串中字母、数字、空格和其它字符的个数,在主函数中输入字符串以及输出上述结果。 只要结果,别输出什么提示信息。
- python 使用socket客户端向服务端传参,调用指定函数并返回值给客户端
- Effective C++ .06 阻止编译器自动生成函数以及被他人调用
- 函数调用时两种传参方式
- 阅读类的定义,说出测试函数中不同情况的调用产生的结果
- 第十周项目一 阅读下面的定义,请说出在测试函数中不同情况的调用产生的结果(5 a)
- 【php基础班】第10天 函数、return详解、函数调用、递归函数、数组
- 通过传参实现函数调用
- 编写一个函数,从实参传来一个字符串,统计其中字母,数字,空格和其他字符的个数,在主函数中输入字符串以及输出上述的结果
- c++中带返回值函数没写return能通过编译但运行时会出现奇怪问题
- 函数调用时发生了什么