Number of comparisons made? - c

I recently took an exam on C programming that provided these expressions:
int a = 3, b = 10, c = 4, d = 6;
(c >= d) || (a > b)
correction: the first expression is: (c <= d) || (a > b)
(a <= b) && (c == d)
and a question asking how many comparisons were made in each expression. I said there were three comparisons in each expression. In the first are great than or equal to, OR, and greater than. In the second is less than or equal to, AND, and equal to. But according to the grader, there's only one comparison in the first expression and two in the second.
Can anyone please explain why?
Are the integers relevant?

The integers are quite relevant to the context because of short-circuiting operators || and &&.
For || the second comparison is never made if the first expression is true.
For && the second comparison is never made if the first expression is false.
Also, the AND and OR operators themselves are not comparisons.

Given the numbers are:
int a = 3, b = 10, c = 4 , d = 6;
For the first expression (after your update):
(c <= d) || (a > b)
variable c is smaller than d (4 is smaller 6), so that whole expression turns out true whatever the value of the second part is, so that's only 1 comparison.
For the second:
(a <= b) && (c == d)
Variable a is smaller than b, but the program has to check that other part too (in case c is not equal to d and they are in fact different), so here there are also 2 comparisons.

The point of this question was to determine whether you understood the concept of short-circuiting for || and && in C. These are logical connectives, not comparisons.
In your example, you are given:
int a = 3, b = 10, c = 4, d = 6;
You are then asked how many comparisons are performed for:
1. (c <= d) || (a > b)
2. (a <= b) && (c == d)
Both of these expressions contain two comparison operations, but that does not mean those comparisons will actually be performed.
In case (1), it first compares c vs. d, using <=. The result of this is true (i.e. 1). This is all it needs to determine that the result of the || operation will be true (i.e. 1), so it skips the second comparison of (a > b), since it's not needed to obtain the final result. This is called short-circuiting.
In case (2), it first compares a vs. b using <=. The result of this is true (i.e. 1), so it proceeds to the second comparison of (c == d). The result of this is false (i.e. 0), so the final result is false (i.e. 0).
So for (1) it only needed to perform one comparison, but for (2) it needed to perform two comparisons. If the values of the variables are changed, then the number of comparisons could change as well.

Related

Expression using ternary operator

a+=b>=300?b=100:a==100;
If a and b are initialized to 100 and 200 respectively,
what will be the values of a and b after executing the ternary operator?
The answer was a=101, b=200.
How is this possible?
Just add some parentheses and spaces to make it more readable and it should be obvious:
a += ((b >= 300) ? (b = 100) : (a == 100));
(Refer to a C operator precedence table to see why the parentheses can be placed where they are in the above expression.)
So this is essentially just:
a += 1;
The conditional operator has nothing to do with it, basically it just adds clutter here. Your program is equivalent to a += a==100. Which gives a += 1, since the result of == is a boolean 1=true.
First add some spaces to make this statement expression easier to parse visually:
a += b >= 300 ? b = 100 : a == 100;
Then parse it according to the C grammar (which is subtly different from the java or javascript grammars in this particular case):
a +=
(b >= 300) ?
b = 100 :
a == 100
;
Since b = 200, the test b >= 300 evaluates to false and the first branch of the ternary operator is not evaluated, but the second branch is and a == 100 evaluates to 1 as a is indeed equal to 100. The result of the ternary operator, 1, is added to a, hence the new value for a is 101. b is unchanged.

What does b = a && b mean in C?

