Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
АиП -Лабораторная работа№2_2_семестр.doc
Скачиваний:
7
Добавлен:
13.09.2019
Размер:
169.98 Кб
Скачать

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

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

Алгоритм решения задачи в основном - тот же, что и в работе №7_1, поэтому его схему тут не приводим. Разница состоит в том, что в начале выполнения, после инициализации датчика случайных чисел, нужно получить случайное число в диапазоне 50 - 200 (назовем его size) и выделить память для массива целых чисел размером size. (На схеме алгоритма для работы № 7_1 эти действия должны быть вставлены сразу же после блока 2). Перед самым выходом из программы необходимо освободить выделенную память (На схеме алгоритма для работы №7_1 - после блока 19).

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

Ar[i] *(Ar+i)

Это соответствовало бы букве задания, но не духу языка C++. Если мы переходим от индексации к адресации, у нас устраняется необходимость в индексах и даже в переменных, которые их представляют. Это приводит к другому способу реализации всех циклов. Если имя массива Ar является указателем на его начало, то вместо цикла, в котором индекс i меняется от 0 до size, мы можем организовать цикл, в котором некоторый текущий указатель Cr меняется от Ar до Ar+size. Также, когда нам нужно запомнить начало отрицательной последовательности, мы можем запоминать не индекс соответствующего элемента, а его адрес - указатель на него.

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

Переменные программы также описаны в сравнении с работой №7_1. Память для массива целых чисел в нашей работе не выделяется на этапе компиляции, так что нам достаточно объявить в программе только переменную - указатель на начало массива:

int *Ar;

Размерность массива определяется при выполнении программы, так что для ее сохранения нужна отдельная переменная:

int size;

Вместо переменных, которые в работе №7_1 являются индексами элементов массива, мы будем применять указатели:

int *Cr;

это будет указатель на текущий элемент массива при его полном переборе, и:

int *Ir;

в этом указателе будет сохраняться адрес начала отрицательной последовательности, а потом – при обработке последовательности – адрес текущего ее элемента.

Переменные для сохранения суммы элементов и среднего значения и количества элементов в последовательности остаются те же самые:

int av;

int nn;

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

 Кроме тех файлов, которые были включены в текст программы работы №7_1:

#include <iostream.h>

#include <time.h>

#include <stdlib.h>

включаем также файл alloc.h, в котором содержатся описания функций динамического выделения/освобождения памяти:

#include <alloc.h>

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

size=rand()%151+50;

Функция rand возвращает нам число в диапазоне 0 - 150, прибавлением к нему 50 мы переводим его в диапазон 50 - 200. Полученный размер массива сразу выводим на экран:

cout<<"size= " <<size;     

Обращаемся к функции выделения памяти:

Ar=(int *)malloc(size*sizeof(int));

Функция malloc() требует параметр – размер запрошенной памяти в байтах. Переменная size – это количество элементов в массиве; для задания размера памяти в байтах умножаем ее на размер одного элемента. Функция malloc() возвращает нетипизированный указатель, мы преобразуем его в указатель на int и записываем в переменную Ar.

Далее организуем цикл перебора массива. В отличие от работы №7_1 мы в одном цикле получаем случайные числа, и выводим начальный массив на экран. Заголовок этого цикла существенно отличается от работы №7_1:

for (Cr=Ar; Cr<Ar+size; Cr++)

{

*Cr=rand()%101-50;

cout<<*Cr <<" ";

}     

В начальных установках цикла мы записываем в переменную Cr адрес начала массива, т.е. Cr показывает на элемент с индексом 0. В конце каждой итерации Cr увеличивается на 1, т.е. показывает на следующий элемент массива. Последняя итерация происходит при значении Cr=Ar+size-1, т.е. Cr будет показывать на последний элемент. В каждой итерации мы обращаемся к текущему элементу массива как *Cr, т.е. обращаемся к тому, на что показывает указатель Cr.

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

Тело цикла в основном подобно тому, что есть в лабораторной работе №7_1 за исключением того, что к текущему элементу массива мы обращаемся через указатель на него: *Cr. Там, где нам требуется запомнить начало отрицательной последовательности, мы просто сохраняем текущее значение указателя Cr в переменной-указателе Ir.

      Внутренний цикл, в котором обрабатывается отрицательная последовательность, существенно отличается от работы №7_1:

for (av/=nn; Ir<Cr; Ir++)

if (*Ir<av) *Ir=av;

Начальные установки этого цикла – только усреднение значения в av, переменная Ir уже содержит в себе указатель на первый элемент отрицательной последовательности. В конце каждой итерации Ir увеличивается на 1, т.е. показывает на следующий элемент последовательности (обращение к этому элементу - *Ir). Последняя итерация происходит при значении Ir=Cr-1, поскольку Cr показывает на первый положительный элемент за отрицательной последовательностью.

Остаток программы повторяет предыдущие фрагменты.

Предпоследний оператор - обращение к функции free() для освобождения памяти, которая была выделена функцией malloc(): free(Ar);

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