Reputation: 3
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
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
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
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
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