Разработка спецификаций функции
Поможем в ✍️ написании учебной работы
Поможем с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой

Дадим функции, которую создаем, имя substr(). Состав и типы ее параметров достаточно просто могут быть определены из задания: это должны быть строка-источник данных (src), строка-результат (dest), начальная позиция (pos) и длина результата (len).

Строки должны быть определены в той функции, которая вызывает нашу, следовательно, функции substr() передаются указатели на эти строки. Остальные параметры должны быть целыми числами. Обратите внимание на наши соображения по поводу размещения символьных строк. Вполне понятно, что память для строки-источника должна быть выделена во внешней функции. Но то же самое предусматриваем и для строки-результата - почему? Если объявим строку-результат как локальную в функции substr(), то память для нее будет выделена в нашей функции, и эта память будет освобождена, когда выполнение функции закончится, следовательно, та функция, которая вызвала нашу, воспользоваться результатом не сможет. Если же выделим память в нашей функции явным образом (с помощью malloc()), то память сохранится, но тогда на ту функцию, которая вызвала нашу, возлагается обязанность явным образом освободить эту память, когда строка-результат уже не будет нужна. Проанализируем возможности некорректного задания параметров при вызове функции. Во-первых, параметры pos и len не могут иметь отрицательного значения - оно просто не имеет смысла. Во-вторых, возможно такое значение параметра pos, которое будет превышать длину строки-источника. Будем считать все эти случаи ошибочным заданием параметров. Что должна делать функция при ошибочном задании параметров? Можно предложить три варианта:

 

1. Функция аварийно завершает работу всей программы.

2. Функция никак не реагирует на ошибку.

3. Функция возвращает какой-то признак ошибки.

 

Из этих вариантов выбираем третий, исходя из тех соображений, что функция может использоваться в большом числе программ, так что пусть внешняя программа, получив признак ошибки, сама принимает решение о дальнейших действиях при ошибке. А если так, то наша функция должна возвращать признак ошибки. Удобно сделать этот признак именно тем значением, которое функция возвращает.

Установим, что это значение будет 0 при нормальной работе функции, а при ошибке в параметрах это значение будет –1, а строка-результат будет пустой.

Возможен еще один вариант некорректного задания параметров — когда начало подстроки лежит в пределах строки-источника, а конец выходит за ее конец. Договоримся не считать этот случай фатальной ошибкою, пусть в этом случае функция формирует результат меньшей длины, чем задано и возвращает 1.

Еще одна проблема: если память для результата выделяет внешняя функция, что делать, если длина результата будет больше объема выделенной памяти? Чтобы контролировать эту ситуацию нужно ввести еще один параметр функции — максимальную длину строки-результата, а это нежелательно. Примем решение не контролировать такую ситуацию, перекладывая ответственность за нее на ту функцию, которая вызывает нашу. Это решения базируется на том, что именно так поступают и библиотечные функции языка С.

В итоге разработки спецификации для функции формулируем такое описание функции substr():

int substr( char *src, char *dest, intpos , intlen ); /* src — строка-источник, dest — строка-результат, pos — позиция, скоторой выделяется подстрока, len — длинаподстроки*/

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

разрабатываем алгоритм только для функции substr(), игнорируя внешнюю функцию, которая вызывает ее.

При разработке алгоритма сразу же "заглядываем вперед", имея в виду его последующую реализацию в программном коде, т.к. уже в задании обусловлены некоторые детали реализации.

Функция начинается с цикла (блоки 2 -5), цель которого - установить указатель на символ с номером pos. Как параметр цикла используется параметр функции pos, который "работает на уменьшение". В каждой итерации цикла pos уменьшается на 1 (блок 5), а указатель srcувеличивается на 1 (блок 4). Когда pos уменьшится до 0 (блок 3) — указатель должен быть установлен на нужный символ. Но есть возможность того, что достигнем конца строки раньше, чем символа с номером pos. Эта возможность проверяется отдельно (блок 2) — не показывает ли srcна символ с кодом 0 — признак конца строки. Следовательно, выход из цикла возможен либо по достижению нужного символа (блок 3), либо по достижению конца строки, причем, последнее возможно только при некорректном задании параметров. После выхода из цикла проверяется корректность задания параметров: не задана ли отрицательная длина подстроки (блок 6) и не выходит ли pos за пределы строки (блок 7). Отметим, что если значение pos ошибочно задано отрицательным, то цикл блоков 2 – 5 не выполнится ни одного раза и в блоке 7 значение pos будет ненулевым. Оно также будет ненулевым, если pos превышает длину строки-источника. В любом случае некорректного задания возвращаемое значение ret устанавливается в -1 (блок 8), и управление переходит на завершение функции.

