Вывод односвязного динамического списка - C (СИ)
Формулировка задачи:
Размер структуры cell - 20 байт. (см. программу ниже). Т.е. при выделении памяти под новый элемент списка к каждому адресу будет прибавляться +20, прим.: 00641730, 00641750, 00641770 и т.д. Пусть список уже сформирован в памяти и нам осталось только вывести его не экран. Тогда, если выполнить операцию rex++; (rex - указатель для перебора адресов элементов списка) то, по аналогии с перебором элементов статического массива, должен произойти переход к адресу следующего элемента, т.е. указатель rex должен бы получить значение адреса следующего звена списка, но этого не проиходит. При выполнении программы он почему-то изменяет значение не на 20, а на 14 и все данные выводятся неправильно.
Что не так в этом примере? В чём моя ошибка? Помогите разобраться.
Листинг программы
- // ПРИМЕР. Напечатать список
- printf("\nСодержимое списка: ");
- rex=beg; /* вернули курсор rex к началу - адресу первого элемента списка */
- while(rex<=end)
- {
- printf("\nsign=%s\tweight=%d",rex->sign,rex->weight);
- printf(" rex=%p rex->pc=%p beg=%p end=%p ",rex,rex->pc,beg,end);
- rex++; /* переход к следующему адресу звена списка */
- }
Листинг программы
- // ПРОГРАММА. Односвязный динамический список
- #include <stdio.h>
- #include <stdlib.h>
- #include <locale.h>
- /* Определение структурного типа "Звено списка" */
- struct cell {
- char sign[10]; // 10 байт
- int weight; // 4 байта
- struct cell * pc; // размер 6 байт
- }; // общий размер 20 байт
- int main()
- {
- setlocale(LC_ALL,"Rus");
- struct cell * rex;
- struct cell * beg = NULL; /* начало списка */
- struct cell * end = NULL; /* конец списка */
- printf("\nВведите значения структур: \n");
- /* Цикл ввода и формирования списка */
- do
- { /* Выделить память для очередного звена списка */
- rex = (struct cell *) malloc (sizeof(struct cell));
- printf("rex=%p beg=%p end=%p rex->pc = %p\n",rex,beg,end,rex->pc);
- /* Ввести значения элементов звена: */
- printf("sign = ");
- scanf("%s",&rex->sign);
- printf("weight = ");
- scanf("%d",&rex->weight);
- if (rex->weight == 0)
- {
- free(rex);
- break; /* Выход из цикла ввода списка */
- }
- /* Включить звено в список */
- if (beg==NULL && end==NULL) /* Если список пуст, то */
- beg = rex; /* сохранить адрес первого звена списка в beg */
- else
- end->pc=rex; /* включить звено (2-й элемент и далее) в уже существующий список
- указателю pc предыдущего эл-та присвоить адрес на следующий эл-т */
- end=rex; /* теперь end указывает на текущий элемент списка */
- end->pc=NULL; /* pc последнего звена будет указывать на NULL - признак конца списка */
- printf("end->pc = %p rex = %p end = %p rex->pc = %p\n",end->pc,rex,end,rex->pc);
- printf("-----------------------------------------------------------\n");
- }
- while(1); /* Конец цикла ввода списка */
- /* Напечатать список */
- printf("\nСодержимое списка: ");
- rex=beg; /* вернули курсор rex к началу - адресу первого элемента списка */
- while(rex!=NULL)
- {
- printf("\nsign=%s\tweight=%d",rex->sign,rex->weight);
- printf(" rex=%p rex->pc=%p beg=%p end=%p ",rex,rex->pc,beg,end);
- rex=rex->pc; /* переход к следующему адресу звена списка через указатель pc */
- }
- rex = beg;
- while (rex<end)
- {
- printf("%p\n",rex++);
- }
- system("PAUSE");
- return EXIT_SUCCESS;
- }
Решение задачи: «Вывод односвязного динамического списка»
textual
Листинг программы
- // Изменение значения указателя на звено списка
- struct cell {поля_данных; struct cell *pc;} *beg,*end, *ptr;
- . . .
- // список сформирован:
- // beg==адрес_1-го_звена_готового_списка
- // end==адрес_последнего_звена_готового_списка
- ptr=beg; // ptr указывает на адрес первого элемента, напр.: FF10
- ptr++; // должен произойти переход к следующему значению: значение ptr - FF30
Объяснение кода листинга программы
- Указатель
beg
инициализируется значениемадрес_1-го_звена_готового_списка
. - Указатель
end
инициализируется значениемадрес_последнего_звена_готового_списка
. - Указатель
ptr
инициализируется значениемbeg
. - Указатель
ptr
инкрементируется на единицу, что должно привести к переходу к следующему звену списка. - Значение
ptr
должно измениться наадрес_следующего_звена_списка
, например,FF30
.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д