Страница 65 из 69
Буфер автоматически очищается при его заполнении, при созда-
нии потока и при нормальном завершении программы. Вы можете ис-
пользовать fflush и flushall для очистки буфера.
Обычно, вы используете потоки для чтения и записи данных
последовательно. Ввод-вывод располагается в текущей позиции фай-
ла. Когда вы записываете или считываете данные, программа переме-
щает файловую позицию непосредственно за обработанными данными.
Поток, который связан с дисковым файлом, может быть также потоком
произвольного доступа. Вы можете использовать fseek для позицио-
нирования файла, а затем результатом выполнения операторов чтения
или записи будет доступ к данным после этой точки.
- 535,536 -
Если вы одновременно записываете и считываете данные из по-
тока, то вы не можете свободно смешивать операторы чтения и запи-
си. Вы должны очистить буфер потока между записью и чтением. Вы-
зов fflush, flushall или fseek очищает буфер и позволяет вам сме-
нить операции. Для максимальной переносимости вы должны очищать
буфер, даже если он не используется, так как другие системы могут
иметь дополнительные ограничения на смешивание операций ввода-вы-
вода даже без буфера.
Предопределенные потоки
-----------------------------------------------------------------
В дополнение к потокам, создоваемым вызовом fopen, пять пре-
допределенных потоков доступны всякий раз, когда ваша программа
начинает исполнятся.
-------------------------------------------------------
Имя ввод-вывод Режим Поток
-------------------------------------------------------
stdin ввод Текстовый Стандартный ввод
stdout вывод Текстовый Стандартный вывод
stderr вывод Текстовый Стандартная ошибка
stdaux ввод-вывод Двоичный Вспом. ввод-вывод
stdprn вывод Двоичный Принтерный вывод
-------------------------------------------------------
Потоки stdaux и stdprn специфичны для DOS и не переносимы на
другие системы.
Потоки stdin и stdout могут быть перенаправлены DOS, в то
время как другие связаны с особыми устройствами: stderr - с кон-
- 537,538 -
солью (CON:), stdprn - с принтером (PRN:), а stdaux - со вспомо-
гательным портом.
Вспомогательный порт зависит от конфигурации вашей машины;
обычно это COM1:. Посмотрите в документации вашей DOS о перенап-
равлении ввода и вывода в командной строке DOS. Без перенаправле-
ния потоки stdin и stdout связаны с консолью (CON:). Кроме того,
если нет перенаправления, stdin имеет строку буфера, а stdout не
буферизируется. Другие предопределенные потоки тоже не буферизи-
руются.
Для установки предопределенного потока в режим отличный от
режима по умолчанию (например, для установки stdprn в текстовый
режим) используйте setmode. Имя предопределенного потока является
константой и вы не можете присваивать ему значения. Если вы хоти-
те связать один из этих потоков с файлом или устройством, то ис-
пользуйте freopen.
Программирование на Си: классический и современный стили
----------------------------------------------------------------
В программировании на Си существует несколько общераспрост-
раненных тенденций, объединяющих известные технические приемы,
облегчающие использование Си. Многие из этих тенденций противоре-
чат классическим традициям и методам программирования на Си.
Большинство из них стали возможны благодаря расширению языка ANSI
C Standart Committee. Этот раздел ознакомит вас с приемами, ис-
пользуемыми ранее и новыми стандартами, которые помогут вам в на-
писании более удобных программ на Си.
Турбо Си позволяет следовать наравне классическому и совре-
менному стилям.
- 539,540 -
Использование прототипов функций
и полных определений функций
-----------------------------------------------------------------
В классическом стиле программирования на Си вы определяете
функцию, специфицируя имя и тип возвращаемого результата.
Например, вы определяете функцию swap следующим образом:
int swap();
Никакой информации о параметрах не передается: ни о коли-
честве их, ни о типе. Классическое определение функции выглядит
так:
int swap(a,b)
int *a, *b;
{
/* Тело функции */
}
Результат такого определения - отсутствие контроля над ошиб-
ками при использовании параметров, что приводит к появлению хит-
рых и труднообнаружимых ошибок.
Избегайте такого стиля.
Современный стиль включает использование прототипов функций
(для описания функций) и списка параметров (для определения функ-
ций). Давайте переопределим swap, используя прототипы:
int swap(int *a, int *b);
Теперь при выполнении ваша программа получает всю необходи-
мую информацию, требуемую для выполнения контроля над ошибками
при любом обращении к swap. Теперь вы можете использовать простой
формат и при определении функции:
int swap(int *a, int *b)
{
/* тело функции */
}
Современный стиль программирования повышает вероятность об-
- 541,542 -
наружения ошибки, даже если вы не используете прототипов функций;
если же вы используете прототипы, то компилятор автоматически от-
слеживает и обеспечивает соответствие описаний и определений.
Использование ключевого слова enum
-----------------------------------------------------------------
В классическом языке Си списки определяются директивой
#define следующим образом:
#define sun 0
#define mon 1
#define tues 2
#define wed 3
#define thur 4
#define fri 5
#define sat 6
Однако в нашей версии Си введен так называемый перечислимый
тип данных, который вы можете объявить с помощьдю ключевого слова
enum, как это показано далее:
typedef enum(sun,mon,tues,wed,thur,fri,sat) days;
Результат здесь тот же, что и в классическом методе: присво-
ение осуществляется в порядке возрастания значений от sun=0 до
sat = 6. Однако современный метод позволяет представлять информа-
цию более абстрактно и содержательно, чем длинный список директив
#define. Кроме того, вы можете описать переменные принадлежащими
к абстрактному типу данных days.
Использование директивы typedef
-----------------------------------------------------------------