Лабораторный практикум по основам языка C/С++ |
Тема 2. Библиотеки функций
В Cи используются различные виды функций. Прежде всего это стандартные и библиотечные функции. Стандартные функции входят в стандартную библиотеку, поставляемую вместе с компилятором. К библиотечным относятся любые функции, описание и реализация которых находятся в библиотеках, не входящих в стандартный набор.
Библиотеки подключаются при помощи директивы препроцессора #include
. После директивы препроцессора указывается
имя библиотеки или имя заголовочного файла библиотеки. Имя заключается в угловые скобки (для стандартных библиотек)
или в двойные кавычки (для остальных библиотек).
Например, для того, чтобы подключить библиотеку математических функций необходимо в начале файла с исходным кодом указать следующую директиву:
#include <math.h>
А если библиотека располагается в том же каталоге, что и приложение (например библиотека mylib
), то подключение библиотеки будет выглядет следующим образом:
#include "mylib.h"
В угловых скобках или в двойных кавычках указывается имя специального заголовочного файла (расширение .h
образовано от английского слова header
– заголовок). В заголовочных файлах приводятся прототипы функций, а реализация, обычно, размещается в файле
с таким же именем, но расширение меняется на .c
Стандартные библиотеки
Каждая стандартная библиотека имеет свой собственный заголовочный файл, содержащий прототипы всех функций данной библиотеки, а также определения различных констант, типов данных и т.д., необходимых функциям.
Список некоторых стандартных библиотек функций
Заголовочный файл | Содержимое заголовочного файла |
---|---|
<ctype.h> |
Содержит прототипы функций, проверяющих различные характеристики символов, а также позволяющих выполнять преобразования символов. |
<errno.h> |
Содержит макросы, полезные для сообщений об ошибках. |
<float.h> |
Содержит пределы значений для чисел с плавающей точкой в системе |
<limits.h> |
Содержит пределы значений для целочисленных чисел в системе |
<locale.h> |
Содержит прототипы функций и другую информацию, которая позволяет изменять работу программы и параметры окружения в соответствии с указанными локальными (в смысле региона, страны) настройками: кодировка символов, представление чисел и т.д. |
<math.h> |
Содержит прототипы математических функций. |
<signal.h> |
Содержит прототипы функций и макросы для обработки различных условий, которые могут возникать во время работы программы. |
<stdarg.h> |
Определяет макросы обработки списка параметров функции, для которой неизвестно число параметров и их тип. |
<stddef.h> |
Содержит общие определения типов, используемых Си для выполнения некоторых вычислений. |
<stdio.h> |
Содержит прототипы функций ввода/вывода и информацию, используемую ими. |
<stdlib.h> |
Содержит прототипы функций преобразования чисел в текст и текста в число, прототипы функций размещения памяти, генерации случайных чисел и других сервисных функций. |
<string.h> |
Содержит прототипы функций обработки строк. |
<time.h> |
Содержит прототипы функций и типы данных для функций управления временем и датой. |
Библиотеки пользователя и заголовочные файлы
Обычно все библиотеки располагаются в каталогах, прописанных в служебных переменных LIB
или INCLUDE
или
в одном каталоге с основной программой.
Однако, если библиотека располагается в некотором специфическом месте, то вместе с именем следует указать полный путь к ней.
Следует отметить, что такая организация является не корректной, поскольку привязывается к текущему состоянию файловой системы.
Случайное удаление файла библиотеки или перенос исходных текстов на другую машину или даже просто в другой каталог могут привести к
невозможности сборки такой программы.
Макросы препроцессора
Существуют два типа макросов: макрос-объект(object-like macro)
и макрос-функция(function-like macro), оба типа объявляются
с помощью директивы #define
.
Рассмотрим сначала макросы-объекты. Объявляются они как:
#define ИМЯ_МАКРОСА [замещающий текст]
Всё, что идёт после имя макроса до конца строки является замещающим текстом.
При помощи макросов-объектов часто определяются константы или часто встречающиеся
последовательности переменных и аврифметических операторов:
Однако следует помнить, что макрос это просто подстановка а не переменная,
то есть везде где встречается символ N
при трансляции программы символ заменяется на его
то что в определении идет после имени, то есть в данном случае на число 10.
С одиночным символом это не страшно, но при использовании выражения может
получиться не верный результат. Например, если на каждом шаге цикла надо не только прибавлять
значение i
, но и увеличивать получившееся значение вдвое, то приведенный ниже код
даст ошибочный результат:
Второй вид макросов — это макро-функции (function-like macros).
Определяются они с помощью той-же директивы #define
,
после которой (сразу без пробелов) в круглых скобках идёт список
разделённых запятыми аргументов:
Важным моментом является то, что делитель x
также заключен в скобки.
Посмотрим, что будет если его не заключать в скобки...
Видно, что во втором случае результат не верный. Все объясняется тем, что макрос препроцессора это просто подстановка, а не функция. То есть при компиляции в строке 21 мы получаем следующее выражение:
val = (a + b + c)/(a+b+c)
А во втором случае (строка 24) получаем:
val = (a + b + c)/a+b+c
то есть периметр делится на длину стороны a
, а затем к результату деления
прибавляются длины сторон b
и c
.