C字符数组初始化

C字符数组初始化,c,arrays,char,initialization,buffer,C,Arrays,Char,Initialization,Buffer,我不确定在以下方式初始化后char数组中会有什么 1.charbuf[10]=” 2. 字符buf[10]=“” 3. 字符buf[10]=“a” 对于案例2,我认为buf[0]应该是',buf[1]应该是'\0',从buf[2]到buf[9]将是随机内容。对于案例3,我认为buf[0]应该是a',buf[1]应该是'\0',从buf[2]到buf[9]将是随机内容 对吗 对于案例1,buf中会有什么buf[0]='\0'和从buf[1]到buf[9]将是随机内容?这不是初始化数组的方式,而是用

我不确定在以下方式初始化后char数组中会有什么

1.
charbuf[10]=”
2. <代码>字符buf[10]=“”
3. <代码>字符buf[10]=“a”

对于案例2,我认为
buf[0]
应该是
'
buf[1]
应该是
'\0'
,从
buf[2]
buf[9]
将是随机内容。对于案例3,我认为
buf[0]
应该是
a'
buf[1]
应该是'\0',从
buf[2]
buf[9]
将是随机内容

对吗


对于案例1,
buf
中会有什么
buf[0]='\0'
和从
buf[1]
buf[9]
将是随机内容?

这不是初始化数组的方式,而是用于:

  • 第一项宣言:

    char buf[10] = "";
    
    char buf[10] = " ";
    
    char buf[10] = "a";
    
    相当于

    char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
    char buf[10] = {' ', 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
    char buf[10] = {'a', 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
  • 第二项宣言:

    char buf[10] = "";
    
    char buf[10] = " ";
    
    char buf[10] = "a";
    
    相当于

    char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
    char buf[10] = {' ', 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
    char buf[10] = {'a', 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
  • 第三项宣言:

    char buf[10] = "";
    
    char buf[10] = " ";
    
    char buf[10] = "a";
    
    相当于

    char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
    char buf[10] = {' ', 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
    char buf[10] = {'a', 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
  • 如您所见,没有随机内容:如果初始值设定项较少,则使用
    0
    初始化数组的其余部分。即使数组是在函数中声明的,也会出现这种情况。

    编辑:OP(或编辑器)在我提供此答案后的某个时刻,将原始问题中的一些单引号默默地更改为双引号

    您的代码将导致编译器错误。您的第一个代码片段:

    char buf[10] ; buf = ''
    
    这是双重违法。首先,在C语言中,没有空的
    char
    。可以使用双引号指定空字符串,如下所示:

    char* buf = ""; 
    
    这将为您提供一个指向
    NUL
    字符串的指针,即一个仅包含
    NUL
    字符的单个字符串。但是你不能使用单引号,里面没有任何东西——这是未定义的。如果需要指定
    NUL
    字符,则必须指定它:

    char buf = '\0';
    
    反斜杠是消除字符
    '0'
    歧义所必需的

    char buf = 0;
    
    完成了同样的事情,但我认为前者不那么模棱两可

    其次,在定义数组之后,不能对其进行初始化

    char buf[10];
    
    声明并定义数组。数组标识符
    buf
    现在是内存中的一个地址,您不能通过赋值更改
    buf
    点的位置。所以

    buf =     // anything on RHS
    
    这是违法的。因此,您的第二个和第三个代码片段是非法的


    要初始化数组,必须在定义时执行以下操作:

    char buf [10] = ' ';
    
    将为您提供一个10个字符的数组,第一个字符是空格
    '\040'
    ,其余字符是
    NUL
    ,即
    '\0'
    。当使用初始值设定项声明和定义数组时,超过具有指定初始值的数组元素(如果有)的数组元素将自动填充为
    0
    。不会有任何“随机内容”

    如果声明和定义数组但不初始化它,如下所示:

    char buf [10];
    

    所有元素中都将包含随机内容

    有趣的是,只要数组是
    结构
    联合
    的成员,就可以在程序中的任何时候以任何方式初始化数组

    示例程序:

    #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;
    }
    
    #包括
    结构容器
    {
    字符数组[32];
    };
    结构图标
    {
    int数组[32];
    };
    int main()
    {
    int-cnt;
    char carray[32]={A',66,6*11+1};//A',B',C','\0','\0'。。。
    int iarray[32]={67,42,25};
    结构ccont cc={0};
    结构icont ic={0};
    /*这些不起作用
    carray={[0]=1};//在“{”标记之前应该有表达式
    carray={[0…31]=1};//(同样)
    carray=(char[32]){[0]=3};//从类型“char*”分配给类型“char[32]”时,类型不兼容
    iarray=(int[32]){1};//(同样,但s/char/int/g)
    */
    //但这些完美的工作。。。
    cc=(struct ccont){.array='a'};/'a','\0','\0','\0'。。。
    //下面是一个gcc扩展,
    cc=(struct ccont){.array={[0…2]='a'};//'a','a','a','\0','\0'。。。
    ic=(struct icont){.array={42,67};//42,67,0,0,0。。。
    //索引范围可以重叠,后者覆盖前者
    //(使用-Wall-Wextra时没有编译器警告)
    ic=(struct icont){.array={[0…1]=42[1…2]=67};//42,67,67,0,0。。。
    对于(cnt=0;cnt
    
  • 这些是等价的

    char buf[10] = "";
    char buf[10] = {0};
    char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
    char buf[10] = " ";
    char buf[10] = {' '};
    char buf[10] = {' ', 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
    char buf[10] = "a";
    char buf[10] = {'a'};
    char buf[10] = {'a', 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
  • 这些是等价的

    char buf[10] = "";
    char buf[10] = {0};
    char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
    char buf[10] = " ";
    char buf[10] = {' '};
    char buf[10] = {' ', 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
    char buf[10] = "a";
    char buf[10] = {'a'};
    char buf[10] = {'a', 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
  • 这些是等价的

    char buf[10] = "";
    char buf[10] = {0};
    char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
    char buf[10] = " ";
    char buf[10] = {' '};
    char buf[10] = {' ', 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
    char buf[10] = "a";
    char buf[10] = {'a'};
    char buf[10] = {'a', 0, 0, 0, 0, 0, 0, 0, 0, 0};
    

  • 我不确定,但我通常将数组初始化为“” 在这种情况下,我不需要担心字符串的空端

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

    C11标准草案n1570 6.7.9的相关部分规定:

    14字符类型的数组可以由字符串文字或UTF-8字符串初始化 文本,可以选择用大括号括起来。字符串文本的连续字节(包括 如果有空间或数组大小未知,则终止空字符)初始化 数组的元素

    21如果大括号内的列表中的初始值设定项少于元素或成员 用于初始化已知数组的聚合,或字符串文本中较少的字符 尺寸大于阵列中的元素,则骨料的剩余部分应为 与具有静态存储持续时间的对象隐式初始化相同。

    因此,如果有足够的空间
    ,则会附加“\0”,剩余的字符将使用在函数中初始化的
    静态字符c;
    的值进行初始化

    最后,

    10如果没有显式初始化具有自动存储持续时间的对象,则其值为 不确定。如果具有静态或线程存储持续时间的对象不是