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

Функции. Локальные переменные в языке программирования C

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     Русский Правила