zz_c_35-function

Программа должна быть маленькой и гибкой, ее подпрограммы должны соединяться как жемчужины в ожерелье. //(Дао Программирования)// Итак, мы только что научились программировать вычисление по формуле. Любой. Что мы будем делать, если та же формула потребуется нам еще раз? А еще?

Простой подход - копирование/вставка. Современные редакторы позволяют делать это легко. Но этот подход - неправильный. Недостатки подхода - "разбухание" программы (один кусок повторяется много раз) и сложность внесения изменений / исправлений (нужно внести одинаковые изменения во все кусочки, которые еще надо найти. И не дай бог пропустить кусочек.)

Правильный подход - повторное использование кода. То, что будет использовано несколько раз, записывается единожды, но оформляется в виде подпрограммы. На С имеется единственный тип подпрограммы - функция. Там, где кусочек нужен, вставляется инструкция вызова функции.

Мы уже использовали функции из стандартной библиотеки. При вычислении по формуле это были знакомые из математики функции, например, синус:. Операция печати тоже выполняется функцией:. Теперь научимся делать свои собственные. Давайте создадим функцию, вычисляющую math y = sin\: 3a+cos\: 5b. math Назовем нашу функцию f. code format="c" double f(double a, double b) { double y;   y=sin(3*a)+cos(5*b); return y; } code У функции есть входные значения (параметры) - в нашем случае их два: a и b, есть возвращаемое значение (результат вычисления). Значения имеют тип, для вычислений это в основном. include page="zz_c_35-2-void" editable="true" Таким образом, первая строка - заголовок функции - будет иметь вид code format="c" double f(double a, double b) code Далее в фигурных скобках идет тело функции - "полезная нагрузка". В данном случае это вычисление выражения. Переданные параметры доступны в теле функции как переменные. Можно дополнительно объявить переменные; эти переменные будут локальными (существовать только внутри функции, никак не влияя на переменные с тем же именем снаружи / в других функциях). Мы создадим переменную y. Полученный результат нужно вернуть как значение функции (строка ""). Можно делать короче, совместив вычисление с возвратом значения. Этот пример можно сократить до одной строки: code format="c" return sin(3*a)+cos(5*b); code Теперь давайте используем нашу функцию для вычисления формулы code sin3x+cos 5y - sin3градуса -1 cos 5(x+y) code math \frac{sin\: 3x+cos\: 5y}{cos\; 5(x+y)} - sin\; 3^o -1 math Формула немножко хитрая (исключительно в учебных целях); если вспомнить, что, а , видно, что ее можно переписать с использованием нашей функции как code f(x, y) --- - f(3градус, 0) f(0, x+y) code math \frac{f(x, y)}{f(0, x+y)} - f(3^o, 0) math Это демонстрирует нам такое важное достоинство функций, как параметризация – что бы мы ни подставили при вызове как фактические параметры, оно при необходимости будет вычислено и передано в функцию. А там уже будет подставлено вместо формальных параметров (у нас a и b).

Для того, чтобы в основной программе можно было использовать функцию, она должна быть записана выше  (можно и ниже, но тогда перед  придется вставлять заголовок функции - ее первую строку, вот так: code format="c"    double f(double a, double b);    int main(void)    /*код main...*/    double f(double a, double b)    /*код f...*/ code )

Полный код программы: code format="c" /*function program*/
 * 1) define _USE_MATH_DEFINES
 * 2) include 
 * 3) include 

double f(double a, double b) { double y;   y=sin(3*a)+cos(5*b); return y; }

int main(void) {	double x=1.2, y = 2.5; double z;

z = f(x, y)/f(0.0, x+y) - f(3*M_PI/180, 0.0); printf("\nz=%lf", z); return 0; } code Как мы уже выяснили раньше, строка нужна для того, чтобы в  стала определена константа, число Пи, нужное нам для преобразование из градусов в радианы в вызове функции. Подробнее о функциях можно почитать, например, в пособии "Информатика. Сегментация программ" Р.Н. Гурьяшова, А.В. Шеянов.