根据C标准(所以链接1和链接2),我们不能使用越界索引访问行中的元素:
int x[10][10] = ...; // initialize x
int q = x[0][10]; // This is an out-of-bounds access
那么使用下面的循环初始化数组是否有效?
int *p = &x[0][0];
for (int i = 0; i < 100; ++i)
p[i] = 0;
如果这是无效的,那么用memset(&x[0][0], 0, sizeof(x))
初始化x
是有效的吗?
int *p = &x[0][0];
memset(p, 0, sizeof(x))?
编辑:我想知道在c++中答案是否也不同…!:)
该循环无效,请参见@ ericdeferischil的注释。
是的,memset
方法也是有效的。但这不是首选的解决方案。它对单个字节进行操作,因此只能合理地用于内存归零。
- 值初始化
T array[10][10] = {};
将原语类型的数组归零,为类调用默认构造函数。 std::fill(p,p+100,value)
用于分配特定的值。没有标准的方法可以将数组初始化为非零值而不列出它们。std::array<T,N>
是已知大小数组的首选方式。
C
cppreference
C中没有对应于c++中值初始化的特殊构造;但是,可以使用={0}(或(T){0}在复合字面值中)(从C99开始),因为C标准不允许空结构体、空联合或零长度的数组。
因此,在嵌套数组的情况下,使用T array[10][10] = {{0}};
。
您在标题中问道:
我可以使用
memset
初始化一个二维数组吗?
是的,因为memset(...)
只关心字节数,你可以这样使用它:
int x[10][10];
memset(&x, 0, sizeof(x));
但是在C++
中,一个空的初始化列表也会做同样的事情,如:
int x[10][10] = {};
和在C
自C99(如在评论中提到),我们可以这样做,而不是:
int x[10][10] = {{0}};
不管怎样,你说:
int q = x[0][10];
//这是一个越界访问
int *p = &x[0][0]; for (int i = 0; i < 100; ++i) p[i] = 0;
是的,但只是因为你做了一些像设置为0这样简单的事情,更复杂的逻辑可能需要你进行二维循环,比如:
for (int x = 0; x < 10; ++x) {
for (int y = 0; y < 10; ++y) {
myArray[x][y] = something_more_complex_here;
}
}