I have come across a piece of code. I am wondering why is the below code returning the value of x as four and not zero.
if(2<1);
else x = (2<0) ? printf("one") : printf("four");
printf("%d",x);
output is 4
Please instead of trying to read the unreadable, make it readable and enjoy
if (2 < 1);
else
x = (2 < 0) ? printf("one") : printf("four");
printf("%d", x);
Of course 2 < 1 is false, and 2 < 0 is false again so the return value of printf("four") which is 4 because "four" has 4 characters is assigned to "x".
So the output should be
four4
Function printf returns the number of printed characters.
Because in this conditional operator
(2<0)?printf("one"):printf("four")
the condition (2<0) is false this expression printf("four") is evaluated and its value is equal to 4 - the number of the outputed characters.
From the description of function printf (the C Standard, 7.21.6.3 The printf function)
3 The printf function returns the number of characters
transmitted, or a negative value if an output or encoding error
occurred.
I think that the reason of the confusion is the assignment operator before the
conditional operator. However the assignment operator has lower priority compared with the conditional operator. So in fact you have
else x = ( (2<0) ? printf("one") : printf("four") );
Related
int a = 0;
a = 7 > 2 ? printf("6") : printf("4");
printf ("%d",a);
The ouput of this block is :
61
I tried the code in its expanded form
int a = 0 ;
if(7>2)
{
printf("6");
}
else
{
printf("4");
}
printf("%d",a);
Here I the output was:
60
I would like to get an explanation on why the output differs.
The first statement assigns the return value of printf to a. printf returns the number of bytes that were written. In this case that is 1. In the second expanded version, a is not assigned. Here is an actually equivalent version to the original:
int a = 0;
if(7>2)
{
a = printf("6");
}
else
{
a = printf("4");
}
printf("%d",a);
They are completely different.
To make them identical:
int a = 0 ;
if(7>2)
{
a = printf("6");
}
else
{
a = printf("4");
}
printf("%d",a);
cond?val1:val2 is the ternary operator. It is not supposed to be a control structure (like if, for or while). It is an operator. To build expression (things that have a value) rather than instruction (things that does things).
Frontier is fuzzier in C than in other languages, because instructions have a value (including void) and expression have potential side-effects.
But, well, you use cond?val1:val2 when you want to get the result. As you did, since you assigned the result to a.
And the result here is the result of printf("6"), that is 1, since printf returns the number of printed characters. Note that there is no real doubt, since even if 7 were smaller than 2, result would still have been 1. Since you print that result, it is normal to have a 1 printed after the 6.
(Just to be clear, even if I assume you know that already, what you did is print string "6" and then number 1, which is the result of 1st printf. Exactly as if you did
printf("%d",printf("6"));
which 1st prints "6", then pass the result to the outer printf to print what the inner printf returned, that is 1)
In your second code, you do nothing to change a's value, and you ignore the result of printf.
Your examples aren't equivalent. To be equivalent, the second one should say a=printf(... everywhere. After which a will get assigned the number of characters printed, 1.
The conditional operator (e1 ? e2 : e3) is not a "short version of if condition", although it has some similarities with an if ... else construct. The conditional operator yields a value (which you assign to a in your first example); an if ... else construct does not have a value.
So, your first example assigns a value to a, because it is written in the form of an assignment statement; that value is the 1 returned by the call to the printf function. To get similar behaviour in your second example, as others have said, you need to also assign the value returned by printf inside the if ... else blocks.
Alternatively, to make the first case work like the second, you can skip the assignment and use the conditional operation to determine the argument that is passed to the printf call:
int main(void)
{
int a = 0;
printf(7 > 2 ? "6" : "4");
printf("%d", a);
return 0;
}
Code
#include <stdio.h>
int main() {
int i;
for (i=1; i<=10; i++) {
(i % 2) ? printf("%d is odd\n", i) : printf("%d is even\n", i);
}
}
Result
1 is odd
2 is even
3 is odd
4 is even
5 is odd
6 is even
7 is odd
8 is even
9 is odd
10 is even
In the above C program, why it still works fine even though the conditional expression only states i%2 and not i%2!=0 ?
In C, integers can be used in a Boolean context, and zero represents false while non-zero represents true.
That's why your code works. The expression num % 2 will be 0 (the single false value) for an even number and 1 (one of the many possible true values) for an odd number.
The following expressions would all work for detecting an odd number:
num % 2
(num % 2) != 0
((num % 2) != 0) != 0
... and so on, ad untilyougetboredum (like 'ad infinitum' but with limits).
Having said that, I don't really consider it a good idea to do it this way, code should express intent as much as possible and the intent here should be to choose the path of execution based on a comparison. That means, if you're looking for an odd number, you should use something like (num % 2) == 1.
You also don't need a separate printf call in each of those code paths:
printf("%d is %s\n", num, ((num % 2) == 1) ? "odd" : "even");
You'll notice I've also used num instead of i. This is simply a style thing of mine, related to the afore-mentioned intent. If the variable is only used as an index, I'm happy to use the i-type variables(a) but, the second it gains a semantic property (like a number being checked for oddity), I tend to use more descriptive names.
I have no issue with people using simple variable names, I just prefer more descriptive ones in my own code.
(a) Actually, I'd probably use idx in that case but that's being too CDO(b), even for me :-)
(b) OCD but in the right order :-)
C doesn't have a dedicated boolean type. It uses int value as boolean. That is 0 is considered false and any non zero value is treated as true.
Try printing some conditions
printf("%d",5==5);
printf("%d",1>3);
This will output
1 and 0.
C always uses 1 to denote true. But any other non-zero value would work as well when using in conditions.
if(6+1)
printf("TRUE");
Will print TRUE.
This is also the reason we can use this form of while loop:
int i= 10;
while(i--){
printf("%d",i);
}
Will print 9876543210. Notice it stops when i becomes 0, which is false.
Now back to the question, i%2 would always result in either 0 or 1. In case of 1(true) the first statement is run while in case of 0 (false) the second statement is run.
This question already has answers here:
What does the comma operator , do?
(8 answers)
Closed 3 years ago.
One of my friends ask me about this code and I and he are unable to find out, what is happening in the if condition. Can you guys explain how this condition works?
int main()
{
int i;
if (i = (1, 2, 0))
printf("Mehrose");
else
printf("Hello ");
printf("%d\n", i);
return 0;
}
The output for this code is Hello 0
First, formatting as the compiler sees the code we get:
int main(void)
{
int i;
if(i=(1,2,0))
printf("Mehrose");
else
printf("Hello");
printf("%d\n",i);
return 0;
}
The if statement can be broken down:
Comma operator , is evaluated first, left-hand side of the operator is discarded. This repeats for each operator:
if(i=(1,2,0))
if(i=(2,0))
if(i=0)
The assignment operator = assigns a value of 0 to i, and returns the right-hand side of the expression:
if(0)
Recall that 0 is evaluated as false (is "falsy") and 1 is evaluated as true (is "truthy"). Thus the first condition fails and the second block is executed. "Hello" is printed to the standard output stream, followed by "0".
In the expression,
i=(1,2,0)
you're using the comma operator, which evaluates all its operands and yields the result of its rightmost operand - which is 0 here.
So 0 is assigned to i.
So it's equivalent to if (i = 0), which assigns 0 to i and yields the value of i which is false and thus it prints the string in the else branch.
i have conditional operator's statement and i have no idea how its works.
there are two questions:
Question 1 : what will the following statement do :
quotient=(b==0)?0:(a/b) \\ here a,b,quotient is integer
Question 2 : Can preceding statement be written as follow ?
quotient=(b)?(a/b):0;
NOW MY QUESTION IS :
Question:1 :: we do not know b's value then how can we check this condition(b==0)
Question 2:: what (b) indicate ?
The conditional check in the C ternary conditional operator is an implicit comparison to not-zero.
In other words
quotient = b ? a / b: 0;
is the same as
quotient = b != 0 ? a / b : 0;
or the absurd
quotient = (b != 0) != 0 ? a / b : 0;
This is consistent throughout C, e.g. in an if, a for stopping condition, a while, &&, ||, &c.
If you try
int b = 0;
if (b) {
printf("Hello World");
}
Does not print anything while :
int b = 1;
if (b) {
printf("Hello World");
}
Prints Hello World. Why ? Because 0 is false and 1 is true.
If you do quotient=(b)?(a/b):0; it is interpreted to is b true ? or in other words is b evaluated to 1 (while, again, 1 is true and 0 is false)
C did not originally have a Boolean type. Conditionals are simply int values in C. 0 is false, and any other value is truthy. If the type of b is int, or it can implicitly convert to int, then (b) ? foo : bar does the same thing as (b == 0) ? bar : foo. (However, b==0 will evaluate to 1 or 0, whereas b by itself might have other nonzero values that if or ? consider truthy.)
This question already has answers here:
Why is "i" variable getting incremented twice in my program?
(8 answers)
Closed 7 years ago.
Why outputs of i and j in the following two printf()s are different?
#include <cstdio>
#define MAX(x,y) (x)>(y)?(x):(y)
int main()
{
int i=10,j=5,k=0;
k==MAX(i++,++j);
printf("%d %d %d\n",i,j,k);
i=10,j=5,k=0;
k=MAX(i++,++j);
printf("%d %d %d\n",i,j,k);
return 0;
}
I think only k should differ, but it is showing different output for all, i, j and k, in printf() statement. What is the reason?
Output :
11 7 0
12 6 11
k==MAX(i++,++j); is translated to:
k==(i++) > (++j) ? (i++) : (++j);
/* 2 1 3 : Precedance */
In your case i = 10 and j = 5, so the comparision would be 10 v/s 6 which would be true or 1 with side effect i becomes 11 and j becomes 6. (Recall that: Macros are not functions)
As k = 0 and not equal to 1, k==(i++) > (++j) would be false and ++j would be executed. Causing j to be incremented to 7.
In latter case, there is no modification to the value of variables.
When can I expect same output in both case?
Even if you change the macro with a function, your arguments have the side effects, which would cause the output 11 6 for i j, so you are changing the variables using ++ operator, don't expect both statements to have the same values.
i++ and ++j both increment i and j, so you change their values before printing.
You have side-effects.
MAX(i++,++j)
is expanded to
(i++)>(j++)?(i++):(j++)
And i is modified twice in the macro call.
Moreover, you have to add parens to your macro definition:
#define MAX(x,y) ((x)>(y)?(x):(y))
Let's analyse the output from first printf()
Assuming you meant = instead of == in your code,
k==MAX(i++,++j);
gets translated to
k = (i++) > (++j) ? (i++): (++j)
which gets evaluated changing all the values of i, j and k.
Even if you meant ==, as mentioned in the answer by Mr. Mohit Jain, you'll face similar issue with precedence.
Have a look at operator precedence for better understanding.
Let's analyse the output from second printf()
In the second printf() statement, you're re-setting the values of i, j, k and not using the MACRO. So, those values will get printed. Simple.
So, TL;DR, before first printf(), the MACRO changes all the three values for i, j, k. So, your output for first and second printf() differs for all the three variable values.
FWIW, if you meant the MACRO to behave as a ternary conditional expression , you need to change your MACRO definition to
#define MAX(x,y) ( (x)>(y) ? (x) : (y) )
To avoid issues with operator precedence after MACRO expansion.
The macro is a red herring. OP did not ask about k but "Why output of i and j in following two printf are different?" The answer is because i and j have been modified between setting their values and printing, in the first case, but not in the second case.