so after
#include <stdio.h>
int main(int argc , char *argv[])
{
int n;
n = _strlen_recursion("Corbin Coleman");
printf("%d\n", n);
}
int _strlen_recursion(char *s)
{
static int count = 0;
count++;
return (count), count = 0;
}
where the comma operator is in action
0 can be seen on screen. Why?
So the real question is : does return have () overload as say sizeof does?
return is not similar to sizeof. The operand of sizeof is either a type in parentheses or an expression.
A return statement has only an expression (or nothing). Parentheses are not part of the grammar of a return statement. Parentheses may be present only because they are part of the expression.
In return (count), count = 0;, the expression is (count), count = 0. That is a comma expression. It evaluates (count), discards the resulting value, then evaluates count = 0. The value of that is the value assigned, 0, so that is the value of the comma expression, so 0 is returned.
In the return statement return (count), count = 0;,
attr(optional) return expression(optional) ; (1)
The expression is (count), count = 0, as comma operator, the 1st operand (count) is evaluated and the result is discarded, then the 2nd operand count = 0 is evaluated, its value 0 is returned as the return value of the omma operator, and returned as the return value of _strlen_recursion() later.
The comma acts as a binary operator in C, the same way +, -, &, and all the other operators in C do. It takes two operands and acts as a sequence point. The left operand, (count) in your example, is evaluated, the result is then discarded. From here, the right operand, count = 0, is evaluated and its return value is returned. In your example, the left operand has no side-effects, so it is essentially useless. The line return (count), count = 0; is equivalent to the two lines
(void) (count);
return count = 0;
Note that count = 0 is an assignment, and in C, assignments return the value assigned, so in this case 0 is returned form this expression, and ultimately the function.
Related
I have these lines of code:
int a = 10, b = 1;
a = --b ? b : (b = -99);
cout << "a= " << a << "b= " <<b<< endl;
the output gives me b=-99 as a is not equal to 0(which makes senses) but it also changes the value of a to a=-99 how?
Your code is the equivalent of:
int a = 10, b = 1;
b -= 1; // b == 0
int x;
if (b != 0) x = b;
else x = b = -99;
a = x;
// at this point a and b have the same value
The ternary operator works as follows:
if (--b != 0) { // b is not 0 means true
a = b;
} else { // b is 0 means false
a = (b = -99);
}
You assign the value to a, so --b is 0 which is considered as false. Then you assign to b value -99 and afterward, you assign b to a. So, both variables have their values -99 in the end. Hope it will help you.
According to ternary operator, The first argument is a comparison argument(condition), the second is the result upon a true comparison, and the third is the result upon a false comparison.
So In Your case, the condition is not True, So the false statement get executed.
so now b has -99.
In c, c++, java we've seen, assigns the value of the variable
a = b = -99
In this, the both a & b gets the same value. Like this, ternary operator also assigning the value of the variable from false statement .
(a = (b = -99 ))
I think what is confusing you here is that, in C, an expression (such as b = -99) has both consequences and a value. The consequence of b = -99 is that b is assigned the value of -99; but note also that the value of this expression is -99.
Thus, in a ternary expression, which takes the general form:
lhs = test ? v_if_true : v_if_false;
the expression test is first evaluated and lhs is assigned either v_if_true (if test evaluates to non-zero) or v_if_false (if test evaluates to zero).
In your case, test is --b. The consequence of this expression is that the value of b is decreased by one, and the value of the expression is the resulting (modified) value of b (which will be zero in your code).
So, your ternary expression assigns to a the value of the v_if_false expression which is b = -99 (the brackets you give add clarity to the expression, but don't change its evaluation). So, as mentioned above, this expression (as well as modifying b) also has a calculated value of -99, which is then given to a.
If you wanted to leave a unchanged in the case when the v_if_false expression is executed, then you could do this using the comma operator, as follows (though I would not recommend using such code):
a = --b ? b : ((b = -99), a); // If --b == 0, this becomes a = a
This works because the value of an expression containing the comma operator is the value of the sub-expression after (to the right of) the comma.
Found as a user submission on leetcode for the problem Plus One.
vector<int> plusOne(vector<int>& digits) {
for (int i=digits.size(); i--; digits[i] = 0)
if (digits[i]++ < 9)
return digits;
digits[0]++;
digits.push_back(0);
return digits;
}
Normally there's something in the conditional like i >= 0; How is this for loop terminating and not accesing some -i element?
A for loop terminates when the second expression is false or when contextually converted to a bool value produces false. In C++, 0 is contextually converted to false; all other integers convert to true in a bool context. (Thanks to M.M.for the link.)
So at the beginning of each loop the expression i-- is evaluated. It's just an expression, so it will produce a result. If the result it produces is zero, the loop will end. If you haven't seen this expression before, here is how it works:
It both decrements i and returns the original value of i before it was decremented. So if i were 5, evaluating i-- will have the "result" 5, but as a side effect, i will be 4 after the evaluation.
The big picture: i is decremented by 1 each time, so assuming it starts off positive, it will get down to 0, at which time evaluating i-- will produce 0.
I am trying to figure out what is going on with the "and" statements in the return line from this sample of code, could someone please tell me what the purpose of putting these "and" statements in the return of a function is?
if just one of them is false would it return false to the function that called it?
return !UsedInRow(board, row, num) && !UsedInCol(board, col, num) &&
!UsedInBox(board, row - row % 3 , col - col % 3, num);
It's equivalent to
bool a;
a = UsedInRow(board, row, num);
if (a) return false;
a = UsedInCol(board, col, num);
if (a) return false;
a = UsedInBox(board, row - row % 3 , col - col % 3, num);
if (a) return false;
return true;
due to the short-circuiting nature of the && and the fact that evaluation is from left to right.
(This holds true even if the function parameters are passed by reference and modified in the functions, as && is a sequencing point.)
if just one of them is false would it return false to the function that called it? The answer is yes.
This will stop the computation of further functions as False AND any value => False.
This will return True or False based on the values returned by the UsedIn* functions.
This is to check whether the number 'num' can be inserted in Suduko. This will check whether the number can be inserted in a given cell provided it is present in that row, column or the box.
UsedInRow and UsedInCol are both functions returning a bool (or a type that can be converted to bool). The && operators just chain the return values of the functions together that results into a final bool result that yields either true or false which is then returned.
Note that not all functions in this case have to run because of short-circuit evaluation, that is, if the result one of the three boolean expressions is false then (because of the &&) the result can't possibly be true and thus functions that are not yet evaluated won't be evaluated.
Yes, it works exactly like in an if statement. If any of the Used functions return true then the whole return value will evaluate to false.
if !UsedInRow(board, row, num) this executes to return false then return statement will automatically return flase without executing other two statements
if !UsedInRow(board, row, num) returns true only then second statement !UsedInCol(board, col, num) will get executed and now if it returns false then the return statement will return false otherwise third statement will get executed
Now if !UsedInBox(board, row - row % 3 , col - col % 3, num) this statement evaluates to be true return statement will return true else it will return false
So in order to get true from return statement all three conditions should be evaluated to get true value
The && operator returns a bool value (true or false) so the expression is equivalent to:
if (!UsedInRow(board, row, num) && !UsedInCol(board, col, num) &&
!UsedInBox(board, row - row % 3 , col - col % 3, num)
return true;
else
return false;
also you may find some sort of these expressions which also holds the same result:
return (!UsedInRow(board, row, num) && !UsedInCol(board, col, num) && !UsedInBox(board, row - row % 3 , col - col % 3, num))?true:false;
This (note the comma operator):
#include <iostream>
int main() {
int x;
x = 2, 3;
std::cout << x << "\n";
return 0;
}
outputs 2.
However, if you use return with the comma operator, this:
#include <iostream>
int f() { return 2, 3; }
int main() {
int x;
x = f();
std::cout << x << "\n";
return 0;
}
outputs 3.
Why is the comma operator behaving differently with return?
According to the Operator Precedence, comma operator has lower precedence than operator=, so x = 2,3; is equivalent to (x = 2),3;. (Operator precedence determines how operator will be bound to its arguments, tighter or looser than other operators according to their precedences.)
Note the comma expression is (x = 2),3 here, not 2,3. x = 2 is evaluated at first (and its side effects are completed), then the result is discarded, then 3 is evaluated (it does nothing in fact). That's why the value of x is 2. Note that 3 is the result of the whole comma expression (i.e. x = 2,3), it won't be used to assign to x. (Change it to x = (2,3);, x will be assigned with 3.)
For return 2,3;, the comma expression is 2,3, 2 is evaluated then its result is discarded, and then 3 is evaluated and returned as the result of the whole comma expression, which is returned by the return statement later.
Additional informations about Expressions and Statements
An expression is a sequence of operators and their operands, that specifies a computation.
x = 2,3; is expression statement, x = 2,3 is the expression here.
An expression followed by a semicolon is a statement.
Syntax: attr(optional) expression(optional) ; (1)
return 2,3; is jump statement (return statement), 2,3 is the expression here.
Syntax: attr(optional) return expression(optional) ; (1)
The comma (also known as the expression separation) operator is evaluated from left to right. So return 2,3; is equivalent to return 3;.
The evaluation of x = 2,3; is (x = 2), 3; due to operator precedence. Evaluation is still from left to right, and the entire expression has the value 3 with the side-effect of x assuming the value of 2.
This statement:
x = 2,3;
is composed by two expressions:
> x = 2
> 3
Since operator precedence,
= has more precedence than comma ,, so x = 2 is evaluated and after 3. Then x will be equal to 2.
In the return instead:
int f(){ return 2,3; }
The language syntax is :
return <expression>
Note return is not part of expression.
So in that case the two expression will be evaluated will be:
> 2
> 3
But only the second (3) will be returned.
Try to apply the simplistic approach just highlighting the precedence with parenthesis:
( x = 2 ), 3;
return ( 2, 3 );
Now we can see the binary operator "," working in the same way on both, from left to right.
Consider the code:
int i, j;
i = (i = 1, j = 3);
i++;
cout<<i<<" "<<j;
This printed 4 3 (c++14).
I read that the comma operator evaluates the expression on its left and returns the one on its right. Now if that is correct, I want to know what is the return value of j = 3? Is it the rvalue? Or a reference to the lvalue?
How does this actually work?
I want to know what is the return value of j = 3?
Assignment operations* return (or "evaluate to") a reference to the left-hand side of the operation, in this case j.
So i = (i = 1, j = 3); is identical to:
i = 1;
j = 3;
i = j;
*For built-in types that is. Custom operator= overloads may return whatever they want, although it's recommended to return a reference to *this as it is the expected behavior among C++ programmers.
To calculate (i=1, j=3), it calculates, from left to right, the expressions separated by comma, and returns the value of the last (rightmost) expression. So it calculates i=1 (i becomes 1), then it calculates j=3 (j becomes 3), then returns 3.
After calculating (i=1, j=3), which returned 3, it performs the assignment, which sets i to 3.
Then i++ is calculated, which sets i to 4.
Then i and j are printed.
The assignment operator returns an lvalue referring to the left operand. It groups right-to-left. ([expr.ass]). Note that saying returning a reference to the lvalue doesn't make sense - it either returns an lvalue or not.
The comma operator performs the value computations and side effects from the left operand, discards them, and then does the same for the right operand. ([expr.comma])
So refactoring the comma operator would produce the following equivalent code:
i = 1; // left operand, value discarded
i = j = 3; // right operand, value preserved
i++;
and then refactoring the compound assignment would produce the following still equivalent code:
i = 1;
j = 3; // rightmost assignment
i = j; // leftmost assignment
i++;