Размеры данных c. Какие особенности типов данных с плавающей запятой? Целочисленные типы данных

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

  • прописные, строчные латинские буквы A, B, C…, x, y, z и знак подчеркивания;
  • арабские цифры от 0 до 9;
  • специальные знаки: { } , | , () + - / % * . \ ‘ : ? < > = ! & # ~ ; ^
  • символы пробела, табуляции и перехода на новую строку.

В тесте программы можно использовать комментарии . Если текст с двух символов «косая черта» // и заканчивается символом перехода на новую строку или заключен между символами /* и */, то компилятор его игнорирует.

Данные в языке C++

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

Для формирования других типов данных используют основные и так называемые спецификаторы. В C++ определенны четыре спецификатора типов данных:

  • short - короткий;
  • long - длинный;
  • signed - знаковый;
  • unsigned - беззнаковый.

Целочисленный тип

Переменная типа int в памяти компьютера может занимать либо 2, либо 4 байта. Это зависит разрядности процессора. По умолчанию все целые типы считаются знаковыми, то есть спецификатор signed можно не указывать. Спецификатор unsigned позволяет представлять только положительные числа. Ниже представлены некоторые диапазоны значений целого типа

Тип Диапазон Размер
int -2147483648…2147483647 4 байта
unsigned int 0…4294967295 4 байта
signed int -2147483648…2147483647 4 байта
short int -32768…32767 2 байта
long int -2147483648…2147483647 4 байта
unsigned short int 0…65535 2 байта

Вещественный тип

Число с плавающей точкой представлено в форме mE +- p, где m - мантисса (целое или дробное число с десятичной точкой), p - порядок (целое число). Обычно величины типа float занимают 4 байта, а double 8 байт. Таблица диапазонов значений вещественного типа:

float 3,4E-38…3,4E+38 4 байта
double 1,7E-308…1,7E+308 8 байт
long double 3,4E-4932…3,4E+4932 8 байт

Логический тип

Переменная типа bool может принимать только два значения true (истина) или fasle (ложь). Любоезначение, не равное нулю, интерпретируется как true. Значение false представлено в памяти как 0.

Тип void

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

Преобразование типов данных

В C++ различают два вида преобразования типов данных: явное и неявное.

  • Неявное преобразование происходит автоматически. Это выполняется во время сравнения, присваивания или вычисления выражения различных типов. Например, следующая программа выведет на консоль значение типа float.

#include "stdafx.h" #include using namespace std; int main() { int i=5; float f=10.12; cout<>void"); return 0; }

#include "stdafx.h"

#include

using namespace std ;

int main ()

int i = 5 ; float f = 10.12 ;

cout << i / f ;

system ("pause>>void" ) ;

return 0 ;

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

  • Явное преобразование в отличие от неявного осуществляется программистом. Существует несколько способов такого преобразования:
  1. Преобразование в стили C : (float ) a
  2. Преобразование в стили C++ : float ()

Также приведения типов может осуществляться при помощи следующих операций:

static_cast <> () const_cast <> () reinterpret_cast <> () dynamic_cast <> ()

static_cast <> ()

const_cast <> ()

reinterpret_cast <> ()

dynamic_cast <> ()

static_cas - осуществляет преобразование связанных типов данных. Этот оператор приводит типы по обычным правилам, что может потребоваться в случае, когда компилятор не выполняет автоматическое преобразование. Синтаксис будет выглядеть так:

Тип static_cast <Тип> (объект);

С помощью static_cast нельзя убрать константность у переменной, но это по силам следующему оператору. const_cast - применяется только тогда, когда нужно снять константность у объекта. Синтаксис будет выглядеть следующим образом:

Тип const_cast < Тип > (объект );

reinterpret_cast - применяется для преобразования разных типов, целых к указателю и наоборот. Если вы увидели новое слово «указатель» - не пугайтесь! это тоже тип данных, но работать с ним Мы будем не скоро. Синтаксис тут такой же как, у ранее рассмотренных операторах:

Тип reinterpret _cast < Тип > (объект );

dynamic_cast - используется для динамического преобразования типов, реализует приведение указателей или ссылок. Синтаксис:

Тип dynamic _cast < Тип > (объект );

Управляющие символы

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

Изображение

Шестнадцатеричный код

Наименование

Звуковой сигнал бипера

Возврат на шаг

Перевод страницы (формата)

