Правила записи программы на языке Си 5 Правила формального описания синтаксиса языка программирования 6
Вид материала | Лекции |
- Правила преобразований из одного типа в другой и правила приведения типов в языке Object, 19.03kb.
- Оформление программы на языке Паскаль. Оператор вывода. Описание переменных. Оператор, 186.34kb.
- Программа наименование дисциплины Латинский язык (1,2 уровни), 154.48kb.
- Экзаменационные вопросы по курсу "Методы программирования", 32.44kb.
- Вопросы по курсу Программирование на языке высокого уровня (яву), 102.97kb.
- Структура программы в языке программирования С++. Обмен данными между функциями (параметры, 37.24kb.
- Программа курса " Азы программирования", 26.19kb.
- Структура программы языка Турбо Паскаль Программа на языке Турбо Паскаль имеет вид, 792.5kb.
- Эволюция языков программирования, 493.92kb.
- Структура программы на языке Turbo Pascal, 26.15kb.
15.3.Организация данных в виде стека.
Понятие стека ("магазина"): первый пришел, последний ушел.
LIFO (LAST IN FIRST OUT)
Описание стека как списка:
typedef struct _LIST {
info_t info; /* тип данных для информации */
struct _LIST *next;
} LIST;
В вызывающей функции стек должен быть описан так:
LIST *head = NULL; /* голова списка */
Действия со стеком определяется несколькими функциями:
- Помещение элемента в стек (в голову списка)
void add_head (LIST *head, info_t a)
{
LIST *t;
if (t=(LIST*) malloc (sizeof (LIST)))
{
t->info = a; /* 1 */
t->next = (*head); /* 2 */
(*head) = t; /* 3 */
}
}
t .......... 2
: 1 a : :
..........
......... ......... ..........
3 : : : : : : : :NULL:
......... ......... ..........
head 3
- Извлечение из стека (из головы списка)
info_t get_head (LIST *head)
{
LIST *t; info_t a;
if ( *head)
{
a = (*head)->info; /* 1 */
t = (*head); /* 2 */
(*head) = (*head)->next; /* 3 */
free (t);
}
return a;
}
t 2
.......... ......... ..........
: 1 a : : : : : : :NULL:
.......... ......... ..........
3
head 3
15.4.Организация данных в виде очереди.
Понятие очереди: первый пришел, первый ушел.
FIFO (FIRST IN FIRST OUT).
Описание очереди: такое же, что и стека, но надо хранить и начало и хвост очереди.
.......... ......... ..........
head : : : : : : : :NULL:
.......... ......... ..........
tail
Тогда в вызывающей программе очередь описывается так:
LIST *head = NULL, *tail = NULL;
Помещение элемента в очередь (в хвост списка):
1-ый элемент: head
3 ..........
: :NULL:
5 ..........
tail t
Остальные: ......... ......... .........
: : : : : : : : :
......... ......... .........
head 5 4
tail ...........
5 :1 a:NULL:
...........
t 2
void add_tail (LIST*head, LIST*tail, info_t a)
{
LIST*t;
if (t = (LIST*) malloc (sizeof (LIST)))
{
t->info = a; /* 1 */
t->next = NULL; /* 2 */
if (*head) == NULL) (*head) = t; /* 3 */
else (*tail)->next = t;/* 4 */
(*tail) = t; /* 5 */
}
}
15.5.Организация данных в виде деревьев.
Схематически данные в виде дерева можно представить в следующем виде:
root .
. .
. . . .
.
root
.....................
: : : :
.....................
.................. ............
: : : : : : : :
.................. ............
........... .......... .......... ..........
: : :0: : :0:0: : :0:0: : :0:0:
........... .......... .......... ..........
..............
: :0 :0 :
..............
Каждая вершина дерева представляет собой структуру, имеющую информационное поле и указатели поддеревья, исходящие из этой вершины. Максимальное количество поддеревьев, сходящихся в одной вершине, называется порядком дерева. В данном случае порядок дерева равен двум, т. е. изображено бинарное дерево.
Описать это дерево можно следующим образом:
typedef struct _NODE {
info_t info;
struct _NODE*left;
struct _NODE*right;
} NODE;
.
.
.
NODE *tree = NULL;
При организации работы с деревом программист с помощью функции malloc получает необходимые вершины дерева и, заполняя поля left и right, организует необходимые связи вершины дерева.
16.Библиотека ввода-вывода языка C.
Прототипы функций описаны в файле
- В C отсутствуют встроенные средства ввода-вывода. Весь ввод-вывод осуществляется через функции, находящеся в библиотеке и легко замещаемые.
- Каждый файл рассматривается как непрерывный поток байт (stream). Никакой внутренней структуры файла не поддерживается.
- Не делается никаких различий между файлами на дисках и на других внешних устройствах.
16.1.Открытие потока.
Перед работой с любым файлом его надо предворительно открыть, т. е. связать с некоторой структурой предопределенного типа FILE, в которой находится вся необходимая информация для работы с потоком. Открытие потока осуществляется с помощью функции fopen, которая в случае успешного завершения возвращает указатель на структуру типа FILE, а в случае аварии - NULL. Полный ее прототип:
FILE *fopen (const char *filename, const char *mode);
где, filename - строка символов, содержащая имя файла (полное или простое), записанное по правилам DOS;
mode - режим работы файла, тоже строка символов;
mode = "r" - открыть существующий файл для чтения;
"w" - создать файл для записи, информация из существующего файла теряется;
"a" - открытие для записи в конец существующего файла или создание для записи, если файла нет;
"r+" - открытие существующего файла для чтения и записи;
"w+" - создание нового файла для чтения и записи;
"a+" - откратие или создание для обновления в конец;
16.2.Закрытие потока.
После того как была выполнени вся работа с файлом, его необходимо закрыть. Это необходимо сделать по крайней мере по двум причинам:
- если программа обрабатывает большое количество файлов, то в конце концов может не хватить на все системных ресурсов;
- незакрытый файл может в случае сбоя пропасть.
Файл закрывается функцией:
int fclose (FILE *stream);
где, stream - указатель потока.
Функция возвращает 0 в случае успеха и EOF - если нет. EOF - (End Of File) - специальная константа из
Функция fcloseall закрывает все потоки:
int fcloseall (void);
В случае успеха функция возвратит количество закрытых потоков, иначе - EOF.
Если программист забыл закрыть какие-либо потоки, то все равно они будут закрыты системой MS DOS по завершению работы программы.
Типичный пример работы с файлом:
.
.
.
void main (void)
{
FILE *my_file; static char *fn = "d:\\USER\\f.dat";
.
.
.
if ((my_file = fopen (fn, "r")) == NULL)
{ printf ("Не могу открыть файл %s\n", fn);
return; }
.
.
.
fclose (my_file);
}
16.3.Предопределенные указатели потоков.
С началом выполнения C-программы автоматически открывается пять потоков. Их указатели имеют предопределенные имена и представляют константы типа указателя на структуру FILE.
stdin - стандартный поток ввода;
stdout - стандартный поток вывода;
stdprn - стандартный поток вывода на печать;
stdaux - стандартный дополнительный поток;
stderr - стандартный вывод сообщений об ошибке.
Имена этих потоков можно использовать везде, где допускаются имена потоков без предварительного открытия соответствующего потока.
Имеется целый ряд специальных функций работы со стандартными потоками ввода-вывода (в основном stdin и stdout). Мы их частично рассматривали (например, printf).
Поскольку указатели стандартных потоков являются константами, им нельзя присваивать значений. Но любой стандартный поток может прерываться с помощью функции freopen.
FILE *freopen (const char *fn, const char *mode, FILE *stream);
stream - указатель существующего потока, в том числе стандартного.
Функция возвращает stream в случае успеха, иначе - NULL.
Пример:
if (fopen ("d:\\a.std", "w", stdout) == NULL)
{ ... обработка ошибки открытия ... }
/* переназначение стандартного вывода на диск */
if (freopen ("CON", "w", stdout) == NULL)
{ ... обработка ошибки переназначения ... }
/* возврат стандартного вывода на консоль */
16.4.Функции ввода-вывода.
---------------------------------------------------------
Opens a stream
FILE *fopen(const char *filename, const char *mode);
Returns a pointer to the newly open stream if successful;
otherwise it returns NULL.
-------------