Пятое занятие по С++: функции, vol 1

Иногда некоторые куски программы удобно выделить в отдельные блоки и называть отдельным именем. Это необходимо, в основном, в двух случаях:

  • Мы делаем сложную задачу, и разбиваем ее на более простые. Например, задачу о сортировке массива удобно разбить на три подзадачи — ввод, сортировка и вывод. Каждую из них можно выделить в отдельную функцию.
  • Один и тот же код в программе используется много раз и постоянно копировать его неудобно. Например, если в программе надо много раз выводить массив, можно сделать функцию — вывести массив, и просто несколько раз ее вызвать. Функции можно выделять в отдельные файлы — библиотеки, и использовать их в разных программах.

У функций есть входные данные и возвращаемое значение.

Входные данные, или параметры (аргументы), — это то, что понадобится функции для работы. Например, функции вывода массива на экран нужен сам массив и количество элементов в нем. А функции возведения числа в степень нужно два числа — число, которое нужно возвести в степень и сама степень.

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

Как определить функцию?

<тип возвращаемого значения> <название> (<тип аргумента> <аргумент>, <тип аргумента> <аргумент>, ...)
{
    <любой код>
    return <возвращаемое значение>;
}

Аргументов может быть сколь угодно много, они могут иметь разный тип. Все аргументы перечисляются в круглых скобках и через запятую.

Возвращаемое значение всегда одно. Это может быть название типа данных, либо слово void, если функция ничего не возвращает.

return возвращает в точку вызова (об этом дальше) возвращаемое значение и завершает выполнение функции.

Давай сделаем функцию, которое находит наибольшее из двух чисел:

int max(int a, int b)
{
    if (a > b) return a;
    else return b;
}

Ничего не напоминает?

Дело в том, что main() — тоже функция, которая по-умолчанию вызывается при запуске нашей программы. Это называется точкой входа в программу. На заметку: в функции main команда return немедленно завершает работу всей нашей программы.

Пользовательские функции определяются перед функцией main().

А как использовать функцию? Очень просто! Допустим, нам надо найти наибольшее из двух чисел:

#include <iostream>

using namespace std;

int max(int a, int b)
{
   if (a > b) return a;
   else return b;
}

int main()
{
   int m, n;
   cin >> m >> n;
   cout << max(m, n);
   return 0;
}

На место max(m, n) компьютер подставит значение, которое нам вернула функция командой return.

Обрати внимание! На место переменный a и b в функции мы подставляем значения m и n. То есть числа лежащие в переменных m и n копируются в переменные a и b. Функция main не знает о существовании a и b, а max не знает ничего о переменных из функции main. Рассмотрим пример:

#include <iostream>

using namespace std;

void func()
{
   int a = 10; 
} //return нет, т.к. функция возвращает void

int main()
{
   func();
   cout << a; //тут будет ошибка, main не видит переменную a 
}

Как разобраться что и где видно? Очень просто!

Все переменные, определенные внутри любых фигурных скобок видны и существуют только внутри этих скобок.

Это касается не только функций, но и условных операторов и циклов.

#include <iostream>
using namespace std;

int main()
{
   if (2 > 1) {
      int a = 10;
   }
   cout << a; //тут будет ошибка, в этом месте a не видна! 
}

Теперь давай вернемся к функциям, и решим с помощью нашей функции max задачку посложнее: вводится четыре числа, надо найти максимум:

#include <iostream>

using namespace std;

int max(int a, int b)
{
   if (a > b) return a;
   else return b;
}

int main()
{
   int a, b, c, d; //так можно, a и b в функции - совсем другие переменные
   cin >> a >> b >> c >> d;
   cout << max(a, max(b, max(c, d)));
   return 0;
}

Как тебе? Не правда ли, гораздо быстрее, чем расписывать много условных операторов =)

Давай рассмотрим еще один пример — вспомним задачку из урока про циклы, где нужно было вывести на экран квадрат из звездочек.

Выводя каждую строку, нам было бы удобно выделить функцию рисования n звездочек. Давай создадим ее:

void DrawStars(int w) {
   for (int i = 0; i < w; i++) 
     cout << "*";
}

Теперь наша программа будет выглядеть проще для понимания:

#include <iostream>
using namespace std;

void DrawStars(int w) {
   for (int i = 0; i < w; i++) 
     cout << "*";
} 

int main() {
   int n;
   cin >> n;
   for (int i = 0; i < n; i++) {
     DrawStars(n);
     cout << endl;
   }
}

А теперь давай сделаем программу, которая будет рисовать фигуру в зависимости от выбора пользователя. Например, если пользователь введет 1, рисовать квадрат, а если 2 — половинную пирамидку. Действуем:

#include <iostream>
using namespace std;

void DrawStars(int w)
{
   for (int i = 0; i < w; i++)
     cout << "*";
} 

void DrawRectangle(int h) //функция рисования квадрата
{
   for (int i = 0; i < h; i++) { 
      DrawStars(h);
      cout << endl;
   }
}

void DrawTriangle(int h)
{
   for (int i = 1; i <= h; i++) {
      DrawStars(i);
      cout << endl;
   }
} 

int main()
{
   int a, n;
   cin >> a >> n;
   if (a == 1) DrawRectangle(n);
   else DrawTriangle(n);
}

Как видишь, получается весьма красиво! Такую программу гораздо легче понять! Если добавить функцию вывода пробелов, то можно добавить и функцию рисования двухсторонней пирамиды…

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

Освоение функций — один из двух самых важных этапов освоения языка Си++. Следующим будут уже объекты. =)

К сожалению ты пока еще не знаешь, как передавать функцию массивы, но об этом мы поговорим на следующих занятиях.

Удачи!

Задачи для самостоятельного решения.

3.1.1
Написать функцию, возвращающую минимальное из двух чисел (2 балла).

3.1.2
Написать функцию, которая определяет, является ли число четным (2 балла).
(Она должна возвращать 0 если число нечетное, 1 — если четное).

3.1.3
Написать функцию, которая возвращает модуль числа. (2 балла).

3.1.4
Написать функцию, которая возводит число в заданную степень. (3 балла).

3.1.5
Написать функцию, которая меняет 2 переменные местами. (5 баллов).

3.1.6
Написать функцию, которая меняет 2 числа местами. (5 баллов).

3.1.8
Написать функцию, которая ищет в массиве максимальное и минимальное числа, и возвращает их сумму. (5 баллов).

(*) 3.1.9
Дан ряд чисел, заданный формулой: 1, 1/2, 1/3, … 1/N.
Написать функцию, которая находит сумму N чисел такого ряда, вызывая сама себя.
Для правильного вычисления дробей (вместо целых чисел), вам следует использовать тип double вместо int. (10 баллов).

 

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *