Similar presentations:
Функции: понятие, описание. Структура программы. Передача параметров и возврат значений
1. Лекция 8
Функции: понятие, описание.Структура программы.
Передача параметров и возврат значений.
2. Основные понятия и определения
Нисходящее программирование – процесс разработки программ, прикотором сложная программа разбивается на ряд более простых
подпрограмм, которые в свою очередь также могут быть разбиты на
ряд еще более простых подпрограмм. Этот процесс продолжается до
получения элементарных
подпрограмм,
реализация которых не
представляет большой сложности.
Восходящее программирование
– процесс разработки программ,
при котором
сложная
программа
реализуется посредством
интеграции более простых подпрограмм, начиная с элементарных
подпрограмм. Этот процесс продолжается до тех пор, пока не будет
получена основная программа.
3. Основные понятия и определения
Функция –это синтаксически выделенный именованный
программный модуль, выполняющий определенное действие
или группу действий.
Каждая функция имеет свой интерфейс и реализацию.
4. Основные понятия и определения
Интерфейс функции–
заголовок
функции, в котором
указывается название функции, список ее параметров и тип
возвращаемого значения.
Реализация функции
–
тело
функции, содержащее
внутренние (локальные) данные функции и программный код,
выполняющий действия
согласно переданным в функцию
параметрам и возвращающий значение, соответствующего
интерфейсу функции типа.
5. Виды функций
С точки зрения программиста функции бывают:библиотечные – функции описанные в библиотеках
языка С (как стандартных, так и не стандартных);
пользовательские – функции реализованные
программистом в процессе разработки программы.
6. Описание функций
Описание функции на языке С осуществляется в любом местепрограммы вне описания других функций и состоит из трех
элементов:
прототип функции;
заголовок функции;
тело функции.
7. Прототип функции
Прототип функции – необязательная часть описания функции,предназначенная для объявления некоторой функции,
интерфейс которой соответствует данному прототипу.
Объявление прототипа имеет следующий вид:
возвращаемый тип имя(список типов формальных параметров);
8. Параметры функции
Параметры функции – значения, передаваемые в функцию приее вызове. Выделяют понятия: формальные и фактические
параметры.
Формальные параметры – переменные, описываемые при
объявлении функции в ее прототипе и заголовке и
используемые в программном коде тела функции.
Фактические параметры – переменные, выражения,
константные значения или вызовы других функций,
указываемые при непосредственном вызове функции внутри
другой функции.
9. Прототип функции
Примеры прототипов:int func(int, double, double);
void func(int, char *);
double func(void);
10. Заголовок функции
Заголовок функции – описание интерфейсной частифункции, которая содержит: тип возвращаемого
значения, имя функции и список формальных параметров
функции.
Синтаксис объявления заголовка функции:
возвращаемый тип имя(список формальных параметров)
11. Заголовок функции
Каждый элемент (формальный параметр) имеет следующийформат объявления:
тип имя
Примеры заголовков функций:
int func(int i, double x, double y)
void func(int ind, char *string)
double func(void)
12. Тело функции
Тело функции – часть-реализация, содержащая программныйкод, выполняемый при вызове функции. Тело функции
всегда следует сразу после заголовка функции (разделять их
нельзя) и заключено в фигурные скобки.
13. Пример
Реализация функции вычисления факториала числа.double factorial(unsigned);
...
double factorial(unsigned num)
{
double fact = 1.0;
for(unsigned i=1;i<=num;i++)
fact *= (double)i;
return fact;
}
14. Пример
Вызов функции вычисления факториала представлен вследующем фрагменте программы:
unsigned n = 8;
double vals[2] = {0.0};
...
//Константа 5 – фактический параметр
vals[0] = factorial(5);
//Переменная n – фактический параметр
vals[1] = factorial(n);
...
15. Пример
Подсчет количества положительных элементов в целочисленноммассиве.
unsigned positive(int [], unsigned);
...
unsigned positive(int arr[], unsigned num)
{
unsigned count = 0;
for(unsigned i=0;i<num;i++)
if(arr[i] > 0) count++;
return count;
}
16. Пример
Вызов функции подсчета положительных элементов вцелочисленном массиве представлен в следующем
фрагменте программы:
unsigned n = 10;
int array[n];
...
unsigned cnt = positive(array,n);
...
17. Структура программы
1: подключение библиотек.2: объявление глобальных пользовательских типов
данных и переменных.
3: объявление прототипов пользовательских
функций.
4: реализация функции main.
5: реализация (описание заголовков и тел)
пользовательских функций.
18. Пример
Разработать программу,которая
в
диалоговом режиме
запрашивает у пользователя два вещественных числа
и
вычисляет
отношение
максимального
числа
к
минимальному числу. Определение максимума и минимума
двух чисел, а также деления двух чисел в соответствии с
заданием
необходимо
реализовать в виде отдельных
функций.
19. Пример
#include <stdio.h>#include <string.h>
void division(double,double);
int main(int argc, char *argv[])
{
do{
char str[80];
printf("Введите два числа для/
вычислений\nили пустую/
строку для выхода\n>:");
gets(str);
if(strcmp(str,"") == 0) break;
double x,y;
sscanf(str,"%lf %lf",&x,&y);
division(x,y);
}while(1);
return 0;
}
double max(double x, double y)
{
return (x>y)?x:y;
}
double min(double x, double y)
{
return (x<y)?x:y;
}
void division(double x, double y)
{
double res = max(x,y)/min(x,y);
printf("Результат: %lf\n",res);
}
20. Функциональная схема программы
Функция mainФункция I-го уровня
…
Функция I-го уровня
Функция II-го уровня
…
Функция II-го уровня
…
…
21. Пример
maindivision
max
min
22. Возвращаемое значение функции
Для реализации возврата значения и завершения выполненияфункции используется оператор завершения функции,
который относится к группе операторов управления, не
рассматривался ранее. Синтаксис использования оператора
завершения функции:
return выражение;
Если функция не возвращает никакого значения (в заголовке
указан тип void), то оператор возврата указывается без
какого-либо выражения:
return;
23. Пример
Функция, определяющую количество корнейквадратного уравнения (целочисленное значение),
заданного коэффициентами a, b и c (формальные
параметры функции):
int NumberOfRoots(double a, double b, double c)
{
double descr = b*b – 4.0*a*c;
if(descr < 0) return 0;
else if(descr > 0) return 2;
else return 1;
}
24. Пример
double descr=b*b–4.0*a*c;if(descr<0) return 0;
else if(descr>0) return 2;
return 1;
double descr=b*b–4.0*a*c;
int num = 1;
if(descr<0) num = 0;
else if(descr>0) num = 2;
return num;
25. Возврат значений сложных типов
Возврат значений сложных типов (структур и объединений)возможен только в стандарте С99.
В более ранних версиях языка возврат в качестве значений
структур или объединений невозможен.
Возвращать в качестве значений массивы в языке С нельзя. Для
этого можно использовать возврат указателя на массив.
26. Параметры функции
Параметры функции могут быть константными: их невозможноизменить. Для описания такого параметра перед его типом
указывается ключевое слово const.
Пример:
int Length(const char *str)
{
int len = 0;
for(char *ptr = str;*ptr!=0;ptr++) len++;
return len;
}
27. Передача параметров по значению и по ссылке
В языках программирования высокого уровняреализованы два механизма передачи
параметров:
по значению;
по ссылке.
28. Передача по значению
Механизм передачи параметра по значению заключается вследующем: в вызываемую функцию передается значение
фактического параметра.
void Inc(int a) { a++; }
int main (int argc, char *argv[])
{
int val = 0;
printf(“Значение: %d\n”,val);
Inc(val);
printf(“Значение: %d\n”,val);
return 0;
}
29. Передача по ссылке
В языке С механизм передачи параметра по ссылкереализован посредством указателей.
void Inc(int *a) { (*a)++; }
int main (int argc, char *argv[])
{
int val = 0;
printf(“Значение: %d\n”,val);
Inc(&val);
printf(“Значение: %d\n”,val);
return 0;
}
30. Передача по ссылке
Механизм передачи параметров по ссылке используетсядля реализации возможностей:
изменение значения переменной, описанной внутри
вызывающей функции, вызываемой функцией;
реализации функций, возвращающих несколько значений.
31. Пример
Реализация функции поиска максимального иминимального значения в целочисленном массиве.
void GetMinMax(int arr[], int n, int *min, int *max)
{
*min = arr[0]; *max = arr[0];
for(int i=1;i<n;i++){
if(arr[i] > *max) *max = arr[i];
if(arr[i] < *min) *min = arr[i];
}
}
32. Пример
Использование данной функции продемонстрировано в следующемфрагменте программы:
int main(int argc, char *argv[])
{
int n;
... //Ввод переменной n
int array[n];
... //Ввод массива array
int maxel, minel;
GetMinMax(array,n,&minel,&maxel);
printf(“Минимум массива: %d\n”, minel);
printf(“Максимум массива: %d\n”, maxel);
...
}
33. Массивы как параметры функции
Так как в языке С имя массива является указателем на массив, то массивы в языке Спередаются только по ссылке.
void ProcArray(int arr[], int n)
{
for(int i=0;i<n;i++) arr[i]++;
}
int main(int argc, char *argv[])
{
int array[] = {0,1,2,3,4,5,6,7,8,9};
int num = sizeof(array)/sizeof(int);
for(int i=0;i<num;i++) printf("%d ",array[i]); //0 1 2 3 4 5 6 7 8 9
puts("");
ProcArray(array,num);
for(int i=0;i<num;i++) printf("%d ",array[i]); //1 2 3 4 5 6 7 8 9 10
puts("");
return 0;
}
34. Массивы как параметры функции
Массив можно передавать в параметрах используя синтаксис указателя.void ProcArray(int *arr, int n)
{
for(int i=0;i<n;i++) arr[i]++;
}
int main(int argc, char *argv[])
{
int array[] = {0,1,2,3,4,5,6,7,8,9};
int num = sizeof(array)/sizeof(int);
for(int i=0;i<num;i++) printf("%d ",array[i]);
puts("");
ProcArray(array,num);
for(int i=0;i<num;i++) printf("%d ",array[i]);
puts("");
return 0;
}
35. Массивы как параметры функции
Массив в параметрах функции может быть объявлен как константный.Значения элементов этого массива нельзя изменить внутри этой
функции, обратившись к ним через имя этого массива. Но можно
через дополнительный не константный указатель, установленный
на массив с явным приведением типа.
void ProcArray(const int arr[], int n)
{
for(int i=0;i<n;i++) arr[i]++;
//Ошибка
int *arrptr1 = arr;
//Ошибка
int *arrptr2 = (int *)arr;
//Корректно
for(int i=0;i<n;i++) arrptr2[i]++; //Корректно
}
36. Массивы как параметры функции
Передача в параметрах многомерных массивов (две и болееразмерности) осуществляется иначе.
Неправильно:
void ProcArray(int arr[][], int n, int m)
{
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
arr[i][j]++;
}
37. Массивы как параметры функции
Правильный способvoid ProcArray(int n, int m, int arr[n][m])
{
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
arr[i][j]++;
}
38. Строки как параметры функции
Строки в языке С в качестве параметров передаются с использованием синтаксисауказателя на символьный тип.
void ProcString(char *str)
{
for(int i=0;str[i]!=0;i++)
if(islower(str[i])) str[i] = 'A' + (str[i] - 'a');
else if(isupper(str[i])) str[i] = 'a' + (str[i] - 'A');
}
int main(int argc, char *argv[])
{
char string[] = "Hello World!";
puts(string);
//Hello World!
ProcString(string);
puts(string);
//hELLO wORLD!
return 0;
}
39. Строки как параметры функции
При передаче в качестве параметра массива строк необходимо использовать способпередачи двумерных массивов. Или возможен следующий вариант:
void ProcString(char *str[], int n)
{
for(int i=0;i<n;i++){
for(int j=0;str[i][j]!=0;j++)
if(islower(str[i][j])) str[i][j] = 'A' + (str[i][j] - 'a');
else if(isupper(str[i][j])) str[i][j] = 'a' + (str[i][j] - 'A');
}
}
int main(int argc, char *argv[])
{
char string[][20] = {"One","Two","Three","Four","Five"};
char *strs[] = {string[0],string[1],string[2],string[3],string[4]};
for(int i=0;i<5;i++) puts(string[i]);
ProcString(strs,5);
for(int i=0;i<5;i++) puts(string[i]);
return 0;
}
40. Передача параметров
В языке С, как и во многих других языкахпрограммирования высокого уровня, используется механизм
передачи параметров через стек. Т.е. сначала все
параметры заносятся в стек, а затем вызывается функция.
Существует два метода передачи параметров через стек:
в прямом порядке,
в обратном порядке.
41. Нижний уровень передачи параметров
В языке С по умолчанию используется метод передачи вобратном порядке. Если необходимо изменить направление
передачи параметров или явно его указать, то перед
именем функции указывают одно из ключевых слов:
_stdcall (или __stdcall) – передача параметров в прямом
порядке;
_cdecl (или __cdecl) – передача параметров в обратном
порядке.
Например:
int __cdecl Function(int ind, double x, double y);
char * __stdcall Function(char *strs[], int num);