Студопедия — ПРАКТИЧЕСКАЯ ЧАСТЬ. Пример 1. Написать программу с функцией пузырьковой сортировки, использующей вызов по ссылке.
Студопедия Главная Случайная страница Обратная связь

Разделы: Автомобили Астрономия Биология География Дом и сад Другие языки Другое Информатика История Культура Литература Логика Математика Медицина Металлургия Механика Образование Охрана труда Педагогика Политика Право Психология Религия Риторика Социология Спорт Строительство Технология Туризм Физика Философия Финансы Химия Черчение Экология Экономика Электроника

ПРАКТИЧЕСКАЯ ЧАСТЬ. Пример 1. Написать программу с функцией пузырьковой сортировки, использующей вызов по ссылке.






 

Пример 1. Написать программу с функцией пузырьковой сортировки, использующей вызов по ссылке.

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

Программный код решения примера

#include <stdio.h> #include <conio.h> // Прототип функции void bsort (int* const, const int); int main (void) { int A[] = {56, 34, 2, 0, 1, -21, 6, 8, 7}; int i, n; //Размерность массива n = sizeof(A)/sizeof(A[0]); puts("\n Data items in original order:"); for (i = 0; i < n; i++) printf(" %3d", A[i]); // Вызов функции сортировки - bsort() bsort (A, n); puts("\n\n Data items in ascending order:"); for (i = 0; i < n; i++) printf(" %3d", A[i]); printf("\n\n... Press any key: "); getch(); return 0; } // Определение функции void swap(int *pa, int *pb) { int temp; temp = *pa; *pa = *pb; *pb = temp; } void bsort (int *const arr, const int size) { int pass,j; //счетчик проходов и счетчик сравнений // Прототип функции обмена - swap() void swap (int*, int*); // Цикл для контроля проходов for (pass = 0; pass < size - 1; pass++) { // цикл для контроля сравнений на данном проходе for (j = 0; j < size - 1; j++) { // обмен значений при нарушении порядка возрастания if (arr[j] > arr[j + 1]) { swap(&arr[j], &arr[j+1]); } } } }

В программе функция сортировки bsort() в качестве формального параметра используется константный указатель, который указывает на первый элемент заданного массива. Второй формальный параметр также константный, так подчеркивается его неизменность в теле функции bsort(). Передача функции размера массива в качестве параметра имеет два преимущества – это хороший стиль программирования и, кроме того, такую функцию можно использовать многократно.

Прототип функции swap() включен в тело функции bsort(), потому что это единственная функция, которая вызывает функцию обмена swap().


Пример выполнения программы представлен на рис. 11.2.

Рис. 11.2. Пример сортировки массива методом пузырька

Задание 1

1. Напишите программу сортировки семи вещественных, которые должны быть случайными по равномерному закону из интервала [–Х, +Х], где Х – номер компьютера, на котором выполняется лабораторная работа.

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


Пример 2. Написать программу, в которой используется функция по расчету среднего значения (среднего арифметического) одномерного числового массива, его исправленной выборочной дисперсии и среднего квадратичного отклонения (стандартного отклонения). Эти значения должны быть выведены на консоль в главной функции программы main().

Приведем расчетные формулы.

Среднее выборочное значение (mean) одномерного массива размерностью N

 

 

где – элементы массива.

Исправленная выборочная дисперсия (D) одномерного массива

 

 

Исправленное среднеквадратичное отклонение есть плюс корень квадратный из дисперсии.

Программный код решения примера

