【问题标题】:Is row-major and column-major order really a property of a programming language行优先和列优先顺序真的是编程语言的属性吗
【发布时间】:2014-08-08 23:12:53
【问题描述】:

我想我发现了一个普遍的误解(教授们做错了!)。人们说 C 和 C++ 以行优先顺序和 Fortran 列优先顺序表示矩阵。但我怀疑 C 和 C++ 是否按主要顺序构建,因为没有真正的矩阵类型?如果我输入

int A[2][3] = { {1, 2, 3}
              , {4, 5, 6} };

顺序主要是行,因为我的编辑器是面向行的而不是面向列的。这与语言本身无关,或者有吗?如果编辑器是面向列的:

i {
n { {
t 1 4
  , ,
A 2 5
[ , ,
2 3 6
] } }
[   ;
3 
]
=

现在矩阵 A 有两列和三行。

为了进一步说明,考虑一个矩阵打印循环

for(int k=0; k<M; ++k)
    {
    for(int l=0; l<N; ++l)
        {printf("%.7g\t",A[k][l]);}
    putchar('\n');
    }

为什么它按行打印?因为'\n'移动到下一行而不是下一列。如果 '\n' 被解释为“转到下一列和第一行”并且 '\t' 转到下一行,则按列打印 A。但我知道我的终端是面向行的,所以如果我想按列打印,唯一的方法就是交换这些循环。

如果 A[k] 逻辑上 表示行或列取决于对 A 进行操作的函数,然后需要权衡选择什么顺序。例如高斯消去走rows{column,rows{column}}。首先放置行索引的优点是它可以在旋转时更容易地交换行。但是,要执行旋转,必须遍历同一列中的所有行,选择相反的应该会更快。最里面的消除循环一次可以访问两行,但都不是很好。

更好的术语可能是first-index indexinglast-index indexing。这是一个纯语言特性:第一个索引索引是指第一个给定索引应该增加最慢的情况,而最后一个索引索引则相反。 “行”和“列”是一个解释问题,很像字节顺序和字符编码:编译器永远不会知道行或列是什么,但它可能具有语言定义的输入顺序(大多数语言碰巧接受大端的数字常量订购,但我的电脑需要小端序)。这些术语来自环境和库例程中的约定。

【问题讨论】:

  • 我也经常考虑这个问题,我同意。它实际上是语言定义的索引顺序,而不是数据的实际二维布局(因为无论如何它都是线性的)。人们在网上激烈地反对这种观点,并认为你是一个困惑的人。是否选择将第一个或最后一个索引称为“行”取决于您。
  • 但请注意,您将违反既定标准...所以大多数库会为您的线性内存假定 2d 布局。
  • @JonathanOlson 我发现了另一个非常好的术语:AoS 和 SoA。尽管矩阵列没有“名称”,但它们可能是线性方程组的系数。所以你可以给他们一个合适的名字。

标签: matrix language-agnostic terminology


【解决方案1】:

这与您的文本编辑器的工作方式无关,而是与 2D 数组的元素在内存中的布局方式有关。这反过来决定了嵌套循环(循环遍历矩阵的所有元素)是否更有效,行循环作为内循环还是列循环作为内循环。

【讨论】:

  • 我指的是内存中没有行或列。只有一个数字数组。行和列只是数据的表示。
【解决方案2】:

正如一位评论者所建议的,实际上只是数组访问语法中的索引顺序使 C 成为行优先。

这是一个更好的示例程序,它使用平面值列表初始化二维数组。

#include <stdio.h>
#include <string.h>

int main() {
    int data[9] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    int arr[3][3];
    memcpy(arr, data, sizeof(int)*9);

    printf("arr[0][1] = %d\n", arr[0][1]);
}

所以现在我们可以避免二维数组声明语法带来的任何混淆,或者该语法在文本编辑器中的布局方式。我们只关心 C 如何解释我们塞入内存的线性值列表。

如果我们运行程序,我们会看到:

$ ./a.out 
arr[0][1] = 2

这就是 C 行主要的原因。访问内存中的数据时,数组语法被解释为 [row][column]。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多