Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中的多维数组索引_C_Arrays_Pointers_Multidimensional Array - Fatal编程技术网

C语言中的多维数组索引

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

我熟悉多维数组的访问方式:arr[rows][cols]当我把它想象成一个网格或坐标系和定位点时,这对我来说很有意义。但我对下面这句话感到困惑。我知道它正在拾取一个指向位于结构数组中的某个结构的指针,我只是很难想象它在我习惯的坐标系中代表了哪个位置……顺便说一下,这是一个位图,有些东西是像素

//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个单元
总共13个单元

行*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;
};