Файл: Могилев А.В. Информатика.pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 31.03.2021

Просмотров: 6824

Скачиваний: 51

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

 

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++); 

 


background image

 

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() ; 


background image

 

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(<имя_файла>, <режим>); 
 
Имя файла должно быть цепочкой символов, которая составляет правильное имя файла для 


background image

 

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, если не достигнут. Например, приведенная ниже программа читает двоичный файл 


background image

 

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"};