
- •1. Краткие теоретические сведения
- •1.1. Знакомство с функциями
- •1.2. Описание функции
- •1.3.1. Тело функции
- •1.3.2. Формальные параметры функции
- •1.3.3. Обращение к функции
- •1.3.4. Фактические параметры.
- •1.4. Формальные и фактические параметры функции
- •1.5. Описание и объявление функции. Прототип функции
- •1 Способ - Перед main().
- •2 Способ - После main ().
- •1.6. Передача параметров в функцию. Изменяемые значения параметров
- •1.6.1. Передача параметров
- •1.6.2. Передача параметров по значению
- •1.6.3. Передача параметров по ссылке
- •1.6.4. Передача параметров по указателю
- •1.7. Механизм обращения к функции и передача данных
- •1.8. Локальные и глобальные переменные. Время жизни и область действия (видимости) переменных
- •1.8.1. Представление об области видимости переменных
- •1.8.2. Объявление локальных переменных
- •1.8.3. О конфликте имен
- •1.8.4. Глобальные переменные
- •1.8.5. Если имена глобальных и локальных переменных конфликтуют
- •1.9. Принцип сокрытия данных внутри функции. Принцип локализации имен
- •1.10. Передача одномерных массивов как параметров функции
- •1.11. Передача многомерных массивов в функцию
- •1.12. Рекурсивные функции
- •1.13. Аргументы по умолчанию
- •1.14. Встраиваемые функции (inline)
- •1.15. Перегрузка функций
- •1.16. Указатель на функцию
- •1.17. Шаблоны функций
- •1.18. Использования библиотеки этапа выполнения
- •1.18.1. Использование функций библиотеки этапа выполнения
- •1.18.2. Изучение функций библиотеки этапа выполнения
- •1.18.3. Использование функций api
- •1.19. Изменение значений параметров функции
- •1.19.1. Почему функции обычно не могут изменить значения параметров
- •1.19.2. Изменение значения параметра
- •1.19.3. Использование ассемблерных листингов для лучшего понимания работы компилятора
- •1.20. Примеры решения задач с использованием механизма функций
- •2. Задание
- •2.4. Задания для выполнения на занятиях
- •2.4.1. Задание 1. Функции пользователя-использование формул
- •2.4.1.1. Условие задания
- •2.4.1.2. Пример для варианта 30
- •2.4.1.3. Программа
- •2.4.1.4. Тестирование
- •2.4.2. Задание 2. Функции пользователя при работе с массивами
- •2.4.2.1. Условие задания
- •2.4.2.2. Пример для варианта 30
- •2.4.2.3. Программа
- •2.4.2.4. Тестирование
- •2.4.3. Задание 3. Функции пользователя при работе с массивами
- •2.4.3.1. Условие задания
- •2.4.3.2. Пример для варианта 30
- •2.4.3.3. Программа
- •2.4.3.4. Тестирование
- •2.4.4. Задание 4. Вычисление выражений с использованием функций
- •2.4.4.1. Условие задания
- •2.4.4.2. Пример для варианта 30
- •2.4.4.3. Программа
- •2.4.4.4. Тестирование
- •2.4.5. Задание 5. Вычисление интеграла методом трапеций
- •2.4.5.1. Условие задания
- •2.4.5.2. Пример для варианта 30
- •2.4.5.3. Программа
- •2.4.5.4. Тестирование
- •2.4.5.5. Типичные ошибки при выполнении работы
- •Вопросы для самоконтроля
- •Литература
- •1. Краткие теоретические сведения 2
- •1.1. Знакомство с функциями 2
1.6. Передача параметров в функцию. Изменяемые значения параметров
1.6.1. Передача параметров
При работе важно соблюдать следующее правило: при объявлении и вызове функции параметры должны соответствовать по количеству, порядку следования и типам. Функция может не иметь параметров, в этом случае после имени функции обязательно ставятся круглые скобки. Существует три основных способа передачи параметров: передача по значению, по ссылке или по указателю.
В C существуют три способа передачи параметров в функцию:
– по значению;
– по ссылке;
– по указателю.
1.6.2. Передача параметров по значению
До сих пор рассматривался синтаксис именно этого способа передачи данных (по значению). Его механизм — это создание локальной копии параметра в теле функции. В таком случае значения параметров не могут быть изменены в результате обращения. Это возможность защитить входные данные от их нежелательного изменения функцией,
В момент обращения к функции в памяти создаются временные переменные с именами, указанными в списке параметров, в которые копируются значения фактических (передаваемых в функцию) параметров. После завершения работы функции временные переменные удаляются из памяти.
Пример 13.14
Вычислить сумму двух переменных x и y.
double Sum(double a, double b)
{
return a+b; // Вычисление и передача результата
}
…
s = Sum (x, y); // Вызов функции Sum
Функция Sum не может изменить значения используемых при вызове функции переменных x и y, так как работает только с их локальными копиями.
1.6.3. Передача параметров по ссылке
При передаче параметров по ссылке передается адрес соответствующей переменной, а не ее значение. Для получения адреса используется операция разадресации («&»).
Пример 13.15
Поменять местами значения двух переменных x и y.
void Swap_Ref (double &a, double &b)
{
int tmp = a;
a = b;
b = tmp;
}
…
Swap_Ref (x, y); // Вызов функции Swap_Ref
При таком способе передачи параметры a и b будут инициализированы в качестве псевдонимов переменных-аргументов x и y. Поэтому любые изменения параметров a и b будут приводить к соответствующему изменению переменных x и y.
Изменение механизма передачи данного в функцию формально выглядит добавлением признака адресной операции & к имени параметра в описании функции:
тип_ функции имя_функции (тип_параметра & имя_параметра)
При этом функция и вызывающая программа работают с адресом объекта в памяти, следовательно, функция может изменить значение параметра. При этом фактическим параметром, соответствующим формальному параметру – ссылке, может быть только имя переменной (левостороннее выражение).
Механизм такого способа передачи данных заключается в том, что функция и вызывающая программа работают с адресом объекта в памяти (фактически, с одной и той же областью данных). Как результат, значения параметров функция может изменить. Как следствие, фактическим параметром, соответствующим формальному параметру — ссылке, может быть только имя переменной.
Пример 13.16
Функция находит площадь и периметр треугольника, заданного длинами сторон. Возвращаемых значений два — площадь и периметр. Эти значения функция вернет через параметры. Кроме того, нужна проверка условия существования треугольника. Это логическое значение функция вернет через return (1, если треугольник существует, и 0, если нет).
#include <stdio.h>
#include <math.h>
int Triangle (float a, float b, float c, float & p, float &s)
{
// эта функция имеет два варианта выхода
// параметры a,b,c передаются по значению (только входные данные),
// параметры p, s, по ссылке (как входные данные, так и результат)
float pp; // полупериметр
if (a+b <=c || a+c<=b || b+c<=a) // треугольник не существует
return 0;
else
{ // треугольник существует
p = a + b + c;
pp = 0.5 * p;
s = sqrt (pp* (pp – a)*(pp – b)*(pp – c));
return 1;
}
}
// при обращении фактическими параметрами, подставляемыми на место
// формальных параметров-значений, могут быть выражения, а фактическими
// параметрами, подставляемыми на место формальных параметров-адресов,
// могут быть только переменные
void main (void)
{
float A, B, C; // длины сторон фактические
float Perim, Square; // периметр и площадь фактические
// пример обращения
printf("Введите длины сторон треугольника\n");
scanf ("%f%f%f", &A, &B, &C);
if (Triangle (A, B, C, Perim, Square) = = 1)
printf("Периметр равен %6.2f, площадь равна %6.2f\n", Perim, Square);
else
printf ("Треугольник не существует\n");
}