以下是我正在使用的内容:
class something
{
char flags[26][80];
} a;
std::fill(&a.flags[0][0], &a.flags[0][0]+26*80, 0);
(更新:我之前应该已经明确表示我正在课堂上使用它。)
答案 0 :(得分:18)
初始化为0
数组的简单方法是定义:
char flags[26][80] = {};
如果您想使用std::fill
,或者想要重置数组,我会发现这一点好一点:
char flags[26][80];
std::fill( &flags[0][0], &flags[0][0] + sizeof(flags) /* / sizeof(flags[0][0]) */, 0 );
根据数组大小表示的fill
将允许您更改维度并保持fill
不变。 sizeof(flags[0][0])
在您的情况下为1
(sizeof(char)==1
),但您可能希望将其保留在那里,以防您想在任何时候更改类型。
在这种特殊情况下(标志数组 - 整数类型)我甚至可以考虑使用memset
,即使它是安全最少的选择(这个如果数组类型更改为非pod类型,则会中断):
memset( &flags[0][0], 0, sizeof(flags) );
请注意,在所有三种情况下,数组大小只键入一次,编译器会推断其余的。这是更安全,因为它为程序员错误留下了更少的空间(在一个地方改变大小,在其他地方忘记它)。
编辑:你已经更新了代码,因为它不会编译,因为数组是私有的,你试图在外部初始化它。根据您的类实际上是一个聚合(并希望保持这样),或者您是否要在该类中添加构造函数,您可以使用不同的方法。const std::size_t rows = 26;
const std::size_t cols = 80;
struct Aggregate {
char array[rows][cols];
};
class Constructor {
public:
Constructor() {
std::fill( &array[0][0], &array[rows][0], 0 ); // [1]
// memset( array, 0, sizeof(array) );
}
private:
char array[rows][cols];
};
int main() {
Aggregate a = {};
Constructor b;
}
即使array
是公开的,使用构造函数可能是更好的方法,因为它将保证array
在类的所有实例中正确初始化,同时外部初始化取决于用户代码,不要忘记设置初始值。
[1]正如@Oli Charlesworth在评论中所提到的,使用常数是一个不同的解决方案,必须在不止一个地方陈述(并保持同步)大小。我在这里使用了一种不同的组合:通过请求第一列的地址超出二维数组,可以获得指向二维数组外部的第一个字节的指针。我使用这种方法只是为了表明它可以完成,但它没有比&array[0][0]+(rows*cols)
答案 1 :(得分:2)
它是安全的,二维数组是一个数组数组。由于数组占用了连续的存储空间,所以整个多维事物也会如此。所以是的,没关系,安全和便携。假设您没有询问其他答案所涵盖的样式(因为您使用的是旗帜,我强烈建议std::vector<std::bitset<80> > myFlags(26)
)
答案 2 :(得分:1)
使用
std::fill
填充多维数组的安全方法是什么?
简单的默认初始化为using braced inilization。
char flags[26][80]{};
上面的代码会将flags
中的所有元素初始化为默认字符。
std::fill
或std::fill_n
的二维数组填充但是,为了提供不同的值来初始化以上是不够的。选项为std::fill
和std::fill_n
。 (假设数组flags
在您的课程中是public
)
std::fill(
&a.flags[0][0],
&a.flags[0][0] + sizeof(a.flags) / sizeof(a.flags[0][0]),
'0');
// or using `std::fill_n`
// std::fill_n(&a.flags[0][0], sizeof(a.flags) / sizeof(a.flags[0][0]), '1');
要对具有任何初始化值的任何类型的任何 2d数组进行概括,我建议使用a templated function,如下所示。这也将避免对数组中的所有元素进行sizeof
计算。
#include <algorithm> // std::fill_n, std::fill
#include <cstddef> // std::size_t
template<typename Type, std::size_t M, std::size_t N>
constexpr void fill_2D_array(Type(&arr2D)[M][N], const Type val = Type{}) noexcept
{
std::fill_n(&arr2D[0][0], M * N, val);
// or using std::fill
// std::fill(&arr2D[0][0], &arr2D[0][0] + (M * N ), val);
}
现在您可以像这样初始化flags
fill_2D_array(a.flags, '0'); // flags should be `public` in your class!
std::fill
或std::fill_n
的3-D数组填充在上述模板函数中再添加一个非模板大小参数,也可以将其引入 3d-array s
#include <algorithm> // std::fill_n
#include <cstddef> // std::size_t
template<typename Type, std::size_t M, std::size_t N, std::size_t O>
constexpr void fill_3D_array(Type(&arr3D)[M][N][O], const Type val = Type{}) noexcept
{
std::fill_n(&arr3D[0][0][0], M * N * O, val);
}
答案 3 :(得分:0)
char[80]
是否应该替代真正的字符串类型?在这种情况下,我建议如下:
std::vector<std::string> flags(26);
flags[0] = "hello";
flags[1] = "beautiful";
flags[2] = "world";
// ...
或者,如果你有一个支持初始化列表的C ++编译器,例如最近的g ++编译器:
std::vector<std::string> flags { "hello", "beautiful", "world" /* ... */ };
答案 4 :(得分:-1)
char flags[26][80];
std::fill((char*)flags, (char*)flags + sizeof(flags)/sizeof(char), 0);