Reputation: 667
I'm learning C from the K&R book and on chapter 5 it shows an implementation of strcpy() with pointers involved (instead of using array indices). It says that:
while ((*s++ = *t++) != '\0')
and
while (*s++ = *t++)
Both do the same thing, and that the != '\0'
part is not necessary. But I don't completely understand why. Is '\0'
equivalent to zero when a pointer pointing to that null character is dereferenced or something?
*EDIT: So if '\0'
is equal to zero, then would this also work? *
while (s[i] = t[i]) i++;
Upvotes: 1
Views: 1140
Reputation: 58281
Yes, '\0'
nul char is 0
.
To understand conditional expressions consider my following points:
One: Because associativity assignment operator =
is right-to-left hence expression
a = b = c;
is equivalents to:
a = (b = c);
in effects equivalents to :
b = c;
a = b;
Two: the pointer assignment expression:
*s++ = *t++;
is equivalents to:
*s = *t;
t++;
s++;
Three: and an expression:
con = *s++ = *t++;
is equivalents to:
*s = *t;
con = *s;
t++;
s++;
Four:
(*s++ = *t++) != '\0'
is equivalents to:
*s = *t;
*s != '\0';
t++;
s++;
[Answer]:
So in second while loop:
while (*s++ = *t++);
// ^ ^
// | |
// assign then increments
// then break condition = *s (updated value at *s that is \0 at the end)
Instruction "*s++ = *t++
copies value at address by t
to value at address by s
and then that value becomes break condition in while loop, So loop runs till \0
found which is equal to 0
.
So conditional expression (*s++ = *t++)
is equivalent to (*s++ = *t++) != '\0'
both runs till *s != 0
.
The last while:
while (s[i] = t[i]) i++;
// ^ ^ ^
// | | increments
// assign then increments
// then break condition = s[i] (s[i] is \0 at the end)
Instruction s[i] = t[i]
first copies value of t[i]
to s[i]
then value of s[i]
uses as breaking condition of while-loop that is \0
(=0) at end.
Upvotes: 2
Reputation: 70929
If you wanted the character that is typed as 0, as in ascii 48, you would naturally use '0'.
Since that '0' is already taken, to specify the "special" NUL character, a different sequence is needed. As many people understand that NUL equals the binary value of 0, they opted for '\0'.
So
'\0' == 0
returns true, but
'0' == 48 // ASCII only, EBCDIC programmers need to lookup their own values ;)
returns true too
And yes, there are many ways one could write the strcpy()
internals. However, pointers and arrays are only representationally equivalent, and sometimes (even if it is not necessary) an explicit comparator can prevent people from focusing on the wrong elements of a demonstrative example.
So, I believe that instead of forcing the reader to understand that the loop would terminate when stumbling upon a NUL character, they just wrote in a clause (which any decent compiler would probably optmize away) that made the termination apparent. After all, they really were focusing on the copying aspect, not the "boolean" to int
mapping.
Upvotes: 1
Reputation: 12629
'\0'
and 0
mean the same thing, so using the former is just syntactic sugar.
The point is to make the code more readable, as we're dealing here with strings of characters, so it's more consistent to use the character-symbol for the number zero, used to terminate C-strings.
If you deal with numbers, it's better style to use 0
, if you deal with characters, '\0'
is better, and if you deal with pointers, NULL
is best. All 3 symbols mean the same, it's just for clarity.
Upvotes: 0
Reputation: 8946
The backslash indicates that there will be some special case in string for example:
`\r` means carriage return and it is equal 13
`\n` means line feed and it is equal 10
there are more of these and in your mentioned case:
`\0` means null and is equal 0
That is how c
works.
Upvotes: 0
Reputation:
Both do the same thing, and that the
!= '\0'
part is not necessary. But I don't completely understand why.
Because in C, in places where a conditional expression is expected, non-0 numbers (integers and floating-point values) and non-NULL
pointers are interpreted as true, and zero an NULL
are considered false. But that doesn't quite have anything to do with the second part of your question.
Is '\0' equivalent to zero when a pointer pointing to that null character is dereferenced or something?
It is always equivalent to 0
, in any context. Even if you do void *foo = '\0';
, it will set foo
to NULL
, since an integer literal zero is a suitable initializer for a pointer and it is converted to NULL
. But I don't see why you are asking about pointers, since you are just comparing integrals with integrals (char
and int
are both integral types).
Upvotes: 2