如何在C++中将数组中的所有元素初始化为相同的数字

32

我试图初始化一个int数组,使每个元素都设置为-1。

我尝试了以下方法,但它不起作用。它只将第一个值设置为-1。

int directory[100] = {-1};

为什么它不能正常工作?


4
在GCC和clang中,您可以使用GNU C扩展进行以下操作:int a[100] = { [0 ... 99] = -1 }; - Johannes Schaub - litb
16个回答

46

我惊讶于所有建议使用vector的答案。它们甚至不是同一件事情!

使用<algorithm>中的std::fill

int directory[100];
std::fill(directory, directory + 100, -1);

我不直接涉及这个问题,但你可能需要一个好的辅助函数来处理数组:

template <typename T, size_t N>
T* end(T (&pX)[N])
{
    return pX + N;
}

提供:

int directory[100];
std::fill(directory, end(directory), -1);

因此,您不需要两次列出大小。

14
我很惊讶没有人建议在初始化列表中100次写出-1。 - Brian R. Bondy
9
只是一个小注释,针对这个问题,std::fill_n 更简单一些:std::fill_n(directory, 100, -1); - Jerry Coffin
3
我很惊讶没有人建议使用memset(directory, -1, ...)。在二进制补码体系结构中,这实际上会将'int'值设置为'-1' :) - AnT stands with Russia
5
在C++11中,std::fill(std::begin(directory), std::end(directory), -1);可以使用。 - Hindol
2
正如每个老练的C程序员所知道的那样,静态分配数组的大小为sizeof(A)/sizeof(A[0]) - gerardw
显示剩余6条评论

9
我建议使用std::array,有以下三个原因:
1. 数组提供了在下标操作(即operator[])中的运行时安全性,避免数组越界;
2. 数组 自动携带大小,无需额外传递参数;
3. 最重要的是,数组提供了所需的fill()方法。
#include <array>
#include <assert.h>

typedef std::array< int, 100 > DirectoryArray;

void test_fill( DirectoryArray const & x, int expected_value ) {
    for( size_t i = 0; i < x.size(); ++i ) {
        assert( x[ i ] == expected_value );
    }
}

int main() {
    DirectoryArray directory;
    directory.fill( -1 );
    test_fill( directory, -1 );
    return 0;
}

使用数组需要使用"-std=c++0x"进行编译(适用于上述代码)。

如果该选项不可用或不是一个选项,则可以选择其他选项,如std::fill()(由GMan建议)或手动编写fill()方法。


对我来说最重要的是它是一个本地数组。如果数组实例在堆栈上,则全部分配在堆栈上等等。当然,如果没有C++0x支持,boost::array或自己封装的C数组也可以。 - Johannes Schaub - litb
@Johannes:是的,那个<array>包含了一个本地数组,这是一个重要的点。我忘了提到了。谢谢! - Arun
1
#1是错误的:operator[]不执行边界检查,只有.at()方法可以(除非您使用某些带有调试选项的stdlib实现,在这种情况下它也会在operator[]上执行,但这绝对不是标准行为)。#2与std::array无关:数组可以通过引用传递,因此一个简单的模板函数可以确定大小,在C++17中我们有一个重载的std::size()。 #3是一个无关联的论点:我们也可以使用指向其第一个和最后一个元素的指针来填充普通数组,自C++11以来可以使用std::begin()std::end()获取它们。 - underscore_d

6
如果元素数量较少,您可以一个接一个地指定它们。 数组初始化是通过指定每个元素而不是指定适用于每个元素的单个值来完成的。
int x[3] = {-1, -1, -1 };

你也可以使用向量并使用构造函数初始化所有值。稍后,您可以通过指定&v.front()来访问原始数组缓冲区。
std::vector directory(100, -1);

还有一种用C语言的方式,可以使用memset或其他类似的函数。 memset会对指定缓冲区中的每个字符进行操作,因此对于像0这样的值来说,它可以正常工作,但是对于-1这样的负数,可能不起作用,具体取决于其存储方式。


您也可以使用STL通过fill_n来初始化数组。如果要对每个元素执行通用操作,则可以使用for_each。

fill_n(directory, 100, -1);

或者,如果您真的想要,可以采用低效的方法,使用100个迭代的for循环,并执行directory[i] = -1;

5
如果您确实需要数组,可以使用boost库的array类。它的assign成员函数可以胜任此工作:
boost::array<int,N> array; // boost arrays are of fixed size!
array.assign(-1);

4

它确实可以工作。你对初始化器的期望是不正确的。如果你真的想采用这种方法,你需要在初始化器中使用100个逗号分隔的-1。但是当你增加数组的大小时会发生什么呢?


1
<tongue position="cheek">我们一段时间以前就把那些开发者都带到后面枪毙了!</tongue> - johnsyweb

1

您可以简单地使用以下代码中的for循环:

for (int i=0; i<100; i++)
{ 
a[i]= -1;
}

根据您的要求,您可以获得所需的结果。 A[100]={-1,-1,-1..........(100次)}


1

使用 int 向量代替数组。

vector<int> directory(100,-1);                       // 100 ints with value 1

1

它正在正常工作。这就是列表初始化程序的工作方式。

我相信C99标准的6.7.8.10部分涵盖了这个问题:

如果一个具有自动存储期限的对象没有明确初始化,则其值是不确定的。如果一个具有静态存储期限的对象没有明确初始化,则:

  • 如果它具有指针类型,则初始化为null指针;
  • 如果它具有算术类型,则初始化为(正数或无符号)零;
  • 如果它是一个聚合体,则每个成员都按照这些规则递归地初始化;
  • 如果它是一个联合体,则第一个命名成员按照这些规则递归地初始化。

如果您需要使数组中的所有元素具有相同的非零值,则必须使用循环或memset

还要注意,除非您真的知道自己在做什么,否则在C++中向量优于数组

以下是关于容器和数组的一些需要了解的事情:
  1. 容器类可以让程序员更加高效。因此,如果你坚持使用数组而其他人愿意使用容器类,那么你可能比他们不那么高效(即使你比他们更聪明、更有经验!)。
  2. 容器类可以让程序员编写更加健壮的代码。因此,如果你坚持使用数组而其他人愿意使用容器类,那么你的代码可能会比他们的代码更容易出现错误(即使你比他们更聪明、更有经验!)。
  3. 如果你非常聪明、非常有经验,可以像他们使用容器类一样快速、安全地使用数组,那么其他人可能最终会维护你的代码,并且他们可能会引入错误。或者更糟糕的是,你可能是唯一能够维护你的代码的人,因此管理层将把你从开发中撤回,并将你调入全职维护角色——这正是你一直想要的!
还有更多关于链接问题的内容,请阅读原文。

3
"向量"并不比数组更受青睐,它们是两种不同的东西。在我的当前情况下,哪个更好就使用哪个。 - GManNickG

1

我有同样的问题,我找到了解决方法,文档提供了以下示例:

std::array<int, 3> a1{ {1, 2, 3} }; // double-braces required in C++11 (not in C++14)

所以我刚刚尝试了:

std::array<int, 3> a1{ {1} }; // double-braces required in C++11 (not in C++14)

当所有元素的值都为1时,它可以正常工作。但使用=运算符时无法正常工作。这可能是C++11的问题。


初始化所有元素为一个给定值,点赞。现在,不考虑“std::vector”和“std::array”,你可以这样说: int directory[100]{-1}; - WilliamClements
1
这是错误的:给定的语法将第一个元素初始化为1,其余的元素初始化为0。 - John Zwinck

0
如果您被允许使用 std::array,您可以进行以下操作:
#include <iostream>
#include <algorithm>
#include <array>
using namespace std;

template <class Elem, Elem pattern, size_t S, size_t L>
struct S_internal {
    template <Elem... values>
    static array<Elem, S> init_array() {
        return S_internal<Elem, pattern, S, L - 1>::init_array<values..., pattern>();
    }
};

template <class Elem, Elem pattern, size_t S>
struct S_internal<Elem, pattern, S, 0> {
    template <Elem... values>
    static array<Elem, S> init_array() {
        static_assert(S == sizeof...(values), "");
        return array<Elem, S> {{values...}};
    }
};

template <class Elem, Elem pattern, size_t S>
struct init_array
{
    static array<Elem, S> get() {
        return S_internal<Elem, pattern, S, S>::init_array<>();
    }
};

void main()
{
    array<int, 5> ss = init_array<int, 77, 5>::get();
    copy(cbegin(ss), cend(ss), ostream_iterator<int>(cout, " "));
}

输出结果为:

77 77 77 77 77


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接