Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Аленский. лекции по проге.doc
Скачиваний:
19
Добавлен:
11.11.2018
Размер:
1.35 Mб
Скачать

§ 6. Дополнительные возможности функций

    1. Встраиваемые функции (inlineфункции)

В первом примере § 4 такими функциями являются DIGIT и RR. Для встраиваемой функции не разделяется прототип и текст функции. На месте прототипа после заголовка сразу в фигурных скобках записываем и текст функции. Перед заголовком функции при этом можно писать ключевое слово inline, которое не является обязательным.

Обычные функции вызываются следующим образом. Если встречается обращение к ней, запоминается место (точка) вызова, управление передаётся на код функции, она выполняется и управление возвращается в место вызова. При этом функция может возвращать значения одного или нескольких параметров. При этом код функции хранится в единственном экземпляре. Поэтому преимущество таких функций в экономии памяти. Но генерация вызова функции, передача параметров и возвращение результатов занимает определённое время.

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

Например,

int InFun (int n, int k) // ‘;’ не пишется

{ return ! (n%k); }

Тогда если встретится, например, вызов

int N=15;

if ( InFun(N, 2)) cout<< N <<” -- чётное”;

else cout<<N <<” – нечётное”;

то на самом деле это функционально идентично

if (!(N% 2)) cout<< N <<” -- чётное”;

else cout<< N <<” – нечётное”;

Поэтому такие функции выполняются быстрее. Недостаток в том, что если встраиваемые функции часто вызываются и они большие, то возрастает объём наших программ. Поэтому встраиваемыми функциями имеет смысл оформлять небольшие относительно функции. Некоторые компиляторы запрещают оформлять функцию как встраиваемую, если, например, она содержит циклы, оператор switch и другие конструкции, увеличивающие объём кода.

6.2. Параметры по умолчанию

В прототипе или при описании функции в её заголовке одному или нескольким формальным параметрам может быть назначено значение по умолчанию по тем же правилам, что при инициализации. При вызове таких функций фактические параметры, соответствующие умалчиваемым, могут быть опущены, и тогда функция будет выполняться с теми значениями, которые указаны в заголовке. Значение по умолчанию можно изменить, записав при вызове фактический вместо умалчиваемого параметра. Остальные фактические параметры должны быть обязательно заданы. Например, функцию с заголовком void fun62 (float f, char ch=’*’, int i=2); можно вызвать одним из следующих способов:

а) fun62 (2.5, ‘-‘, 11); // параметры получат значения: f=2.5, ch=’-‘, i=11;

б) fun62 (2.5, 196); // f=2.5, ch — символ с кодом 196, i=2 по умолчанию;

в) fun62 (196); // f=196 как вещественное, сh=’*’ и i=2 по умолчанию;

г) fun62(0.01, ‘*’, 33); // f=0.01, ch=’*’, i=33;

При передаче параметров по умолчанию необходимо руководствоваться следующими правилами:

  1. значение по умолчанию может быть задано либо в прототипе, либо при описании функции, но только в одном месте один раз;

  2. в качестве умалчиваемых значений должны быть либо константы, либо глобальные переменные;

  3. параметры со значениями по умолчанию должны быть последними в списке;

  4. если при вызове функции опустили аргумент для параметра по умолчанию, то не надо писать аргумент и для всех оставшихся в списке. Например, если для функции fun62 надо изменить i на 196, то fun62 (0.11, 196); компилируется из-за совместимости целого и символьного типов, но неправильно выполняется, так как i останется по умолчанию (см. б)), а fun62(0.11 , , 196) не компилируется. Правильным будет следующий вызов: fun62(0.11 , ’*’ , 196);

Поэтому рекомендуется упорядочить умалчиваемые параметры по частоте их изменения. Например, если строка меняется чаще, чем символ, а вероятность изменения целого числа наименьшая, то задаём следующий порядок параметров:

int test=2;

void Out62(float f1, char str2[]="hello", char c3='*', int p4=test )

{ textcolor(12);

cprintf("%f %s %c %d\n\r", f1, str2, c3, p4);

}

int main(int argc, char* argv[])

{ Out62(11,"MMF",65);

Out62(11);

int q1=1111; Out62(q1,";",196 ,9);

// Целое число можно передать вместо вещественного f1

getch(); return 0;

}

Успешная компиляция и выполнение последней программы показывают, что в качестве параметра по умолчанию можно использовать и строку.

Упражнение. Определить результат выполнения последней программы.