Если же параметры заданы корректно, выполняется второй цикл (блоки 9 - 13). Этот цикл имеет параметром параметр функции len, который тоже " работает на уменьшение ". В каждой итерации символ, на который показывает указатель src, пересылается туда, куда показывает указатель dest (блок 11) после чего оба эти указателя увеличиваются на 1 (блок 12), а len уменьшается на 1. Когда значение len достигнет 0, это означает, что из источника в результат переслано уже len символов и происходит выход из цикла (блок 10). Другая возможность выхода — если будет найден конец строки прежде, чем закончится пересылка (блок 9). После выхода из цикла проверяется остаток в переменной len (блок 14). Если он нулевой, значение для ret устанавливается в 0 (блок 16), если нет — это означает, что переслано меньшее количество символов, и значение ret устанавливается в 1 (блок 17).

 

Перед завершением в любом случае записывается признак конца строки туда, куда показывает dest (блок 17). Если функция завершается из-за некорректного задания параметров, это обеспечит пустую строку по адресу dest. То значение ret, которое было установлено при выполнении алгоритма, возвращается функцией (блок 18).

5.3. Фунція substr(). Текст программы

Заголовок функции substr() полностью соответствует ее описанию, сформулированному при разработке спецификаций функции. В функции объявляется только одна локальная переменная — ret — в которой формируется то значение, которое возвращает функция.

Цикл, который на схеме алгоритма представлен блоками 2 - 5, реализован одним оператором:

for(; pos&&*src; pos--, src++);

Начальные установки для цикла не нужны. Оба условия выхода из цикла проверяются одним выражением:

pos&&*src,

что эквивалентно: (pos==0)&&(*src=0),

в конце каждой итерации уменьшается pos и увеличивается src. Тело этого цикла пустое.

Единственный условный оператор:

if (pos||(len<0)) ret=-1;

является программной реализацией проверок некорректного задания параметров (блоки 6–8).

Если параметры корректны, следующий оператор цикла выполняет пересылку символов из источника в результат (блоки 9–13):

for(;len&&*src; *dest++=*src++,len--);

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

После цикла проверяется остаток и устанавливается значение ret(блоки 14–16):

ret = len ? 1 : 0;

Перед возвратом еще записывается признак конца строки (символ с кодом 0) в результат (блок 17):

*dest=0;

При завершении функция возвращает (блок 18) значение ret:

return ret;

5.4. Функция main()

Основным результатом нашего проекта должна быть функция substr(). Но эта функция не может выполняться самостоятельно, она должна вызываться из какой-нибудь внешней функции. Вообще для выполнения любого программного кода, написанного на языке C, в нем должна быть функция maіn(). На эту функцию возлагаем задачи ввода данных и вывода результатов. Следовательно, чтобы заставить нашу функцию substr() выполняться и проверить ее выполнение, должны создать также и функцию maіn().

5.4.1. Переменные функции main ()

В функции maіn() должны бытьобъявленыпеременные для:

· строки-источника: char s1[80];

· строки-результата: char s2[80];

· позиции первого символа в подстроке: int n;

· длиныподстроки: int l;

· того значения, которое вернет функция substr(): int r;

Пользуясь случаем, сделаем небольшое отступление, чтобы предупредить Вас про возможность ошибки, которую часто допускают начинающие программисты. Зная, что обращение к символьным строкам в языке C происходит через указатель на начало строки, такие программисты иногда объявляют символьную строку как char * Но такое объявление, например:

char *s1;

выделяет память только для размещения указателя, но не для размещения самих символов строки. Если далее введем, например, 80 символов функцией gets(s1), то символы разместятся там, куда показывает указатель s1, но значение этого указателя не определено, следовательно, и символы разместятся неизвестно где. Следовательно, символьная строка обязательно должна быть объявлена как массив символов - этим выделяется для нее память, а уже обращаться к ней можно через указатель.

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

