Лекция 6 Функции
Объявления и определения Объявление функции – указание имени функции, а также входных и выходных параметров Определение функции – указание набора инструкций, составляющих тело функции Чтобы использовать функцию, необходимо ее объявить Объявление функции может встречаться в теле программы несколько раз Определение функции может встречаться в теле программы не более одного раза Определение включает в себя объявление
Объявление функции Формат модификаторы возвращаемый_тип имя ( список_аргументов ); Примеры void process (); void undo ( void ); int sum ( int a, int b ); const char* find ( const char *, char letter ); void process (); void undo ( void ); int sum ( int a, int b ); const char* find ( const char *, char letter );
Определение функции Формат объявление функции { инструкции } Примеры int sum ( int a, int b ) { return a + b ; } const char* find ( const char * str, char letter ) { for ( ; *str; str++ ) if ( *str == letter ) return str ; return NULL; } int sum ( int a, int b ) { return a + b ; } const char* find ( const char * str, char letter ) { for ( ; *str; str++ ) if ( *str == letter ) return str ; return NULL; }
Модификатор inline Рекомендует компилятору замещать вызов функции ее телом Указывается только в определениях функций Определение функции с inline может повторяться более одного раза inline int sum ( int a, int b ) { return a + b ; } int main () { return sum ( 4, 7 ); } inline int sum ( int a, int b ) { return a + b ; } int main () { return sum ( 4, 7 ); }
Передача аргументов Входные параметры функции называютя ее аргументами Для каждого аргумента создается локальная переменная Значения, указанные при вызове функции, копируются в эти локальные переменные В объявлении функции можно не указывать имена аргументов В определении функции нельзя использовать необъявленное имя int sum ( int, int ); int sum ( int a, int b ) { return a + b ; } int main () { int a = 7 ; int b = 9 ; return sum ( b, a ); } int sum ( int, int ); int sum ( int a, int b ) { return a + b ; } int main () { int a = 7 ; int b = 9 ; return sum ( b, a ); }
Передача с помощью адресных типов Виды передачи Передача по значению Передача по ссылке Передача по адресу void sum1 (int a, int b) { a += b ; } void sum2 (int & a, int b) { a += b ; } void sum3 (int * a, int b) { *a += b ; } void main () { int a = 3, b = 5 ; sum1 ( a, b ); sum2 ( a, b ); sum3 ( &a, b ); } void sum1 (int a, int b) { a += b ; } void sum2 (int & a, int b) { a += b ; } void sum3 (int * a, int b) { *a += b ; } void main () { int a = 3, b = 5 ; sum1 ( a, b ); sum2 ( a, b ); sum3 ( &a, b ); }
Использование const в аргументах Использование константных ссылок и константных указателей подразумевает, что их «адресат» не изменится в теле функции void f1 ( int a ) { a = 5 ; } void f2 ( int const a ) { a = 5 ; } void f3 ( int * a ) { *a = 5 ; } void f4 ( int *const a ) { *a = 5 ; } void f5 ( int const *a ) { *a = 5 ; } void f6 ( int & a ) { a = 5 ; } void f7 ( int const & a ){ a = 5 ; } void main () { int a = 3 ; f1( a ); f2( a ); f3(&a); f4(&a); f5(&a); f6(a);f7(a); } void f1 ( int a ) { a = 5 ; } void f2 ( int const a ) { a = 5 ; } void f3 ( int * a ) { *a = 5 ; } void f4 ( int *const a ) { *a = 5 ; } void f5 ( int const *a ) { *a = 5 ; } void f6 ( int & a ) { a = 5 ; } void f7 ( int const & a ){ a = 5 ; } void main () { int a = 3 ; f1( a ); f2( a ); f3(&a); f4(&a); f5(&a); f6(a);f7(a); }
Аргументы - массивы Массивы можно указывать в качестве аргументов и возвращаемых значений Фактически передается только адрес первого элемента массива. Массивы нельзя передавать по значению void f1 ( int a[3] ) { a[1] = 5 ; } void f2 ( int a[] ) { a[1] = 5 ; } void f2 ( int a[][4] ) { a[1][2] = 5 ; } void main () { int a[3]; f1 (a); f2(a); int b[4][4]; f3 (b); } void f1 ( int a[3] ) { a[1] = 5 ; } void f2 ( int a[] ) { a[1] = 5 ; } void f2 ( int a[][4] ) { a[1][2] = 5 ; } void main () { int a[3]; f1 (a); f2(a); int b[4][4]; f3 (b); }
Аргументы по умолчанию Позволяют указывать не полное количество аргументов при вызове Указываются всегда в конце списка Не могут быть изменены в последующих объявлениях void f1 ( int a = 0, int b = 5 ); void f2 ( int a = 0, int b ); void f3 ( int * a = 0 ); void f3 ( int * = 0 ); void f3 ( int * a = 3 ); void f1 ( int a = 0, int b = 5 ); void f2 ( int a = 0, int b ); void f3 ( int * a = 0 ); void f3 ( int * = 0 ); void f3 ( int * a = 3 );
Неуказанные аргументы Указываются в конце списка аргументов Типы не проверяются компилятором Требует восстановления стека #include void error ( int code,... ) { va_list ap ; va_start ( ap, code ); while(1) { char * p = va_arg(ap,char*); if ( !p ) break ; std::cout
Возвращаемые значения Возвращаемое значение задается инструкцией return. Функция, объявленная как void, не должна возвращать значения Функция, объявленная как void, может вернуть значение другой объявленной как void функции Функция, объявленная иным типом, обязана вернуть значение данного типа Возврат всегда осуществляется по значению int f () { return 4 ; } int max ( int a, int b ) { if ( a > b ) return a ; return b ; } int max2 ( int a, int b ) { return a > b ? a : b ; } void f () { } void g () { return f(); } int f () { return 4 ; } int max ( int a, int b ) { if ( a > b ) return a ; return b ; } int max2 ( int a, int b ) { return a > b ? a : b ; } void f () { } void g () { return f(); }
Указатели на функцию Имя функции совпадает с указателем на нее Вызов функции с помощью оператора () применим как к имени, так и к указателю на нее void sum ( int ){} void (*pfn) ( int ); typedef void fn_t ( int ); typedef fn_t* pfn_t ; void main () { pfn = &sum ; pfn = sum ; pfn_t fn = &sum ; pfn_t fo = sum ; fn( 3 ); pfn( 5 ); } void sum ( int ){} void (*pfn) ( int ); typedef void fn_t ( int ); typedef fn_t* pfn_t ; void main () { pfn = &sum ; pfn = sum ; pfn_t fn = &sum ; pfn_t fo = sum ; fn( 3 ); pfn( 5 ); }