Функции в языке С. Объявление функции. Оператор return. Прототипы функций. Параметры и аргументы функции, страница 5

Функция main(), как и другие функции, может возвращать целое значение. Оно передается в вызывающий процесс. В наших программах это всегда операционная система MS DOS.

По принятому соглашению для операционной системы MS DOS возврат нулевого значения говорит об успешном окончании работы, другие значения говорят об аварийном окончании работы программы.

Проверить значение, возвращаемое функцией main(), можно командой MS DOS

> if error level value где value - конкретное значение.

Функция mainO может и не возвращать значения, если она объявлена как void main(void){...}

Параметры командной строки можно задать не выходя из интегрированной среды системы. Для этого надо выбрать в меню Run|Arguments. В открывшемся диалоговом окне можно задать командную строку. Имя выполняемой программы добавлять не надо.

Рекурсивные функции

В языке С функции могут вызывать сами себя. Функция называется рекурсивной, если оператор в теле функции содержит вызов этой же функции. Классический пример рекурсивной функции - это вычисление факториала числа N! = 1*2*3*...*N.

Назовем эту функцию factorial().

factorial(int n)

{

int a;

if (n=l) return 1;

a = factorial(n-l)*n;

return a;

}

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

Указатель на функцию

На функцию, как и на другой объект языка С, можно создать указатель Указатель pfunc на функцию, возвращающую значение типа type и имею щую параметры типа typel, type2, объявляется следующим образом:

type (*pfunc)(typel tl, type2 t2);

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

#include <stdio.h>

#include <math.h>

/* Пример  Использование указателя на функцию */

double f(double x);

double f 1 (double x);

double f2(double x);

double ff(double (* pf)(double x)); /* Указатель на фукцию в качестве аргумента функции */

main()

{

double 2=1.1, у;

double (*ptrf)(double x); /* Указатель на функцию */

ptrf=f;     /* Инициализация указателя */

y=(*ptrf)(z);  /* Вызов функции через указатель - первый способ */   printf("z=%f y=%f\n", z, у);

y=ptrfl(z);      /* Вызов функции через указатель - второй способ */ printf("z=%f y=%f\n", z, у);

ptrf=sin;    /* В качестве функции можно использовать стандартные библиотечные функции */

y=ptrf(z);

printf(" z=%f sin(z)=%f\n", z, у);

y=(*ptrf)(2.5);    /* Можно вызвать функцию и так */

pnntf("z=%f y=%f\n", z, у);

y=ff(fl);          /* Вызов функции ff сп параметром f1 */

printf("z=%f y=%f\n", z, у);

y=ff(cos);         /* Другой вызов с другой функцией */

printf("z=%f y=%f\n", z, у);

y=ff(ptrf);        /* То же через указатель на функцию */   

printf("z=%f y=%f\n", z, у);   

return 0;

}          

double f(double x)     

puts("In f()");    

return x;   

double fl (double x)

{

puts("In fl()");

return x*x;

}

double f2(double x)

{

puts("In f20");

return x*x*x; }

double ff(double (* pf)(double x)) /* Функция с указателем на функцию в качестве параметра */

{

printf(" In ff() %f\n", pf(3));

return pf(3);

}

Так же как и для других типов переменных, можно использовать массив указателей на функцию. Такая структура данных называется jump table. Если есть объявления

int f(0(void);    int fl(void); int f2(void);      int f3(void); int(*jtable[])(void)={f0, fl, f2, f3};

Соответствующую функцию можно вызвать val = (*jtable[i])();   или   val = jtable[i]();