C Program Output Complexity - c

Could you please explain why the following program is giving such outputs?
#include<stdio.h>
int main()
{
int i=-3,j=1,k=0;
int m;
m=++i || ++j && ++k;
printf("i= %d\nj=%d\nk=%d\nm=%d", i,j,k,m);
return 0;
}
Output:
i= -2
j=1
k=0
m=1

Since ++i is essentially true, because it is not 0, therefore the || other part will not be evaluated, since it does not matter at this point, the expression is true. Therefore j and k will not change. true is 1, that is why m is 1.

Related

How the following relational expression written in if-else statement is understood by the C Compiler?

I am unable to understand why this code is displaying 20 30 40 as output. Can anyone explain how the relational expression written in if statement is understood by the C Compiler ?
This is the image of code of the C Program
#include <stdio.h>
int main()
{
int i = 20, j = 30, k = 40;
if (i > j == k)
{
printf("%d %d %d ",--i,j++,++k);
}
else
{
printf("%d %d %d ",i,j,k );
}
return 0;
}
Output:
20 30 40
first thing to consider is operator precedence. the operator > is evaluated before the operator == and it returns a value. in this case, i > j is wrong so it returns zero. then it checks if zero equals to k which is 40 and it isn't. so it goes to else branch.
According operator precedence i > j == k is executed as (i > j) == k
So i > j is executed first, returning a boolean (here, false, ie 0)
And result is compared to k, which is not equal to 0. Condition is than false, so else part of condition is executed

Effect of the ||-operator on ++x

#include<stdio.h>
int main()
{
int i=0, k=0, m;
m = ++i || ++k;
printf("%d, %d, %d\n", i, k, m);
return 0;
}
returns
1,0,1
Why is k = 0 and not 1? what is the effect of the ||-operator on the ++k?
Thanks!
example: https://ideone.com/Fjsbii
In || OR , if first condition is true, it will not check second condition.(it will skip 2nd condition).
As
m = ++i || ++k;
in this condition after ++i, value of i will become 1, as first condition is true, so it will skip second condition. so the operation ++k will not be performed.
And hence k will remain 0.
Same as if you are using && , and first condition is false it will skip second condition. and result will be 0 (false).

Why The Value Of K is Not Increasing in this code?

#include<stdio.h>
int main()
{
int i=-3, j=2, k=0, m;
m = ++i && ++j || ++k;
printf("%d, %d, %d, %d\n", i, j, k, m);
return 0;
}
The value of k increases if i am using a || operator but in case of && the value is not increasing what would be the reason for that , i am very confused.
The out put is -2,3,0,1
You have a test in your code:
m = ++i && ++j || ++k;
When you use multiple tests like this, you will first evaluate ++i && ++j. If it's true, you will never evaluate the || ++k part (because m would be true anyway). This is called lazy evaluation.
If ++i && ++j had been false in your example, k would have been increased because the last part of the test would have been evaluated.
if the operators of “&&”are not zero,it will come true,then the rest part will not be used.
In c,if it is not zero,it is true.
It is called lazy evaluation. false && b is always false whatever b might be.
In your case:
m = ++i && ++j || ++k; evaluates to m = true || ++k; which leads to ++k not being evaluated because of lazyness.
Because ++k is not evaluated as ++i && ++j evaluates to true.
The OR condition is lazily evaluated.
The ++k is never executed, because the first part of the condition is not true.
expressions after || when the values before it evaluate to true will NOT be evaluated.
(c=10)|| (y=20)
In this example, c=10 evaluates to true, due to which y=20 will not be evaluated.

What will the following code evaluate?

