Полезное в сети

Всегда в теме

Статистика


Яндекс.Метрика


Онлайн всего: 1
Гостей: 1
Пользователей: 0

Рекомендуем



Главная » Статьи » Образовательные » Программирование

Использование библиотечных процедур СИ

О библиотеке СИ

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

1) интерфейс с функциями ОС (такими, как открытие и закры-
тие файлов);
2) использование быстрых и эффективных функций (таких, как
строковые манипуляции) в общих задачах программирования.

Библиотека Си особенно важна при использовании базовых фун-
кций, которые не содержатся в языке. Это, например, функции ввода
и вывода
, распределения памяти и управления процессами.

Для обеспечения возможности контроля компилятором типов данных языка Си используются сопровождающие эту библиотеку include-файлы. Кроме определений и объявлений библиотечных функций как макро include-файлы содержат объявления функций со списками типов аргументов. Списки типов аргументов дают возможность компилятору контролировать обращение к библиотечным функциям. Это может быть полезным для обнаружения ошибок в программе, возникающих в результате несоответствия между типами фактических и формальных аргументов функций. Однако можно не использовать контроль типов аргументов.


К списку стандартных include-файлов библиотеки Си могут
быть добавлены новые include-файлы, содержащие списки типов аргументов для всех функций библиотеки Си.

Вызов библиотек СИ

Вызов Библиотек языка СИ Прежде чем вызвать процедуру библиотеки Си из программы пользователя, нужно ее объявить в этой программе. Все библиотечные процедуры размещаются в объектном виде в библиотечных файлах,
которые сопровождают программное обеспечение компилятора Си. Во время линкования программа увяэывается с соответствующим файлом или файлами, чтобы разрешить ссылки на библиотечные функции и обеспечить коды для вызываемых библиотечных функций. В большинстве случаев подготовка к вызову библиотечных функций может быть осуществлена одним из следующих способов:
1) включением стандартного #include-файла в программу. Мно-
гие процедуры требуют объявлений и определений. Для этого можно
просто задать include-файлы, в которых определяются все требуемые
объявления и определения;
2) объявлением библиотечной функции, возвращающей значение
любого типа, кроме integer. Предполагается, что все функции возв-
ращают значение integer, если они заранее не объявлены. Обеспе-
чить эти объявления можно использовав библиотечные include-файлы,
содержащие объявления функций программы.

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

Идентификация функций и макро

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

 

Макроопределения Си аналогичны определениям функций: они принимают аргументы и возвращают значения. Важное преимущество применения макро - быстрое время их выполнения; определения макро расширяются на препроцессорной стадии. Поскольку перед компиляцией макро расширяются, т.е. заменя-
ются своими определениями, они увеличивают размер программ, особенно при многократном их использовании в программе. Каждое макро расширяется, в отличии от функции, которая определена только однажды, несмотря на многоразовость ее вызовов. Таким образом, функции и макро различаются по скорости и размеру. Во многих случаях библиотека Си обеспечивает версиимакро и функции, позволяю-
щие сделать выбор одной и той же библиотечной процедуры. Наиболее
важные различия между макро и функцией описаны ниже.

1) Некоторые макро не могут обрабатывать аргументы с побоч-
ными эффектами.

2) Идентификатор макро не обладает теми же свойствами, что
идентификатор функции. В частности, идентификатору макро не соот-
ветствует адрес, а идентификатору функции - соответствует. Поэто-
му в контексте нельзя использовать идентификатор макро, как со-
держимое указателя. Например, если идентификатор макро использу-
ется как аргумент вызова функции, то пересылается значение, возв-
ращаемое макро. Если же в качестве аргумента используется иденти-
фикатор функции, то пересылается адрес функции.


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

4) Библиотечные процедуры, выполняемые как макро, описыва-
ются при помощи препроцессорных директив в библиотечных
include-файлах. Для использования библиотеки макро необходимо
выбрать соответствующий файл, иначе макро не будет определен.


Пример:

#include <ctype.h>
int a='m';
a=toupper(a++);

В этом примере содержится процедура toupper из стандартной
библиотеки Си. Здесь процедура toupper выполняется как макро, ее
определение задано в <ctype.h>:

#define toupper (c)
((islower(c)? toupper(c):(c))



В приведенном определении используется условная операция
(?:). В условном выражении аргумент "c" вычисляется дважды: пер-
вый раз - если он задан буквой нижнего регистра, второй раз - при
возврате соответствующего значения. По этим причинам аргумент
"a++" также должен быть вычислен дважды. В результате значение
"a" должно увеличиться два раза и значение, выработанное по
islower, отличается от значения, выработанного по toupper. Не
все макро имеют такой побочный эффект. Для определения существо-
вания побочного эффекта нужно перед использованием макро подроб-
но рассмотреть его определение.

Include-файлы

Большинство процедур Си используют макро, определения конс-
тант и типов. Они задаются в отдельных include-файлах. Чтобы ис-
пользовать библиотечные процедуры, необходимо соединить специаль-
ный #include-файл (используя директиву препроцессора #include) с
компилируемым исходным файлом. Содержимое каждого include-файла
различно и зависит от специфики процедур. В общем include-файлы
содержат комбинации следующих величин:


1) Определений манифестных констант.


