Встраивание.
Ключевое слово inline.
В прошлом уроке мы познакомились с понятием функции. И выяснили, что как
только программа встречает вызов функции, она сразу же обращается к телу данной
функции и выполняет его. Этот процесс существенно сокращает код программы, но
при этом увеличивает время ее выполнения за счет постоянных обращений к описанию
конкретной вызванной функции. Но, бывает и не так. Некоторые функции в языке C
можно определить с использованием специального служебного слова inline.
Данный спецификатор позволяет определить функцию как встраиваемую, то есть
подставляемую в текст программы в местах обращения к этой функции. Например,
следующая функция определена как подставляемая:
inline float module(float x = 0, float у = 0)
{
return sqrt(x * x + у * у);
}
|
Обрабатывая каждый вызов встраиваемой функции module, компилятор
подставляет на место ее вызова - в текст программы - код операторов тела
функции. Тем самым при многократных вызовах подставляемой функции, размер
программы может увеличиться, однако исключаются временные затраты на обращение к
вызываемой функции и возврат из нее в основную функцию программы.
Примечание: Наиболее эффективно использовать
подставляемые функции в тех случаях, когда тело функции состоит всего из
нескольких операторов.
Случается так, что компилятор не может определить функцию, как встраиваемую и
просто игнорирует ключевое слово inline. Перечислим причины, которые приводят к
такому результату:
1. Слишком большой размер функции.
2. Функция является рекурсивной. (с этим понятием вы познакомитесь в
следующих уроках)
3. Функция повторяется в одном и том же выражении несколько раз
4. Функция содержит цикл, switch или if.
Как видите - всё просто, но inline-функции не единственный способ
встраивания. Об этом расскажет следующая тема урока.
Раскрытие макро.
Помимо вызова функции, для встраивания в программу повторяющегося фрагмента
используют, так называемое, раскрытие макро. Для этих целей применяется
директива препроцессора #define, со следующим синтаксисом:
#define Имя_макроса(Параметры) (Выражение)
|
Пример.
#include <iostream>
#define SQR(X) ((X) * (X))
#define CUBE(X) (SQR(X)*(X))
#define ABS(X) (((X) < 0)? -(X) : X)
using namespace std;
void main()
{
у = SQR(t + 8) - CUBE(t - 8) ;
cout <<sqrt(ABS(y)) ;
}
|
1. C помощью директивы #define объявляются три макроса sqr(x), cube(x) и
abs(x).
2. В функции main происходит вызов вышеописанных макросов по имени.
3. Препроцессор раскрывает макро (т. е. подставляет на место вызова выражение
из директивы #define) и передает получившийся текст компилятору.
4. После встраивания выражение в main выглядит для программы таким
образом:
у = ((t+8) * (t+8)) - ((((t-8)) * (t-8)) * (t-8));
cout << sqrt(((y < 0)? -(y) : y));
|
Примечание: Следует обратить внимание на
использование скобок при объявлении макроса. С помощью них мы избегаем ошибок в
последовательности вычислений. Например:
#define SQR(X) X * X
у = SQR(t + 8); //раскроет макро t+8*t+8
|
В примере при вызове макроса SQR сначала
выполнится умножение 8 на t, а потом к результату прибавится значение переменной
t и восьмерка, хотя очевидно, что нашей целью было получение квадрата суммы t+8.
Теперь вы полностью знакомы с понятием встраивания и можете использовать его
в своих программах.