Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
OOP_Lab_16_17.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
14.46 Mб
Скачать

2.Массивушки и подпрограммочки

Фундаментальный закон теории ошибок: на ошибках учатся.

Следствие 1. Программист, написавший программу, становится ученым.

Следствие 2. Чем больше программист делает ошибок, тем быстрее он делается ученым.

Следствие 3. Крупный ученый-программист никогда не пишет правильные программы.

Замечание. На то он и ученый.

Закон Мерфи

Цель работы – освоить создание консольного приложения, включающего дополнительные файлы с собственными функциями, и выполняющего некоторые операции над массивами чисел (4 час.)

Задание. Проделайте следующее:

  1. Прочитайте это задание и методические указания до конца, прежде чем терзать клавиатуру, соседа, преподавателя и пр. Сущности

  2. Напишите программный код, реализующий выпавший вам по жребию вариант задания, и попробуйте его отладить, используя средства отладки. Если вдруг вы не обнаружите ошибок, то это очень плохая примета: удалите весь программный код безвозвратно и начните проект с самого начала.

  3. Попробуйте сдать работу, предварительно тщательно протестировав ее на предмет отсутствия хомутов

2.1.Методические указания

Шаг 1. Создание заготовки приложения.

Запустите на выполнение ИС, с помощью команды FileNewProject вызовите мастера ИС, выберите шаблон Win32 Console Application, в свойствах проекта выберите, для простоты, поддержку MFC. В этом сценарии я присвоил проекту очень оригинальное имя Lab2. При создании проекта не устанавливайте (или снимите, если он установлен по умолчанию), переключатель Create directory for solutions.

Совет. В условиях работы в сети рекомендую выбрать локальный диск компьютера, а не сетевой, для ускорения работы, отсутствия проблем согласования времени локального компьютера и сетевого, уменьшения вероятности потери проекта из-за возможных сбоев сети. На локальном компьютере рекомендую выбирать каталог, имя которого и путь к нему не содержат символов кириллицы, например, C:\Temp. Самое плохое место для работы над проектом – флешка. Сохраняйте проект на флешке только тогда, когда вы закончили работу с ним, например, в конце лабораторной работы.

С самого начала работы добавьте в проект заголовочный файл (.h) и файл реализации (.cpp), в которые вы будете помещать свои собственные описания и функции. Проще всего это сделать путем добавления в проект нового класса (ProjectAdd Class). В сгенерированных файлах просто удалите заготовку класса, конструктор и деструктор, оставив директивы препроцессора. Эти файлы должны приобрести такой простой вид:

// Файл Lib.h

#pragma once

// Файл Lib.cpp

#include "StdAfx.h"

#include "Lib.h"

Добавляйте свои описания в конец этих файлов, например:

// Файл Lib.h

#pragma once

const int Count=100;

int Max(int a, int b);

// Файл Lib.cpp

#include "StdAfx.h"

#include "Lib.h"

int Max(int a, int b)

{return a>b?a:b;}

В завершение подключите свой заголовочный файл Lib.h к файлу, в котором находится главная функция _tmain, например:

// Lab2.cpp : Defines the entry point for the console application.

//

#include "stdafx.h"

#include "Lab2.h"

#include "Lib.h"

#include <ConIO.h> // не забудьте подключить для функции _getch()

Как и в предыдущей л.р., замените функцию _tmain на

void main()

{

setlocale(LC_ALL,"rus");

cout<<Max(10,Count)<<endl;

_getch();

}

Теперь вытрите пот со лба, запустите программу на выполнение, убедитесь в появлении числа 100 экране. Если у вас свой новый ноутбук, а на экране число 100 не появилось, подарите свой ноут кафедре, там его утилизируют, а себе купите другой – исправный.

Шаг 2. Главное – Функции!

Главная цель этой работы – структурировать программу путем размашистого применения процедурного подхода. Все свои функции вы должны разместить в файлах Lib.h и Lib.cpp, а в главной функции должны быть размещены только их вызовы. Эти файлы должны быть разработаны таким образом, чтобы обеспечить возможность простого применения описанных в ней функций и типов в других приложениях путем включения в них этих файлов.

