#matrix #language-agnostic #terminology
#матрица #язык не зависит от языка #терминология
Вопрос:
Я думаю, что обнаружил широко распространенное недоразумение (профессора делают это неправильно!). Люди говорят, что 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("%.7gt",A[k][l]);}
putchar('n');
}
Почему он печатается по строкам? Потому что ‘n’ перемещается в следующую строку, а не в следующий столбец. Если ‘n’ было интерпретировано как «перейти к следующему столбцу и первой строке», а ‘t’ перейти к следующей строке, то A печатается по столбцам. Но я знаю, что мой терминал ориентирован на строки, поэтому, если я хочу печатать по столбцам, единственный способ — поменять местами эти циклы.
Если A [k] логически представляет строку или столбец, зависит от функций, которые работают с A, а затем есть компромисс, какой порядок выбрать. Например, исключение Гаусса rows{column,rows{column}}
. Преимущество размещения индекса строки в первую очередь заключается в том, что это упрощает замену строк при повороте. Однако для выполнения поворота необходимо перебирать все строки в одном столбце, что должно быть быстрее, если выбрать противоположное. Самый внутренний цикл исключения имеет доступ к двум строкам одновременно, и ни одна из них не является действительно хорошей.
Лучшей терминологией, вероятно, является индексация по первому индексу и индексация по последнему индексу. Это чисто языковая особенность: индексация по первому индексу относится к ситуации, когда предполагается, что первый заданный индекс увеличивается медленнее всего, в то время как индексация по последнему индексу противоположна. «Строки» и «столбцы» — это проблема интерпретации, очень похожая на порядок байтов и кодировки символов: компилятор никогда не узнает, что такое строка или столбец, но он может иметь определенный языком порядок ввода (большинство языков принимают числовые константы в порядке большого конца, но моему компьютеру нужен маленький конец).). Эти термины взяты из соглашений в среде и библиотечных подпрограммах.
Комментарии:
1. Я тоже часто думал об этом, и я согласен. На самом деле порядок индексов определяется языком, а не фактическим 2d-расположением данных (потому что в любом случае все это просто линейно). Люди яростно возражают против этого мнения в Интернете и предполагают, что вы в замешательстве. Решаете ли вы называть первый или последний индекс «строкой», зависит от вас.
2. Но, как примечание, вы будете против установленного стандарта… поэтому большинство библиотек будут использовать 2d-макет для вашей линейной памяти.
3. @JonathanOlson я нашел другую неплохую терминологию: AoS и SoA. Хотя столбцы матрицы не имеют «имен», они могут быть коэффициентами для линейной системы уравнений. Таким образом, вы можете присвоить им соответствующее имя.
Ответ №1:
Это не имеет ничего общего с тем, как работает ваш текстовый редактор, и все связано с тем, как элементы 2D-массива расположены в памяти. Это, в свою очередь, определяет, является ли более эффективным для вложенных циклов (перебор всех элементов матрицы) более эффективным с циклом строк в качестве внутреннего цикла или с циклом столбцов в качестве внутреннего цикла.
Комментарии:
1. Я указываю на то, что в памяти нет строк или столбцов. Все, что есть, это массив цифр. Строки и столбцы являются только представлением данных.
Ответ №2:
Как предположил один из комментаторов, на самом деле это просто порядок индексов в синтаксисе доступа к массиву, который делает C основным для строк.
Вот лучший пример программы, которая инициализирует 2D-массив, используя плоский список значений.
#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] = %dn", arr[0][1]);
}
Итак, теперь мы можем избежать путаницы, добавленной синтаксисом объявления 2D-массива или тем, как этот синтаксис изложен в текстовом редакторе. Нас просто интересует, как C интерпретирует линейный список значений, которые мы поместили в память.
И если мы запустим программу, мы увидим:
$ ./a.out
arr[0][1] = 2
Это то, что делает C основным строкой. Тот факт, что синтаксис массива интерпретируется как [строка] [столбец] при доступе к данным в памяти.