Типы данных
Как и во многих языках программирования, в C# есть своя система типов данных, которая используется для создания переменных. Тип данных определяет внутреннее представление данных, множество значений, которые может принимать объект, а также допустимые действия, которые можно применять над объектом.
В языке C# есть следующие примитивные типы данных:
-
bool: хранит значение
trueилиfalse(логические литералы). Представлен системным типомSystem.Boolean12boolalive =true;boolisDead =false; byte: хранит целое число от
0до255и занимает 1 байт. Представлен системным типомSystem.Byte12bytebit1 = 1;bytebit2 = 102;sbyte: хранит целое число от
-128до127и занимает 1 байт. Представлен системным типомSystem.SByte12sbytebit1 = -101;sbytebit2 = 102;short: хранит целое число от
-32768до32767и занимает 2 байта. Представлен системным типомSystem.Int1612shortn1 = 1;shortn2 = 102;ushort: хранит целое число от
0до65535и занимает 2 байта. Представлен системным типомSystem.UInt1612ushortn1 = 1;ushortn2 = 102;int: хранит целое число от
-2147483648до2147483647и занимает 4 байта. Представлен системным типомSystem.Int32. Все целочисленные литералы по умолчанию представляют значения типа int:123inta = 10;intb = 0b101;// бинарная форма b =5intc = 0xFF;// шестнадцатеричная форма c = 255uint: хранит целое число от
0до4294967295и занимает 4 байта. Представлен системным типомSystem.UInt32123uinta = 10;uintb = 0b101;uintc = 0xFF;long: хранит целое число от
–9 223 372 036 854 775 808до9 223 372 036 854 775 807и занимает 8 байт. Представлен системным типомSystem.Int64123longa = -10;longb = 0b101;longc = 0xFF;ulong: хранит целое число от
0до18 446 744 073 709 551 615и занимает 8 байт. Представлен системным типомSystem.UInt64123ulonga = 10;ulongb = 0b101;ulongc = 0xFF;float: хранит число с плавающей точкой от
-3.4*1038до3.4*1038и занимает 4 байта. Представлен системным типомSystem.Singledouble: хранит число с плавающей точкой от
±5.0*10-324до±1.7*10308и занимает 8 байта. Представлен системным типомSystem.Doubledecimal: хранит десятичное дробное число. Если употребляется без десятичной запятой, имеет значение от ±1.0*10-28 до ±7.9228*1028, может хранить 28 знаков после запятой и занимает 16 байт. Представлен системным типом
System.Decimalchar: хранит одиночный символ в кодировке Unicode и занимает 2 байта. Представлен системным типом
System.Char. Этому типу соответствуют символьные литералы:123chara ='A';charb ='\x5A';charc ='\u0420';string: хранит набор символов Unicode. Представлен системным типом
System.String. Этому типу соответствуют символьные литералы.12stringhello ="Hello";stringword ="world";object: может хранить значение любого типа данных и занимает 4 байта на 32-разрядной платформе и 8 байт на 64-разрядной платформе. Представлен системным типом
System.Object, который является базовым для всех других типов и классов .NET.123objecta = 22;objectb = 3.14;objectc ="hello code";
Например, определим несколько переменных разных типов и выведем их значения на консоль:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | using System;namespace HelloApp{ class Program { static void Main(string[] args) { string name = "Tom"; int age = 33; bool isEmployed = false; double weight = 78.65; Console.WriteLine($"Имя: {name}"); Console.WriteLine($"Возраст: {age}"); Console.WriteLine($"Вес: {weight}"); Console.WriteLine($"Работает: {isEmployed}"); } }} |
Для вывода данных на консоль здесь применяется интерполяция: перед строкой ставится знак $ и после этого мы можем вводить в строку в фигурных скобках значения переменных. Консольный вывод программы:
Имя: Tom Возраст: 33 Вес: 78,65 Работает: False
Использование суффиксов
При присвоении значений надо иметь в виду следующую тонкость: все вещественные литералы рассматриваются как значения типа double. И чтобы указать, что дробное число представляет тип float или тип decimal, необходимо к литералу добавлять суффикс: F/f - для float и M/m - для decimal.
1 2 3 4 5 | float a = 3.14F;float b = 30.6f;decimal c = 1005.8M;decimal d = 334.8m; |
Подобным образом все целочисленные литералы рассматриваются как значения типа int. Чтобы явным образом указать, что целочисленный литерал представляет значение типа uint, надо использовать суффикс U/u, для типа long - суффикс L/l, а для типа ulong - суффикс UL/ul:
1 2 3 | uint a = 10U;long b = 20L;ulong c = 30UL; |
Использование системных типов
Выше при перечислении всех базовых типов данных для каждого упоминался системный тип. Потому что название встроенного типа по сути представляет собой сокращенное обозначение системного типа. Например, следующие переменные будут эквивалентны по типу:
1 2 | int a = 4;System.Int32 b = 4; |
Неявная типизация
Ранее мы явным образом указывали тип переменных, например, int x;. И компилятор при запуске уже знал, что x хранит целочисленное значение.
Однако мы можем использовать и модель неявной типизации:
1 2 3 4 5 | var hello = "Hell to World";var c = 20; Console.WriteLine(c.GetType().ToString());Console.WriteLine(hello.GetType().ToString()); |
Для неявной типизации вместо названия типа данных используется ключевое слово var. Затем уже при компиляции компилятор сам выводит
тип данных исходя из присвоенного значения. В примере выше использовалось выражение Console.WriteLine(c.GetType().ToString());,
которое позволяет нам узнать выведенный тип переменной с. Так как по умолчанию все целочисленные значения рассматриваются как значения типа
int, то поэтому в итоге переменная c будет иметь тип int или System.Int32
Эти переменные подобны обычным, однако они имеют некоторые ограничения.
Во-первых, мы не можем сначала объявить неявно типизируемую переменную, а затем инициализировать:
1 2 3 4 5 6 7 | // этот код работаетint a;a = 20;// этот код не работаетvar c;c= 20; |
Во-вторых, мы не можем указать в качестве значения неявно типизируемой переменной null:
1 2 | // этот код не работаетvar c=null; |
Так как значение null, то компилятор не сможет вывести тип данных.
double или decimal
Из выше перечисленного списка типов данных очевидно, что если мы хотим использовать в программе числа до 256, то для их хранения мы можем использоват переменные
типа byte. При использовании больших значений мы можем взять тип short, int, long. То же самое для дробных чисел - для обычных дробных чисел
можно взять тип float, для очень больших дробных чисел - тип double. Тип decimal здесь стоит особняком в том плане, что несмотря на большую разрядность по сравнению с типом
double, тип double может хранить большее значение. Однако значение decimal может содержать до 28 знаков после запятой, тогда как значение типа double - 15-16 знаков после запятой.
Decimal чаще находит применение в финансовых вычислениях, тогда как double - в математических операциях. Общие различия между этими двумя типами можно выразить следующей таблицей:
Decimal |
Double |
|
Наибольшее значение |
~1028 |
~10308 |
Наименьшее значение (без учета нуля) |
10-28 |
~10-323 |
Знаков после запятой |
28 |
15-16 |
Разрядность |
16 байт |
8 байт |
Операций в секунду |
сотни миллионов |
миллиарды |