为什么int a [5] = {0}和int a [5] = {1}之间的区别(缺失特征)

Naw*_*waz 4 c++ arrays language-features language-design array-initialization

当我们初始化这样的数组时int a[5] = {0},编译器会使所有5个元素为0.这是非常好的,紧凑的初始化和有用的功能.

但我想知道为什么编译器没有int a[5]={1}类似的初始化?为什么它不能使所有5个元素1?为什么标准不强制要求?它不是一个很棒的功能吗?不是不见了?

此外,如果初始化程序中的元素数小于数组的大小,则编译可以使用初始化程序中的最后一个元素初始化剩余的元素.手段,int a[5]={1,2,3}相当于int a[5]={1,2,3,3,3}.同样,int a[10]={1,2,3,0}相当于int a[10]={1,2,3,0,0,0,0,0,0,0};.

如果标准要求,这一切都不是一个很棒的功能吗?或者这个缺失的功能有什么好的理由吗?


并且在C99中有一个称为指定初始化程序的东西,其用途如下:

指定的初始值设定项可以与常规初始值设定项结合使用,如下例所示:

int a[10] = {2, 4, [8]=9, 10}

在该示例中,a [0]被初始化为2,a 1被初始化为4,a [2]至a [7]被初始化为0,并且a [9]被初始化为10.

很有趣.但即便是这个功能也不在C++中.

Bil*_*eal 10

为什么它不能使所有5个元素1?

因为你误解了什么{}意思.(实际上,在C++中,更好的方法是做到这一点{}而不是{0}).语法{0}并不意味着您希望聚合集中的所有元素都为零.相反,它表示你想要一个聚合,第一个元素零分配给指定的变量(可以是C++中的数组或类类型).由于聚合通常具有多于一个值零的字段,因此聚合中的其余元素是默认构造的.内置或POD类型的默认值是将所有字段设置为零,因此您有效地将整个聚合设置为零.

至于具体原因,请考虑以下内容.根据当前标准,以下断言均不会失败:

struct abc
{
    char field1;
    int field2;
    char field3;
};

int main()
{
    abc example = {'a', static_cast<int>('b')};
    //All three asserts pass
    assert(example.field1 == 'a');
    assert(example.field2 == static_cast<int>('b'));
    assert(example.field3 == '\0');

    int example2[3] = {static_cast<int>('a'), 42};
    assert(example2[0] == static_cast<int>('a'));
    assert(example2[1] == 42);
    assert(example2[2] == 0);
}
Run Code Online (Sandbox Code Playgroud)

您期望field3在拟议的标准变更中有什么价值?即使您将其定义为聚合初始值设定项中的最后一个元素(如上所示),也会破坏与现有代码的兼容性,现有代码假定其余元素是默认构造的.


编辑:刚刚意识到你的问题是根据数组提出的 - 但答案与结构或数组相同,所以它并不重要.

EDIT2:为了使这更符合标准,对类/结构的引用已经被下面的"聚合"所取代,它涵盖了结构和数组的情况.

  • @Billy:他们现在遵守相同的规则,但如果标准制定,他们可以遵循不同的规则. (2认同)