Шаг 17.
Язык программирования C#. Начала
Базовые типы и операторы. Переменные и базовые типы данных

    На этом шаге мы рассмотрим основные типы данных.

    С переменными мы кратко познакомились на предыдущих шагах. Напомним, что переменной называется именованный блок памяти. Этот блок может хранить определенное значение. Мы в программе имеем возможность прочитать эго значение и изменить его. Для получения доступа к блоку памяти используется переменная. Перед тем как переменную использовать, ее необходимо объявить. Объявление переменной подразумевает, что указывается имя переменной и ее тип. При выполнении команды, которой объявляется переменная, для этой переменной в памяти выделяется место. Каждый раз, когда мы будем обращаться к этой переменной, в действительности будет выполняться обращение к соответствующему месту в памяти. При этом совершенно не важно, где именно в памяти выделено место под переменную. Нам достаточно знать имя переменной, чтобы прочитать ее текущее значение или присвоить новое.

    Тип переменной определяет, какие значения могут присваиваться переменной. Также ти переменной влияет на то, какие операции можно выполнять с переменной. В языке C# для каждой переменной должен быть указан тип. После объявления тип переменной не может быть изменен.

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


Мы познакомимся с базовыми типами данных (иногда их еще называют простыми или примитивными типами). Способы реализации переменных, описываемые здесь, имеют отношение к переменным базовых типов. Помимо базовых типов, существуют еще и ссылочные типы данных. Данные ссылочного типа реализуются несколько иначе по сравнению реализацией данных базовых типов. Ссылочные типы мы рассмотрим при знакомстве с классами и массивами.

    В языке C# большинство базовых типов предназначено для реализации числовых значений (здесь имеются в виду целые числа и числа с плавающей точкой), символьных значений (значением символьной переменной может быть отдельный символ) и логических значений (переменная логического типа может принимать одно из двух логических значений - истина или ложь). Наибольшую группу составляют целочисленные тины - то есть тины данных, предназначенных для реализации целых чисел. Мы уже знакомы с одним из целочисленных типов (речь о типе int). Но кроме типа int в языке C# существуют и другие целочисленные типы. На первый взгляд может показаться странным, что для реализации целых чисел используется несколько типов данных. Но странного здесь ничего нет: хотя каждый раз имеем дело с целыми числами, записываются они по-разному. Если кратко, то есть две "позиции", по которым отличаются способы реализации целых чисел (при использовании разных типов):


Для записи целых чисел в памяти компьютера используется битовое представление. Вся память, выделяемая для записи числа, разбита на отдельные блоки - биты. Каждый бит может содержать значения 0 или 1. Блок из 8 битов называется байтом. Для хранения данных определенного типа выделяется одно и то же количество битов. Например, для записи значений типа int в языке C# выделяется 32 бита, или 4 байта. Таким образом, значение типа int представляет собой последовательность из 32 нулей и единиц. Такой код интерпретируется как двоичное представление числа. Чем больше выделяется битов для записи числа, тем больше значений можно закодировать. Если через n обозначить количество битов, с помощью которых кодируются числа, то всего с помощью такого количества битов можно реализовать 2n разных чисел. Для значений типа int количество чисел, которые можно реализовать через переменную данного типа, равно 232. Диапазон возможных значений для переменной типа int ограничен числами -231 (число -2147483648) и 231 - 1 (число -2147483647) включительно. Всего с учетом нуля получается 232 разных чисел.

    Поскольку в общем случае приходится кодировать не только положительные, но и отрицательные числа, то один из битов (старший бит) используется как индикатор того, положительное число или отрицательное. У положительных чисел знаковый бит нулевой, а у отрицательных чисел - единичный. Более детально способы кодирования целых чисел рассматриваются в шагах, посвященных побитовым операторам.


    Для реализации целых чисел, кроме типа int, используются типы byte, sbyte, short, ushort, uint, long и ulong. Значения типов byte и sbyte кодируются с помощью 8 битов. Различие между типами в том, что значение типа byte - эго неотрицательное число. Значение типа sbyte может быть и положительным, и отрицательным.


Начальная буква s в названии типа sbyte - это "остаток" от слова "signed" (что означает "со знаком").

    С помощью 8 битов можно записать 28 = 256 разных чисел. Поэтому возможное значение для переменной типа byte лежит в пределах от 0 до 255 включительно. Значение переменной типа sbyte находится в пределах от -128 до 127 включительно.

    Для хранения значения типов short и ushort выделяется 16 битов. То есть "мощность" этих типов одинакова. Но тип short используется для работы с отрицательными и положительными числами, а тип ushort используют при работе с неотрицательными числами.


