Solved

operators precedence

Posted on 2004-08-25
18
183 Views
Last Modified: 2010-04-15
char *z="testing";
      char arr[20];
      char *y=arr;
      
      while(*y++=*z++);
 
   printf("%s\n",arr);   // prints "testing"

Im having troubles understanding this code fragment.
when you say *z++, is not equivalent to saying ' take the content of where z is pointing to now , and increment it'?

why is this working correctly?
0
Comment
Question by:ramnars
  • 8
  • 5
  • 3
  • +1
18 Comments
 
LVL 46

Expert Comment

by:Sjef Bosman
Comment Utility
It's not the CONTENT of z that gets incremented, it's z itself, making it point to the next location. The increments are executed after the assignment.
0
 

Author Comment

by:ramnars
Comment Utility
Based on operator precedence, * (dereference) must be executed first right?
and also, why is increments executed AFTER assignment? the assignment operarot has more precedence.

Bear with me for silly questions
0
 
LVL 16

Accepted Solution

by:
PaulCaswell earned 20 total points
Comment Utility
OPerator precedence can be seen as the compiler automatically inserting brackets for you.

>>while(*y++=*z++);

would become

while((*y)++=(*z)++);

because '*' binds more tightly than '++'.

So the effect will be equivalent to (since '++' generally happens at the end of everything).

char it;
do
{
 it = *z;
 *y = *z;
 y += 1;
 z += 1;
} while ( it != 0  );

Paul
0
 

Author Comment

by:ramnars
Comment Utility
Ok. Gotcha.
Is thre any specific reason why increment happens later. Is it due to right to left or some thing like that?
0
 
LVL 46

Expert Comment

by:Sjef Bosman
Comment Utility
++ is not defined as an operator in my C-book. There is
    expression:
        ++ lvalue
        lvalue ++
        etc...

and
    lvalue:
        *expression

It cannot be explained using operator precedence, it's a language construction. It says:
    *y= *z;
    y++;
    z++
0
 
LVL 46

Expert Comment

by:Sjef Bosman
Comment Utility
Paul, the original loop works! See pg 101 and pg 187 of the C Programming Language, K&R, 1987
0
 
LVL 16

Expert Comment

by:PaulCaswell
Comment Utility
Increment doesn't always happen later. You can use ++x to make it happen earlier. The reason that *y++=*z++ stops at the end of the string (after the terminating zero is copied) is because an assignment expression has the value that was copied.

Paul
0
 
LVL 46

Expert Comment

by:Sjef Bosman
Comment Utility
But you stated that ...

> while(*y++=*z++);
>
> would become
>
> while((*y)++=(*z)++);
>
> because '*' binds more tightly than '++'.

Pls explain...
0
 
LVL 16

Expert Comment

by:PaulCaswell
Comment Utility
sjef,

>>Paul, the original loop works! See pg 101 and pg 187 of the C Programming Language, K&R, 1987

It does indeed work .. sorry if my comment implied that it doesnt. I was exploding the loop into a form that might more clearly demonstrate its functionality.

>>Pls explain...

I was demonstrating what the compiler would do first because "OPerator precedence can be seen as the compiler automatically inserting brackets for you."

Paul
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 46

Expert Comment

by:Sjef Bosman
Comment Utility
Indeed it did, for
    while(*y++ = *z++);
must have been something like
    while(*(y++)= *(z++));

and the (postfixed) increments are executed after the whole statement. See also pp 214-215 of the same book, both * and ++ as unary operators without any indicated precedence. The exact moment of incrementing the variables is not defined, which makes
    a[i++]= b[i++]
a dangerous operation.
0
 
LVL 16

Expert Comment

by:PaulCaswell
Comment Utility
sjef,

I'll quote K&R:

The unary operators * and & bind more tightly than arithmetic operators, so the assignment
y = *ip + 1
takes whatever ip points at, adds 1, and assigns the result to y, while
*ip += 1
increments what ip points to, as do
++*ip
and
(*ip)++
The parentheses are necessary in this last example; without them, the expression would
increment ip instead of what it points to, because unary operators like * and ++ associate right
to left.

Not clear but also not ambiguous. I dont think this is helping ramnars. Lets take this up elsewhere.

Paul
0
 
LVL 46

Expert Comment

by:Sjef Bosman
Comment Utility
Agreed, it's getting theoretical. And I still don't agree (++ and -- are unary, not arithmetic operators).

Let's meet behind the church, 06:00 tomorrow. Weapons your choice. ;)
0
 
LVL 16

Expert Comment

by:PaulCaswell
Comment Utility
sjef,

I can make church. It makes me hot. How about the bike sheds? Weapons; I choose stress balls.

Paul
0
 
LVL 46

Expert Comment

by:Sjef Bosman
Comment Utility
Bike sheds? Too many courting youngsters around, and I hate a disrespectful public. Stress balls are okay, though. The good old blunt object. Eh, filled with sand, rice, foam or led? And bring some gorgeous nurses, please?

Where do the operators come in, by the way? And who has precedence?
0
 
LVL 7

Expert Comment

by:aib_42
Comment Utility
Postfix ++ and -- do not increment/decrement the lvalue until a sequence point is met and the expression has been therefore evaluated. I do not know where this is stated (pointers welcome), but ++ must bind closer, in this case, than the unary * because otherwise the code wouldn't work:

*y++=*z++;
is equivalent to
*(y++) = *(z++);

Since there is no sequence point within this expression, we know that the two sequence points are before the beginning and after the end of the expression. Therefore (y++) and (z++) evaluate to y and z respectively, the unary * operators get the chars at y and z respectively, set one equal to the other, and then after the full expression is evaluated and the ; (or the end of the while condition) is met, the values of y and z are incremented.

(*y)++ = (*z)++; would obviously not work in the other hand, since (*y)++ is not a legal lvalue.
(It is also obvious from the fact that the pointer values would never get updated)
0
 
LVL 7

Expert Comment

by:aib_42
Comment Utility
About the part I said I didn't know:
I think "right-to-left associativity" means that for " $%x " where x is a variable and $ and % are operators, % is used before $, as well as that if any of the operators happen to be on the right-hand side, they are used before the left-hand side ones.
Please correct me.
0
 
LVL 46

Expert Comment

by:Sjef Bosman
Comment Utility
Seems all okay to me. That sequence point of yours is another undefined thing in the C language and therefore another source of interesting problems.

int i= 4;
printf("%d\n", i++ + i++);
printf("%d\n", ++i + ++i);

What's to be the outcome of the expression in both occasions is not defined. Different compilers may produce different results. Oh well, that should be a different question in this TA...
0
 
LVL 7

Expert Comment

by:aib_42
Comment Utility
Actually, I think the two expressions cause an undefined behaviour. Theoretically, small nazal demons may fly out of your nose :).

I think sequence points are well-defined somewhere in the language specification. Unfortunately, I have no access to it and the resources I have access to either don't mention it or mention it in passing. Anyhow, they should be studied especially before using the postfix ++/-- operators. For anyone who might be interested, this is where the C-FAQ at www.faqs.org says sequence points are put:
&&, ||, the comma operator and the ? part of the ternary ?: operator.
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
The goal of this video is to provide viewers with basic examples to understand recursion in the C programming language.
The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now