Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Правильно ли я понял суть, В данном случае касательно списков 
V
    Опции темы
ТРЕТЬ
  Дата 21.6.2006, 11:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 92
Регистрация: 8.1.2006
Где: mind's gloomy corner

Репутация: нет
Всего: 1



Заранее прошу войти в моё положение. (Если у кого-то достаточно доброе сердце, то следущие 3 обзаца можно пропустить)
Вообще, я в школе начал програмить на Си (чистом). Но это было так называемое "олимпиадное" программирование, которое даже скорее выявляло не программистов а математиков, пототму как нам объяснили только азы (стандартные переменные, функции, циклы... и вроде бы все). В школе как-то все равно было на каком языке пишешь, потому что уровень программирования все равно ниже плинтуса давался. 
Но вот, пошел в универ, а тут все преподают на паскале... Пробовал на паскале писать, но не смог - откровенно говоря, затошнило... продолжил писать на Си (уже к этому времени Си++, но как понимаете, разницу вряд ли на своем уровне смог уловить). Но появилась серьезная проблемма - курс програмухи включает в себя ООП (кое-как через РНР научился) и рекурентные типы данных... И вот на последних и смотрю теперь как баран на новые ворота...
Самое страшное. что у меня через 3 дня экзамен, а я до сих опр до конца не врубился в обозначения и механизмы.


А вот теперь вопрос конкретно по проге. Код брал  из коллекции тов Смита... 
Код

//////////////////////////////////////////////////////////////////////////////    
//    
//  Dynamic structures (bidirectional cycled list)    
//  (c) Johna Smith, 1996    
//    
//  Method description:    
// .................    
// -> * -> * -> * ->    
// <- * <- * <- * <-    
// .  A    B    C  .    
// .................    
//////////////////////////////////////////////////////////////////////////////    
#include <stdio.h>    
#include <alloc.h>    
struct item    
{    
  int element;    
  item *prev;    
  item *next;    
};    
item *list; // base element of the list    
// this function removes element pointed by i from list    
void Remove(item* i)    
{    
  i->next->prev=i->prev;    
  i->prev->next=i->next;    
  free(i);    
}    
// this function inserts element after    
// element pointed by i    
void Insert(item *i, int element)    
{    
  item *tmp;    
  // creating new item    
  tmp=(item*)malloc(sizeof(item));    
  tmp->element=element;    
  tmp->next=i->next;    
  tmp->prev=i->next->prev;    
  // correcting nearest elements pointers    
  i->next->prev=tmp;    
  i->next=tmp;    
}    
// this function searches element in the list    
item* Search(int element)    
{    
  item *p,*q,*result=NULL;    
  char found=0;    
  p=list;    
  q=list->next;    
    
  while (p!=q && found==0)    
  {    
    if (q->element==element)    
    {    
      found=1;    
      result=q;    
    }    
    q=q->next;    
  }    
  return result;    
}    
// this function prints the list    
void printlist(void)    
{    
  item *p;    
  p=list->next;    
  while (p!=list)    
  {    
    printf("%d ",p->element);    
    p=p->next;    
  }    
}    
void main(void)    
{    
  // creating first element of the list    
  list=(item*)malloc(sizeof(item));    
  list->element=0;    
  list->next=list;    
  list->prev=list;    
  printf("Adding elements 1,2,4 & 5\n");    
  Insert(list,5);    
  Insert(list,4);    
  Insert(list,2);    
  Insert(list,1);    
  printlist();    
  printf("\nSearching element 2\n");    
  item *tmp=Search(2);    
  printf("Inserting element 3 after it\n");    
  Insert(tmp,3);    
  printlist();    
  printf("\nDeleting element 1\n");    
  Remove(list->next);    
  printlist();    
  // destroying list    
  while (list->next!=list) Remove(list->next);    
  free(list);    
}


Ну и собственно вопросы практически по каждой строчке...
1. Сама по себе структура (struct), это как бы класс, в котором нету методов? Т.е. есть конечно различия, но в целом, можно ли такое сказать?
2. item *list;  Объявляет (хм, как бы это сказать) "полноценный" элемент списка, или только ссылку на первый(последний???) элемент?
3. Объясните вообще, так сказать, на пальцах, как организуется доступ к каждому элементу списка. Что значит "->", в чем отличие i->prev->next от i->next->prev?

