Правила записи и использования функций

1. Имя определяет деление функций на главную и дополнительные. Главная – функция с именем main, WinMain, OwlMain (головная). В ней, как правило, описатель типа, список формальных параметров и оператор return не указываются.

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

3. Операнды любой функции – локальные параметры и формальные, перечисленные в заголовке.

4. В качестве формальных параметров используются переменные и указатели.

Количество, типы и последовательность расположения формальных параметров в списке задается создателем функции.

Результаты вычислений тела функции – константы.

7. В качестве выражения РВ оператора return используются константы, переменные и их совокупности.

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

9. Тип возвращаемого значения определяется типом функции. Если он не указан, подразумевается целочисленный результат (int). Результат возвращается в точку вызова.

10. В теле функции в соответствии с требованиями ветвящегося алгоритма могут использоваться несколько операторов возврата (return), но выполняться будет только один из них.

11. Отсутствие в головной функции оператора return подтверждается на этапе компиляции соответствующим предупреждением.

12. Головная и дополнительные функции – отдельные программные модули. Поэтому в них могут использоваться одноимённые переменные, указатели и массивы.

13. Тексты дополнительных пользовательских функций могут располагаться в любом месте программы (вне тела любой из функций).

14. Тексты стандартных функций располагаются в соответствующих библиотеках языка Си/Си++ в виде объектных модулей.

15. Независимо от взаиморасположения функций выполнение программного модуля начинается с головной функции.

16. Из тела каждой функции можно обращаться к любой другой (вызывать ее).

17. Фактические и формальные параметры в списках должны совпадать по количеству, месту расположения и типу.

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

19. Вызов дополнительной функции требует ее предварительного определения (расположения над вызывающей). В противном случае её необходимо описать (задать прототипом). Описание размещается над вызывающей функцией. Описания стандартных функций (их прототипы) находятся в стандартных заголовочных файлах.

Прототип – конструкция, аналогичная описателям переменных.

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

Прототип функции идентичен ее заголовку и имеет структуру

[тип] имя([тип [b1], . . . ,тип [bi], . . . ,тип [bn]]);

где имя – идентификатор (название) функции;

тип – описатель типа функции (результата) и формальных параметров;

b1 … bi bn – элементы списка формальных параметров с указанием типа;

, , , – разделители элементов списка;

( ) – ограничители списка формальных параметров;

[ ] – признак необязательности содержимого;

; – признак оператора.

Структура прототипа определяет, что в списке можно указывать только типы формальных параметров.

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

Вариант 1.

#include<stdio.h>/*файл с прототипами функций ввода-вывода*/

#include<math.h> /*файл с прототипами математич. функций */

float sum(float a, float b);/*прототип пользовательской ф-ции*/

main( ) /* заголовок головной функции */

{

float a, b, c, d, d1; /* описатели локальных переменных */

. . .

c = pow( a, 2 ) + b; /* вычисление с вызовом

стандартной функции pow */

d = sum( a, b ) - 0.5*c; /* вычисления с вызовами пользователь-*/

d1=d+sum(3.6, sqrt(d)); /*ской функции sum и стандартной sqrt*/

. . .

printf(“%f %f %f ”, c, d, d1); /* вызов функции printf */

}

/* определение пользовательской функции sum */

float sum(float s1, float s2 ) /* заголовок пользовательской функции */

{

float s; /* описание локальной переменной s */

s = s1 + s2; /*вычисление s по формальным параметрам s1 и s2*/

return s; /* возвращение значения s в вызывающую функцию */

}

В представленном варианте до определения главной функции заголовочными файлами выполнены описания стандартных функций (математических и ввода-вывода), а затем пользовательской функции sum – указанием её прототипа.

Главная функция расположена над дополнительной и не содержит в заголовке описатель типа и список формальных параметров. В теле главной функции выполнены обращения к стандартным функциям: sqrt – с одним фактическим параметром (d), pow – с двумя (a, 2) и printf – с тремя (“%f %f %f ”, c, d, d1). В арифметическом выражении вычисления переменной d в качестве первого операнда используется вызов пользовательской функции sum с указанием фактических параметров – a и b, описанных в головной функции как локальные переменные. Типы (вещественные) определяет постановка задачи, последовательность расположения в списке задана произвольно.

В арифметическом выражении вычисления переменной d1 в качестве второго операнда используется вызов пользовательской функции sum с указанием фактических параметров – 3.6 и sqrt( d ). Последовательность их расположения в списке аналогична выбранной для а и b.

Дополнительная функция предназначена для вычисления суммы двух операндов (формальных параметров) и выполнена по левому варианту структуры. Ее заголовок определяет тип возвращаемого значения (float), название функции (sum) и список формальных параметров – вещественных переменных s1 и s2. Порядок их расположения в списке определяется соответствующими фактическими параметрами (a и b), (3.6 и sqrt( d )) в обращениях главной функции.

Выполнение программного модуля (аналогично работе со стандартными функциями) приведет к двукратной автоматической передаче численных значений фактических параметров (a, b), а затем (3.6, sqrt(d)) из головной функции в вызываемую пользовательскую (sum) – формальным параметрам (s1, s2). После выполнения вычислений тела функции результаты (s) автоматически возвратятся в точки вызова как операнды вычисления переменных d и d1. Время существования переменных s1, s2 и s соответствует длительности работы функции sum.

Вариант 2.

#include<stdio.h>/*файл с прототипами функций ввода-вывода */

#include<math.h> /* файл с прототипами математич. функций */

/* определение пользовательской функции sum */

