Understanding operator precedence from the table - c++

I was going over the following link and it states
Operators between dashed lines have the same "precedence level", of
which you will note that there are 18
Now my question is what does the above statement mean. For instance if two operators are between the dashed lines like -> comes before [] does this mean -> has higher precedence than [] ?

Yes .. you are right.. also note that in case like when * and / comes in an expression,that's where associativity is considered... in such a case you have to evaluate from left to right...
In a * b / c, the operation a * b is evaluated first and then / is evaluated.
In a / b * c, the operation a / b is evaluated first and then * is evaluated.

For instance if two operators are between the dashed lines like -> comes before [] does this mean -> has higher precedence than [] ?
Yes, both are at same precedence level but because of Left to right associativite for example:
a->b[i];
is parsed or equivalent as (a->b)[i];. This is useful when a is a pointer to structure and b is a array member of struct.
And an expression like:
a[i]->b;
same as (a[i])->b;. This is useful when a is an array of structure's pointers.
You don't need parenthesis.
For *, ., ->, and [] operators you can read this answer "Pointer to structure".

Related

Operator precedence Confusion

Hello guys after going through href=http://en.cppreference.com/w/c/language/operator_precedence this link ,
I thought I understood the operator precedence but I came to followings doubt.
The link says that When parsing an expression, an operator which is listed on some row will be bound tighter (as if by parentheses) to its arguments than any operator that is listed on a row further below it. For example, the expression *p++ is parsed as *(p++), and not as (*p)++.
So how does the expression ++*p gets evaluated is it like ++(*p) but if yes ++ has higher priority or bound then *, Then why does * is bound tighter in the above case, and what about the expression *++p ?
Operator precedence defines which operator should be applied first when there is more than one choice.
From your link:
Precedence and associativity are independent from order of evaluation.
The expression ++*p, or any expression of the form:
{operator 2} {operator 1} {expression}
has a well-defined order of evaluation, where {operator 1} {expression} must be applied in order to make an expression that {operator 2} may act on.
Yes ++ has higher precedence over * and the associativity for both is from right to left.
So
++*p will be evaluated as ++(*p) because ++ need to be applied on a modifiable value.
Whereas
*++p as you see when this is evaluated the operator close to p is ++ as well as have higher precedence over * so ++p will happen first followed by dereferencing *(++p)

Trying to understand more about operator associativity in OCaml

I got quite confusioned about associativity in OCaml.
Let's have some examples first.
1. Is + left associative or right?
I think it is left associative. which means if we have a + b + c + d, then it is ((a+b)+c)+d.
But what if we do f1 1 + f2 2? Will it throw an error? because it should be ((f1 1)+f2) 2, right?
2. :: is right associative, but what if used with ,?
If we do 4,3::[], then we have [4,3]. it will create a tuple (4,3), then :: into [].
then why doesn't 4,3::5,6::[] work?
3. functions
Say we have let f x y = y x 5, so y is a function taking two parameters.
If we do f 1 + 2, because + is actually a function taking two parameters, why won't f 1 + 2 work? Why doesn't + become a parameter of f?
4. right associativity
How to create a infix function with right associativity?
Basically, I guess I haven't understood the whole associative / precedence thing in OCaml.
I know there are tables like this http://caml.inria.fr/pub/docs/manual-caml-light/node4.9.html out there. But can someone explain more to me?
Operator associativity determines how to parse an expression when there are multiple operators with the same precedence. For example, a + b + c has two operators with the same precedence (+ and +), so the associativity determines how to parse that expression: the operator is left-associative, so the expression is equivalent to (a + b) + c.
In the expression f1 1 + f2 2, juxtaposition (f1 1 and f2 2) has higher precedence than +, so the expression is equivalent to (f1 1) + (f2 2). There aren't two or more operators at the same precedence level, so associativity doesn't matter.
Your statement about 4,3::[] is wrong: :: has higher precedence than ,, so it is parsed as 4, (3::[]), not (4,3)::[]. The result is a pair whose second element is a list. Read the type error for 4,3::5,6::[]: it is equivalent to (4, (3::5), (6::[])), thus the compiler complains that 5 has type int but the context (due to the :: operator) requires a list.
When you write f 1 + 2, it is parsed as (f 1) + 2. The function f is applied to an integer argument; since f expects two arguments, the result is a function (waiting for the second argument), but the + operator wants an integer, so the expression is ill-typed. + isn't a parameter of f because + by itself is not an expression, and the argument of a function is an expression.
I don't know what you mean by “infix function with right associative”. The associativity and precedence of operators in Ocaml is determined by the first character of the operator as indicated in the table you link to.
These are all standard concepts in parsing, applicable to almost every programming language out there. I recommend reading any textbook with a chapter on programming language syntax or parsing, or start with the Wikipedia articles on associativity and precedence.

