Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Встроенные функции

Операция расширения области видимости

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

double A;void main() {

int A;

A = 5; // присваивает значение 5 переменной А типа int

}

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

double A; // глобальная переменная Аvoid main(){

int A; // локальная переменная А

А = 5; // присваивает значение 5 локальной переменной А типа int

::А = 2.5; // присваивает значение 2,5 глобальной переменной А типа double

}

Обратите внимание: операция расширения области видимости используется только для организации доступа к глобальной переменной. Данную операцию нельзя использовать для доступа к локальной переменной, объявленной внутри блока, как в следующем примере некорректного кода:

void FuncX(int Code) {

double A;

 

if (Code == 1)

{

int A;

 

// попытка доступа к переменной А типа double во внешнем блоке:

::А = 2.5; // СШИБКА:::А описывает глобальную переменную А, что неправильно,

// если А не определена на глобальном уровне

//...

}

//...

}

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

#include <iostreara.h> typedef int A;enum (Red, White, Blue); void main (){

typedef double A;

enum (Blue, White, Red);

cout << sizeof (A) << '\n'; // печатает размер переменной // А типа double

cout << sizeof (::A) << '\n'; // печатает размер переменной // А типа int

cout << (int)Blue << ‘\n'; // печатает О

cout << (int)::Blue << '\n'; // печатает 2

}

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

inline int FuncA(int X) {

// код функции...

}

Замена вызовов функции копией кода функции называется макрорасширением (inline expansion) или просто встраиванием (inlining).

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

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

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

inline int Abs(int N) {return N < 0? -N: N;}

подобна макросу

#define ABS(N) ((N) < 0? -(N): (N));

Но есть и отличие: вызовы встроенной функции обрабатываются компилятором, а макросов – препроцессором, выполняющим простую текстовую подстановку. Следовательно, встроенная функция имеет два важных преимущества перед макросом. Во-первых, при вызове функции компилятор проверяет тип передаваемых ей параметров, чтобы убедиться в том, что они целочисленные или их значения можно преобразовать в целочисленные. Во-вторых, если функции передается выражение, го оно вычисляется всего один раз. Если же выражение передается в макрос, то оно вычисляется дважды, что может привести к неожиданным результатам. Например, следующий вызов макроса дважды декрементирует переменную I (возможен неожиданный или нежелательный результат!):

Abs (--I);

Макрос также имеет преимущество перед встроенной функцией: ему можно передать данные любого типа и он возвратит результат такого же типа (например, long, int или double). Хотя во встроенную функцию также можно передать аргумент любого числового типа, тип значения будет преобразован в int, а функция возвратит значение типа int, в результате чего может быть потеряна точность. Однако, как будет показано далее (в разделе «Перегруженные функции»), в языке C++ эти ограничения преодолеваются путем определения нескольких вариантов функции, по одному для каждого типа или для множества типов параметров, передаваемых функции.

Примечание

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

<== предыдущая лекция | следующая лекция ==>
Операторы объявления переменных | Стандартные параметры функции
Поделиться с друзьями:


Дата добавления: 2014-01-07; Просмотров: 438; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.01 сек.