Самостоятельная работа 1: функции

Кувшинов Д.Р.

2015


Общее оглавление


4 балла

Цели и критерии

Цель: освоить базовый синтаксис определения и применения функций, элементарные средства ввода-вывода.

Критерии полноты

  1. Программа должна запрашивать у пользователя значение и выполнять все возможные переводы единиц (всего шесть вариантов для трёх единиц).
  2. Определить функции перевода единиц, позволяющих переводить значение, заданное в любой из указанных в задании единиц, в значение в любой другой из указанных в задании единиц.
  3. Использовать композицию функций: для шести направлений “перевода” достаточно определить четыре функции.


Основные определения

Функция function (в C++, также процедура subroutine, procedure в некоторых других языках программирования) — именованный фрагмент кода, предоставляющий стандартизованный интерфейс вызова (выполнения действий с набором значений параметров и возвращения результата).

Функция является основой структурирования действий (процедурной или функциональной декомпозиции). Группы связанных по смыслу действий выделяются в функции, получая имена и стандартный способ исполнения (вызов функции = исполнение действий, из которых состоит тело функции), таким образом сложные действия получаются из простых и затем могут выполняться уже как “простые” действия (сокрытие сложности) и в свою очередь использоваться как составные части ещё более сложных действий.

Оформление функции

// Возводит в квадрат, имя параметра указывать не обязательно.
int square(int); // Это объявление функции, а не определение.

// Объявление не содержит тела функции --
// собственно описания того, как эта функция вычисляется.
// Объявление просто представляет некую функцию:
// что она возвращает (тип возвращаемого значения) -- здесь int (целое число);
// как она называется -- здесь square (квадрат);
// какие у неё параметры -- здесь один параметр типа int без имени.

// А это уже определение той же функции.
int square(int x)
{
  return x * x;
}

// Часть параметров могут иметь значения по умолчанию.
int sum(int a, int b = 0, int c = 0)
{
  return a + b + c; // вернуть сумму a, b и c
}

// Вывести координаты точки отдельной строкой.
void println(double x, double y)
{
  cout << x << " " << y << "\n";
}

// Композиция функций: сумма квадратов.
int squares_sum(int a, int b = 0, int c = 0)
{
  return sum(square(a), square(b), square(c));
}

// Функция может не принимать параметров -- так (C++):
int read_int()
{
  int x = 0; // переменная, куда будет считано число
  cin >> x;  // считать число с потока ввода в переменную x
  return x;  // вернуть считанное значение
}

// ... или так (в стиле C):
int read_int(void)
{
  int x = 0; // переменная, куда будет считано число
  scanf("%i", &x); // считать число с потока ввода в переменную x
  return x;  // вернуть считанное значение
}

Распространённые ошибки

При переводе математических формул на язык C++ не следует пропускать знаки операций: например 2a следует записать как 2*a, где * — обозначение операции умножения чисел. Знаменатель дроби брать в скобки: a/2*b равно (a/2)b, а не a/(2 b).

Ниже приведён чуть более сложный пример. Программа запрашивает у пользователя пару целых чисел a и b и выводит значение выражения (a + 2b)(a - 2b), подставляя полученные значения a и b (хранящиеся в одноимённых переменных):

#include <iostream>
#include <cstdlib>

int main()
{
  using namespace std;

  int a = 0, b = 0; // Целые числа.
  cout << "a = ";
  cin >> a;
  cout << "b = ";
  cin >> b;

  cout << "(a + 2b) (a - 2b) = ";
  cout << (a + 2*b) * (a - 2*b) << endl;
  return EXIT_SUCCESS;
}

Ниже приведены примеры некоторых распространённых синтаксических ошибок в заголовках и вызовах функций.

#include <cmath> // здесь определены функции sqrt, abs, fmax и pow.

// Ошибка: не указан тип возвращаемого значения.
add(float a, float b) { return a + b; }

// Ошибка: не указан тип параметра.
double square(x) { return x * x; }

// Ошибка: тип параметра должен быть указан для каждого параметра.
double length(double x, y)
{
  return sqrt(x * x + y * y);
}