Очень прошу дать максимально доступные пояснения. Только не посылайте за учебниками - уже больше месяца ничего толкового за бесплатно найти не могу... и все-таки, 3 дня до экзамена.... не хочется его с пересдачи сдавать... 
PM MAIL WWW ICQ   Вверх
Никто
Дата 21.6.2006, 12:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 180
Регистрация: 21.3.2006

Репутация: нет
Всего: нет



Цитата

Сама по себе структура (struct), это как бы класс, в котором нету методов? Т.е. есть конечно различия, но в целом, можно ли такое сказать?

Где-то так.
Цитата

Объясните вообще, так сказать, на пальцах, как организуется доступ к каждому элементу списка.

Если вместо указателей переменные,то доступ к ним осуществляется с помощью точки.
Например.
struct item    
{    
  int element;    
  int prev;    
  int next;    
};
item list;
list.element=2;
list.prev=3;
list.next=4;
Если же это указатели,то вместо точки ставится указатель -> на данное.
struct item    
{    
  int element;    
  item *prev;    
  item *next;    
};    
item *list;
list->element=0;    
  list->next=list;    
  list->prev=list;
Цитата

Что значит "->", в чем отличие i->prev->next от i->next->prev?

Next-это поле prev,а prev-это следующее поле в next. 
--------------------
   
PM MAIL   Вверх
Никто
Дата 21.6.2006, 12:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 180
Регистрация: 21.3.2006

Репутация: нет
Всего: нет



У тебя prev и next имеют тип структуры,в который они входят,поэтому они имеют такие же поля,как и структура. 
--------------------
   
PM MAIL   Вверх
ТРЕТЬ
Дата 21.6.2006, 14:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 92
Регистрация: 8.1.2006
Где: mind's gloomy corner

Репутация: нет
Всего: 1



Угу... Все-таки не совсем понятно насчет i->prev->next от i->next->prev...

Как я понял, в первом случае будет от заданной записи перескакивать на предыдущую (->prev) а после можно будет работать с инфой, вписанной в поле next этой записи... блин... сам почти запутался... 
PM MAIL WWW ICQ   Вверх
SaDFromSpb
Дата 21.6.2006, 14:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 5.4.2006
Где: Санкт-Петербург

Репутация: 3
Всего: 3



ТРЕТЬ, 
Структура почти тоже самое, что и класс (она тоже может иметь методы и участвовать в наследовании).
Отличается она от класса тем, что по умолчанию доступ к элементам открыт (public), а для класса - закрыт (private).
Больше, лично мне никаких различий обнаружить не удалось (ну хотя еще, при наследовании структуры от струтктуры наследование по-умолчанию открытое)

item* list; - это определение переменной list, которая может хранить ссылку на экземпляр типа item, но пока еще она не инициализирована (то есть еще не указывает на какой-либо экземпляр типа item). Зовется переменная list указателем на тип item.

-> - это оператор доступа к полю через ссылку (т.е. через значение указателя). То есть, если мы пишем 
Код
item* list;  // объявляем указатель
list = new item;   // инициализируем его адресом созданной структуры
то мы теперь можем иметь доступ к полям этой структуры через оператор ->:
Код
list->element = 4;
// а можно обойтись без оператора -> :
(*list).element = 4;
Если же объявить list как обычную переменную, то доступ к полю осуществляется через точку:
Код
item list;
list.element = 4;


На третий твой вопрос ответ должен быть уже ясен по идее.

И все-таки охота тебя за учебниками послать  smile  Во первых,  и на этом форуме обучающие статьи есть про все эти дела, во-вторых, в нете он-лайн книги найти - не проблема (того же Страуструпа, к примеру).
 


--------------------
"За исключением части, касающейся потоков, библиотека Loki написана на стандартном языке С++. Увы, это означает, что многие современные компиляторы не смогут работать с ней в полном объеме." (А. Александреску. Modern C++ design. 2001)
PM   Вверх
MAKCim
Дата 21.6.2006, 17:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата

Угу... Все-таки не совсем понятно насчет i->prev->next от i->next->prev...

i->prev->next=i
i->next->prev=i 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
ТРЕТЬ
Дата 21.6.2006, 21:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 92
Регистрация: 8.1.2006
Где: mind's gloomy corner

Репутация: нет
Всего: 1



Так... во-первых всем ОГРОМНОЕ спасибо!!!
Сегодня встретил одного умного человека, он мне тож пообъяснял...

Теперь вот сам сел, решил сам свой список написать, причем не глядя на скрипт Смита, но что-то подобное...
Вообчем, то все работает, только осталось всего несколько вопросиков... Точнее они появились....
1. Самое интересное на текущий момент...
Код

