简体   繁体   中英

C char array initialization

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?

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.

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, ie, 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 , ie, '\\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.

  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}; 

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.

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;
}

I'm not sure but I commonly initialize an array to "" in that case I don't need worry about the null end of the string.

main() {
    void something(char[]);
    char s[100] = "";

    something(s);
    printf("%s", s);
}

void something(char s[]) {
    // ... do something, pass the output to s
    // no need to add s[i] = '\0'; because all unused slot is already set to '\0'
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM