如何将数组部分地初始化为某个默认值?

3
我有一个数组(例如,unsigned int arr[1000])。
我想要像这样初始化数组的元素...
arr = {4, 10, 34, 45, 6, 67, UINT_MAX, UINT_MAX .. 994 times}

直到我分配了某个值,我希望数组中的默认值为 UINT_MAX。
有没有其他方法可以实现这个目标?
当然,除了使用 for 循环之外,还有其他方法。

您可以执行memset(arr+6, -1, sizeof(unsigned int) * 1000) - srt1104
1
@lucieon 这是未定义行为。您从第六个元素开始并写入1000个更多的元素。 - Evg
3个回答

7
请使用两步法。首先使用初始化器列表,然后用 std::fill 填充其余部分。
#include <limits>
#include <algorithm>

constexpr size_t ArraySize = 1000U;

int main() {
    int arr[ArraySize] = { 4,10,34,45,6,67 };
    
    std::fill(arr + 6U, arr + ArraySize, std::numeric_limits<int>::max());

    return 0;
}

这应该被接受,因为它更清晰地解决了 OP 的问题。 - UserUsing
由于您正在使用C ++,请勿使用C数组,而应优先使用std :: array - Antoine Morrier

5
使用std::fill函数:
unsigned int array[5];
std::fill(array, array + 5, UINT_MAX);

或者使用std::fill_n函数:

unsigned int array[5];
int count = 5; //           -   number of elements to modify
auto value = UINT_MAX; //   -   the value to be assigned 
std::fill_n(array, count, value);

或者考虑使用std::array代替,它是一个薄层封装的C风格数组,具有一些额外的功能,如迭代器和size()函数。此外,它不会自动转换为指针。

根据下面@Evg的评论,更符合惯用法、通用、安全可靠的方法是使用库提供的功能:

unsigned int array[5];
// number of elements to modify
int count = std::size(array); // C++17

// the value to be assigned 
auto value = std::numeric_limits<uint32_t>::max();

std::fill_n(std::begin(array), count, value);

//OR with std::fill
std::fill(std::begin(array), std::end(array), value);

以上方法的优势是显而易见的:
  • 您只需将容器从C风格数组切换到std::vectorstd::array,而不必更改上述代码中的任何其他部分。
  • 如果您更改数组的大小,代码将自动适应
  • 减少了人为错误的可能性

2
不要使用 array + 5,而是可以使用 std::end(array)(对称的还有 std::begin(array))来代替,这样会更少出错——没有神秘的常量 5。同样的,对于 count,可以使用 auto count = std::size(array); - Evg
2
我在想,为什么这个回答有4个UV并且被接受了。问题是关于部分初始化然后填充剩余部分的。但我们永远不会学到... - A M

5
以下代码允许你对任何类型、大小和默认值进行操作:
template<typename T, size_t Size, size_t N, size_t... In, size_t... Isize>
constexpr std::array<T, Size> make_array_impl(const T(&user_supplied)[N], T default_value, std::index_sequence<In...>, std::index_sequence<Isize...>)
{
    return {user_supplied[In]..., (Isize, default_value)...};
}

template<typename T, size_t Size, size_t N>
constexpr std::array<T, Size> make_array(const T(&user_supplied)[N], T default_value)
{
    static_assert(N <= Size, "bla bla bla");
    return make_array_impl<T, Size> (user_supplied, default_value, std::make_index_sequence<N>{}, std::make_index_sequence<Size - N>{});
}

你可以这样使用它:

int main()
{
    auto arr = make_array<unsigned int, 1000>({4, 10, 34, 45, 6, 67}, UINT_MAX); // expands to arr = {4, 10, 34, 45, 6, 67, UINT_MAX... 994 times}
}

点击这里在Godbolt上试一试


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