Why my for loop works with "&&" and not with "," - c

I am stuck at this exercise of c program that have a comma in C for loop if, I replace , with && it works same
for(i = 5, j = i - 1 ; i > 0 , j > 0 ; --i ,j = i - 1)
printf("\n%d",i);
In this loop I get how for( i = 5,j = i - 1 ; ? ; --i ,j= i - 1) but the part where ? is there I don't get how that is working 1,1 = true ? 1,0 = false ? C is trick that's why love it 3> can you explain me how that part is working

but the part where ? is there i don't get how that is working
The comma operator in C evaluates the expression before the comma, and then the expression after the comma, and then returns the value of the expression after the comma. So the value of the expression 1, 0 in C is 0. The result of 1, 1 is 1. The result of foo(x), bar(x) is the value of bar(x).
This doesn't come up very often because in practice, the comma operator isn't used all that often. It can be handy in a few cases, such as in for or while loops where you might want to manipulate more than one variable each time through the loop. But in general, combining expressions with the comma operator just creates uncertainty about how those expressions will be evaluated, what the result of the overall expression is, and so on. Whenever possible, separate the expressions and execute them one at a time.
Why my for loop works with "&&" and not with ","
The && operator combines (using logical AND) the result of both expressions instead of throwing the result of the first expression away, so depending on the expression you can get a different result than you do with ,. 1 ? 0 and 1 ? 1 give the same result for both , and && because the result of the && depends on the second expression in both cases. But 0 ? 0 and 0 ? 1 will give different results — , again returns the value of the second expression, and && returns 0 because both expressions are considered and 0 AND anything is 0.

; i > 0 , j > 0 ;
Formally, the "," is know as the Comma operator:
The comma operator expression has the form
lhs , rhs
where
lhs - any
expression rhs - any expression other than another comma operator (in other words, comma operator's associativity is left-to-right)
First, the left operand, lhs, is evaluated and its result value is discarded. Then, a sequence point takes place, so that all side effects of lhs are complete. Then, the right operand, rhs, is evaluated and its
result is returned by the comma operator as a non-lvalue.
More informally, in ;i > 0 , j > 0; the i > 0 is evaluated and ignored to determined if the loop should or not terminate, and then j > 0 is evaluated and its value is used to determined if the loop should (or not) continue.
I am stuck at this exercise of c program that have a comma in C for
loop if, I replace , with && it works same
In this case it works the same with "," or "&&" because when i = 1 then j = 0 and consequently j > 0 evaluates to false and you exit the loop. When j > 0 evaluates to false i > 0 also evaluates to false, hence the reason why in your case it is the same using i > 0 && j > 0 or i > 0 , j > 0. Nevertheless, i > 0 && j > 0 and i > 0 , j > 0 are not semantically the same.
In your case:
for(i = 5, j = i - 1 ; i > 0 && j > 0 ; --i ,j = i - 1)
actually, you can simplified i > 0 && j > 0 to just i > 0 since whenever j > 0 evaluates to false i > 0 will also evaluate to false since j = i - 1.

Related

Comma(,) operator suppress the precedence of parentheses in C

I just started reading C.
Situation :
x = ( y = 3, ( z = ++y + 2 ) + 5 )
It is evaluating y = 3 first then evaluating ( z = ++y + 2 )
My Problem :
It should first evaluate ( z = ++y + 2 ) because the precedence of comma(,) is much less than parenthesis
My way of Thinking :
Due to precedence we select outer parenthesis
Then we need to evaluate parenthesis
Under this (parenthesis) I again started applying precedence rule
So I took inner bracket to evaluate first
P.S. :
This is not a Duplicate
I have already gone through these links but still unable to understand
Behavior of comma operator in C
C comma operator
What does the comma operator , do?
https://learn.microsoft.com/en-us/cpp/cpp/comma-operator
Uses of C comma operator
https://en.wikipedia.org/wiki/Comma_operator
You're confusing operator precedence with order of evaluation.
Operator precedence dictates how subexpressions are grouped. It does not dictate when each operand is evaluated.
The comma operator has a sequence point between its left operand and its right operand. In the case of y = 3, ( z = ++y + 2 ) + 5, that means that y = 3 must be fully evaluated before ( z = ++y + 2 ) + 5 can be evaluated.
Note also in the subexpression ( z = ++y + 2 ) + 5 that there is no guarantee that everything inside the parenthesis are evaluated before everything inside. You only know that ( z = ++y + 2 ) and 5 are evaluated before ( z = ++y + 2 ) + 5 is evaluated. If for example you had (z = ++y + 2) + y this would invoke undefined behavior because the second y could be evaluated before or after the side effect of ++y.
As another example, if you had x = (func1() + 3) + func2(), either func1 could be called first or func2 could be called first since the order of evaluation of operands is unspecified. If both of those functions modified the same global variable, you wouldn't be able to reliably know the value of that variable.
Precedence and evaluation order are different things. In the expression (a*b) - (c+d), the compiler is free to evaluate (c+d) before (a*b), even though multiplication has higher precedence than addition. But in the expression a,b, as well as the code a;b, the compiler is required to sequence the computation of a before the computation of b.
You are confused between Precedence and Order of Evaluation. Precedence is the priority for grouping different types of operators with their operands.
The comma (,) operator constitute Sequence Point and therefore guarantee a particular order of evaluation for their operands which is left to right.
Order of evaluation
Ordering
......
If a sequence point is present between the subexpressions E1 and E2, then both value computation and side effects of E1 are sequenced-before every value computation and side effect of E2
Rules
.....
2) There is a sequence point after evaluation of the first (left) operand and before evaluation of the second (right) operand of the following binary operators: && (logical AND), || (logical OR), and , (comma).
In this expression:
x = ( y = 3, ( z = ++y + 2 ) + 5 )
First y = 3 will be evaluated first and then ( z = ++y + 2 ) + 5.