I had the following code in a test.I am confused about what (i,j) evaluates,while reading about the "," operator i found that it just evaluates the variables or functions but what does it do here?
main()
{
int i = 10, j = 20;
j = i ? (i, j) ? i : j : j;
printf("%d %d", i, j);
}
(i,j) is exactly the same as just j, because i is just a variable and evaluating it doesn't cause any side effect.
So basically it's just obfuscation here.
in (i,j), the , operator does nothing because the left-hand side expression does not have side-effects.
The assignment is thus equivalent to:
j = i? (j? i : j) : j;
And since i and j are non-zero, to j = i;
The comma operator can be used to link the related expressions together. A comma-linked list of expressions is evaluated left-to-right and the value of the rightmost expression is the value of the combined expression. It acts as a sequence point.
A sequence point guarantees that all side effects of previous evaluations will have been performed, and no side effects from subsequent evaluations have yet been performed.
So, any expression/assignment will be completed & only then will the next expression to the right be evaluated.
For example,
b=(a=4,a=5);
gives,
a=5
b=5
Also, note that the comma operator ranks last in the precedence list of operators in C.
It will print:
10 10
This is because you can break the expression down like:
j = i ? ((i, j) ? i : j) : j;
The comma operator evaluates to the last expression - so (i, j) == j. That is non-zero, so the center expression evaluates to i. 'i' being non-zero, the outer expression evaluates to i, so j is assigned to the value of i.
This is equivalent to:
int main() {
int i = 10, j = 20;
if (i != 0) {
(void)i; // Do nothing with i.
if (j != 0) {
j = i;
} else {
j = j; // Assign j to itself.
}
} else {
j = j; // Assign j to itself.
}
printf("%d %d", j);
}
Looks like typical software written test question. It is used to confuse candidates. As suggested by sepp2k above it is same as j. One more interview question
i = 10; j = 20;
1) k = i,j;
2) k = (i,j);
Answer for 1 will be 10 and answer for 2 will be 20. As coma operator doesnt do anything. I hope this will clear more.
It's not really doing anyting. It's evaluating the expression i, discards the result, evaluates the expression j and returns the result.
As evaluating the expression i has no side effects, (i,j) has the same meaning as just j.
main()
{
int i = 10, j = 20; // i=10, j=20
j = i ? /*if i */ ( (i, j) ? /* if j (1) */ i : /* else */ j ) : /* else */ j; // Added parenthesis and see (2)
printf("%d %d", i, j); // Will therefore print 10 10
}
it is equivallent to if(j) because (i,j) evaluate to j because i has no side effect.
all ifs evaluate to true because i and j are ints and are non zero

Need some help understanding a weird C behavior

This part of my code works fine:
#include <stdio.h>
int main(){
//char somestring[3] = "abc";
int i, j;
int count = 5;
for((i=0) && (j=0); count > 0; i++ && j++){
printf("i = %d and j = %d\n", i, j);
count--;
}
return 0;
}
The output as expected:
i : 0 and j : 0
i : 1 and j : 1
i : 2 and j : 2
i : 3 and j : 3
i : 4 and j : 4
Things get weird when I uncomment the char string declaration on the first line of the function body.
#include <stdio.h>
int main(){
char somestring[3] = "abc";
...
}
The output:
i : 0 and j : 4195392
i : 1 and j : 4195393
i : 2 and j : 4195394
i : 3 and j : 4195395
i : 4 and j : 4195396
What's the logic behind this? I'm using gcc 4.4.1 on Ubuntu 9.10.
j never gets initialised, because of the short-circuiting behaviour of &&. Since (i=0) evaluates to false, (j=0) never gets executed, and hence j gets a random value. In the first example, that just happens to be zero.
You should say i=0, j=0 to achieve what you want.
The i++ && j++ has the same problem; it should be i++, j++.
Also, this:
char somestring[3] = "abc";
is reserving one too few bytes, because of the trailing NUL character in the string - you need four bytes. But if you're not going to modify the string, you don't need to specify the number of bytes - you can simply say this:
char *somestring = "abc";
instead.
If you use &&, only the first argument gets evaluated if it's false. i=0 is false, so j doesn't get set to 0. You should use the komma operator:
for((i=0) , (j=0); count > 0; i++, j++){ [...]
for((i=0) && (j=0)... seems to be incorrect already.
i=0 has already value of 0, so the evaluation of j=0 is not needed, so it is skipped.
(i++) && (j++) seems to be incorrect for the very first iteration, too, by the same reason.
You are using (i==0) && (j==0) to initialise both variables in your loop.
However, a property of && is that if the first operand evaluates to FALSE (i.e. 0), the second operand is never executed. So, as i is 0, j is left uninitialised. In your first run, you were simply lucky that it happened to contain the value 0.
Your variables i & j aren't initialized. What do do mean by (i=0) && (j=0)?
The compiler will make a shortcut and only assign i=0 j remains uninitialized with the effect you described.

Resources