Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторная работа4.doc
Скачиваний:
5
Добавлен:
30.11.2018
Размер:
130.05 Кб
Скачать

Объявления и определения

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

// объявление функции calc()

// определение находится в другом файле

void calc(int);

int main()

{

int loc1 = get(); // ошибка: get() не объявлена

calc(loc1); // правильно: calc() объявлена

}

// ...

Глобальный объект можно определить в программе только один раз. Поскольку он должен быть объявлен в исходном файле перед использованием, то для программы, состоящей из нескольких файлов, необходима возможность объявить объект, не определяя его. Как это сделать?

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

extern int i;

Эта инструкция “обещает”, что в программе имеется определение, подобное

int i;

extern-объявление не выделяет места под объект. Оно может встретиться несколько раз в одном и том же исходном файле или в разных файлах одной программы. Однако обычно находится в общедоступном заголовочном файле, который включается в те модули, где необходимо использовать глобальный объект:

// заголовочный файл

extern int obj1;

extern int obj2;

// исходный файл

int obj1 = 97;

int obj2;

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

extern const double pi = 3.1416; // определение


const double pi; // ошибка: повторное определение pi

Ключевое слово extern может быть указано и при объявлении функции – для явного обозначения его подразумеваемого смысла: “определено в другом месте”. Например:

extern void putValues( int*, int );

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

В C++ можно задать функцию, которая на самом деле не вызывается, а ее тело встраивается в программу в месте ее вызова.

Спецификатор inline для функций помещается перед определением функции для того, чтобы код функции был подставлен компилятором непосредственно в место ее вызова для исключения накладных расходов по вызову функции (помещение параметров в стек, оформление возврата и прочее).

Inline void func(void) {тело функции}

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

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

//Пример встраиваемой функции #include<iostream>

using namespace std;

inline int even(int x) {

return !(x%2); }

int main()

{

if (even(10)) cout« "10 является четным W;

if (even(1l)) cout«; "11 является четными»;

return 0; }

В этом примере функция even(), которая возвращает истину при четном аргументе, объявлена встраиваемой. Это означает, что строка

if (even(10)) cout« "10 является четными";

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

if (! (10%2)) cout « "10 является четным\п";

Этот пример указывает также на другую важную особенность использования встраиваемой функции: она должна быть задана до ее первого вызова. Если это не так, компилятор не будет знать, какой именно код предполагается встроить в программу с помощью встраиваемой функции. Поэтому функция even() была определена перед функцией main().

Примеры

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

// file1.c:

int a = 1;

int f() { /* что-то делает */ }

// file2.c:

extern int a;

int f();

void g() { a = f(); }

a и f(), используемые g() в файле file2.c,- те же, что определены в файле file1.c. Ключевое слово extern (внешнее) указывает, что описание a в file2.c является (только) описанием, а не определением. Если бы a инициализировалось, extern было бы просто проигнорировано, поскольку описание с инициализацией всегда является определением. Объект в программе должен определяться только один раз. Описываться он может много раз, но типы должны точно согласовываться.