Перевод строки

Возврат каретки

Горизонтальная табуляция

Вертикальная табуляция

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

Процесс проверки и накладывания ограничений на типы используемых данных называется контролем типов или типизацией программных данных . Различают следующие виды типизации:

  • Статическая типизация - контроль типов осуществляется при компиляции.
  • Динамическая типизация - контроль типов осуществляется во время выполнения.

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

Различают простые, составные и прочие типы данных.

Простые данные

Простые данные можно разделить на

  • целочисленные,
  • вещественные,
  • символьные
  • логические.

Составные (сложные) данные

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

Другие типы данных

  • Указатель — хранит адрес в памяти компьютера, указывающий на какую-либо информацию, как правило - указатель на переменную.

Программа, написанная на языке Си, оперирует с данными различных типов. Все данные имеют имя и тип. Обращение к данным в программе осуществляется по их именам (идентификаторам).

Идентификатор - это последовательность, содержащая не более 32 символов, среди которых могут быть любые буквы латинского алфавита a — z, A — Z, цифры 0 — 9 и знак подчеркивания (_). Первый символ идентификатора не должен быть цифрой.

Несмотря на то, что допускается имя, имеющее до 32 символов, определяющее значение имеют только первые 8 символов. Помимо имени, все данные имеют тип. Указание типа необходимо для того, чтобы было известно, сколько места в оперативной памяти будет занимать данный объект.

Компилятор языка Си придерживается строгого соответствия прописных и строчных букв в именах идентификаторов и лексем.

Целочисленные данные

Целочисленные данные могут быть представлены в знаковой и беззнаковой форме.

Беззнаковые целые числа представляются в виде последовательности битов в диапазоне от 0 до 2 n -1, где n-количество занимаемых битов.

Знаковые целые числа представляются в диапазоне -2 n-1 …+2 n-1 -1. При этом старший бит данного отводится под знак числа (0 соответствует положительному числу, 1 – отрицательному).

Основные типы и размеры целочисленных данных:

Вещественные данные

Вещественный тип предназначен для представления действительных чисел. Вещественные числа представляются в разрядной сетке машины в нормированной форме.

Нормированная форма числа предполагает наличие одной значащей цифры (не 0) до разделения целой и дробной части. Такое представление умножается на основание системы счисления в соответствующей степени. Например, число 12345,678 в нормированной форме можно представить как

12345,678 = 1,2345678·10 4

Число 0,009876 в нормированной форме можно представить как

0,009876 = 9,876·10 -3

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

Значащие разряды числа, стоящие в нормированной форме после разделителя целой и дробной части, называются мантиссой числа .

В общем случае вещественное число в разрядной сетке вычислительной машины можно представить в виде 4 полей.

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

    где n — количество разрядов, отводимых для представления степени числа.

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

Различают три основных типа представления вещественных чисел в языке Си:

Как видно из таблицы, бит целое у типов float и double отсутствует. При этом диапазон представления вещественного числа состоит из двух диапазонов, расположенных симметрично относительно нуля. Например, диапазон представления чисел типа float можно представить в виде:

Пример : представить число -178,125 в 32-разрядной сетке (тип float ).

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

178 10 = 10110010 2 .

0,125 10 = 0,001 2 .

178,125 10 = 10110010,001 2 =1,0110010001·2 111

Для преобразования в нормированную форму осуществляется сдвиг на 7 разрядов влево).

Для определения степени числа применяем сдвиг:

0111111+00000111 = 10000110 .

Таким образом, число -178,125 представится в разрядной сетке как

Символьный тип

Символьный тип хранит код символа и используется для отображения символов в различных кодировках. Символьные данные задаются в кодах и по сути представляют собой целочисленные значения. Для хранения кодов символов в языке Си используется тип char .

Логический тип

Логический тип имеет применяется в логических операциях, используется при алгоритмических проверках условий и в циклах и имеет два значения:

  • истина — true
  • ложь — — false

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

Пример объявления объектов

int n; // Переменная n целого типа
double a; // Переменная a вещественного типа двойной точности

Ответ:
  1. Целочисельные типы данных:

short int , unsigned short int , int , unsigned int , long , unsigned long .

  1. Типы данных с плавающей запятой (соответствуют вещественным типам):

float , double , long double .

  1. Символьный тип данных:

char (signed char ), unsigned char, wchar_t .

  1. Логический тип данных:

