This is a matter of convenience.
The ISO C standard, section 7.1.1, defines a string as follows:
A string is a continuous sequence of characters terminated by and including the first null character.
There are many possible ways to represent character strings, such as using a counter and an array, or a counter and a pointer. Zero termination is the method chosen for C for string literals and standard library functions associated with strings.
This is convenient because the null character is not actually used for anything else. It cannot be printed; it is not a control character with some specific display behavior, for example, moving the cursor in a certain way.
You can have arrays of almost any type, but the agreement to use a null value to indicate the end of a sequence may not be as convenient for other types. For integer or floating-point types, zero is a valid value that may be required as regular data in an array.
Pointers have a distinguished value that can be used to indicate the end of a sequence: null pointer NULL . And actually it is sometimes used like that. C command line arguments are passed as a sequence of line pointers; the length of this sequence is indicated by the argc value and is labeled with a trailing null pointer. See also the environ pointer and the exec*() functions on Unix-like systems.
(But for some applications, a null pointer may also be a valid value, so it cannot be used as a terminator.)
Character string manipulation is a pretty big part of what C language and the library say, so it makes sense to have an agreement on how to represent character strings. The convention does not apply just as accurately to arrays of other types.
(By the way, it is important to remember that NULL is a macro that expands to a pointer constant of zero. It is incorrect to use the NULL name to denote the null character '\0' . Both, depending on the context, may be represented in source C as constant 0 , but these are completely different things.)