Матрицы в Си
Матрица это набор объектов, которые хранятся в виде таблицы. У каждой матрицы есть имя, единый тип всех ее объектов.
Обявление матрицы в Си
Также как и переменные матрицу в Си необходимо объявить перед тем как с ней работать, необходимо указать ее тип, ее имя , количество строк -1 и количество столбцов -1. Нумерация столбцов и строк идет с 0.
Тип матрицы Имя [количество строк-1][количество столбцов-1];
int A[8][9] ; / /объявляет целочисленную матрицу с именем A , у которой 9 строк и 10 столбцов
После объявления матрицы, с ее элементами можно работать. Чтобы обратитсья к элементу матрицы нужно указать имя матрицы в первых квадратных скобках указать номер строки, во вторых квадратных скобках указать номер столбца.
A[0][1]=10; // элементу матрицы с номер строки 0 и столбца 1 присваивается значение 10
printf(“%d”, A[0][1]);// выводит на экран элемент матрицы с номер строки 0 и столбца 1
Задание матрицы в Си
Чтобы работать с матрицей в Си, необходимо присвоить начальные значения всех ее элементов.
Для работы со всеми элементами матрицы используется вложенные циклы for
В главном цикле “пробегаем” по всем строкам, а во вложенном “пробегаем” по всем столбцам для каждой строки.
// “пробегаемся” по всем строкам. Нумерация строк с 0.
for (i=0; i < количество строк; i++)
// вложенный цикл, “пробегаемся” по всем столбцам для Нумерация столбцов с 0.
for (j=0; j < количество столбцов; j++)
…Имя матрицы [i][j]…// работаем с элементом матрицы с номером строки i и номером столбца j
Пример программы 22. Программа задаёт целочисленную матрицу размером 10 на 10 и заполняет ее случайными числами в диапазоне, который укажет пользователь и выводит ее на экран.
int a[9][9]; // объявление матрицы 10 на 10
int i,j; // счетчики циклов
int range;// диапазон в котором присваиваются значения элементов матрицы
//ввод диапазона случайных чисел
printf("введите диапазон заполнения\n");
// пробегаем по всем строкам
// пробегаем по всем столбцам для данной строки i
a[i][j]=rand() % range+1; // прсиваиваем элементу матрицы a с номером строки i и номер столбца j случайного значения в диапазоне от 0 до 9
// пробегаем по всем строкам
// пробегаем по всем столбцам для данной строки i
// переход на следующую строку
При выводе матрицы на экран в Си для каждой строки мы совершаем переход на следующую строку с помощью оператора printf(" ");
Ввод матрицы в Си с помощью клавиатуры
Пример программы 23. Задаётся матрица размера 3 на 3 с помощью клавиатуры и ищется ее максимальный элемент. Он выводится на экран. При поиске максимального элемента, мы создаем специальную переменную max и присваиваем ей значение элемента a[0][0]. Пробегаем по всем элементам матрицы с помощью вложенного цикла, сравнивая текущий элемент с максимумом, если текущий элемент больше максимума, то максимуму присваивается значение этого элемента.
int a[2][2]; // объявление матрицы 3 на 3
int i,j; // счетчики циклов
int max; // переменная для хранения максимального элемента матрицы
// пробегаем по всем строкам
// пробегаем по всем столбцам для данной строки i
// ввод текущего элемента матрицы с клавиатуры
printf("Введите элемент матрицы [%d][%d]", i, j);
// переход на следующую строку
// пробегаем по всем строкам
// пробегаем по всем столбцам для данной строки i
// переход на следующую строку
// пробегаем по всем строкам
// пробегаем по всем столбцам для данной строки i
// сравниваем текущий элемент массива с максимумом
// вывод максимального элемента
printf ("Максимальный элемент массива %d", max);
Вернуться к содержанию
Перейти к теме Работа с файлами в Си
Полезно почитать по теме массивы и матрицы в си
Массивы в си
Игра на си Крестики Нолики
Лекция 13
Допустим нам необходимо создать матрицу 3×4, тогда мы можем попробовать реализовать её следующим образом.
Но так сделать не получится, потому что произойдёт ошибка компиляции: мы не определили конструктор по умолчанию. Необходимо добавить в класс myvector следующую строку.
Теперь мы имеем 3 экземпляра класса myvector с размером 0. Чтобы увеличить размер всех векторов выполним для каждого из них resize() .
В данном случае значение элемента будет присваиваться по ссылке, поэтому передаваемый объект будет очень маленьким.
Рассмотрим, как данная матрица будет выглядеть в памяти.
Будет ли данная динамическая память возвращена системе?
При выходе из блока < … m[1][2] = 777; >, будет вызван деструктор
m() выполняющий delete[] data .
Замечание. Если data является массивом объектов некоторого класса, тогда до возврата своей памяти он вызывает деструкторы всех элементов этого массива. То есть сначала будут освобождены массивы int , а за тем массив data .
Реализация класса matrix
Если в списке инициализации мы забыли вызвать конструктор подобъекта являющегося объектом другого класса, то сгенерируется код вызывающий конструктор этого объекта по умолчанию.
Деструктор для данного класса писать не надо. Будет сгенерирован деструктор по умолчанию
Правило. Деструкторы всех подобъектов вызываются автоматически в эпилоге (перед закрытием фигурной скобки деструктора основного объекта). Первым вызовется деструктор основного объекта. Деструкторы вызываются в порядке обратном порядку вызова конструкторов. То есть последовательность вызовов конструкторов и деструкторов будет следующая.
- Конструктор подобъекта
- Конструктор основного объекта
- Деструктор основного объекта
- Деструктор подобъекта
Операция доступа по индексу в matrix
m[1, 2] — в C++ так писать нельзя
m[1][2] — класс matrix не контролирует [2]
Поэтому лучше всего перегрузить operator() , тогда обращение по индексу будет выглядеть следующим образом m(1, 2) .
Так как operator() будет inline -функцией, то в результате вызов m(1, 2) будет преобразован следующим образом:
Конструктор копий и operator= для класса matrix
Их писать не нужно. Они сгенерируются автоматически и будут работать правильно. Конструктор копии и operator= необходимо писать вручную, только если мы в конструкторе данного класса выделяем динамическую память, а в деструкторе ее явно возвращаем. Если в классе есть подобъект, который берет на себя все функции, то определять эти члены не нужно.
Как работают автоматически сгенерированные конструктор копии и операция присваивания?
Автоматически сгенерированный конструктор копии вызывает конструкторы копий для всех своих полей. Автоматически сгенерированная операция присваивания вызывает операции присваивания для всех своих полей.
C#: Класс "Матрица" (сложение, вычитание, умножение матриц)
Данный класс позволяет производить некоторые операции над матрицами:
- Сложение матрицы А с матрицой Б
- Вычитание матрицы Б из матрицы А
- Умножение матрицы А на матрицу Б
- Умножение матрица А на число
- Проверка матрицы А на единичность
- Выполнение нексольких операций над матрицами одновременно, образуя матрицу D
Так же он содержит операторы перегрузки и скрытые поля для соблудения инкапсуляции.
A proper way to create a matrix in c++
I want to create an adjacency matrix for a graph. Since I read it is not safe to use arrays of the form matrix[x][y] because they don’t check for range, I decided to use the vector template class of the stl. All I need to store in the matrix are boolean values. So my question is, if using std::vector<std::vector<bool>* >* produces too much overhead or if there is a more simple way for a matrix and how I can properly initialize it.
EDIT: Thanks a lot for the quick answers. I just realized, that of course I don’t need any pointers. The size of the matrix will be initialized right in the beginning and won’t change until the end of the program. It is for a school project, so it would be good if I write «nice» code, although technically performance isn’t too important. Using the STL is fine. Using something like boost, is probably not appreciated.
10 Answers 10
Note that also you can use boost.ublas for matrix creation and manipulation and also boost.graph to represent and manipulate graphs in a number of ways, as well as using algorithms on them, etc.
Edit: Anyway, doing a range-check version of a vector for your purposes is not a hard thing:
Note that you would also need to add the const version of the operators, and/or iterators, and the strange use of exceptions, but you get the idea.