Hi All:
I was having problems with pointers, deref, and l-values. So I set up an excercise for myself. Below is the code that I created. IT ALL WORKS THE WAY I WANT. However, I still don't understand deref pointer, oper prec, or l-val's completely.
EX.
(x++)++; l-val missing ok (x++) is an r-val.
(from item #3 in code below)
(*first++)++; How can this work? How is this statement being parsed? Does ++ left to right and * right to left allows this stmt to be parsed?
*(first++)++; Doesn't work? l-val missing ???
Second part, if any of the examples (#3 to #6) can be arranged differently (paranthesis etc.), and still have the same output, please post, and explain.
>> (*first++)++; How can this work?
The *first returns a reference to (l-value) whatever first originally points to, something like an int or char. This return value (int or char) then gets incremented by the last ++. Thus it says
1. return what first points to.
2. increment first.
3. increment what was returned in step 1.
*(first++)++; Doesn't work? l-val missing ???
right because ++ has higher precendance than *. This says
1. increment first.
2. increment what was returned in step 1. Well nothing was returned in step 1. Step 1 yielded a r-value.
(*(first++))++ should work because it makes the * occur before the last ++.
cout << "#2 incr ptr, deref ptr, use val"<< endl;
do
cout << *++first << " ";
while (first != (last - 1));
That is fine as long as the array holds at least 1 item. could also be *(++first) or *(first++) and woule be the same.
I'm not sure what to say about the others. You seem to have a good grasp on it.
0
With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.
(*first++)++
I believe the postfix++ and() have higher precedence than *.
>>>> (*first++)++; How can this work?
>>1. return what first points to.
>>2. increment first.
>>3. increment what was returned in step 1.
Yes postfix ++ has higher precendence than * (it has the highest precendence actually), but because the effects of postfix ++ are delayed, it doesn't seem like it. In
*first++
The ++ is done first, but only in a sense.
1. first it returns the original value of first,
2. then it changes first,
3. then * is applied to the original value of first. (the one returned in 1)
Another way to look at this is to convert it to the equivalent overloaded operator notation. this would be
operator *(operator++(first,0))
(you can ignore the ",0" there. It diferentiates between prefix and postfix ++. It indicates this one is postfix.)
The inner operator ++ saves the original first, then changes first, then returns that saved original value. That value is then passed to operator *.
overloaded operator notation helped alot. thanks
That would mean the following(I changed to NNN to avoid confusion)
1. (*NNN++)++ =>
operator++( (*NNN++), 0) =>
operator++( (operator *(operator++(NNN,0))),0)
2. operator ++(NNN,0) =>NNN=NNN+1, return old NNN (suppose ptr to old NNN)
Just as a notational thing, the prefix operator ++ and -- take only 1 parameter. This is the item they are to operate on. (The member versions of these take no parameters, as they operate on the object of the class they are part of.) The postfix versions of these take two parameters. The 2nd is an int parameter. The value of this int parameter is not specified, it could be anything, not necessarily 1 or 0. The existance of this int is so that the two functions have unique signatures, that is so the prefix and postfix functions are different overloads. The int value isn't really used for any other purpose.
//y = why 39 and not 44
...int x = 4, y;
...y = (x+3) * 5 + x++;
x+3 uses the old x value of 4, even though x++ evaluates before (x+3) and changes x's value to 5.
This won't be the same for classes. REGARDLESS of how the post-fix operator is defined, correct? Why?
I created a "Rational" class to see all this.
...Rational x(1,4), y;
...y = (x+3) * 5 + x++;
x=5/4 , this will than be used in x+3
POSTFIX FUNCTION
const Rational Rational::operator++(int dummy)
{ Rational Tmp = *this;
numer = numer + denom;
return (Tmp);
};
>> x+3 uses the old x value of 4, even though
>> x++ evaluates before (x+3) and changes x's
>> value to 5.
Converting to the operator function notation might have been missleading. That is exactly what happens when you use these functions with classes that have overloaded the operators. In that case, it is not missleading, you will get the results that are suggested by the operator function notation (because that is how the expesssion is evaluated.) Unfortunately, if the expression involves the predefined operators, like the ones for int that appear in your equation, you might not get the same result. This is because the C++ compiler is not required to update the value changed by the increment or decrement operators at a specific point--like it would have to do if the increment or decrement was handled by a function. This allows the compiler much more freedom in how it performs the calculation and therefore allows it much greater opportunity to optimize the calculation. (These sort of expressions are very ripe for optimization too.) So in
y = (x+3) * 5 + x++;
the value in x may be updated at any time during the evaluation of the statement. Thus this sort of expression may yield different results on different compilers. A classic example of this is
f(int i1, int i2)
* * *
int x = 0;
f(x++,x++);
depending on the compiler the function could be called with (0,0), (1,0), or (0,1). To make things a little more rational, the standard defines "sequence points" which are places in an expression where the value must be updated, if not updated before then. In the f(x++,x++); the first sequence point is the call to the function. by the time the function is called x must be updated to 2, however the parameters will be passed before that, so the parameters might not be corrrect. In your example, the only sequence point (I think) was the end of the statement (;), which is always a sequence point.
With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.