Вывод односвязного динамического списка - 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
.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д