Пример: обработка связного списка

Пример: обработка связного списка

Если осуществима передача необязательных данных, мы можем расширить возможности указателей в XDR и использовать их для кодирования и декодирования связных списков, содержащих произвольное количество элементов. В нашем примере используется связный список пар имя-значение. Соответствующий файл спецификации XDR приведен в листинге 16.21.

Листинг 16.21. Спецификация XDR для связного списка пар имя-значение

//sunrpc/xdr1/opt2.x

1 struct mylist {

2  string name<>;

3  long value;

4  mylist *next;

5 };

6 struct args {

7  mylist *list;

8 };

1-5 Структура mylist содержит одну пару имя-значение и указатель на следующую структуру такого типа. Указатель в последней структуре списка будет нулевым.

В листинге 16.22 приведен текст заголовочного файла, созданного программой rpcgen из файла opt2.х.

Листинг 16.22. Заголовочный файл, созданный программой rpcgen

//sunrpc/xdr1/opt2.h

7  struct mylist {

8   char *name;

9   long value;

10  struct mylist *next;

11 };

12 typedef struct mylist mylist;

13 struct args {

14  mylist *list;

15 };

16 typedef struct args args;

В листинге 16.23 приведен текст программы, инициализирующей связный список с тремя парами имя-значение и кодирующей его с помощью библиотеки XDR.

Листинг 16.23. Инициализация, кодирование связного списка и вывод результата

1  //sunrpc/xdr1/opt2.c

2  #include "unpipc.h"

3  #include "opt2.h"

4  int

5  main(int argc, char **argv)

6  {

7   int i;

8   XDR xhandle;

9   long *lptr;

10  args out; /* структура, которую мы заполняем */

11  char *buff; /* результат кодирования */

12  mylist nameval[4]; /* до четырех элементов в списке */

13  size_t size;

14  out.list = &nameval[2]; /* [2] –> [1] –> [0] */

15  nameval[2].name = "name1";

16  nameval[2].value = 0x1111;

17  nameval[2].next = &nameval[1];

18  nameval[1].name = "namee2";

19  nameval[1].value = 0x2222;

20  nameval[1].next = &nameval[0];

21  nameval[0].name = "nameee3";

22  nameval[0].value = 0x3333;

23  nameval[0].next = NULL;

24  buff = Malloc(BUFFSIZE); /* адрес должен быть кратен 4 */

25  xdrmem_create(&xhandle, buff, BUFFSIZE, XDR_ENCODE);

26  if (xdr_args(&xhandle, tout) != TRUE)

27   err_quit("xdr_args error");

28  size = xdr_getpos(&xhandle);

29  lptr = (long*)buff;

30  for (i = 0; i < size; i += 4)

31   printf("%8lx ", (long)ntohl(*lptr++));

32  exit(0);

33 }

Инициализация связного списка

11-22 Мы выделяем память под четыре элемента, но инициализируем только три из них. Первая запись nameval[2], потом nameval[1] и nameval[0]. Указатель на начало списка (out.list) устанавливается на &nameval[2]. Мы инициализируем список в таком порядке, чтобы показать, что библиотека XDR обрабатывает указатели и порядок в списке оказывается именно таким, каким он был в нашей программе, и не зависит от того, какие массивы для этого используются. Мы также инициализируем значения элементов списка шестнадцатеричными величинами, поскольку будем выводить их в этом формате.

Вывод программы показывает, что перед каждым элементом списка идет значение 1 в 4 байтах (что мы можем считать длиной массива переменной длины с одним элементом или булевским значением TRUE). Четвертая запись состоит из 4 байт, в которых записан 0. Она обозначает конец списка:

solaris % opt2

1        дальше идет один элемент

5        длина строки

6e616d65 имя(name)

31000000 1 и три байта дополнения

1111     значение

1        один элемент

6        длина строки

6e616d65 имя

65320000 е 2 и 2 байта дополнения

2222     значение

1        один элемент

7        длина строки

6e616d65 имя

65653300 е е 3 и 1 байт дополнения

3333     значение

0        конец списка

При декодировании списка библиотека XDR будет динамически выделять память под его элементы и указатели и связывать все это вместе, что позволит легко переходить от одного элемента списка к другому в программе на С.

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

Управление памятью связного списка

Из книги Основы объектно-ориентированного программирования автора Мейер Бертран

