紧凑的多条件if语句

时间:2016-10-18 23:30:22

标签: c++ if-statement

我有一个最简单的问题。我正在练习if语句,并想知道我是否可以在不同条件下打印出不同的消息,但我想保持简单。如果第一个条件为真,则cout的第一行将打印;如果第二个条件为真,则cout的第二行将打印出来;等等。代码如下;

int x; cin >> x;
int y; cin >> y;

if(x<y||x>y||x==y)
{
    cout << x << " is smaller than " << y << endl;
    cout << x << " is bigger than " << y << endl;
    cout << x << " is equal to " << y << endl;
}

显然有些东西缺失,||之间有某种cout s。是否可以保持此代码的紧凑性并使其正常运行?

7 个答案:

答案 0 :(得分:3)

要做你要求的,你的代码应该是:

int x; cin >> x;
int y; cin >> y;

if(x<y)
{
    cout << x << " is smaller than " << y << endl;
}
else if (x>y)
{
    cout << x << " is bigger than " << y << endl;
}
else
{
    cout << x << " is equal to " << y << endl;
}

换句话说,你的三个条件必须位于if-else if-else控制结构的不同部分。这样,其中一个根据您的输入执行,并打印出相应的消息。

答案 1 :(得分:2)

有助于以数学方式思考这些情况。如果有三种可能的情况(&lt;,&gt;和=),则需要测试两次。在下面的代码中,进行了两项测试以确定关系是否小于或大于;如果是,则发出适当的输出。假设以上都不是真的,那么唯一的另一种可能性是相同的。由else处理。链接if ... else if ... else语句在一起是一般解决方案。对于更有限的方法,存在switch关键字。

#include <iostream>
using namespace std;

int main() {
    int x;

    cout << "Enter x: ";
    cin >> x;

    cout << "Enter y: ";
    int y; cin >> y;

    if (x < y)
        cout << x << " is smaller than " << y << endl;
    else if (x > y)
        cout << x << " is bigger than " << y << endl;
    else
        cout << x << " is equal to " << y << endl;
}

答案 2 :(得分:2)

你简单的意思是什么?如果是紧凑的,那么这是正确的(但不是最可读的)。 。

x==y?cout<<"x=y":(x<y?cout<<"x<y":cout<<"x>y");

。 。或者发疯并使==成为保存字符的默认情况

x>y?cout<<"x>y":(x<y?cout<<"x<y":cout<<"x=y");

答案 3 :(得分:1)

你可以这样:

int x; cin >> x;
int y; cin >> y;

if(x<y) {
    cout << x << " is smaller than " << y << endl;
} else if (x>y) {
    cout << x << " is bigger than " << y << endl;
} else if (x==y)  {
    cout << x << " is equal to " << y << endl;
}

或者如果你觉得冒险只是:

 } else {
    cout << x << " is equal to " << y << endl;
 }

答案 4 :(得分:0)

你使用三元运算符的魔力:

#include <iostream>

int main()
{
    int x, y;
    std::cin >> x >> y;

    (x == y) ? (std::cout << x << " is equal to " << y << std::endl) : 
    ((x <  y) ? (std::cout << x << " is smaller than " << y << std::endl) :
    (std::cout << x << " is bigger than " << y << std::endl));

    return 0;
}

答案 5 :(得分:0)

如果你想完全落伍,你可能会滥用模板系统。

auto if_ = make_if(
    std::greater<>{}, [](auto x, auto y){ cout << x << " is greater than " << y << endl; },
    std::less<>{}, [](auto x, auto y){ cout << x << " is smaller than " << y << endl; },
    std::equal_to<>{}, [](auto x, auto y){ cout << x << " is equal to " << y << endl; }
);

if_(0,0);
if_(0,1);
if_(1,0);

会产生

0 is equal to 0
0 is smaller than 1
1 is greater than 0

live demo

以下全面实施:

template<typename Pred, typename Result, typename... Others>
struct If;

namespace detail
{
template<typename... Ts>
struct IfSelector
{
    using type = If<Ts...>;
};

template<>
struct IfSelector<>
{
    struct EmptyIf
    {
        template<typename... Ts>
        void operator()(Ts&&...){}
    };

    using type = EmptyIf;
};

template<typename... Ts>
using ParentIf = typename IfSelector<Ts...>::type;

}

template<typename Pred, typename Result>
struct IfEntry
{
    Pred pred;
    Result result;
};

template<typename Pred, typename Result, typename... Others>
struct If : detail::ParentIf<Others...>
{
    using pred = Pred;
    using result = Result;
    using parent = detail::ParentIf<Others...>;

    template<typename P, typename R, typename... Os>
    If(P&& p, R&& r, Os&&... os):
        parent{std::forward<Os>(os)...},
        entry{std::forward<P>(p), std::forward<R>(r)}
    {}

    template<typename... Ts>
    void operator()(Ts&&... ts) {
        if(entry.pred(ts...)) {
            entry.result(std::forward<Ts>(ts)...);
        } else {
            this->parent::operator()(std::forward<Ts>(ts)...);
        }
    }

    IfEntry<Pred, Result> entry;
};


template<typename... Ts>
auto make_if(Ts&&... ts){
    return If<Ts...>(std::forward<Ts>(ts)...);
}

基本上,您将谓词 - 结果对列表传递给模板,然后以相反的顺序检查它们。如果谓词产生true,则执行配对操作。

答案 6 :(得分:0)

如果你真的想要它简短,并且不太关心可读性,那就从一系列标签开始:

static char const *names[] = {" is smaller than ", " is equal to ", " is bigger than "};

然后使用丑陋的布尔逻辑来索引:

std::cout << x << names[1 + (y<x)-(x<y)] << y << '\n';

要弄清楚这一逻辑,请记住,a<b会生成false(将转换为0)或true(将转换为1)。

所以:

  • if x < y => y<x = 0, x<y = 1, 0-1 = -1
  • if y == x => y<x = 0, x<y = 0, 0-0 = 0
  • if y < x => y<x = 1, x<y = 0, 1-0 = 1

然后添加一个以使-1 ... 1变为0..2,并使用它来索引数组。

严重的是:如果您要做这样的事情,至少将比较包装成cmp(x,y)或该订单上的某些内容:

int cmp(int x, int y) { return y<x - x<y; }

然后在其他代码中使用它:

std::cout << names[1+cmp(x, y)] << '\n';

这并没有消除不可读的代码,但至少它将它限制在一个小地方(并且当你厌倦了它的过度可爱时,让你用更正常的逻辑替换它,而没有编辑其余代码。)

对于它的价值(不多),cmp函数被定义为生成与qsortbsearch所期望的相同类型的结果。