
5.3. Определение переменных программы (вариант 1)
Программа будет состоять из двух функций - main() и fill(). В соответствии с принципом модульности желательно, чтобы функции имели минимальное количество общих переменных, и здесь мы имеем возможность обойтись совсем без них. Все переменные, с которыми работают наши функции, будут локальными переменными функций или параметрами.
Переменные для функции main().
Указатель на начало линейного массива, в котором размещаются данные матрицы:
int *Ar;
Размерность массива:
int S;
Общее количество элементов массива (его использование будет видно из текста программы):
int size;
Указатель на текущий элемент массива при его выводе:
int *Cr;
Счетчик выведенных элементов:
int i;
Параметры для функции fill().
Указатель на начало линейного массива, в котором размещаются данные матрицы:
int *A;
Размерность массива:
int s;
Переменные для функции fill().
Указатель на текущий элемент массива при его обработке:
int *C;
Номера строки и столбца:
short l, r;
Текущий член линейной последовательности:
int k=1;
5.4. Разработка текста программы (вариант 1)
Текст программы начинаем с включения файлов: stdio.h, alloc.h, stdlib.h (в последнем определены макросы max и min).
Включаем описание функции fill() и открываем главную функцию. В главной функции объявляем ее локальные переменные, выводим приглашение и вводим значение размерности матрицы S. Размерность сравнивается с нижней и с верхней границей и, если она выходит за границы, выводится соответствующее сообщение и программа завершается (функцией exit()). Если S удовлетворяет установленным условиям, его значение выводится на экран.
Потом выделяется память для размещения матрицы. Для этого вызывается функция malloc(). Ей передается размер памяти в байтах, который нужен для размещения S2 элементов типа int. Функция malloc() возвращает указатель на выделенную область памяти, значение этого указателя записывается в переменную Ar - это будет указатель на начало массива, в котором разместятся данные матрицы. Если значение, которое вернула функция malloc(), - пустой указатель, это признак того, что памяти не хватает, в этом случае видается сообщение и программа завершается.
Оператор:
fill(Ar,S);
- обращение к функции заполнения матрицы. Функции передаются: указатель на начало массива и размерность матрицы.
После возврата управления из функции fill() уже готовая матрица выводится на экран. При выводе матрица рассматривается как линейный массив из S2 элементов. Счетчик i меняется от 0 до S2-1. Но обращение к элементам матрицы в этом цикле ведется через указатель Cr. В начальных установках этот указатель устанавливается на начало массива, а после каждой итерации увеличивается на 1, т.е. сдвигается на следующий элемент массива. Счетчик i используется для определения момента выхода из цикла, а также для перехода на новую строку экрана после вывода каждых S элементов - для этого проверяется условие: i%S==S-1.
Последним действием в функции main() является освобождение с помощью функции free() выделенной ранее памяти.
Функция fill() получает параметры - указатель на начало массива и размерность матрицы. Тело функции начинается с объявления ее локальных переменных, переменная k получает начальное значение при объявлении.
Далее в функции организуются вложенные циклы для перебора строк и столбцов. Но номера строки и столбца используются не для обращения к элементам матрицы, а только для проверки, попадает ли элемент в нулевую или ненулевую область (в точном соответствии условиям, приведенным в п.5.2). Обращение к элементам матрицы ведется через указатель C, который указывает на текущий элемент матрицы. Этот указатель устанавливается на начало массива в начальных установках внешнего цикла и увеличивается на 1 в конце каждой итерации внутреннего цикла.
Полный текст программы приведен ниже.
/***************************************************/
/* Лабораторная работа #8 */
/* Функции */
/* Пример выполнения. Вариант #19. */
/* Вариант реализации 1 */
/***************************************************/
#include <cstdlib>
#include <iostream>
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
void fill(int *, int);
using namespace std;
int main(int argc, char *argv[])
{ int *Ar,
*Cr; /* текущий указатель у массиве */
int i, /* счетчик элементов */
S; /* размерность матрицы */
/* ввод размерности */
printf("Введите размерность матрицы >");
scanf("%d",&S);
/* проверка размерности */
if (S<=0) {
printf("Размерность слишком мала\n");
exit(0);
}
if (S>24) {
printf("Размерность слишком велика\n");
exit(0);
}
printf("S=%d\n",S);
/* выделение памяти */
if ((Ar=(int *)malloc(sizeof(int)*S*S))==NULL) {
printf("Недостаток памяти\n");
exit(0);
}
/* обращение к функции заполнения матрицы */
fill(Ar,S);
/* вывод матрицы */
for (Cr=Ar, i=0; i<S*S; Cr++,i++) {
printf("%3d",*Cr);
if (i%S==S-1) putchar('\n');
}
/* освобождение памяти */
free(Ar);
system("PAUSE");
return EXIT_SUCCESS;
// return 0;
}
/*** функция заполнения матрицы ***/
/* параметры: A - указатель на начало массива
s - размерность матрицы */
void fill(int *A, int s) {
int *C; /* текущий указатель в массиве */
int l, r; /* строка и столбец */
int k=1; /* текущий член ЛП */
for (l=0,C=A; l<s; l++) /* перебор строк */
for (r=0; r<s; r++, C++) /* перебор столбцов */
/* условие нулевого значения */
if ((r>=max(l,s-l-1))||(r<=min(l,s-l-1))) *C= k++;
else *C=0;
/* конец перебора строк */
/* конец перебора столбцов */
}5.5. Отличия для варианта реализации 3
В тексте программы для варианта реализации 3 мы для упрощения исключили все проверки корректности. Описание реализации мы ограничиваем только отличиями от варианта 1.
Указатель Ar в функции main() тут - указатель на массив указателей, следовательно, его тип - int**. Выделение памяти ведется в несколько приемов: сначала выделяется память для массива из S указателей, а потом в цикле - S раз выделяется память для массива из S целых чисел, адреса выделенных массивов записываются в элементы массива указателей. При выводе матрицы используются i и j - номера строки и столбца и обращение к элементам матрицы ведется как к элементам 2-мерного массива.
Первый параметр функции fill() - указатель на указатель на int. Это дает возможность использовать номера строки и столбца - l и r также и для обращения к элементам матрицы.
/***************************************************/
/* Лабораторная работа #8 */
/* Функции */
/* Пример выполнения. Вариант #19. */
/* Вариант реализации 2 */
/***************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <alloc.h>
void fill(int far **, int);
/*** главная функция ***/
main() {
int far **Ar; /* указатель на массив указателей */
int i, j; /* строка и столбец */
int S; /* размерность матрицы */
/* ввод размерности */
printf("Enter S>"); scanf("%d",&S);
printf("S=%d\n",S);
/* выделение памяти для массива указателей */
Ar=(int far **)malloc(sizeof(int *)*S);
/* выделение памяти для каждой строки
и заполнение массива указателей */
for (i=0; i<S; i++)
Ar[i]=(int far *)malloc(sizeof(int)*S);
/* обращение к функции заполнения матрицы */
fill(Ar,S);
/* вывод матрицы */
for (i=0; i<S; i++) {
for (j=0; j<S; printf("%3d",Ar[i][j++]) );
putchar('\n');
}
/* освобождение памяти строк */
for ( i=0; i<S; free(Ar[i++]) );
/* освобождение памяти массива указателей */
free(Ar);
return 0;
}
/*** функция заполнения матрицы ***/
/* параметры: A - указатель на массив указателей
s - размерность матрицы */
void fill(int far **A, int s) {
short l, r; /* строка и столбец */
short k=1; /* текущий член ЛП */
for (l=0; l<s; l++) /* перебор строк */
for (r=0; r<s; r++) /* перебор столбцов */
/* условие нулевого значения */
if ((r>=max(l,s-l-1))||(r<=min(l,s-l-1)))
A[l][r]=0;
else A[l][r]=k++;
/* конец перебору строк */
/* конец перебору столбцов */
}