将if语句与逻辑相关的条件组合

时间:2017-01-02 22:25:05

标签: c if-statement nested-if

我有这种情况。

**更新了我的代码,它以我想要的方式工作。 *根据要求澄清了代码(完整程序)

如果我给

开始时间:2:30:30

停止时间:2:30:25

我应该

过去了:23:59:55

得到它?它过了午夜......进入第二天......

那是我想要的,它的确有效!

我有五个具有逻辑相关条件的if语句。

该程序提供了所需的输出,但是可以以任何方式组合这些if语句(除了使用' OR'运算符并创建巨大的条件;如嵌套if或if条件运算符。

//time elapsed program
//including support for time crossing midnight into the next day
#include<stdio.h>

struct time
{
  int hour;
  int minute;
  int second;
};

struct time timeElapsed(struct time, struct time);

int main()
{
  struct time start, stop, elapse;

  printf("Enter start time (hh:mm:ss)  :  ");
  scanf("%d:%d:%d", &start.hour, &start.minute, &start.second);
  printf("Enter stop  time (hh:mm:ss)  :  ");
  scanf("%d:%d:%d", &stop.hour, &stop.minute, &stop.second);

  elapse = timeElapsed(start, stop);

  printf("The time elapsed is          :  %.2d:%.2d:%.2d", elapse.hour, elapse.minute, elapse.second);

  return 0;
}

struct time timeElapsed(struct time begin, struct time end)
{
  struct time elapse;

  if(end.hour < begin.hour)
    end.hour += 24;

  if(end.hour == begin.hour  &&  end.minute < begin.minute)
    end.hour += 24;

  if(end.hour == begin.hour  &&  end.minute == begin.minute  &&  end.second < begin.second)
    end.hour += 24;

  if(end.second < begin.second)
  {
    --end.minute;
    end.second += 60;
  }

  if(end.minute < begin.minute)
  {
    --end.hour;
    end.minute += 60;
  }

  elapse.second = end.second - begin.second;
  elapse.minute = end.minute - begin.minute;
  elapse.hour = end.hour - begin.hour;

  return elapse;
}

4 个答案:

答案 0 :(得分:0)

逻辑上,您正在比较结束时间是否早于开始时间。

如果您可以通过保留订单的映射将这三个数字转换为一个,那么您将能够使用单个比较。

在这种情况下,转换为总秒数突出:

if (   end.hour * 3600L +   end.minute * 60 +   end.second
   < begin.hour * 3600L + begin.minute * 60 + begin.second )

这可能会或可能不会比原始代码更有效。如果您要定期执行此操作,则可以使用inline函数将时间转换为总秒数。

答案 1 :(得分:0)

所以前三个测试相当于检查“结束&lt;开始”。假设字段已经被验证在范围内(即.minute和.second都是0..59),为什么不转换为秒并直接比较它们,例如:

if((end.hour * 3600 + end.minute * 60 + end.second) < 
   (begin.hour * 3600 + begin.minute * 60 + begin.second))

对我来说,这更明显是源代码,在现代CPU上可能会生成更好的代码(即假设分支很昂贵,整数乘法很便宜)

为了看看这两种方法如何比较,这是用Clang 3.9 -O3编译的两个这样的比较函数的Godbolt版本(21对11指令,我没有计算代码字节或试图猜测执行时间)。

https://godbolt.org/g/Ki3CVL

答案 2 :(得分:0)

下面的代码与OP的逻辑略有不同,但我认为这符合真正的目标(可能不是)

减去类似的术语和比例。通过在缩放之前减去,溢出机会减少了。

#define MPH 60
#define SPM 60
int cmp = ((end.hour - begin.hour)*MPH + (end.minute - begin.minute))*SPM +
    (end.second - begin.second);

if (cmp < 0) Time_After();
else if (cmp > 0) Time_Before();
else Time_Same();    

答案 3 :(得分:0)

保持你的方法,我会做如下。这没有什么不同,但有两个主要分支:一个end肯定不需要修改,因为它发生在begin之后或同时发生(因此差异为0:0.0 ),另一个字段经过调整以考虑模数运算。

struct time timeElapsed (struct time begin, struct time end)
{
  if ((end.hour >= begin.hour) &&
      (end.minute >= begin.minute) &&
      (end.second >= begin.second)) {
    /* end is greater or equal to begin, nothing to adjust. */
  } else {
    end.hour +=24;

    if (end.second < begin.second) {
      --end.minute;
      end.second += 60;
    }

    if (end.minute < begin.minute) {
      --end.hour;
      end.minute += 60;
    }
  }

  struct time elapsed = {
    end.hour - begin.hour,
    end.minute - begin.minute,
    end.second - begin.second
  };
  return elapsed;
}