Привет! Очень надеюсь на вашу помощь в разжевывании некоторых понятий
Итак приступим-с:
1. Банально.. Свойства алгоритма. Массовость - це значит, что любой алгоритм должен решать какую-то конкретную задачу из определенного класса задач, причем такой класс либо бесконечен, либо конечен, но очень "баальшой".. Так вот.. А можно это сказать как-то по-человечески и с примером?
2. Тут мне б тоже пример хотелось:
а) перечислимый тип (а сюда пойдет, например, тип месяцы(-а))) с элементами январь, февраль и т.д.?)
б) ссылочный тип - знаю, что значение любого ссылочного типа - это адрес памяти, но в живую не встречала.. познакомите?))
Пока все, но думаю еще вопросы появятся.. Я только начала подготовку..
Заранее пасибо))
1. По-человечески...
Алгоритм совершения покупок в супермаркете должен позволять тебе купить как хлеб, так и мыло.
2.
а) Перечислимый... ну, обычно под этим понимают не только перечисляемый (месяцы; товары в конкретном магазине; книжки на полке), но и стандартные типы языка, элементы которых могут быть перечислены в определенном порядке (например, char - может... integer - побольше, но все же мы можем записать 1,2,3...MaxInt. а со строками так не получится... хотя, конечно, в условиях ограниченности длины строки/разрядной сетки для чисел это условность). Это понятие обычно используется при выборе типа переменной в таких операторах, как for <переменная>, case <переменная>
б) какого рода пример тебе бы хотелось? код? или жЫзненный?
2а) так месяцы подходят? ура)) алгоритм построения типа понятен.. я забыла уточнить, что речь идет о конструируемых типах, т.е. стандартные сейчас не пойдут, но все равно спасибо))
2б) а я хочу все и сразу )
Добавлено через 17 мин.
Да по-поводу 1-го: теперь на более близком к теме языке - если я пишу программку для сортировки массива, то она должна сортировать не только один какой-то понравившийся мне массив))
2а) А почему нет?
Вот так например:
type
Month= (jan, feb, mar, apr, may, jun,
jul, aug, sept, oct, nov, dec);
type
zapiska = ^Tainik; {значок ^ показывает, что записка - это указатель на тайник}
Tainik = record
Oreh: eda; {допустим, тип eda был описан раньше }
Next: zapiska; {указатель на следующий тайник}
end;
Спасибо!! Теперь я умная белка)))
Добавлено через 7 мин.
..хотя надо проверить:
el:=((el^.next)^.next)^.next;
У списка есть недостаток перед массивом - нельзя сразу перейти к элементу с нужным номером: приходится перебирать все элементы с начала. Тут ничего не поделаешь - зато у списка есть другие преимущества перед массивом. Поэтому длиная цепочка ссылок - всего лишь способ добраться до нужного элемента (как знать, вдруг белке захотелось полакомиться именно орехом урожая 1894 года?).
Еще один пример на ссылку на ссылку (мне привычнее употреблять термин "адрес").
В Паскале не очень вразумительно сделаны указатели, поэтому лучше на примере Си.
Хочется иметь строки неограниченной длины. Но хочется также иметь тип данных фиксированной длины, например для того, чтобы можно было сделать из них массив.
Как совместить эти требования?
Например, использовав в качестве типа адрес первого символа строки, а конец строки пометить каким-либо ограничителем, скажем, символом с кодом 0.
То есть строка у нас на самом деле имеет тип указателя.
Теперь нам нужно, чтобы некая процедура возвращала строку.
Чтобы передать строку внутрь процедуры достаточно переда ее значение (в нашем случае это адрес), а чтобы получить обратно - нужен адрес: для того, чтобы записать по этому адресу значенние переменной.
Вот мы и передаем в процедуру адрес указателя на первый символ строки. А процедура записывает по этому адресу адрес тела уже существующей строки.
Если бы перед нами стояла задача обойтись единственным адресом, пришлось бы дополнительно резервировать память и создавать копию строки вместо того, чтобы использовать адрес уже существующей.
type, в вызывающей программе оно не изменится (вариант с использованием Var не предлагать, ибо пример - только для учебных целей. Оля спросила про указатель на указатель, я привел пример, показывающий такую ситуацию).
plist = ^list;
list = record
data: item_type;
next: plist;
end;
procedure add_first(head: plist; item: item_type);
...
type
pplist = ^plist; // определяем тип - указатель на "указатель на элемент списка"
...
// передаем указатель на "голову" списка, чтобы изменение передалось в вызывающую программу...
procedure add_first(phead: pplist; item: item_type);
var new_item: plist;
begin
// выделяем память под переменную типа list,
// в new_item вернется указатель на выделенную область памяти
new(new_item);
// заполняем поля структуры:
// в поле data пишем само значение
new_item^.data := item;
// в поле next - то, что раньше было "головой" списка, но поскольку phead у нас не просто
// указатель, а "двойной" указатель - то разыменовываем его, в итоге получается присвоение
// "указателя на элемент списка" такому же "указателю на элемент списка"
new_item^.next := phead^;
// а теперь - изменяем "голову", первым элементом должен быть тот, который создан только что,
// операцией new, т.е. new_item... Обрати внимание - опять разыменование, чтобы "уравнять" типы
// указателей: pplist^ = plist
phead^ := new_item;
end;
...
// @ - берем адрес фактической переменной - "головы" списка, и передаем его
// для обработки в процедуру
add_first(@my_head, 10); { <--- Пример вызова }
...
А можно я попробую прокомментировать код (попытаемся проверить, насколько я поняла ):
type
plist = ^list; // тип plist - это указатель на тип list
list = record // list - это запись с двумя полями, где 1-е поле - это какие-то данные
// а второе - указатель, получается, на следующий элемент записи?
data: item_type;
next: plist;
end;
procedure add_first(head: plist; item: item_type); //добавляем запись, head - указатель именно на первый
//элемент, item - данные
...
type
pplist = ^plist; // pplist - тип-указатель на тип-указатель))
...
procedure add_first(phead: pplist; item: item_type); // а здесь у нас уже не сам указатель на первый
//элемент, а указатель на указатель на первый элемент)) + данные
var new_item: plist; // новые данные - указатель на запись
begin
new(new_item); // прочитала, что new создает новую динамическую переменную и указатель на нее, вроде понятно
new_item^.data := item; // а здесь new_item^ - это уже значение (т.е. запись) на которую ссылается этот указатель
new_item^.next := phead^; //записали в новой записи в поле next значение указателя, указывающего на head
phead^ := new_item; // а тут присвоили ему значение указателя на новую запись
// т.е. мы какбы поменяли местами значения? например была первая запись, со всеми приложениями))
// phead(типа pplist)->head(типа plist)->list', потом мы дописали еще одну запись и получилось
// pnext->next->list'', но теперь эта первая, а верхняя - 2-я.. а после всех махинаций с указателями получится:
// phead->next->list'' и pnext->head->list' ?..
// ой, как-то бредово у меня получилось, особенно вконце..
end;
...
add_first(@my_head, 10); { <--- Пример вызова } // @my_head - т.е. берется значение указателя my_head..
...
Оля, я добавил комментарии постом выше...
Еще пара вопросов:
1. Регулярный тип - то бишь массивы.. прочитала что в качестве элементов массива можно использовать элементы любого типа кроме файлового.. не поверила))
на всякие извращения вида:
m1: array[1..5] of text;
m: array[1..5] of file of text;
n: array[1..5] of file of file; // <- тут ошиблась при вводе, но прошло о_О
k: array[1..5] of file of file of integer;
1. Смотрим здесь: http://forum.pascal.net.ru/index.php?s=&showtopic=13146&view=findpost&p=76699
2.
type
pint = ^integer;
pdouble = ^double;
var
p: pointer;
p_i, p_j: pint;
p_d: pdouble;
begin
...
p_i := p_j; { Можно, одинаковые типы }
p_i := p; { <--- Можно, указатель совместим со всеми типами ссылок }
p := p_d; { <--- Аналогично предыдущему }
p_i := p_d; { <--- А вот этого делать нельзя }
[offtop] 1. оказывается не одну меня это заинтересовало)) это один из этапов обучения программированию? [/offtop]
2. теперь все ясно Спасибо!