Пользовательские типы данных

Предыдущая тема Следующая тема Перейти вниз

Пользовательские типы данных

Сообщение  justar в Чт Окт 02, 2008 4:42 pm

Кроме стандартных типов данных, "зашитых" в компилятор, язык FB позврояет программисту объявлять собственные. Для этого в языке FB предусмтремы три ключевых слова: TYPE, UNION и ENUM

Конструкция TYPE имя_типа AS тип позволяет создать cиноним к уже существующему типу данных (стандартному или ранее объявленному пользовательскому). Фактически эта конструкция не создаёт нового типа, она лишь переименовывает существующий, но иногда это очень полезно с точки зрения читабельности программы. Например, инструкция
Код:
TYPE CHAR AS STRING * 1
создаёт тип данных для работы с одиночными символами, а инструкция
Код:
TYPE BOOL AS BYTE
создаёт логический тип (объявления этих двух типов очень помогают переносить программы с языков Си и Паскаль на FB)

Конструкция TYPE ... END TYPE предназначенна для объявления сложных cтруктурированных типов (или говоря попросту, "по-сишному", - структур). Структуры позволяют систематизировать сложные данные и работать с ними как с единым целым. В простейшем случае внутри этой конструкции просто обычным образом объявляются составляющую структуру переменные, называемые поля структуры:
Код:

TYPE BIOSKey
    DIM key  AS BOOL
    DIM code AS CHAR
END TYPE
Данная структура предназначенна для хранения "расширенного" кода клавиши - поле key хранит признак того, обычная ли это (алфавитно-цифровая) или функциональная клавиша, а поле code - собственно код хранимой клавиши. После объявления типа им можно пользоваться как обычным:
Код:

DIM AS BIOSKey k, m 
DIM AS CHAR c
FUNCTION BIOSKey () AS BIOSKey 
    DIM OutKey  AS BIOSKey
    OutKey.char = INKEY$
    IF MULTIKEY (1) THEN
          OutKey.key = TRUE
    ELSE
          OutKey.key = FALSE
    END IF
    RETURN OutKey
END FUNCTION
k = BIOSKey ()
m = k
c = m.code
IF k.key = FALSE THEN PRINT k.code
Как видно из этого примера, к структурной переменной можно обращаться как целиком (m = k) - при этом переменной присваивается структура целиком, либо по отдельным полям - в этом случае имя требуемого поля добавляется к имени структурной переменной через точку. В общем случае Синтаксис доступа к членам структур следующий:
имя_структуры.поле
указатель_на_структуру->поле


Кроме переменных FB позволяет в качестве полей структуры использовать процедуры и функции. Эта возможность широко используется в объектно-ориентированном программировании, но так как о нём говорится подробно в отдельном разделе. то тут останавливаться на этой возможности не будем.

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

UNION u_tag
    DIM ival AS INTEGER
    DIM fval AS SINGLE
    DIM sval AS CHAR PTR
END UNION
DIM u AS u_tag
Переменная u будет достаточно большой, что бы в ней поместилась любая переменная из указанных трёх типов. Значение одного из этих трёх типов может быть присвоено переменной u и далее использовано в выражениях, если это правомерно, т.е. если тип взятого ею значения совпадает с типом последнего присвоенного ей значения. Выполнение этого требования в каждый текущий момент - целиком на совести программиста.

Синтаксис доступа к членам объединения аналогичен синтаксису доступа к полям структур:
имя_объединения.член
указатель_на_объединение->член


Объединения могут входить в структуры и массивы и наоборот.
Фактически объединение - это структура, все члены которой имеют нулевое смещение относительно её базового адреса, размера, который позволяет поместиться в ней самому большому её члену, и выравнивание которой удовлетворяет всем типам объединения.
Инициализировать объединение можно только значением, имеющим тип его первого члена; таким образом, упомянутую выше переменную u можно инициализировать лишь значением типа INTEGER.

Конструкция ENUM ... END ENUM описывает так называемый перечисляемый тип
Enum - это пользовательский тип данных, в определении которого явно перечисляются все возможные значения. Перечисление может быть в явном виде:
Код:

ENUM TDayOfWeek
  mon
  tue
  wed
  thu
  fri
  sat
  sun
END ENUM
либо в виде констант:
Код:

ENUM TColor
  Red = 1
  Green = 2
  Blue = 3
END ENUM
Различия этих объявлений только в том, что в первом случае значениям будут сопоствленны целые числа в порядке перечисления (1, 2, 3 и т.д.), а во втором - конкретные значения, выбранные программистом.
После объявления перечисляемого типа можно обычным образом объявлять переменные:
Код:

DIM AS TDayOfWeek ThisDay, LastDay
DIM rgb AS TColor
и пользоваться ими обычным образом, помня, что переменная может принимать только значения, перечисленные в объявлении типа:
Код:

ThisDay = wed
INPUT LastDay
IF LastDay > ThisDay THEN PRINT "Ошибка, прошедший день должен бытт меньше текущего"
SELECT CASE LastDay
CASE mon
CASE tue
END SELECT
ThisDay = LastDay + 1
PRINT ThisDay
Так как перечисляемые значения фактически являются именованными константами, следующие выражения эквивалентны:
ThisDay = wed и ThisDay = 3
rgb = Green и rgb = 2
Соотвественно, переменными перечисляемого типа можно пользоваться как обычными переменными типа INTEGER в рамках области перечисленных целочисленных значений.


Последний раз редактировалось: justar (Сб Окт 11, 2008 5:09 pm), всего редактировалось 2 раз(а)

justar

Сообщения : 135
Дата регистрации : 2008-05-12
Возраст : 43
Откуда : Кишинёв, Республика Молдоа

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Пользовательские типы данных

Сообщение  tux в Чт Окт 02, 2008 6:22 pm

Конструкция UNION ... END UNION на сегодняшний день является синонимом конструкции TYPE ... END TYPE - т.е. если заменить ключевое слово "TYPE" на "UNION" фактически ничего не изменится.
Жуть, ну ты дал, попробуй такое:
Код:
union uuMy
    dim as byte x
    dim as byte y
end union
dim as uuMy uTmp
uTmp.x=5
print uTmp.y
sleep
UNION - это объединение, те ее прикол в том, что для разных элементом, она использует одни и те же ячейки памяти, удобно ее использовать допустим тут:
Код:
union uuMy
    dim as uinteger ip
    dim as ubyte b(1 to 4)
end union
dim as uuMy uTmp
uTmp.b(1)=127
uTmp.b(2)=0
uTmp.b(3)=0
uTmp.b(4)=1
print uTmp.ip
print hex(uTmp.ip)
sleep
avatar
tux

Сообщения : 365
Дата регистрации : 2008-04-06
Возраст : 29
Откуда : Сибирь

Посмотреть профиль http://tux.nsk.ru/

Вернуться к началу Перейти вниз

Re: Пользовательские типы данных

Сообщение  justar в Чт Окт 02, 2008 10:07 pm

Упс! Не знал такого... Действительно это так. Сорри.

justar

Сообщения : 135
Дата регистрации : 2008-05-12
Возраст : 43
Откуда : Кишинёв, Республика Молдоа

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Пользовательские типы данных

Сообщение  justar в Чт Окт 02, 2008 10:16 pm

tux пишет:
UNION - это объединение, те ее прикол в том, что для разных элементом, она использует одни и те же ячейки памяти
Что-то тут не то... Если все поля расмещаются в одной и той же ячейке, то присваивание значения второму полю должно ведь затирать значение, ранее присвоенное первому - так как в ту же ячейку помещается новое значение? Но это не так:
Код:

union uuMy
    dim as byte x
    dim as byte y
end union
dim as uuMy uTmp
uTmp.x=5
uTmp.y=3
print uTmp.y, uTmp.x
выводит правильно: 3 5
Т.е. получается, что uTmp.x и uTmp.y всё же хранятся отдельно друг от друга...
В общем непонятно... Напиши свою редакцию раздела про UNION, плиз.

justar

Сообщения : 135
Дата регистрации : 2008-05-12
Возраст : 43
Откуда : Кишинёв, Республика Молдоа

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Пользовательские типы данных

Сообщение  Eric-S в Чт Окт 02, 2008 10:47 pm

Только сегодня утром думал, что назрела необходимость в этой главе.

Да, действительно остаёться ещё многое непонятно.

Ведь и с type не всё так просто. Есть какие-то временные типы и ещё много чего.

С union сам не понимаю.
Хорошо что с enum быстро въехал.

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: Пользовательские типы данных

Сообщение  justar в Вс Окт 05, 2008 8:54 am

По скольку многое FB заимствует у С, решил посмотреть что же думают об объединениях патриархи С - Керниган и Ричи (текст привожу в оригинале, а примеры я старался сразу переписывать в синтаксисе FB).

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

UNION u_tag
    DIM ival AS INTEGER
    DIM fval AS SINGLE
    DIM sval AS CHAR PTR
END UNION
DIM u AS u_tag
Переменная u будет достаточно большой, что бы в ней поместилась любая переменная из указанных трёх типов. Значение одного из этих трёх типов может быть присвоено переменной u и далее использовано в выражениях, если это правомерно, т.е. если тип взятого ею значения совпадает с типом последнего присвоенного ей значения. Выполнение этого требования в каждый текущий момент - целиком на совести программиста.
Синтаксис доступа к членам объединения следующий:
имя_объединения.член
указатель_на_объединение->член
Объединения могут входить в структуры и массивы и наоборот.
Фактически объединение - это структура, все члены которой имеют нулевое смещение относительно её базового адреса, размера, который позволяет поместиться в ней самому большому её члену, и выравнивание которой удовлетворяет всем типам объединения.
Инициализировать объединение можно только значением, имеющим тип его первого члена; таким образом, упомянутую выше переменную u можно инициализировать лишь значением типа INTEGER.

justar

Сообщения : 135
Дата регистрации : 2008-05-12
Возраст : 43
Откуда : Кишинёв, Республика Молдоа

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Пользовательские типы данных

Сообщение  Eric-S в Вт Янв 13, 2009 7:22 am

Подскажите. Хочу совместить два типа. Как это грамотно сделать?

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

Или по другому. Я хочу создать класс, но чтобы у него был синоним. Т.е. class1 и class2 это было одно и тоже, только с разными именами.

Мне это нужно, просто для более удобного коденья. Потому, что в некоторых случаях имя первого класса, совершенно не в тему, а в других имя второго класса не в тему. Но класс-то один и тот же!

Вот смотрите, забавно выходит.
Код:

dim doc as List ptr = new List ' создаём дерево
dim lst as Tree ptr = new Tree ' создаём список

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: Пользовательские типы данных

Сообщение  tux в Вт Янв 13, 2009 8:56 am

с типами помоему мона было так делать:
Код:
type mi_uinteger as uinteger
avatar
tux

Сообщения : 365
Дата регистрации : 2008-04-06
Возраст : 29
Откуда : Сибирь

Посмотреть профиль http://tux.nsk.ru/

Вернуться к началу Перейти вниз

Re: Пользовательские типы данных

Сообщение  Eric-S в Вт Янв 13, 2009 11:23 am

Спасибо! Кажись скушал и не подавился!

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: Пользовательские типы данных

Сообщение  justar в Ср Янв 14, 2009 11:04 am

Именно так и делается. Кстати, я писал об этом в статье, положившей начало данной ветке.

justar

Сообщения : 135
Дата регистрации : 2008-05-12
Возраст : 43
Откуда : Кишинёв, Республика Молдоа

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Пользовательские типы данных

Сообщение  Eric-S в Ср Янв 14, 2009 3:45 pm

Тьфу! Просмотрел статью и спросил. Сейчас ещё раз просмотрел и пошел на второй заход. Какого же было моё удивление, когда я всё же нашел это место!


Конструкция TYPE имя_типа AS тип позволяет создать cиноним к уже существующему типу данных (стандартному или ранее объявленному пользовательскому).

Простите, туплю!

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: Пользовательские типы данных

Сообщение  Gena в Вт Окт 06, 2009 4:40 pm

выводит правильно: 3 5
Ничего подобного, justar, выводит 3 3, как надо.

Gena

Сообщения : 182
Дата регистрации : 2008-11-05
Возраст : 24
Откуда : Москва

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Пользовательские типы данных

Сообщение  Спонсируемый контент


Спонсируемый контент


Вернуться к началу Перейти вниз

Предыдущая тема Следующая тема Вернуться к началу


 
Права доступа к этому форуму:
Вы не можете отвечать на сообщения