Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Функции в C.docx
Скачиваний:
0
Добавлен:
26.01.2020
Размер:
56.26 Кб
Скачать

Функции в C++.

Функция - это группа операторов у которой есть имя. Во всех предыдущих уроках, код наших программ располагался в одной функции - main. Функции позволяют разбить программу на небольшие части, каждая из которых выполняет какую-то небольшую задачу. Посмотрите на полный код морского боя (раздел - Листинги). В нём больше 500 строк кода. Без функций было бы довольно проблематично написать эту программу. В ней используется 11 функций, самая длинная из которых состоит из 50 строк кода.

Обязательными для функции являются два компонента: определение и вызовы.

Определение функции

Определение функции должно располагаться в глобальной области видимости, до начала функции main. Рассмотрим пример, простого определения:

int simple_function ()

{

return 0;

}

Определение функции состоит из заголовка и тела. Заголовок фукнции включает в себя:

Тип возвращаемого значения

Почти все функции должны возвращать значения. Тип этого значения указывается в заголовке перед именем функции. Вот несколько примеров заголовков функций:

int simple_function()

float simple_function()

char simple_function()

В первом случае функция должна вернуть целое число (int), во втором - вещественное число (float), а в третьем случае - символ (char).

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

Идентификатор или имя функции

Идентификатор (имя) функции задаётся точно также, как и любой другой идентификатор. В данном примере мы создали функцию с идентификатором simple_function (simple - простой).

Список аргументов или параметров

Список аргументов функции записывается в круглых скобках после имени функции. В данном примере список аргументов пуст.

Список аргументов записывается через запятую. Каждый элемент списка состоит из типа и идентификатора. Рассмотрим пример заголовка функции со списком из двух аргументов:

int simple (int a, float b)

В скобках мы записали два аргумента: a и b. У аргумента a тип int, а у аргумента b тип float.

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

Тело функции

Тело функции располагается сразу под заголовком и заключено в фигурные скобки. В теле функции может содержаться сколько угодно операторов. Но обязательно должен присутствовать оператор return. Оператор return возвращает значение:

int simple_function ()

{

return 0;

}

Здесь, simple_function всегда будет возвращать 0. Надо признать, что данная функция бесполезна. Напишем функцию, которая принимает из вызывающего окружения два значения, складывает их и возвращает результат в вызывающее окружение. Назовём эту функцию sum (сумма):

int sum (int a, int b)

{

int c;

c = a + b;

return c;

}

В функцию передаётся два аргумента: a и b типа int. В теле функции они используются как обычные переменные (они и являются обычными переменными). Давайте договоримся: снаружи функции, переменные, которые передаются в неё, мы будем называть аргументами, а эти же переменные в теле функции - параметрами.

В теле функции определяется переменная c. А затем, в эту переменную мы помещаем значение суммы двух параметров.

Последняя строчка возвращает значение переменной c во внешнее окружение.

После ключевого слова return нужно указать значение которое будет возвращено. Можно возвращать как простые значения, так и переменные и даже выражения. Например:

return 32;

return a;

return b;

return a+b;

В последнем случае в вызывающее окружение будет возвращён результат суммы переменных a и b.

Обратите внимание, что оператор return не только возвращает значение, но и служит как бы выходом из функции, после него не будет выполнен ни один оператор:

return a;

c = a+b; // этот оператор не будет выполнен

Благодаря этому, с помощью return удобно создавать условия выхода из функций:

if (a > 0)

{

return 0;

}

else if (a < 0)

{

return 1

}

Здесь, из функции будет возвращено число в зависимости от значения переменной a: если a больше нуля, то будет возвращён 0, в противном случае - 1.

Вызов функции

После того как создано определение функции, её можно вызвать.

int sum (int a, int b)

{

int c;

c = a + b;

return c;

}

int main()

{

int s;

s = sum(2,2); // вызов функции

cout << s;

return 0;

}

В результате выполнения программы, на экран будет выведено: 4.

Вызов функции состоит из идентификатора функции и списка аргументов в круглых скобках. Вот несколько вызовов функции sum:

int x = 5;

int y = 4;

int z;

sum(0,1); // 1

sum(x,2); // 7

sum(x,y); // 9

z = sum(x,y); // z = 9

Вызывающее окружение

То место, откуда вызывается функция, называется вызывающим окружением. Вызывающим окружением функции sum является функция main, а вызывающим окружением функции main является отладчик или операционная система.

Функция может обмениваться данными с вызывающим окружением благодаря списку аргументов и возвращаемому значению: вызывающее окружение передаёт данные в функцию с помощью аргументов, а функция передаёт данные в вызывающее окружение с помощью возвращаемого значения.

