ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 31.03.2021
Просмотров: 6824
Скачиваний: 51
331
данный объект. При этом где-либо во внешних описаниях (т.е. вне определения функций) должно
быть расположено определение внешнего статического объекта в виде
static <Спецификация типа> <Спецификация данных>;
На основании определения под объект отводится память и может быть произведена ини-
циализация. Статические переменные можно инициализировать только выражениями с констан-
тами и с указателями на ранее описанные объекты.
При первом входе в соответствующую локальную область (блок или модуль) статические
переменные инициализируются один раз (по умолчанию - нулем). При последующих входах в
данную область статические переменные получают те значения, которые они имели при послед-
нем выходе из области.
По умолчанию все функции данного модуля, расположенные
ниже определения
статиче-
ского объекта, включаются в его область действия - в них не обязательно дополнительно описы-
вать объект для получения к нему доступа. Функции, определения которых расположены в модуле
выше определения внешнего статического объекта, для пол\чения доступа к нему должны содер-
жать описание этого объекта с классом памяти extern.
Константы являются объектами статического класса памяти.
Функция может быть определена как статический внешний объект. В этом случае она будет
доступной в любой точке данного мод\ля и не доступной за пределами модуля.
Программа 105
#include<stdio.h>
main()
(
int count;
int trystat () ;
for (count=l; count<=3; count++)
(
printf ("Итерация %d:\n", count);
trystat() ;
}
)
trystat ()
{
int fade=l;
static int stay=l;
printf("fade = %d и stay = %d\n", fade++, stay++) ;
}
Результат работы программы:
Итерация 1:
fade = 1 и stay = 1
Итерация 2:
fade = 1 и stay = 2
Итерация 3:
fade = 1 и stay = 3
Если мы лишь немного видоизменим в программе функцию trystat()
trystat()
{
int fade=l;
int stay=l;
printf("fade = %d и stay = %d\n", fade++, stay++);
}
332
то получим следующий результат:
Итерация 1:
fade = 1 и stay = 1
Итерация 2:
fade = 1 и stay = 1
Итерация 3:
fade = 1 и stay = 1
6.7. ФУНКЦИИ ВВОДA-ВЫВОДА
Средства ввода-вывода не являются составной частью языка Си. Имеется ряд библиотеч-
ных функций Си. обеспечивающих стандартною систему ввода-вывода для программ на Си. Мак-
роопределения, описания переменных и определения этих функций содержатся в файле стандарт-
ных заголовков stdio h Поэтому, как указывалось выше, каждая пользовательская программа
должна содержать в начале ссылку
#include <stdio.h>.
В примерах программ мы неоднократно использовали форматные функции ввода
(scanf())
и
вывода
(printf())
. Набор стандартных функций ввода и вывода значительно шире и включает
большое число функций для работы с данными различного типа, различными устройствами, бу-
феризованного и небуферизованного, форматного и бесформатного ввода и вывода.
Система ввода-вывода Си обеспечивает некоторый уровень абстракции между программи-
стом и используемым устройством. Эта абстракция называется потоком, а фактическое устройство
ввода-вывода называется файлом. Буферизованная файловая система преобразует каждое физиче-
ское устройство в логическое устройство,
называемое потоком. Существуют потоки двух типов:
текстовые и двоичные.
Текстовый поток - это последовательность символов, которая организуется в строки, за-
вершающиеся символами новой строки. Обработка текстового потока предполагает преобразова-
ние данных из текстового (внешнего) представления в машинное (внутреннее) или наоборот. При
обработке двоичного потока последовательность его байтов взаимно однозначно соответствует
байтам во внешнем устройстве.
В языке программирования Си файл - это логическое понятие, которое система может от-
носить к чему угодно (от дисковых файлов до терминалов). Поток связывается с конкретным фай-
лом выполнением операции «открыть» Как только файл открывается, можно обмениваться ин-
формацией между ним и программой. Закрытие выводимого потока заставляет ЭВМ записывать
содержимое этого потока на внешнее устройство Этот процесс обычно называется промыванием
потока. В начале выполнения программы ЭВМ открывает три предопределенных текстовых пото-
ка stdin, stdout и stderr, связанных со стандартными устройствами ввода-вывода (консоль - клавиа-
тура и дисплей). Допускается переадресация ввода-вывода к другим устройствам.
Простейшими функциями консольного ввода-вывод являются функция
getche(),
которая
читает символ с клавиатуры, и функция
putchar()
, которая печатает символ на экране. Функция
getche() ждет, пока не будет нажата клавиша, а затем возвращает ее значение, автоматически вы-
давая на экран «эхо» нажимаемой клавиши. Функция putchar() записывает ее символьный аргу-
мент на экран в текущую
позицию курсора.
Ниже приводится пример простой программы, которая принимает один символ с клавиату-
ры и выводит его на экран.
Программа 106
#include<stdio.h>
main()
(
char ch;
ch
=
getchar() ;
333
putchar(ch);
)
Есть две важные версии функции getche(). Первая –
getchar()
- буферирует ввод до тех пор,
пока не введен возврат каретки. Второй версией является функция
getch()
, которая работает точно
так же, как getchar(), за исключением того, что getch() не возвращает на экран эхо введенного сим-
вола.
Функции
gets()
и
puts()
позволяют читать и писать цепочки символов (строки) с консоли.
Функция gets() читает цепочку символов, которая вводится с клавиатуры (ввод оканчивается воз-
вратом каретки), помещает ее с адреса, который указывает ее аргумент - указатель символа. Функ-
ция puts() выводит на экран ее аргумент - цепочку символов, а затем символ новой строки. Напри-
мер, нижеследующая программа читает цепочку в массив str и тут же печатает ее.
Программа 107
main ()
(
char str[80] ;
gets (str) ;
puts(str) ;
)
Функция puts() занимает меньше памяти и работает быстрее, чем printf() при выводе сим-
вольных цепочек, поэтому программисты часто используют функцию puts() в тех случаях, когда
важно иметь высоко минимизированный
код.
Таблица 3.4
Некоторые функции буферизованной сисгемы ввода-вывода
Имя
Функция
fopen()
fclose()
putc()
getc()
fseek()
fprintf()
fscanfl()
feof()
ferror()
rewind()
remove()
Открывает поток
Закрывает поток
Выводит символ в поток
Вводит символ из потока
Ищет указанный байт в потоке
Форматный вывод в поток
Форматный ввод из потока
Возвращает истину, если достигается метка EOF (конец файла)
Возвращает истину, если встретилась ошибка
Устанавливает начальную позицию файла
Стирает файл
Для работы с файлами в Си используются функции буферизованной системы ввода-вывода,
табл. 3.4. Обращение к ним использует указатель файла, который определяет различные характе-
ристики файла, включая его имя, статус и текущую позицию; используется связанным с этим фай-
лом потоком для привязки каждой функции буферированного ввода-вывода к месту, над которым
она выполняет свои операции. Указатель файла является переменной типа FILE, которая опреде-
ляется в файле заголовков
stdio.h.
Функция
fopen()
вызывается так:
fореn(<имя_файла>, <режим>);
Имя файла должно быть цепочкой символов, которая составляет правильное имя файла для
334
операционной системы и может включать спецификацию пути. Режим задает желаемый статус от-
крытия, табл.3.5.
Таблица 3.5
Значения режимов в Турбо-Си
Режим
Смысл
"r"
"w"
"а"
"r+"
"w+"
''а+"
Открыть файл для чтения
Создать файл для записи
Добавлять в файл
Открыть файл для чтения/записи
Создать файл для чтения/записи
Открыть или создать файл для чтения/записи
Например, для того чтобы открыть файл с именем test для записи, можно написать
fp = fopen("test", "w");
где fp -переменная типа FILE*. Переменная fp является указателем файла.
Следующий оператор обнаруживает любую ошибку при открытии файла, такую, как, на-
пример, попытку открыть защищенный от записи диск или заполненный диск, прежде чем состо-
ится попытка записи на него:
if((fp = fopen("tesf, "w"))==NULL)
{
рuts("Нельзя открыть файл!\n");
exit(l);
}
NULL - это макро, которое определяется в файле заголовка stdio.h.
Функция
putc()
в виде
рuts(<символ>, fp);
используется для записи символа в поток, который предварительно открыт для записи с помощью
функции fopen(); fp - возвращаемый функцией fopen() указатель файла.
Функция
getc()
в виде
getc(fp)
используется для чтения символов, которые она возвращает из потока, открытого в режиме чтения
функцией fopen(). fp является указателем файла типа FILE, который возвращается функцией
fopen(). В тех случаях, когда достигается конец файла, функция getc() возвращает маркер его кон-
ца EOF. Например, для чтения текстового файла до маркера конца файла можно использовать сле-
дующие операторы:
ch = setc(fp);
while(ch!=EOF)
{
ch = getc(fp);
}
Функция
feof()
использует аргумент указателя-файла и возвращает 1, если достигнут конец
файла, или 0, если не достигнут. Например, приведенная ниже программа читает двоичный файл
335
до тех пор, пока ЭВМ не встречает маркер конца файла:
while(!feof(fp)) ch = getc(fp);
Функцию
fdose()
используют для закрытия потока, который был открыт с помощью функ-
ции foреn(). Все потоки необходимо закрыть перед завершением программы. Аргументом функ-
ции является указатель файла, который закрывается.
Функции foреn(), getc(), putc() и fdose() составляют минимальный набор функций ввода-
вывода. Простым примером использования функций putc(), foреn() и fdose() является программа,
которая приведена ниже. Эта программа просто читает символы с клавиатуры и записывает иx в
дисковый файл до тех пор, пока не введен знак $. Имя выходного файла задается из командной
строки. Например, если вы назовете программу ktod («клавиша - на диск»), то набор на клавиатуре
ktod test будет позволять вам вводить строки текста в файл с именем test.
Программа 108
#include .h"
main(argc,argv)
/*ktod - клавиша на диск */
int argc;
char *argv[];
(
FILE *fp;
char ch;
if(argc!=2)
{
printf("Bы забыли ввести имя файла\n);
exit(l);
)
if((fp=fopen(argv[l], "w"))== NULL)
(
printf("He может открыть файл\n);
exit(l);
}
do
(
ch = getchar();
putc(ch, fp);
)
while (ch!='s');
fclose (fp) ;
}
Еще одним примером является программа
dtos
, которая будет читать любой ASCII файл и
выводить его содержимое на экран.
Программа 109
#include "studio.h"
main (argc, argv)
/*dtos-wicK на экран*/
int argc;
char *argv[] ;
(
FILE *fp;
char ch;
if(argc!=2) {
printf("Вы забыли ввести имя файла\n"};
exit(l);
}
if((fp=fopen(argv[l], "r"))==NOLL)(
printfC'He может открыть файл\n"};