Читайте также: |
|
Для полноты описания следует отметить, что в языке С++ структуры можно передавать в функции по значению.
Возможно, в силу невозможности передачи параметров по ссылке, в зыке С нельзя передавать структуры в функции в качестве параметров. Вместо этого, естественно, можно передавать указатели на структуры. Ситуация с массивами выглядит несколько двусмысленно. С одной сторону, массивы, в чистом виде, передаются по ссылке (т.е. при указании массива в качестве параметров функции передается не копия массива а адрес его нулевого элемента), но, с другой стороны, если вспомнить, что массивы, по всем своим свойствам являются постоянными указателями, то все сразу становится ясным: передавая массив в качестве параметра, мы передаем указатель на нулевой элемент массива и, при этом, сам указатель передается по значению.
Для правильного понимания понятия `структура’ следует иметь представление о выравнивании в структурах. Имеется в виду следующее. При определении структуры гарантируется, что первый член структуры будет располагаться по адресу самой структуры и все члены структуры располагаются в памяти в порядке их расположения в структуре. Однако, размер структуры может не совпадать с суммой размеров членов структуры. Это объясняется тем, что, обычно, адреса всех элементов в структуре должны иметь определенную четность – т.е. они должны быть кратны одному из значений 1, 2, 4, 8 и т.д. Это значение определяет выравнивание элементов в структуре (Structure Alignment). Например, если создать структуру
struct SS{char a; int b;};
то, с большой вероятностью, по умолчанию, ее размер будет равен 8 (т.е. sizeof(struct SS) = = 8). Поведение по умолчанию, как правило, можно изменить с помощью соответствующих ключей компилятора. Но это можно сделать не на всех машинах и не на всех компиляторах.
Ссылочная реализация списков с фиктивным элементом
Алгоритмы работы со списком можно упростить, если использовать фиктивный элемент в списке. Фиктивный элемент будет играть роль разделителя между началом и концом списка. При этом, в качестве указателя на головной элемент списка будет выступать указатель на следующий элемент за фиктивным. В последнем элементе списка указатель на следующий элемент и в первом элементе указатель на предыдущий элемент должны указывать на фиктивный элемент. При этом, скорость работы алгоритмов повышается, но требуется память под лишний элемент списка.
Для локализации всех данных, относящихся к одному списку, можно завести следующую структуру
Typedef struct TList_
{
TList2 temp;
TList2 *current;
}TList;
В данном определении типа мы объединили определение типа struct TList_ и определение нового типа TList с помощью оператора typedef. При этом в большинстве реализаций языка С (но не во всех!!!) идентификатор TList_ можно вообще не писать.
В качестве инициализации списка можно использовать следующую функцию
void ListInit(TList *list)
{list->temp.next=list->temp.prev=&list->temp; list->current=&list->temp;}
Вставка элемента со значением value после текущего может быть произведена следующим образом:
TList2 *InsertData(int value, TList *list)
{
TList2 *New=(TList2 *)malloc(sizeof(TList2));
New->value = value;
New->next = list->current->next; New->prev=list->current;
list->current->next->prev = New; list->current ->next = New;
Return New;
}
Дата добавления: 2015-10-30; просмотров: 99 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Стандартная ссылочная реализация списков | | | Реализация L2-списка на основе двух стеков |