Лабораторная работа 11 работа с массивами в функциях
Скачать 36.02 Kb.
|
Лабораторная работа №11 РАБОТА С МАССИВАМИ В ФУНКЦИЯХ 1. Цель и задачи работы Целью работы является изучение алгоритмов работы с массивами в функциях. Задачи работы: – изучить методы передачи одномерных и двумерных массивов в функции С++; – проработать примеры программ с массивами в функциях; – запрограммировать и отладить программы, реализующие разработанные алгоритмы; – составить и защитить отчет. 2. Теоретическая часть 2.1. Передача массивов в функцию При передаче массива в функцию всегда происходит передача его адреса. Таким образом, в C++ все массивы передаются по адресу. Пример 11.1. Даны два массива из n целых чисел каждый. Определить, в каком из них больше положительных элементов. Очевидно, что для решения этой задачи потребуется подсчитать количество положительных элементов в двух массивах, то есть выполнить для обоих массивов одни и те же действия. Следовательно, эти действия надо поместить в функцию. Интерфейс функции: входные данные – массив и количество его элементов, результат – количество положительных элементов в массиве. Таким образом, заголовок функции должен иметь вид: intn_posit(constint *a, constintn); Имя массива представляет собой указатель на его нулевой элемент, поэтому в функцию массивы передаются через указатели. Количество элементов в массиве должно передаваться отдельным параметром, потому что, в отличие от строк символов, использующих признак конца строки, для массивов общего вида никакого признака конца массива не существует. #include #include int n_posit(const int *a, const int n); // прототипфункции main(){ inti, n; cout << "Введите количество элементов: "; cin >> n; int *a = new int[n]; int *b = new int[n]; cout<< "Введите элементы первого массива: "; for (i = 0; i < n; i++) cin >> a[i]; cout << "Введите элементы второго массива: "; for (i = 0; i < n; i++) cin >> b[i]; if (n_posit(a, n) > n_posit(b, n)) cout << " В первом положительных больше \n”; else if(n_posit(a, n) < n_posit(b, n)) cout << " Во втором положительных больше \n "; elsecout << " Одинаковое количество \n "; getch(); } /*функция, подсчитывающая количество положительных элементов в массиве*/ int n_posit(const int *a, const int n) { int count = 0; for (int i = 0; i < n; i++) if (a[i] > 0) count++; return count; } В этой программе место под массивы выделяется в динамической области памяти, поскольку в задании не указано конкретное количество элементов. Однако функцию n_posit можно без изменений применять и для «обычных» массивов, потому что для каждого из них имя тоже является указателем на нулевой элемент, только константным. Например, опишем массив из 10 элементов и инициализируем первые шесть из них (оставшимся будут присвоены нулевые значения): int х[10] = {2, 3, -1, -10, 4, -2}; cout << n_posit(x, 10); // будет выведено значение 3 2.2. Передача двумерных массивов в функцию Пример 11.2. Написать программу, определяющую, в какой строке целочисленной матрицы n×m находится самая длинная серия одинаковых элементов. Под серией имеются в виду элементы, расположенные подряд. В виде функции здесь удобно оформить решение основной задачи, оставив главной программе только ввод исходных данных и вывод результатов. Для удобства отладки ввод массива в программе выполняется случайным образом. Память под массив выделяется в цикле для того, чтобы можно было задавать обе размерности массива в виде переменных. #include #include int ser_equals(int **a, const int n, const int m); int RandomMas(int **a, const int n, const int m); int main() { int m, n, i , j; cout << "Vvedite kolichestvo strok: "; cin >> n; cout << "Vvedite kolichestvo stolbchov: "; cin >> m; int **a = new int *[n]; // выделение памяти for (i =0; i < n; i++) a[i] = new int [m]; // вызов функции RandomMas для заполнения массива randomMas(a, n, m); for (int i = 0; i < n; i++) { // вывод массива на экран for (int j = 0; j < m; j++) cout << a[i][j]<<" "; cout <<"\n"; } /* вызов функции ser_equals для поиска самой длинной серии одинаковых элементов */ int line = ser_equals(a, n, m); if (line >= 0) cout << "Samaia dlinnaia seria v stroke " << line+1; else cout << "Serii odinakovix elementov net "; getch(); } // функция заполнения массива случайным образом int RandomMas(int **a, const int n, const int m) { randomize; for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) a[i][j] = random(4); } // функция поиска самой длинной серии одинаковых элементов int ser_equals(int **a, const int n, const int m) { int i, j, count, line = -1, maxcount = 0; for (i = 0; i < n; i++) { count =0; for (j = 0; j < m - 1; j++) { if (a[i][j] == a[i][j + 1] ) count++; else { if (count > maxcount) { maxcount = count; line = i; } count = 0; } } if (count > maxcount) { maxcount = count; line = i; } } returnline; } Алгоритм работы функции ser_equals прост: в каждой строке выполняется сравнение соседних элементов. Если они равны, мы находимся внутри серии, при этом увеличиваем ее текущую длину. Она накапливается в переменной count, которая обнуляется перед обработкой каждой строки. Если же элементы не равны, это означает либо окончание серии, либо просто одиночный элемент. В этом случае надо посмотреть, не является ли данная серия самой длинной из рассмотренных и, если да, то запомнить ее длину и номер строки, в которой она встретилась. Для подготовки к анализу следующих серий в этой же строке надо обнулить счетчик count. Аналогичная проверка после цикла просмотра строки выполняется для серии, которая расположена в конце строки, поскольку в этом случае ветвь else выполняться не будет. Если в массиве нет ни одной серии одинаковых элементов, функция вернет значение, равное –1. 3. Описание оборудования и используемых программных комплексов При выполнении лабораторной работы необходим специализированный компьютерный класс с минимальными системными требованиями компьютеров: – Процессор – Intel Pentium III; – ОЗУ – 256 Mb; – видеокарта – 32 Mb. Требуемое программное обеспечение: – операционная система Microsoft Windows; – пакет прикладных программ Microsoft Office 2010; – интегрированная среда Borland C++ Builder. При использовании оборудования необходимо: – соблюдать общие правила нахождения в учебных лабораториях, работы с компьютером и использования программных средств; – привести в порядок одежду; – осмотреть рабочее место, убрать все мешающие работе предметы; – визуально проверить правильность подключения ПЭВМ к электросети. 4. Задание 1. Запустить интегрированную среду BorlandC++ Builder, выполнить задание для самостоятельной работы по указанному преподавателем варианту из табл. 8.1, оформив каждый пункт меню отдельной подпрограммой по примеру задачи с монастырями по методике п. 5.1. Для вывода текста на русском языке использовать следующую функцию: #include <windows.h> void printru(char* s) { char s1[81]; CharToOem(s,s1); printf(s1); } Составить файл, содержащий список со сведениями об N студентах. Для каждого учащегося указать фамилию, дату рождения, оценки сессии по трем предметам. Информацию о каждом студенте оформить в виде структуры. Совокупность структур объединить в массив. Составить программу, которая с помощью меню обеспечивает ввод исходных данных, сортировку, обработку и вывод на экран информации. 2. Выполнить задание для самостоятельной работы по варианту из табл. 11.1, оформив подпрограммы заполнения, подсчета нужного числового значения (по заданию) и вывода массива в виде отдельных функций. В основной программе произвести вызов нужных функций для двух матриц и выдать в качестве результата полученное значение. Все необходимые данные должны передаваться подпрограммам в качестве параметров; все величины, используемые только внутри подпрограмм, должны быть описаны как локальные. Заполнение массивов следует производить с помощью датчика случайных чисел: randomize – инициализирует генератор случайных чисел; random (int num); – генератор случайных чисел. Например, для заполнения матрицы случайными числами от –20 до 20 можно создать следующую функцию: int RandomMas(int **a, const int n, const int m) { randomize; for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) a[i][j] = -20+random(41); } Таблица 11.1 Задания для самостоятельной работы на использование массивов в функциях
5. Методика выполнения задания Пример использования функций для задачи с монастырями: #include #include #include #include #include # include #include <windows.h> /* Описание прототипов функций */ void printru(char* s); int sozd_f(char* filename); int dob_dan(char* filename); void vivod_dan(char* filename); void sort_dan(char* filename); /* Описание структуры, которая представляет монастырь */ struct mon { char name[15]; /* название */ charsc; /* школа */ intcnt; /* количество монахов */ floatsq; /* площадь */ }; /* Основная программа*/ int main() { int v char filename[] = "monastir.bin"; while (true){ printru ("Выберите действие: \n"); printru ("1: создать файл \n"); printru ("2: добавить данные \n"); printru ("3: вывести данные на экран \n"); printru ("4: отсортировать по названиям монастырей \n"); printru ("5: выйти \n"); cin>>v; switch (v){ case 1: sozd_f(filename); break; case 2: dob_dan(filename);break; case 3: vivod_dan(filename); break; case 4: sort_dan(filename); vivod_dan(filename); break; case 5: getch() ; return 1; default: printru("нeт такого пункта меню\n"); }; } getch(); } //функция создания файла int sozd_f(char* filename){ FILE *m_file; m_file = fopen(filename, "w+"); if ( m_file==0 ) { printru("Создать файл не удалось!\n"); getch(); return(1); } fclose(m_file); } //функция добавления данных int dob_dan(char* filename) { FILE *m_file; char y_n; struct mon x; m_file = fopen(filename, "ab"); if ( m_file==0 ) { printru ("Открыть файл не удалось!\n"); getch(); return(1); } do { int tt=0; // Ввод данных printru("Введите: название, школу, количество, площадь монастыря\n"); cin>> x.name; cin>> x.sc; cin>> x.cnt; cin>> x.sq; fwrite((char *) &x, sizeof(mon), 1, m_file); printru ("Продолжить(y/n)?\n"); cin>>y_n; if (y_n=='y' || y_n=='Y') tt=1; } while(tt==1); fclose(m_file); } //функция вывода данных на экран voidvivod_dan(char* filename){ FILE *m_file; m_file = fopen(filename, "r"); printru("------------------------------------------------------------\n"); printru("| монастыри |\n"); printru("|----------------------------------------------------------|\n"); printru("| название | школа | Количество | Площадь |\n"); printru("| | | монахов | земель |\n"); printru("|---------------|----------|--------------|----------------|\n"); fseek(m_file, 0, SEEK_END); int n = ftell(m_file) / sizeof(mon); mon *mm = new mon[n]; fseek(m_file, 0, SEEK_SET); // Функция fread позволяет считать весь файл за одно обращение fread(mm, sizeof(mon), n, m_file); fclose(m_file); for(int i=0;i cout<<"|"< cout<<"------------------------------------------------------------\n"; } //функция сортировки void sort_dan(char* filename) { FILE *m_file; struct mon x; int n, i, j, m; m_file = fopen(filename, "r"); fseek(m_file, 0, SEEK_END); n = ftell(m_file) / sizeof(mon); mon *mm = new mon[n]; fseek(m_file, 0, SEEK_SET); fread(mm, sizeof(mon), n, m_file); fclose(m_file); for (i=0; i m=i; for (j=i+1; j if (strcmp(mm[m].name, mm[j].name)>0) m=j; if (m>i) { x=mm[i]; mm[i]=mm[m]; mm[m]=x; } } fopen(filename, "w"); fwrite(mm, sizeof(mon), n, m_file); fclose(m_file); } //функция для вывода русского текста void printru(char* s) { char s1[81]; CharToOem(s,s1); printf(s1); } 6. Требования к содержанию и оформлению отчета Отчет по лабораторной работе должен содержать: – название университета, факультета и кафедры; – название работы; – сведения о студенте (ФИО, группа, курс) и о преподавателе (ФИО); – цель и задачи работы; – постановку задачи (№ варианта и задания по нему); – результаты выполнения заданий работы; – ответы на контрольные вопросы по указанию преподавателя; – дату выполнения лабораторной работы; – выводы по работе. Контрольные вопросы 1. Каким образом передаются одномерные массивы в функцию? 2. Существуют ли ограничения на тип возвращаемого функцией значения? 3. Каким образом передаются двумерные массивы в функцию? 4. Сформулируйте определение рекурсивной функции. 5. Алгоритм вычисления значения функции F(n) задан следующими соотношениями. Чему равно значение функции F(5)? F(1) = 1; F(2) = 1; F(n) = 2F(n- 1) + F(n - 2), при n > 2. 6. Ниже записан рекурсивный алгоритм F. Чему равна сумма всех чисел, напечатанных на экране при выполнении вызова F(2)? void F(int n) { cin>> n; if (n <= 5) { F(n + 2); F(n + 3); } } 7. Ниже записаны две рекурсивные функции: F и G. Чему будет равно значение, вычисленное при выполнении вызова F(7)? int F(int n) { if (n > 2) F= F(n - 1) + G(n - 2); else F= 1; return F; } int G(int n) { if (n > 2) G = G(n - 1) + F(n - 2); else G = 1; returnG; } |