Тип передаваемого в функцию значения должен совпадать с типом указанным в списке аргументов. Нельзя, например, написать вот так:

int simple (int a)

{

return 1;

}

int main ()

{

int b;

b = simple(0.5);

return 0;

}

В списке аргументов мы указали тип int, а в функцию передаётся вещественное значение 0.5. Так делать нельзя.

Рассмотрим более полезный пример: напишем функцию для передвижения персонажа:

int x; // глобальная переменная

int move_x (int dx)

{

x = x + dx;

return x;

}

int main ()

{

int ch;

char act;

while (1)

{

act = _getch();

ch = static_cast(act);

if (ch == 75) // была нажата стрелочка влево

move_x(-1);

else if (ch == 77) // была нажата стрелочка вправо

move_x(1);

} // конец while

return 0;

} // конец main

Обратите внимание, что для тела if и else if не стоит скобочек. Скобочки ветвлений можно опускать, если в теле ветвления всего один оператор.

Функция move_x двигает персонажа на одну единицу влево или вправо в зависимости от клавиши, которую нажал пользователь.

Создадим ещё одну функцию, а заодно уберём из main часть кода:

int x; // глобальная переменная

int move_x (int dx)

{

x = x + dx;

return x;

}

void move (int ch)

{

if (ch == 75) // была нажата стрелочка влево

move_x(-1);

else if (ch == 77) // была нажата стрелочка вправо

move_x(1);

}

int main ()

{

int ch;

char act;

while (1)

{

act = _getch();

ch = static_cast(act);

move(ch); // вызов функции move

} // конец while

return 0;

} // конец main

Обратите внимание, что в функции move на месте типа возвращаемого значения стоит void, кроме того, в теле move нет оператора return.

Объявления функций (прототипы)

В последнем примере, определение функции move_x должно располагаться выше определения move (а определения move_x и move должны располагаться до main), так как в функции move происходит вызов move_x.

Обычно определения всех пользовательских функций располагаются после определения main. При этом используются объявления функций (прототипы). Внесём изменения в предыдущую программу:

int x; // глобальная переменная

void move(int); // прототип (объявление) функции move

int move_x(int); // прототип функции move_x

int main ()

{

int ch;

char act;

while (1)

{

act = _getch();

ch = static_cast(act);

move(ch); // вызов move

}

return 0;

}

void move (int ch)

{

if (ch == 75) // была нажата стрелочка влево

move_x(-1);

else if (ch == 77) // была нажата стрелочка вправо

move_x(1);

}

int move_x (int dx)

{

x = x + dx;

return x;

}

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

int move_x(int dx);

int move_x(int);

Объявления функций расположены в начале файла. Прототип функции говорит компилятору, что данную функцию можно вызывать, а её определение будет позже (или находится в другом файле).

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

Возврат void

На месте возвращаемого типа, в определении (и в объявлении) функции move стоит ключевое слово void (void - пусто, пустой). Это значит, что функция не возвращает никакого значения. Следовательно не требуется и оператор return, так как функции нечего вернуть в вызывающее окружение.

Передача массивов в функцию

Передача массивов в функцию имеет небольшое отличие от передачи простой переменной. В прототипе функции необходимо указывать идентификатор:

int simple_function (int array[]);

int simple_function (int array[]) { return 0;}

Обратите внимание, что рядом с идентификатором и в объявлении и в определении стоят скобочки.

При вызове функции, в которую нужно передать массив, указывается только идентификатор массива (без квадратных скобок):

int a[] = { 0, 1, 2 };

simple_function(a);

Запомните, при вызове указывается только идентификатор, а при объявлении/определении ещё и скобки.

Глобальные переменные

Глобальные переменные - это переменные, которые определены за пределами любой функции:

int x = 0; // глобальная переменная

int main () { код main }

void simple_function ()

{

x = 5;

}

Здесь переменная x видна из любой функции программы, в том числе и из simple_function. Что значит: "функция видит переменную"? Это значит, что внутри функции можно обращаться к этой переменной.

Глобальные переменные существуют с того момента как они встретились в коде и до конца программы. Т.е. если глобальную переменную объявить после какой-нибудь функции, то в этой функции данную переменную нельзя будет использовать:

int main () { код main }

void simple_function ()

{

x = 5 // компилятор выдаст ошибку, переменная ещё не объявлена

}

int x = 5; // объявление глобальной переменной

int getX ()

{

return x; // getx видит переменную x

}

Переменная x объявлена после функций main и simple_function, а значит, в этих функциях её не видно.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]