【问题标题】:if I initialize a char array to zero/{0} do I have to null terminate?如果我将 char 数组初始化为零/{0},我是否必须 null 终止?
【发布时间】:2021-02-03 00:13:02
【问题描述】:

例如,我声明一个 char 数组,所有值都按以下方式设置为零:

char array[4] = {0};

如果我给它赋值,例如:

array[0] = 'A';
array[1] = 'B';
array[2] = 'C';

我需要像这样终止数组吗?:

array[3] = '\0';

或者操作char array[4] = {0} null 在任何分配之前终止?

【问题讨论】:

  • 数组完全被0字节填充。空终止与此没有什么不同。但是不会为空字节添加另一个元素。
  • 也就是说 {0} null 终止了字符串?
  • 请注意char array[4] = {'A'}; 不会用As 填充整个数组,而只会填充第一个元素。然而,其余部分用 0 填充。
  • 与所有变量初始化一样,没有初始化器的成员是零填充的。如果您提供{0},您的初始化列表中将有 1 个字节,其余的将用零填充。如果将该数组用于最多包含 3 个字符的字符串,则它以空值结尾。如果你将它用于不同的目的,它仍然包含 0 个字节,但术语“空终止”在那里没有任何意义。
  • 从概念上讲,这会第二次写入一个 nul 终止符。实际上,假设事情在范围内,编译器应该能够识别多余的写入并摆脱它。就个人而言,我认为明确性是首选。

标签: arrays c initialization c-strings null-terminated


【解决方案1】:

此声明

char array[4] = {0};

等价于

char array[4] = { 0, 0, 0, 0 };

来自 C 标准(6.7.9 初始化)

19 初始化应按初始化列表顺序进行,每个 为覆盖任何特定子对象提供的初始化程序 先前列出的同一子对象的初始化程序;151) 全部 未显式初始化的子对象应被初始化 与具有静态存储持续时间的对象隐式相同

10 如果具有自动存储时长的对象未初始化 明确地说,它的值是不确定的。 如果一个物体有静电 或线程存储时长未显式初始化,则:

——如果它有算术类型,它被初始化为(正数或 无符号)零; — 如果是聚合,则每个成员都被初始化(递归) 根据这些规则,任何填充都被初始化为零位; ...

所以元素数组[3]包含0。直到它被覆盖,数组包含一个字符串。

字符数组零的替代初始化如下

char array[4] = "";

或以下

char array[4] = { "" };

甚至以下

char array[] = { [3] = '\0' };

这是一个演示程序。

#include <stdio.h>

int main(void) 
{
    char array[] = { [3] = '\0' };
    
    array[0] = 'A';     //  the array contains a string
    
    printf( "%s\n", array );
    
    array[1] = 'B';     //  the array contains a string
    
    printf( "%s\n", array );
    
    array[2] = 'C';     //  the array contains a string
    
    printf( "%s\n", array );
    
    array[3] = 'D';     //  the array does not contain a string
    
    printf( "%.*s\n", ( int )sizeof( array ), array );
    
    
    return 0;
}

程序输出是

A
AB
ABC
ABCD

【讨论】:

    【解决方案2】:

    我需要像这样终止数组吗?

    没有。 '\0' 只是写0 的一种奇特方式。这是一种编写自记录代码的方法,专门引用空终止符,脱离传统。 (实际上,它只是一个写成八进制转义序列的零。)

    由于您已经将所有项目设置为0,因此不需要额外的\0

    【讨论】:

    • 另请注意char array[4] = ""; 也会将所有项目设置为零。
    • 出于好奇,char *array; memset(&amp;array[0], 0, sizeof(array)); 是否等同于 char array[4] = {0}
    • @Lundin 嗯?? array 指向无处,sizeof(array) 是指针的大小。
    • @asd23553 不会,但char array[4]; memset(&amp;array[0], 0, sizeof(array)) 会。
    • @e2-e4 是的,部分初始化的“聚合”(结构或数组)的规则保证了这一点。 “...所有未显式初始化的子对象都应隐式初始化,与具有静态存储持续时间的对象相同。”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多