-1

I have the simplest question ever. I was practising with the if statement and wondered if I could print out different messages under different conditions, but I wanted to keep it simple. If the 1st condition is true, the 1st line of cout will print; and if the 2nd condition is true, the 2nd line of cout will print; and so on. Code follows;

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

Apparently there is something missing, some kind of ||s between the couts. Is it possible to keep this code as compact as it is and make it function properly?

amanuel2
  • 4,508
  • 4
  • 36
  • 67
a56444c
  • 21
  • 3
  • 1
    The body of an if is ran for the entire condition. If you need three different things to happen based on three different conditions then you need three if statements. – NathanOliver Oct 18 '16 at 23:33
  • this is not correct! if one of the conditions above succeeds then the whole body of if will be executed. – Raindrop7 Oct 18 '16 at 23:37
  • You don't learn programming by guessing at the syntax. You will get it wrong more often than not. Get a few good [books](http://stackoverflow.com/q/388242/1889329) on the subject. – IInspectable Oct 18 '16 at 23:44

7 Answers7

3

To do what you ask, your code should be:

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

In other words, your three conditions have to be in separate parts of the if-else if-else control structure. This way, one of them executes based on your inputs and the corresponding message is printed out.

space_voyager
  • 1,984
  • 3
  • 20
  • 31
2

it helps to think mathematically about these situations. if there are three possible cases (<, >, and =), then you need to test twice. in the code below, two tests are done to determine if the relationship is less than, or greater than; if either, then the proper output is issued. assuming that neither of the above is true, then the only other possibility is equal. that is handled by the else. chaining if...else if...else statements together is the general solution. the switch keyword exists for a more limited approach.

#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;
}
ryonts
  • 126
  • 6
2

What to you mean by simple? If compact, then this is correct (but not the most readable) . .

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

. . or go crazy and make == the default case to save a char

x>y?cout<<"x>y":(x<y?cout<<"x<y":cout<<"x=y");
learnvst
  • 15,455
  • 16
  • 74
  • 121
1

You can go like this:

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

Or if you feel adventurous just:

 } else {
    cout << x << " is equal to " << y << endl;
 }
Cemal Eker
  • 1,266
  • 1
  • 9
  • 24
  • That is exactly my answer, though... why have two answers that are the same? – space_voyager Oct 18 '16 at 23:40
  • the last else if is redundant – Raindrop7 Oct 18 '16 at 23:41
  • 2
    @space_voyager this site has no rule against multiple answers. And it seems unlikely that anyone plagiarised your answer , just three people reached a similar construct independently (since it is by far the most obvious solution) – M.M Oct 18 '16 at 23:45
0

you use the magic of ternary operator:

#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;
}
Raindrop7
  • 3,889
  • 3
  • 16
  • 27
0

If you want to go completely overboard you could abuse the template system a little.

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

Would yield

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

live demo

Here's full implementation of this:

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

Basically, you pass a list of predicate-result pairs to the template, and they're checked in the reverse order. If a predicate yields true, the paired action is executed.

krzaq
  • 16,240
  • 4
  • 46
  • 61
0

If you really want it short, and don't care much about readability, start with an array of labels:

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

Then use ugly Boolean logic to index into that:

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

To figure out that logic, keep in mind that a<b produces either false (which will convert to 0) or true (which will convert to 1).

So:

  • 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

Then add one to get the -1...1 to be 0..2 instead, and use that to index into the array.

Seriously though: if you're going to do something like this, at least wrap the comparisons up into a cmp(x,y) or something on that order:

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

Then use that in the other code:

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

That doesn't eliminate the unreadable bit of code, but at least it restricts it to one little place (and lets you replace it with more normal logic when you're sick of its excessive cuteness, without having to edit the rest of the code).

For what it's worth (not much) this cmp function is defined to produce the same type of result as expected by qsort and bsearch.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111