如何简化或提高复杂逻辑语句的可读性?

时间:2016-04-16 22:51:58

标签: c++ logic readability

所以我有一个逻辑陈述的怪物:

(((ncode[i]+key[ikey])>90 && (ncode[i]+key[ikey])<97) || (ncode[i] + key[ikey])>122)

我总是被告知,如果你有需要换行的逻辑语句,你可能会做错事。我知道我可能会将它重构为一种新方法,但对于我正在进行的工作而言,这并不一定有意义。我该怎么做才能让它更具可读性?

4 个答案:

答案 0 :(得分:2)

我只是使用一个临时变量来清理:

auto code = ncode[i] + key[ikey];
if ( (code > 90 && code < 97) || (code > 122) )

大多数编译器无论如何都会优化临时性。

答案 1 :(得分:0)

假设ncodekey中的值都是整数(或浮点数),您是否可以将它们的求和值分配给新变量?将该行转为:

int result = ncode[i] + key[iKey];
if( (result > 90 && result < 97) || result > 122)
    //Logic

它变成了两行,但在我看来确实提高了可读性。

答案 2 :(得分:0)

我会使用const temp变量来替换三个重复的(ncode[i]+key[ikey]),以获得性能和可读性。不要重复自己。

const auto temp = ncode[i] + key[ikey];
if ( ((90<temp) && (temp<97)) || (122<temp) )

此外,在这种情况下仅使用<。因此,前两个比较变为“温度在90到97之间。想象一下,在线上绘制一条90,97和122的线,与这三个点相关的线上的”良好“温度范围。

答案 3 :(得分:0)

<Style TargetType="telerik:RadGridView" BasedOn="{StaticResource GridViewRowStyle}">
        <Setter Property="ShowGroupPanel" Value="False" />
        <Setter Property="AutoGenerateColumns" Value="False" />
        <Setter Property="RowIndicatorVisibility" Value="Collapsed" />
        <Setter Property="CanUserFreezeColumns" Value="False" />
        <Setter Property="IsReadOnly" Value="True" />
        <Setter Property="BorderThickness" Value="1,1,1,0" />
    </Style>

是一些玩具。

然后:

template<class Lower>
auto is_gt(Lower&&l){
  return [=](auto&&x){ return l<x; };
}
template<class Higher>
auto is_lt(Higher&&l){
  return [=](auto&&x){ return x<l; };
}
template<class L, class R>
auto also(L&& l, R&& r){
  return [=](auto&&x){return l(x)&&r(x); };
}
template<class L, class R>
auto either(L&& l, R&& r){
  return [=](auto&&x){return l(x)||r(x); };
}
template<class Lower, class Upper>
auto between(Lower&& l, Upper&& u){
  return also(is_gt(l), is_lt(u));
}

这可以更加光滑。如果我们将谓词定义为返回支持if (either(between(90,97), is_gt(122))(ncode[i]+key[ikey])) { bool以及&&重载的||的函数对象,并让上面的玩具返回谓词,我们得到:

~

摆脱if (( between(90,97) || is_gt(122))(ncode[i]+key[ikey])) { 前缀噪音。

为了提高非either个案例的效率,请通过移动来捕捉界限。

int

上述每个template<class F> struct predicate_t:F{ predicate_t(F const& f):F(f){} template<class F2> friend auto operator&&(predicate const& f1,predicate<F2> const& f2){ auto r=[=](auto&&...args){ return f1(args...)&&f2(args...); }; return predicate_t<decltype(r)>(r); } template<class F2> friend auto operator||(predicate const& f1,predicate<F2> const& f2){ auto r=[=](auto&&...args){ return f1(args...)||f2(args...); }; return predicate_t<decltype(r)>(r); } template<class F2> friend auto operator!(predicate const& f1){ auto r=[=](auto&&...args){ return !f1(args...); }; return predicate_t<decltype(r)>(r); } }; template<class F> predicate_t<std::decay_t<F>> predicate(F&&f){ return std::forward<F>(f); } 函数都返回toy而不是lambda。

这个代码在使用时更简单,并且应该没有运行时开销,但是与传统的C ++不同,它是一种不同的编码风格。