Solved

operators precedence

Posted on 2004-08-25
18
205 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
ID: 11893020
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
ID: 11893072
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
ID: 11893161
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
Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

 

Author Comment

by:ramnars
ID: 11893206
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
ID: 11893218
++ 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
ID: 11893260
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
ID: 11893269
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
ID: 11893411
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
ID: 11893529
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
 
LVL 46

Expert Comment

by:Sjef Bosman
ID: 11893749
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
ID: 11894172
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
ID: 11894540
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
ID: 11900437
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
ID: 11903675
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
ID: 11947419
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
ID: 11947482
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
ID: 11949712
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
ID: 11959357
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

Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

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…
Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use while-loops in the C programming language.

777 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