Функции
98.33K
Категория: ПрограммированиеПрограммирование

Функции

1. Функции

2.

ФУНКЦИИ
Любая программа на языке высокого уровня
может быть разбита на ряд логически
завершенных
программных единиц подпрограмм. Такое разделение вызвано двумя
причинами.
1)Экономия памяти.
2)Структурирование программы
В языке Си существует один вид подпрограмм,
который
называется
функция.
Каждая
программа имеет главную функцию (main),
которая служит точкой входа в программу и
может иметь произвольное число функций.

3.

При изучении работы функций важно понимать, что
такое локальная и что такое глобальная
переменные.
В
языке
программирования
C
глобальные (внешние) переменные объявляются вне
какой-либо функции. С их помощью удобно
организовывать обмен данными между функциями,
однако это считается дурным тоном, т.к. легко
запутывает программу.
Локальные переменные в языке программирования C
называют автоматическими.
Область действия автоматических переменных
распространяется только на ту функцию, в которой
они были объявлены. Параметры функции также
являются локальными переменными.

4.

Ниже схематично приведена структура программы, в
которой описана подпрограмма-функция.
#include "stdio.h "
тип переменная; //глобальная переменная
Тип имя_функции(тип параметр1, тип параметр2,...)
{тип переменная; //локальная переменная
тело функции
}
………………………………….
main() //начало главной функции
{ тип переменная; //локальная переменная
Обращение к подпрограмме
……………………..
} //конец главной функции

5.

Функция – это автономная часть программы,
реализующая определенный алгоритм и
допускающая обращение к ней из различных
частей программы.
Общий вид описания функции
Тип Имя(список формальных параметров)
{ Описание локальных переменных;
Операторы тела функции;
return результат;
}
Тип указываемый в заголовке функции
определяет тип результата ее работы, который
будет возвращаться в точку вызова.

6.

Список формальных параметров обеспечивает
передачу исходных данных в функцию.
Параметры, указанные в заголовке функции,
называются формальными, а параметры,
указываемые при ее вызове – фактическими.
Рассмотрим пример функции для вычисления
максимального значения из двух заданных.
int max(int a, int b)
{ int c;
if (a>b) c=a;
else
c=b;
return c;
}

7.

Обращение к типизированной функции не
является
специальным
оператором,
а
включается в состав выражения. Результат
выполнения функции возвращается в точку
вызова через имя функции.
Приведем пример вызова приведенной выше
функции:
void main()
{ int x,y,z;
printf("Введите x и y:");
scanf("%d%d",&x,&y);
z=max(x,y);
printf("max=%d\n",z); }

8.

При каждом вызове функции происходит
замена формальных параметров (int a, int b) на
фактические (x,y). Вычисленный результат
возвращается в выражение. Далее вычисляется
значение z и выводится на экран.
Формальные и фактические параметры должны
быть согласованы друг с другом по количеству,
типу и порядку следования.
Для того чтобы функция могла быть вызвана,
необходимо, чтобы до ее вызова о ней было
известно компилятору (имена, количество и
тип параметров, тип возвращаемого значения).

9.

#include <stdio.h>
float median (int n1, int n2) {
float m;
m = (float) (n1 + n2) / 2;
return m;
}
main () {
int num1 = 18, num2 = 35;
float result;
printf("%10.1f\n", median(num1, num2));
result = median(121, 346);
printf("%10.1f\n", result);
printf("%10.1f\n", median(1032, 1896));
}

10.

#include <stdio.h>
float
median
(int a,, int b);
float
median(int
); // объявление функции
main () {
int num1 = 18, num2 = 35;
float result;
printf("%10.1f\n", median(num1, num2));
result = median(121, 346);
printf("%10.1f\n", result);
printf("%10.1f\n", median(1032, 1896));
}
float median (int n1, int n2) { // определение функции
float m;
m = (float) (n1 + n2) / 2;
return m;
}

11.

В теле main() функция median() вызывается три
раза. Результат выполнения функции не
обязательно
должен
быть
присвоен
переменной.
Функция median() вычисляет среднее значение
от двух целых чисел. В выражении
(float) (n1 + n2) / 2;
сначала вычисляется сумма двух целых чисел,
результат преобразуется в вещественное число
и только после этого делится на 2. Иначе мы бы
делили целое на целое и получили целое (в
таком случае дробная часть просто усекается).

12.

Временем жизни переменной называется
интервал выполнения программы, в течение
которого она существует.
Поскольку локальные переменные имеют своей
областью видимости функцию, то время жизни
локальной переменной определяется временем
выполнения функции, в которой она объявлена. Это
означает, что в разных функциях совершенно
независимо друг от друга могут использоваться
переменные с одинаковыми именами.
float median (int n1, int n2) {
float m; m = (float) (n1 + n2) / 2;
return m;}