bool .

  1. Перечислимый тип данных (введен в Visual C++ ):

enum .

2. Какие особенности использования целочисленных типов данных?

В C++ основные целочисленные типы данных: short int , unsigned short int , int , unsigned int , long (long int ), unsigned long (unsigned long int ).

Эти типы данных представляют значения из множества целых чисел. Например:

2 -100 398

Типы данных, которые начинаются из приставки unsigned , могут содержать только положительные числа.

Данные типа short int , unsigned short int занимают в два раза меньше места в памяти чем данные типа int , unsigned int .

Данные типа long , unsigned long занимают в два раза больше места в памяти чем данные типа int , unsigned int .

3. Как в программе описать переменную с именем x целого типа?

Ответ:
int x; // целое со знаком

В результате под переменную x будет выделено место в памяти размером 4 байта. Размер памяти, которая выделяется под переменную зависит от характеристик компьютера, типа операционной системы и настроек компилятора.

4. Как в переменную целого типа записать число 239?

Для этого используется оператор присваивания, который обозначается символом ‘= ‘.

Ответ 1. Внесение числа в переменную после ее описания.

int x; x = 239;

Ответ 2. Внесение числа в переменную во время ее описания (начальная инициализация).

int x = 239;

5. Какие особенности типов данных с плавающей запятой?

Типы данных с плавающей запятой разрешают представлять значения из множества вещественных чисел. Например:

8.35 -990.399 239.0.

В C++ есть следующие базовые типы данных с плавающей запятой:

float , double , long double .

Переменная типа double занимает в 2 раза больше места в памяти компьютера чем переменная типа float .

Так же переменная типа long double занимает в 2 раза больше места в памяти компьютера, чем переменная типа double .

6. Как описать переменную, которая принимает значение с плавающей запятой?

Пример описания переменных типа float , double , long double :

float f; double d; long double ld;

7. Как в переменную с плавающей запятой записать числовые значения?

Пример внесения числовых данных в переменные типы с плавающей запятой:

float f = -9928.45; // начальная инициализация double d; long double ld; d = 0.445332; // оператор присваивания ld = 3892923898239.030903; // оператор присваивания

8. Как перевести переменную типа float в тип int ?

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

float a; int b; a = 8.457; b = (int ) a; // b = 8

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

Например, переменная типа short int может представлять меньший диапазон чисел, чем переменные типов float , double . В следующему листинге происходит переполнение значения в переменной типа short int :

short int i; float f; f = 3990099.8; i = (int )f; // i = -7597 - переполнение

9. Как перевести переменную из типа int в тип double ?

Пример приведения с int в double :

int i; double d; i = 982; d = (double )i; // d = 982.0

10. Какие особенности использования данных типа char (символьных данных) в программе?

Данные типа char представляют символьное значение кода, введенного с клавиатуры. Код символа есть целое число.

Например, код символа ‘f’ равен значению 102 .

Фрагмент кода, в котором вычисляется код символа:

int code; char symbol; symbol = "f" ; code = (int )symbol; // code = 102

Данные типа char есть теми же целыми числами. Данные типа char занимают в памяти компьютера 1 байт.

Соотношение «символ-код» размещается в таблице символов Windows. Символы с кодами от 0 до 127 – это зарезервированные символы BIOS. Они включают наиболее употребляемые символы, символы цифр, символы латинской азбуки. Эти символы изменить нельзя.

Символы с кодами от 128 до 255 – это региональные символы, которые привязанные к конкретной азбуке того компьютера на котором установленная операционная система Windows.

11. Какие особенности использования данных типа bool (логический тип)?

Переменные типа bool могут принимать только два значения:

true – истина,

false – ложь.

Эти переменные используются для проверки логических выражений. Числовое значение true равно 1 . Числовое значение false равно 0 .

Фрагмент кода, который определяет числовые значения true и false :

int result; bool b; result = (int )true ; // result = 1 b = false ; result = (int )b; // result = 0

Фрагмент кода, который превращает типы int и float в bool :

int i; float f; bool b; i = 6; b = (bool )i; // b = True f = 0.0; b = (bool )f; // b = False

12. Как определить размер памяти, который занимает переменная данного типа?

Для этого используется операция sizeof() .

Фрагмент кода, который определяет размер некоторых типов данных:

