Встраиваемые функции

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

Чтобы объявить функцию встраиваемой, следует перед функцией добавить ключевое слово inline (или __inline). Следует учитывать, что эти ключевые слова являются лишь рекомендацией компилятору и могут быть проигнорированы. В качестве примера объявим функцию sum() встраиваемой (листинг 12.28).

Листинг 12.28. Встраиваемые функции

#include <iostream>

inline int sum(int x, int y) {
   return x + y;
}

int main() {
   std::cout << sum(10, 20) << std::endl;
   return 0;
}

Создать встраиваемую функцию можно также с помощью директивы #define. Значение, указанное в этой директиве, подставляется в место вызова функции до компиляции. Название, указанное в директиве #define, принято называть макроопределением или макросом. Директива имеет следующий формат:

#define <Название функции>(<Параметры>) <Инструкция>

Пример использования директивы #define приведен в листинге 12.29.

Листинг 12.29. Использование директивы #define

#include <iostream>

#define SUM(x, y) ((x) + (y))

int main() {
   std::cout << SUM(10, 20) << std::endl;
   return 0;
}

Обратите внимание на то, что в конце инструкции точка с запятой не указывается. Концом инструкции является конец строки. Если точку с запятой указать, то значение вместе с ней будет вставлено в выражение. Например, если определить макрос так:

#define SUM(x, y) (x + y);

то после подстановки значения, инструкция:

std::cout << SUM(10, 20) << std::endl;

будет выглядеть следующим образом:

std::cout << (10 + 20); << std::endl;

Точка с запятой после закрывающей круглой скобки является концом инструкции, поэтому этот код вызовет ошибку при компиляции. Однако в следующем примере ошибки не будет, но результат будет совершенно другим. Инструкция

int z = SUM(10, 20) + 40;

после подстановки будет выглядеть следующим образом:

int z = (10 + 20); + 40;

Подобная ситуация приводит к ошибкам, которые бывает трудно найти.

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

#define SUM(x, y) x + y

то после подстановки значения, инструкция

int z = SUM(10, 20) * 40;

будет выглядеть следующим образом:

int z = 10 + 20 * 40;

Приоритет оператора умножения выше приоритета оператора сложения, поэтому число 20 будет умножено на 40, а затем к результату прибавлено число 10. Таким образом, результат будет 810, а не 1200.

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

#define SUM(x, y) \
(x + y)

Учебник C++ (MinGW-W64)
Учебник C++ (MinGW-W64) в формате PDF

Помощь сайту

ЮMoney (Yandex-деньги): 410011140483022

ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов