C# – язык программирования со статической типизацией. То есть каждая переменная перед использованием должна быть объявлена и ей должен быть присвоен тип хранящихся в ней данных, который закрепляется за этой переменной на протяжении ее существования в программе.
Правила объявления и инициализации переменных
Переменные объявляются в следующей форме:
type variable_name; // type – тип данных, variable_name – имя переменной
При объявлении переменной за ней закрепляется тип и выделяется соответствующая область памяти.
Имя переменной должно соответствовать следующим правилам:
- Нельзя использовать зарезервированные слова языка C# в качестве имени;
- Имя может состоять из цифр, латинских букв и символа подчеркивания, но нельзя использовать цифру в качестве первого символа;
- Максимальная длина имени 255 символов;
Для дальнейшего использования переменную также нужно инициализировать – придать ей начальное значение.
Это можно сразу сделать в строке объявления при помощи оператора присваивания (=). При инициализации можно использовать не только константы, но и любые вычислительные выражения на основе объектов и операторов C#.
Примеры объявления и инициализации:
int my_variable; // Объявление
int 1variable; // Неправильное имя, компилятор выдаст сообщение об ошибке;
int copy_variable = my_variable; // Ошибка, так как переменная my_variable не инициализирована;
double pi = 3.1416; // Объявление с инициализацией;
bool OnOff;
bool isOn = true;
OnOff = isOn; // Отложенная инициализация;
Также, при присвоении переменной значения с плавающей точкой важно знать о суффиксах. Компиляторы зачастую по умолчанию воспринимают числа с плавающей точкой как тип double. Для типа float нужно добавлять в конце f, для decimal – m, а для double – d:
float flt = 15.36f;
decimal dcml = 30.43m;
double dbl = 10.453d;
Типы данных
В соответствии с особенностями использования разных областей памяти (стек и куча) и дальнейшего взаимодействия переменных, типы данных разделяют на типы значений (value type) и ссылочные типы (reference type). В таблице указаны встроенные типы в C# со ссылками на документацию MSDN.
Типы значений
Ссылочные типы
Целочисленные (sbyte, byte, short, ushort, int, uint, long, ulong, char)
Объявление ссылочных типов
С плавающей запятой (float, double)
Встроенные ссылочные типы
Далее рассмотрим каждый тип значений по отдельности.
Целочисленные типы
Целочисленные типы различаются между собой объемом занимаемой памяти и диапазоном возможных значений:
Тип
Системный тип (.NETFramework)
Размер в байтах
Диапазон значений
sbyte, short, int и long являются целочисленными типами со знаком. Работая с такими числами, компилятор C# в двоичном представлении считает первый бит флагом знака: 0 – положительный, 1 – отрицательный. Чтобы представить целое число со знаком минус в таком виде, его модуль преобразуется в двоичную систему счисления, биты заменяются на противоположные, а в качестве старшего бита прибавляется единица.
Чаще всего в C# используется тип int, так как он предоставляет достаточный диапазон для большинства вычислительных нужд. Если вы точно знаете будущий диапазон значений объявляемой целочисленной переменной, в идеале стоит выбрать соответствующий тип. В ином случае, поскупившись на пару байт и, использовав short вместо int, вы рискуете появлением бага в программе.
Также целочисленным переменным можно присваивать значения в шестнадцатеричной системе счисления, используя префикс 0x. Например, так:
byte sxt = 0xf0;
Отдельное внимание стоит уделить типу char, отвечающему за представление символов. Его 16-разрядный двоичный код при преобразовании в шестнадцатеричную систему счисления становится четырехзначной кодировкой символа Unicode.
Юникод охватывает символы почти всех языков мира, а так же множество спецсимволов. В десятичном представлении это целое число от 0 до 65535. Стандартный 8-битный ASCII код представляется в юникоде в оригинальном порядке от 0 до 127 (т.е. от U+0000 до U+007f). Символьные значения присваиваются при помощи одинарных кавычек:
char k = ‘c’;
Типы чисел с плавающей запятой
Типов с плавающей запятой всего два:
Тип
Системный тип (.NET Framework)
Диапазон
Точность
Размер в байтах
Как уже говорилось, при инициализации компилятор присваивает нецелочисленным значениям тип double. Также он зачастую делает это при неявном преобразовании в тип с плавающей запятой. Если же вы хотите сэкономить 4 байта, зная, что точность в данном случае не сильно важна, то можете использовать тип float при помощи суффикса f.
float value = 1.72f;
Десятичный тип
Десятичный тип (decimal) применяется там, где нужна высокая точность чисел с плавающей запятой. Он занимает 16 байт, может хранить значения в диапазоне от -7.9*1028 до 7.9*1028 с точностью до 29 знаков после запятой, и представлен системным типом System.Decimal. Создан этот тип для применения в финансовых расчетах.
decimal value = 1.72m
Логический тип
Логический тип (bool) может принимать всего два значения: true либо false. Он занимает 1 байт и наследуется от структуры System.Boolean. Переменной типа bool можно присвоить любое выражение, которое вычисляется как bool. Например:
bool c = (a == b); // Если значение a равно значению b, bool будет присвоено true, иначе false
Структура
Структура (struct) – тип, в котором можно хранить некоторое количество разнотипных переменных (полей), а также методы, операторы, свойства, конструкторы и прочее, присущее классу C#. Их различие в том, что struct – это знаковый тип, а class – ссылочный. Подробнее их различия описаны в отдельном разделе.
Пример структуры с полями:
public struct Bycicle
{
public string name = 'TwoWheels';
public byte gears = 18;
public float price = 99.99;
}
Перечисление
Перечисления объявляются ключевым словом enum. Это набор именованных констант любого целочисленного типа, кроме char. Например:
enum CountdownFromThree : byte {Zero, One, Two = 2, Three};
Хотя в примере инициализирован только перечислитель Two, остальным по умолчанию присвоены значения по порядку, начиная с 0.
Неявная типизация
В C# есть возможность неявной типизации – когда компилятор самостоятельно пытается определить тип объявленной и инициированной переменной. Делается это с помощью ключевого слова var, в объявлении заменяющего тип. При этом инициировать переменную неким значением обязательно, ведь именно по этому значению компилятор будет судить о типе переменной. Выглядит это так:
var lucky = ‘k’; // Будет выбран тип переменной char
var fin = 23.91352342132m; // Будет выбран тип переменной decimal, благодаря суффиксу m
Динамические переменные
В C# есть особый тип, предоставляющий некоторые возможности динамической типизации. Он объявляется ключевым словом dynamic. По сути, этот тип все же является статическим, но он обходит проверку компилятора. После компиляции он превращается в object. И дальше все просто: если вы правильно использовали динамический тип и дальнейший ход программы с использованием такой переменной правильно работает с любым ее значением, то вы сэкономили некоторое время исполнения и написали грациозный код, который реагирует сразу на несколько типов принимаемых значений. Если же вы допустили ошибку, то узнаете о ней уже в ходе исполнения программы, так как сами запретили компилятору распознать ее.
dynamic value = 'a';