假设我有一个全局声明的 3d 数组(在数据段中),我想将它的 1d 内存设置为 0。

int multi_dimension_array[x][y][z];

我可以用这条线 memset 整个事情:

memset(multi_dimension_array, 0, sizeof(multi_dimension_array));

但是现在假设我只想为某个值(比如 2)设置 x 维度,这意味着 multi_dimension_array[2][0][0] 到 multi_dimension_array[2][y-1][z-1] 的值应该全部为零。我不认为有一种聪明的方法可以将 memset 用于 y 或 z,因为它们不连续。以下行应该有效:

memset(&multi_dimension_array[2][0][0], 0, sizeof(multi_dimension_array[2][0][0]) * y * z);

我的“问题”是我不喜欢 memset 参数的 * y * z 部分。数组中是否有表示 sizeof(multi_dimension_array[2]) == byte_size_of_type * y * z 的内容?

在这个例子中,我想使用数组的一个属性,sizeof 会计算出“x”维度的正确字节数。我不想在有人更改声明中的大小并且他们不更改此 memset 的情况下使用 * y *z,而且我不喜欢它的外观。


memset(&multi_dimension_array[2], 0, sizeof multi_dimension_array[2]);

这要求它multi_dimension_array[i]是数组数组的数组,而不是指针。它之所以有效,是因为当sizeof应用于数组时,它会返回数组的大小。数组不会像大多数表达式那样自动转换为指针。

当然,它只适用于第一个维度(或者前几个维度,如果你做的不止一个)。例如,您可以将一个 memset 与array[i]array[i][j]但不与中间维度一起使用,例如array[???][j].


对于这个问题的未来读者,Eric Postpischil 的回答是正确的,我已经接受了,因为它是。下面是一个示例程序和输出,用于演示适用于多维数组的 sizeof 运算符/函数。一般来说,如果声明为整数数组

int mda[x][y][z]; 
then mda[a][b][c] == *(mda + ((a *( y* z)) + (b*z) + (c))

重要的是,至少对于我问的原始问题来说,索引到比您的程序声明的“维度”更少的数组仍然会编译和维护下一个数组的“sizeof”。

mda[a] == *(mda + (a * (y*z))) AND sizeof(mda[a]) == sizeof(array_type) * y * z
mda[a][b] == *(mda + (a * (y*z)) + (b * z)) AND sizeof(mda[a][b]) == sizeof(array_type) * z

好的,下面是一个示例程序,您可以在在线 IDE 中运行并验证:

#include <stdio.h>

#define X (4)
#define Y (10)
#define Z (5)
int multi_dimension_array[X][Y][Z];

void print_array(){
    for(int i=0; i<X; i++){
        printf("THIS IS THE %dth value of X\n", i);
        for(int j=0; j<Y; j++){
            for(int k=0; k<Z; k++){
                printf("%d ", multi_dimension_array[i][j][k]);
            }
            printf("\n");
        }
    }
}

int main(void) {
    printf("%d %d %d %d\n", sizeof(multi_dimension_array[0][0][0]), sizeof(multi_dimension_array[0][0]), sizeof(multi_dimension_array[0]), sizeof(multi_dimension_array));

    memset(multi_dimension_array,0x01,sizeof(multi_dimension_array));
    print_array();

    memset(&multi_dimension_array[2],0x0,sizeof(multi_dimension_array[2]));

    printf("\n\n\nNEXT MEMSET with the X=2 zeroed out\n\n\n");
    print_array();

    return 0;
}

这是这个程序的输出:

4 20 200 800
THIS IS THE 0th value of X
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
THIS IS THE 1th value of X
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
THIS IS THE 2th value of X
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
THIS IS THE 3th value of X
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 



NEXT MEMSET with the X=2 zeroed out


THIS IS THE 0th value of X
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
THIS IS THE 1th value of X
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
THIS IS THE 2th value of X
0 0 0 0 0 
0 0 0 0 0 
0 0 0 0 0 
0 0 0 0 0 
0 0 0 0 0 
0 0 0 0 0 
0 0 0 0 0 
0 0 0 0 0 
0 0 0 0 0 
0 0 0 0 0 
THIS IS THE 3th value of X
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 
16843009 16843009 16843009 16843009 16843009 

*请注意,memset 将每个字节设置为第二个参数的值,在本例中为 0x01,这使得 4 字节整数 0x01010101 == 16843009。


一般来说,你不能这样做。我将在二维示例中进行解释。数组是逐行存储的。如果你想将第二行设置为某个值,你可以使用 memset,因为该行是连续的块哦内存,但如果你想设置第二列,你不能,因为该列不是连续的。你需要迭代。nD 阵列也一样

感谢你的回答。考虑数组下标背后的隐式指针算法,很明显为什么会这样。