[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 231
  • Last Modified:

operators precedence

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
ramnars
Asked:
ramnars
  • 8
  • 5
  • 3
  • +1
1 Solution
 
Sjef BosmanGroupware ConsultantCommented:
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
 
ramnarsAuthor Commented:
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
 
PaulCaswellCommented:
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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
ramnarsAuthor Commented:
Ok. Gotcha.
Is thre any specific reason why increment happens later. Is it due to right to left or some thing like that?
0
 
Sjef BosmanGroupware ConsultantCommented:
++ 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
 
Sjef BosmanGroupware ConsultantCommented:
Paul, the original loop works! See pg 101 and pg 187 of the C Programming Language, K&R, 1987
0
 
PaulCaswellCommented:
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
 
Sjef BosmanGroupware ConsultantCommented:
But you stated that ...

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

Pls explain...
0
 
PaulCaswellCommented:
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
 
Sjef BosmanGroupware ConsultantCommented:
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
 
PaulCaswellCommented:
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
 
Sjef BosmanGroupware ConsultantCommented:
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
 
PaulCaswellCommented:
sjef,

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

Paul
0
 
Sjef BosmanGroupware ConsultantCommented:
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
 
aib_42Commented:
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
 
aib_42Commented:
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
 
Sjef BosmanGroupware ConsultantCommented:
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
 
aib_42Commented:
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

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 8
  • 5
  • 3
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now