索引2d数组到1d

时间:2017-04-07 14:00:25

标签: c arrays

我想将2d数组转换为1d。我把我的代码中最重要的部分。

int mask[3][3] = {{0, -1, 0}, {-1, 4, -1}, {0, -1, 0}}; 

for (i = 1; i < rows - 1; i++) {
    for (j = 1; j < cols - 1;j++) {
        int s;
            s = mask[0][0] * image[i-1][j-1]
                + mask[0][1] * image[i-1][j]
                + mask[0][2] * image[i-1][j+1]

                + mask[1][0] * image[i][j-1]
                + mask[1][1] * image[i][j]
                + mask[1][2] * image[i][j+1]

                + mask[2][0] * image[i+1][j-1]
                + mask[2][1] * image[i+1][j]
                + mask[2][2] * image[i+1][j+1];
    }
}

我的1d数组

for (k = rows + 1; k < (cols * rows) / 2; k++) {
  int s;
          s =  0 * image_in[k-rows-1]
          - 1 * image_in[k-rows]  
          + 0 * image_in[k-rows+1]

          - 1 * image_in[k-1]
          + 4 * image_in[k]
          - 1 * image_in[k+1]

          + 0 * image_in[k+rows-1]
          - 1 * image_in[k+rows]
          + 0 * image_in[k+rows+1];
} 

那应该是一样的,但我不知道我是否正确地进行了转换。有人可以告诉我,如果可以吗?

2 个答案:

答案 0 :(得分:1)

首先:为什么要放弃2D阵列?您认为2D数组维度必须是常量吗?那么,在那种情况下,我有一个好消息:你错了。这段代码应该可以完美运行:

int width = ..., height = ...;
//Create a 2D array on the heap with dynamic sizes:
int (*image_in)[width] = malloc(height * sizeof(*image_in));

//initialize the array
for(int i = 0; i < height; i++) {
    for(int j = 0; j < width; j++) {
        image_in[i][j] = ...;
    }
}

你会看到,除了数组指针有点神秘的声明之外,索引与堆栈上的自动2D数组保持完全相同。

在给定的循环中,您希望相对于中心单元格寻址单元格。通过相对于该单元格的实际寻址,这是最简单的方法:

for (i = 1; i < rows - 1; i++) {
    for (j = 1; j < cols - 1;j++) {
        int* center = &image_in[i][j];
        int s = mask[0][0] * center[-width - 1]
                + mask[0][1] * center[-width]
                + mask[0][2] * center[-width + 1]

                + mask[1][0] * center[-1]
                + mask[1][1] * center[0]
                + mask[1][2] * center[1]

                + mask[2][0] * center[width - 1]
                + mask[2][1] * center[width]
                + mask[2][2] * center[width + 1];
    }
}

这是因为2D数组与1D数组具有相同的内存布局(这由C标准保证)。

1D循环中的边处理始终是错误的:它将为每行的第一个和最后一个单元格执行循环体。 如果不在循环中引入一些if()语句,这将无法修复,这将显着减慢速度。

如果后果被证明无关紧要(您仍需要排除第一行和最后一行以及单元格),则可以忽略这一点。但是,如果您坚持使用2D阵列,边缘处理会更容易。

答案 1 :(得分:0)

如果代码的第一部分给出了预期的结果,那么你可以用这种方式对1d数组做同样的事情:

for (i = 1; i < rows - 1; i++) {
    for (j = 1; j < cols - 1;j++) {
        int s;
            s = mask[0][0] * image_in[i-1+rows*(j-1)]
                + mask[0][1] * image_in[i-1+rows*j]
                + mask[0][2] * image_in[i-1+rows*(j+1)]

                + mask[1][0] * image_in[i+rows*(j-1)]
                + mask[1][1] * image_in[i+rows*j]
                + mask[1][2] * image_in[i+rows*(j+1)]

                + mask[2][0] * image_in[i+1+rows*(j-1)]
                + mask[2][1] * image_in[i+1+rows*j]
                + mask[2][2] * image_in[i+1+rows*(j+1)];
    }
}

这样一来,如果你对2d数组很好,你可以使用1d数组做同样的事情,就好像它们是2d一样。