#include <stdio.h> #include <conio.h> #include <stdlib.h> #include <math.h> // Прототип функции double *mean_D_S(int arr[], int n); int main(void) { int mass[] = {2, -3, 5, 6, 7, 8, 9,-1}; int i, n; double *R; n = sizeof(mass)/sizeof(mass[0]); puts("\n\t Initial array:"); for (i = 0; i < n; i++) printf(" %3d", mass[i]); R = mean_D_S(mass, n); // вызов функции // Вывод расчтных характеристик массива printf("\n\n The average value of an array: %g\n", R[0]); printf(" The dispersion of the array: %g\n", R[1]); printf(" The standard deviation of the array: %g\n", R[2]); free(R); // освобождение памяти printf("\n... Press any key: "); getch(); return 0; } // Определение функции double *mean_D_S(int arr[], int N) { int j; double *PTR3 = (double *)calloc(N, sizeof(double)); double D, S, mean; mean = D = 0.0; for (j = 0; j < N; j++) mean += arr[j]; mean /= N; // среднее арифметическое for (j = 0; j < N; j++) D += (arr[j] - mean)*(arr[j] - mean); D /= (N-1); // дисперсия S = sqrt(D); // среднее квадратическое отклонение PTR3[0] = mean; PTR3[1] = D; PTR3[2] = S; return PTR3; }

Расчетные характеристики одномерного массива размещаются последовательно друг за другом в выделенной памяти для указателя *PTR3. Сформированный указатель функция возвращает в точку вызова функции mean_D_S().


Результат выполнения программы показан на рис. 11.3.

Рис. 11.3. Расчет статистических характеристик числового массива

Задание 2

1. В качестве первого аргумента функции mean_D_S() используйте указатель на числовой массив.

2. Воспользуйтесь справкой по математическим функциям и в программе примените функцию, которая осуществляет возведение в степень.


3. Дополните возврат функцией mean_D_S() исходного массива, поэлементно возведенного в квадрат. В главной функции main() результаты выведите на консоль.

Пример 3. Написать программу с указателем на функции, которые рассчитывают следующие статистические характеристики одномерного числового массива: среднее арифметическое значение, медиану и модус (моду).

Среднее арифметическое рассчитывалось в предыдущем примере.

Приведем определения медианы и модуса [3]. Медиана – это серединное значение в наборе данных – т. е. такое, что ровно половина значений располагается выше, и ровно половина ниже его. Модус – это значение, наиболее часто встречающееся в наборе данных.

Программный код решения примера

#include <stdio.h> #include <conio.h> double mean(int*, int); double median(int*, int); double mode(int*, int); int main(void) { int mass[] = {5, 6, 5, 5, 3, 6, 5, 3, 1, 4, 5, 3, 1, 6, 5, 2, 5, 2, 3, 4}; int temp, i, j, k, n, *ptr = mass; // Указатель на функции double (*fun[3])(int*, int) = {mean, median, mode}; n = sizeof(mass)/sizeof(mass[0]); puts("\n The original array:"); j = 0; for (i = 0; i < n; i++) { j++; if (j%6) printf(" %2d", mass[i]); else {puts(""); printf(" %2d", mass[i]); j = 1;} } // Сортировка методом выбора for (i = 0; i < (n - 1); ++i) { temp = ptr[i]; k = i; for (j = i + 1; j < n; ++j) if (ptr[j] < temp) { k = j; temp = ptr[k]; } ptr[k] = ptr[i]; ptr[i] = temp; } puts("\n\n Results - mean, mediana, modus: "); for (i = 0; i < 3; i++) printf("%6g\n",(*fun[i])(ptr, n)); printf("\n\n... Press any key: "); getch(); return 0; } // Определения функций double mean(int* arr, int N) { int i; double aver = 0.0; for (i = 0; i < N; i++) aver += arr[i]; return (aver/N); } double median(int* arr, int N) { int i; double med = 0.0; for (i = 0; (i < N/2); i++) med = arr[i]; if (N % 2) med = arr[i]; else med = (med + arr[i])/2; return med; } double mode(int* arr, int N) { int instances = 0, tempinst = 1, i = 1; double tempmode, mode_return = 1.0; tempmode = (double)arr[0]; if (i < N) { if ((double)arr[i] == tempmode) { i++; tempinst++; } if (tempinst > instances) { mode_return = tempmode; instances = tempinst; } tempinst = 1; tempmode = (double)arr[i]; i++; } return (mode_return); }

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


 

