С поддерживает предварительное объявление (декларацию) функций, которое также созданием называется прототипом. Предварительное объявление позволяет перечислить список функций в начале исходной программы. Такой список предлагает удобный способ указания того, какие функции будут использованы в программе. Кроме того, использование прототипов заранее уведомляет компилятор о типах возвращаемых значений и формальных параметров различных функций. После объявления функций можно размещать их определения в любом порядке и не волноваться по поводу ошибок компиляции, которые происходят, когда функция вызывается перед объявлением или определением. Общий синтаксис объявления для функции:
[ <Класс_памяти>] <Тип_возвращаемого_значения> <имя> ([ <Список_типов_параметров >]);
Классы памяти для функций: extern и static. По умолчанию – extern .
Каждая функция имеет <тип_возвращаемого_значения>, который указывается перед названием (<именем>) функции. <Список_параметров> следует за названием функции и заключается в круглые скобки.
Точка с запятой в конце необходима для объявления функции, но не нужна в определении функции. Имена формальных параметров могут отсутствовать или не опадать с именами в определении функции, но типы должны совпадать обязательно. По умолчанию тип возвращаемого значения int.
Пример объявления функции:
dauble summa(float a, float b); // два параметра типа float, возвращается
// значение типа dauble
С использует специальный тип void, чтобы указать, что функция не требует параметров или не возвращает значение. Использование оператора return в void -функции не требуется.
Примеры объявлений функций:
upDate(); // без параметров, // возвращается int void (void); // без параметров // getPrint | void releesDate(int fop);// один // параметр void reseedType(float Seed); // один // параметр |
Синтаксис определения функций в С
Синтаксис определения функций в С имеет следующий вид:
[<Класс_памяти>] <Тип возвращаемго_значения> <Имя> ([<Список_объявлений_формальных_параметров>])
{[// - объявления переменных (декларации);]
// - операторы;
[return <возвращаемое_значение_заданного_типа>;]
}
Функция возвращает результат своей работы, используя оператор return, который обычно появляется в конце тела функции. Однако, функция может иметь больше одного оператора return.
<Список_объявлений_формальных_параметров> функции может отсутствовать (void), содержать одно или больше объявлений формальных параметров, соответствующих (аргументов)данной функции. Параметры в списке разделяются запятой и имеют синтаксис:
[модификатор]<тип_параметра><имя>
В качестве модификаторов могут использоваться следующие ключевые слова const, near, face, huge.
Примеры определений функций, объявленных ранее
dauble summa(float x, float y)// требу- // ет два параметра {return x+y; // возвращаемое значение преобразуется к типу dauble } | void getPrint(void) //без параметров // и возвращаемого значения {printf (n \” Пример\n”); } // returnотсутствует |
Функция summa() имеет два параметра и тип возвращаемого значения dauble. Функция getPrint() не имеет параметров и возвращаемого значения.
Если функция объявлена с ключевым словом inline, то компилятор заменяет любой вызов inline - функции копией её тела, приведенного в определении.
Пример inline - функции: inline long square(int nNum) {return nNum*nNum; } | В примере определена inline - функция square (), которая возвращает квадрат параметра nNumтипаint. |
Использование локальных и глобальных переменных в функциях.
Вызов функции
В любойфункции можно объявлять локальные константы и переменные. Область действия локальных констант и переменных ограничена телом функции-хозяина. Никакая функция не может непосредственно получить доступ к локальным константам и переменным другой функции. Существует два класса памяти локальных переменных: register и auto, которые указываются перед типом переменных. Локальные переменные создаются каждый раз, когда функция начинает выполняться, а когда функция завершает работу, система устраняет локальные переменные.
В отличие от автоматических переменных, статические переменные (с классом памяти static) сохраняют своё значение между вызовами функции. Эта особенность позволяет в функциях использовать значения, вычисленные при предыдущем вызове. Статическая переменная инициализируется один раз при первом вызове функции явно или по умолчанию нулевым значением. Инициализация статических переменных позволяет, например, функции-хозяину определить, выполняется ли она впервые.
Пример статических переменных, объявленных в функции
int doCalc() {static int index1=2; static float my_index; // другие объявления // операторы return …; } | В примере объявлена и явно инициализирована статическая переменная index1, а также инициализирована неявно переменная my_index(по умолчанию равна 0).Эти переменные сохраняют свои значения между вызовами функции doCalc (). |
Пример
/* ЗАНЯТИЕ N 7
Выполнил студент группы......... Петров Ю.В.
Объявление и определение функций. Применение функций:
передача переменных в функцию по значению, по адресу
и по ссылке, возврат значений из функции. Области
видимости переменных, примеры операций.
Выбор функции - по номеру с помощью оператора switch*/
#include <stdio.h>
#include <conio.h>
#include <math.h>
float glob=2.5;
float Fx0(float a, float b, float c) //Определение функции
{ return --b/(2*a)*(++c); }
//Fx0-Передача параметров и возврат по значению
float* Fx1(float, float, float); //Объявление функции
//Fx1-Передача параметров по значению, возврат указателя
float& Fx2(float, float, float); //Объявление функции
//Fx2-Передача параметров по значению, возврат ccылки
//Передача параметров по значению, последнего по адресу
void changex0(float, float, float, float *);
//Передача и изменение параметров по адресу
void changex1(float *, float *, float *, float *);
//Передача изменение параметров по ccылке
void changex2(float &, float &, float &, float &);
void main()
{ float a1,b1,c1,x1;
float* px=&x1;
float& sx=x1;
char diskr;
clrscr();
printf(" Введитe значения переменных: а, b, c: ");
scanf("%f %f %f", &a1, &b1, &c1);
printf("Введитe номер функции (0...5),\
6 или ESC-конец расчета: ");
vvod1: diskr=getche();
switch (diskr)
{case '0': x1=Fx0(a1,b1,c1); break;
case '1': px=Fx1(a1,b1,c1); printf("\nglob= \
%6.3f *px= %6.3f", glob, *px); break;
case '2': sx=Fx2(a1,b1,c1); printf("\nglob= \
%6.3f sx= %6.3f", glob, sx); break;
case '3': changex0(a1, b1, c1,&x1); break;
case '4': changex1(&a1,&b1,&c1,&x1); break;
case '5': changex2(a1, b1, c1, x1); break;
case '6':case 27: goto end;
default:printf("\nВне диапазона, введите другой \
номер функции (0...5) ");
goto vvod1;
}
printf("\nРезультат: a1= %5.3f b1= %5.3f c1= %5.3f \
x1= %5.3f\n",a1,b1,c1,x1);
printf("Введите другой номер функции: ");
goto vvod1;
end:;
}
float* Fx1(float a, float b, float c) //Определение функции N 1
{ float*pf;
*pf=glob+(--b)/(2*a)*(++c);
//printf("\nglob= %6.3f *pf= %6.3f",glob,*pf);
return pf;
}
float& Fx2(float a, float b, float c) //Определение функции N 2
{ float& sf=glob;
sf=(--b-sqrt(abs(++c)))/(4*++a);
glob+=5; //printf("\nglob= %6.3f sf= %6.3f ",glob,sf);
return sf;
}
void changex0(float a, float b, float c, float *d) //N 3
{ *d=pow(b,2)-4*--a*++c; }
void changex1(float *a, float *b, float *c, float *d) //N 4
{++*a; ++*b++; ++*c; *d+=*a+*b+*c; }
void changex2(float &a, float &b, float &c, float &d) //N 5
{ a+=2; b+=2; c+=2; d-=a+b+c; }
/* Введитe значения переменных: а, b, c: 3 4 5
Введитe номер функции (0...5), 6 или ESC-конец расчета: 0
Результат: a1= 3.000 b1= 4.000 c1= 5.000 x1= 3.000
Введите другой номер функции: 1
glob= 2.500 *px= 5.500
Результат: a1= 3.000 b1= 4.000 c1= 5.000 x1= 5.500
Введите другой номер функции: 2
glob= 5.034 sx= 5.034
Результат: a1= 3.000 b1= 4.000 c1= 5.000 x1= 5.034
Введите другой номер функции: 3
Результат: a1= 3.000 b1= 4.000 c1= 5.000 x1=-32.000
Введите другой номер функции: 4
Результат: a1= 4.000 b1= 5.000 c1= 6.000 x1=-18.000
Введите другой номер функции: 5
Результат: a1= 6.000 b1= 7.000 c1= 8.000 x1=-39.000
Введите другой номер функции: 8
Вне диапазона, введите другой номер функции (0...5) 6 */
Ход работы
1 Изучить теоретические сведения.
2 В соответствии с индивидуальным заданием разработать алгоритмы для заданных функций и функции main(). При разработке функции предусмотреть передачу и возврат значений различных типов.
3 Разработать программу с использованием функций.
4 Выполнить определение функции до функции main() и после нее.
5 Набрать программу на компьютере и устранить ошибки.
6 Получить результат и сделать выводы по работе.
7 Оформить отчет.
8 Подготовиться к защите лабораторной работы, изучив контрольные вопросы по теме.
Индивидуальное задание к лабораторной работе №7
Составить программу реализующую вызов функций H, a, b, c согласно индивидуальному заданию приведенному в таблице 7.1.
Таблица 7.1 - Индивидуальное задание
Вар. | H | a | B | с | x |
A2+b2-6c | x2-e-x | lnx+ | cos2x+x5 | 5,4 | |
c2+8b+10a | sin2x+x1/4 | tgx-8x3 | x4+2sinx2 | 1,2 | |
3a2+4b-8 | 3x-2cos3x | lnx+2ex | x1/3+4x-1 | 0,3 | |
A3+b2-8c | sin3x+x4 | -lnx | 4x-5x3 | 1,7 | |
6b3+4c-2 | tgx+e2x | x2-6x3 | 1/x-2lnx | 4,1 | |
A2+b2+c2 | ex+e2x+4 | x-sin3x | x2/cos3x | 2,4 | |
5b3-2a+c | tgx-2x | -sinx | x3/7 | 5,5 | |
4a2+5b2 | cosx+2x | x4-2x/5 | 2x-5 | 4,6 | |
3ab-4c | sin2x+5 | cosx5 | x1/3+tgx | 1,6 | |
c2+5a3-b | cos3x-6x | -4x3+lnx | e2x+4cosx | 4,6 | |
2a+4c-b4 | ex-2lnx | 2x-5/x | x5-2lnx | 3,9 | |
A2+b2+c2 | 2/x+x3 | lnx2-4x | tgx-sin2x | 4,1 | |
(a+b)2 | lnx+2ex | tgx+e2x | x2-e-x | 3,4 | |
2ac-3cb | 1/x-2lnx | cosx+2x | sin2x+x1/4 | 1,9 | |
5c+2a4 | x2-2/x | (2-x)/6 | cos3x-2x | 2,3 | |
A+b+c | lnx/2x | x3-4x | tgx-2x | 4,2 | |
2a+3b+4c | x2+x3 | lnx-x4 | cos2(x-4) | 2,8 | |
A2+b3+c4 | sin2x+x1/4 | x3+4x | ex+2lnx | 1,3 | |
A+2b+3c | 2x-x1/4 | -2cosx | tgx-4x | 3,1 | |
2(a+b)-c4 | (x3-x/2)3 | lnx-e2x | 2,4 | ||
c2-b3 | 2x+sinx4 | sin(x-lnx) | lnx2+2x | 1,1 | |
3a-4cb | 2cosx3 | tgx/4 | x/5 | 3,1 | |
c5-2ab | 1/2sin3x | sin6x/x3 | x-4sin2x | 1,8 | |
6a+3b3+c | cosxx+2x | sin2x+tgx | lnx-e-x | 2,1 | |
4abc | xx-sinx3 | x/2-x5 | 2x-sin3x | 4,1 | |
A2+(b-c)5/3 | 2x1/3+1 | sin(x2+4) | lncos3x | 5,3 | |
(a+4b)1/3-c2 | tg(2x)/4 | cosx2/x1/5 | e-2x+1/x2 | 3,8 | |
A1/3+(b3-c) | x+23x | lnsin34x | arcsin2x | 4,2 | |
B3+(a-4c)1/5 | 53x/(3x-1) | e-5x+4/x | cos(x1/3) | 2,6 | |
c1/5-(b+3a)2 | +ex | cosx+x2 | arctg(x3) | 1,3 |