Помощь - Поиск - Пользователи - Календарь
Полная версия: Отличие type и var
Форум «Всё о Паскале» > Pascal, Object Pascal > Теоретические вопросы
-notpron
Всем добрый вечер, не могу никак понять, в чем разница между type и var? Скорее всего - я немного не допонял саму функцию type.
И я совсем запутался в порядковых типах данных, для чего они нужны? Как(не теоритически) можно проверить функцию, например, ord(x)? Заранее спасибо)
IUnknown
Type - это не функция. Это зарезервированное слово. Которое говорит компилятору, что начинается раздел описания типов. А var - это раздел описания переменных. Разница? Ну, скажем
type T = array[1 .. 10] of integer;
это описывается тип T, который представляет из себя массив из 10 целых чисел. Но вот записать ничего в этот самый массив ты не сможешь, пока не опишешь переменную этого типа:
var arr : T;
Это уже описание переменной, теперь уже под a выделится нужное количество памяти, и с массивом можно будет работать... Под тип ничего не выделяется...

Цитата
И я совсем запутался в порядковых типах данных, для чего они нужны?
Если есть - значит нужны... Порядковые - это значит, те, которые можно перечислить. Вот и нужны они для того, чтобы что-то перечислять, подсчитывать, индексировать... Тот же массив. Ты не можешь записать
type T = array[1.2 .. 10.3] of integer;
, тебе нужен порядковый тип в качестве индекса. И циклы For ты можешь использовать только с переменными порядковых типов, и никаких других.

Цитата
Как(не теоритически) можно проверить функцию, например, ord(x)?
Что значит "проверить"? "Trust me, it's there..." © "День Независимости"
-notpron
2 IUnknown
А можно не на примере массивов? Просто я до них пока не дошел. =(
Что насчет проверить.Возьмем к примеру
Код
type week =(sun,mon,tue,wed,thu,fri,sat)

Тогда для него будет верно что
Код
dec(sun)=sat

Вот у меня и вопрос, как это проверить? Не теоретически, а на паскале.
IUnknown
не на примере массивов? Ну, напечатай первые 10 четных чисел... Как ты это будешь делать (считать, что напечатано именно 10, а не больше и не меньше, я имею в виду)? Вот видишь, тебе опять нужны порядковые (они же - перечислимые) типы... Только не надо говорить, что и до циклов ты тоже не дошел. Тогда до чего ж дошел?

Цитата
Тогда для него будет верно что
Неправда. Пользовательские типы не "закольцованы", то, что следующий после Fri будет Sat - верно, а вот значения после Sat или перед Sun - не определены, то есть, запрещено их получать... Нельзя написать Pred(Sun) или Succ(Sat)...
-notpron
2 IUnknown
Не, до циклов я дошел)
И вы не правы - перечисляемый тип данных является не пользовательским, а конструируемым. Можете проверять. Поэтому мое утверждение верно.
Но так я и не понял практического применения. Да, можно воспользоваться, будь то дни недели или Nое количество чисел. Я не понимаю, как их можно "вытащить" оттуда. Ведь если заместо sat в
Код
dec(sun)=sat
поставить переменную и потом вывести ее - так не получится.
Тоже самое не получится(у меня не получилось) вывести просто 10 чисел.
IUnknown
Цитата
И вы не правы - перечисляемый тип данных является не пользовательским, а конструируемым. Можете проверять.
Ты это "можете проверять" кому-нибудь другому расскажи, ладно? Я эту "Филькину грамоту" уже лет 20 как наизусть знаю, не надо мне ничего проверять... Конструируемый - это тот, который строится на основании простого. На основании какого именно простого типа построен тип Week, не подскажешь?

Цитата
Поэтому мое утверждение верно.
Какое утверждение? Что Dec(sun) = Sat? Это бред, а не утверждение. Знаешь, почему? По одной простой причине: Компилятору все равно, как там называются у тебя элементы перечисления... Для него это 0, 1, 2, ..., 255 (максимум). Заметь, от 0!!! Вот что получается:

type
Week = (sun, mon, tue, wed, thu, fri, sat);

begin
writeln( ord(sun) );
writeln( week(ord(sun) - 1) ); // <--- !!!
end.
Что выведется?

А вот что: Ord(Sun) = 0. Хорошо, это напечатается. А теперь - следующий шаг: попробуем напечатать предыдущий элемент перечисления... И вот тут тебя поджидает большой облом... Ошибка 107, вот и все... Нет предыдущего элемента у Sun... Он есть только в одном-единственном случае: когда перечисление содержит ровно 255 элементов, тогда Pred(первый_элемент) = последний_элемент, но это скорее побочный эффект, поэтому пользоваться этим не стоит...

Хотя writeln( week(ord(sun) + 1) ); прекрасно печатает mon (я пользуюсь FPC, и тебе советую, в Турбо Паскале будет ошибка, там такое не позволяется)...

Цитата
Тоже самое не получится(у меня не получилось) вывести просто 10 чисел.
Да что ты? Теория программирования понесла тяжелую утрату smile.gif :
var i : integer; // Integer - это по-твоему тоже НЕпорядковый тип? Ну-ну...
begin
for i := 1 to 10 do writeln(2 * i);
end.
Если у тебя что-то не получается - это не значит, что оно невозможно...
-notpron
Не надо ругаться, спокойнее. Просто аргументированный спор(хотя какой спор я могу вам предложить не знаю массивы smile.gif )
Конструированный тип данных это тот тип, который конструируется(извините за тафтологию) самим программистом. Разве не так?
И потом dec(min_element)= max_element не?
возьмем тип данных
Код
type sixteen = 0..15;

И вместе ненавистного вам dec возьмем inc, который действует по аналогичной системе. Inc(x) возвращает значение, следующее за х (для арифметических типов данных это эквивалентно оператору x:=x+1). Правильно?
15 это 1111 в двоичной системе. 1111 + 1 получается 1 0 0 0 0. Начальную единицу откидываем и получается inc(15)=0. Разве нет? Я не спорю - ошибаться могу, 100%.
Спасибо большое за программу для использование порядковых типв данных, правда, очень пригодилось. И насчет FPC спасибо, но я использую school pack, ибо на mac я ничего не нашел ;)
И насчет 10 чисел - вывести не через цикл а через перечисляемый тип данных.
Не надо агрессии, правда. Я бы не хотел этого)
Lapp
Я извиняюсь за встрятие..

Цитата(-notpron @ 5.07.2011 23:59) *
Не надо ругаться, спокойнее. Просто аргументированный спор(хотя какой спор я могу вам предложить не знаю массивы smile.gif )
-notpron, а кто ругался и где? Покажи мне то место, плз. А манера говорить у каждого своя - ты волен не слушать.. И учти, если ты будешь нести чушь, приговаривая при этом "я прав", - ты будешь получать ответы в таком именно духе. Само по себе нести чушь - пожалуйста, на то и форум. Но не говори "вы не правы" тем, кто тысячи таких как ты научил уже..

Цитата
Конструированный тип данных это тот тип, который конструируется(извините за тафтологию) самим программистом. Разве не так?
Нет, не так, и IUnknown тебе уже говорил это. У конструируемого есть синоним (или перевод на русский, если хочешь) - "составной". То есть он может состоять минимум из двух квантов определения типов. Но раз ты не знаешь массивы (и, наверное, записи), я затрудняюсь привести пример. А вообще - избегай "свободной трактовки терминов на основе здравого смысла и опыта", действуй только на основе определений.

Цитата
И потом dec(min_element)= max_element не?
Нет.

Цитата
возьмем тип данных
Код
type sixteen = 0..15;

И вместе ненавистного вам dec возьмем inc, который действует по аналогичной системе. Inc(x) возвращает значение, следующее за х (для арифметических типов данных это эквивалентно оператору x:=x+1). Правильно?
15 это 1111 в двоичной системе. 1111 + 1 получается 1 0 0 0 0. Начальную единицу откидываем и получается inc(15)=0. Разве нет? Я не спорю - ошибаться могу, 100%.
Ошибаешься, 100% yes2.gif
Твоя ошибка, по-видимому, есть результат трех факторов.

1. Неудачно выбран пример - я имею в иду вот это:
   Week = (sun, mon, tue, wed, thu, fri, sat);
(кстати, ставь, пожалуйста, ПРАВИЛЬНЫЕ теги; прочти Правила форума и правила этого раздела - там все подробно написано)
Почему неудачно? Потому что дни недели действительно зациклены, причем идеально (т.е. лучше, чем, скажем, числа в месяцах). Но это есть всего лишь свойство дней недели, а не общая математическая закономерность. Например, в некоторых карточных играх, шестерка бьет туза, а в некотороых - нет, не бьет.

2. Ты знаешь, как устроено машинное представление чисел (и это хорошо), но, видимо, не до конца (или кое-что не учитываешь). Если при сложении двух байт (или беззнаковых целых) происходит переполнение, действительно в результате будет число с отрезанным верхним разрядом. Но! Но при этом будет установлен признак переполнения. Иными словами, обрезание при переполнении есть вынужденная мера (поскольку любая реальная разрядная сетка конечна), но есть и средство исправить ситуацию.

3. У тебя в опциях компилятора выключена проверка выхода за пределы диапазона (range check). Вот это - очень плохо! Рекомендую тебе зайти в опции и установить ее range check в дефолт. И убирай его ТОЛЬКО после полной отладки программы, и ЕСЛИ собираешься отдать программу в эксплуатацию. Иначе ты хлебнешь горя.. ))

Вот тебе пример программы, которая либо будет работать неправильно, либо выдаст три (ну, не одновременно)) ошибки выхода за диапазон.
{$R+} // замени + на -, и прога пройдет - но результат будет неверный
type
tHex= 1 .. 15;
tWeek = (sun,mon);

var
a,b,c: tHex;
d: tWeek;

begin
d:= mon;
Inc(d); // тут будет ошибка 201 при исполнении
writeln(Ord(d));
a:= 8;
b:= 15;
c:= a+b; // тут будет ошибка 201 при исполнении
writeln©;
Inc(b); // тут будет ошибка 201 при исполнении
writeln(b);
readln
end.


Зацикленные целые множества (группы "по модулю") весьма часто бывают нужны. Встроенной поддержки их в языке Pascal нет. Если у тебя в программе нужна такая функциональность (те же дни недели, например), ты должен сам явным образом определить сложение/вычитание (при этом очень удобно использовать перезагрузку операторов).

Цитата
насчет FPC спасибо, но я использую school pack, ибо на mac я ничего не нашел ;)
Да? странно.. А про что тогда строчка: "Mac OS X and several crosscompilers" на странице скачивания FreePascal? Я сам, правда, эту ссылку не пробовал..

Добавлено через 12 мин.
Вдогонку еще один простенький примерчик использования типов. Допустим, твоя программа производит сложные расчеты. Ты использовал тип single для представления чисел в ней. Но потом (когда прога на много килобайт кода была уже написана) понял, что в некоторых случаях все же лучше использовать double (для большей точности). И ты начинаешь ползать по всей программе, состоящей из нескольких модулей, и менять там все single на double.. Причем, некоторые переменные могут не относиться к собственно расчетам, и их можно (и нужно) оставить single. И ты кусаешь локти..
А если бы у тебя было в самом начале:
type
tReal = single;
- а потом везде (где надо) стояло бы tReal, то тебе надо было бы сделать всего одно изменение:
type
tReal = double;
IUnknown
Цитата
Зацикленные целые множества (группы "по модулю") весьма часто бывают нужны. Встроенной поддержки их в языке Pascal нет.
Кстати, встроенной поддержки циклических перечислений, определенных пользователем, насколько я помню, нет нигде, хотя очень многие просят. В некоторых языках есть встроенные модульные типы (обладающие необходимым функционалом). Но пользоваться вариантом "описать модульный тип, а потом Sun, Mon, ... Sat - как константы этого типа" не очень удобно, проще переопределить функции Pred и Succ:

{$mode objfpc}
type
Week = (sun, mon, tue, wed, thu, fri, sat);

