MFR
MFR

Reputation: 3

using semicolon without any command in for loop in C

these codes do the same work. I don't understand why

for ( ; *s1 = *s2; s1++, s2++ ) { ;}
for ( ; *s1 = *s2; s1++, s2++ ) {*s1=*s2;} 

Upvotes: 0

Views: 63

Answers (4)

merlin2011
merlin2011

Reputation: 75585

The second clause of the loop will evaluate to the value of the assignment and then use this value to determine whether to continue looping, so both loops will copy s2 to s1 until *s1 == 0. If s1 and s2 are the same type of pointer, then this occurs when *s2 == 0. If they are not the same type, then this is tricky code that is quite possibly incorrect.

The second loop contains an entirely redundant body, since it just repeats what the second clause of the loop does already.

Upvotes: 4

Stephan Lechner
Stephan Lechner

Reputation: 35154

If s1 and s2 are of type char*, then the code implements a strcpy. The end-condition of a strcpy is "stop after having assigned the '\0'-string termination character.

So a third version would be...

for ( ; ; s1++, s2++ ) {
   *s1=*s2;
   if (!*s1) {
      break;
   }
} 

Now let's dive into the meaning of an assignment like *s1 = *s2, which does actually two things: (1) it assigns *s2 to *s1, and (2) the expression result is the value of *s1 after the assignment;

In for ( ; *s1 = *s2; s1++, s2++ ) { ;}, where *s1 = *s2 is used in the loop-end-condition, two things happen (1) the assignment and (2) the check if '\0' got assigned (in which case the loop ends).

In for ( ; *s1 = *s2; s1++, s2++ ) {*s1=*s2;}, the loop's body is simply superfluous; the assignment has already taken place when evaluating the "condition".

BTW: you could also write it as while((*s1++=*s2++));...

Upvotes: 1

0___________
0___________

Reputation: 67765

Both codes copy the memory block referenced by the s2 into the the memory block referenced by the s1 until *s2 is not zero.

They are the same as your condition is the assignment.

the {*s1=*s2;} will be optimized out by most compilers.

for example if the pointers are char *

int main()
{
  for ( ; *s1 = *s2; s1++, s2++ ) { ;}
  for ( ; *s3 = *s4; s3++, s4++ ) {*s3=*s4;} 
}

The code is (-O3, -O2, -O1)

main:
        movzx   eax, BYTE PTR ds:0
        test    al, al
        je      .L2
        mov     eax, 1
.L3:
        movzx   edx, BYTE PTR [rax]
        add     rax, 1
        test    dl, dl
        jne     .L3
.L2:
        movzx   eax, BYTE PTR ds:0
        test    al, al
        je      .L4
        mov     eax, 1
.L5:
        movzx   edx, BYTE PTR [rax]
        add     rax, 1
        test    dl, dl
        jne     .L5
.L4:
        xor     eax, eax
        ret

Both loops are exactly the same

Upvotes: 0

user2864740
user2864740

Reputation: 61935

Did you mean to use == in the loop condition? Regardless,

Right now it performs an assignment - the result of the expression is the assigned value and is “true” until the value is 0.

Since the assignment is done in the loop condition, at the top of each loop, the assignment inside the loop is redundant as the same assignment has already occurred before the loop body executes.

Upvotes: 0

Related Questions