ВВЕДЕНИЕ

2.3 Использование стандартных библиотек

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

Часть функций из библиотек времени выполнения стандартизована, в стандарте зафиксированы имя функции, ее назначение, перечень и типы параметров и тип возвращаемого значения. Другие функции ориентированы на конкретные модели ЭВМ и операционные системы, способы их вызова и использования могут быть различными в системах программирования разных фирм.

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

Ниже приведены имена некоторых файлов заголовков и назначение описанных в них прототипов групп функций.

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

ASSERT.H - Содержит макросы для сообщений об ошибках при выполнении условия, задаваемого программистом.

CTYPE.H - Функции для проверки и преобразования данных типа char.

FLOAT.H - Макросы для операций над числами с плавающей точкой.

LIMITS.H - Макросы, задающие диапазоны представления целых.

LOCALE.H - Представление даты, времени, денежных единиц.

MATH.H - Пакет стандартных математических функций.

SETJUMP.H - Имена типов и функции для реализации операторов перехода, используется редко.

SIGNAL.H - Макросы для сигнализации об ошибках согласно стандарта ANSI.

STDARG.H - Макросы для вызова функций с переменным числом аргументов.

STDDEF.H - Определение общих типов для указателей, типов size_t и NULL.

STDIO.H - Стандартные функции ввода-вывода.

STDLIB.H - Определение общих типов, переменных и функций.

STRING.H - Функции для операций над строковыми данными.

TIME.H - Структуры и функции для операций с датами и временем.

В Си++ добавлены операции с комплексными числами и десятичными данными:

BCD.H - Данные, представленные в десятичной системе счисления

COMPLEX.H - Функции и операции над комплексными числами.

Имеются также файлы прототипов функций для распределения и освобождения динамической памяти, использования средств DOS и BIOS.

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

# include < имя файла >

Например, для включения заголовка с функциями ввод-вывода в стиле Си в начале программы записывается строка

< include>

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

stdin - стандартный ввод,

stdout - стандартный вывод,

stderr - для вывода сообщений об ошибках,

stdprn - стандартное устройство печати,

stdaux - стандартный последовательный порт.

Потоки stdin, stdout и stderr обычно связываются с консолью, но могут быть переназначены на другие устройства. Назначение двух последних потоков зависит от используемой аппаратуры. Стандартные потоки автоматически открываются при запуске Си-программы и закрываются при ее завершении. Потоки, создаваемые программистом, открываются функцией fopen и закрываются функцией fclose.

Функции ввода-вывода из stdio.h условно можно разбить на четыре группы: ввод-вывод байтов, ввод-вывод строк, форматный ввод-вывод и так называемый прямой (бесформатный) ввод-вывод. Здесь отметим только отдельных представителей первых трех групп, предназначенных для ввода из потока stdin и вывода в поток stdout.

Функция int getchar( ) служит для ввода одного символа с клавиатуры и возвращает код символа, преобразованный к типу int. Функция int putchar (int c) выводит символ c в очередную позицию на экране монитора.

Для ввода строки с клавиатуры служит функции char * gets ( char * buf ), которая читает ввод с клавиатуры (до символа новой строки или нажатия клавиши Enter) и помещает коды прочитанных символов в буфер, адрес которого задается параметром buf, в конце строки добавляется нулевой байт. Вывод строки выполняет функции int puts ( char * string), которая выводит строку по адресу string на экран, пока в строке не встретится нулевой байт и возвращает код последнего выведенного символа.

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

d - для представления целого со знаком в десятичной системе счисления,

i - для представления целого без знака в десятичной системе счисления,

f - для представления числа с плавающей точкой в естественной форме,

e или E - представление числа с плавающей точкой в экспоненциальной форме,

s - ввод-вывод строковых данных,

c - ввод-вывод символов.

Для форматного вывода служит функция int printf ( char *format, ... ), имеющая список параметров переменной длины, количество дополнительных параметров должно соответствовать числу спецификаций формата в форматной строке, данные для вывода могут задаваться выражениями, ответственность за правильное задание спецификации формата для каждого выводимого данного полностью лежит на программисте. Пример применения функции printf:

printf ( "\n x = %d, y = %f %s", x, y, st);

При выполнении этой функции просматривается строка формата слева направо и символы не являющиеся спецификациями формата копируются на выводное устройство, управляющий символ \n переводит курсор на экране к началу следующей строки, когда встречается спецификация формата, выбирается очередной аргумент из списка вывода, преобразуется в соответствии с форматом и выводится в очередную позицию экрана. Для правильного вывода требуется, чтобы переменная x была типа int, y - типа float, а переменная st - типа char*.

Форматный ввод выполняет функция int scanf ( char *format, ...) в которой список ввода должен задавать указатели на вводимые переменные. Если в строке формата присутствуют символы, не входящие в спецификации форматов и не являющиеся пробельными, то во входном потоке должны присутствовать те же символы. Пробельными символами считаются знаки пробела, табуляции, новой строки, они считываются из потока ввода, но не участвуют в формировании входных данных. Когда в форматной строке встречается спецификация формата, во входном потоке пропускаются пробельные символы, а последующие символы интерпретируются в соответствии с типом формата, преобразуются во внутреннее представление и полученное значение записывается в память по адресу очередного элемента списка ввода. Например, для ввода двух переменных целого типа и одной вещественного типа можно применить оператора вызова функции

scanf ( "%d %d %f", &x1, &x2, &y );

Здесь x1 и x2 должны быть типа int, а y - типа float. Во входном потоке вводимые значения должны разделяться хотя бы одним пробелом.

Более полную информацию о функциях ввода-вывода в стиле Си можно получить в справочной системе интегрированной среды Borland C++.

Недостатком рассмотренных выше функций ввода-вывода является отсутствие контроля соответствия типов форматов и типов вводимых (выводимых) данных, часто приводящее к ошибкам в программах. В Си++ включены собственные средства потокового ввода-вывода, обеспечивающие жесткий контроль типов в операциях ввода-вывода. Для этого определены четыре новых стандартных потока:

cin - для ввода данных,

cout - для вывода данных,

cerr - вывод сообщений об ошибках без буферизации вывода,

clog - вывод сообщений об ошибках с буферизацией вывода.

В качестве знака операции вывода определены знаки << , а знаком операции ввода - знаки >>, те же, что и для операций сдвига. Компилятор по контексту определяет, какую операцию задают эти символы, ввод-вывод или сдвиг.

Чтобы использовать средства ввода-вывода Си++ в программу должен быть включен файл-заголовок iostream.h:

# include <iostream.h>

В операциях вывода левым операндом должен быть поток вывода, правым операндом - выводимое данное. Результатом операции вывода является поток вывода, что позволяет записывать вывод в виде цепочки операций <<, например,

cout << "x1 = " << x1 << " x2 = " << x2 << "\n";

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

В операции ввода левым операндом должен быть поток ввода, а правым операндом - имя вводимого данного для арифметических данных или указатель типа char* для ввода строк, например,

cin >> x1 >> x2 >>st ;

Операции ввода-вывода выполняются слева направо и последний оператор эквивалентен оператору ( (cin>> x1) >> x2) >> st; или трем операторам

cin >> x1; cin >> x2; cin >> st;

В заключение приведем пример простой программы, запрашивающей у пользователя два целых числа и выводящей на экран их сумму:

# include <iostream.h>

int x, y ;

int main ( )

{ cout << "x = "; cin >> x; // Запрос и ввод значения x

cout << "\n y = "; cin >> y; // Запрос и ввод значения y

cout << "\n" << " x + y = " << x + y;

return 0;

}