function Pred (Value : Week) : Week;
begin
if Value = Low (Week) then Pred := High (Week)
else Pred := System.Pred (Value)
end;

function Succ (Value : Week) : Week;
begin
if Value = High (Week) then Succ := Low (Week)
else Succ := System.Succ (Value)
end;

var
W : Week;

begin
W := sun;
writeln (W); // sun
W := Pred (W);
writeln (W); // sat
W := Succ (W);
writeln (W); // sun
W := Succ (W);
writeln (W); // mon
end.

, а когда в FPC наконец допилят дженерики хотя бы до того уровня, что есть сейчас в Дельфи - можно будет написать две шаблонные функции Pred и Succ и передавать в них параметры любых перечислимых типов.
-notpron
2 Lapp
Я понимаю что манера говорить у всех своя, но я же не использую сленг имиджбордов, правильно? Поэтому везде есть рамки. Но не в этом суть.
Цитата
И учти, если ты будешь нести чушь, приговаривая при этом "я прав", - ты будешь получать ответы в таком именно духе.

Ну почему чушь, я всего лишь ошибался. Это тоже самое(пусть пример будет глупым) если спросить у мальчика, который учится в третьем классе, "какое самое маленько число?", то он ответит "0". А если спросить это же у 8 класса, то они ответят "-бесконечность". И разве можно будет винить 3 класс? Как я прочитал в литературе - так и сказал здесь. Поймите меня тоже, кому вы поверите сначала, книге или какому то парню с форума? Теперь я понял что ошибался, без вопросов.
Цитата
(кстати, ставь, пожалуйста, ПРАВИЛЬНЫЕ теги; прочти Правила форума и правила этого раздела - там все подробно написано)

Чем вас не устраивает тег [cоde]? По-моему его можно использовать.
Цитата
Да? странно.. А про что тогда строчка: "Mac OS X and several crosscompilers" на странице скачивания FreePascal? Я сам, правда, эту ссылку не пробовал..

После установки она не появляется в программах, я гуглил, там надо черех xcode пилить, а это геморно.
Про последний пример - я его не понял, уж извините)


-TarasBer-
это тролль, не реагируйте
-notpron
Не надо оффтопить, есть что сказать по теме - скажи.
-TarasBer-
канонично...
-notpron
Ну и сразу дурацкий вопрос - а как копипастить в turbo pascal? Тоесть допустим отсюда код в программу?
sheka
.pas - текстовый документ.
Создавай новые темы в новых темах smile.gif
-notpron
Ну про этот способ мне известно, но все равно спасибо)
Lapp
Цитата(-notpron @ 6.07.2011 12:18) *
Чем вас не устраивает тег [cоde]? По-моему его можно использовать.
Еще раз, теперь уже как админ тебе говорю:
М
прочти Правила!!
особенно обрати внимание на п.5 Правил Форума



Цитата
Про последний пример - я его не понял, уж извините)
Уточни, что ты имел в виду: мой пример или IUnknown. И точно указывай, в каком месте затык.


Добавлено через 3 мин.
Цитата(-notpron @ 6.07.2011 18:41) *
Ну про этот способ мне известно, но все равно спасибо)
Другого способа нет и быть не может. TP - это досовская прога, она ничего не знает про виндусовый буфер. Все равно что сказать: объясните, как заливать бензин в лошадь..
-notpron
2 Lapp
2. Все тексты фрагментов программ должны помещаться в теги [cоde] ... [/cоde] или [cоde=pas] ... [/cоde].
Нет?
Не, я ваш пример немного не въехал smile.gif
Спасибо за объяснение по поводу копипаста)
Lapp
Цитата(-notpron @ 7.07.2011 19:52) *
2. Все тексты фрагментов программ должны помещаться в теги [cоde] ... [/cоde] или [cоde=pas] ... [/cоde].
Нет?
Ты цитируешь п.2 правил раздела. Я уже понял, что у тебя трудности с его пониманием, поэтому просил посмотреть п.5 Правил Форума (ссылка вверху страницы). Кроме того, посмотри все остальные пункты.

Цитата
Не, я ваш пример немного не въехал smile.gif
Что именно в нем неясно?
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.