int d; d = sizeof (char ); // d = 1 d = sizeof (unsigned int ); // d = 4 d = sizeof (float ); // d = 4 d = sizeof (double ); // d = 8

13. Каким образом осуществляется инициализация переменных разных типов?

int d = 28; float z = (float )2.85; char c = "k" ; String ^s = "Hello!" ; double r = -8.559;

14. Каким образом определить максимально допустимое (минимально допустимое) значение переменной определенного типа?

Чтобы определить максимально допустимое или минимально допустимое значение переменной некоторого типа в библиотеке .NET Framework используются свойства MaxValue и MinValue .

Примеры определения предельных значений переменных разных типов.

Для переменных типа int :

// тип int int i; long MaxInt; long MinInt; MaxInt = (long )i.MaxValue; // MaxInt = 2147483647 MinInt = (long )i.MinValue; // MinInt = -2147483648

Для переменных типа short int :

// тип short int short int si; int MaxInt; int MinInt; MaxInt = (int )si.MaxValue; // MaxInt = 32767 MinInt = (int )si.MinValue; // MinInt = -32768

Для переменных типа unsigned int :

// тип unsigned int unsigned int ui; unsigned int MaxInt; unsigned int MinInt; MaxInt = ui.MaxValue; // MaxInt = 4294967295 MinInt = ui.MinValue; // MinInt = 0

Для переменных типа float :

// тип float float f; float MaxF; float MinF; MaxF = f.MaxValue; // MaxF = 3.402823E+38 MinF = f.MinValue; // MinF = -3.402823E+38

Для переменных типа double :

// тип double double d; double MaxD; double MinD; Max = d.MaxValue; // Max = 1.79769313486232E+308 Min = d.MinValue; // Min = -1.79769313486232E+308

Для переменных типа char :

// тип char char c; int MaxC; int MinC; Max = (int )c.MaxValue; // Max = 127 Min = (int )c.MinValue; // Min = -128

15. Какие особенности использования типа enum ?

Тип enum – это перечислительный тип данных. В нем задаются мнемонические значения для множеств целых значений. Каждое мнемоническое значение имеет определенное содержание и представляется целым числом.

Пример использования типа enum для обозначения месяцев года:

enum months { January, February, March, April, May, June, July, August, September, October, November, December } mn; mn = January; // mn = 0 mn = March; // mn = 2 mn = September; // mn = 8

В приведенном примере описывается переменная с именем mn типа enum months . Мнемонические значения месяцев (January , February , …) начинаются с 0 (0 , 1 , 2 , …). Мнемоническому значению January соответствует целое значение 0 , мнемоническому значению February соответствует целое значение 1 , и т.д.

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

Можно написать и так:

mn = (enum months)2; // mn = March mn = (enum months)11; // mn = December

16. Какие особенности применения типа void в программах на C ++ ?

Тип данных void используется в следующих случаях:

  • если нужно описать функцию, которая не возвращает никакого значения (см. пример);
  • если нужно описать функцию, которая не получает параметров (см. пример).

Пример . Функция MyFun() без параметров, которая не возвращает никакого значения (возвращает тип void ) и не получает параметров.