5.4.2. Текст функции maіn ()

После объявления переменных текст функции maіn() состоит из единственного бесконечного цикла. В каждой его итерации прежде всего выводится приглашение не ввод строки-источника. Следующий оператор, возможно, требует более детального рассмотрения:

if (! strcmp ( gets ( s 1),"***")) break ;

При его выполнении прежде всего выполняется функция gets(s1), которая вводит данные в строку s1. Эта функция возвращает указатель на строку s1. Строка, на которую показывает этот указатель, сравнивается с помощью функции strcmp() со строковой константой «***». Если они равны, strcmp() возвращает 0, тогда значение логического выражения в условном операторе истинное и выполняется выход из бесконечного цикла. Следовательно, цикл будет выполняться, пока не будет введена строка «***».

Потом вводятся значения переменных n и l и выполняется вызов функции substr(), которой передаются параметры s1, s2, n, l. Значения, которое возвращает substr(), присваивается переменной r.

Строка-источник, строка-результат и возвращенное значение выводятся на экран, и цикл повторяется. (Обратите внимание на то, что при выводе символьных строк берем их в "скобки": >><<. Это сделано для того, чтобы на экране можно было разглядеть символы-пробелы, которые могут быть в начале и в конце строк.)

Обращение к функции gets() в конце цикла - "технологическое". Дело в том, что функция scanf() оставляет в буфере ввода последний код клавиши Enter, которым был закончен ввод. Если не будет "технологического" gets(), то gets()в следующей итерации цикла прочитает этот символ, как пустую строку. Так что "технологическое" gets() удаляет из буфера код клавиши Enter. Чтобы убедиться, попробуйте его убрать и посмотрите, что получится.

Загальні оголошення

В функции maіn() применяются библиотечные функции ввода-вывода и функция сравнения строк, так что включим в программу файлы stdіo.h и strіng.h. Кроме того, следует включить и описание функции substr(). Хотя все эти описания нужны только для функции maіn(), стиль программирования на языке C требует размещения их в начале программы, вне программных блоков.

Полный текст программы приведен ниже.

#include <stdio.h> #include <string.h> int substr(char *, char *, int, int);                                     /*** главная функция ***/ int main(void) { char s1[80],s2[80];               /* источник и результат */ int n, l, r;                      /* позиция, длина, результат */ for (;;) {                       /* бесконечный цикл */ printf("Введите строку >"); /* ввод строки-источника */ if (!strcmp(gets(s1),"***")) break; printf("Введиту pos len>"); /* ввод остальных параметров */ scanf("%d %d",&n,&l); r=substr(s1,s2,n,l);       /* обращениекфункции substr() */ printf("pos=%d, len=%d\n",n,l); /* вывод результатов */ printf("s1=>>%s<<\n",s1); printf("s2=>>%s<<\n",s2); printf("R=%d\n\n",r); gets(s1); } } /*** функция выделения подстроки функция возвращает: 0 - нормальное выполнение, 1 - подстрока имеет меньшую длину, чем задано, -1 - ошибка в параметрах, результат пустой ***/ int substr(char *src, char *dest, int pos, int len) { int ret;                     /* значение, которое возвращается */ for(; pos&&*src; pos--, src++); /* выход на начальную позицию */ if (pos||(len<0)) ret=-1;         /* проверка параметров */ else {                           /* параметры корректны */ for(;len&&*src; *dest++=*src++,len--);/* пересылка символов */ ret = len ?1 : 0;     /* проверка длины результата */ } *dest=0;                /* запись признака конца в результат */ return ret; }

Отладка программы

При отладке программы в пошаговом режиме следует отслеживать:

· правильность передачи параметров функции,

· правильность выхода на начальный символ подстроки,

· правильность контроля параметров,

· правильность копирования символов,

· правильность окончательного формирования строки-результата (достаточно распространенной ошибкой является отсутствие признака конца в строке-результате).

