//what does this line mean SOMETHING *o = original + row*cols + col;
for (row=0; row < rows; row++)
for (col=0; col < cols; col++) {
SOMETHING* o = original + row*cols + col;
SOMETHING* n = (*new) + row*cols + (cols-1-col);
*n = *o;
}
//what does this line mean SOMETHING *o = original + row*cols + col;
for (row=0; row < rows; row++)
for (col=0; col < cols; col++) {
SOMETHING* o = original + row*cols + col;
SOMETHING* n = (*new) + row*cols + (cols-1-col);
*n = *o;
}
想一想数组在内存中的布局方式。多维数组只是一个数组的数组,所以假设你有一个像SOMETHING[10][10]
这样的数组。
内存布局将会是:
[0][0], [0][1], .. [0][9], [1][0], [1][1].. [9][9]
这实际上与分配 sizeof(SOMETHING)*100
完全相同。
代码 SOMETHING* o = original + row*cols + col;
是在说“创建一个类型为 SOMETHING
的对象的指针”。
指针地址应该是:
original 的内存地址,
加上行数乘以列数,
这将把它放到一行的开头,
就可以到达数组中对象的确切位置了。
original
的类型需要是 SOMETHING *
,而不是 SOMETHING
的二维数组。否则,指针算术运算会按行递增,而不是按 SOMETHING
元素递增,并返回一个数组(表示一行),而不是单个的 SOMETHING
元素。 - Dmitri一个二维数组如下:
{{00,01,02,03},
{10,11,12,13},
{20,21,22,23},
{30,31,32,33}}
将按顺序放置在内存中。就像这样:
{00,01,02,03,10,11,12,13,20,21,22,23,30,31,32,33}
a[i][j]
访问数组时,您也可以使用 a + i *(ELEMENTS_IN_ROW) + j
访问该数组。有一个指针名为original
,它可能位于原点([0][0]
)。您正在进行简单的算术运算以指向当前坐标。
假设它是一个5x5的数组,现在您在第3行第4列([2][3]
)
要从原点到达[2][3]
,您必须移动:
总共13个单位。
row*cols + col
给出了2*5 + 3
即13
因此,如果您从origin
移动row*cols + col
个单位,则可以到达当前位置。
行列坐标在与其他不同的东西混合时往往会导致一些混淆...例如典型的图像坐标系统,其中原点是左上角。
矩阵的坐标表示为(行,列)。这相当于图像坐标中的(y,x):通过增加行数,向下移动;增加列数,向右移动。
在您的代码中,2D空间只是遵循C(行优先)和图像(按行)的典型约定。因此,您可以阅读:
SOMETHING* o = original + row*cols + col;
如下
SOMETHING* o = original + iy*width + ix;
original[NROWS][NCOLS];
...
SOMETHING *o = &original[row][col];
或者
SOMETHING original[HEIGHT][WIDTH];
...
SOMETHING *o = &original[iy][ix];
有一个非常重要的限制,即在这种情况下,维度必须在编译时知道。在您的情况下,您正在处理动态二维数组,这是C语言不支持的。
总之,如果SOMETHING是一个像素,让我猜一下...
struct SOMETHING {
unsigned char r;
unsigned char g;
unsigned char b;
};
这意味着以其中任何一种方式寻址的元素只有3个字节长,并且它们是连续排列的。
事实上,你所想象的二维网格实际上是由连续的线性内存表示的。
因此,要访问索引为(r,c)
的坐标,您需要从数组的基地址开始,然后通过将行索引(r)
乘以每行中的列数来跳到第r
行 - 再次强调,我们是在一个线性方向上移动。这将带您到第r行的第一列。从这里,您将指针递增c列,然后就到达了目的地。
因此,在您的代码中,我假设original
是您的数组的起始位置。因此,该行代码:
original + row*cols + col
正在准确地执行我上面所描述的操作。