Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Visual_Studio_2010

.pdf
Скачиваний:
109
Добавлен:
03.03.2016
Размер:
5.94 Mб
Скачать

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

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

1 N mean N ai ,

i 1

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

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

 

1

N

2 .

D

(ai mean)

 

 

N 1i 1

 

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

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

#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); // освобождение памяти

181

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.Воспользуйтесь справкой по математическим функциям и в программе примените функцию, которая осуществляет возведение в степень.

182

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));

183

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];

while (i < N) {

while ((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) – это массив указателей на три функции. В случае когда возвращаемые значения функций имеют различный тип, можно определить несколько указателей на функции.

184

Для понимания работы функции по расчету модуса алгоритм вычислений рекомендуется формулировать следующим образом: «Разбить сортированный список значений на ряд меньших списков, каждый из которых содержит одинаковые значения. Пересчитать число элементов в этих списках, и список с наибольшим числом элементов будет соответствовать модусу данных» [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]);

185

// Вызов функции сортировки по возрастанию в алфавитном порядке puts("\n The sorting in ascending order:");

bsort (Lines, n, less);

for (i = 0; i < n; ++i) printf("\t %s\n", Lines[i]);

// Вызов функции сортировки по убыванию в алфавитном порядке puts("\n The sorting in descending order:");

bsort (Lines, n, greater);

for (i = 0; i < n; ++i) printf("\t %s\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() в процессе сортировки для определения

порядка расположения элементов (слов).

186

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

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

Задание 4

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

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

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

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

= sin 3 −/3.

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

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

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

#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

187

//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;

}

188

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.В программу добавьте описание кубической и параболической функций. Напишите необходимые строчки программного кода для запроса о построении графика соответствующей функции.

189

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

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

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

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

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

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

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

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

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

БИБЛИОГРАФИЧЕСКИЙ СПИСОК

1.Керниган Б. У. Язык программирования С : пер. с англ./Б. У. Керниган, Д. М. Ритчи. – 2-е изд. – М. : Вильямс, 2007. – 304 с.

2.Дейтл Х. М. Как программировать на С : пер. с англ./Х. М. Дейтл, П. Дж. Дейтл. – 4-е изд. – М. : Бином-Пресс, 2006. – 912 с.

3.С/С++. Архив программ / А. Фридман, Л. Кландер, М. Михаэлис, Х.

Шильдт. – М. : БИНОМ, 2001. – 640 с.

190

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