C字符数组初始化:如果字符串文本中的字符数少于数组大小,会发生什么?

jfgube3f  于 2022-12-22  发布在  其他
关注(0)|答案(6)|浏览(272)

我不确定用下面的方法初始化后char数组中会有什么。
1.第一个月
2. char buf[10] = " ";
3. char 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]将是随机内容?

lyr7nygr

lyr7nygr1#

这不是初始化数组的方式,但用于:
1.第一个宣言:

char buf[10] = "";

相当于

char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

1.第二个宣言:

char buf[10] = " ";

相当于

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

1.第三个宣言:

char buf[10] = "a";

相当于

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

如您所见,没有随机内容:如果初始化器较少,则数组的剩余部分用0初始化。即使数组是在函数内部声明的,情况也是如此。

pcww981p

pcww981p2#

1.它们是等效的

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

1.它们是等效的

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

1.它们是等效的

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

vbopmzt13#

  • 编辑: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];

所有元素的内容都是随机的。

lawou6xi

lawou6xi4#

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

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

以及

    • 21**如果用大括号括起来的列表中的初始值设定项比聚合的元素或成员少**,或者用于初始化已知大小的数组的字符串文本中的字符比数组中的元素少**,则聚合的其余部分应隐式初始化为与具有 * 静态存储持续时间的对象相同。*

因此,'\0'被追加,如果有足够的空间,并且剩余的字符被初始化为static char c;将在函数中被初始化的值。
最后,

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

[--]

  • 如果是算术类型,则初始化为(正或无符号)零;

[--]
因此,char是算术类型,数组的余数也保证用零初始化。

kuuvgm7e

kuuvgm7e5#

有趣的是,在程序中的任何时候都可以用任何方式初始化数组,只要它们是structunion的成员。

示例程序:

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

af7jpaap6#

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

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

相关问题