return的烦恼

最近几天,真忙坏了.以至于我有一种向C语言标准化组织写信建议去掉return关健字或者让return只能使用在函数最后一行的冲动,当然这是不可能的,只是一个玩笑,return是一种与技巧无关的绝不可缺的关键字.那些小朋友或者老先生们太喜欢这个关健字了,而在使用中又常常不考虑全局而出了太多的问题,我在许多公司都发现了因为return直接返回而引起的问题.甚至一些老手也常常犯这样的问题.公司里因为不恰当的使用return而引起的问题在公司的BUG库上可以列出非常庞大的一张表.虽然这些问题大部都表现在死机,重启,内存泄漏,无法进入窗口,操作失败等方面,但仍然花费了公司太多的维护成本.在研究问题过程中,我发现许多老手还是能注意到代码配对使用,比如打开了文件,立即写个关闭文件,分配了内在,立刻写个释放内存,但偏偏因为return的存在,破坏了程序正常的配对,导致许多时候压根就执行不到释放的代码.其实很多时候return是可以使用if  else+返回变量和do while(0)+break来替代的,return尽量保持在函数末尾,当然不是绝对,在某些情况下为了提高程序健壮性,是可以这么做的,因为过滥的使用return,已经像goto一样,给软件维护造成了太多的负担.

 

有很多朋友不关心代码调试和优化,他们只管拷贝代码,然后修补成看起来和用户需求上要求的一样就完事了,这是一种很糟糕的习惯,我在一个工程师的短短十几行的代码中的前五行发现了超过三处BUG,还有几处不规范的使用.当然后面有更多处的无用代码,当我问他为什么这样写时,他们给出的理由是写程序当然有错误,项目完成了慢慢改和优化.这绝对是一种很错误的思想,当我看到别人发布的一段十几行的代码存在超过3个以上的明显的错误时,我认为这段代码绝对有理由重新写.如果写程序时不消除那些明显是错误地方的代码,等着以后测试的同志发现时再改,我敢肯定你的BUG是改不完的,当看到七凑八拼的代码中遗留了原程序太多的无用代码或者垃圾代码时,绝对会让维护者发疯.忘了今天的主角return,那个工程师的代码模块入口函数十几行的代码,在第六行有return导致至少两处错误,一处代码冗余,一处是因为return后内存没有释放,一处是因为锁定了共享资源没有解锁,如果这些判断重新排列一下,可以节约掉那些无用代码.流程如下:

有错流程:

分配窗口内存->创建窗口->设置LCD独占->判断窗口需要的图片资源是否就绪->不就绪->释放窗口->return返回->取消LCD独占->释放分配的内存

 

Return,独占没有去掉,内存没有释放,多了个释放窗口的动作,如果把资源判断提到创建窗口前,就可以精简代码,减少出错

正确流程:

分配内存->判断窗口需要的图片资源是否就绪->不就绪->释放分配的内存->return返回

 

这些问题完全可以在编程之初就解决,而不是等着测试部发现问题再去解决,代码总是有错误的,但能够预料的代码错误一定的尽力避免,这样的错误难道不应该提前在发布给别人时先解决掉吗?这样才能为自己节约时间处理那些和用户接口有关的问题及效率优化.如果构架之初就有这样那样的问题,后期怎么还会有时间去优化代码和用户接口.无错是没有预料不及的错误,有错是因为经验原因或者复杂的难以预料的用户环境触发的错误.如果因为打算以后修改,所以就故意留下一些问题,或者就故意不在代码里做错误处理,或者看到错误不去处理,只等同事或者测试部门发现再修改.这是很糟糕的.

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
好的,下面是洛谷P1678 烦恼的高考志愿的样例代码: ```c++ #include <iostream> #include <algorithm> using namespace std; const int N = 1e5 + 10; int n, m, s; int a[N], b[N]; bool check(int x) { int cnt = 0; for (int i = 0; i < n; i++) { cnt += upper_bound(b, b + m, x - a[i]) - b; // 统计符合要求的专业数量 } return cnt >= s; } int main() { cin >> n >> m >> s; for (int i = 0; i < n; i++) { cin >> a[i]; } for (int i = 0; i < m; i++) { cin >> b[i]; } sort(b, b + m); // 排序 int l = 0, r = 1e9; while (l < r) { int mid = l + r >> 1; if (check(mid)) r = mid; else l = mid + 1; } cout << l << endl; return 0; } ``` 这道题目的思路还是比较清晰的,我们要求的就是“每个考生至少能报考s个专业”,因此我们可以二分答案,每次判断一个数mid,看看是否存在至少s个专业的分数之和不超过mid。 具体实现上,我们可以用一个check函数统计符合要求的专业数量。对于每个考生,我们枚举所有专业的分数,然后用upper_bound函数在专业分数数组b中查找第一个大于mid减去该考生分数的元素的位置,这个位置之前的所有专业的分数之和都不超过mid减去该考生分数。统计每个考生符合要求的专业数量,最后判断所有考生的符合要求的专业数量是否不少于s即可。 需要注意的是,在check函数中我们使用的是upper_bound函数而不是lower_bound函数,因为题目中要求的是“每个考生至少能报考s个专业”,因此我们需要找到第一个大于mid减去该考生分数的元素的位置,而不是第一个大于或等于mid减去该考生分数的元素的位置。 另外,我们在二分答案之前要对专业分数数组b进行排序,这样才能使用upper_bound函数进行二分查找。 最后,输出的答案应该是l而不是r。因为当l == r时,二分查找已经结束,此时l和r都是符合要求的答案,但是题目要求输出最小的符合要求的答案,因此应该输出l。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值