user485498
user485498

Reputation:

C syntax. Copying a character string

Going through K&R I saw the following code snippet of a function, strcopy, which copies a character array to another.

If t is the pointer to the first array, and s is the pointer to the array which t is copied to, the code is:

void strcopy(char *s, char *t){

     while(*s++=*t++)
             ;
}

I'm confused by the while loop. I undersatnd that inside the condition t is copied to s, but I don't understand what condition is being tested here. When will *t++ be false (or zero)? Presumably, when the character string finishes. We can test whether the string is finished by checking if the character pointed at is '\0'. K&R says as much. But then the book rather blithely points out that this test isn't necessary. So I'm wondering what is being tested here?

Upvotes: 4

Views: 452

Answers (4)

Frédéric Hamidi
Frédéric Hamidi

Reputation: 262979

*s++ = *t++ will evaluate to the value that was assigned. At the end of the string, *t will be '\0', and upon assignment the expression will evaluate to '\0' (which C interprets as false).

I guess K&R are saying that an additional test is not necessary, since everything is handled in the while condition.

Upvotes: 5

helios35
helios35

Reputation: 1637

You can test explicitly if the terminating character is reached by using

while ((*s++ = *t++) != '\0')
    ;

if you look up '\0' in an ascii table, you'll see that the character '\0' has an integer-value of 0. Writing something like printf("%d\n", '\0'); would also prove it.

So, the while-statement above can also be written as

while ((*s++ = *t++) != 0)
    ;

However, a while-loop always checks whether the condition has a non-zero-value, so it's always redundant to compare a value in a while-loop against zero in this way. Therefore, you can simply skip the comparison.

Upvotes: 3

vsz
vsz

Reputation: 4909

*s++ = *t++;

is the same as:

*s = *t;
t++;
s++;

The condition always evaluates the left value, so in this case it is like testing

while(*s)

Of course, '\0' evaluates to false, so you don't need while(something!='\0'), because while(something) is enough.

Upvotes: 6

Andrew White
Andrew White

Reputation: 53496

C assignments flow right-to-left and a while loop does an implicit "if" test. So what the compiles does from the perspective of the test is ...

while(*t != 0) // for the sake off testing if the loop should continue ONLY

Another example...

if (a = b) // note the = vs == so, this will only be true if b != 0

A kind of under-the-hood pseudo code version of that loop...

loop:
*s=*t;
if (*s == 0) should_break=1;
s++;
t++;
if (should_break==1) break;
goto loop;

Upvotes: 0

Related Questions