Указатели и функции в языке программирования С
Практическая часть
Пример 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.

