C char array initialization
Solution 1
This is not how you initialize an array, but for:
The first declaration:
char buf[10] = "";
is equivalent to
char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
The second declaration:
char buf[10] = " ";
is equivalent to
char buf[10] = {' ', 0, 0, 0, 0, 0, 0, 0, 0, 0};
The third declaration:
char buf[10] = "a";
is equivalent to
char buf[10] = {'a', 0, 0, 0, 0, 0, 0, 0, 0, 0};
As you can see, no random content: if there are fewer initializers, the remaining of the array is initialized with 0
. This the case even if the array is declared inside a function.
Solution 2
These are equivalent
char buf[10] = ""; char buf[10] = {0}; char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
These are equivalent
char buf[10] = " "; char buf[10] = {' '}; char buf[10] = {' ', 0, 0, 0, 0, 0, 0, 0, 0, 0};
These are equivalent
char buf[10] = "a"; char buf[10] = {'a'}; char buf[10] = {'a', 0, 0, 0, 0, 0, 0, 0, 0, 0};
Solution 3
Edit: OP (or an editor) silently changed some of the single quotes in the original question to double quotes at some point after I provided this answer.
Your code will result in compiler errors. Your first code fragment:
char buf[10] ; buf = ''
is doubly illegal. First, in C, there is no such thing as an empty char
. You can use double quotes to designate an empty string, as with:
char* buf = "";
That will give you a pointer to a NUL
string, i.e., a single-character string with only the NUL
character in it. But you cannot use single quotes with nothing inside them--that is undefined. If you need to designate the NUL
character, you have to specify it:
char buf = '\0';
The backslash is necessary to disambiguate from character '0'
.
char buf = 0;
accomplishes the same thing, but the former is a tad less ambiguous to read, I think.
Secondly, you cannot initialize arrays after they have been defined.
char buf[10];
declares and defines the array. The array identifier buf
is now an address in memory, and you cannot change where buf
points through assignment. So
buf = // anything on RHS
is illegal. Your second and third code fragments are illegal for this reason.
To initialize an array, you have to do it at the time of definition:
char buf [10] = ' ';
will give you a 10-character array with the first char being the space '\040'
and the rest being NUL
, i.e., '\0'
. When an array is declared and defined with an initializer, the array elements (if any) past the ones with specified initial values are automatically padded with 0
. There will not be any "random content".
If you declare and define the array but don't initialize it, as in the following:
char buf [10];
you will have random content in all the elements.
Solution 4
The relevant part of C11 standard draft n1570 6.7.9 initialization says:
14 An array of character type may be initialized by a character string literal or UTF-8 string literal, optionally enclosed in braces. Successive bytes of the string literal (including the terminating null character if there is room or if the array is of unknown size) initialize the elements of the array.
and
21 If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.
Thus, the '\0' is appended, if there is enough space, and the remaining characters are initialized with the value that a static char c;
would be initialized within a function.
Finally,
10 If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static or thread storage duration is not initialized explicitly, then:
[--]
- if it has arithmetic type, it is initialized to (positive or unsigned) zero;
[--]
Thus, char
being an arithmetic type the remainder of the array is also guaranteed to be initialized with zeroes.
Solution 5
Interestingly enough, it is possible to initialize arrays in any way at any time in the program, provided they are members of a struct
or union
.
Example program:
#include <stdio.h>
struct ccont
{
char array[32];
};
struct icont
{
int array[32];
};
int main()
{
int cnt;
char carray[32] = { 'A', 66, 6*11+1 }; // 'A', 'B', 'C', '\0', '\0', ...
int iarray[32] = { 67, 42, 25 };
struct ccont cc = { 0 };
struct icont ic = { 0 };
/* these don't work
carray = { [0]=1 }; // expected expression before '{' token
carray = { [0 ... 31]=1 }; // (likewise)
carray = (char[32]){ [0]=3 }; // incompatible types when assigning to type 'char[32]' from type 'char *'
iarray = (int[32]){ 1 }; // (likewise, but s/char/int/g)
*/
// but these perfectly work...
cc = (struct ccont){ .array='a' }; // 'a', '\0', '\0', '\0', ...
// the following is a gcc extension,
cc = (struct ccont){ .array={ [0 ... 2]='a' } }; // 'a', 'a', 'a', '\0', '\0', ...
ic = (struct icont){ .array={ 42,67 } }; // 42, 67, 0, 0, 0, ...
// index ranges can overlap, the latter override the former
// (no compiler warning with -Wall -Wextra)
ic = (struct icont){ .array={ [0 ... 1]=42, [1 ... 2]=67 } }; // 42, 67, 67, 0, 0, ...
for (cnt=0; cnt<5; cnt++)
printf("%2d %c %2d %c\n",iarray[cnt], carray[cnt],ic.array[cnt],cc.array[cnt]);
return 0;
}
lkkeepmoving
Updated on July 08, 2022Comments
-
lkkeepmoving almost 2 years
I'm not sure what will be in the char array after initialization in the following ways.
1.
char buf[10] = "";
2.char buf[10] = " ";
3.char buf[10] = "a";
For case 2, I think
buf[0]
should be' '
,buf[1]
should be'\0'
, and frombuf[2]
tobuf[9]
will be random content. For case 3, I thinkbuf[0]
should be'a'
,buf[1]
should be '\0', and frombuf[2]
tobuf[9]
will be random content.Is that correct?
And for the case 1, what will be in the
buf
?buf[0] == '\0'
and frombuf[1]
tobuf[9]
will be random content?-
Martin R over 10 yearsWell, my compiler does not accept your (corrected) code: "array type 'char [10]' is not assignable".
-
lkkeepmoving over 10 years@MartinR now it will work...
-
Martin R over 10 years@lkkeepmoving:
char buf[10]; buf = "a";
does not compile. - Please try it first, and then copy/paste your actual code into the question. That saves a lot of work for you and for all readers of your question. -
lkkeepmoving over 10 years@MartinR Sorry for that. I thought I can assign the buf[] latter but it seems no. Now the code runs.
-
Antti Haapala -- Слава Україні almost 8 yearsPossible duplicate of Does a string literal count as a partial initializer and zero-initialize?
-
Antti Haapala -- Слава Україні almost 8 yearsThat older question has answers drawing from standards and also talks about aggregate initializer as well
-
lkkeepmoving almost 8 yearsI don't think the other question covers all question cases here. Also, this question is more search-friendly and clear, which results in more views on this question. Thanks!
-
paddy almost 4 years@SouravGhosh I'll delete all my comments since they are no longer relevant.
-
-
paddy over 10 yearsFor the sake of the person asking the question, it's worth pointing out that the C standard requires any partially-complete array initialisation to be padded with zero for the remaining elements (by the compiler). This goes for all data types, not just
char
. -
lkkeepmoving over 10 years@ouah why there is no '\0' at the end of buf[]?
-
ouah over 10 years@lkkeepmoving
0
and'\0
have the same value. -
lkkeepmoving over 10 yearsAnd why I can not do 'char buf[10]; buf = "a"' ?
-
ouah over 10 years@lkkeepmoving because C requires you to initialize at declaration time. You then cannot assign a value to an array.
-
Lorenzo Donati support Ukraine over 10 years@lkkeepmoving Initialization and assignment are two different beasts, thus C lets you provide a string as an initializer for a char array, but forbids array assignments (as ouah said).
-
ouah over 9 years@StevenPenny I rolled back your edit, it's correct but I don't think it adds anything more.
-
Pacerier over 9 years@ouah, What happens then when you have more elements than space? E.g.
char buff[3] = "abcdefghijkl";
? Is this valid and identical to charbuff[3] = {'a', 'b', 'c'}
? -
ouah over 9 years@Pacerier it is invalid as per c99, 6.7.8p1.
-
Pacerier over 9 years@ouah, Do you mean that
char buff[3] = "abcdefghijkl";
wouldn't compile? (I'm not a C coder.) Then why willchar p3[5] = "String";
compile? -
ouah over 9 years@Pacerier
char buff[3] = "abcdefghijkl";
is invalid.char p3[5] = "String";
is also invalid.char p[6] = "String";
is valid and is the same aschar p[6] = {'S', 't', 'r', 'i', 'n', 'g'};
. -
ouah over 9 years@Pacerier for the terminology, there is a constraint violation in the two invalid examples, which means an compiler is required to issue a diagnostic and may refuse to compile the program.
-
RastaJedi about 8 yearsYou should not really make use of the implicit int rule. You should specify a type for
main()
(and you should also usevoid
, i.e.,int main(void) { ... }
. C99 got rid of this rule, so this code will not compile for C99 and later. The other thing to note here is that starting with C99, if you omitreturn
in main, there is an automaticreturn 0;
placed/implied before the}
at main's end. You are making use of implicit int rule which only works before C99, yet you are making use of the implicitreturn
that only works with C99 and later; these two are obviously contradictory. -
Lei Yang almost 8 yearswhat about char buf[] = {}?
-
ouah almost 8 years@LeiYang
char buf[] = {}
is invalid in C as empty initializers are not allowed. GNU C allows it and it declares an array of size0
. -
Admin over 7 yearsIf you have a constant MAX = 5000, I will not put 0x500 in my code... is crazy solution!!!! if you want set a value in a function use "strcpy" please...
-
Laurie Stearn over 7 years"To initialize an array, you have to do it at the time of definition..." This, and the following line makes this better than the accepted answer.
-
underscore_d over 6 years@delive What do you mean, and what relevance did it have to this answer?
-
Tiina about 3 years
This is not how you initialize an array
what do you mean