{{ !$last && ', ' || '.'}} is this working as ternary operator or if-else condition

I am developing an application using AngularJS. I have used the if-else conditions and ternary Operator. Once I found a code {{ !$last && ', ' || '.'}} to put the , after each entry and . at the end. It is working fine, but I have a confusion about its working process. Is it working like an if-else condition or ternary operator? My whole example is as below.
<span data-ng-repeat="allSuppliers in vm.allIncentiveSuppliers | unique:'supplierName'">
{{allSuppliers.supplierName }}{{ !$last && ', ' || '.'}}
</span>
It is a form of ternary operator. && returns first operand if it is a falsy value and second operand if first operand is truthy e.g. 1 && 3 will return 3 but 0 && 3 will return 0. Second operator is not evaluated if first is falsy. || is similar but returns first operand if it is truthy and second operand if first is falsy.
So basically cond && val1 || val2 is equivalend to cond ? val1 : val2 under condition that val1 is truthy value. If this is not the case e.g. cond && 0 || 1 this will always return last value 1 in this case.
For readability reasons you should always prefer ternary opreator ?: than boolean shortcircuting operators.
Be wary that this won't work in languages where && only return a boolean value, like C and PHP. There, 3 && 4 returns 1/true, so your code won't work as expected.
In JS, && returns the first truthy value or false. So 3 && 4 returns 3 and your code works fine.
Another thing to be careful of is when you want &&'s right-hand-side to be falsy:
cond() && false || true will always return true.
A ternary operator is basically a shorthand for if-else condition. So the syntax you provided can be termed as both.
Other varients of that expression can be:
{{ !$last ? ', ' : '.'}}
Or
{{ $last ? '.' : ','}}

Ternary operator usage issue

