Хранение данных в программе: типы данных
Когда ты начинаешь изучать новый язык программирования, одной из первых вещей, которую ты должны вызубрить, являются типы данных языка. Практически каждая программа управляет данными, и для правильного управления этими данными ты должен полностью понимать доступные типы. Ошибки неправильного использования типа данных занимают второе место по сравнению с синтаксическими ошибками, но они намного сложнее. Компилятор может отлавливать синтаксические ошибки и некоторые ошибки неправильного приведения типа данных, но большинство ошибок возникают уже во время работы программы и часто только при использовании определённых типов данных. Такие прерывистые ошибки трудно найти и их трудно исправить. Знание вида, размера и ограничений данных поможет свести такие ошибки к минимуму.
Иерархия типов данных
У 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. Это только предложения; какой тип данных ты в конечном итоге используешь, будет определяться потребностями твоей программы.