函数的return,返回值

问题初始

int select(int arr[],int left,int right,int target){
	if(left>right)return -1;		// 没找到 
	int mid=left+(right-left)/2;
	if(arr[mid]==target){
		return mid;						//  存入 寄存器中。
	}else if(arr[mid]>target){
		select(arr,left,mid-1,target);
	}else{
		select(arr,mid+1,right,target);
	}
}

昨天突然意识到,这个函数返回值并不是靠 return 直接给到的,但是结果依然是正确输出的,所以 查点资料 弄明白一些。

对 void 型

void func(){
}
1.return -1;				// [Error] return-statement with a value, in function returning 'void' [-fpermissive]
函数体内可以有 return ,但不能 with a value。
2.int b=func(a,0,4,28);		// [Error] void value not ignored as it ought to be
不能进行赋值
3.cout<<func(a,0,4,28);		// [Error] no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream<char>}' and 'void')
也不能进行输出

对非 void 型

无论 函数体内 有无 return ,都可进行赋值

int k=func(10);			// OK, func 是一个 non-void 的函数
  • 如果有return,return 后边必须跟一个 值
int func(int a){
	int b=9;
	return ;		// [Error] return-statement with no value, in function returning 'int' [-fpermissive]
}
当 我们 在进行 return 27; 的时候, 对应的汇编 是 mov eax,27 (向eax寄存器存 27)
  • 如果函数体内没有 return,以及 有return,但因为分支结构等原因 , return语句没有执行到,此时 函数的返回值
函数体内 没有 return
int func(int a){
	int b=9;
	int x=23;
}
		cout<<func(10)<<endl;		// 传入常量,函数返回值 不定
		cout<<func(10)<<endl;
		int m=9;
		cout<<func(m)<<endl;						// 传入变量,返回 eax 寄存器 中的值(本例中 是 实参 m 的值)
		cout<<func(10)<<endl;
		cout<<func(m)<<endl;

输出结果:				 在另一台机器
0						1
4710240					4745728
9						9
4710240					4745728
9						9

对于 函数体内 无return时的返回值

返回值取决于确切的平台,可能是程序集级别返回寄存器(例如 x86 上的 EAX)中发生的任何随机值。
C function defined as int but having no return statement in the body still compiles
Technically, if a non-void function returns without a value and the function’s return value is used, the behavior is undefined (C99 §6.9.1/12) – it might return a random value, it could crash, etc. On x86, it will probably just use whatever junk is in the EAX register. But on other architectures, such as IA64, uninitialized garbage could be deadly. – Adam Rosenfield

从技术上讲,如果非空函数返回没有值并且使用了函数的返回值,则行为未定义(C99 §6.9.1/12)——它可能返回一个随机值,它可能会崩溃等。在 x86 上 ,它可能只会使用 EAX 寄存器中的任何垃圾。 但是在其他架构上,例如 IA64,未初始化的垃圾可能是致命的。 — 亚当·罗森菲尔德


eax 里是什么 ?

可以是 函数参数的值

函数调用的时候的会将实参从右向左依次入栈

如果传入的参数是变量,则依次放在eax寄存器中,根据上面的入栈顺序,就是说eax中保存的是函数第一个参数的值(但是,实际我测试的并不完全是第一个参数,也可以是其他位置);
如果传入的参数是常量,则不会使用eax寄存器。

可以是 return 右边的值

如果,函数执行过程中,碰到了 return,使用return关键字会将右边表达式的结果保存在eax寄存器中,如果不写return,则eax中可能是之前传入参数的值,也可能是上一次return的值,看情况分析。
函数不写return以及调用无参函数时传参会出现什么结果


一般返回值在 EAX 寄存器
没将返回值写到eax中,但调用者依旧去读取eax的值,谁也不知道是个啥
总之,还是写规范一点吧。例如,对开始的代码进行修改:

int select(int arr[],int left,int right,int target){
	if(left>right)return -1;		// 没找到 
	int ret;
	int mid=left+(right-left)/2;
	if(arr[mid]==target){
		return mid;						//  存入 寄存器中。
	}else if(arr[mid]>target){
		ret=select(arr,left,mid-1,target);
	}else{
		ret=select(arr,mid+1,right,target);
	}
	return ret;
}
  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值