Vijay Chauhan
Vijay Chauhan

Reputation: 405

Why don't numeric arrays end with a '\0' or null character?

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

Answers (13)

Alok Save
Alok Save

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

paidapps
paidapps

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

user4815162342
user4815162342

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

Yu Hao
Yu Hao

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

cHao
cHao

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

Sameer
Sameer

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

pablo1977
pablo1977

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

Dariusz
Dariusz

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

John Bode
John Bode

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

Drop
Drop

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

haccks
haccks

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

Alok Singhal
Alok Singhal

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

Rahul Tripathi
Rahul Tripathi

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

Related Questions