Similar presentations:
Структурное программирование
1. ФУНКЦИИ
12. Структурное программирование
Программа может быть разделена на более простые иобозримые подпрограммы (или процедуры, или функции)
В языке С – функции
Программа
Функция 1
Функция 2
Функция …
Функция 3
Функция N
Преимущества использования функций:
- При использовании функций упрощается структура программы
- Использование функций позволяет избежать избыточности кода
- Повторное использование функций в других программах
(библиотеки функций)
- Упрощается процесс отладки программ
2
3. Функция
Функция — это именованная последовательность описаний иоператоров, выполняющая какое-либо законченное действие.
Любая программа на C++ состоит из функций, одна из которых
должна иметь имя main (или WinMain) (с нее начинается выполнение
программы). Во время работы из нее могут вызываться другие
функции, из них третьи и т.д.
3
4. Функция
Одна из функций должна иметь имя main. Во время работы из неемогут вызываться другие функции, из них третьи и т.д.
#include <stdio.h>
#include <conio.h>
#include <locale.h>
void main()
{
float a, x, y;
setlocale( LC_ALL, "Russian" ); // Смена кодировки
printf("Вычисление sin(x)\n");
printf(" Введите x: ");
scanf("%f", &x);
y = sin(x);
printf("Результат: %f\n", y);
_getch();
}
4
5. Функция
Функция может принимать параметрыprintf(“%d”, k);
или не принимать параметры
getch();
Функция может возвращать значение
y = sin(x);
или не возвращать значение
sleep(1000);
Количество и типы параметров, а также тип возвращаемого
значения зависят от конкретной задачи, выполняемой функцией.
Для работы с функциями необходимо:
– объявить функцию
– определить функцию
– вызвать функцию
5
6. Вызов функции
Вызывающая функция:int
{
. .
y
. .
}
main()
.
= sin(3.1415);
.
Вызываемая функция:
код функции sin( )
. . .
. . .
. . .
. . .
. . .
6
7. Вызов функции
Аргумент – информация, передаваемая функцииy = sin(3.1415);
Скобки
Конец оператора вызова функции
Имя
Возвращаемое функцией значение
присваивается y
double sin(double x); // прототип функции
7
8. Определение функции
В определении функции реализуется алгоритм функции.Определение функции состоит из заголовка и тела функции.
В заголовке указывается:
тип возвращаемого значения,
имя функции,
список передаваемых параметров.
Тип
Имя_функции (список параметров)
{
операторы
// тело функции
}
Тело функции, представляет собой последовательность
операторов и описаний в фигурных скобках.
double sin(double x); // прототип функции
8
9. Определение функции
Пример:Определение функции состоит из заголовка и тела функции.
В заголовке указывается:
тип возвращаемого значения,
имя функции,
список передаваемых параметров.
float Мах(float a, float b)
{
if (a > b)
return a;
return b;
}
Функция, которая имеет возвращаемое значение, должна
использовать ключевое слово return для передачи
возвращаемого значения и завершения функции.
9
10. Параметры функции
Список передаваемых параметров определяет величины,которые требуется передать в функцию при ее вызове.
Элементы списка параметров разделяются запятыми. Для
каждого параметра, передаваемого в функцию, указывается его
тип и имя
float Мах(float a, float b)
{
if (a > b) return a;
return b;
}
Если у функции нет параметров, скобки остаются пустыми
или пишется void
key = getch();
10
11. Параметры функции
При определении функции задаются не только типыпараметров, но и их имена.
float Мах(float a, float b)
{
if (a > b) return a;
return b;
}
Они становятся именами локальных переменных функции,
значения этих переменных задаются при каждом вызове
функции.
float f1 = 10.5, f2 = 22.3, fmax;
fmax = Max(f1, f2);
11
12. Параметры функции
Параметры, перечисленные в заголовке описания функции,называются формальными параметрами, или просто
параметрами,
float Мах(float a, float b)
{
if (a > b) return a;
return b;
}
а записанные в операторе вызова функции — фактическими
параметрами (аргументами):
float f1 = 10.5;
float f2 = 22.3;
float fmax;
fmax = Max(f1, f2);
12
13. Передача аргументов в функцию
Аргументы в функцию передаются по значению или черезуказатели (а в языке С++ еще по ссылке).
Для передачи используется специальная область памяти, которая
называется стек.
В следующем примере аргументы передаются по значению, т.е.
значение переменной f1 копируется в локальную переменную a данной
функции, а переменной f2 – в локальную переменную b:
float f1 = 10.5;
float f2 = 22.3;
float fmax;
fmax = Max(f1, f2);
float Мах(float a, float b)
{
if (a > b) return a;
return b;
}
13
14. Передача аргументов в функцию
Если аргументы в функцию передаются по значению, их исходныезначения не изменяются.
int x, y;
x = 15;
y = Mult10(x);
int Mult10(int a) a = 15
{
a *= 10;
a = 150
return a;
}
printf(“x = %d\n”, x);
printf(“y = %d\n”, y);
x = 15
y = 150
14
15. Локальные переменные
Кроме параметров в функции можно объявлять и другиелокальные переменные:
void PrintStar(int n)
{
int i;
for(i=0; i<n; i++)
printf(“*”);
}
Область видимости
локальных переменных
Область видимости локальных переменных – только сама
функция, в других функциях эти переменные не доступны.
15
16. Локальные переменные
int main(){
int i, k, n;
. . . .
k = 25;
PrintStar(k);
printf(“\n”);
PrintStar(50);
. . . .
}
void PrintStar(int n)
{
int i;
for(i=0; i<n; i++)
printf(“*”);
}
Область видимости
локальных переменных
По завершении функции локальные переменные, в том числе
и объявленные в строке параметров, удаляются из памяти, т.е.
имена локальных переменных могут совпадать с именами
локальных переменных других функций и даже с именами
глобальных переменных.
16
17. Локальные переменные
Пример использования функциидля рисования:
int main()
{
int f;
. . . .
for (int i = 0; i < 20; i++)
{
f = 20 * sin(6.28 / 40 * i);
PrintStar(f);
printf("\n");
}
. . . .
}
void PrintStar(int n)
{
int i;
for(i=0; i<n; i++)
printf(“*”);
}
17
18. Массивы в качестве параметров функции
В качестве аргументов в функцию можно передавать и массивы, истроки.
При передаче массива в качестве параметра нужно в заголовке
функции после имени массива указать пустые квадратные скобки,
например:
Тип
массива
Адрес
массива
Сколько элементов
в массиве
float SumArr(float Arr[], int size)
{
float s = 0;
for (int i = 0; i < size; i++)
s += Arr[i];
return s;
}
Передать массив в функцию можно также в форме указателя:
float SumArr(float* Arr, int size)
{
. .
}
18
19. Массивы в качестве параметров функции
float SumArr(float Arr[], int size){
float s = 0;
for (int i = 0;i < size; i++)
s += Arr[i];
return s;
}
При вызове функции имя массива задается уже без квадратных скобок:
int main()
{
. . .
float FArray[10];
. . .
float f = SumArr(FArray, 10); // вызов функции
. . .
}
Сам массив не копируется, в функцию передается указатель на начало
массива, это значит, что элементы массива в функции можно изменить
19
20. Массивы в качестве параметров функции
При передаче в качестве аргумента в функцию сам массив некопируется, в функцию передается лишь указатель на его начало, это
значит, что элементы массива в функции можно изменить:
void FillArr(int Arr[], int size)
{
for (int i = 0; i < size; i++)
Arr[i] = i + 1;
}
После вызова функции элементы массива
принимают значения от 1 до 10:
int main()
{
int IArray[10] = {0};
for(int i = 0; i < 10; i++)
printf(“%d\n”, IArray[i]);
. . .
FillArr(IArray, 10); // вызов функции
for(int i = 0; i < 10; i++)
printf(“%d\n”, IArray[i]);
}
20
21. Массивы в качестве параметров функции
Вывод содержимого массива на дисплей тоже целесообразнооформить в виде отдельной функции:
ViewArr(int Arr[],
int size)
void ViewArr(const
int Arr[],
int size)
{
for(int i = 0; i < size; i++)
printf(“%d\n”, Arr[i]);
}
Теперь можно выводить информацию проще:
int main()
{
int IArray[10] = {0};
ViewArr(IArray, 10);
. . .
FillArr(IArray, 10);
ViewArr(IArray, 10);
// заполнение массива
}
21
22. Возвращаемое значение функции
Тип возвращаемого значения – может быть любым (кромемассива).
float Мах(float a, float b)
{
if (a > b) return a;
return b;
}
Если функция ничего не должна возвращать, вместо типа
пишется void
void PrintStar(int n)
{
for(int i=0; i<n; i++)
printf(“*”);
}
22
23. Возвращаемое значение функции
Возвращаемое функцией значение может быть присвоенокакой-либо переменной вызывающей функции
key = getch();
или проигнорировано.
Например, если код нажатой клавиши при вызове этой
функции не нужен, можно написать просто:
getch();
23
24. Возвращаемое значение функции
Функция завершается, когда будут выполнены все ее инструкцииили когда встретится оператор return.
Если функция должна возвращать какое-либо значение, то в
операторе return должно присутствовать выражение (или переменная
или константа) :
return а; // возвращается значение переменной
return 0; // возвращается значение 0
return (a + b) / c; // возвращается значение,
// вычисленное по формуле
В теле функции может быть несколько операторов return или не
быть вовсе (если функция ничего не возвращает).
float Мах(float a, float b)
{
if (a > b) return a;
return b;
}
void PrintStar(int n)
{
for(int i=0; i<n; i++)
printf(“*”);
} return;
}
24
25. Возвращаемое значение функции
Сумма всех элементов функции:float SummArr(const float FArr[], int size)
{
float s = 0;
for(int i = 0; i < size; i++)
s += FArr[i];
return s;
}
Вызов функции:
int main()
{
float f;
float FArray[50];
. . . . . // заполнение массива
f = SummArr(FArray, 50);
. . .
printf(“%f\n”, f);
}
25
26. Предварительное объявление функции
Объявление функции (или предварительное объявление илипрототип) должно находиться в тексте раньше ее вызова для того,
чтобы компилятор мог осуществить проверку правильности вызова.
Объявление функции состоит из заголовка функции, после которого
стоит точка с запятой:
float Мах(float a, float b);
// Прототип функции
Прототипы функций обычно помещают в заголовочные файлы (с
расширением h), а определения – в файлы с расширением с или cpp).
Прототип описывает интерфейс функции для компилятора. Это
значит, что он сообщает компилятору, каков тип возвращаемого
значения, если оно есть у функции, а также количество и типы
аргументов данной функции.
Заголовочные файлы подключаются с помощью директивы #include.
#include <stdio.h>
26
27. Объявление, определение и вызов функции
. . . . . . .float Мах(float a, float b); // Прототип функции
. . . . .
int main()
{
. . . .
float f1 = 10.5, f2 = 22.3, fmax;
fmax = Max(f1, f2);
// Вызов функции
. . . .
}
. . . . .
float Мах(float a, float b)
// Определение функции
{
if (a > b) return a;
return b;
}
В определении, в объявлении и при вызове одной и той же функции
типы и порядок следования параметров должны совпадать.
27
28. Разработка функции
При разработке функциинеобходимо:
- определить задачу, которую
должна выполнять функция;
- определить, какие аргументы
нужны ей для решения этой
задачи;
- определить, должна ли функция
возвращать какую-либо
информацию.
В программе необходимо:
- придумать имя функции;
- решить вопрос, какие
переменные необходимо
передавать в качестве
параметров в будущую
функцию;
- решить вопрос о типе
возвращаемого значения
функции.
На основании этой информации создается заголовок функции.
Каждая функция должна выполнять одну точно поставленную задачу.
Имя функции должно соответствовать смыслу этой задачи.
28
29. Разработка функции
Следующий шаг – создание тела функции:- разработать алгоритм выполнения задачи, решаемой функцией;
- определить, какие переменные будут являться локальными в
функции, и объявить их;
- разработать тело функции в соответствии с решаемой ею задачей, с
учетом параметров функции и возвращаемого значения.
Последний шаг – разместить прототип (предварительное объявление)
функции в заголовочном файле или в верхней части основного файла.
Теперь функцию можно использовать в своей программе.
29
30. Пример разработки функции
y = 3.14154Пример разработки функции
Задача – разработать функцию для
возведения числа в целую степень
- имя функции: Power;
- параметры: float v, int n;
- float.
Аргументы – число, которое
возводится в степень и показатель
степени
Функция должна возвращать
результат вычисления
Заголовок функции:
float Power(float v, int n)
y = 2*x 4 + 5*x 3 + 7*x 2 + x
30
31. Пример разработки функции
Алгоритм выполнения задачи: умножаем число v на себя n раз, дляэтого используем цикл.
Локальные переменные: число, в котором будем хранить результат
(float result) и переменная цикла (int i);
Тело функции:
float Power(float v, int n)
{
float result; // для результата
int i;
result = 1;
for(i = 0; i < n; i++)
result *= v;
return result; // возвращаем вычисленное значение
}
В заголовочном файле или в верхней части основного файла
размещаем прототип:
float Power(float v, int n);
Теперь функцию можно использовать в своей программе.
31
32. Пример разработки функции
Теперь функцию можно использовать в своей программе:float Power(float v, int n);
int main()
{
float f, g;
int k;
float Power(float v, int n)
{
float result = 1;
for(int i = 0; i < n; i++)
result *= v;
return result;
}
setlocale(0, "Russian");
printf("Введите число : ");
scanf("%f", &f);
printf("Введите степень : ");
scanf("%d", &k);
g = Power(f, k);
printf("Число %f в степени %d равно %f\n", f, k, g);
}
32
33. Пример разработки функции
Еще вариант использования:float Power(float v, int n);
int main()
{
float f, g;
int k;
float Power(float v, int n)
{
float result = 1;
for(int i = 0; i < n; i++)
result *= v;
return result;
}
setlocale(0, "Russian");
printf("Введите число : ");
scanf("%f", &f);
printf("Введите макс. степень : ");
scanf("%d", &k);
printf("\n");
for (int i = 0; i <= k; i++)
printf("%8.2f ^ %2d = %8.2f\n", f, i, Power(f, i));
return 0;
}
33
34. Пример разработки функции
Для программы, работающейс массивами удобно сделать функцию
вывода массива на дисплей:
int main()
{
int IArray[10] = {0};
for(int i = 0; i < 10; i++)
printf(“%d\n”, IArray[i];
. . .
FillArr(IArray, 10);
for(int i = 0; i < 10; i++)
printf(“%d\n”, IArray[i];
}
void FillArr(int Arr[], int size)
{
for (int i = 0; i < size; i++)
Arr[i] = i + 1;
}
void PrintArr(int Arr[], int size)
{
for (int i = 0; i < size; i++)
printf(“%d\n”, Arr[i];
}
34
35. Пример разработки функции
Для программы, работающейс массивами удобно сделать функцию
вывода массива на дисплей:
int main()
{
int IArray[10] = {0};
PrintArr(IArray, 10);
. . .
FillArr(IArray, 10);
PrintArr(IArray, 10);
. . .
. . .
int IArr2[50];
FillArr(IArr2, 50);
PrintArr(IArr2, 50);
}
void FillArr(int Arr[], int size)
{
for (int i = 0; i < size; i++)
Arr[i] = i + 1;
}
void PrintArr(int Arr[], int size)
{
for (int i = 0; i < size; i++)
printf(“%d\n”, Arr[i];
}
35
36. Типичные ошибки
Типичные ошибки при определении и вызове функций:void Square(float f)
{
f = f * f;
}
float Square(float f)
{
f = f * f;
}
float Square(float f)
{
return f * f;
}
//Основная программа
float y, f;
f = 25;
y = Square(f);
Если функция проводит какие-то
вычисления и по ее завершении
результат предполагается присваивать
какой-либо переменной, необходимо
обязательно указывать соответствующий
тип возвращаемого значения. Кроме
того, в функции должен быть хотя бы
один оператор return
36
37. Типичные ошибки
Типичные ошибки при определении и вызове функций:float SummAB(float a, float b, float Summ)
{
while (a <= b)
{
//Основная программа
Summ += a;
float x = 5, y = 25;
a++;
float z;
}
float Summ = 0;
return Summ;
}
z = SummAB(x, y, Summ);
Не нужно передавать в функцию
лишние параметры
37
38. Типичные ошибки
Типичные ошибки при определении и вызове функций:float SummAB(float a, float b)
{
float Summ = 0;
while (a <= b)
{
Summ += a;
a++;
}
return Summ;
}
//Основная программа
float x = 5, y = 25;
float z;
z = SummAB(x, y);
Не нужно передавать в функцию
лишние параметры
38
39. Типичные ошибки
Типичные ошибки при определении и вызове функций:float SummAB(float a, float b)
{
float Summ = 0;
while (a <= b)
{
Summ += a;
a++;
}
return Summ;
printf(“Сумма = %f", Summ);
}
//Основная программа
float x = 5, y = 25;
float z;
z = SummAB(x, y);
Если после оператора return
стоят какие-то операторы, то
они не будут выполнятся
39
40. Типичные ошибки
Типичные ошибки при определении и вызове функций:float SummAB(float a, float b)
{
float Summ = 0;
while (a <= b)
{
Summ += a;
a++;
}
printf(“Сумма = %f", Summ);
return Summ;
}
//Основная программа
float x = 5, y = 25;
float z;
z = SummAB(x, y);
printf(“Сумма = %f", z);
В подобных функциях не стоит
помещать вывод результатов на
дисплей
40
41. Типичные ошибки
Типичные ошибки при определении и вызове функций:float SummAB(float a, float b)
{
//Основная программа
float Summ = 0;
float x1 = 5, y1 = 25;
while (a <= b)
float z1;
{
float x2 = 105, y2 = 125;
Summ += a;
float z2;
a++;
float x3 = 1005, y3 = 1025;
}
float z3;
return Summ;
float z;
} //Основная программа
float x1 = 5, y1 = 25;
float x2 = 105, y2 = 125; z1 = SummAB(x1, y1);
float x3 = 1005, y3 = 1025; z2 = SummAB(x2, y2);
z3 = SummAB(x3, y3);
float z;
В подобных функциях не стоит
z = z1 + z2 + z3;
помещать вывод результатов
printf(“Сумма
= %f",y3);
z);
z = SummAB(x1, y1)+ SummAB(x2,
y2)+ SummAB(x3,
на дисплей
printf(“Сумма = %f", z);
41
42. Рекомендации
Функция должна выполнять одну задачу:Не надо смешивать в одной функции вычисления и вывод на дисплей
Не надо смешивать в одной функции ввод массива и вывод на дисплей
Не надо смешивать в одной функции заполнение двух массивов
Функция не может возвращать больше одного значения:
float OppositeVector(float x, float y)
{
float x1, y1;
x1 = -x;
y1 = -y;
return x1, y1; // ОШИБКА!!!
}
//Основная программа
float vx, vy;
vx = OppositeVector(10, 23);
42
43. Функция main
Функция, которой передается управление после запускапрограммы, должна иметь имя main.
Два формата функции
Без параметров:
int main()
{
...
}
С двумя параметрами:
int main(int argc, char* argv[])
{
...
}
При вызове из командной строки:
C:\cProgramms\MyProgr.exe abc def ghij klmno
argc будет равно 5
43