Управление памятью связного списка Приведем пример подхода на уровне компонентов. Рассмотрим класс LINKED_LIST, описывающий список, состоящий из заголовка (header) и набора связанных ячеек, являющихся экземплярами класса LINKABLE. Модель размещения и удаления для связного списка


Пример: обработка ошибок

Из книги Системное программирование в среде Windows автора Харт Джонсон М

Пример: обработка ошибок В программе 1.2 было продемонстрировано использование лишь самых примитивных средств обработки ошибок, а именно, получение номера ошибки в переменной типа DWORD с помощью функции GetLastError. Вызов функции, а не просто получение глобального номера


Пример: обработка ошибок как исключений

Из книги C++ для начинающих автора Липпман Стенли

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


Пример: последовательная обработка файлов с использованием метода отображения

Из книги автора

Пример: последовательная обработка файлов с использованием метода отображения Программа atou (программа 2.4) иллюстрирует последовательную обработку файлов на примере преобразования ASCII-файлов к кодировке Unicode, приводящего к удвоению размера файла. Этот случай является


Узлы связного списка

Из книги автора

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


Пример 9-6. arglist: Вывод списка аргументов с помощью переменных $* и $@

Из книги автора

Пример 9-6. arglist: Вывод списка аргументов с помощью переменных $* и $@ #!/bin/bash# Вызовите сценарий с несколькими аргументами, например: "один два три".E_BADARGS=65if [ ! -n "$1" ]then echo "Порядок использования: `basename $0` argument1 argument2 и т.д." exit $E_BADARGSfiechoindex=1echo "Список аргументов в переменной "$*":"for arg in


Пример 10-2. Цикл for с двумя параметрами в каждом из элементов списка

Из книги автора

Пример 10-2. Цикл for с двумя параметрами в каждом из элементов списка #!/bin/bash# Список планет.# Имя кажой планеты ассоциировано с расстоянием от планеты до Солнца (млн. миль).for planet in "Меркурий 36" "Венера 67" "Земля 93" "Марс 142" "Юпитер 483"do set -- $planet # Разбиение переменной "planet" на


Пример 10-4. Обработка списка файлов в цикле for

Из книги автора

Пример 10-4. Обработка списка файлов в цикле for #!/bin/bash# list-glob.sh: Создание список файлов в цикле for с использованием# операции подстановки имен файлов ("globbing").echofor file in *do ls -l "$file" # Список всех файлов в $PWD (текущем каталоге). # Напоминаю, что символу "*" соответствует любое имя


Пример 10-6. Создание списка аргументов в цикле for с помощью операции подстановки команд

Из книги автора

Пример 10-6. Создание списка аргументов в цикле for с помощью операции подстановки команд #!/bin/bash# уЩЫЬ for гЯ [гаЩгЫЯЭ], гЯкФСЮЮйЭ г аЯЭЯниР аЯФгдСЮЯзЫЩ ЫЯЭСЮФ.NUMBERS="9 7 3 8 37.53"for number in `echo $NUMBERS` # for number in 9 7 3 8 37.53do echo -n "$number "doneecho exit 0Более сложный пример использования подстановки


Пример 12-20. Пример форматирования списка файлов в каталоге

Из книги автора

Пример 12-20. Пример форматирования списка файлов в каталоге #!/bin/bash# За основу сценария взят пример "man column".(printf "PERMISSIONS LINKS OWNER GROUP SIZE DATE TIME PROG-NAME " ; ls -l | sed 1d) | column -t# Команда "sed 1d" удаляет первую строку, выводимую командой ls,#+ (для локали "С" это строка: "total N",#+ где "N" -- общее


Пример 24-1. Проверка аргументов командной строки с помощью "И-списка"

Из книги автора

Пример 24-1. Проверка аргументов командной строки с помощью "И-списка" #!/bin/bash# "И-список"if [ ! -z "$1" ] && echo "Аргумент #1 = $1" && [ ! -z "$2" ] && echo "Аргумент #2 = $2"then echo "Сценарию передано не менее 2 аргументов." # Все команды в цепочке возвращают true.else echo "Сценарию передано менее 2


5.11. Пример связанного списка

Из книги автора

5.11. Пример связанного списка Мы завершали главы 3 и 4 примерами для введения читателя в механизм классов С++. В конце этого раздела мы покажем, как разработать класс, представляющий собой односвязный список. (В главе 6 мы рассмотрим двусвязный список, являющийся частью