2016-10-18 3 views
-1

У меня самый простой вопрос. Я тренировался с заявлением if и задавался вопросом, могу ли я печатать различные сообщения в разных условиях, но я хотел сохранить его простым. Если первое условие истинно, будет напечатана 1-я строка cout; и если второе условие истинно, будет напечатана вторая строка cout; и так далее. Код следует;Compact multi-conditional if statement

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 с. Возможно ли сохранить этот код настолько компактным, чтобы он функционировал должным образом?

+1

Корпус if выполняется для всего состояния. Если вам понадобятся три разные вещи, основанные на трех разных условиях, вам понадобятся три оператора if. – NathanOliver

+0

это неверно! если одно из приведенных выше условий удастся, тогда будет выполнено все тело if. – Raindrop7

+0

Вы не изучаете программирование, угадывая синтаксис. Вы будете ошибаться чаще, чем нет. Получите несколько хороших [книг] (http://stackoverflow.com/q/388242/1889329) по этому вопросу. – IInspectable

ответ

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"); 
+0

Как я уже сказал, я практиковал/экспериментировал. И это на самом деле то, что я искал. Спасибо :) – a56444c

+0

ЕСЛИ вы хотите сделать его одним символом короче, вы можете сделать '==' случай по умолчанию. – learnvst

+0

Перемещение 'cout <<' вне тернарного оператора сделало бы это многого коротким –

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; 
} 

Другими словами, ваши три условия должны быть в отдельных частях, если-то еще, если-иначе структура управления. Таким образом, один из них выполняется на основе ваших входов и выводится соответствующее сообщение.

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; 
} 
+0

Это точно мой ответ, хотя ... почему два ответа одинаковы? –

+0

последнее, если избыточно – Raindrop7

+1

@space_voyager Этот сайт не имеет правила против нескольких ответов. И кажется маловероятным, что кто-либо плагиат ваш ответ, только три человека достигли аналогичной конструкции независимо (так как это, безусловно, самое очевидное решение) –

2

помогает математически думать об этих ситуациях. если есть три возможных случая (<,>, и =), то вам нужно дважды проверить. в приведенном ниже коде два теста проводятся для определения того, является ли отношение меньше или больше; если либо, то выдается правильный вывод. предполагая, что ни одно из вышеизложенных истинно, то единственная другая возможность равна. который обрабатывается 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; 
} 
+1

Wow! Это выглядит как код @ space_voyager. –

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; 
} 
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, выполняется парное действие.

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 определена для получения того же типа результатов, что и ожидалось qsort и bsearch.