// Ошибка: значения по умолчанию должны заполняться, начиная с конца списка параметров.
double norm(int p = 2, double x, double y)
{
  if (p == 2) // если p равно 2, вернуть евклидову длину
    return length(x, y);
  if (p == 1) // если p равно 1, вернуть сумму модулей координат
    return abs(x) + abs(y);
  if (p == 0) // если p равно 0, вернуть максимум модулей координат
    return fmax(abs(x), abs(y));

  // По умолчанию (если не выполнено ни одно из условий выше)
  // вернуть корень p-й степени суммы p-степеней координат.
  return pow(pow(x, p) + pow(y, p), 1.0 / p);
}

int main()
{
  int n = 2;
  double x = 0, y = 0;
  cin >> n >> x >> y;

  // Ошибка: типы аргументов не надо указывать в месте вызова функции,
  // там должны стоять только передаваемые в функцию значения.
  cout << norm(int n, double x, double y) << endl;
  // Правильный вариант:
  cout << norm(n, x, y) << endl;
  return EXIT_SUCCESS;
}


Пример выполнения задания

Данный пример демонстрирует использование функций для описания способа приведения различных единиц длины (дюймы ↔ футы ↔ метры) друг ко другу.

#include <iostream>
#include <cstdlib>

// Дюймы in в метры.
double in2m(double in) { return 0.0254 * in; }

// Футы ft в метры.
double ft2m(double ft) { return 0.304 * ft; }

// Метры m в дюймы.
double m2in(double m) { return m / 0.0254; }

// Метры m в футы.
double m2ft(double m) { return m / 0.304; }

int main()
{
  using namespace std;
  cout << "Enter length: ";
  double len = 0.0;
  cin >> len;
  cout << "in to m = " << in2m(len) << endl;
  cout << "ft to m = " << ft2m(len) << endl;
  cout << "m to in = " << m2in(len) << endl;
  cout << "m to ft = " << m2ft(len) << endl;
  cout << "in to ft = " << m2ft(in2m(len)) << endl; // обратите внимание на
  cout << "ft to in = " << m2in(ft2m(len)) << endl; // порядок композиции
  return EXIT_SUCCESS;
}

C++, HTML


Варианты

1

Температура в градусах Цельсия ↔ Кельвина ↔ Фаренгейта.

Обозначим температуру в градусах Цельсия через tC, температуру в градусах Кельвина через tK, температуру в градусах Фаренгейта через tF. Тогда

2

Масса в (английских) фунтах ↔ унциях ↔ килограммах.

1 английский фунт = 16 унциям = 453.59237 г.

3

Расстояние в секундах экватора Земли ↔ милях ↔ километрах.

4

Расстояние в парсеках ↔ световых годах ↔ астрономических единицах.

1 парсек ≈ 3.2616 световых лет ≈ 206’264.8 а. е.

5

Энергия в джоулях ↔ калориях ↔ электронвольтах.

6

Длины в типографских пунктах ↔ линиях ↔ миллиметрах.

7

Объёма в литрах ↔ галлонах ↔ баррелях (американских).

8

Площади в гектарах ↔ квадратных милях ↔ квадратных километрах.

9

Скорости в узлах ↔ км/ч ↔ м/с.

10

Углов в градусах ↔ градах ↔ радианах.

Полная окружность = 360 градусов = 400 град = 2π радиан.

11

Времени в секундах ↔ звёздных сутках ↔ звёздных месяцах.

Условные средние значения, реальная продолжительность изменяется со временем.

12

Телесных углов в квадратных секундах ↔ квадратных градусах ↔ стерадианах.

13

Единицы объёма при одинаковой массе и в нормальных условиях: дистиллированная вода ↔ этанол (95.6%) ↔ концентрированная серная кислота (98%).

14

Единицы массы при одинаковом объёме и в нормальных условиях: свинец ↔ вольфрам ↔ уран-238 (обеднённый).


Общее оглавление

Кувшинов Д.Р. © 2015