Следует отметить, что при наличии некоторых ошибок отладка может быть несколько неудобной за счет того, что в функции применены очень мощные операторы цикла, которые занимают одну строку. В пошаговом режиме все итерации такого цикла выполняются за один шаг. При наличии ошибок в цикле, возможно, нужно будет "разгружать" оператор цикла - переносить часть действий из заголовка цикла в его тело.

Очень важно подобрать для отладки такие входные данные, которые позволили бы убедиться в правильном функционировании программы на всех ветвях ее алгоритма. при отладке этой работы использовали во всех случаях строку-источник вида: «0123456789». Такой вид позволяет легко установить по выводу на экран, какое преобразование было выполнено функцией. Параметры posи len задавали в таких вариантах:

 

pos=2, len=3 — проверка правильности работы при правильных заданиях параметров
pos=0,len=4 — подстрока начинается с начала строки
pos=6, len=4 — подстрока заканчивается на конце строки
pos=0, len=10 — подстрока захватывает всю строку
pos=3, len=0 — подстрока нулевой длины
pos=8, len=4 — особый случай: подстрока будет иметь меньшую длину, чем задано
pos=3, len=–2 — ошибка: отрицательная длина
pos=–1, len=3 — ошибка: отрицательная начальная позиция
pos=10, len=3 - ошибка: позиция начала больше длины источника

 


Лабораторная работа №7

Указатели и массивы. Динамическое
выделение памяти

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

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

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

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

5. Примеры решения задачи

5. Пример 1

5.1. Разработка алгоритма

5.2. Определение переменных программы

5.3. Разработка текста программы

5.4. Отладка программы

6. Пример 2

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

6.2. Определение переменных программы

6.3. Разработка текста программы

6.4. Отладка программы

 


Цель работы

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

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

  • Операторы цикла языка C. Вложенные циклы.
  • Условный оператор языка C.
  • Выделение динамической памяти.
  • Указатели. Типизированные указатели.
  • Указатели и массивы.
  • Адресная арифметика.

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

Объявить массив целых чисел и заполнить его случайными значениями(размер массива определяется вначале выплнения программыкакслучайное число в диапазоне, например, 3–200 (диапазон задан во 2 столбце таблицы вариантов)). В индивидуальных заданиях указан диапазон значений его элементов (3 столбец таблицы) икакую обработку массива следует произвести.

Для всех вариантов задания следует иметь в виду следующее:

· 0 считается положительным числом, если в задании не оговорен какой-то другой его статус;

· когда речь идет о какой-то последовательности чисел, имеется в виду последовательность с длиной, большей 1;

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

· в тексте программы запрещается использовать операцию индексации!!!!!!!

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

