Функции. Аргументы по умолчанию в функциях

Функции. Аргументы по умолчанию в функциях


Содержание



1. Что такое аргументы по умолчанию? Каким образом объявляются аргументы по умолчанию? Общая форма объявления функции, содержащей аргументы по умолчанию

Аргумент по умолчанию – это такой аргумент функции, который программист может не указывать при вызове функции. Аргумент по умолчанию добавляется компилятором автоматически.

Чтобы использовать аргументы по умолчанию в функции, эта функция должна быть соответствующим образом объявлена. Аргументы по умолчанию объявляются в прототипе функции.

Общая форма объявления функции, которая содержит аргументы по умолчанию

returned_type FunName(type1 v1 = val1, type2 v2 = val2, ..., typeN vN = valN)
{
    // ...
}

где

  • returned_type – тип возвращаемый функцией;
  • FunName – имя функции;
  • type1, type2, …, typeN – типы переменных v1, v2, …, vN;
  • val2, …, valN – значения, которое присваиваются по умолчанию переменным v2, …, vN. В этом случае типы и присваиваемые значения должны быть совместимыми. Если в объявлении функции в списке параметров встречается запись вида
type v = val

то аргумент v есть аргументом по умолчанию (здесь type-некоторый тип, v — переменная типа type, val — значение что присваивается по умолчанию переменной v).

2. Примеры объявления и использования функций, которые используют аргументы по умолчанию

Пример 1. Объявляется функция Inc(),получающая два параметра. Функция возвращает сумму значений первого и второго параметров. Второй параметр функции есть параметром (аргументом) по умолчанию, которому присваивается значение 1.

Текст программы типа Win32 Console Application, демонстрирующий использование функции Inc(), имеет вид

#include "stdafx.h"
#include <iostream>
using namespace std;

// функция, содержащая аргумент по умолчанию
int Inc(int value, int step = 1)
{
    return value + step;
}

int _tmain(int argc, _TCHAR* argv[])
{
    //
    int v1, v2;

    v1 = 5;

    // использование аргумента по умолчанию
    v2 = Inc(v1); // v2 = 5 + 1 = 6
    v1 = 5;
    v2 = Inc(v1, 3); // v2 = 5 + 3 = 8

    cout << v2 << endl;
    return 0;
}

Пример 2. Задается функция AreaTriangle(),вычисляющая площадь треугольника, заданного длинами сторон a, b, c. Функция получает параметры, которые имеют единичные значения по умолчанию.

Листинг объявления и использования функции следующий.

#include "stdafx.h"
#include <iostream>
using namespace std;

// Площадь треугольника
// функция получает параметры по умолчанию
double AreaTriangle(double a = 1, double b = 1, double c = 1)
{
    double p, s;
    if ((a+b)<c || (b+c)<a || (a+c)<b)
        return 0;
    p = (a + b + c)/2.0; // полупериметр
    s = ::sqrt(p * (p-a) * (p-b) * (p-c)); // формула Герона
    return s;
}

int _tmain(int argc, _TCHAR* argv[])
{
    double area;

    area = AreaTriangle(); // area = 0.433013
    area = AreaTriangle(1.5); // area = 0.496078
    area = AreaTriangle(1.5, 1.5); // area = 0.707107
    area = AreaTriangle(1, 1, 1); // area = 0.433013
    area = AreaTriangle(2, 2, 2); // area = 1.7325
    area = AreaTriangle(2, 2, 8); // area = 0
    cout << area << endl;

    return 0;
}

3. Может ли конструктор класса содержать параметры по умолчанию?

Да.

4. Пример использования конструктора и метода класса, которые получают аргументы по умолчанию

Пусть задан класс Circle, реализующий круг на координатной плоскости. В классе объявляются:

  • внутренние скрытые (private) переменные с именами x, y, radius;
  • конструктор, который содержит три аргумента по умолчанию;
  • методы чтения значений внутренних переменных GetX(), GetY(), GetR();
  • метод установления новых значений внутренних переменных SetXYR(). Этот метод получает параметры по умолчанию.
#include "stdafx.h"
#include <iostream>
using namespace std;

// класс, который описывает круг
class Circle
{
    // внутренние переменные класса
    double x, y, radius;

    public:
    // конструктор, который принимает аргументы по умолчанию
    Circle(double nx=10, double ny = 10, double nradius = 1)
    {
        x = nx;
        y = ny;
        radius = nradius;
    }

    // Методы доступа
    // чтение значений x, y, r
    double GetX(void) { return x; }
    double GetY(void) { return y; }
    double GetR(void) { return radius; }

    // метод, который содержит аргументы по умолчанию
    void SetXYR(double nx=0, double ny=0, double nradius=1)
    {
        x = nx;
        y = ny;
        radius = nradius;
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    Circle c1; // объект класса Circle - аргументы по умолчанию nx=10, ny=10, nradius=1
    Circle c2(5); // nx=5, ny=10, nradius=1
    Circle c3(7, 8); // nx=7, ny=8, nradius=1
    Circle c4(12, 14, 20); // nx=12, ny=14, nradius=20
    double d;

    d = c1.GetX(); // d = 10
    d = c1.GetR(); // d = 1
    d = c2.GetX(); // d = 5
    d = c3.GetY(); // d = 8
    d = c4.GetR(); // d = 20

    // метод Circle::SetXYR()
    c1.SetXYR(2, 3, 4); // nx=2, ny=3, nradius=4
    d = c1.GetX(); // d = 2

    c2.SetXYR(20,22); // nx=20, ny=22
    d = c2.GetY(); // d = 22;

    cout << d << endl;

    return 0;
}

5. Какие преимущества дает использование аргументов по умолчанию в программах на C++?

Использование аргументов по умолчанию дает следующие преимущества:

  • сокращается листинг программного кода за счет избежания написания лишних функций, которые выполняют ту же работу только с другими значениями аргументов;
  • обеспечивается простой, естественный и эффективный стиль программирования;
  • в некоторых случаях аргументы по умолчанию есть сокращенной формой перегрузки функции. Это, в свою очередь улучшает читабельность программного кода и упрощает вызов функции.

6. Сколько раз можно задавать аргументы по умолчанию при объявлении функции? Пример

Во время объявления функции, аргументы по умолчанию задаются только один раз. Здесь возможны два случая. Первый, если функция имеет прототип и реализацию. Второй случай, если функция не имеет прототипа, а имеет только реализацию.

В первом случае (с прототипом), аргумент по умолчанию задается только в прототипе функции (а не в реализации). Во втором случае, аргумент по умолчанию задается в реализации функции, поскольку нет прототипа функции.

Пример. Заданы две функции:

  • функция GetAreaCircle(), которая вычисляет площадь круга. Эта функция имеет прототип;
  • функция GetVolumeSphere(), которая вычисляет объем шара. Эта функция не имеет прототипа.

В приведенном ниже коде демонстрируется применение функций, которые содержат аргументы по умолчанию. Важно: аргументы по умолчанию объявляются только один раз. В функции GetAreaCircle() аргументы по умолчанию объявляются в прототипе, поскольку эта функция имеет прототип. В функции GetVolumeSphere() аргументы по умолчанию объявляются в реализации, так как функция не имеет прототипа.

Лістинг программы, созданной по шаблону Win32 Console Application следующий:

#include "stdafx.h"
#include <iostream>
using namespace std;

const double Pi = 3.1415;

// объявление аргументов по умолчанию в прототипе функции
double GetAreaCircle(double r = 1);

// функция GetVolumeSphere() не имеет прототипа,
// поэтому аргумент по умолчанию задается непосредственно в реализации
double GetVolumeSphere(double r = 1)
{
    return 4.0/3 * Pi*r*r*r;
}

int _tmain(int argc, _TCHAR* argv[])
{
    double area;
    double volume;

    area = GetAreaCircle(); // area = 3.1415
    volume = GetVolumeSphere(); // volume = 4.18867

    area = GetAreaCircle(2); // area = 12.566
    volume = GetVolumeSphere(2); // volume = 33.5093

    cout << area << endl;
    cout << volume << endl;

    return 0;
}

// реализация функции - аргументы по умолчанию уже заданы в прототипе
double GetAreaCircle(double r)
{
    return Pi * r * r;
}

7. В каком порядке должны следовать аргументы по умолчанию по отношению к обычным аргументам?

Аргументы (параметры) по умолчанию должны следовать после объявления обычных аргументов. Если объявить аргументы по умолчанию первыми, а за ними объявить обычные аргументы, то это будет ошибка.


Связанные темы