I have used ternary operator before for a condition like if-else but here it's different i.e. not checking a condition before ?.
printf( "%d\n",10?0?5:11:12 );
Edited:
So,how will it evaluate 11 as by compiler because i don't see any condition before first ?.
The expression 10 ? 0 ? 5 : 11 : 12 is parsed this way: 10 ? (0 ? 5 : 11) : 12. So this means that in the first test, since 10 is true, it will evaluate 0 ? 5 : 11, which evaluates to 11 since 0 is false.
It will be solved in this manner
printf("%d\n",10?0?5:11:12);
i.e 10?(0?5:11):12
First solve 0?5:11 as 0 means false so it will return 11.
Now Condition will be like 10?11:12
As 10 is non zero condition will be true, so it will return 11.
printf( "%d\n",10?0?5:11:12 ); is of syntax (condition)?TRUE:FALSE
There are two ternary operators. For better readibility and understanding, let's put it this way
(10 ? (0 ? 5 : 11) : 12)
So, the inner condition, (0 ? 5 : 11) checks whether 0 is TRUE or FALSE. It is a FALSE value, [yes, zero is considered as FALSE and non-zero value is considered as TRUE and both are perfectly valid sysntax for conditional check]. so , it evaluates to 11.
Now, for the outer condition, the code appears as (10 ? 11 : 12). Following simmilar logic, 10 being a TRUE, it returns 11. which is passed to printf(). That's how you get your output.
Your expression is parsed as 10?(0?5:11):12 and the inner conditional expression (0?5:11) is constant folded to 11 then the entire expression is constant folded to 11 (since 10 is true since non-zero).
Notice that a condition (such as the first test operand of a ?: ternary conditional expression) can be any scalar, non-void, expression. In particular 11 is a valid condition.
What is going on is in pseudo code a little bit:
(But in the ternary operator first the inner ternary condition get's "calculated")
if (10) { //true
if(0) { //false
print 5
} else {
print 11 //Output 11
}
} else {
print 12
}
Or as a ternary operator but a little bit more readable:
(10 ? (0 ? 5 : 11) : 12)

JavaScript null and plus (+) operatior

I am trying to understand the core of JavaScript. I know it doesnt have much implementation value. If you dont want to answer, just leave it. However, I will appreciate if you could help to understand the following type coercion while applying addition(+).
1.
null + null // 0
2.
null + undefined; // NaN
3.
null + NaN; // NaN
4.
1 + null; //1
5.
true + null; //1
6.
true + [null]; //"true"
I know null is an empty or missing object. I will appreciate, if you can explain steps in type coercion or unary(+) operation here. Thanks for reading the question.
This is covered in 11.6.1 The Addition operator ( + ) - feel free to read it and follow the rules.
The first five cases can be explained by looking at ToNumber:
Value ToNumber(Value)
--------- ---------------
null 0
undefined NaN
NaN NaN
1 1
true 1
And 0 + 0 == 0 (and 1 + 0 == 1), while x + NaN or NaN + x evaluates to NaN. Since every value above is also a primitive, ToPrimitive(x) evaluates to x (where x is not a string) and the "string concatenation clause" was not invoked.
The final case is different in that it results from the ToPrimitive (which ends up calling Array.prototype.toString) on the array which results in a string value. Thus it ends up applying ToString, not ToNumber, and follows as such:
true + [null]
=> true + "" // after ToPrimitive([null]) => ""
=> "true" + "" // after ToString(true) => "true"
=> "true" // via String Concatenation
Conclusions derived from analysing results
true coerces to 1 (and false to 0).
null coerces to 0.
undefined coerces to NaN.
Arrays behave as:
under unary + (+[]):
their first element if length is 1
0 if they're empty
NaN if there's more than 1 element
under binary + (1+[]):
coerces both operators to strings and joins them
All operations on NaN return NaN

AND/OR based on variable value in stored procedures

I would like to use AND/OR between the conditions in a stored procedure, and the decision is dependent on the parameter value whether it was 0 (AND) or 1 (OR)
Can anyone help me with this please, i guess this is an easy thing to do but i can't seem to figure it out. Thanks
The easiest way (on first glance) would be to concatenate the query string using dynamic SQL, but dynamic SQL has its issues.
See The Curse and Blessings of Dynamic SQL for an in-depth explanation.
So I would try to avoid dynamic SQL, which is no big deal if your queries are not too complex.
The easiest way is just to fire two different queries depending on the parameter value:
CREATE PROCEDURE spTest
#AndOr bit
AS
BEGIN
if #AndOr = 0 begin
select * from YourTable where foo = 1 and bar = 2
end
else begin
select * from YourTable where foo = 1 or bar = 2
end
END
This is of course an example with a very simple query.
If you have lots of queries, or if your queries are very complex, this might not be the best solution because it forces you to duplicate all queries...but as always, it depends :-)
You can implement your logic on a CASE statement. Something like this:
CREATE PROCEDURE dbo.MySP #OrAnd BIT
AS
BEGIN
SELECT *
FROM MyTable
WHERE CASE WHEN Condition1 AND Condition2 AND #OrAnd = 0 THEN 1
WHEN (Condition1 OR Condition2) AND #OrAnd = 1 THEN 1 ELSE 0 END = 1
END
If you convert the simple conditions' boolean results into numeric ones (0 or 1), you will be able to use your parameter in the following way:
(
(CASE WHEN condition1 THEN 1 ELSE 0 END ^ #AndOr)
&
(CASE WHEN condition2 THEN 1 ELSE 0 END ^ #AndOr)
) ^ #AndOr = 1
Here #AndOr is your parameter, ^ is the Transact-SQL bitwise exclusive OR operator, & stands for the bitwise AND in Transact-SQL, and the CASE expressions are used to convert the boolean results into 0 or 1.
If #AndOr = 0 (which means we want AND between the conditions), the above expression effectively boils down to this:
case1 & case2 = 1
because X XOR 0 yields X and so neither individual values of case1 and case2 nor the entire result of the & operator are not affected by the ^ operators. So, when #AndOr is 0, the result of the original expression would be equivalent to the result of condition1 AND condition2.
Now, if #AndOr = 1 (i.e. OR), then every ^ operator in the expression returns the inverted value of its left operand, in other words, negates the left operand, since 1 XOR 1 = 0 and 0 XOR 1 = 1. Therefore, the original expression would essentially be equivalent to the following:
¬ (¬ case1 & ¬ case2) = 1
where ¬ means negation. Or, converting it back to the booleans, it would be this:
NOT (NOT condition1 AND NOT condition2)
According to one of De Morgan's laws,
(NOT A) AND (NOT B) = NOT (A OR B)
Applying it to the above condition, we get:
NOT (NOT condition1 AND NOT condition2) = NOT (NOT (condition1 OR condition2)) =
= condition1 OR condition2
So, when #AndOr is 1, the expression given in the beginning of my answer is equivalent to condition1 OR condition2. Thus, it works like expected based on the value of #AndOr.
Having the input parameter you can use a IF clause to make different selects.
If input parameter = 0 make the AND conditions, otherwise make the OR conditions.
I can't see any particular elegant way to do it. So here's the straightforward approach
create function myfun (#parm1 int, #parm2 int, #andor int) returns int
begin
if (#andor = 0 AND #parm1 = 99 AND #parm2 = 99) return 1
else if (#andor = 1 AND (#parm1 = 99 OR #parm2 = 99)) return 1
return 0
end
go
select dbo.myfun(99,98,0) -- AND condition should return 0
select dbo.myfun(99,98,1) -- OR condition should return 1
select dbo.myfun(98,98,0) -- AND condition should return 0
select dbo.myfun(98,98,1) -- OR condition shoujld return 0

Resources