void Cicle (item *list)

и
Код

void Cicle (item list)

какова по сути разница между такими функциями? На сколько я понял, в первом варианте, если встретится например list = list->next, то у нас как бы "бегунок" переместится на следущую позицию списка (заранее извиняюсь, за самодеятельность типа "бегунок" и т.д., но просто я сейчас еменно так это воспринимаю)... А во втором случае по возращению в основную программу list останется таким как был... Или второй вариант вообще что-то другое из себя представляет?

*Далее несколько вопросов скорее по поводу стиля, а не работы алгоритма в целом.*
2. Не становится ли односвязный список почти бесполезной схемой в силу своей односторонности?
3. Тов Смит дал пример как создавать замкнутые списки, т.е. кольца по сути. Это дает сразу классную возможность не отслеживать конец списка, что очень удобно (по сути проверка конца списка - проверка не попали ли мы в начало), но если список не замкнут, то как отследить его конец и не "выскочить" куда не надо?
4. Когда понял, что список замкнут, то подумал, может можно как-то избежать такого понятия, как базовый элемент. Правда мысль пошла каким-то странным путём... Получилось примерно следущее - "А можно ли сделать так, чтобы базовый элемент вообще обстрактным - т.е. после первого инсерта (см. скрипт из первого поста) у нас только появлялся первый элемент списка?"
Как думаете, похоже на бред?
5. Так сказать "question 1 revisited"... Этакое перемещение "бегунка" считается допустимым в главной программе, или все-таки считается, что как мы создали первый элемент, так он первым и должен оставаться?


Я очень извиняюсь, что вопросы звучат неразборчиво - просто я еще только начинаю понимать, что это такое, так что с терминологией у меня полный завал...

И еще... Не могли бы вы дать пример программы, которая использовала бы списки не потому что та задание звучит, а потому что это удобно... 
PM MAIL WWW ICQ   Вверх
SaDFromSpb
Дата 22.6.2006, 02:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 5.4.2006
Где: Санкт-Петербург

Репутация: 3
Всего: 3



ТРЕТЬ, 
На счет первого вопроса - весь код напиши. Нифига не понимаю.
2. Есть задачи, где элементы должны следовать строго в определенном порядке с первого до последнего.
3. Поле next у последнего элемента приравнивается к NULL (аналог нуля для указателя). При прохождении проверяем next на равенство NULL.
4. Как только список замыкается, то начальный элемент - это уже условность. У кольца начала и конца нет. Можно любой элемент за первый считать.
5. Опять не особо понял вопрос. При работе со списками как правило хранят указатель на первый элемент, чтобы его "не потерять", и используют хоть сотню "бегунков".

Цитата
Не могли бы вы дать пример программы, которая использовала бы списки не потому что та задание звучит, а потому что это удобно
Так тебе текст программы нужен, или формулировка задачи? 


--------------------
"За исключением части, касающейся потоков, библиотека Loki написана на стандартном языке С++. Увы, это означает, что многие современные компиляторы не смогут работать с ней в полном объеме." (А. Александреску. Modern C++ design. 2001)
PM   Вверх
MAKCim
Дата 22.6.2006, 09:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата

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

Из глобального, например, списки активных и неактивных страниц для реализации управления памятью Linux
еще, тот же стек - разновидность списка, а уж удобность и оправданность его применения не вызывает сомнения (разбор выражений, програмный  стек и пр.) 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
ТРЕТЬ
Дата 22.6.2006, 12:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 92
Регистрация: 8.1.2006
Где: mind's gloomy corner

Репутация: нет
Всего: 1



2 SaDFromSpb, 
насчет первого вопроса... Вот 2 кода, отличаются только на * в аргументе...
Код

void Remove(item* i)     
{     
  i->next->prev=i->prev;     
  i->prev->next=i->next;     
  free(i);     
}   

Код

void Remove(item i)     
{     
  i->next->prev=i->prev;     
  i->prev->next=i->next;     
  free(i);     
}   

Первый работает, это уже проверено... А что насчет второго варианта? Вызывать еготочно так же как первый? Будет ли вообще что-то меняться по выполнению такой процедуры? И вообще нет ли в нем ошибок? 
PM MAIL WWW ICQ   Вверх
SaDFromSpb
Дата 22.6.2006, 12:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 5.4.2006
Где: Санкт-Петербург

Репутация: 3
Всего: 3