float sum(s1, s2 ) /* заголовок дополнительной функции */

float s1, s2; /*описание формальных параметров*/

{

return s2+s1;/*возвращение значения s в вызывающую ф-цию*/

}

main( ) /* заголовок головной функции */

{

float a, b, c, d, d1; /* описатели локальных переменных */

. . .

c = pow( a, 2 ) + b; /* вычисление с вызовом

стандартной функции pow */

d = sum( a, b ) - 0.5*c; /* вычисления с вызовами поль- */

d1 = d + sum( 3.6, sqrt(d) ); /* зовательской функции sum */

. . .

printf(“%f %f %f ”, c, d, d1); /* вызов стандартной функции printf */

}

Дополнительная функция составлена с использованием правого варианта структуры. Тело дополнительной функции составляет один оператор return.

Дополнительная функция расположена над основной. Описание типов формальных параметров вне заголовка подпрограммы при машинной обработке приведет к выдаче предупреждений «по заголовку функции невозможно проконтролировать типы параметров, что может повлиять на результаты счета». Устранение возможных последствий выполняется стандартным способом – указанием прототипа дополнительной функции над главной.

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

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

Таблица 10.1

Обозначение в алгоритме a z n m k f fi i
Обозначение в программе a z n m k f fi i

Классический вариант программирования задачи

#include<stdio.h>/*файл с прототипами функций ввода-вывода*/

#include<conio.h>/*файл с прототипом функций getch(), clrscr()*/

#include <math.h> /*файл с прототипами математич. функций*/

#include<windows.h>/* файл с прототипом функции СharToOem*/

long fakt(int fi); /* прототип функции расчета факториала */

main( ) /* определение головной функции */

{

float a, z1, z2, z;

int n, m, k;

char buf[30];

clrscr( );

CharToOem(" Введите значения a, n, m, k: ",buf);

printf("\n %s \n",buf);

scanf("%f%d%d%d", &a, &n, &m, &k);

z1 = log(a) + fakt(n);

z2 = fakt(m) - fakt( k-m );

z = z1 + z2 - 0.2*a;

printf( "\n a=%.2f n=%d m=%d k=%d"

"\n z1=%.2f z2=%.2f"

"\n z=%.2f\n", a, n, m, k, z1, z2, z);

getch( );

}

long fakt(int f) /* заголовок дополнительной функции расчета факториала */

{

int i;

long fi;/*описание переменной текущего значения факториала*/

for(fi=1, i=1; i<=f; i++) /*заголовок цикла расчета факториала */

{

fi = fi * i; /* расчет текущего значения факториала */

}

return fi;/* возврат в головную функцию значения fi */

}

16.9 5 4 10

Под закрывающей скобкой приведены исходные данные для решения задачи.

В подпрограмме наряду с формальным параметром f использованы локальные переменные fi и i. Первая из них определяет значение вычисляемого факториала, изменяясь от единицы до конечного возможно большого (long) значения. Вторая используется как параметр цикла для организации последовательного умножения в заданном диапазоне.

Результаты решения представлены в приложении 10.1.

Программирование задачи с графическим интерфейсом

Программирование задачи при использовании графического интерфейса предварим его разработкой. Для ввода значений a, n, m, k планируем однострочные поля редактирования (EditA, EditN, EditM, EditK).

Вывод расчетных значений z1, z2, z реализуем в однострочные поля редактирования (EditZ1, EditZ2, EditZ).

Управление процессом решения реализуем двумя командными кнопками, расположенными в нижней части окна. Назначение каждой определяется ее названием.

С учетом планируемого интерфейса выполним программирование задачи.

#include <stdio.h>/*файл с прототипами функций ввода-вывода*/

#include <math.h>

long fakt(int fi); /* прототип функции расчета факториала */

void TSumprDlgClient::BNClickedOk()

{

// INSERT>> Your code here.

float a, z1, z2, z;

int n, m, k;

char buf[30];

EditA->GetText(buf,10); /*ввод */

a=atof(buf); /*значения а*/

EditN->GetText(buf,10); /*ввод */

n=atoi(buf); /*значения n*/

EditM->GetText(buf,10); /*ввод */

m=atoi(buf); /*значения m*/

EditK->GetText(buf,10); /*ввод */

k=atoi(buf); /*значения k*/

z1 = log(a) + fakt(n);

z2 = fakt(m) + fakt( k-m );

z = z1 + z2 - 0.2*a;

sprintf(buf,"%.2f ",z1); /* вывод */

EditZ1->SetText(buf); /*значений z1*/

sprintf(buf,"%.2f ", z2); /* вывод */

EditZ2->SetText(buf); /* значений z2*/

sprintf(buf,"%.2f",z); /* вывод */

EditZ->SetText(buf); /*значений z3*/

}

long fakt(int f) /* заголовок дополнительной функции расчета факториала */

{

int i;

long fi;/*описание переменной текущего значения факториала*/

char buf[30];

for(fi=1, i=1; i<=f; i++)/*заголовок цикла расчета факториала*/

{

fi = fi * i; /* расчет текущего значения факториала */

}

return fi; /* возврат в головную функцию значения fi */

}

16.9 5 4 10

Под закрывающей скобкой приведены исходные данные для решения задачи.

Результаты решения представлены в приложении 10.2.

10.2. Подпроцесс с аргументом – одномерным массивом и одним результатом

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

Постановка задачи

Вычислить значение функции:

Вычисления функции проводить с элементами массивов X(n) и Y(m), когда n £ 10, m £ 15, при a = 0,96; b = 35.