Опубликован: 15.09.2010 | Доступ: свободный | Студентов: 4808 / 630 | Оценка: 3.97 / 3.80 | Длительность: 14:45:00
Лекция 2:

Состав языка и типы данных

< Лекция 1 || Лекция 2: 12 || Лекция 3 >

Типы данных

Данные, с которыми работает программа, хранятся в оперативной памяти. Естественно, что компилятору необходимо точно знать, сколько места они занимают, как именно закодированы и какие действия с ними можно выполнять. Все это задается при описании данных с помощью типа.

Тип данных однозначно определяет:

  • внутреннее представление данных, а следовательно и множество их возможных значений ;
  • допустимые действия над данными (операции и функции).

Например, целые и вещественные числа, даже если они занимают одинаковый объем памяти, имеют совершенно разные диапазоны возможных значений.

Каждое выражение в программе имеет определенный тип. Компилятор использует информацию о типе при проверке допустимости описанных в программе действий.

Память, в которой хранятся данные во время выполнения программы, делится на две области: стек (stack) и динамическая область, или хип (heap), чаще называемый кучей (поскольку этот термин мне не нравится, я его использовать не буду). Стек используется для хранения величин, память под которые выделяет компилятор, а в динамической области память резервируется и освобождается во время выполнения программы с помощью специальных команд. Основным местом для хранения данных в C# является хип.

Классификация типов

Типы можно классифицировать по разным признакам. Если принять за основу строение элемента, все типы можно разделить на простые (не имеют внутренней структуры) и структурированные (состоят из элементов других типов). По своему "создателю" типы можно разделить на встроенные (стандартные) и определяемые программистом. По способу хранения значений типы делятся на значимые, или типы-значения, и ссылочные. Рассмотрим в первую очередь встроенные типы C#.

Встроенные типы

Встроенные типы не требуют предварительного определения. Для каждого типа существует ключевое слово, которое используется при описании переменных, констант и т. д. Встроенные типы C# приведены в таблице 2.4. Они однозначно соответствуют стандартным классам библиотеки .NET, определенным в пространстве имен System. Как видно из таблицы, существуют несколько вариантов представления целых и вещественных величин. Программист выбирает тип каждой величины, используемой в программе, с учетом необходимого ему диапазона и точности представления данных.

Таблица 2.4. Встроенные типы C#
Название Ключевое слово Тип .NET Диапазон значений Описание Размер, битов
Логический тип bool Boolean true, false
Целые типы sbyte SByte От –128 до 127 Со знаком 8
byte Byte От 0 до 255 Без знака 8
short Int16 От –32768 до 32767 Со знаком 16
ushort UInt16 От 0 до 65535 Без знака 16
int Int32 От –2 x 109 до 2 x 109 Со знаком 32
uint UInt32 От 0 до 4 x 109 Без знака 32
long Int64 От –9 x 1018 до 9 x 1018 Со знаком 64
ulong UInt64 От 0 до 18 x 1018 Без знака 64
Символьный тип char Char От U+0000 до U+ffff Unicode-символ 16
Вещественные float Single От 1.5 x 10-45 до 3.4 x 1038 7 цифр 32
double Double От 5.0 x 10-324 до 1.7 x 10308 15–16 цифр 64
Финансовый тип decimal Decimal От 1.0 x 10-28 до 7.9 x 1028 28–29 цифр 128
Строковый тип string String Длина ограничена объемом доступной памяти Строка из Unicode-символов
Тип object object Object Можно хранить все, что угодно Всеобщий предок

Примечание

Вещественные типы и финансовый тип являются знаковыми. Для них в столбце "диапазон значений" приведены абсолютные величины допустимых значений.

Логический, или булев, тип содержит всего два значения: true (истина) и false (ложь). Их внутреннее представление программиста интересовать не должно. Все целые и вещественные типы вместе с символьным и финансовым можно назвать арифметическими типами.

Внутреннее представление величины целого типа  — целое число в двоичном коде. В знаковых типах старший бит числа интерпретируется как знаковый (0 — положительное число, 1 — отрицательное).

