Направления программирования. История создания языка Си. Особенности языка, страница 27

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

Типы библиотек. Различают две модели библиотек.

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

·  Динамические библиотеки.(DLL), которые используются в Windows. При формировании загрузочного кода программы, программа получает ссылку на динамическую библиотеку. И только при выполнении программы и вызове функции из DLL – библиотеки данная библиотека загружается в память. Если несколько программ вызывают одинаковые DLL – функции, то в рабочую память загружается только одна копия, которая совместно используется всеми программами.

п.16.Препроцессор языка Си.

Препроцессор – это специальная программа, которая обрабатывает текст программы до ее компиляции, т.е. расширяет все макровызовы (т.е. заменяет в тексте программы аббревиатуры на соответствующие директивы), подключает необходимые файлы и может влиять на условие компиляции. Признак директивы препроцессора символ “#”, который нигде больше не используется. Директивы препроцессора могут быть записаны в любом месте файла.

п.16.1.Макроопределение и макровызовы.

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

# define <идентификатор>[<список параметров>]<текст>

может отсутствовать

<идентификатор> - это имя макроса. Чтобы выделить имена макросов их пишут прописными буквами.

<список параметров> - содержит один или более параметров, разделенных запятыми.

<текст> - значение макроса.

Директива # define заменяет все вхождения <идентификатора> на <текст>. Если макроопределение имеет параметры, то <текст> модифицируется путем замены формальных параметров на фактические. Подстановка параметров носит текстовый характер, никаких преобразований типов при этом не происходит.

Макровызов имеет следующий синтаксис:

<имя макроса>[<список фактических параметров>]

может отсутствовать

п.16.2.Макроопределение с параметрами.(функциональные макросы)                           

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

Пример макроопределения с параметрами.

G(3, x)+G(x, y*z)+G(x*y-z, z)

G(a, b)=(a²+b²)*(a²+3b²-2a+b)

1)  # define G(a, b) ((a)*(a)+(b)*(b))*((a)*(a)+3*(b)*(b)-2*(a)+(b))

2)  # define SQ(x) (x)*(x)

# define G(a, b) (SQ(a)+SQ(b))*(SQ(a)+3* SQ(b)-2*(a)+(b))

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

Пример:

1.  Лексический анализ

# define SQ(x) ((x)*(x)) – нужны скобки, если их нет, то получим:

при j=3

SQ(j)à(j*j)=>9

SQ(j+1)à(j+1*j+1)=>7

2.  Счета

# define max(x, y)(((x)>(y))?(x):(y))

a=5, b=3

max(++a, b)

(((++a)>(b))?(++a):(b))

 


увеличится на 1 дважды.

В директиве define есть возможность создавать новые идентификаторы <склеивать>

# define Ident(x, y) (x##y)

Ident(x, 4)à(x4)

Стандартные макросы.

Стандартный пакет Си включает в себя ряд предопределенных функциональных макросов; например, функция feof(), предназначенная для нахождения конца файла в действительности Макрос, определенный в файле stdio.h.