Ryan
Ryan

Reputation: 667

Why is '\0' equivalent to 0 when using pointers?

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

Answers (5)

Grijesh Chauhan
Grijesh Chauhan

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

Edwin Buck
Edwin Buck

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

SzG
SzG

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

ST3
ST3

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

user529758
user529758

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

Related Questions