Вещественные типы, или типы данных с плавающей точкой, хранятся в памяти компьютера иначе, чем целочисленные. Внутреннее представление вещественного числа состоит из двух частей — мантиссы и порядка, причем каждая часть имеет знак. Длина мантиссы определяет точность числа, а длина порядка — его диапазон. Все вещественные типы могут представлять как положительные, так и отрицательные числа. Чаще всего в программах используется тип double, поскольку его диапазон и точность покрывают большинство потребностей. Этот тип имеют вещественные литералы и многие стандартные математические функции.

Тип decimal предназначен для денежных вычислений, в которых критичны ошибки округления. Величины типа decimal позволяют хранить 28–29 десятичных разрядов. Тип decimal не относится к вещественным типам, у них различное внутреннее представление. Величины денежного типа даже нельзя использовать в одном выражении с вещественными без явного преобразования типа. Использование величин финансового типа в одном выражении с целыми допускается.

Любой встроенный тип C# соответствует стандартному классу библиотеки .NET, определенному в пространстве имен System. Имя этого класса приведено в третьем столбце таблицы 2.4. Везде, где используется имя встроенного типа, его можно заменить именем класса библиотеки.

Типы литералов

Литералы (константы) тоже имеют тип. Если значение целого литерала находится внутри диапазона допустимых значений типа int, литерал рассматривается как int, иначе он относится к наименьшему из типов uint, long или ulong, в диапазон значений которого он входит. Вещественные литералы по умолчанию относятся к типу double.

Например, константа 10 относится к типу int, хотя для ее хранения достаточно и байта, а константа 2147 483 648 будет определена как uint. Для явного задания типа литерала служит суффикс, например, 1.1f, 1UL, 1000m. Явное задание применяется в основном для уменьшения количества неявных преобразований типа, выполняемых компилятором.

Типы-значения и ссылочные типы

Чаще всего типы C# разделяют по способу хранения элементов на типы-значения и ссылочные типы ( рис. 2.1). Элементы типов-значений, или значимых типов (value types), представляют собой просто последовательность битов в памяти, необходимый объем которой выделяет компилятор. Иными словами, величины значимых типов хранят свои значения непосредственно. Величина ссылочного типа хранит не сами данные, а ссылку на них (адрес, по которому расположены данные). Сами данные хранятся в хипе.

Внимание

Несмотря на различия в способе хранения, и типы-значения, и ссылочные типы являются потомками общего базового класса object.

Классификация типов данных C# по способу хранения

Рис. 2.1. Классификация типов данных C# по способу хранения

рис. 2.2 иллюстрирует разницу между величинами значимого и ссылочного типов. Одни и те же действия над ними выполняются по-разному. Рассмотрим в качестве примера проверку на равенство. Величины значимого типа равны, если равны их значения. Величины ссылочного типа равны, если они ссылаются на одни и те же данные (на рисунке b и c равны, но a не равно b даже при одинаковых значениях). Из этого следует, что если изменить значение одной величины ссылочного типа, это может отразиться на другой.

Хранение в памяти величин значимого и ссылочного типов

Рис. 2.2. Хранение в памяти величин значимого и ссылочного типов

Упаковка и распаковка

Для того чтобы величины ссылочного и значимого типов могли использоваться совместно, необходимо иметь возможность преобразования из одного типа в другой. Преобразование из типа-значения в ссылочный тип называется упаковкой (boxing), обратное преобразование — распаковкой (unboxing).

Если величина значимого типа используется в том месте, где требуется ссылочный тип, автоматически выполняется создание промежуточной величины ссылочного типа. При необходимости обратного преобразования с величины ссылочного типа "снимается упаковка", и в дальнейших действиях участвует только ее значение.

Вопросы и задания для самостоятельной работы студента

  1. Перечислите и опишите лексемы языка C#.
  2. Перечислите и опишите литералы языка C#.
  3. Перечислите встроенные типы данных и опишите их.
  4. Приведите классификацию типов данных C#.
  5. Какие элементы стандартных классов .NET, соответствующих встроенным типам языка, вы знаете?
  6. Опишите отличия значимых и ссылочных типов. В чем состоят процессы упаковки и распаковки?
< Лекция 1 || Лекция 2: 12 || Лекция 3 >
Stefan Berzan
Stefan Berzan
Молдова, Кишинев
Дмитрий Казимиров
Дмитрий Казимиров
Россия, Омск