№ варианта Диапазон изменения размерности массива Диапазон значений элементов Что нужно сделать
1 от 8 до 200 от 0 до 100 Поменять местами 1-й положительный элемент с последним положительным элементом, 2-й - предпоследним и т.д.
2 от 6 до 100 от –50 до 50 Найти количество пар соседних элементов, которые имеют одинаковые абсолютные значения, но противоположные знаки, и вывести эти пары
3 от 5 до 200 от 0 до 100 Найти значение 3-го по величине элемента и значения всех элементов массива, которые его превышают, заменить на найденное значение.
4 от 6 до 100 от –50 до 50 Заменить все элементы с положительными значениями абсолютным значением отрицательного элемента с максимальным абсолютным значением
5 от 6 до 200 от –50 до 50 Подсчитать количество пар соседних элементов с одинаковыми значениями и вывести эти пары на экран
6 от 5 до 160 от –100 до 100 Во всех последовательностях положительных чисел ограничить значения тех элементов, абсолютное значение которых ниже абсолютного среднего для этой последовательности.
7 от 7 до 100 от –100 до 100 Заменить каждый элемент на среднее арифмети­ческое его и его соседей слева и справа(для граничных элементов брать лишьсам элементи существующего соседа).
8 от 8 до 100 от –100 до 100 Найти ту непрерывную последовательность положительных чисел, сумма элементов в которой максимальная.
9 от 3 до 200 от –50 до 50 Во всех последовательностях отрицательных чисел поменять местами элементы с максимальным и минимальным значениями.
10 от 5 до 200 от –100 до 100 Во всех последовательностях положительных чисел ограничить снизу значения тех элементов, значения которых меньше среднего для этой последовательности.
11 от 3 до 200 от –50 до 50 Подсчитать количество пар соседних элементов, которые имеют противоположные знаки и вывести эти пары.
12 от 5 до 200 от –50 до 50 Для каждого положительного элемента определить, есть ли в массиве отрицательный элемент с противоположным значением; если да, заменить эти элементы на 0.
13 от 9 до 100 от –100 до 100 Разместить все элементы с положительными значени­ями в левой части массива, элементы с отрицательными значениями — в правой, а нули — между ними.
14 от 4 до 200 от 0 до 100 Найти непрерывный участок из 10 элементов, который имеет наибольшее среднее значение элементов.
15 от 6 до 100 от –100 до 100 Ограничить значения всех элементов, абсолютные значения которых превышают среднее для положительных и отрицательных элементов.
16 4 до 100 от –50 до 50 Вывести начальные индексы всех непрерывных знакопеременных последовательностей чисел.
17 от 8 до 200 от 0 до 100 Подсчитать количество участков, которые образуют непрерывные последовательности чисел с неуменьшающимися значениями.
18 от 4 до 200 от –50 до 50 Найти из непрерывных последовательностей отрица­тельных чисел ту, которая имеет наибольшее абсолют­ное значение среднего арифметического ее элементов.
19 от 7 до 100 от –100 до 100 Во всех последовательностях отрицательных чисел изменить порядок элементов на противоположный и зеркально поменять последовательности местами.
20 от 3 до 100 от –50 до 50 Во всех последовательностях положительных чисел изменить порядок элементов на противоположный.
21 от 3 до 200 от 0 до 100 Найти непрерывный участок из 10 элементов, сумма которых максимальна.
22 от 5 до 200 от –50 до 50 Вывести начальные индексы всех непрерывных последовательностей чисел с неувеличивающимися значениями.
23 от 7 до 100 от –100 до 100 Вывести начальные индексы всех непрерывных последовательностей неотрицательных чисел, длина которых больше 5
24 от 4 до 100 от –100 до 100 Заменить все элементы с отрицательными значениями средним арифметическим значением всех положительных элементов.
25 от 8 до 200 от –50 до 50 Найти непрерывные участки, на которых сумма элементов равна 0, вывести участки на экран.
26 от 6 до 200 от –50 до 50 Определить среднюю длину непрерывных участков положительных чисел.
27 от 3 до 200 от –50 до 50 Подсчитать количество всех, непрерывных последовательностей положительных чисел, длина которых больше 7.
28 от 5 до 100 от –100 до 100 Разместить все элементы с нулевыми значениями в левой части массива, элементы с отрицательными значениями — за ними, а за ними — элементы с положительными значениями.
29 от 5 до 200 от –100 до 100 Во всех последовательностях положительных чисел заменить значения элементов с максимальным и минимальным значением на среднее для этой последовательности.
30 от 5 до 130 от –100 до 100 Заменить все элементы с отрицательным значением на значение минимального не равного 0 положительного элемента.
31 от 3 до 150 от –100 до 100 Для каждого положительного элемента определить, есть ли в массиве отрицательный элемент с противоположным значением; если это так, заменитьэти элементы на среднее всей последовательности.
32 от 8 до 200 от 0 до 100 Поменять местами 1-й отрицательный элемент споследнимотрицательным элементом, 2-й — предпоследними т.д.
33 от 6 до 150 от –50 до 50 Определить среднюю длинунепрерывныхучастков отрицательных чисел, заменить ею максимальныеи минимальные элементы каждойиз последовательностей.
34 от 3 до 180 от –50 до 50 Найти непрерывныйучастокиз 5 элементов, в котором сумма модулей элементов максимальна, заменитьэтотучасток элементами с противоположными значениями.
35 от 4 до 170 от –100 до 100 Найти из непрерывных последовательностей положительных чисел ту, что имеет наибольшее среднее значениеее элементов и вывести последовательность на экран.
36 от 5 до 180 от –50 до 150 Найти непрерывныйучасток, имеющий наибольшее количество положительных элементов, и вывести его.
37 от 3 до 150 от –150 до 150 Вовсех последовательностях положительных чисел элементы с максимальным и минимальным значениями заменить количеством элементов этой последовательности.
38 от 10 до 150 от –150 до 100 Найти ту непрерывную последовательность отрицательных чисел, сумма модулей элементов вкоторой максимальна и заменитьее нулями.
39 от 5 до 140 от –100 до 100 В отрицательных последовательностях ограничить значения всех элементов, превышающихпо модулю среднее для этой последовательности.
40 от 3 до 180 от –150 до 150 Подсчитать количество всіх, непрерывных последовательностей отрицательных чисел, длина которых меньше 5.