public : void MyFun(void ) { // тело функции // ... return; // возврат из функции, которая не возвращает значения } // вызов функции из программы ... MyFun(); ...

17. Можно ли объявлять переменную типа void в программе?

Нельзя, так как тип void не связан со значением.

Объявление переменной типа void приводит к ошибке компиляции с выводом сообщения:

"Illegal use of type void "

18. Какие особенности применения типа wchar _ t в Visual C ++ ?

Переменные типа char (смотрите предыдущие пункты) используются для сохранения 8-разрядных ASCII -символов.

Тип wchar_t используется для сохранения символов, которые входят в состав больших символьных наборов. Например, в китайской азбуке есть огромное количество символов. 8 разрядов недостаточно, чтобы представить весь набор символов китайской азбуки. Поэтому, если нужно использовать программу на международном рынке, целесообразно заменить тип char на wchar_t .

Пример использования типа wchar_t .

... wchar_t t; // для переменной t выделяется 2 байта памяти t = "s"; ...

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

Существование двух числовых типов (целого и вещественного) связано с двумя возможными формами представления чисел в памяти компьютера.

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

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

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

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

В Си имеется 4 базовых типа:

char - символьный тип;

int - целый тип,

float - вещественный тип одинарной точности,

double - вещественный тип двойной точности.

Для задания производных типов используются квалификаторы :short (короткий) - используется с типомint ,long (длинный) - используется с типамиint иdouble ;signed (со знаком),unsigned (без знака) - применимы к любому целому типу. При отсутствии словаunsignedзначение считается знаковым,т. е. по умолчанию принятоsigned. В силу допустимости произвольного соединения квалификаторов и названий базовых типов один тип может иметь несколько обозначений. Сведения о стандартных типах Си представлены в таблицах 1 и 2. Через запятую в клетках первого столбца перечислены описатели-синонимы.

Таблица 1. Стандартные целые типы данных Си

Тип данных

Диапазон значений

char, signed char

unsigned int, unsigned

int, signed int, short int, short

2147483648...2147483647

Интересно, что в Си тип charв зависимости от контекста может использоваться как символьный или как целый тип.

Таблица 2. Стандартные вещественные типы данных Си

Замечание. Для написания программ первой части пособия нам потребуются в основномдва типа: float и int .

В этом уроке мы рассмотрим целочисленные типы данных, их диапазоны значений, деление, а также переполнение: что это такое и примеры.

Целочисленные типы данных

Целочисленный тип данных - это тип, переменные которого могут содержать только целые числа (без дробной части, например: -2, -1, 0, 1, 2). В C++ есть пять основных целочисленных типов, доступных для использования:

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

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

Определение целочисленных переменных

Происходит следующим образом:

char c; short int si; // допустимо short s; // предпочтительнее int i; long int li; // допустимо long l; // предпочтительнее long long int lli; // допустимо long long ll; // предпочтительнее

В то время как полные названия short int , long int и long long int могут использоваться, их сокращённые версии (без int) более предпочтительны для использования. К тому же постоянное добавление int затрудняет чтение кода (легко спутать с переменной).

Диапазоны значений и знак целочисленных типов данных

Как вы уже знаете из предыдущего урока, переменная с n-ным количеством бит может хранить 2 n возможных значений. Но что это за значения? Те, которые находятся в диапазоне. Диапазон - это значения от и до, которые может хранить определённый тип данных. Диапазон целочисленной переменной определяется двумя факторами: её размером (в битах) и её знаком (который может быть signed или unsigned ).

signed (со знаком) означает, что переменная может содержать как положительные, так и отрицательные числа. Чтобы объявить переменную как signed, используйте ключевое слово signed :

signed char c; signed short s; signed int i; signed long l; signed long long ll;

signed char c ;

signed short s ;

signed int i ;

signed long l ;

signed long long ll ;

По умолчанию, ключевое слово signed пишется перед типом данных.

1-байтовая целочисленная переменная со знаком (signed) имеет диапазон значений от -128 до 127. Любое значение от -128 до 127 (включительно) может храниться в ней безопасно.

В некоторых случаях мы можем заранее знать, что отрицательные числа в программе использоваться не будут. Это очень часто встречается при использовании переменных для хранения количества или размера чего-либо (например, ваш рост или вес не может быть отрицательным). Целочисленный тип unsigned (без знака) может содержать только положительные числа. Чтобы объявить переменную как unsigned , используйте ключевое слово unsigned :

unsigned char c; unsigned short s; unsigned int i; unsigned long l; unsigned long long ll;

unsigned char c ;

unsigned short s ;

unsigned int i ;

unsigned long l ;

unsigned long long ll ;

1-байтовая целочисленная переменная без знака (unsigned) имеет диапазон значений от 0 до 255.

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

Теперь, когда вы поняли разницу между signed и unsigned, давайте рассмотрим диапазоны значений разных типов данных:

Размер/Тип Диапазон значений
1 байт signed от -128 до 127
1 байт unsigned от 0 до 255
2 байта signed от -32 768 до 32 767
2 байта unsigned от 0 до 65 535
4 байта signed от -2 147 483 648 до 2 147 483 647
4 байта unsigned от 0 до 4 294 967 295
8 байтов signed от -9 223 372 036 854 775 808 до 9 223 372 036 854 775 807
8 байтов unsigned от 0 до 18 446 744 073 709 551 615

Для математиков: переменная signed с n-ным количеством бит имеет диапазон от -(2 n-1) до 2 n-1 -1. Переменная unsigned с n-ным количеством бит имеет диапазон от 0 до (2 n)-1. Для нематематиков: используем таблицу 🙂

Начинающие программисты иногда путаются между signed и unsigned переменными. Но есть простой способ запомнить их различия. Чем отличается отрицательное число от положительного? Правильно! Минусом спереди. Если минуса нет, значит число — положительное. Следовательно, целочисленный тип со знаком (signed) означает, что минус может присутствовать, т.е. числа могут быть как положительными, так и отрицательными. Целочисленный тип без знака (unsigned) означает, что минус спереди полностью отсутствует, т.е. числа могут быть только положительными.

Что используется по умолчанию: signed или unsigned?

Так что же произойдёт, если мы объявим переменную без указания signed или unsigned?

Все целочисленные типы данных, кроме char, являются signed по умолчанию. Тип char может быть как signed, так и unsigned (но, обычно, signed).

В большинстве случаев ключевое слово signed не пишется (оно и так используется по умолчанию), за исключением типа char (здесь лучше уточнить).

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

Правило: Используйте целочисленные типы signed, вместо unsigned .

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

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

Примеры переполнения

Рассмотрим переменную unsigned, которая состоит из 4 битов. Любое из двоичных чисел, перечисленных в таблице выше, поместиться внутри этой переменной.

«Но что произойдёт, если мы попытаемся присвоить значение, которое занимает больше 4 битов?». Правильно! Переполнение. Наша переменная будет хранить только 4 наименее значимых (те, что справа) бита, все остальные — потеряются.

Например, если мы попытаемся поместить число 21 в нашу 4-битную переменную:

Десятичная система Двоичная система
21 10101

Число 21 занимает 5 бит (10101). 4 бита справа (0101) поместятся в переменную, а крайний левый бит (1) просто потеряется. Т.е. наша переменная будет содержать 0101, что равно 101 (нуль спереди не считается), а это уже число 5, а не 21.

Примечание : О конвертации чисел из двоичной системы в десятичную и наоборот будет отдельный урок, где мы всё детально рассмотрим и обсудим.

Теперь рассмотрим пример в коде (тип short занимает 16 бит):

#include int main() { unsigned short x = 65535; // наибольшее значение, которое может хранить 16-битная unsigned переменная std::cout << "x was: " << x << std::endl; x = x + 1; // 65536 - это число больше максимально допустимого числа из диапазона допустимых значений. Следовательно, произойдёт переполнение, так как переменнная x не может хранить 17 бит std::cout << "x is now: " << x << std::endl; return 0; }

#include

int main ()

unsigned short x = 65535 ; // наибольшее значение, которое может хранить 16-битная unsigned переменная

std :: cout << "x was: " << x << std :: endl ;

x = x + 1 ; // 65536 - это число больше максимально допустимого числа из диапазона допустимых значений. Следовательно, произойдёт переполнение, так как переменнная x не может хранить 17 бит

std :: cout << "x is now: " << x << std :: endl ;

return 0 ;

x was: 65535
x is now: 0

Что случилось? Произошло переполнение, так как мы попытались впихнуть невпихуемое в переменную x.

Для тех, кто хочет знать больше: Число 65 535 в двоичной системе счисления представлено как 1111 1111 1111 1111. 65 535 - это наибольшее число, которое может хранить 2-байтовая (16 бит) целочисленная переменная без знака, так как это число использует все 16 бит. Когда мы добавляем 1, то получаем число 65 536. Число 65 536 представлено в двоичной системе как 1 0000 0000 0000 0000, и занимает 17 бит! Следовательно, самый главный бит (которым является 1) теряется, а все 16 бит справа — остаются. Комбинация 0000 0000 0000 0000 соответствует десятичному 0, что и является нашим результатом.

Аналогичным образом, мы получим переполнение, использовав число, меньше минимального из диапазона допустимых значений:

#include int main() { unsigned short x = 0; // наименьшее значение, которое 2-байтовая unsigned переменная может хранить std::cout << "x was: " << x << std::endl; x = x - 1; // переполнение! std::cout << "x is now: " << x << std::endl; return 0; }

#include

int main ()

unsigned short x = 0 ; // наименьшее значение, которое 2-байтовая unsigned переменная может хранить

std :: cout << "x was: " << x << std :: endl ;

x = x - 1 ; // переполнение!

std :: cout << "x is now: " << x << std :: endl ;

return 0 ;

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

x was: 0
x is now: 65535

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



Есть вопросы?

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: