Функції. Аргументи за замовчуванням у функціях

Функції. Аргументи за замовчуванням у функціях


Зміст


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. У якому порядку мають слідувати аргументи за замовчуванням по відношенню до звичайних аргументів?

Аргументи (параметри) за замовчуванням мають слідувати після оголошення звичайних аргументів. Якщо оголосити аргументи за замовчуванням першими, а за ними оголосити звичайні аргументи, то це буде помилка.


Зв’язані теми