Reputation: 405
Why don't the numeric arrays end with a null character?
For example,
char name[] = {'V', 'I', 'J', 'A', 'Y', '\0'};
But in case of numeric arrays there is no sign of null character at the end...
For example,
int marks[] = {20, 22, 23};
What is the reason behind that?
Upvotes: 33
Views: 27822
Reputation: 206518
Arrays by themselves do not have to be \0
terminated, it is the usage of the character arrays in a specific way that needs them to be \0
terminated. The standard library functions which act on character arrays will use the \0
to detect end of the array and hence treat it as a string, this behavior means the users of these functions will need to follow the \0
termination precondition. If your character array usage doesn't use any such functionality then it doesn't need the \0
terminator.
Upvotes: 1
Reputation: 1
In a numeric arrray character values, including '\0', are all numeric. Ascii code numbers to be precise.
Thus with numeric arrays there is no possible end of array character that is distinguishable from the array members themselves.
With character arrays there is, '\0', which in character arrays is treated specially as the 'null character', aka not a character, thus distinguishable from the array members and hence can be used to mark the end of the array.
Upvotes: -1
Reputation: 154876
The question asked contains a hidden assumption, that all char
arrays do end with a null character. This is in fact not always the case: this char
array does not end with \0
:
char no_zero[] = { 'f', 'o', 'o' };
The char
arrays that must end with the null character are those meant for use as strings, which indeed require termination.
In your example, the char
array only ends with a null character because you made it so. The single place where the compiler will insert the null character for you is when declaring a char array from a string literal, such as:
char name[] = "VIJAY";
// the above is sugar for:
char name[] = { 'V', 'I', 'J', 'A', 'Y', '\0' };
In that case, the null character is inserted automatically to make the resulting array a valid C string. No such requirement exists for arrays of other numeric types, nor can they be initialized from a string literal. In other words, appending a zero to a numeric array would serve no purpose whatsoever, because there is no code out there that uses the zero to look for the array end, since zero is a perfectly valid number.
Arrays of pointers are sometimes terminated with a NULL pointer, which makes sense because a NULL pointer cannot be confused with a valid pointer. The argv
array of strings, received by main()
, is an example of such an array.
Upvotes: 34
Reputation: 122383
An array can end in anything that is a valid value of the array element type. But only a \0
terminated char
array is called a string.
For example
char name[]={'V','I','J','A','Y'};
Valid, but not a string, the limit is that you can't use it in functions expecting a string like strlen
etc.
To clarify from OP's comment below, by the C standard, any character literals like 'a'
, '1'
, etc, including '\0'
are type int
. And you can put a '\0'
at the end of an int
array like this:
int arr[] = {20, 22, 23, '\0'};
But people usually don't do that because it's conventional that '\0'
is only used to terminated strings. The above code is equivalent to
int arr[] = {20, 22, 23, 0};
Upvotes: 8
Reputation: 86506
There are three, maybe four decent ways of tracking an array's length, only two of which are common in C:
Keep track of the length yourself and pass it along with the pointer.
This is how arrays typically work. It doesn't require any special formatting, and makes sub-array views trivial to represent. (Add to the pointer, subtract from the length, and there ya go.)
Any function in the standard library that works with non-string arrays expects this already. And even some functions that mess with strings (like strncat
or fgets
) do it for safety's sake.
Terminate the array with some "sentinel" value.
This is how C strings work. Because nearly every character set/encoding in existence defines '\0'
as a non-printable, "do nothing" control character, it's thus not a typical part of text, so using it to terminate a string makes sense.
Note that when you're using a char[]
as a byte array, though, you still have to specify a length. That's because bytes aren't characters. Once you're dealing with bytes rather than characters, 0
loses its meaning as a sentinel value and goes back to being plain old data.
The big issue is that with most fundamental types, every possible arrangement of sizeof(type)
bytes might represent a valid, useful value. For integral values, zero is particularly common; it is probably one of the most used and most useful numbers in all of computing. I fully expect to be able to put a 0
into an array of integers without appearing to lose half my data.
So then the question becomes, what would be a good sentinel value? What otherwise-legal number should be outlawed in arrays? And that question has no good, universal answer; it depends entirely on your data. So if you want to do such a thing, you're on your own.
Besides the lack of a decent sentinel value, this approach falls flat with non-character types for another reason: it's more complicated to represent subsets of the array. In order for a recursive function to pass part of the array to itself, it would have to insert the sentinel value, call itself, and then restore the old value. Either that, or it could pass a pointer to the start of the range and the length of the range. But wait...isn't that what you are trying to avoid? :P
For completeness, the two other methods:
Create a struct that can store the array's length along with a pointer to the data.
This is a more object-oriented approach, and is how arrays work in nearly every modern language (and how vectors work in C++). It works OK in C iff you have an API to manage such structs, and iff you use that API religiously. (Object-oriented languages provide a way to attach the API to the object itself. C doesn't, so it's up to you to stick to the API.) But any function that wasn't designed to work with your structs will need to be passed a pointer (and possibly a length) using one of the above two methods.
Pass two pointers.
This is a common way to pass a "range" in C++. You pass a pointer to the start of the array, and a pointer just past the end. It's less common in C, though, because with raw pointers, (start,length)
and (start,end)
represent the same data -- and C doesn't have the iterators and templates that make this so much more useful.
Upvotes: 3
Reputation: 3183
Char array ends with special char '\0'
so that it can be treated as string.
And when you are manipulating string there must be some way to tell the length(boundary) of that string.
Look at function prototype of strcpy
char * strcpy ( char * destination, const char * source );
How does it know to copy how many chars from source to destination? The answer is by looking at the position of '\0
'.
The '\0'
char is prominent when dealing with string as a char *
. Without '\0'
as an end marker you wouldn't have been able to treat char *
as string.
Upvotes: 2
Reputation: 4433
An array of char not necessarilly ends with \0.
It is a C convention that strings are ended with \0.
This is useful to find the end of the string.
But if you are only interested in holding data that is of type char, you can have a \0 at end or not.
If your array of char is intended to be used as a string, you should add \0 at the end of it.
EDIT: What is ended by \0 are the string literals, not the array of char.
The question is ill formulated.
Upvotes: 1
Reputation: 22241
You do not have to have a '\0'
char at at the end of character array! This is a wrong assumption. There is no rule which says you do. Characters (char
type) are exactly like any other kind of data.
You do have to have a null terminated char array if you want to print the array using standard printf
-family functions. But only because those functions depend on the ending of the character array - '\0'
char.
Functions often have rules concerning the kind of data they expect. String (char[]
) functions are not exception. But this is not a language requirement, it's the API you're using which has these requirements.
Upvotes: 2
Reputation: 123448
A string ends with a 0 terminator, but a string is not the same thing as an array. We use arrays to store strings, but we also use arrays to store things that are not strings. That's why arrays in general don't automatically have a 0 appended to them.
Besides, in any generic array of int
, 0 may be a valid (non-sentinel) value.
Upvotes: 5
Reputation: 13005
We have a convention: special character '0'
with numeric code 0
, marks end of the string.
But if you want to mark end of int
array, how will you know is that 0
is a valid array member or end-of-array mark? So, in general, it is not possible to have such a mark.
In other words:
The character '\0'
(but not character '0'
, code 48
) have no any sense in context of text string (by convention, it is a special character, that marks end), so it can be used as end-of-array mark:
Integer 0
or \0
(which is the same), are valid integer. It can have sense, and that is why it cannot be used as end-of-array mark:
int votesInThisThread[] = { 0, -1, 5, 0, 2, 0 }; // Zeroes here is a valid numbers of upvotes
If you'l try to detect end of this example array by searching 0
, you'll get size of 0.
That is what question about?
Upvotes: -3
Reputation: 106012
You need to end C strings with '\0'
since this is how the library knows where the string ends.
The NUL
-termination is what differentiates a char array from a string (a NUL
-terminated char-array). Most string-manipulating functions relies on NUL
to know when the string is finished (and its job is done), and won't work with simple char-array (eg. they will keep on working past the boundaries of the array, and continue until it finds a NUL
somewhere in memory - often corrupting memory as it goes).
Upvotes: 2
Reputation: 96111
You can make an int
array end with 0
as well, if you wish:
int iarray[] = {1, 2, 3, 0};
Since '\0'
and 0
are exactly the same, you could even replace the 0
above by '\0'
.
Your confusion might be due to the automatic insertion of '\0'
in a declaration such as:
char s[] = "hello";
In the above, the definition of s
is equivalent to char s[] = {'h', 'e', 'l', 'l', 'o', '\0'};
. Think of this a a convenient shortcut provided by the C standard. If you want, you can force a non-zero terminated char array by being explicit about the size:
char s[5] = "hello";
In the above example, s
won't be NUL
terminated.
Also note that character literals in C are of type int
, so '\0'
is actually an int
. (Also further, char
is an integral type.)
Upvotes: 4
Reputation: 172398
An example to take the point that how \0 will confuse if taken in a integer array:-
int marks[]={20,22,23,0,93,'\0'};
^
So now your array will assume that 0(marked) is an end of the array which is not true.
\0
is usually used to terminate a string. In string \0
is regarded as the end of the string.
In your example you dont need to terminate it with '\0'
Found a very interesting wiki post:-
At the time C (and the languages that it was derived from) was developed, memory was extremely limited, so using only one byte of overhead to store the length of a string was attractive. The only popular alternative at that time, usually called a "Pascal string" (though also used by early versions of BASIC), used a leading byte to store the length of the string. This allows the string to contain NUL and made finding the length need only one memory access (O(1) (constant) time). However, C designer Dennis Ritchie chose to follow the convention of NUL-termination, already established in BCPL, to avoid the limitation on the length of a string caused by holding the count in an 8- or 9-bit slot, and partly because maintaining the count seemed, in our experience, less convenient than using a terminator.
Also check a related post:- nul terminating a int array
Upvotes: 0