【问题标题】:Convention with rows and columns index for most of languages大多数语言的行和列索引约定
【发布时间】:2017-09-08 20:59:18
【问题描述】:

根据this link 上的问题,对于二维数组“x(i,j)”,考虑是否是一般规则(我的意思是大多数语言),第一个索引 i 表示行索引,索引 j 表示列索引?

我知道 Fortran 主要是列,C 语言主要是行,对于两者来说,经典约定似乎是 i = 行和 j = 列,不是吗?

此外,谁能告诉我 Matlab 是行专业还是列专业?

【问题讨论】:

  • 在 Matlab 中,第一个索引是行,第二个索引是列。
  • 否:Fortran 以一种方式看待它,而 C 以另一种方式看待它。这两种观点是对立的。
  • MATLAB 是 column major,因为它的 Fortran 根源。
  • C 没有二维数组这样的东西。如果你想的是一个数组数组,那就不完全一样了。

标签: c arrays matlab fortran


【解决方案1】:

这是一个误解。原始数据在内存中的分配方式与原始数据应该建模的高级表示之间没有关系。

C 对[i][j] 中的索引没有任何意义,它只是指定数据如何在内存中分配,而不是如何呈现给用户。 i 可以是行也可以是列,这是由程序员在他们的应用程序中指定的。

但是,C 确实将最右边的维度一起分配在内存中,例如:

int arr[2][3] = { {1,2,3}, {1,2,3} };

+-------+-------+-------+-------+-------+-------+
|       |       |       |       |       |       |
|   1   |   2   |   3   |   1   |   2   |   3   |
|       |       |       |       |       |       |
+-------+-------+-------+-------+-------+-------+

这意味着迭代这个矩阵的首选方法是:

for(size_t i=0; i<2; i++)
  for(size_t j=0; j<3; j++)
    arr[i][j] = x;

因为这个顺序提供了最快的内存访问,就缓存内存而言。但是该语言不强制执行此顺序,我们可以在外循环中使用 j 进行迭代,程序将正常运行(只是更慢)。

我们也无法判断这个矩阵应该是 2x3 还是 3x2。

【讨论】:

    【解决方案2】:

    对于 MATLAB,第一个索引是行,第二个是列。但是数组在内部以列优先顺序存储(非常早期的 MATLAB 版本是在 FORTRAN 中实现的;最初商业化时,它主要转换为 C,但保留了该约定)。

    【讨论】:

    • 你是说如果我这样做:`A = [1 2;3 4;5 6]`实际上在内部存储为1,3,5,2,4,6
    • 回答我自己,这似乎确实是这种情况,因为 matlab 允许在多维数组上使用单个(平面)索引,例如 A(3) -&gt; 5
    • 正确 - 这在 MATLAB 中称为线性索引。
    【解决方案3】:

    您的问题已回答here

    引用:

    总结:

    内存的“形状”在 C 和 Fortran 中完全相同,尽管由于反向数组索引导致语言差异使其看起来不同。

    如果您不按 k,j,i 顺序遍历 Fortran 数组,您将无序访问内存并对缓存性能产生负面影响。

    【讨论】:

    • 记忆的“形状”是什么意思?数据最终被有效地“扁平化”存储,这里相关的是索引方案,所以不清楚他们在做什么。
    猜你喜欢
    • 2018-02-15
    • 1970-01-01
    • 2016-03-17
    • 1970-01-01
    • 2014-02-12
    • 2017-10-19
    • 2014-06-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多