Вывод односвязного динамического списка - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Размер структуры cell - 20 байт. (см. программу ниже). Т.е. при выделении памяти под новый элемент списка к каждому адресу будет прибавляться +20, прим.: 00641730, 00641750, 00641770 и т.д. Пусть список уже сформирован в памяти и нам осталось только вывести его не экран. Тогда, если выполнить операцию rex++; (rex - указатель для перебора адресов элементов списка) то, по аналогии с перебором элементов статического массива, должен произойти переход к адресу следующего элемента, т.е. указатель rex должен бы получить значение адреса следующего звена списка, но этого не проиходит. При выполнении программы он почему-то изменяет значение не на 20, а на 14 и все данные выводятся неправильно.

Что не так в этом примере? В чём моя ошибка? Помогите разобраться.

Листинг программы
  1. // ПРИМЕР. Напечатать список
  2. printf("\nСодержимое списка: ");
  3. rex=beg; /* вернули курсор rex к началу - адресу первого элемента списка */
  4. while(rex<=end)
  5. {
  6. printf("\nsign=%s\tweight=%d",rex->sign,rex->weight);
  7. printf(" rex=%p rex->pc=%p beg=%p end=%p ",rex,rex->pc,beg,end);
  8. rex++; /* переход к следующему адресу звена списка */
  9. }
Листинг программы
  1. // ПРОГРАММА. Односвязный динамический список
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <locale.h>
  5. /* Определение структурного типа "Звено списка" */
  6. struct cell {
  7. char sign[10]; // 10 байт
  8. int weight; // 4 байта
  9. struct cell * pc; // размер 6 байт
  10. }; // общий размер 20 байт
  11. int main()
  12. {
  13. setlocale(LC_ALL,"Rus");
  14. struct cell * rex;
  15. struct cell * beg = NULL; /* начало списка */
  16. struct cell * end = NULL; /* конец списка */
  17. printf("\nВведите значения структур: \n");
  18. /* Цикл ввода и формирования списка */
  19. do
  20. { /* Выделить память для очередного звена списка */
  21. rex = (struct cell *) malloc (sizeof(struct cell));
  22. printf("rex=%p beg=%p end=%p rex->pc = %p\n",rex,beg,end,rex->pc);
  23. /* Ввести значения элементов звена: */
  24. printf("sign = ");
  25. scanf("%s",&rex->sign);
  26. printf("weight = ");
  27. scanf("%d",&rex->weight);
  28. if (rex->weight == 0)
  29. {
  30. free(rex);
  31. break; /* Выход из цикла ввода списка */
  32. }
  33. /* Включить звено в список */
  34. if (beg==NULL && end==NULL) /* Если список пуст, то */
  35. beg = rex; /* сохранить адрес первого звена списка в beg */
  36. else
  37. end->pc=rex; /* включить звено (2-й элемент и далее) в уже существующий список
  38. указателю pc предыдущего эл-та присвоить адрес на следующий эл-т */
  39. end=rex; /* теперь end указывает на текущий элемент списка */
  40. end->pc=NULL; /* pc последнего звена будет указывать на NULL - признак конца списка */
  41. printf("end->pc = %p rex = %p end = %p rex->pc = %p\n",end->pc,rex,end,rex->pc);
  42. printf("-----------------------------------------------------------\n");
  43. }
  44. while(1); /* Конец цикла ввода списка */
  45. /* Напечатать список */
  46. printf("\nСодержимое списка: ");
  47. rex=beg; /* вернули курсор rex к началу - адресу первого элемента списка */
  48. while(rex!=NULL)
  49. {
  50. printf("\nsign=%s\tweight=%d",rex->sign,rex->weight);
  51. printf(" rex=%p rex->pc=%p beg=%p end=%p ",rex,rex->pc,beg,end);
  52. rex=rex->pc; /* переход к следующему адресу звена списка через указатель pc */
  53. }
  54. rex = beg;
  55. while (rex<end)
  56. {
  57. printf("%p\n",rex++);
  58. }
  59. system("PAUSE");
  60. return EXIT_SUCCESS;
  61. }

Решение задачи: «Вывод односвязного динамического списка»

textual
Листинг программы
  1. // Изменение значения указателя на звено списка
  2. struct cell {поля_данных; struct cell *pc;} *beg,*end, *ptr;
  3. . . .
  4. // список сформирован:
  5. // beg==адрес_1-го_звена_готового_списка
  6. // end==адрес_последнего_звена_готового_списка
  7. ptr=beg; // ptr указывает на адрес первого элемента, напр.: FF10
  8. ptr++; // должен произойти переход к следующему значению: значение ptr - FF30

Объяснение кода листинга программы

  1. Указатель beg инициализируется значением адрес_1-го_звена_готового_списка.
  2. Указатель end инициализируется значением адрес_последнего_звена_готового_списка.
  3. Указатель ptr инициализируется значением beg.
  4. Указатель ptr инкрементируется на единицу, что должно привести к переходу к следующему звену списка.
  5. Значение ptr должно измениться на адрес_следующего_звена_списка, например, FF30.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

14   голосов , оценка 3.929 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы