Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Основные операции над двунаправленными списками




Ну, перед тем, как проводить какие-то операции с компонентами, их необходимо добавить в список, чем мы

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

часть. Так как мы будем помещать его в конец списка, то ссылочная часть узла будет иметь значение NULL.

Теперь давайте поймем, что должно происходить со ссылками head и tail при этой операции. Здесь

рассматриваются 2 случая - наш список пуст или в нем есть хотя бы один компонент. Если пуст, то и head и tail

будут указывать на только что созданный компонент. Если же узлы в списке присутствуют, очевидно, что сначала

нужно последний узел связать с добавляемым (для этого ссылочной части компонента, на который указывает tail,

присвоить адрес того, который хотим добавить), а затем "передвинуть" tail. Вот как просто все это выглядит на

С++:

// Включение в список нового компонента

void comp_in(dyn_list &l, char* n, char* v)

{

comp* c = new comp();

strcpy_s(c->name, 20, n);

strcpy_s(c->value, 10, v);

c->next = NULL;

if (chk_empty(l))

l.head = c;

else

l.tail->next = c;

l.tail = c;

}

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

значению. В качестве аргументов, функции поиска передаем сам список и искомый текст. Возвращать наша

функция будет адрес найденного узла или NULL, если ничего не найдено. Искать начнем с компонента, на

который указывает head и, двигаясь вперед, сравнивать имя текущей переменной с искомым. В функции поиска

мы можем не боясь, передвигать ссылку head, так как передаем ее не по ссылке.

// Поиск компонента в списке по имени

comp* search(dyn_list l, char *n)

{

while (l.head!= NULL)

{

if (!strcmp(l.head->name,n))

return l.head;

l.head = l.head->next;

}

return l.head;

}

А сейчас удалим компонент. В качестве аргумента, передаем по ссылке список, а также ссылку на компонент,

который собираемся удалить. В самой же функции рассматриваем 2 случая. Первый случай простой: если

компонент является первым (то есть на него указывает head), то достаточно лишь переместить ссылку на первый

элемент вперед. В противном случае, нам понадобится рабочая переменная-узел, которую мы будем

использовать для движения по списку. Двигаться будем до тех пор, пока следующий за текущим узел не будет

тем, который мы собираемся удалить. Ну а после этого, "перепрыгиваем" удаляемый компонент, присваивая

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

умещаются буквально в несколько строк исходного кода:

// Удаление компонента из списка

void comp_del(dyn_list &l, comp* c)

{

if (c == l.head)

{

l.head = c->next;

return;

}

comp* r = new comp();

r = l.head;

while (r->next!= c)

r = r->next;

r->next = c->next; delete c;

}

Последняя и самая простая операция - это изменение значения информационной части узла. Менять будем поле

value. В качестве параметров, по ссылке передадим адрес компонента, а также новое значение изменяемого

поля. Ну и в одну строчку все изменим. Вот как просто это выглядит:

// Изменение значения компонента

void comp_edit(comp &c, char* v)

{

strcpy_s(c.value, 10, v);

}

Инициализация структур

struct klass {
char name[20];
char klass_name;
float bal;
};

Struct

Любая структура в языке си (c) должна начинаться с ключевого слова - struct, которое сообщает компилятору, что тут у нас будет структура. Все данные в структуре (struct) пишутся в фигурных скобках, и в конце ставится запятая с точкой (;). Советую сразу ставить запятую с точкой, что бы не было ошибок.

Как вы видите, в структуре (struct) у нас находятся данные различных типов, но они объединены в логическую связь, так как в моем примере они являются определенным школьным классом. Данные в структуре должны иметь уникальные имена, но в различных структурах можно использовать одинаковые названия.

Структура, которая создана выше не занимает в памяти компьютера места, так как мы, на самом деле, просто создали свой тип данных. Объявление структуры ни чем не отличается от объявления любого типа данных в языке си (c). Вот пример:

Объединения

Объединение – это облась памяти, которая используется для хранения переменных разных типов. Объединение позволяет интерпретировать один и тот же набор битов по разному. Объединение похоже на

структуру и в своем описании отличается от структуры тем, что вместо ключевого слова struct используется

слово union.

union имя_типа {определения_элементов};

Объединение отличается от структуры способом организации во внутренней памяти. Все элементы объединения в памяти начинаются с одного байта.

Объединение занимает столько памяти, сколько нужно для самого большого из его полей. Объединение иницилизируется по 1 полю.по этому порядок важен.

38)Открытие потока ввода-вывода,

Файл открывается при помощи fopen, которая возвращает информацию потока ввода-вывода, прикрепленного к указанному файлу или другому устройству, с которого идет чтение (или в который идет запись). В случае неудачи функция возвращает нулевой указатель.

Схожая функция freopen библиотеки Си выполняет аналогичную операцию после первого закрытия любого открытого потока, связанного с ее параметрами.

Они определяются как

FILE *fopen(const char *path, const char *mode);FILE *freopen(const char *path, const char *mode, FILE *fp);

Параметр mode (режим) для fopen и freopen должен быть строковый и начинаться с одной из следующих последовательностей:

режим Описание начинает с..
r rb   открывает для чтения начала
w wb   открывает для записи (создает файл в случае его отсутствия). Удаляет содержимое и перезаписывает файл. начала
a ab   открывает для добавления (создает файл в случае его отсутствия) конца
r+ rb+ r+b открывает для чтения и записи начала
w+ wb+ w+b открывает для чтения и записи. Удаляет содержимое и перезаписывает файл. начала
a+ ab+ a+b открывает для чтения и записи (добавляет в случае существования файла) конца

Значение «b» зарезервировано для двоичного режима С. Стандарт языка Си описывает два вида файлов — текстовые и двоичные — хотя операционная система не требует их различать (однако, для некоторых компиляторов, например LCC, указание 'b' при работе с бинарным файлом принципиально важно!). Текстовый файл — файл, содержащий текст, разбитый на строки при помощи некоторого разделяющего символа окончания строки или последовательности (в Unix — одиночный символ перевода строки; в Microsoft Windows за символом перевода строки следует знак возврата каретки). При считывании байтов из текстового файла, символы конца строки обычно связываются (заменяются) с переводом строки для упрощения обработки. При записи текстового файла одиночный символ перевода строки перед записью связывается (заменяется) с специфичной для ОС последовательностью символов конца строки. Двоичный файл — файл, из которого байты считываются и выводятся в «сыром» виде без какого-либо связывания (подстановки).

При открытом файле в режиме обновления ('+' в качестве второго или третьего символа аргумента обозначения режима) и ввод и вывод могут выполняться в одном потоке. Тем не менее, запись не может следовать за чтением без промежуточного вызова fflushили функции позиционирования в файле (fseek, fsetpos или rewind), а чтение не может следовать за записью без промежуточного вызова функции позиционирования в файле. [1]

Режимы записи и добавления пытаются создать файл с заданным именем, если такого файла еще не существует. Как указывалось выше, если эта операция оканчивается неудачей, fopen возвращает NULL.

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...