Хранение данных в программе: типы данных
Когда ты начинаешь изучать новый язык программирования, одной из первых вещей, которую ты должны вызубрить, являются типы данных языка. Практически каждая программа управляет данными, и для правильного управления этими данными ты должен полностью понимать доступные типы. Ошибки неправильного использования типа данных занимают второе место по сравнению с синтаксическими ошибками, но они намного сложнее. Компилятор может отлавливать синтаксические ошибки и некоторые ошибки неправильного приведения типа данных, но большинство ошибок возникают уже во время работы программы и часто только при использовании определённых типов данных. Такие прерывистые ошибки трудно найти и их трудно исправить. Знание вида, размера и ограничений данных поможет свести такие ошибки к минимуму.
Иерархия типов данных
У FreeBASIC есть все стандартные числовые типы данных, которые ты ожидаешь для базового компилятора, а также указатели, которые обычно ты найдёшь только в языках низкого уровня, таких как Си.
Типы данных
│
├───простые
│ │
│ ├───целочисленные
│ │ │
│ │ ├───знаковые
│ │ │
│ │ └───беззнаковые
│ │
│ ├───дробные (вещественные)
│ │
│ ├───логический
│ │
│ ├───указатели
│ │
│ └───ссылки
│
└───сложные
│
├───перечисления
│
├───массивы
│
├───строки
│
├───структуры
│
└───объединения
В данном уроке мы будем изучать простые типы данных.
Целочисленные типы данных
Основные типы данных: Byte
, Short
, Long
, LongInt
, Integer
. К ним может добавляться приставка U, превращающая их в беззнаковый тип: UByte
, UShort
, ULong
, ULongInt
, UInteger
.
Знаковые целые
Знаковые целые могут хранить в себе отрицательные значения, положительные значения и 0.
Знаковое целое | Размер в памяти, байт | Размер в памяти, бит | Минимальное значение | Максимальное значение |
---|---|---|---|---|
Byte | 1 | 8 | -128 | 127 |
Short | 2 | 16 | -32768 | 32767 |
Long | 4 | 32 | -2147483648 | 2147483647 |
LongInt | 8 | 64 | -9223372036854775808 | 9223372036854775807 |
Integer | 4 или 8 | 32 или 64 | Как у Long или LongInt | Как у Long или LongInt |
Диапазон хранимых значений для типа Integer
зависит от битности платформы: на 32‐битной платформе такой же как у Long
, на 64‐битной такой же как у LongInt
.
Беззнаковые целые
Беззнаковое целые могут хранить в себе положительные значения и 0.
Беззнаковое целое | Размер в памяти, байт | Размер в памяти, бит | Минимальное значение | Максимальное значение |
---|---|---|---|---|
UByte | 1 | 8 | -128 | 127 |
UShort | 2 | 16 | -32768 | 32767 |
ULong | 4 | 32 | -2147483648 | 2147483647 |
ULongInt | 8 | 64 | -9223372036854775808 | 9223372036854775807 |
UInteger | 4 или 8 | 32 или 64 | Как у ULong или ULongInt | Как у ULong или ULongInt |
Диапазон хранимых значений для типа UInteger
зависит от битности платформы: на 32‐битной платформе такой же как у ULong
, на 64‐битной такой же как у ULongInt
.
Дробные типы
Типы данных с плавающей запятой, Single
и Double
могут хранить в себе дробные числа. Такие числа подвержены ошибкам округления, которые накапливаются при длительных вычислениях. Очень плохая идея использовать такие числа для хранения денежных сумм.
Дробный тип данных | Размер в памяти, байт | Размер в памяти, бит | Минимальное значение | Максимальное значение |
---|---|---|---|---|
Single | 4 | 32 | 1.1E-38 | 3.43E+38 |
Double | 8 | 64 | -2.2E-308 | +1.7E+308 |
Логический тип
Этот тип данных может принимать только два значения: истину True
или ложь False
. Технически представляет из себя целое число, все биты которого либо сброшены в 0, либо установлены в 1.
Логический тип | Размер в памяти, байт | Размер в памяти, бит | Минимальное значение | Максимальное значение |
---|---|---|---|---|
Boolean | 1 | 8 | True | False |
Из‐за того, что Boolean
можно трактовать как знаковое число, вытекает интересное наблюдение. Если считать, что False
— это 00000000, тогда истина True
определяется как отрицание лжи. Отрицание нуля — это обращение всех бит числа на противоположное значение, то есть в 11111111. Знаковое число со всеми установленными битами — это -1. Следовательно, False
равна нулю, а True
— минус единице.
Указатель
Технически представляет из себя беззнаковое целое число, но на практике с указателем работают не как с числом, а как с особым типом данных, в котором хранится адрес памяти. Размер указателя зависит от платформы: на 32‐битной платформе такой же как у ULong
, на 64‐битной такой же как у ULongInt
, однако существуют и экзотические платформы, где это не так.
Указатель | Размер в памяти, байт | Размер в памяти, бит | Минимальное значение | Максимальное значение |
---|---|---|---|---|
<тип> Ptr или <тип> Pointer | Зависит от платформы | Зависит от платформы | 0 | Зависит от платформы |
Какой тип данных выбрать
Эмпирическое правило таково: использовать самый большой тип данных, который необходим для хранения ожидаемого диапазона значений. Это может показаться очевидным, но многие программы терпят неудачу, потому что программист не полностью понял диапазон данных в своей программе. Когда ты создаёшь программу, ты должен отображать не только логику программы, но и данные, связанные с каждым блоком логики. Когда ты наберёшь данные загодя, ты с меньшей вероятностью столкнёшься с ошибками типа данных. Например, если ты работаешь с кодами ASCII, которые варьируются от 0 до 255, то UByte будет хорошим выбором, так как диапазон UByte совпадает с диапазоном кодов ASCII, и ты используешь только 1 байт памяти.
Однако есть ещё одно соображение: «естественный» размер данных компьютера. В 32‐битной системе размер естественных данных составляет 4 байта или Integer
. Это означает, что компьютер оптимизирован для обработки Integer
и делает это более эффективно, даже если ты «теряешь» 3 байта памяти, используя Integer
для кода ASCII.
В большинстве случаев Integer
является хорошим универсальным выбором для целочисленных данных. Диапазон довольно велик, он обрабатывает как отрицательные, так и положительные числа, и тебе выгодно использовать естественный тип данных компьютера. Для данных с плавающей запятой Double
является хорошим выбором, поскольку, как и Integer
, он имеет хороший диапазон значений и лучшую точность, чем Single
. Это только предложения; какой тип данных ты в конечном итоге используешь, будет определяться потребностями твоей программы.