Структуры и алгоритмы обработки данных Часть 5 Функции
4. Структурное программирование 4. 10. Функции Структурная декомпозиция void input_vect (double v [ ], int dim) программы { Выполнение начинается с main int main() { … input_vect (a, n); … add_vect (a, b, c, n); … output_vect (c, n); … return 0 } Возврат из main в ОС … return; } void add_vect (double v 1 [ ], double v 2 [ ], double res [ ], int dim) { … return; } void output_vect (double v [ ], int dim) { … return; }
4. Структурное программирование 4. 10. Функции Структурная декомпозиция void input_vect (double v [ ], int dim) программы { Выполнение начинается с main int main() { … input_vect (a, n); … add_vect (a, b, c, n); … output_vect (c, n); … return 0 } Возврат из main в ОС … return; } void add_vect (double v 1 [ ], double v 2 [ ], double res [ ], int dim) { … return; } void output_vect (double v [ ], int dim) { … return; }
4. Структурное программирование 4. 10. Функции Структурная декомпозиция void input_vect (double v [ ], int dim) программы { Выполнение начинается с main int main() { … input_vect (a, n); … add_vect (a, b, c, n); … output_vect (c, n); … return 0 } Возврат из main в ОС … return; } void add_vect (double v 1 [ ], double v 2 [ ], double res [ ], int dim) { … return; } void output_vect (double v [ ], int dim) { … return; }
4. Структурное программирование 4. 10. Функции Структурная декомпозиция void input_vect (double v [ ], int dim) программы { Выполнение начинается с main int main() { … input_vect (a, n); … add_vect (a, b, c, n); … output_vect (c, n); … return 0 } Возврат из main в ОС … return; } void add_vect (double v 1 [ ], double v 2 [ ], double res [ ], int dim) { … return; } void output_vect (double v [ ], int dim) { … return; }
4. Структурное программирование 4. 10. Функции Структурная декомпозиция void input_vect (double v [ ], int dim) программы { Выполнение начинается с main int main() { … input_vect (a, n); … add_vect (a, b, c, n); … output_vect (c, n); … return 0 } Возврат из main в ОС … return; } void add_vect (double v 1 [ ], double v 2 [ ], double res [ ], int dim) { … return; } void output_vect (double v [ ], int dim) { … return; }
4. Структурное программирование 4. 10. Функции Структурная декомпозиция void input_vect (double v [ ], int dim) программы { Выполнение начинается с main int main() { … input_vect (a, n); … add_vect (a, b, c, n); … output_vect (c, n); … return 0 } Возврат из main в ОС … return; } void add_vect (double v 1 [ ], double v 2 [ ], double res [ ], int dim) { … return; } void output_vect (double v [ ], int dim) { … return; }
4. Структурное программирование 4. 10. Функции Структурная декомпозиция void input_vect (double v [ ], int dim) программы { Выполнение начинается с main int main() { … input_vect (a, n); … add_vect (a, b, c, n); … output_vect (c, n); … return 0 } Возврат из main в ОС … return; } void add_vect (double v 1 [ ], double v 2 [ ], double res [ ], int dim) { … return; } void output_vect (double v [ ], int dim) { … return; }
4. Структурное программирование 4. 10. Функции Структурная декомпозиция void input_vect (double v [ ], int dim) программы { Выполнение начинается с main int main() { … input_vect (a, n); … add_vect (a, b, c, n); … output_vect (c, n); … return 0 } Возврат из main в ОС … return; } void add_vect (double v 1 [ ], double v 2 [ ], double res [ ], int dim) { … return; } void output_vect (double v [ ], int dim) { … return; }
4. Структурное программирование 4. 10. Функции Структурная декомпозиция void input_vect (double v [ ], int dim) программы { Выполнение начинается с main int main() { … input_vect (a, n); … add_vect (a, b, c, n); … output_vect (c, n); … return 0 } Возврат из main в ОС … return; } void add_vect (double v 1 [ ], double v 2 [ ], double res [ ], int dim) { … return; } void output_vect (double v [ ], int dim) { … return; }
4. Структурное программирование 4. 10. Функции Структурная декомпозиция void input_vect (double v [ ], int dim) программы { Выполнение начинается с main int main() { … input_vect (a, n); … add_vect (a, b, c, n); … output_vect (c, n); … return 0 } Возврат из main в ОС … return; } void add_vect (double v 1 [ ], double v 2 [ ], double res [ ], int dim) { … return; } void output_vect (double v [ ], int dim) { … return; }
4. Структурное программирование 4. 10. Функции Структурная декомпозиция void input_vect (double v [ ], int dim) программы { Выполнение начинается с main int main() { … input_vect (a, n); … add_vect (a, b, c, n); … output_vect (c, n); … return 0 } Возврат из main в ОС … return; } void add_vect (double v 1 [ ], double v 2 [ ], double res [ ], int dim) { … return; } void output_vect (double v [ ], int dim) { … return; }
4. Структурное программирование 4. 10. Функции Структурная декомпозиция void input_vect (double v [ ], int dim) программы { Выполнение начинается с main int main() { … input_vect (a, n); … add_vect (a, b, c, n); … output_vect (c, n); … return 0 } Возврат из main в ОС … return; } void add_vect (double v 1 [ ], double v 2 [ ], double res [ ], int dim) { … return; } void output_vect (double v [ ], int dim) { … return; }
4. Структурное программирование 4. 10. Функции Структурная декомпозиция void input_vect (double v [ ], int dim) программы { Выполнение начинается с main int main() { … input_vect (a, n); … add_vect (a, b, c, n); … output_vect (c, n); … return 0 } Возврат из main в ОС … return; } void add_vect (double v 1 [ ], double v 2 [ ], double res [ ], int dim) { … return; } void output_vect (double v [ ], int dim) { … return; }
4. Структурное программирование 4. 10. Функции Структурная декомпозиция void input_vect (double v [ ], int dim) программы { Выполнение начинается с main int main() { … input_vect (a, n); … add_vect (a, b, c, n); … output_vect (c, n); … return 0 } Возврат из main в ОС … return; } void add_vect (double v 1 [ ], double v 2 [ ], double res [ ], int dim) { … return; } void output_vect (double v [ ], int dim) { … return; }
4. Структурное программирование 4. 10. Функции Структурная декомпозиция void input_vect (double v [ ], int dim) программы { Выполнение начинается с main int main() { … input_vect (a, n); … add_vect (a, b, c, n); … output_vect (c, n); … return 0 } Возврат из main в ОС … return; } void add_vect (double v 1 [ ], double v 2 [ ], double res [ ], int dim) { … return; } void output_vect (double v [ ], int dim) { … return; }
4. Структурное программирование 4. 10. Функции l l l Функция – изолированный именованный блок кода, имеющий определенное назначение Информация в функцию передается с помощью аргументов (фактических параметров), задаваемых при ее вызове. Эти аргументы должны соответствовать формальным параметрам, указанным в описании функции. аргументы int k = add_ints (2, 3); Значения аргументов заменяют соответствующие параметры в определении функции Возвращается значение 5 int add_ints (int a, int b) { return a+b; } формальные параметры
4. Структурное программирование 4. 10. Функции Структура функций Тип_Возврата Имя_функции (список_параметров) Заголовок { операторы; Тело return выражение; функции } l Область видимости параметров функции, объявленных в ее заголовке и переменных, объявленных в ее теле, ограничивается блоком тела функции. l Эти переменные, если они не объявлены с атрибутом static уничтожаются после завершения выполнения функции, а хранимые ими значения безвозвратно теряются. l Если функция не возвращает значения, в качестве типа возврата указывается void, а оператор return не содержит выражения, значение которого должно быть возвращено в вызываемую функцию.
4. Структурное программирование 4. 10. Функции Прототипы функций l К моменту вызова функции компилятор должен иметь информацию о ней, чтобы скомпилировать правильно ее вызов. l Если текст функции размещен в файле с исходным текстом после ее вызова или вообще размещен в другом файле, необходимо объявить функцию с помощью оператора, называемого прототипом функции. l Все прототипы функций обычно помещаются в начале исходного файла программы. Заголовочные файлы, включаемые для использования стандартных библиотечных функций, помимо прочего включают в себя прототипы этих функций. l Описание прототипа ничем не отличается от описания заголовка функции: Тип_Возврата Имя_функции (список_параметров); l Описание прототипа, в отличие от заголовка, заканчивается точкой с запятой.
4. Структурное программирование 4. 10. Функции Простой пример: void input_vect( double v[ ], int n) функции для ввода и вывода { одномерного массива for (int i=0; i<=n-1; i++) void input_vect(double v[ ], int n); void output_vect(double v[ ], int n); int main() { const int m=5; double x[5]; input_vect(x, m); output_vect(x, m); return 0; } { cout << "Enter vector[" << i << "] : "; cin >> v[i]; } return; } void print_vector (double v[ ], int n) { cout << endl << "The vector is: "; for (int i=0; i<=n-1; i++) cout <<setw(10)<<v[i]; cout << endl; return; }
4. Структурное программирование 4. 10. Функции Способы передачи данных в вызываемую функцию l l l Путем передачи аргументов функции С использованием глобальных переменных Через файлы на внешних запоминающих устройствах Способы передачи данных из вызываемой функции l Через возвращаемое значение l Через формальные параметры, вызываемые по ссылке l Путем изменения значений глобальных переменных l Через файлы на внешних запоминающих устройствах l Кроме того, функция может выполнять какое-либо действие, не требующее передачи из нее данных в вызывающую функцию
4. Структурное программирование 4. 10. Функции Передача аргументов в функцию по значению l В С++ используются два механизма передачи аргументов в функцию: по значению и по ссылке. l При передаче по значению в функции создаются копии аргументов с именами формальных параметров. Значения аргументов копируются в созданные переменные. По завершении работы функции обратное копирование из формальных параметров в переменные - аргументы не производится. Если в теле функции значения формальных параметров были изменены, эти изменения по завершении работы функции будут потеряны и никак не отразятся на значениях фактических параметров. По умолчанию все аргументы, кроме массивов, передаются в функции по значению l l
4. Структурное программирование 4. 10. Функции Передача аргументов по значению int my(int i); int main() { int k=3, m=0; m=my(k); АЛУ cout << k << " " << m; // 3 8 _getch(); return 0; } int my(int i) { 3 0 int p=2; F 5 C F 5 E F 60 F 62 F 64 F 66 F 68 F 7 A F 7 C F 7 E F 80 i*=2; return p+i; } k m
4. Структурное программирование 4. 10. Функции Передача аргументов по значению int my(int i); int main() { int k=3, m=0; m=my(k); АЛУ cout << k << " " << m; // 3 8 _getch(); return 0; } int my(int i) { 3 3 0 int p=2; F 5 C F 5 E F 60 F 62 F 64 F 66 F 68 F 7 A F 7 C F 7 E F 80 i*=2; return p+i; } k i m
4. Структурное программирование 4. 10. Функции Передача аргументов по значению int my(int i); int main() { int k=3, m=0; m=my(k); АЛУ cout << k << " " << m; // 3 8 _getch(); return 0; } int my(int i) { 2 3 3 0 int p=2; F 5 C F 5 E F 60 F 62 F 64 F 66 F 68 F 7 A F 7 C F 7 E F 80 i*=2; return p+i; } k i m p
4. Структурное программирование 4. 10. Функции Передача аргументов по значению int my(int i); int main() { int k=3, m=0; m=my(k); АЛУ cout << k << " " << m; // 3 8 3*2 = 6 _getch(); return 0; } int my(int i) { 2 3 3 0 int p=2; F 5 C F 5 E F 60 F 62 F 64 F 66 F 68 F 7 A F 7 C F 7 E F 80 i*=2; return p+i; } k i m p
4. Структурное программирование 4. 10. Функции Передача аргументов по значению int my(int i); int main() { int k=3, m=0; m=my(k); АЛУ cout << k << " " << m; // 3 8 3*2 = 6 _getch(); return 0; } int my(int i) { 2 6 3 0 int p=2; F 5 C F 5 E F 60 F 62 F 64 F 66 F 68 F 7 A F 7 C F 7 E F 80 i*=2; return p+i; } k i m p
4. Структурное программирование 4. 10. Функции Передача аргументов по значению int my(int i); int main() { int k=3, m=0; m=my(k); АЛУ cout << k << " " << m; // 3 8 2+6 = _getch(); return 0; } int my(int i) { 2 6 3 0 int p=2; F 5 C F 5 E F 60 F 62 F 64 F 66 F 68 F 7 A F 7 C F 7 E F 80 i*=2; return p+i; } k i m p
4. Структурное программирование 4. 10. Функции Передача аргументов по значению int my(int i); int main() { int k=3, m=0; m=my(k); АЛУ cout << k << " " << m; // 3 8 2+6 = 8 _getch(); return 0; } int my(int i) { 8 2 6 3 0 int p=2; F 5 C F 5 E F 60 F 62 F 64 F 66 F 68 F 7 A F 7 C F 7 E F 80 i*=2; return p+i; } k i m my p
4. Структурное программирование 4. 10. Функции Передача аргументов по значению int my(int i); int main() { int k=3, m=0; m=my(k); АЛУ cout << k << " " << m; // 3 8 _getch(); return 0; } int my(int i) { 8 3 8 int p=2; F 5 C F 5 E F 60 F 62 F 64 F 66 F 68 F 7 A F 7 C F 7 E F 80 i*=2; return p+i; } k m my
4. Структурное программирование 4. 10. Функции Передача аргументов в функцию по ссылке l l l l При передаче по ссылке в вызываемую функцию передаются ссылки на переменные – аргументы. Копии аргументов с именами формальных параметров не создаются. Вместо этого, по ссылке обеспечивается доступ к участкам памяти, занимаемым аргументами. Говоря другими словами, обработка аргументов ведется «на месте» . Чтобы передать значения аргументов по ссылке, в качестве формальных параметров указывают переменные –ссылки. Все изменения формальных параметров, сделанные в функции, происходят с аргументами. Если в качестве аргумента по ссылке передается константа, то формальный параметр-ссылка должен быть объявлен с модификатором const.
4. Структурное программирование 4. 10. Функции int my(int &i); int main() { int k=3, m=0; m=my(k); cout << k << " " << m; // 6 8 _getch(); return 0; } int my(int &i) F 5 C F 5 E F 60 F 62 { int p=2; i*=2; return p+i; } АЛУ 3 F 64 F 66 F 68 F 7 A k 0 F 7 C F 7 E m Передача аргументов в функцию по ссылке F 80
4. Структурное программирование 4. 10. Функции int my(int &i); int main() { int k=3, m=0; m=my(k); cout << k << " " << m; // 3 8 _getch(); return 0; } int my(int &i) F 5 C F 5 E F 60 F 62 { int p=2; i*=2; return p+i; } АЛУ 3 F 64 F 66 F 68 F 7 A k 0 F 7 C F 7 E m i Передача аргументов в функцию по ссылке F 80
4. Структурное программирование 4. 10. Функции int my(int &i); int main() { int k=3, m=0; m=my(k); cout << k << " " << m; // 3 8 _getch(); return 0; 2 } int my(int &i) F 5 C F 5 E F 60 F 62 { int p=2; p i*=2; return p+i; } АЛУ 3 F 64 F 66 F 68 F 7 A k 0 F 7 C F 7 E m i Передача аргументов в функцию по ссылке F 80
4. Структурное программирование 4. 10. Функции int my(int &i); int main() { int k=3, m=0; m=my(k); cout << k << " " << m; // 3 8 _getch(); return 0; 2 } int my(int &i) F 5 C F 5 E F 60 F 62 { int p=2; p i*=2; return p+i; } АЛУ 3*2 = 6 3 F 64 F 66 F 68 F 7 A k 0 F 7 C F 7 E m i Передача аргументов в функцию по ссылке F 80
4. Структурное программирование 4. 10. Функции int my(int &i); int main() { int k=3, m=0; m=my(k); cout << k << " " << m; // 3 8 _getch(); return 0; 2 } int my(int &i) F 5 C F 5 E F 60 F 62 { int p=2; p i*=2; return p+i; } АЛУ 3*2 = 6 6 F 64 F 66 F 68 F 7 A k 0 F 7 C F 7 E m i Передача аргументов в функцию по ссылке F 80
4. Структурное программирование 4. 10. Функции int my(int &i); int main() { int k=3, m=0; m=my(k); cout << k << " " << m; // 3 8 _getch(); return 0; 2 } int my(int &i) F 5 C F 5 E F 60 F 62 { int p=2; p i*=2; return p+i; } АЛУ 2+6 = 6 F 64 F 66 F 68 F 7 A k 0 F 7 C F 7 E m i Передача аргументов в функцию по ссылке F 80
4. Структурное программирование 4. 10. Функции int my(int &i); int main() { int k=3, m=0; m=my(k); cout << k << " " << m; // 3 8 _getch(); return 0; 2 } int my(int &i) F 5 C F 5 E F 60 F 62 { int p=2; p i*=2; return p+i; } АЛУ 2+6 = 8 6 F 64 F 66 F 68 F 7 A k 0 F 7 C F 7 E m i Передача аргументов в функцию по ссылке F 80
4. Структурное программирование 4. 10. Функции int my(int &i); int main() { int k=3, m=0; m=my(k); cout << k << " " << m; // 3 8 _getch(); return 0; 8 } int my(int &i) F 5 C F 5 E F 60 F 62 { int p=2; my i*=2; return p+i; } АЛУ 6 F 64 F 66 F 68 F 7 A k 8 F 7 C F 7 E m Передача аргументов в функцию по ссылке F 80
4. Структурное программирование 4. 10. Функции Передача массивов по ссылке Массивы передаются в функции по ссылке. При этом записывать перед формальным параметров знак ссылки & не следует: int example (short a[3]); l При описании в качестве формального параметра одномерного массива, его размер указывать необязательно: int example(short a[ ]); l При описании в качестве формального параметра многомерного массива, его размер по левому измерению указывать необязательно: int example(short y[ ][4][3]); l
4. Структурное программирование 4. 10. Функции void set(short [ ][3], int); Передача массивов по ссылке int main() { short a[2][3]={0}; set(a, 2); return 0; } 2 void set (short k[ ][3], int m) F 2 E F 30 F 32 F 34 F 36 … { for (short i=0; i<=m-1; i++) for (short j = 0; j<=2; j++) k[i][j]=i+j; return; } 0 0 0 F 5 C F 5 E F 60 F 62 F 64 F 66 a F 68 F 7 A F 7 C F 7 E F 80
4. Структурное программирование 4. 10. Функции void set(short [ ][3], int); Передача массивов по ссылке int main() { short a[2][3]={0}; set(a, 2); return 0; } 2 void set (short k[ ][3], int m) F 2 E F 30 F 32 F 34 F 36 … { for (short i=0; i<=m-1; i++) for (short j = 0; j<=2; j++) k[i][j]=i+j; return; } 2 0 0 0 F 5 C F 5 E F 60 F 62 m F 64 F 66 a k F 68 F 7 A F 7 C F 7 E F 80
4. Структурное программирование 4. 10. Функции void set(short [ ][3], int); Передача массивов по ссылке int main() { short a[2][3]={0}; set(a, 2); return 0; } 2 void set (short k[ ][3], int m) F 2 E F 30 F 32 F 34 F 36 … { for (short i=0; i<=m-1; i++) for (short j = 0; j<=2; j++) k[i][j]=i+j; return; } 0 0 2 0 0 0 F 5 C F 5 E F 60 F 62 j i m F 64 F 66 a k F 68 F 7 A F 7 C F 7 E F 80
4. Структурное программирование 4. 10. Функции void set(short [ ][3], int); Передача массивов по ссылке int main() { short a[2][3]={0}; set(a, 2); return 0; } 2 void set (short k[ ][3], int m) F 2 E F 30 F 32 F 34 F 36 … { for (short i=0; i<=m-1; i++) for (short j = 0; j<=2; j++) k[i][j]=i+j; return; } 0 0 2 0 1 2 3 F 5 C F 5 E F 60 F 62 j i m F 64 F 66 a k F 68 F 7 A F 7 C F 7 E F 80
4. Структурное программирование 4. 10. Функции void set(short [ ][3], int); Передача массивов по ссылке int main() { short a[2][3]={0}; set(a, 2); return 0; } 2 void set (short k[ ][3], int m) F 2 E F 30 F 32 F 34 F 36 … { for (short i=0; i<=m-1; i++) for (short j = 0; j<=2; j++) k[i][j]=i+j; return; } 0 1 2 3 F 5 C F 5 E F 60 F 62 F 64 F 66 a F 68 F 7 A F 7 C F 7 E F 80
4. Структурное программирование 4. 10. Функции Передача указателей в функции l l Указатели обычно передаются по значению. Доступ к объектам, на которые они указывают при этом происходит «на месте» . Применение указателя в качестве параметра позволяет функции получить аргумент, а не его копию.
4. Структурное программирование 4. 10. Функции int my(int *i); int main() { int k=3, m=0; m=my(&k); cout << k << " " << m; // 6 8 _getch(); return 0; } int my(int *i) F 5 C F 5 E F 60 F 62 { int p=2; *i *= 2; return p + *i; } АЛУ 3 F 64 F 66 F 68 F 7 A k 0 F 7 C F 7 E F 80 m Передача указателей в функции
4. Структурное программирование 4. 10. Функции int my(int *i); int main() { int k=3, m=0; m=my(&k); cout << k << " " << m; // 6 8 _getch(); return 0; } int my(int *i) F 5 C F 5 E F 60 F 62 { int p=2; *i *= 2; return p + *i; } АЛУ F 7 A F 64 &i F 66 3 F 68 F 7 A k 0 F 7 C F 7 E F 80 m Передача указателей в функции
4. Структурное программирование 4. 10. Функции int my(int *i); int main() { int k=3, m=0; m=my(&k); cout << k << " " << m; // 6 8 _getch(); return 0; 2 } F 5 C F 5 E F 60 F 62 int my(int *i) { int p=2; p *i *= 2; return p + *i; } АЛУ F 7 A F 64 &i F 66 3 F 68 F 7 A k 0 F 7 C F 7 E F 80 m Передача указателей в функции
4. Структурное программирование 4. 10. Функции int my(int *i); int main() { int k=3, m=0; m=my(&k); cout << k << " " << m; // 6 8 _getch(); return 0; 2 } F 5 C F 5 E F 60 F 62 int my(int *i) { int p=2; p *i *= 2; return p + *i; } АЛУ 3*2 = 6 F 7 A F 64 &i F 66 3 F 68 F 7 A k 0 F 7 C F 7 E F 80 m Передача указателей в функции
4. Структурное программирование 4. 10. Функции int my(int *i); int main() { int k=3, m=0; m=my(&k); cout << k << " " << m; // 6 8 _getch(); return 0; 2 } F 5 C F 5 E F 60 F 62 int my(int *i) { int p=2; p *i *= 2; return p + *i; } АЛУ 3*2 = 6 F 7 A F 64 &i F 66 6 F 68 F 7 A k 0 F 7 C F 7 E F 80 m Передача указателей в функции
4. Структурное программирование 4. 10. Функции int my(int *i); int main() { int k=3, m=0; m=my(&k); cout << k << " " << m; // 6 8 _getch(); return 0; 2 } F 5 C F 5 E F 60 F 62 int my(int *i) { int p=2; p *i *= 2; return p + *i; } АЛУ 2+6 = F 7 A F 64 &i F 66 6 F 68 F 7 A k 0 F 7 C F 7 E F 80 m Передача указателей в функции
4. Структурное программирование 4. 10. Функции int my(int *i); int main() { int k=3, m=0; m=my(&k); cout << k << " " << m; // 6 8 _getch(); return 0; 8 2 } F 5 C F 5 E F 60 F 62 int my(int *i) { int p=2; my p *i *= 2; return p + *i; } АЛУ 2+6 = 8 F 7 A F 64 &i F 66 6 F 68 F 7 A k 0 F 7 C F 7 E F 80 m Передача указателей в функции
4. Структурное программирование 4. 10. Функции int my(int *i); int main() { int k=3, m=0; m=my(&k); cout << k << " " << m; // 6 8 _getch(); return 0; 8 } F 5 C F 5 E F 60 F 62 int my(int *i) { int p=2; my *i *= 2; return p + *i; } АЛУ 6 F 64 F 66 F 68 F 7 A k 8 F 7 C F 7 E F 80 m Передача указателей в функции
4. Структурное программирование 4. 10. Функции Передача указателей на функции l l l Указатель может хранить адрес функции. Это позволяет присваивать ему адрес точки вызова функции и вызывать ее через указатель. Указатель на функцию должен не только содержать адрес памяти, где находится функция, которую необходимо вызвать. Такой указатель должен поддерживать информацию о количестве и типах аргументов и типе возвращаемого значения. Объявление указателей на функцию: Тип_возврата (*Имя_указателя) (список_типов_параметров); Скобки, в которые взято *Имя_указателя позволяет отличит описание указателя на функцию double (*pfun)(char*, int); от описания прототипа функции, возвращающей указатель на double: double *pfun (char*, int); l
4. Структурное программирование 4. 10. Функции Передача указателей на функции: пример double calc_fun (double (*p_f)(double), double x); int main() { double (*p_func)(double)=NULL; p_func=sin; // можно и p_func = &sin; cout << p_func(0) << endl; cout << calc_fun(cos, 0) << endl; // можно и calc_fun(&cos, 0) _getch(); return 0; } double calc_fun (double (*p_f)(double), double x) { return p_f(x); }
4. Структурное программирование 4. 10. Функции Инициализация параметров l l Параметры функции, передаваемые по значению, можно инициализировать в ее прототипе Если при вызове функции аргумент, соответствующий инициализированному формальному параметру будет опущен, формальному параметру будет присвоено инициализирующее значение. Если аргумент при вызове задан, инициализирующее значение игнорируется. Инициализировать можно произвольное число параметров функции Так как аргументы сопоставляются формальным параметрам по порядку следования, то, чтобы опустить при вызове какой-либо аргумент придется опустить и все следующие за ним.
4. Структурное программирование 4. 10. Функции Инициализация параметров void repchar (char с = ‘_', int n = 20); int main () { repchar (); // __________ repchar (‘&'); // &&&&&&&& repchar ('=', 10); / // ===== _getch(); return 0; } void repchar (char с, int n) { for (int i=1; i<=n; i++) cout << с; cout << endl; }
4. Структурное программирование 4. 10. Функции Перегрузка функций l l l Перегруженная функция выполняет различные действия, зависящие от количества аргументов и типов данных, передаваемых ей в качестве аргументов Для того, чтобы создать перегруженную функцию необходимо описать требуемое число одноименных функций с требуемыми наборами формальных параметров. Сопоставив количество и типы аргументов при вызове, компилятор сгенерирует обращение к требуемой перегруженной функции.
4. Структурное программирование 4. 10. Функции void repchar () { void repchar (); for (int i=1; i<=20; i++) cout << ’_’ void repchar (char с); cout << endl; void repchar (int n); } void repchar (char c, int n); void repchar (char c) int main () { { for (int i=1; i<=20; i++) cout << c; repchar (); // _______ cout << endl; repchar (5); // _____ } repchar ('=', 3); // === void repchar (int n) repchar ('+'); // +++++++ { _getch(); for (int i=1; i<=n; i++) cout << ’_'; return 0; cout << endl; } } void repchar (char c, int n) { for (int i=1; i<=n; i++) cout << c; cout << endl; } Перегрузка функций
4. Структурное программирование 4. 10. Функции Возвращаемые значения l l В случае, если функция возвращает значение, его тип должен быть определен в описании функции. Он указывается перед идентификатором функции в описании прототипа и в заголовке функции. Количество аргументов у функции может быть произвольным, но возвращаемое значение только одно (или ни одного). Если функция не возвращает значения, в качестве типа возвращаемого значения следует указать void (по умолчанию считается, что функция возвращает целочисленное значение). Возвращаемое значение является операндом оператора return. В качестве возвращаемого значения может быть указано выражение, вырабатывающее значение соответствующего типа.
4. Структурное программирование 4. 10. Функции Структуры как возвращаемые значения l В С в качестве возвращаемых значений могут фигурировать структуры. struct myst { short i; short j; }; myst init (); int main() { myst r; r=init(); return 0; } myst init() { myst w; w. i=1; w. j=2; return w; }
4. Структурное программирование 4. 10. Функции Массивы и структуры как возвращаемые значения l Массив не может быть непосредственно возвращаемым значением. Зато вполне можно вот так: struct myst { short k [10]; }; myst init (int n); int main() { myst r; r=init(10); return 0; } myst init(int n) { myst w; for (int i=0; i<=n-1; i++) w. k[i]=i; return w; }
4. Структурное программирование 4. 10. Функции Возврат ссылок: функция в левой части оператора присваивания l l l Функция может возвращать ссылку на объект программы В этом случае записанное по адресу, на который указывает ссылка, значение может быть модифицировано. Для этого вызов функции должен осуществляться из левой части оператора присваивания.
4. Структурное программирование 4. 10. Функции char &repl (int i, char c[ ]); int main() { char str[]="Hehlo"; repl(2, str)=‘l'; cout << str; // Hello _getch(); return 0; } l 2 F 5 E char &repl(int i, char c[]) { return c[i]; } F 60 F 62 F 64 F 30 F 32 H F 5 C F 2 E F 34 F 36 e F 66 F 68 h l o /0 F 6 A F 6 C F 6 E F 70 Str Возврат ссылок …
4. Структурное программирование 4. 10. Функции char &repl (int i, char c[ ]); int main() { char str[]="Hehlo"; repl(2, str)=‘l'; cout << str; // Hello _getch(); return 0; } l F 2 E F 5 E char &repl(int i, char c[]) { return c[i]; } F 60 i F 62 F 64 F 30 F 32 H 2 F 5 C 2 F 34 F 36 e F 66 F 68 h l o /0 F 6 A F 6 C F 6 E F 70 Str c Возврат ссылок …
4. Структурное программирование 4. 10. Функции char &repl (int i, char c[]); int main() { char str[]="Hehlo"; repl(2, str)=‘l'; cout << str; // Hello _getch(); return 0; } l F 2 E F 5 E char &repl(int i, char c[]) { return c[i]; } F 60 i F 62 F 64 F 30 F 32 H 2 F 5 C 2 e F 66 F 68 Str F 34 F 36 h l o /0 F 6 A F 6 C F 6 E F 70 c[2] c Возврат ссылок …
4. Структурное программирование 4. 10. Функции char &repl (int i, char c[]); int main() { char str[]="Hehlo"; repl(2, str)=‘l'; cout << str; // Hello _getch(); return 0; } l F 2 E F 5 E char &repl(int i, char c[]) { return c[i]; } F 60 i F 62 F 64 F 30 F 32 H 2 F 5 C 2 F 34 F 36 e F 66 F 68 h l o /0 F 6 A F 6 C F 6 E F 70 Str c[2] c repl Возврат ссылок …
4. Структурное программирование 4. 10. Функции char &repl (int i, char c[]); int main() { char str[]="Hehlo"; repl(2, str)=‘l'; cout << str; // Hello _getch(); return 0; } l 2 F 5 E char &repl(int i, char c[]) { return c[i]; } F 60 F 62 F 64 F 30 F 32 H F 5 C F 2 E F 34 F 36 e F 66 F 68 l l o /0 F 6 A F 6 C F 6 E F 70 Str repl Возврат ссылок …
4. Структурное программирование 4. 10. Функции Возврат ссылок: предупреждение l l Внимание: рассмотренный выше пример находится на грани фола. Возвращаемая ссылка остается действительной (ссылается на существующий после вызова функции объект ) только потому, что массив с – формальный параметр и ссылается на то же место в памяти, что и продолжающий существование массив str. Гораздо спокойнее возвращать ссылки на глобальные или статические переменные. Все сказанное относится и к возврату указателей. Пример некорректной функции: char &repl(int i) { char c=“Hello”; return c[i]; }
4. Структурное программирование 4. 10. Функции Области видимости и классы памяти переменных l l l Область видимости определяет, из каких частей программы возможен доступ к переменной Класс памяти определяет время, в течение которого перменная существует в памяти компьютера В С++ существуют 3 типа области видимости переменных: l локальная область видимости l область видимости файла l область видимости класса (будет рассмотрена позднее) Переменные, имеющие локальную область видимости доступны только внутри того блока, в котором они определены (блоком обычно считается код, заключенный в фигурные скобки) Переменные, имеющие область видимости файла, доступны из любого места файла, в котором они определены
4. Структурное программирование 4. 10. Функции Области видимости и классы памяти переменных l В С++ существует 3 класса памяти: l auto (автоматический) l static (статический) l динамический (будет рассмотрен позднее) l Автоматическая переменная «рождается» в момент ее объявления и прекращает свое существование в момент завершения выполнения блока, где она определена. Автоматическая переменная не инициализируется автоматически. Если она инициализируется при объявлении, инициализация будет выполняться каждый раз при входе в блок и «рождении» переменной. У переменных, имеющих класс памяти static, время жизни равно времени жизни всей программы. Статическая переменная по умолчанию инициализируется нулем. Статическая переменная создается и инициализируется один раз – при первом выполнении блока. l
4. Структурное программирование 4. 10. Функции Локальные автоматические переменные int main() { int k=1; int i=10; cout << k << endl; for (int j=1; j<=3; j++) { int k=2; //2 2 2 cout << k << endl; { cout << i << endl; // 10 int k; if (j==1) k=3; // Это неправильно! cout << k << endl; k++; //3 4 5 Но! В режиме отладки - ошибка // выполнения: неинициализированная переменная } cout << k << endl; // 2 2 2 } cout << k << endl; // 1 return 0; }
4. Структурное программирование 4. 10. Функции Локальные статические переменные int main() { static int k=1; for (int j=1; j<=3; j++) { static int k=2; //2 2 2 cout << k << endl; { static int k=3; // Корректно ! cout << k << endl; k++; //3 4 5 } cout << k << endl; // 2 2 2 } cout << k << endl; // 1 return 0; }
4. Структурное программирование 4. 10. Функции Области видимости и классы памяти переменных l l l Глобальные переменные объявляются вне всех блоков и классов (о последних речь пойдет позже) и имеют область видимости файла. Они доступны всем функциям и блокам, начиная с той точки файла программы, где они объявлены. Глобальные переменные можно сделать доступными и из других файлов, если программа состоит из нескольких файлов. По умолчанию глобальные переменные имеют статический класс памяти. Глобальные переменные живут все время выполнения программы. Если они не инициализируются явно, по умолчанию, глобальные переменные инициализируются нулевым значением. По возможности, использования глобальных переменных следует избегать
4. Структурное программирование 4. 10. Функции Просто пример: внутреннее представление переменных internal_form (void *p, int n_bytes, char str [72]) // Explores memory area from p within n_bytes (n_bytes <=8) // The result is string str[72]: // each bit is represented with '0' or '1‘ like bits in the memory // bytes are separated with space // Returns 0 if OK, -1 when n_bytes >8 { unsigned char k=0, m=0; if (n_bytes > 8) return -1; unsigned char *pc = reinterpret_cast <unsigned char*> (p); for (int i=0; i<=70; i++)str[i]=' '; str[71]='