C语言中的多维数组索引
我熟悉多维数组的访问方式:arr[rows][cols]当我把它想象成一个网格或坐标系和定位点时,这对我来说很有意义。但我对下面这句话感到困惑。我知道它正在拾取一个指向位于结构数组中的某个结构的指针,我只是很难想象它在我习惯的坐标系中代表了哪个位置……顺便说一下,这是一个位图,有些东西是像素C语言中的多维数组索引,c,arrays,pointers,multidimensional-array,C,Arrays,Pointers,Multidimensional Array,我熟悉多维数组的访问方式:arr[rows][cols]当我把它想象成一个网格或坐标系和定位点时,这对我来说很有意义。但我对下面这句话感到困惑。我知道它正在拾取一个指向位于结构数组中的某个结构的指针,我只是很难想象它在我习惯的坐标系中代表了哪个位置……顺便说一下,这是一个位图,有些东西是像素 //what does this line mean SOMETHING *o = original + row*cols + col; for (row=0; row < rows; ro
//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;
}
//这行是什么意思*o=original+row*cols+col;
对于(行=0;行<行;行++)
for(col=0;col
有一个名为original
的指针,它可能位于原点([0][0]
)。您正在进行简单的算术运算,以指向当前坐标
假设它是一个5x5数组,您现在位于第3行第4列([2][3]
)
要从起点到达[2][3]
,您必须旅行:
- 第一排有5个单元
- 第二排5个单元
- 第三节有3个单元
行*cols+col
为您提供2*5+3
即13
因此,如果您将
行*cols+col
单位从原点
移动到当前位置。思考一下数组在内存中的布局。多维数组只是数组的数组,所以假设您有一个类似于SOMETHING[10][10]
的数组
内存布局将是:
[0][0], [0][1], .. [0][9], [1][0], [1][1].. [9][9]
这实际上与分配(某物)*100的大小完全相同
行SOMETHING*o=original+row*cols+col
的意思是“创建一个指向类型为某物的对象的指针”
指针地址应为:
- 原始的内存地址
- 将行乘以cols添加到其中
将其放置在一行的开头
- 然后将特定列添加到其中
获取阵列中对象的确切位置的步骤
二维数组,例如:
{{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*(行中的元素)+j
事实上,您想象的二维网格实际上表示为连续的线性内存
因此,要访问索引(r,c)
处的坐标,您需要从数组的基址开始,然后将行索引(r)
乘以每行中的列数,跳到第r
行——同样,我们沿着线性方向移动。这将带您进入第r行的第一列。从这里开始,指针按c列递增,就到达了目的地
因此,在您的代码中,我假设original
是数组的开始。因此,该行:
original + row*cols + col
这正是我上面描述的。行-列坐标在与其他坐标混合时往往会导致一些混淆。。。例如,对于典型的图像坐标系,原点位于左上角
矩阵的坐标表示为(行、列)。这相当于图像坐标中的(y,x):通过增加向下的行数;递增列,对
在您的代码中,2D空间正好遵循C(行主调)和图像(按行)的典型约定。因此,您可以阅读:
SOMETHING* o = original + row*cols + col;
作为
最后请注意,这与在C中使用静态2D Arry相同,因此它们是等效的:
original[NROWS][NCOLS];
...
SOMETHING *o = &original[row][col];
或
在这种情况下,维度必须在编译时已知,这是一个非常重要的限制。在您的例子中,您正在处理C语言不支持的动态二维数组
最后,作为一个像素,让我猜猜
struct SOMETHING {
unsigned char r;
unsigned char g;
unsigned char b;
};
这意味着以两种方式之一寻址的任何元素只有3个字节长,并且它们只是连续排列。这是一个糟糕的变量名选择。请注意,要使其正常工作,原始
的类型必须是某物*
——而不是某物的二维数组。否则指针算术按行递增,而不是按SOMETHING
s递增,并给出一个数组(表示一行)而不是单个SOMETHING
元素。
SOMETHING original[HEIGHT][WIDTH];
...
SOMETHING *o = &original[iy][ix];
struct SOMETHING {
unsigned char r;
unsigned char g;
unsigned char b;
};