Отправляет email-рассылки с помощью сервиса Sendsay

[prg] удаление к элемента из односвязного списка

Здравствуйте.
Помогите с задачей, указанной в теме, пожалуйста.
Вот мой вариант:

#include <stdio.h>
#include<stdlib.h>
struct item
{
int data;
struct item* next;
};
void delete_items(struct item* head, int k)
{
struct item *cur;
cur =head;
struct item *s;
int i =1;
cur =head;
while (i <=k)
{
i++;
cur =cur->next;
}
s =cur->next;
free(cur);

cur =head;
do
{
printf("%d\n", cur->data);
cur =cur->next;
}
while (cur->next !=NULL);
}

int main (void)
{
struct item* head =malloc (sizeof(struct item));
head -> data =10;

delete_items(head, 2);
free (head);
free (head->next);
return 0;
}

Ответить   Mon, 27 May 2013 01:54:25 +0700 (#2753540)

 

Ответы:

Приветствую всех.

У меня есть пожелание для всех, кто публикует в рассылке свой исходный код и
просит помочь разобраться в нём: прежде чем помещать код в свое сообщение, откомпилируйте
его, устраните ошибки компиляции (какие сможете).
Если код компилируется без ошибок, то запустите и попробуйте отладить получившиеся
приложение. И только после того, как столкнетесь с действительно непреодолимым
препятствием, обращайтесь в рассылку за помощью.
Правилами рассылки не запрещается публиковать код и без всей вышеописанной процедуры,
но когда код крайне "сырой" и очевидно, что человек даже не пытался его скомпилировать,
то помогать такому халтурщику лично у меня желание пропадает.

Судя по коду функции, вы удаляете только один элемент. Если так, то имя функции
составлено неправильно -- множественное число тут неуместно.

Если это стандартный C (C89), то все используемые локальные переменные должны
быть описаны до первого оператора функции.

Зачем вы два раза выполняете cur =head;?

while можно заменить на for -- будет нагляднее:
for(i=1; i<k; ++i)
(Но это неправильный for. См. ниже)

Здесь нужна проверка, т.к. cur может содержать NULL.

Вы удалили cur в предыдущей строке, после чего cur превратился в "висящий" указатель,
то есть в том месте памяти, куда он указывает, находится "мусор". В зависимости
от того, как реализовано управление памятью в run-time C library, здесь может
проявиться ошибка, а может не проявиться.
Если ошибка не проявится здесь, то вы точно столкнетесь с ней при печати элементов
списка.
Кроме того, у вас здесь возникает разрыв списка: вы удалили элемент списка, но
не связали предыдущий и последующий элементы.
Иными словами "хвост" списка вы потеряли.

Во-первых, при таком условии последний элемент в списке никогда не будет напечатан.
Во-вторых, печать элементов списка не имеет отношения к удалению элемента, поэтому
не должно тут находиться.
Оформите печать элементов списка в виде отдельной функции и вызывайте её при
необходимости.
Главное правило при написании кода функции -- функция должна выполнять одно конкретное
действие (в соответствии со своим названием) и ничего больше.

Громоздкий код, а также повторяющиеся фрагменты одного и того же кода, это верный
признак плохого программирования. Здесь явно требуется оформить добавление элементов
списка по-другому. Например, использовать цикл и написать функцию добавления
элемента в список (например, add_item(struct item *headint data) и использовать
ее.

Если вы раньше оформили печать элементов списка как самостоятельную функцию,
то здесь как раз можно поместить ее вызов. Также печать элементов списка можно
сделать до вызова функции удаления элемента.

Вы удалили head, после чего head стал "висячим" указателем. Любое последующее
обращение к head вызовет ошибку доступа к памяти.
Перед удалением head надо было head->next сохранить во временной переменной.

Опять же, удаление всего списка тоже предпочтительнее оформить в виде самостоятельной
функции.

Успехов. Анатолий.

Ответить   "i_chay" Mon, 27 May 2013 08:00:10 +0300 (#2753643)