免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2973 | 回复: 9

[函数] if语句的嵌套使用 [复制链接]

论坛徽章:
0
发表于 2014-06-18 16:17 |显示全部楼层
最近写代码碰到一个if语句嵌套的问题,这种语句通常需要避免使用吗?通常处理这种情况,同志们有没有高招。
if(a)
{
   if (b)
  {
      if (c)
      {
          do();
      }
      else
     {
         log();
     }
  else
  {
       log();
  }
}
else
{
    log();
}
   

论坛徽章:
323
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
发表于 2014-06-18 16:35 |显示全部楼层
只要3层还行吧,如果log()都是一样的,可以合并

求职 : 系统工程师等
论坛徽章:
5
技术图书徽章
日期:2014-04-19 22:01:05天蝎座
日期:2014-05-09 13:49:28双子座
日期:2014-06-16 15:08:042015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:55:28
发表于 2014-06-18 16:36 |显示全部楼层
代码重构啊

论坛徽章:
0
发表于 2014-06-18 16:43 |显示全部楼层
一共六层,log的内容都不一样的。回复 2# hellioncu


   

论坛徽章:
0
发表于 2014-06-18 16:44 |显示全部楼层
你的意思是把b和c合并然后,重新封装一个函数?回复 3# qxhgd


   

求职 : 系统工程师等
论坛徽章:
5
技术图书徽章
日期:2014-04-19 22:01:05天蝎座
日期:2014-05-09 13:49:28双子座
日期:2014-06-16 15:08:042015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:55:28
发表于 2014-06-18 16:51 |显示全部楼层
回复 5# ronaldoa
  1. if(a&&b&&c)
  2. {
  3.     do();
  4. }
  5. if(!a)
  6. {
  7.     log1();
  8. }
  9. else(!b)
  10. {
  11.     log2();
  12. }
  13. else(!c)
  14. {
  15.     log3();
  16. }
复制代码
这样是否会好些?

求职 : 系统工程师等
论坛徽章:
5
技术图书徽章
日期:2014-04-19 22:01:05天蝎座
日期:2014-05-09 13:49:28双子座
日期:2014-06-16 15:08:042015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:55:28
发表于 2014-06-18 16:52 |显示全部楼层
或者可以将abc的值打印到Log里,
如printf("",a,b,c)
一条Log可以搞清楚实际的状况了。

论坛徽章:
0
发表于 2014-06-18 17:05 |显示全部楼层
Thank you。 我在stackoverflow上找到了一些解决办法,似乎用goto语句还是比较有用的。
like:

stackoverflow

For me do{...}while(0) is fine. If you don't want to see the do{...}while(0), you can define alternative keywords for them.

Example:

#define BEGIN_TEST do{
#define END_TEST }while(0);

BEGIN_TEST
   if(!condition1) break;
   if(!condition2) break;
   if(!condition3) break;
   if(!condition4) break;
   if(!condition5) break;

   //processing code here

END_TEST

I think the compiler will remove the unneccessary while(0) condition in do{...}while(0) in binary version and convert the breaks into unconditional jump. You can check it's assembly language version to be sure.

Using goto also produces cleaner code and it is straightforward with the condition-then-jump logic. You can do the following:

{
   if(!condition1) goto end_blahblah;
   if(!condition2) goto end_blahblah;
   if(!condition3) goto end_blahblah;
   if(!condition4) goto end_blahblah;
   if(!condition5) goto end_blahblah;

   //processing code here

}end_blah_blah:;  //use appropriate label here to describe...
                   //  ...the whole code inside the block.

Note the label is placed after the closing }. This is the avoid one possible problem in goto that is accidentally placing a code in between because you didn't see the label. It is now like do{...}while(0) without condition code.

To make this code cleaner and more comprehensible, you can do this:

#define BEGIN_TEST {
#define END_TEST(_test_label_) }_test_label_:;
#define FAILED(_test_label_) goto _test_label_

BEGIN_TEST
   if(!condition1) FAILED(NormalizeData);
   if(!condition2) FAILED(NormalizeData);
   if(!condition3) FAILED(NormalizeData);
   if(!condition4) FAILED(NormalizeData);
   if(!condition5) FAILED(NormalizeData);

END_TEST(NormalizeData)

With this, you can do nested blocks and specify where you want to exit/jump-out.

#define BEGIN_TEST {
#define END_TEST(_test_label_) }_test_label_:;
#define FAILED(_test_label_) goto _test_label_

BEGIN_TEST
   if(!condition1) FAILED(NormalizeData);
   if(!condition2) FAILED(NormalizeData);

   BEGIN_TEST
      if(!conditionAA) FAILED(DecryptBlah);
      if(!conditionBB) FAILED(NormalizeData);   //Jump out to the outmost block
      if(!conditionCC) FAILED(DecryptBlah);

      // --We can now decrypt and do other stuffs.

   END_TEST(DecryptBlah)

   if(!condition3) FAILED(NormalizeData);
   if(!condition4) FAILED(NormalizeData);

   // --other code here

   BEGIN_TEST
      if(!conditionA) FAILED(TrimSpaces);
      if(!conditionB) FAILED(TrimSpaces);
      if(!conditionC) FAILED(NormalizeData);   //Jump out to the outmost block
      if(!conditionD) FAILED(TrimSpaces);

      // --We can now trim completely or do other stuffs.

   END_TEST(TrimSpaces)

   // --Other code here...

   if(!condition5) FAILED(NormalizeData);

   //Ok, we got here. We can now process what we need to process.

END_TEST(NormalizeData)

论坛徽章:
46
2015小元宵徽章
日期:2015-03-06 15:58:18羊年新春福章
日期:2015-04-14 10:37:422015年亚洲杯之阿曼
日期:2015-04-14 10:41:50NBA常规赛纪念章
日期:2015-05-04 22:32:03NBA季后赛大富翁
日期:2015-05-04 22:34:11菠菜明灯
日期:2015-05-04 22:35:49新奥尔良黄蜂
日期:2015-05-04 22:49:2315-16赛季CBA联赛之广夏
日期:2015-12-11 15:02:342015年亚洲杯之巴勒斯坦
日期:2015-03-04 19:56:562015年亚洲杯之阿联酋
日期:2015-03-04 11:19:04休斯顿火箭
日期:2015-03-02 16:32:11纽约尼克斯
日期:2015-03-02 16:09:04
发表于 2014-06-25 17:27 |显示全部楼层
可以根据条件重新组合一下

论坛徽章:
46
2015小元宵徽章
日期:2015-03-06 15:58:18羊年新春福章
日期:2015-04-14 10:37:422015年亚洲杯之阿曼
日期:2015-04-14 10:41:50NBA常规赛纪念章
日期:2015-05-04 22:32:03NBA季后赛大富翁
日期:2015-05-04 22:34:11菠菜明灯
日期:2015-05-04 22:35:49新奥尔良黄蜂
日期:2015-05-04 22:49:2315-16赛季CBA联赛之广夏
日期:2015-12-11 15:02:342015年亚洲杯之巴勒斯坦
日期:2015-03-04 19:56:562015年亚洲杯之阿联酋
日期:2015-03-04 11:19:04休斯顿火箭
日期:2015-03-02 16:32:11纽约尼克斯
日期:2015-03-02 16:09:04
发表于 2014-06-25 17:27 |显示全部楼层
可以根据条件重新组合一下
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP