Re: [问题] return问题

楼主: Schottky (顺风相送)   2016-04-28 15:23:32
※ 引述《david830317 (dd810)》之铭言:
: 开发平台(Platform): (Ex: VC++, GCC, Linux, ...)
: Xcode
: 额外使用到的函数库(Library Used): (Ex: OpenGL, ...)
: 问题(Question):
: 在xcode时用void以外不能用reture
: 错误结果(Wrong Output):
: Control may reach end of non-void function
: 程式码(Code):(请善用置底文网页, 记得排版)
: http://ideone.com/T36LJH
: 补充说明(Supplement):
关于这个 function 的写法
float Quantity::calcValue() const
{
if (unit >= 1 && unit <= 10)
{
return unit * 3.00;
}
if (unit >= 11 && unit <= 50)
{
return unit * 2.50;
}
if (unit >= 51)
{
return unit * 2.00;
}
}
我比较建议用 if-elseif-elseif 的结构来写:
float Quantity::calcValue() const
{
if (unit >= 1.0f && unit <= 10.0f) {
return unit * 3.00f;
} else if (unit > 1.0f && unit <= 50.0f) {
return unit * 2.50f;
} else if (unit >= 50.0f) {
return unit * 2.00f;
} else {
/* default */
return unit;
}
/* Unreached */
}
原因:
1. 这样才看得清楚这三条 if 其实是负责同一件事,条件排列整齐后,漏网之鱼也
在 default 那一区块有处理,不管是 error handling 还是 return default,
而且所有的状况在 if-else 结构内都会 return,能轻易判断函式终结点。
2. float 运算时,不管是比大小还是运算,最好两边都是 float (10.0f),
你有些写 int,问题倒还不大反正会转成 float,但有些写 double (2.50) 就
会两边都转成 double 运算,运算完再转 float 再 return,浪费效能。
另一个问题点,你大概一开始把 unit 定义为 int 后来才改 float,
所以 if 里面完全没有处理到 10.0f<unit<11.0f, 50.0f<unit<51.0f 的状况,
如果习惯把常数的 data type 也写对,遇到可能有问题的状况,心中自然会产生
违和感,觉得这样写怪怪的。你写 10.0f 时就会考虑 10.5f 会发生什么事
3. 最后注解 Unreached 其实很有必要,照我的写法所有状况都应该在 if-else 的
结构内 return,所以不会跑到 Unreached 那边。但就是有些人在修改 code 时
会呆呆加在后面,以为 if 跑完就会跑他加的东西,所以要注解提醒。
实务上有很多地方需要这样的防呆措施,不只是合作写程式防别人耍呆,很多
时候自己也会发蠢,
* * *
举另一个经典例子:
if (unit > 1.0f)
return unit*3.0f;
这样写在 C/C++ 是允许的,省略大括号。但是就有人这样插一行...
if (unit > 1.0f)
printf("Using 3.0 ratio.\n");
return unit*3.0f;
结果变成不管 unit 值多少,有没有 print 那行字,都变成 return unit*3.0f 了
所以我会严格要求如果 if 的内容分成两行写,一定要加大括号
if (unit > 1.0f) {
return unit*3.0f;
}
或这样也行
if (unit > 1.0f)
{
return unit*3.0f;
}
写成同一行的话随便你加不加
if (unit > 1.0f) return unit*3.0f;
大家应该会觉得是插入新行却不长眼看清楚的那个人的错,我也觉得是他的错,
但是这种状况实在太多太多了,大家都是用 Ctrl-C & Ctrl-V 在写程式的样子,
熬夜拼命贴的时候就常常贴错地方,只好设法定一些规则防呆。
这样至少你 code review 时就可以检查大括号来预防出错,而不是每次 release 的
前一天晚上才在抓几百个这种无脑错误。
作者: MOONRAKER (㊣牛鹤鳗毛人)   2016-04-28 15:55:00
else if 不错,清楚要求只有一个case执行也有人要求很长很大的if block不要用else而是要 if (flag) { ... } if (!flag) { ... } 的不过那是另外一回事情
作者: james732 (好人超)   2016-04-28 20:11:00
作者: CoNsTaR ((const *))   2016-04-29 12:42:00
用 monads 来写最方便啦 XDD
作者: bibo9901 (function(){})()   2016-04-29 13:09:00
monad是个糟糕的设计
作者: CoNsTaR ((const *))   2016-04-29 13:13:00
是啊 它隐藏了不该隐藏的细节 可是就是方便嘛 XDD
作者: bibo9901 (function(){})()   2016-04-29 13:15:00
C又没有绑手绑脚的"纯"函数 跟本不必用monad啊
作者: chen20 (sOnE)   2016-04-29 21:59:00
推推

Links booklink

Contact Us: admin [ a t ] ucptt.com