C++ Converting Postfix to infix

So i'm programming a cmd-based calculator in C++. I finished it, but i was wondering, after converting the infix to postfix, i have a queue called the postfix queue containing the operators/operands in correct order. How do I convert a postfix expression back to infix?
If you don't mind producing some extra parentheses, it should be pretty easy. You basically "evaluate" the postfix data about like usual, except that when you get to an operator, instead of evaluating that operator and pushing the result on the stack, you print out an open-paren, the first operand, the operator, the second operand, and finally a close-paren.
If you didn't mind changing the order, it would also be pretty easy to avoid the extraneous parentheses. Walk the expression backwards, rearranging things from operator operand operand into operand operator operand. If you encounter an operator where you need an operand, you have a sub-expression to print out similarly. You need to enclose that sub-expression in parentheses if and only if its operator is of lower precedence than the operator you encountered previously.
For example, consider: a b + c *. Walking this backwards, we get *, then c, so we start by printing out c *. Then we need another operand, but we have a +, so we have a sub-expression. Since + is lower precedence than *, we need to enclose that sub-expression in parentheses, so we get c * (b + a).
Conversely, if we had: a b * c +, we'd start similarly, producing c +, but then since * is higher precedence that +, we can/could print out the a * b (or b * a) without parens.
Note that with - or / (or anything else that isn't commutative) you'd have to be a bit more careful about getting the order of operands correct. Even so, you're not going to get the original expression back, only an expression that should be logically equivalent to it.

How is this Precedence operators working?

I know this is silly question but I don't know which step I'm missing to count so can't understand why the output is that of this code.
int i=2;
int c;
c = 2 * - ++ i << 1;
cout<< c;
I have trouble to understanding this line in this code:
c = 2 * - ++ i <<1;
I'm getting result -12. But I'm unable to get it how is precedence of operator is working here?
Have a look at the C++ Operator Precedence table.
The ++i is being evaluated, yielding 3.
The unary - is being evaluated, yielding -3.
The multiplication is being done1, yielding -6.
The bit shift is evaluated (shifting left by 1 is effectively multiplying by two) yielding -12.
The result -12 is being assigned to the variable c.
If you used parentheses to see what operator precedence was doing, you'd get
c = ((2 * (-(++i))) << 1);
Plus that expression is a bit misleading due to the weird spacing between operators. It would be better to write it c = 2 * -++i << 1;
1 Note that this is not the unary *, which dereferences a pointer. This is the multiplication operator, which is a binary operator.
Operator precedence defined the grouping between the operators and their operands. In your example the grouping is as follows
c = ((2 * (-(++i))) << 1);
That's how "precedence of operator is working here" and that's the only thing it does.
The result of this expression is -6 shifted one bit to the left. This happens to be -12 on your platform.
According to your comment in another answer, you mistakenly believe that operator precedence somehow controls what is executed "first" and what is executed "next". This is totally incorrect. Operator precedence has absolutely nothing to do with the order of execution. The only thing operator precedence does, once again, is define the grouping between the operators and their operands. No more, no less.
The order of execution is a totally different thing entirely independent from operator precedence. In fact, C++ language does not define any "order of execution" for expressions containing no sequence points inside (the above one included).

operators computing direction

I encountered something that I can't understand.
I have this code:
cout << "f1 * f1 + f2 * f1 - f1 / f2 is: "<< f1 * f1 + f2 * f1 - f1 / f2 << endl;
All the "f"s are objects, and all the operators are overloaded.
The weird this is that the first computation is of the / operator,
then the second * and then the first *; after that, the operator + and at last, operator -.
So basically, the / and * worked from right to left,
and the + and - operators worked from left to right.
I made another test...
I checked this code:
cout << "f1 * f1 / f2 is: " << f1 * f1 / f2 << endl;
Now, the first operator was * and only then operator /.
So now, it worked from left to right.
Can someone help me understand why is there difference in the directions?
10X!
This is yet again a question of the order of evaluation of function parameters - C++ does not specify such an order. Your code is equivalent to:
(f1 * f1) + (f2 * f1) - (f1 / f2)
The three multiply and divide operations can be evaluated in any order. This is perhaps cleraer for named functions:
add(f1*f2,f2*f1)).minus(f1/f2);
The bottom line is that associativity and precedence have nothing to say about the order of evaluation of function parameters and/or sub-expressions. Given the simple expression:
a + b
the C++ (and C) compiler is free to evaluate a first, then b, or b first then a, whether or not the '+' is overloaded.
It is unspecified in what sequence operator arguments will be calculated.
C++ Standard 5/4:
Except where noted, the order of evaluation of operands of individual operators and subexpressions of individual
expressions, and the order in which side effects take place, is unspecified.
Your expression is equivalent to (* and / are operators too, but leave them as is):
operator-( operator+(f1*f1, f2*f1), f1/f2 )
Operator precedence defines the order of operators that have different precedence, so that, e.g., * and / always evaluate before + and -. Then there is the left-to right rule when multiple operators of the same precedence are concatenated.
However, there is (with the exception of logical and ternary operators) no rule about which of an operator's arguments should be evaluated first. The compiler is free to perform the multiplicative operations in any order in pleases before passing them to the additive operators.
In fact, with the expression f() + g() + h(), the compiler is free to call the functions in reverse order, h(), then g(), then f(), then add together the result of f() and g(), and finally add the result of h(). That wouldn't be a very sensible thing to do in most cases, but it's perfectly legal.
User defined operators use the same precedence and associativity rule than buil-in ones.
Rule of precedence state that operators with higher precedence should be executed before those with lower precedence when adjacent in an expression (separated by a single operator).
Associativity rule state in wich order operators should be executed when an expression contains adjacent operators of same precedence.
In your first exemple precedence rule apply, but as associativity is only about adjacent operators the compiler choose in which order he will execute multiply and divide.
In Your second exemple the asociativity rule applies.
Rule of thumb to avoid problems with this kind of rules (that can be somewhat complex):
if unsure use parenthesis or local variables to force order.
avoid side effect when you call function (or user defined operators) because result could be surprising
when redefining operators try to be consistent with maths
http://www.cppreference.com/wiki/operator_precedence
strange behavior, indeed.
But what i would say is that this should not matter, because a * b / c should be equal to a / c * b if you implemented them mathematical-wise
This just looks like simple operator precedence at work.
In your first example, all the multiplication and division must be done before the addition and subtraction. Since the results of the multiplications and divisions are independent, it really doesn't matter what order they're performed, just that the results are used from left to right in the addition and subtraction.
In the second example, the multiplication and division are not independent and must be performed left to right.
You're always getting the correct results based upon operator precedence. THat's all that really matters. The compiler does not guarantee anything about the order of evaluation other than that operator precedence is honored.
Neil is right .
It is matter of operator associativity and precedence.
The expression is evaluated as (f1 * f1) + (f2 * f1) - (f1 / f2) as per the rules suggests and after that it is left to right in second pass . lastly addition and sub. takes place.
second example is simple. * and / have same precedence so we evaluate the expression as per the associativity rules which is left to right hence the order.