why does this else if statement never run?

for some reason the else if statement to catch if the denominator number is 0 never runs when y is enter as 0.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 #include <iostream>

using namespace std;

int main()
{
    int x , y;
    cin >> x;
    cin >> y;
    
    
    if(x % y == 0)
        cout << "even";
    else if(y == 0)
        cout << "cant divide by 0";
    else
        cout << "odd";

    return 0;
}.


but this will run:
1
2
3
4
5
6
7
8
9
if(y == 0)
{
 cout << "can't divide by 0";
}

if(x%y == 0)
{
 cout << " even ";
}


im just curious as to the reason why
Last edited on
Try this if/then layout:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>

int main()
{
   std::cout << "Enter numerator: ";
   int x;
   std::cin >> x;

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

   if ( y == 0 )
   { std::cout << "Can't divide by 0\n"; }
   else if ( x % y == 0 )
   { std::cout << "Even\n"; }
   else
   { std::cout << "Odd\n"; }
}

You need to check for y (your denominator) being zero before you use the modulus operator. If you perform a modulo operation with zero, *BLAM!* run-time error, if you're lucky.
If y is zero your two separate if statements will still bomb. The first will execute as expected, the 2nd will go boom.

Whether you see the output statement from the "can't divide by zero" message when the run-time error occurs depends.

Depends on your OS, your compiler, how you execute your program (in a terminal/from an IDE), the number of sunspots, etc. Dividing/performing modulo by zero should be a run-time error.

A run-time error is not a good thing.
elses chain if blocks together, is why.
fixing the error, and then more explains..

if(y == 0)
cout << "error\n";
else if(x % y == 0)
cout << "ok";

above, if its zero, you will not try to do the % operation which would throw an error. This is because, if y is zero, it does not go into the else at all. The else only happens when the if(y==0) is false.

removing the else, it WILL go into the % and crash:
if(y == 0)
cout << "error\n"; //the if y == 0 block is DONE and FORGOTTEN.
-------------------------
if(x % y == 0) //its as if the above did not exist. it now tries x%0 and explodes.
cout << "not ok";


one thing to note:
if is a statement, and can produce a compound statement (multiple lines treated as one statement) with {} around it.
else is also a compound statement that can have one or more statements inside it.
else if(something) is NOT a thing, not really. Its a pretty way to write two statements on one line, and its common to see it, but this is really, to the computer, shaped like the following:
1
2
3
4
5
6
7
8
9
10
11
if(something)
{
   statement; //for you, the cout 
   statement2;  //and not present in your code, you only had 1 statement, ok
}
else  //and it so happens in your example that 
//statement 3 is an if statement and statement 4 is the cout
{
  statement3;
  statement4;   
}


many folks claim best practice is to always use {} even for one line compound statements. That way it is clear what is going on in these kinds of blocks and its less error prone if you edit it later and inject another statement that should be in {} but oops.
Last edited on
Consider it re-formatted as:

1
2
3
4
5
6
7
8
	if (x % y == 0) {
		cout << "even";
	} else {
		if (y == 0)
			cout << "cant divide by 0";
		else
			cout << "odd";
	}


First L1 is evaluated. If that is true then L2 is executed. If false then L4 is executed. So L4 is executed only if x % y != 0. L4 tests y and L5 is executed if y is 0 otherwise L7 is executed. So as coded, the test for y == 0 is only executed if x & y != 0 ie. after y has already been used - even if 0.

As has been pointed out above, the test for y == 0 should be done first - before the test for odd/even.

Consider:

1
2
3
4
5
6
7
8
if (y == 0) {
		cout << "cant divide by 0";
	} else {
		if (x % y == 0)
			cout << "even";
		else
			cout << "odd";
	}


Also note that the cout statements are not correct. They are only correct for when y is 2. If y is greater than 2 then you're considering factors - not even/odd numbers. if you use 12 and 5 then 12 is certainly 5, but 12 % 5 is 2 which is not 0 and so it would print odd for 12!

Perhaps consider:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if (y == 0)
		cout << "Can't divide by 0";
	else {
		cout << x << " is ";

		if (x % y == 0)
			if (y == 2)
				cout << "even";
			else
				cout << "divisible by " << y;
		else
			if (y == 2)
				cout << "odd";
			else
				cout << "not divisible by " << y;
	}


Last edited on
Hello. We can easily get tangled up with multiple conditions and statements. I appreciate this alternative more concise which is the same that GeorgeP showed you, but with another semantic. I think that it is better to check before everything if the divider is 0. Then it checks if the modulo defines the number as an even or odd integer. I hope that it helps you ++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>

int main()
{
    std::cout << "Enter numerator : ";
    int x;
    std::cin >> x;

    std::cout << "Enter denominator : ";
    int y;
    std::cin >> y;
    
    y == 0 ? std::cout << "Cannot divide by 0" : x % y == 0 ? std::cout << "even" : std::cout << "odd";

    return 0;
}

Last edited on
Sometimes verbosity (to a point) has its place, multiple if/then conditions and statements tend to make it easier to follow the logic flow. Using the ? operator is compact, but makes readability harder. Especially when chained up.