Второй кусок вобще скомпилиться не должен, так как i не указатель, оператор -> для доступа к элементам использовать нельзя.
В первом примере мы на вход получаем адрес элемента, который нужно удалить (он хранится в перменной i). 
Во втором же к нам идет попадает копия элемента списка, подлежащего удалению.
Здесь можно написать вот так:
Код
void Remove(item i)     
{ 
  free(i.prev->next);
  i.next->prev = i.prev;     
  i.prev->next = i.next;     
} 
Но это все при условии, что в функцию передана структура, у которой верно заполнены поля prev и next. Стоит отметить, что здесь идет передча параметра по значению, то есть в i содержится копия того элемента списка, который нужно удалить. Следовательно, оригинал можно удалить сразу, что и делается в первой строчке. 
И последнее: второй способ - это изврат =), так как чаще всего стоит задача удалить элемент по такому-то адресу или с таким-то содержанием (например, с определенным номером, если элементы нумеруются).  

Это сообщение отредактировал(а) SaDFromSpb - 22.6.2006, 12:31


--------------------
"За исключением части, касающейся потоков, библиотека Loki написана на стандартном языке С++. Увы, это означает, что многие современные компиляторы не смогут работать с ней в полном объеме." (А. Александреску. Modern C++ design. 2001)
PM   Вверх
Rockie
Дата 22.6.2006, 16:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1143
Регистрация: 23.4.2006

Репутация: 8
Всего: 31



ТРЕТЬ, можно почитать про спики на С++ здесь 


--------------------
Чтобы иметь большой гардероб - надо иметь большой гардероб.
PM   Вверх
ТРЕТЬ
Дата 22.6.2006, 19:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 92
Регистрация: 8.1.2006
Где: mind's gloomy corner

Репутация: нет
Всего: 1



Ладно... Впринципе есть еще один вопрос. но не думаю. что он уж очень важен...

Всем огромное спасибо!!!

Вопрос закрываю... И открываю новый=)


Что за тип данных такое "граф"? Насчет деревьев, стеков и иже с ними разобрался, а вот графа так и не встретил с нормальными комментариями... На сколько понял, это тоже что-то основанное на списках, или нет... Вообчем напишите. Очень будет сдорово, если найдется пример, хоть самый простой, но только чтобы можно было его сразу компилить - т.е. законченная прога была. Как правило, имея пример я уже могу разобраться. 
PM MAIL WWW ICQ   Вверх
ManiaK
Дата 22.6.2006, 20:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Homo Sapience
***


Профиль
Группа: Комодератор
Сообщений: 1145
Регистрация: 3.8.2004
Где: ИУ5-93

Репутация: 5
Всего: 29



Цитата(ТРЕТЬ @  21.6.2006,  11:45 Найти цитируемый пост)
Сама по себе структура (struct), это как бы класс, в котором нету методов? Т.е. есть конечно различия, но в целом, можно ли такое сказать?

Нельзя. В Си это просто набор переменных, объединённых одним именем, в Си++ - это синоним класса, отличающийся от него только тем, что доступ в классе по умолчанию protected, в структуре - public. Во всём остальном struct = class. 
PM MAIL WWW   Вверх
MAKCim
Дата 22.6.2006, 21:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата

что доступ в классе по умолчанию protected

private

Добавлено @ 21:03 
Цитата

Во всём остальном struct = class.  

не совсем
по умолчанию при наследовании от структуры используется модификатор public
Код

struct A {};
struct B: A {}; // не private-наследование как при class

int main()
{
    A* a=new B; // OK
    return 0;
}
 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
BreakPointMAN
Дата 23.6.2006, 06:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 725
Регистрация: 15.9.2004
Где: Saratov

Репутация: 14
Всего: 24



Цитата(ТРЕТЬ @  22.6.2006,  19:47 Найти цитируемый пост)
Что за тип данных такое "граф"? 

Читаем здесь: 


--------------------
"Разруха не в клозетах, а в головах." © Ф.Ф. Преображенский (М.Булгаков, "Собачье сердце")
PM WWW ICQ   Вверх
ТРЕТЬ
Дата 23.6.2006, 14:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 92
Регистрация: 8.1.2006
Где: mind's gloomy corner

Репутация: нет
Всего: 1



 smile 
Всмысле почитал, интересно конечно, но просто ОЧЕНЬ хочется самый простой пример на СИ++ (вплоть до простого объявления структуры)

Эту уже последний вопрос, так что после его ответа буду помечать вопрос как решенный. 
PM MAIL WWW ICQ   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0610 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.