Указатели и функции в языке программирования С
Практическая часть
Пример 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.
Задание 1
- Напишите программу сортировки вещественных чисел в количестве семи, которые должны быть случайными по равномерному закону из интервала от –Х до +Х, где Х – номер компьютера, за которым выполняется лабораторная работа.
- Видоизмените программу так, чтобы функция bsort() возвращала указатель на отсортированный массив, а сам исходный массив был при этом неизменным. Предусмотрите вывод на консоль исходного массива, потом отсортированного массива после вызова функции сортировки, и снова для контроля исходный массив. При этом аргументы функции bsort() оставить без изменения.
Пример 2. Напишите программу, в которой используется функция по расчету среднего значения (среднего арифметического) одномерного числового массива, его исправленной выборочной дисперсии и среднего квадратичного отклонения (стандартного отклонения). Эти значения должны быть выведены на консоль в главной функции программы main()
Приведем формулы, по которым рассчитываются среднее значение выборки, исправленная выборочная дисперсия и среднеквадратичное отклонение.
Среднее выборочное значение одномерного массива размерностью N
где – элементы массива.
Исправленная выборочная дисперсия одномерного массива размерностью N
где mean – среднее значение данного массива
Исправленное среднеквадратичное отклонение S
где 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 mean, D, S; mean = 0.0; for (j = 0; j < N; j++) mean += arr[j]; mean /= N; D = 0.0; 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; }
В программе используется функция динамического распределения памяти calloc(), которая выделенные ячейки памяти обнуляет. Расчетные характеристики одномерного массива размещаются последовательно друг за другом в выделенной памяти для указателя *PTR3. Сформированный указатель функция возвращает в точку вызова функции mean_D_S().
Результат выполнения программы показан на рис. 11.3.