a=5; b=0; c=1;
if(b=2) c = a++ & b;
else a=4;
b = a && b;
Code is in C. How will this code work? What will a, b, c have values? What
does b = a && b mean in C?
In C, && is the logical AND operator. Therefore a && b is the result of the logical operation "a AND b". Since C originally had no boolean type you often see int being "abused" as an substitute. An int is "true", if it has a non-zero value - and "false" if it is zero. (I think C99 added some boolean type called _Bool, but I'm not exactly sure on that one.) So the result of the expression a && b is either 1, if both a and b are non-zero, or zero if (at least) one of them is zero. That also is what gets assigned to b in b = a && b; then.
However, there also is the binary & operator in C, which is the bitwise AND and does something different than &&. This can also be a source of confusion and unintended errors/bugs in C code, because accidentally missing a & in && changes the behaviour of the compiled code.

Assignment operators in if statement

int a = 0, b = 0, c = -1;
if (b = a || b == ++c )
a+=3;
Why are the values of a,b and c 3 , 1, 0 respectively? More specifically, why is b 1 and not 0?
Because || has higher precedence than =, so it's being parsed as if you'd written.
if (b = (a || (b == ++c)))
This calculates a || (b == ++c). This is true because b == 0 and ++c == 0, so b == ++c is true, and true is 1.
Add parentheses to get what you want:
if ((b = a) || (b == ++c))
But IMHO it's generally best to avoid writing such complex expressions. Do them as separate statements:
b = a;
if (b || b == ++c)
Once you are clear with the precedence of operators,it will be easy for you to tackle such type of questions.Go through this to know about operator precedence in C.
You should see my answer after going through the precedence list because then it will get more easily inside your mind.
Now,coming to your question....
Out of all the operators used in the above code, ++c has the highest precedence.So the value of c becomes 0 and then value of c is compared to value of b here b == ++c which evaluates to true i.e 1 and now || of 1 and a is taken which is 1.
And finally this result 1 is assigned to b.So the overall execution of if statement evaluates to true and value of a is incremented by 3.
Hence finally the value of a=3,b=1 and c=0.

What happens when we arbitrarily use ==?

I tried running the following code in C:
#include <stdio.h>
int main() {
int a = 10, b = 5, c = 5;
int d;
d = b + c == a;
printf("%d", d);
}
I got the output as d = 1. Can someone please explain to me what happens when we use == like this?
ยง6.5.9 (== and !=)-http://c0x.coding-guidelines.com/6.5.9.html
The == (equal to) and != (not equal to) operators are analogous to the relational operators except for their lower precedence.)Each of the operators yields 1 if the specified relation is true and 0 if it is false. The result has type int.
For any pair of operands, exactly one of the relations is true.
So here as b+c is equal to a as both has value 10 therefore it yields 1.
Because b + c is executed first, and after is evaluate comparison with == operator.
In c, addition has higher precedence than ==, so it adds b and c before comparing the result to a, since it is true it results in 1, if it was false it would result in 0.
== is the equal-to operator. It returns 1 if the two sides are equal and 0 otherwise.

Confusion with Associativity of Assignment operator in C

As we all know that Associativity of assignment operator is from right to left but
in the given code output should be zero if we go from right to left but output is 1 .
main()
{
int a=3,b=2;
a=a==b==0;
printf("%d",a);
}
How output is coming out to be 1 if we go by right to letf??
If we go by right to left then (b==0) should be Evaluated first and gives result 0 and then expression (a==0) is Evaluated also gives 0 and at last a's value will be 0.
Assignment is done RTL, but equality (==) isn't.
The statement is actually:
a = ((a == b) == 0)
The right hand side of the assignment is evaluated from left to right. In steps, this is what's happening:
a == b is 0
0 == 0 is 1
1 is assigned to a
Your code is equivalent to :
a = ((a == b) == 0);
Note, this is phrased this way as it was merged from this question. OP asked why a==b==c is equivalent to a==b && b==c in Objective C (which is a strict superset of C). I asked this answer to be migrated since it cites the specificatio where other answers here do not.
No, it is not, it's like (a==b) == c.
Let's look at a simple counter example to your rule:
(0 == 0 == 0);// evaluates to 0
However
(0 == 0) && (0 == 0) // evaluates to 1
The logic is problematic since:
(0 == 0 == 0) reads out as ((0 == 0) == 0) which is similar to 1 == 0 which is false (0).
For the ambitious student
A little dive on how this is evaluated. Programming languages include grammar which specifies how you read a statement in the language. Siance Objective-C does not have an actual specification I'll use the C specificification since objective-c is a strict superset of c.
The standard states that an equality expression (6.5.9) is evaluated as the following:
Equality Expression:
relational-expression
equality-expression == relational-expression
equality-expression != relational-expression
Our case is the second one, since in a == b == c is read as equality_expression == relational_expression where the first equality expression is a == b.
(Now, the actual result number follow quite a way back to a number literal, equality->relational->shift->additive->multiplicative->cast->unary->postfix->primary->constant , but that's not the point)
So the specification clearly states that a==b==c does not evaluate the same way as a==b && b==c
It's worth mentioning that some languages do support expressions in the form a<b<c however, C is not one such language.

Resources