Например, константы BUFSIZЕ, определяющей размеры буфера для
операций буферизованного ввода/вывода. Сама константа определяет-
ся в include-файле <stdio.h>.


2) Определений типов.


Некоторые процедуры Си требуют в качестве аргументов струк-
туры данных или возвращают значения структурных типов. В
include-файлах задаются объявления этих структур. Например, боль-
шинство операций потокового ввода/вывода используют указатели на
структуру типа FILE, объявленную в файле <stdio.h>.


3) Двух множеств объявления функций.


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


4) Макро определений.

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

Объявление функций

Всякий раз, используя библиотечную функцию, возвращающую
значение любого типа, кроме int, нужно перед вызовом ее объяв-
лять. Для этого нужно в программу включить файл, содержащий объ-
явление требуемой функции. Каждый include-файл обеспечивает два
множества объявлений функций. Первое множество определяет типы
возврата и список типов аргументов функции.


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

char * calloc(); ,

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

char * calloc (unsigned,unsigned); .

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


Проверка типов аргументов

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


Каждая функция библиотеки Си объявлена в одном или более
include-файлах. Для каждой функции приводится два объявления: од-
но со списком типов аргументов и одно без него. Объявления функ-
ций задаются препроцессорным блоком #if define.
Ограниченная проверка типов может выполняться только для
функций, имеющих переменное число аргументов.

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

 


1) При вызове функций cprintf, cscanf, printf и scanf про-
верка типов аргументов выполняется только для первого аргумента,
т.е. для аргумента, определяющего формат строки.


2) При вызове функций fprintf, fscanf, sprintf и sscanf
проверка типов выполняется только для первых двух аргументов,
т.е. для аргумента, определяющего файл или буфер, и аргумента
формата строки.


3) При вызове open только два первых аргумента подлежат
проверке, т.е. path-имя и флаг открытия.


4) При вызове sopen первые три аргумента подлежат проверке,
т.е. path-имя, флаг открытия и распеделенный режим (sharing
mode).


5) При вызове execl, execle, execlp и execlpe проверка ти-
пов выполняется для первых двух аргументов: для path-имени и пер-
вого указателя на аргумент.


6) При вызове spawnl, spawnle, spawnlp и spawnlpe проверка
типов выполняется для первых трех аргументов: для флага режима,
path-имени и первого указателя на аргумент.

 

Обработка ошибок

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


Для каждой функции библиотеки Си определено ожидаемое зна-
чение возврата. Для некоторых функций ошибочный возврат по неко-
торым причинам может быть не определенным. Это возникает, напри-
мер, тогда, когда типы возврата верного значения и ошибочного
совпадают. Некоторые функции при возникновении ошибки устанавли-
вают значение типа ошибки в глобальную переменную errno. Заметим,
что нельзя установить переменную errno, пока в описании функции
эта переменная не будет явно определена.

При использовании функций, устанавливающих errno, можно сверить значение errno со значениями ошибок, определенных в include-файле <errno.h>, или же
использовать функции perror и strerror. Если нужно распечатать
сообщение о стандартной ошибке - используется perror; если сооб-
щение об ошибке нужно расположить в строке, то используется
strerror.


Чтобы убедиться в практической возможности появления ошиб-
ки, нужно перед доступом к errno проверить возвращаемое значение.
Если при этом возникла ошибка, то нужно использовать значение
errno или функцию perror. Ошибки в математических функциях под-
держиваются функцией matherr.


Ошибки в операциях с потоком проверяются функцией ferror.
Функция ferror обнаруживает, установлены ли индикаторы ошибки
данного потока. Индикатор ошибки автоматически сбрасывается, если
поток закрывается или выбрасывается, или вызывается функция
clearerr для обнуления индикатора ошибки. Ошибки в низкоуровневых
операциях ввода/вывода требуют установки переменной errno. Про-
верка конца файла (eof) данного потока осуществляется функцией
feof. В низкоуровневых операциях ввода/вывода конец файла обнару-
живается при помощи функции eof или когда операция считывания
возвращает 0 как число прочитанных байтов.

Имена файлов и path-имена

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

Категория: Программирование | Добавил: Admin (19.04.2012)
Просмотров: 3358 | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]

Поиск

Вход

Гость
  • Вход
  • Регистрация
  • Читаемое

    Заходи не жди