Для понимания работы функции по расчету модуса алгоритм вычислений рекомендуется формулировать следующим образом: «Разбить сортированный список значений на ряд меньших списков, каждый из которых содержит одинаковые значения. Пересчитать число элементов в этих списках, и список с наибольшим числом элементов будет соответствовать модусу данных» [3].


Результат выполнения программы представлен на рис. 11.4.

Рис. 11.4. Значения среднего, медианы и модуса

Задание 3

1. В функции расчета модуса приведение типов примените только один раз.

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

3. Объедините три функции – mean(), median(), mode() в одну и определите необходимый тип возвращаемого значения, чтобы в главной функции main() можно было распечатать результаты расчетов статистических характеристик.

Пример 4. Написать программу сортировки массива строк с использованием указателей на функции.

Программный код решения примера

#include <stdio.h> #include <conio.h> #include <string.h> // Прототипы функций void bsort (char***arr, int size, int (*comp) (const char**s1, const char**s2)); int less (const char**s1, const char**s2); int greater (const char**s1, const char**s2); int main (void) { char**Lines[] = { "asd", "aza", "baza", "qwerty", "hello", "world", "aza" }; int i; int n = sizeof (Lines) / sizeof (Lines[0]); // Вызов функции сортировки по возрастанию в алфавитном порядке puts("\n The sorting in ascending order:"); bsort (Lines, n, less); for (i = 0; i < n; ++i) printf("\t %c\n", Lines[i]); // Вызов функции сортировки по убыванию в алфавитном порядке puts("\n The sorting in descending order:"); bsort (Lines, n, greater); for (i = 0; i < n; ++i) printf("\t %c\n", Lines[i]); printf("\n\n... Press any key: "); getch(); return 0; } // Определение функции сортировки строк void bsort (char***arr, int size, int (*comp) (const char**s1, const char**s2)) { int i, j; for (i = 0; i < size - 1; ++i) for (j = 0; j < size - 1; ++j) if (comp (arr[j], arr[j + 1]) > 0) { char**s = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = s; } } // Определение функции сравнения строк по возрастанию int less (const char**s1, const char**s2) { return strcmp (s1, s2); } // Определение функции сравнения строк по убыванию int greater (const char**s1, const char**s2) { return -strcmp (s1, s2); }

В программе используются указатель на функцию для вызова двух функций – less() и greater() в процессе сортировки для определения порядка расположения элементов (слов).


 


Результат выполнения программы показан на рис. 11.5.

Рис. 11.5. Пример сортировки строк

Задание 4

1. Ввод массива строк осуществите с клавиатуры построчно.

2. Ввод массива строк осуществите с клавиатуры одной строкой, содержащей несколько слов, разделенных пробелами, и заполните символьный массив так, чтобы в каждом элементе было по одному слову из исходной строки.

3. Измените программу так, чтобы при сравнении строк не различались строчные и прописные буквы латинского алфавита.

Пример 5. Написать программу построения на экране дисплея графика функции

 

 

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

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

Программный код решения примера

