Типы данных в языке си

Размер основных типов данных в C++

Возникает вопрос: «Сколько памяти занимают переменные разных типов данных?». Вы можете удивиться, но размер переменной с любым типом данных зависит от компилятора и/или архитектуры компьютера!

Язык C++ гарантирует только их минимальный размер:

Категория Тип Минимальный размер
Логический тип данных bool 1 байт
Символьный тип данных char 1 байт
wchar_t 1 байт
char16_t 2 байта
char32_t 4 байта
Целочисленный тип данных short 2 байта
int 2 байта
long 4 байта
long long 8 байт
Тип данных с плавающей запятой float 4 байта
double 8 байт
long double 8 байт

Фактический размер переменных может отличаться на разных компьютерах, поэтому для его определения используют оператор sizeof.

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

#include <iostream>

int main()
{
std::cout << «bool:\t\t» << sizeof(bool) << » bytes» << std::endl;
std::cout << «char:\t\t» << sizeof(char) << » bytes» << std::endl;
std::cout << «wchar_t:\t» << sizeof(wchar_t) << » bytes» << std::endl;
std::cout << «char16_t:\t» << sizeof(char16_t) << » bytes» << std::endl;
std::cout << «char32_t:\t» << sizeof(char32_t) << » bytes» << std::endl;
std::cout << «short:\t\t» << sizeof(short) << » bytes» << std::endl;
std::cout << «int:\t\t» << sizeof(int) << » bytes» << std::endl;
std::cout << «long:\t\t» << sizeof(long) << » bytes» << std::endl;
std::cout << «long long:\t» << sizeof(long long) << » bytes» << std::endl;
std::cout << «float:\t\t» << sizeof(float) << » bytes» << std::endl;
std::cout << «double:\t\t» << sizeof(double) << » bytes» << std::endl;
std::cout << «long double:\t» << sizeof(long double) << » bytes» << std::endl;
return 0;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

#include <iostream>

intmain()

{

std::cout<<«bool:\t\t»<<sizeof(bool)<<» bytes»<<std::endl;

std::cout<<«char:\t\t»<<sizeof(char)<<» bytes»<<std::endl;

std::cout<<«wchar_t:\t»<<sizeof(wchar_t)<<» bytes»<<std::endl;

std::cout<<«char16_t:\t»<<sizeof(char16_t)<<» bytes»<<std::endl;

std::cout<<«char32_t:\t»<<sizeof(char32_t)<<» bytes»<<std::endl;

std::cout<<«short:\t\t»<<sizeof(short)<<» bytes»<<std::endl;

std::cout<<«int:\t\t»<<sizeof(int)<<» bytes»<<std::endl;

std::cout<<«long:\t\t»<<sizeof(long)<<» bytes»<<std::endl;

std::cout<<«long long:\t»<<sizeof(longlong)<<» bytes»<<std::endl;

std::cout<<«float:\t\t»<<sizeof(float)<<» bytes»<<std::endl;

std::cout<<«double:\t\t»<<sizeof(double)<<» bytes»<<std::endl;

std::cout<<«long double:\t»<<sizeof(longdouble)<<» bytes»<<std::endl;

return;

}

Вот результат, полученный на моем компьютере:

Ваши результаты могут отличаться, если у вас другая архитектура, или другой компилятор

Обратите внимание, оператор sizeof не используется с типом void, так как последний не имеет размера

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

Интересно то, что sizeof — это один из 3-х операторов в языке C++, который является словом, а не символом (еще есть new и delete).

Вы также можете использовать оператор sizeof и с переменными:

#include <iostream>

int main()
{
int x;
std::cout << «x is » << sizeof(x) << » bytes» << std::endl;
}

1
2
3
4
5
6
7

#include <iostream>
 

intmain()

{

intx;

std::cout<<«x is «<<sizeof(x)<<» bytes»<<std::endl;

}

Результат выполнения программы:

На следующих уроках мы рассмотрим каждый из фундаментальных типов данных языка С++ по отдельности.

Типы чисел с плавающей точкой (по IEEE 754)[править]

Число половинной точности (Binary16, Half precision)править

Число́ полови́нной то́чности  — компьютерный формат представления чисел, занимающий в памяти половину машинного слова (в случае 32-битного компьютера — бит или байта). В силу невысокой точности этот формат представления чисел с плавающей запятой обычно используется в видеокартах, где небольшой размер и высокая скорость работы важнее точности вычислений.

Знак
Порядок Мантисса
1,
14 10 9

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

Ограничения точности

  • Целые от нуля до передаются как есть.
  • Целые от до округляются к ближайшему чётному целому.
  • Целые от до округляются до ближайшего целого, делящегося нацело на четыре.
  • Целые от до округляются до ближайшего целого, делящегося на восемь.
  • Целые от до округляются до ближайшего целого, делящегося на шестнадцать.
  • Целые от до округляются до ближайшего целого, делящегося на тридцать два.

Число одинарной точности (Binary32, Single precision, float)править

Число́ одина́рной то́чности — компьютерный формат представления чисел, занимающий в памяти одно машинное слово (в случае 32-битного компьютера — бита или байта). Используется для работы с вещественными числами везде, где не нужна очень высокая точность.

Знак
Порядок (8 бит) Мантисса (23+1 бита)
1,
30 23 22

Порядок записан со сдвигом .

Число двойной точности (Binary64, Double precision, double)править

Число́ двойно́й то́чности
компьютерный формат представления чисел, занимающий в памяти два машинных слова (в случае 32-битного компьютера — бита или байт). Часто используется благодаря своей неплохой точности, даже несмотря на двойной расход памяти и сетевого трафика относительно чисел одинарной точности.

Знак
Порядок(11 бит) Мантисса(52+1 бит)
1,
62 52 51

Порядок записан со сдвигом .

Число четверной точности (Binary128, Quadruple precision)править

Число́ четверно́й то́чности
компьютерный формат представления чисел, занимающий в памяти четыре машинных слова (в случае 32-битного компьютера — бит или байт). Используется в случае необходимости крайне высокой точности.

Знак
Порядок(15 бит) Мантисса(112+1 бит)
1,
126 112 111
Мантисса(112+1 бит)

Порядок записан со сдвигом .

Обычно этот формат реализуется программно, случаи аппаратной реализации крайне редки. Также не гарантируется поддержка этого типа в языках программирования, хотя кое-где она и реализована (например, компилятор gcc для архитектуры x86 позволяет использовать тип __float128, являющийся программной реализацией числа с четверной точностью).
В совокупности эти факторы делают Quadruple весьма экзотичным и редко встречающимся форматом чисел с плавающей запятой.

Диапазон значений чисел с плавающей запятойправить

Диапазон чисел, которые можно записать данным способом, зависит от количества бит, отведённых для представления мантиссы и показателя. Пара значений показателя (когда все разряды нули и когда все разряды единицы) зарезервирована для обеспечения возможности представления специальных чисел. К ним относятся ноль, значения NaN (Not a Number, «не число», получается как результат операций типа деления нуля на ноль) и .

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

Название в IEEE 754 Название типа переменной в Си Диапазон значений Бит в мантиссе Бит на переменную
Half precision 6,10×10-5..65504 11 16
Single presicion float -3,4×1038..3,4×1038 23 32
Double precision double -1,7×10308..1,7×10308 53 64
Extended precision На некоторых архитектурах (например в сопроцессоре Intel) long double -3,4×104932..3,4×104932 65 80

Работа с типом doubleWork with the double type

Числовой тип представляет число с плавающей запятой двойной точности.The numeric type represents a double-precision floating point number. Эти термины могут быть новыми для вас.Those terms may be new to you. Число с плавающей запятой можно использовать для представления нецелых чисел, которые могут быть очень большими или малыми.A floating point number is useful to represent non-integral numbers that may be very large or small in magnitude. Число двойной точности — это относительный термин, описывающий количество двоичных разрядов, используемых для хранения значения.Double-precision is a relative term that describes the number of binary digits used to store the value. Числа двойной точности имеют в два раза больше двоичных символов по сравнению с числами одиночной точности.Double precision numbers have twice the number of binary digits as single-precision. На современных компьютерах числа двойной точности используются чаще, чем одиночной.On modern computers, it’s more common to use double precision than single precision numbers. Числа одиночной точности объявляются с помощью ключевого слова .Single precision numbers are declared using the keyword.
Рассмотрим их.Let’s explore. Добавьте следующий код и просмотрите результат:Add the following code and see the result:

Обратите внимание, что ответ включает десятичную долю частного.Notice that the answer includes the decimal portion of the quotient. Попробуйте более сложное выражение с типом double:Try a slightly more complicated expression with doubles:. Диапазон значений типа double гораздо больше, чем диапазон значений целых чисел.The range of a double value is much greater than integer values

Добавьте следующий фрагмент после написанного кода:Try the following code below what you’ve written so far:

Диапазон значений типа double гораздо больше, чем диапазон значений целых чисел.The range of a double value is much greater than integer values. Добавьте следующий фрагмент после написанного кода:Try the following code below what you’ve written so far:

Значения выводятся в экспоненциальном представлении.These values are printed out in scientific notation. Число слева от символа является значащим.The number to the left of the is the significand. Число справа — это показатель степени, который равен 10.The number to the right is the exponent, as a power of 10.

Так же, как десятичные числа в математике, значения double в C# могут содержать ошибки округления.Just like decimal numbers in math, doubles in C# can have rounding errors. Выполните этот код:Try this code:

Вы знаете, что периодическая десятичная дробь не равняется .You know that repeating isn’t exactly the same as .

ЗадачаChallenge

Выполните другие вычисления с большими числами, малыми числами, умножением и делением с помощью типа .Try other calculations with large numbers, small numbers, multiplication, and division using the type. Попробуйте выполнить более сложные вычисления.Try more complicated calculations.

После того как вы решите сложную задачу, поместите написанный код в новый метод.After you’ve spent some time with the challenge, take the code you’ve written and place it in a new method. Присвойте этому методу имя .Name that new method .

Объявление и инициализация переменных

В общем случае при объявлении переменной в C#, вначале указывается тип данных переменной, затем ее имя:

int nVal;
string strVal;

Задание значения переменной можно произвести в момент инициализации:

int radius = 10;
string name = "John";

либо после инициализаций:

string name;
name = "John";

Необходимо иметь ввиду, что переменную нельзя использовать до тех пор пока она не будет проинициализирована, Например, выполнение следующей программы завершится с ошибкой:

int notInitedVal;
Console.Write(notInitedVal);

В примерах мы не будем приводить код импорта и объявления класса. В конце главы будет приведен листинг программы со всеми примерами из данного урока.

Ключевое слово new

Ключевое слово new, как правило, используется при инициализации переменных, которые имеют ссылочный тип данных. О том, что это такое мы расскажем чуть ниже. Пусть у нас есть класс Rectangle

class Rectangle
{
    public double Width = 0;
    public double Height = 0;
}

Данный класс нам нужен только для демонстрации, при разработке собственных классов не стоит создать поля с ключевым словом public. О создании классов и основах объектно-ориентированного программирования будет рассказано в одном из ближайших уроков.

Создадим переменную класса Rectangle

Rectangle rect = new Rectangle();
Console.WriteLine($"Rectangle Width={rect.Width}, Height={rect.Height}");

Переменные типа int, double и т.п. также можно проинициализировать с помощью ключевого слова new, в этом случае будет присвоено значение по умолчанию:

int newInitedValue = new int();
Console.WriteLine("Default int value: " + newInitedValue);

Ключевое слово var. Неявная типизация

При объявлении переменной вместо явного задания типа можно поставить ключевое слово var. В этом случае будет использована система вывода типов для определения типа переменной по ее значению.

int v1 = 12345;
var v2 = 12345;

Console.WriteLine($"Type of v1: {v1.GetType()}\nType of v2: {v2.GetType()}");

При работе с var необходимо помнить следующее:

  • использовать var можно только для объявления локальных переменных;
  • var нельзя использоваться для объявления типа возвращаемого значения, типов полей и параметров;
  • при объявлении переменной с использованием var она обязательно должна быть проинициализирована, при этом использовать для этого null запрещено;
  • объявлять переменную допускающую null-значение с использованием лексемы ? через var нельзя.

Introduction to C float types

C provides various floating-point types that represent non-integer number with a decimal point at any position. For example, with integer types, you only can have numbers  , , … however with floating-point type, you can have , , and so on.

There are three standard floating-point types in C:

  • : for numbers with single precision.
  • : for numbers with double precision.
  • : for numbers with extended precision.

The following table illustrates the technical attributes of various floating-point types in C. It is important to notice that this is only the minimal requirement for storage size defined by C.

Type Size Ranges Smallest Positive Value Precision
float 4 bytes ±3.4E+38 1.2E-38 6 digits
double 8 bytes ±1.7E+308 2.3E-308 15 digits
long double 10 bytes ±1.1E+4932 3.4E-4932 19 digits

Переполнение

Вопрос: «Что произойдет, если мы попытаемся использовать значение, которое находится вне диапазона значений определенного типа данных?». Ответ: «Переполнение».

Переполнение (англ. «overflow») случается при потере бит из-за того, что переменной не было выделено достаточно памяти для их хранения.

На уроке №28 мы говорили о том, что данные хранятся в бинарном (двоичном) формате и каждый бит может иметь только 2 возможных значения ( или ). Вот как выглядит диапазон чисел от 0 до 15 в десятичной и двоичной системах:

Десятичная система Двоичная система
1 1
2 10
3 11
4 100
5 101
6 110
7 111
8 1000
9 1001
10 1010
11 1011
12 1100
13 1101
14 1110
15 1111

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

Полиморфизм

полиморфизмом

В итоге

  • выделяйте главные характеристики объекта;
  • выделяйте общие свойства и поведение и используйте наследование при создании объектов;
  • используйте абстрактные типы для описания объектов;
  • старайтесь всегда скрывать методы и поля, относящиеся к внутренней реализации класса.

Типы с плавающей точкой

Числа с плавающей точкой (иногда их называют действительными числами) применяются при вычислении выражений, в которых требуется точность до десятичного знака. Например, это может быть вычисление квадратного корня, значений синуса, косинуса и т.п. Существует два типа с плавающей точкой: float и double, которые представляют числа одинарной и двойной точности.

Слово «плавающая» означает, что десятичная точка может располагаться в любом месте (она «плавает»). Вот коты плавать не особенно любят, поэтому они не float и не double.

Тип float

Тип float определяет значение одинарной точности, которое занимает 32 бит. Переменные данного типа удобны, когда требуется дробная часть без особой точности, например, для денежных сумм.

Рекомендуется добавлять символ F или f для обозначения этого типа, иначе число будет считаться типом double.

Конвертируем из строки.

Класс Float является оболочкой для данного типа. Без необходимости не используйте в Android класс Float.

Также есть специальный класс BigDecimal для проведения арифметических действий повышенной точности (финансовые расчёты).

Тип double

Тип double обеспечивает двойную точность, что видно из его названия (double — двойная). Занимает 64 бит для хранения значений. Многие математические функции возвращают значения типа double. Кстати, современные процессоры оптимизированы под вычисления значений двойной точности, поэтому они предпочтительнее, чем тип float.

Тип double содержит не только числа, но и слова. Сейчас вам докажу. Разделим число типа double на ноль. Ошибки не произойдёт.

Пример вернёт значение Infinity (Бесконечность). Если разделить отрицательное число на ноль, то вернётся -Infinity.

А что произойдёт, если сложить две бесконечности? Если рассуждать логически, то сломается интернет, наступит конец света или можно вызвать Волдеморта. Я долго не решался, но потом набрался храбрости и попробовал.

Вернулось ещё одно слово — NaN. Что это вообще? Может должно вернуться Nyan — ну вы знаете, это странный котик, который летит бесконечно в космосе, оставляя за собой шлейф из радуги.

Умножать две бесконечности я побоялся. И вам не советую.

Класс Double является оболочкой для данного типа. Без необходимости не используйте в Android класс Double.

Конвертация double в строку

При работе с числами double следует держать ухо востро. Рассмотрим пример конвертации трёх чисел.

Первые два числа нормально преобразовались, а вот третье число преобразовалось в строку в странном виде (на самом деле это научное представление числа). И это может источником проблемы при передаче строки куда-нибудь, например, на сервер. Если сервер не ожидает от вас такой подлости, то будет генерировать ошибки из-за странной записи. Нужно найти другие способы конвертации.

Первый способ — используем String.format().

Последний пример самый подходящий для нас, но вам нужно знать, сколько знаков идёт после десятичной точки. Остальные два пригодятся, если число можно округлить.

Второй способ — метод Double.toString(). У меня метод превратил число в «непонятную» строку. А у некоторых этот пример возвращал строку в нормальном виде. Не заслуживает доверия.

Третий способ — добавить пустую строку. В Android не помогло, хотя тоже утверждается, что у кого-то выводится в нормальном виде. Врут, наверное.

Четвёртый экзотический способ, которым редко пользуются — DecimalFormat.

What is precision?

If you consider the fraction 5/3, this number can be represented in decimal as  with infinite 6. When you use the floating-point type with limited bytes to store infinite number, it is impossible. Therefore the floating-point value can be stored only with a limited precision. The precision is expressed as a number of significant digits or in another way, the precision is defined as how many digits that a number can represent without data loss.

For example, the type with 4 bytes = 4 x 8 bits = 32 bits, is for numbers with single precision. It means that a float gives 1 sign bit, 8 bits of exponent and 23 bits of significand.

The type is for a number with the double precision that gives 1 sign bit, 11 bits of exponent and 52 bits of significand. (8 bytes x 8 bits = 64 bits = 1 bits + 52 bits + 11 bits).

Характеристики типов с плавающей запятойCharacteristics of the floating-point types

C# поддерживает следующие предварительно определенные типы с плавающей запятой:C# supports the following predefined floating-point types:

Ключевое слово или тип C#C# type/keyword Приблизительный диапазон значенийApproximate range ТочностьPrecision РазмерSize Тип .NET.NET type
От ±1,5 x 10−45 до ±3,4 x 1038±1.5 x 10−45 to ±3.4 x 1038 6–9 цифр~6-9 digits 4 байта4 bytes System.Single
от ±5,0 × 10−324 до ±1,7 × 10308±5.0 × 10−324 to ±1.7 × 10308 15–17 цифр~15-17 digits 8 байт8 bytes System.Double
от ±1,0 x 10-28 до ±7,9228 x 1028±1.0 x 10-28 to ±7.9228 x 1028 28-29 знаков28-29 digits 16 байт16 bytes System.Decimal

В приведенной выше таблице каждый тип ключевого слова C# из крайнего левого столбца является псевдонимом для соответствующего типа .NET.In the preceding table, each C# type keyword from the leftmost column is an alias for the corresponding .NET type. Они взаимозаменяемые.They are interchangeable. Например, следующие объявления объявляют переменные одного типа:For example, the following declarations declare variables of the same type:

По умолчанию все типы с плавающей запятой имеют значение .The default value of each floating-point type is zero, . Все типы с плавающей запятой имеют константы и с минимальным и максимальными итоговыми значениями этого типа.Each of the floating-point types has the and constants that provide the minimum and maximum finite value of that type. Типы и также предоставляют константы, обозначающие бесконечные и нечисловые значения.The and types also provide constants that represent not-a-number and infinity values. Например, тип предоставляет следующие константы: Double.NaN, Double.NegativeInfinity и Double.PositiveInfinity.For example, the type provides the following constants: Double.NaN, Double.NegativeInfinity, and Double.PositiveInfinity.

Так как тип характеризуется более высокой точностью и меньшим диапазоном, чем и , он подходит для финансовых расчетов.Because the type has more precision and a smaller range than both and , it’s appropriate for financial and monetary calculations.

В одном и том же выражении можно сочетать и целочисленные типы, и типы и .You can mix integral types and the and types in an expression. В этом случае целочисленные типы неявно преобразуются в один из типов с плавающей запятой. При необходимости тип неявно преобразуется в .In this case, integral types are implicitly converted to one of the floating-point types and, if necessary, the type is implicitly converted to . Выражение вычисляется следующим образом.The expression is evaluated as follows:

  • Если в выражении есть тип , оно оценивается как или в реляционных сравнениях или сравнениях на равенство.If there is type in the expression, the expression evaluates to , or to in relational and equality comparisons.
  • Если в выражении нет типа , оно оценивается как или в реляционных сравнениях или сравнениях на равенство.If there is no type in the expression, the expression evaluates to , or to in relational and equality comparisons.

Можно также смешивать целочисленные типы и тип в выражении.You can also mix integral types and the type in an expression. В этом случае целочисленные типы неявно преобразуются в тип , а выражение вычисляется как или в реляционных сравнениях и сравнениях на равенство.In this case, integral types are implicitly converted to the type and the expression evaluates to , or to in relational and equality comparisons.

Тип нельзя смешивать с типами и в выражении.You cannot mix the type with the and types in an expression. В этом случае, если требуется выполнить арифметические операции или операции сравнения или равенства, необходимо явно преобразовать операнды из типа или в тип , как показано в следующем примере:In this case, if you want to perform arithmetic, comparison, or equality operations, you must explicitly convert the operands either from or to the type, as the following example shows:

Можно использовать строки стандартных числовых форматов или строки пользовательских числовых форматов для форматирования значения с плавающей запятой.You can use either standard numeric format strings or custom numeric format strings to format a floating-point value.

Конвертация чисел в экспоненциальную запись

Для конвертации чисел в экспоненциальную запись необходимо следовать процедуре, указанной ниже:

   Ваш экспонент начинается с нуля.

   Переместите разделительную точку (которая разделяет целую и дробную части) влево, чтобы слева от нее осталась только одна ненулевая цифра:

   каждое перемещение точки влево увеличивает экспонент на ;

   каждое перемещение точки вправо уменьшает экспонент на .

   Откиньте все нули перед первой ненулевой цифрой в целой части.

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

Рассмотрим примеры:

Самое главное, что нужно запомнить — это то, что цифры в мантиссе (часть перед ) называются значащими цифрами. Количество значащих цифр определяет точность самого значения. Чем больше цифр в мантиссе, тем точнее значение.

Общая система типов (CTS)

Под типом в C# понимается: класс, интерфейс, структура, перечисление и делегат. При разработке программного обеспечения на этом языке, фактически вы будет создавать и организовывать определенным образом взаимодействие между различными типами данных. Так как .NET – это платформа, под которую можно разрабатывать на разных языках, то существует так называемая общая система типов CTS (Common Type System), которая определяет как должны быть описаны типы, чтобы вы могли с ними работать в других языках, то есть как они должны быть представлены в CLR. CLR – это аббревиатура от Common Language Runtime – общеязыковая исполняющая среда, она отвечает за обнаружение, загрузку и управление типами, управляет памятью, отвечает за безопасность, обеспечивает работу многопоточных приложений и т.п.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector