C char array initialization

720,191

Solution 1

This is not how you initialize an array, but for:

  1. The first declaration:

    char buf[10] = "";
    

    is equivalent to

    char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
  2. The second declaration:

    char buf[10] = " ";
    

    is equivalent to

    char buf[10] = {' ', 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
  3. 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

  1. These are equivalent

    char buf[10] = "";
    char buf[10] = {0};
    char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
  2. These are equivalent

    char buf[10] = " ";
    char buf[10] = {' '};
    char buf[10] = {' ', 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
  3. 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;
}
Share:
720,191
lkkeepmoving
Author by

lkkeepmoving

Updated on July 08, 2022

Comments

  • lkkeepmoving
    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 from buf[2] to buf[9] will be random content. For case 3, I think buf[0] should be 'a', buf[1] should be '\0', and from buf[2] to buf[9] will be random content.

    Is that correct?

    And for the case 1, what will be in the buf? buf[0] == '\0' and from buf[1] to buf[9] will be random content?

    • Martin R
      Martin R over 10 years
      Well, my compiler does not accept your (corrected) code: "array type 'char [10]' is not assignable".
    • lkkeepmoving
      lkkeepmoving over 10 years
      @MartinR now it will work...
    • Martin R
      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
      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 -- Слава Україні
      Antti Haapala -- Слава Україні almost 8 years
    • Antti Haapala -- Слава Україні
      Antti Haapala -- Слава Україні almost 8 years
      That older question has answers drawing from standards and also talks about aggregate initializer as well
    • lkkeepmoving
      lkkeepmoving almost 8 years
      I 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
      paddy almost 4 years
      @SouravGhosh I'll delete all my comments since they are no longer relevant.
  • paddy
    paddy over 10 years
    For 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
    lkkeepmoving over 10 years
    @ouah why there is no '\0' at the end of buf[]?
  • ouah
    ouah over 10 years
    @lkkeepmoving 0 and '\0 have the same value.
  • lkkeepmoving
    lkkeepmoving over 10 years
    And why I can not do 'char buf[10]; buf = "a"' ?
  • ouah
    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
    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
    ouah over 9 years
    @StevenPenny I rolled back your edit, it's correct but I don't think it adds anything more.
  • Pacerier
    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 char buff[3] = {'a', 'b', 'c'}?
  • ouah
    ouah over 9 years
    @Pacerier it is invalid as per c99, 6.7.8p1.
  • Pacerier
    Pacerier over 9 years
    @ouah, Do you mean that char buff[3] = "abcdefghijkl"; wouldn't compile? (I'm not a C coder.) Then why will char p3[5] = "String"; compile?
  • ouah
    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 as char p[6] = {'S', 't', 'r', 'i', 'n', 'g'};.
  • ouah
    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
    RastaJedi about 8 years
    You should not really make use of the implicit int rule. You should specify a type for main() (and you should also use void, 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 omit return in main, there is an automatic return 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 implicit return that only works with C99 and later; these two are obviously contradictory.
  • Lei Yang
    Lei Yang almost 8 years
    what about char buf[] = {}?
  • ouah
    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 size 0.
  • Admin
    Admin over 7 years
    If 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
    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
    underscore_d over 6 years
    @delive What do you mean, and what relevance did it have to this answer?
  • Tiina
    Tiina about 3 years
    This is not how you initialize an array what do you mean