But it ain't my code, so how things are done ain't really my "gotta do it this way" call.
George P wrote:
Sometimes verbosity (to a point) has its place, multiple if/then conditions and statements tend to make it easier to follow the logic flow.

I agree. Personally I prefer to always use curly brackets with the if statement for consistency even if it's not needed. It makes it easier to read and add statements later if I want. It's like using std:: everywhere, just less thinking to do it always.

1
2
3
4
5
6
7
8
9
10
11
12
if (y == 0)
{
	std::cout << "Cant divide by zero.\n";
}
else if (x % y == 0)
{
	std::cout << x << " _is_ evenly divisible by " << y << ".\n";
}
else
{
	std::cout << x << " is _not_ evenly divisible by " << y << ".\n";
}

Using else if is not harder to read than the alternatives. Not once you get used to it and knows how it works.

Writing the second if statement explicitly inside the else-block like so ...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if (y == 0)
{
	std::cout << "Cant divide by zero.\n";
}
else
{
	if (x % y == 0)
	{
		std::cout << x << " _is_ evenly divisible by " << y << ".\n";
	}
	else
	{
		std::cout << x << " is _not_ evenly divisible by " << y << ".\n";
	}
}

... is good for understanding what is technically going on but I wouldn't normally do it
unless there is some common code that I want to always run when the first if condition is false.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
if (y == 0)
{
	std::cout << "Cant divide by zero.\n";
}
else
{
	std::cout << x << " ";
	if (x % y == 0)
	{
		std::cout << "_is_";
	}
	else
	{
		std::cout << "is _not_";
	}
	std::cout << " evenly divisible by " << y << ".\n";
}
    ^ This kind of code reuse wouldn't have been possible using "else if".
Last edited on
Geckoo wrote:
y == 0 ? std::cout << "Cannot divide by 0" : x % y == 0 ? std::cout << "even" : std::cout << "odd";

Note that the conditional operator (a.k.a. ternary operator) is not designed to be a shorthand if statement.

As an operator it actually has a return type and the intention is to return one of two values depending on the outcome of some condition. This means that both sides of the : needs to be the same type (or have a common type that they can be implicitly converted to).

Geckoo's code just happened to work because the expressions std::cout << "even", std::cout << "odd" and std::cout << "Cannot divide by 0" all have the same return type (std::ostream&).

Something like the following would not work:
1
2
3
4
5
6
7
void print_division_by_zero_error()
{
	std::cout << "Cannot divide by 0";
}

...
y == 0 ? print_division_by_zero_error() : x % y == 0 ? std::cout << "even" : std::cout << "odd";
error: second operand to the conditional operator is of type ‘void’, but the third operand is neither a throw-expression nor of type ‘void’
Last edited on
The other 'gotcha' with using the ternary operator is that each part can only have one statement. If the , operator is used then it's fine with the ? part but care needs to be used with the : part as the : clause is terminated at the , (, has the lowest precedence):

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>

int main() {
	int a { 3 }, b { 4 }, c {};

	c = true ? a = 5, 6 : b = 7, 8 ;
	std::cout << "a: " << a << ", b: " << b << ", c: " << c << '\n';

	c = false ? a = 11, 12 : b = 13, 14;
	std::cout << "a: " << a << ", b: " << b << ", c: " << c << '\n';
}


which displays:


a: 5, b: 4, c: 6
a: 5, b: 13, c: 13


Note the value of c in the 2nd line. it's not 14 as might be expected as the : terminated at b = 13. L9 is executed as:

 
(c = false ? a = 11, 12 : b = 13), 14;


To get the 'expected' result:

 
c = false ? a = 11, 12 : (b = 13, 14);


which displays:


a: 5, b: 13, c: 14


as expected.

Last edited on
I agree with you. This line in the previous code works as expected according to its environment and context. If genkers needed to do something more complex, I should not use a ternary operator instead of a classical if/else statement. According to the genkers question, I exposed this alternative which in the context seemed to me clever ++

In three seperated rooms ask a question to three developers. Come back a few minutes after, and you will get three different answers :)
Geckoo wrote:
I exposed this alternative which in the context seemed to me clever ++

Yeah, but not as "clever" as:
y && (x % y && std::cout << "odd" || std::cout << "even") || std::cout << "Cannot divide by 0";

:-)

My point is just that being "clever" is not necessarily a good thing. Not when there are simpler solutions that doesn't require any cleverness to write, understand and make changes to.
Last edited on
Well for 'clever':

 
std::cout << (y ? &"odd\0even"[0 + !(x % y) * 4] : "Cannot divide by 0") << '\n';

Yes. I noticed that the same goal can have many different code "shapes". Sometimes I watch a tutorial about a lambda C++ process - and from an experienced dev, and I don't like how he elaborates his code. I think that often there is no rule - this shape is good, another one too, maybe this last sucks, but it works...
Furthermore each of us has his preferences and habits. What is wrong? Nothing - while there is readability and optimisation. It is not a question about skill - but only personal perception and vision. How many good answers and codes have we posted in this topic ? Which one is THE best? It's interesting ++
Last edited on
Topic archived. No new replies allowed.