В качестве примера приведу примеры реализации функции ввода (фактического) числа элементов массива:

void GetNum(int &N)

{

cout<<"Введи фактическое число элементов массива>";

cin>>N;

}

int GetNum()

{

int N;

cout<<"Введи фактическое число элементов массива>";

cin>>N;

return N;

}

int GetNum(char * Prompt)

{

int N;

cout<<Prompt;

cin>>N;

return N;

}

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

  • нет проверки вводимого числа на предмет его вхождения в требуемый диапазон и повторения запроса на ввод в случае ввода некорректного значения;

  • нет проверки корректности соблюдения формата ввода. Например, не контролируется ввод недопустимых символов. Проверьте, что будет, если вместо числа ввести букву(ы). Для этой цели лучше всего было бы использовать механизм обработки ИС (мы этого еще не изучали!);

  • две первые реализации функции «заточены» только на запрос ввода числа элементов массива и их нельзя использовать для запроса, например, числа ног или зубов;

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

Следующая функция генерирует целое псевдослучайное число из заданного диапазона:

int GetRandom(int Min, int Max)

{

double res=(double)rand()/(RAND_MAX+1) * (Max-Min) +Min;

return (int)res;

}

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

srand((unsigned)time(NULL));

И вопрос на засыпку по этой функции: зачем сначала используется приведение к типу double, а потом к типу int? А ежели эти приведения типов убрать, шо буде?

Шаг 3. И уже самостоятельная работа!

Во всех вариантах заданий предполагается неукоснительное соблюдение следующих требований:

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

  2. Число элементов массива (ов) программа должна запрашивать у пользователя и контролировать корректность его ввода.

  3. Значения элементов массивов должны генерироваться как псевдослучайные числа из диапазона, оговоренного в задании.

  4. Исходные и обработанные массивы должны выводиться в самом что ни на есть красивом виде и при этом удобном для контроля корректности выполнения программы. Для вещественных данных число значащих цифр дробной части ограничить 2-3.

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

  6. Все функции должны получать все необходимые им исходные данные и возвращать результаты посредством параметров (или имени функции). Вы должны показать свое умение грамотно использовать параметры разных видов: параметры-значения, параметры-ссылки, константные параметры и т.д.

  7. Магические числа, т.е. непосредственно заданные числовые константы, следует именовать и далее использовать только именованные константы. Например, вместо int Vec[100]; следует писать const int NMax=100; int Vec[NMax]. Вместе с тем, не стоит и скатываться до идиотизма, например, вводить константы для цифр 0 или 1, широко используемых в любой программулине.

Алгоритмы сортировок и другие ценные сведения можно найти в Приложениях (см. оглавление), Интернете и в др. местах.

№ вар.

Задание

Тип элементов массива (ов)

Диапазон значений элементов массива

Сортировка массива включением

float

-1e-3 .. +1е+3

Сортировка массива с помощью прямого обмена (пузырьковый метод)

double

-100 .. 50

Инвертирование массива, т.е. перестановка его элементов в обратном порядке

int

100 ..120

Сортировка Шелла

float

-0.1 .. 0.2

Сортировка массива с помощью прямого выбора

double

-1e-3 .. +1е+3

Вставка нового массива в заданную позицию существующего массива

int

-200 .. 0

Удаление части массива

float

-1e-3 .. +1е+3

Вставка одного массива в другой

double

-100 .. 50

Поиск заданного подмассива в массиве

int

100 ..120

Подсчет числа вхождений подмассива в массив

int

10 .. 20

Поиск в массиве повторяющихся значений и перенос их в другой (новый) массив

int

100 .. 120

Исключить из заданного массива одинаковые элементы (сжать массив)

int

-10 .. -15

Отсортировать значения элементов двумерного массива (матрицы) в порядке возрастания. Например, если исходный массив выглядит так:

3 6 1 0

12 -6 7 3

то отсортированный должен иметь следующий пристойный вид:

12 7 6 3

3 1 0 -6

double

-10 .. 20

Ввести массив из N чисел и найти максимальное значение среди элементов, значения которых в массиве встречаются более одного раза. Например, в массиве 2,3,4,5,5,4,3,10 таким максимальным значением является 5

int

10 .. 15

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]