Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторная работа №11_по функциям в си+.doc
Скачиваний:
2
Добавлен:
17.11.2018
Размер:
182.27 Кб
Скачать

Лабораторная работа ╧11

Функции пользователя

1. Цель работы

    Целью лабораторной работы является получение практических навыков в работе с функциями пользователя и передачей параметров функциям.

2. Темы для предварительной проработки

  • Указатели и массивы.

  • Функции пользователя.

3. Задания для выполнения

    Составить программу, которая решает задачу для лабораторной работы ╧10 с такими дополнительными условиями:

  • размерность матрицы должна вводиться при выполнении программы;

  • само решение задачи должно быть оформлено в виде функции, которой передается матрица и ее размерность.

4. Варианты индивидуальных заданий

Представлены в работе

 №10

и в конце файла.

5. Пример решения задачи (вариант 30)

    Решение приводится со ссылками на по двумерным массивам (матрицам).

5.1. Разработка алгоритма решения.

    Сам алгоритм решения мог бы быть тем же, что и в работе ╧9. Но обратим внимание на то, что условие этой работы несколько отлично от условия работы ╧9. Если в работе ╧9 мы имели фиксированную размерность матрицы, то тут у нас размерность матрицы заранее не известна. Составляет ли это существенное различие? Да. Если мы проверим функционирования алгоритма работы ╧9 при разных значениях размерности (S), то мы убедимся, что корректно он срабатывает только при нечетных значениях S. При четных значениях верхняя половина матрицы формируется правильно, а в нижней половине область ненулевых значений будет захватывать также и сами диагонали, что не соответствует условиям задания. Поэтому для этой работы следует пересмотреть алгоритм.

    Для элемента, который лежит на главной диагонали, индексы удовлетворяют условию: L=R, на побочной - R=S-L-1. Следовательно, для верхней половины условие попадания в ненулевую область: L < R < S-L-1, а для нижней: S-L-1 < R < L. Или, обобщая: min(L,S-L-1) < R < max(L,S-L-1) . В схеме алгоритма, которая приведена на рисунке 1, мы используем именно это условие. К тому же в схеме отражено разделение программы на две функции: главную функцию - main(), которая выполняет выделения памяти для матрицы, вызов функции заполнения матрицы и вывод результата, и функцию fill(), которая выполняет заполнение матрицы по заданным правилам.

    

Рисунок 1. Схема алгоритма

В этой работе ми несколько усложним алгоритм, добавив в него проверку значения S, которое введено оператором (блоки 3 - 8). Нижняя граница для значения S - 1, поскольку матрица нулевой или отрицательной размерности просто не имеет смысла. Верхняя граница - 24, поскольку для матрицы большего размера невозможно будет обеспечить наглядный вывод (она не поместится на экране).

5.2. Представление матрицы в памяти

Возможно представлять матрицу в программе как двумерный массив - естественное представление матрицы. Но при условии динамического размещения в памяти ее представление уже не такое простое. Возможны три варианта размещения в памяти и представления матрицы в программе. Во всех трех вариантах очевидно, что общий объем памяти для размещения данных матрицы должен быть S2 элементов типа int.

    Вариант 1 показан на рис.2

    Рисунок 2. Размещение в памяти. Вариант 1.

Для данных матрицы выделяется необходимый объем памяти. В программе объявляется указатель на начало этой области. Тип этого указателя - int*. Таким образом, матрица является одномерным массивом и для того, чтобы по номеру строки (L) и столбца (R) определить индекс в одномерном массиве (N) следует выполнить вычисление: N=L*S+R.

    Вариант 2 показан на рис.3.

    

Рисунок 3. Размещение в памяти. Вариант 2.

Память для данных матрицы выделяется так же, как и в предыдущем случае. Но дополнительно выделяется память для одномерного массива размерности S, элементы которого имеют тип int* (указатель на целое). Указатель на начало этого массива имеет тип int** (указатель на указатель на целое). В элементы этого массива записываются указатели на начала соответствующих строк в массиве данных матрицы. В этом варианте можно обращаться к данным матрицы, указывая номера строки и столбца как два индекса в массиве указателей.

    Вариант 3 показан на рис.4.

    Рисунок 4. Размещение в памяти. Вариант 3

Этот вариант отличается от предыдущего тем, что для каждой строки матрицы память выделяется отдельно (S областей памяти по S элементов в каждой), и в массив указателей заносятся указатели на соответствующие области. Таким образом, матрица необязательно занимает смежные области памяти. Можно обращаться к данным матрицы, указывая два индекса. Выделение памяти (и соответственно - освобождение) нужно выполнять в цикле. Вариант 1 обеспечивает экономию памяти, а варианты 2 и 3 - возможность "естественного" обращения к элементам матрицы. Вариант 3 позволяет рациональнее использовать память, чем вариант 2, но вариант 2 алгоритмически более простой. Мы покажем реализации алгоритма для вариантов 1 и 3.