您的位置:首页 > 编程语言 > C语言/C++

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. 思考

  尽量不要这么玩,很危险!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  函数 c语言 return 参数
相关文章推荐