Начальная буква и в названии типа ushort, а также в названиях рассматриваемых далее типов uint и ulong появилась из слова "unsigned" (что означает "без знака").

    Следующая пара типов int (числа со знаком) и uint (неотрицательные числа) использует 32 бита для хранения числовых значений. Наконец, самые "мощные" целочисленные типы - это long и ulong. Переменные данных типов хранятся в ячейках памяти объемом в 64 бита. Значения типа long интерпретируются как числа со знаком, а значения типа ulong обрабатываются как неотрицательные числа. Более подробная информация не только о целочисленных типах, но и о прочих базовых типах языка C# приведена в таблице 1.

Таблица 1. Базовые типы языка C#
Тип Память в битах Диапазон значений Описание Структура
byte 8 от 0 до 255 Целое неотрицательное число Byte
sbyte 8 от -128 до 127 Целое число SByte
short 16 от -32768 до 32767 Целое число Intl6
ushort 16 от 0 до 65535 Целое неотрицательное число UIntl6
int 32 от - 2147483648 до 2147483647 Целое число Int32
uint 32 от 0 до 4294967295 Целое неотрицательное число
long 64 от -9223372036854775808 до 9223372036854775807 Целое число Int64
ulong 64 от 0 до 18446744073709551615 Целое неотрицательное число UInt64
float 32 от 1.5Е-45 до 3.4Е+38 Действительное число (с плавающей точкой) Single
double 64 от 5Е-324 до 1.7Е+308 Действительное число (с плавающей точкой) двойной точности Double
decimal 128 от 1Е-28 до 7.9Е+28 Действительное число для выполнения особо точных (финансовых) расчетов Decimal
char 16 от 0 до 65535 Символьное значение Char
bool 8 значения true и false Логическое значение Boolean

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


В действительности значения базовых типов реализуются как экземпляры структур. Структуры мы рассмотрим немного позже. В таблице 1 для каждого базового типа указана структура, которая соответствует данному типу. Фактически идентификаторы базовых типов являются псевдонимами для названий структур. Например, для работы с целыми числами можно создать переменную базового типа int, что означает создание экземпляра структуры Int32. То есть ситуация не самая тривиальная, но в большинстве случаев это не играет никакой роли.

    Кроме целых чисел часто приходится иметь дело с действительными числами, или числами с плавающей точкой. Такие числа имеют целую часть и дробную, которая указывается через точку после целой части.


Для чисел с плавающей точкой также можно использовать экспоненциальное (компьютерное) представление в виде мантиссы и показателя степени. Действительное число представляется в виде произведения мантиссы (действительное число) на 10 в целочисленной степени. Записать число в таком представлении можно следующим образом: указать мантиссу, затем символ Е (или е) и целое число, определяющее показатель степени. Например, выражение 1.5Е-45 означает число 1,5*10-45, а выражение 3.4Е+38 соответствует числу 3.4*1038. Если показатель степени положительный, то знак + можно не указывать.

    Для реализации действительных чисел используются типы float, double и decimal. Для значения типа float выделяется 32 бита, а под значение типа double выделяется 64 бита. Поэтому числа, реализованные как значения тина double, имеют большую "точность". Наименьшее по модулю float-число равно 1.5*10-45, а самое маленькое по модулю double-число равно 5*10-324. Верхняя граница для значений типа double составляет величину 1.7*10308, а float-значения ограничены сверху числом 3.4*1038. В этом смысле тип double является более предпочтительным.


Есть и другая причина для приоритетного использования типа double по сравнению с типом float. Ее мы обсудим немного позже.

    Помимо типов float и double в языке C# есть тип decimal. Под значение типа decimal выделяется 128 битов, что в два раза больше, чем для типа double. Но главное назначение такой мощной "поддержки" - обеспечить высокую точность вычислений, выполняемых со значениями типа decimal. Обычно необходимость в высокой точности операций возникает при финансовых расчетах. Поэтому обычно тип decimal упоминают как специальный тип, предназначенный для поддержки высокоточных финансовых вычислений.

    Для работы с символьными значениями предназначен тип char. Значением переменной типа char может быть отдельный символ (буква). Для хранения такого значения в памяти выделяется 16 битов.


Значения типа char кодируются так же, как и целые числа - имеем дело с 16 битами, заполненными нулями и единицами. Аналогичным образом кодируются, например, значения типа ushort. Поэтому технически char-значение можно рассматривать как неотрицательное числовое значение, которое попадает в диапазон целых чисел от 0 до 65535. Но обрабатывается такое значение несколько иначе (по сравнению с обработкой целочисленных значений), а именно: по двоичному коду определяется число, и затем из кодовой таблицы берется символ с соответствующим кодом.

    Наконец, тип bool предназначен для работы с логическими значениями. Поэтому этот тип обычно называют логическим. Переменная логического типа может принимать одно из двух значений: true (истина) или false (ложь). Значения логического типа используются в управляющих инструкциях - таких, как условный оператор или операторы цикла.

    На следующем шаге мы рассмотрим литералы.




Предыдущий шаг Содержание Следующий шаг