//
, унаследованные от его предшественника, языка BCPL, когда мне надоело печатать комментарии вида /* ... */
. Комментарии //
приняты в большинстве диалектов языка, включая версию C99, поэтому их можно использовать совершенно безопасно. В наших примерах мы будем использовать комментарии вида /* ... */
исключительно для того, чтобы показать, что мы пишем программу на языке C. В языке C99 реализованы некоторые возможности языка C++ (а также некоторые возможности, несовместимые с языком С++), но мы будем придерживаться версии C89, поскольку она используется более широко.
27.1.3. Стандартная библиотека языка С
• Класс vector
.
• Класс map
.
• Класс set
.
• Класс string
.
• Алгоритмы библиотеки STL: например, sort()
, find()
и copy()
.
• Потоки ввода-вывода iostream
.
• Класс regex
.
Из-за этого библиотеки языка С часто основаны на массивах, указателях и функциях. К основной части стандартной библиотеки языка С относятся следующие заголовочные файлы.
•
. Общие утилиты (например, malloc()
и free()
; см. раздел 27.4).
•
. Стандартный механизм ввода-вывода; см. раздел 27.6.
•
. Манипуляции со строками и памятью в стиле языка C; см. раздел 27.5.
•
. Стандартные математические функции для операций над числами с плавающей точкой; см. раздел 24.8.
•
. Коды ошибок математических функций из заголовочного файла
; см. раздел 24.8.
•
. Размеры целочисленных типов; см. раздел 24.2.
•
. Функции даты и времени; см. раздел 26.6.1.
•
. Условия для отладки (debug assertions); см. раздел 27.9.
•
. Классификация символов; см. раздел 11.6.
•
. Булевы макросы.
Полное описание стандартной библиотеки языка С можно найти в соответствующем учебнике, например в книге K&R. Все эти библиотеки (и заголовочные файлы) также доступны и в языке С++.
27.2. Функции
В языке C есть несколько особенностей при работе с функциями.
• Может существовать только одна функция с заданным именем.
• Проверка типов аргументов функции является необязательной.
• Ссылок нет (а значит, нет и механизма передачи аргументов по ссылке).
• Нет функций-членов.
• Нет подставляемых функций (за исключением версии C99).
• Существует альтернативный синтаксис объявления функций.
Помимо этого, все остальное мало отличается от языка С++. Изучим указанные отличия по отдельности.
27.2.1. Отсутствие перегрузки имен функций
Рассмотрим следующий пример:
void print(int); /* печать целого числа */
void print(const char*); /* печать строки */ /* ошибка! */
Второе объявление является ошибкой, потому что в программе, написанной на языке С, не может быть двух функций с одним и тем же именем. Итак, нам необходимо придумать подходящую пару имен.
void print_int(int); /* печать целого числа int */
void print_string(const char*); /* печать строки */
Иногда это свойство называют преимуществом: теперь вы не сможете случайно использовать неправильную функцию для вывода целого числа! Очевидно, что нас такой аргумент убедить не сможет, а отсутствие перегруженных функций усложняет реализацию идей обобщенного программирования, поскольку они основаны на семантически похожих функциях, имеющих одинаковые имена.
27.2.2. Проверка типов аргументов функций
Рассмотрим следующий пример:
int main()
{
f(2);
}
f()
может находиться где-то в другом месте. Кроме того, функция f()
может находиться в другом модуле компиляции, в противном случае редактор связей сообщит об ошибке.
К сожалению, это определение в другом исходном файле может выглядеть следующим образом:
/* other_file.c: */
int f(char* p)
{
int r = 0;
while (*p++) r++;
return r;
}
Редактор связей не сообщит об этой ошибке. Вместо этого вы получите ошибку на этапе выполнения программы или случайный результат.