#include <stdio.h> #include <conio.h> #include <stdlib.h> #include <math.h> // Размеры диаграммы по ширине и высоте экрана #define SCREENW 79 #define SCREENH 25 // Функция построения графика заданной функции void plot (FILE *fout, double a, double b, double (*f) (double)) { // Формальные параметры функции plot // FILE *fout – указатель на поток вывода // double a – левая граница оси абсцисс // double b – правая граница оси абсцисс // double (*f) (double) – указатель на функцию char screen[SCREENW][SCREENH]; double x, y[SCREENW]; double hx, hy, ymin = 0, ymax = 0; int i, j, xz, yz; // hx – шаг по оси абсцисс hx = (b - a) / (SCREENW - 1); for (i = 0, x = a; i < SCREENW; ++i, x += hx) { // вычисляем значение функции y[i] = f (x); // запоминаем минимальное и максимальное значения if (y[i] < ymin) ymin = y[i]; if (y[i] > ymax) ymax = y[i]; } hy = (ymax - ymin) / (SCREENH - 1); yz = (int)floor (ymax / hy + 0.5); xz = (int)floor (-a / hx + 0.5); // Рисование осей координат for (j = 0; j < SCREENH; ++j) { for (i = 0; i < SCREENW; ++i) { if (j == yz && i == xz) screen[i][j] = '+'; // '.', '?', '+' else if (j == yz) screen[i][j] = '-'; else if (i == xz) screen[i][j] = '|'; else screen[i][j] = ' '; } } // Рисование графика функции for (i = 0; i < SCREENW; ++i) { j = (int)floor ((ymax - y[i]) / hy + 0.5); screen[i][j] = '.'; // символ начертания графика } // Вывод результата в файл или в стандартный поток stdout for (j = 0; j < SCREENH; ++j) { for (i = 0; i < SCREENW; ++i) fputc (screen[i][j], fout); fprintf (fout, "\n"); } } // Определение заданной функции double f (double x) { return sin (3.0*x) * exp (-x / 3.0); //return x * x - 3; } int main (void) { // Вывод графика в стандартный поток (консоль) plot (stdout, 0.0, 10.0, f); printf(“\n\n... Press any key: “); getch(); return 0; }

В программе используется указатель на файл, который может быть стандартным потоком, т. е. экраном дисплея. В главной функции main() происходит обращение к функции рисования графика plot(), в которую вводят фактические параметры, в частности файл – это stdout, т. е. стандартный поток, 0.0 – это левая граница оси абсцисс, 10.0 – правая граница оси абсцисс, f – имя функции с описанием зависимости y = f (x).

Пример выполнения программы представлен на рис. 11.6.


Рис. 11.6. Пример построения графика функции на консоли

 

Задание 5

1. Выполните вывод графика в текстовый файл с именем compX.txt, где Х – номер компьютера, на котором выполняется лабораторная работа.

2. Проанализируйте программу с целью возможного улучшения вида графика заданной функции.

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


Контрольные вопросы

1. Каким образом можно вернуть из функции несколько значений?

2. Каким образом определяется тип функции?

3. Как выглядит описание функции, которая возвращает указатель на заданный тип, например char?

4. Можно ли использовать многоуровневую адресацию для функции, которая возвращает указатель на заданный тип? Если можно, то как происходит определение такой функции?

5. В каком месте программы можно определить указатель на функцию?

6. Имеет ли указатель на функцию прототип и определение?

7. Как осуществляется вызов функции с помощью указателя?

8. Как взаимосвязаны между собой объявление функции, ее определение и вызов?







Дата добавления: 2015-09-06; просмотров: 504. Нарушение авторских прав; Мы поможем в написании вашей работы!



Расчетные и графические задания Равновесный объем - это объем, определяемый равенством спроса и предложения...

Кардиналистский и ординалистский подходы Кардиналистский (количественный подход) к анализу полезности основан на представлении о возможности измерения различных благ в условных единицах полезности...

Обзор компонентов Multisim Компоненты – это основа любой схемы, это все элементы, из которых она состоит. Multisim оперирует с двумя категориями...

Композиция из абстрактных геометрических фигур Данная композиция состоит из линий, штриховки, абстрактных геометрических форм...

Интуитивное мышление Мышление — это пси­хический процесс, обеспечивающий познание сущности предме­тов и явлений и самого субъекта...

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

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

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

Случайной величины Плотностью распределения вероятностей непрерывной случайной величины Х называют функцию f(x) – первую производную от функции распределения F(x): Понятие плотность распределения вероятностей случайной величины Х для дискретной величины неприменима...

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

Studopedia.info - Студопедия - 2014-2024 год . (0.014 сек.) русская версия | украинская версия