5. Примеры решения задачи

П ример 1. Объявить массив целых чисел и заполнить его случайными значениями.

Пример 2. размер массива определяется в начале выполнения программы как случайное число в диапазоне 50—200; в тексте программы запрещается применять операцию индексации.

 

Общее задание для примера

№ варианта Диапазон изменения размерности массива Диапазон значений элементов Что нужно сделать
от 50 до 100 от –50 до 50 Во всех последовательностях отрицательных чисел ограничить значения тех элементов, абсолютное значение которых превышает абсолютное среднее для этой последовательности.  

ПРИМЕР 1

Розработка алгоритма

Схема алгоритма показана на рисунке ниже. В первой фазе выполнения программынеобходимо будет сформировать массив случайных чисел. Перед тем, как будем обращаться к датчику случайных чисел, необходимо его проинициализировать (блок 2). Далее организуем цикл со счетчиком (блок 3), в каждой итерации которого генерируется следующее случайное число и записывается в следующий элемент массива (блок 4). После окончания цикла заполнения массива выводим массив на экран (блок 5).

необходимо будет вычислять среднее значение последовательности, следовательно — подсчитывать количество элементов в ней. Для этоговводим переменную nn— счетчик элементов, нулевое значение этой переменной будет показывать, что у нас нет последовательности для обработки. В начале обработкиустанавливаем nn=0(блок 6).

Далее организуем цикл со счетчиком (блок 7), в котором перебираем элементы массива. Для каждого элемента в первую очередь проверяется его знак (блок 8). Если это отрицательный элемент, то это может быть первый или не первый элемент последовательности. Это можно определить, проверяя значение переменной nn: если она 0 — это первый элемент (блок 9). Для первого элементазапоминаем в переменной іb индекс начала последовательности, устанавливаем счетчик элементов nn в 1, а в переменную av записываем значение этого элемента (блок 10). Для не первого элементаувеличиваем счетчик на 1, а значение элемента суммируем со занчением переменной av (блок 11). Таким образом, переменная av у нас играет роль накопителя суммы элементов последовательности.

Если же очередной элемент последовательности положительный, то возникает вопрос — не является ли этот элемент первым положительным элементом после отрицательной последовательности? Это можно проверить по счетчику nn. Если элемент первый, то значение nn должно быть больше 0 (блок 12). Если нет, тонеобходимо обработать ту отрицательную последовательность, которая только что закончилась. Для обработкив первую очередь получаем среднее значение (блок 13). Потом организуем цикл (блок 14) со счетчиком j, который изменяется от іb (индекс начала отрицательной последовательности, которыйсохранили раньше) до і–1 (і— это индекс первого положительного элемента после отрицательной — это индекс первого положительного элемента после отрицательной последовательности, следовательноі–1— индекс последнего элемента отрицательной последовательности). В каждой итерации этого цикласравниваем j-й элемент массива со средним значением av (блок 15).

Если значение элемента меньше среднего (т.е. больше по абсолютному значению), то среднее значение записывается в j -й элемент (блок 16), если же нет — ничего не происходит. По выходу из циклаустанавливаем счетчик nn в 0 (блок 17), как признак того, что у нас нет необработанной последовательности. Для не первого положительного элемента нет необходимости что-либо делать.

После выхода из того цикла, который начался в блоке 7, необходимо проверить, не осталась ли у нас необработанная последовательность и, если да, обработать ее. На схеме алгоритмапоказали это одним блоком 18, действия, которые выполняются в этом блоке тождественны действиям, которые детально показаны в блоках 12–17.

По окончанию обработкивыводим массив-результат (блок 19) и заканчиваем программу.

Дата: 2018-12-21, просмотров: 375.