13.

Статические переменные
В
языке
программирования
C
существуют
так
называемые
статические переменные. Они могут
быть
как
глобальными,
так
и
локальными. Перед именем статической
переменной пишется ключевое слово
static.

14.

Внешние статические переменные, в отличие
от обычных глобальных переменных, нельзя
использовать из других файлов в случае
программы, состоящей не из одного файла.
Они глобальны только для функций того
файла, в котором объявлены.
Это своего рода сокрытие данных, по
принципу "не выставлять наружу ничего
лишнего, чтобы 'что-нибудь' нечаянно не могло
'испортить' данные".

15.

Статические переменные, объявленные внутри функций имеют
такую же область действия, как автоматические. Однако в
отличие от автоматических, значения локальных статических
переменных не теряются, а сохраняются между вызовами
функции:
#include <stdio.h>
int hello();
main() {
printf(" - %d-й вызов\n", hello());
printf(" - %d-й вызов\n", hello());
printf(" - %d-й вызов\n", hello()); }
int hello () {
static count = 1;
printf("Hello world!");
return count++;}

16.

Механизм передачи параметров
Функция – это автономная часть программы,
реализующая определенный алгоритм.
в языке С существует два вида функции:
- Типовая
- Без типовая.
void
Тип Имя(список формальных параметров)
{ Описание локальных переменных;
Описание
переменных;
Операторылокальных
тела функции;
Операторы
тела функции;
return результат;
}

17.

Для возврата значения в теле функции
должен быть оператор return. В
дальнейшем будем называть такую
функцию типизированной (типовой).
Если функция не должна возвращать
результат,
то
она
считается
нетипизированной (без типовой), что
задается ключевым словом
void,
стоящим на месте типа. В этом случае
оператор return в функции не требуется.

18.

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

19.

20.

На один и тот же участок памяти может существовать
множество ссылок, и с помощью каждой из них
можно поменять находящееся там значение.
#include <stdio.h>
void multi (int *px, int y);
main () {
int x = 34, y = 6;
multi(&x, 367);
multi(&y, 91);
printf("%d %d\n", x, y);
}
void multi (int *base, int pow) {
while (pow >= 10) {
*base = *base * 10;
pow = pow / 10;} }

21.

Кроме того, следует знать, что функция
может возвращать адрес.
float *form(int N, float *x);
Важно понять механизм так называемой
передачи аргументов по ссылке, т.к. это
понимание
пригодится
при
изучении
массивов и строк. Использовать указатели при
работе с простыми типами данных не стоит.

22.

Массивы, так же как и простые переменные,
можно передавать в функции в качестве
параметров. Так как имя массива – это
адрес, то передача массива происходит
всегда по адресу.
Обратим внимание, что в заголовке функции
размер
массива
рекомендуется
указать
отдельно. Тогда функцию можно использовать
для работы с массивом разной длины. Нельзя
объявлять массив-параметр как A[N], а только
как A[] или *A.

23.

#include <stdio.h>
#include <time.h>
#define N 10
void arr_make(int arr[], int min, int max);
main () {
int arrI[N], i;
arr_make(arrI, 30, 90);
for (i=0; i<N; i++)
printf("%d ", arrI[i]);
printf("\n");}
void arr_make(int arr[], int min, int max) {
int i; srand(time(NULL));
for (i=0; i<N; i++)
arr[i] = rand() % (max - min + 1) + min;
}

24.

Часто при передаче в функцию массивов туда
же передают и количество его элементов в
виде отдельного параметра. В примере выше N
является глобальной константой, поэтому ее
значение доступно как из функции main(), так и
arr_make(). Более грамотно было
бы написать функцию arr_make() так:
void arr_make(int *arr, int n, int min, int max) {
int i;
srand(time(NULL));
for (i=0; i<n; i++)
arr[i] = rand() % (max - min + 1) + min;
}

25.

Следует еще раз обратить внимание на то, что
при передачи имени массива в функцию,
последняя может его изменять. Однако такой
эффект не всегда является желательным.
int arr_sum(int *arr) {
int i, s=0;
for(i=0; i<N; i++) {
s = s + arr[i];
}
return s;
}

26.

Но если вы хотите написать более надежную
программу, в которой большинство функций
не
должны менять значения элементов массивов,
то лучше в заголовках этих функций объявлять
параметр-указатель как константу, например:
int arr_sum(const int *arr);
В этом случае, любая попытка изменить
значение по адресу, содержащемуся в таком
константном указателе, будет приводить к
ошибке и программист будет знать, что в
функция пытается изменить массив.
English     Русский Правила