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



Переменные. Типы данных. Константы.

 

Переменные

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

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

 

тип_переменной имя_переменной;

 

Простейшее определение переменной:

 

int age;

 

Здесь определена переменная age, которая имеет тип int. Поскольку определение переменной представляет собой инструкцию, то после него ставится точка с запятой.

Имя переменной может представлять последовательность символов латинского алфавита, чисел и знака подчеркивания. При этом имя должно начинаться либо с алфавитного символа, либо со знака подчеркивания.

 

int _age33;

 

Других символов в названии переменной не должно быть. Например, следующее определение будет неправильным:

 

int $age;

 

Так как символ $ не является ни буквой, ни цифрой, ни символом подчеркивания.

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

 

int age;

int Age;

 

Поэтому переменная Age не будет представлять то же самое, что и переменная age.

Кроме того, в качестве имени переменной нельзя использовать ключевые слова языке C++, например, for или if. Но таких слов не так много: alignas, alignof, asm, auto, bool, break, case, catch, char, char16_t, char32_t, class, const, constexpr, const_cast, continue, decltype, default, delete, do, double, dynamic_cast, else, enum, explicit, export, extern, false, float, for, friend, goto, if, inline, int, long, mutubale, namespace, new, noexcept, nullptr, operator, private, protected, public, register, reinterpret_cast, return, short, signed, sizeof, static, static_assert, static_cast, struct, switch, template, this, thread_local, throw, true, try, typedef, typeid, typename, union, unsigned, using, virtual, void, volatile, wchar_t, while.

Также нельзя объявить больше одной переменной с одним и тем же именем, например:

 

int age;

int age;

 

Подобное определение вызовет ошибку на этапе компиляции.

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

Инициализация

 

После определения переменной можно присвоить некоторое значение:

 

int age;

age = 20;

 

Например, определим в программе переменную и выведем ее значение на консоль:

 

#include <iostream>

 

int main()

{

int age;

age = 28;

std::cout<<"Age = " << age;

return 0;

}

 

С помощью последовательности операторов << можно вывести несколько значений на консоль.

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

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

 

#include <iostream>

int main()

{

int age = 28;

std::cout<<"Age = " << age;

return 0;

}

Инициализация по умолчанию

 

Если переменную не инициализировать, то происходит ее инициализация по умолчанию. И переменная получает некоторое значение по умолчанию, которое зависит от места, где эта переменная определена.

Если переменная, которая представляет встроенный тип (например, тип int), определена внутри функции, то она получает неопределенное значение. Если переменная встроенного типа определена вне функции, то она получает то значение по умолчанию, которое соответствует ее типу. Для числовых типов это число 0. Например:

 

#include <iostream>

 

int x;

int main()

{

int y;

std::cout <<"X = " << x << "\n";

std::cout <<"Y = " << y;

return 0;

}

 

Переменная x определена вне функции, и поэтому она получит значение по умолчанию - число 0.

Гораздо сложнее дело обстоит с переменной y, которая определена внутри функции main - ее значение будет неопределенным, и многое будет зависеть от используемого компилятора. В частности, вывод программы, скомпилированной с помощью компилятора G++, может выглядеть следующим образом:

 

 

А в Visual Studio отсутствие значения переменной y вызовет ошибку.

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

 

Изменение значения

 

Ключевой особенностью переменных является то, что мы можем изменять их значения:

 

#include <iostream>

 

int main()

{

int x = 6;

x = 8;

x = 10;

std::cout <<"X = " << x; // X = 10

return 0;

}

 

Типы данных

 

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

· bool: логический тип. Может принимать одну из двух значений true (истина) и false (ложь). Размер занимаемой памяти для этого типа точно не определен.

· char: представляет один символ в кодировке ASCII. Занимает в памяти 1 байт (8 бит). Может хранить любое значение из диапазона от -128 до 127, либо от 0 до 255

· signed char: представляет один символ. Занимает в памяти 1 байт (8 бит). Может хранить любой значение из диапазона от -128 до 127

· unsigned char: представляет один символ. Занимает в памяти 1 байт (8 бит). Может хранить любой значение из диапазона от 0 до 255

· wchar_t: представляет расширенный символ. На Windows занимает в памяти 2 байта (16 бит), на Linux - 4 байта (32 бита). Может хранить любой значение из диапазона от 0 до 65 535 (при 2 байтах), либо от 0 до 4 294 967 295 (для 4 байт)

· char16_t: представляет один символ в кодировке Unicode. Занимает в памяти 2 байта (16 бит). Может хранить любой значение из диапазона от 0 до 65 535

· char32_t: представляет один символ в кодировке Unicode. Занимает в памяти 4 байта (32 бита). Может хранить любой значение из диапазона от 0 до 4 294 967 295

· short: представляет целое число в диапазоне от –32768 до 32767. Занимает в памяти 2 байта (16 бит).

Данный тип также имеет синонимы short int, signed short int, signed short.

· unsigned short: представляет целое число в диапазоне от 0 до 65535. Занимает в памяти 2 байта (16 бит).

Данный тип также имеет синоним unsigned short int.

· int: представляет целое число. В зависимости от архитектуры процессора может занимать 2 байта (16 бит) или 4 байта (32 бита). Диапазон предельных значений соответственно также может варьироваться от –32768 до 32767 (при 2 байтах) или от −2 147 483 648 до 2 147 483 647 (при 4 байтах). Но в любом случае размер должен быть больше или равен размеру типа short и меньше или равен размеру типа long

Данный тип имеет синонимы signed int и signed.

· unsigned int: представляет положительное целое число. В зависимости от архитектуры процессора может занимать 2 байта (16 бит) или 4 байта (32 бита), и из-за этого диапазон предельных значений может меняться: от 0 до 65535 (для 2 байт), либо от 0 до 4 294 967 295 (для 4 байт).

В качестве синонима этого типа может использоваться unsigned

· long: представляет целое число в диапазоне от −2 147 483 648 до 2 147 483 647. Занимает в памяти 4 байта (32 бита).

У данного типа также есть синонимы long int, signed long int и signed long

· unsigned long: представляет целое число в диапазоне от 0 до 4 294 967 295. Занимает в памяти 4 байта (32 бита).

Имеет синоним unsigned long int.

· long long: представляет целое число в диапазоне от −9 223 372 036 854 775 808 до +9 223 372 036 854 775 807. Занимает в памяти, как правило, 8 байт (64 бита).

Имеет синонимы long long int, signed long long int и signed long long.

· unsigned long long: представляет целое число в диапазоне от 0 до 18 446 744 073 709 551 615. Занимает в памяти, как правило, 8 байт (64 бита).

Имеет синоним unsigned long long int.

· float: представляет вещественное число ординарной точности с плавающей точкой в диапазоне +/- 3.4E-38 до 3.4E+38. В памяти занимает 4 байта (32 бита)

· double: представляет вещественное число двойной точности с плавающей точкой в диапазоне +/- 1.7E-308 до 1.7E+308. В памяти занимает 8 байт (64 бита)

· long double: представляет вещественное число двойной точности с плавающей точкой не менее 8 байт (64 бит). В зависимости от размера занимаемой памяти может отличаться диапазон допустимых значений.

· void: тип без значения

Таким образом, все типы данных за исключением void могут быть разделены на три группы: символьные (char, wchar_t, char16_t, char32_t), целочисленные (short, int, long, long long) и типы чисел с плавающей точкой (float, double, long double).

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

 

Для представления символов в приложении используются типы char, wchar_t, char16_t и char32_t.

Определим несколько переменных:

 

char c ='d';

wchar_t d ='c';

 

Переменная типа char в качестве значения принимает один символ в одинарных кавычках: char c ='d'. Также можно присвоить число из указанного выше в списке диапазона: char c = 120. В этом случае значением переменной c будет тот символ, который имеет код 120 в таблице символов ASCII.

Стоит учитывать, что для вывода на консоль символов wchar_t следует использовать не std::cout, а поток std::wcout:

 

#include <iostream>

 

int main()

{

char a = 'H';

wchar_t b = 'e';

std::wcout << a << b << '\n';

return 0;

}

 

При этом поток std::wcout может работать как с char, так и с wchar_t. А поток std::cout для переменной wchar_t вместо символа будет выводить его числовой код.

В стандарте С++11 были добавлены типы char16_t и char32_t, которые ориентированы на использование Unicode. Однако на уровне ОС пока не реализованы потоки для работы с этими типами. Поэтому если потребуется вывести на консоль значения переменных этих типов, то необходимо преобразовать переменные к типам char или wchar_t:

 

#include <iostream>

 

int main()

{

char a = 'H';

wchar_t b = 'e';

char16_t c = 'l';

char32_t d = 'o';

std::cout << a << (char)b << (char)c << (char)d << "\n";

return 0;

}

 

В данном случае при выводе перед переменными указывается операция приведения к типу char - (char), благодаря чему значения переменных b, c и d преобразуются в тип char и могут быть выведены на консоль с помощью потока std::cout.

 

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

 

Целочисленные типы представлены следующими типами: short, unsigned short, int, unsigned int, long, unsigned long, long long и unsigned long long:

 

short a = -10;

unsigned short b= 10;

int c = -30;

unsigned int d = 60;

long e = -170;

unsigned long f = 45;

long long g = 89;

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

 

Типы чисел с плавающей точкой или дробные числа представлены такими типами как float, double и long double:

 

float a = -10.45;

double b = 0.00105;

long double c = 30.890045;

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

 

В выше приведенном списке для каждого типа указан размер, который он занимает в памяти. Однако стоит отметить, что предельные размеры для типов разработчики компиляторов могут выбирать самостоятельно, исходя из аппаратных возможностей компьютера. Стандарт устанавливает лишь минимальные значения, которые должны быть. Например, для типов int и short минимальное значение - 16 бит, для типа long - 32 бита, для типа long double. При этом размер типа long должен быть не меньше размера типа int, а размер типа int - не меньше размера типа short, а размер типа long double должен быть больше double. К примеру, компилятор g++ под Windows для long double использует 12 байт, а компилятор, встроенный в Visual Studio и также работающий под Windows, для long double использует 8 байт. То есть даже в рамках одной платформы разные компиляторы могут по разному подходить к размерам некоторых типов данных. Но в целом используются те размеры, которые указаны выше при описании типов данных.

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

 

#include <iostream>

 

int main()

{

long double number = 2;

std::cout << "sizeof(number) =" << sizeof(number);

return 0;

}

 

Консольный вывод при компиляции в g++:

 

 

При этом при определении переменных важно понимать, что значение переменной не должно выходить за те пределы, которые очерчены для ее типа. Например:

 

unsigned short number = -65535;

 

Компилятор G++ при компиляции программы с этой строкой выдаст ошибку о том, что значение -65535 не входит в диапазон допустимых значений для типа unsigned short и будет усечено.

В Visual Studio компиляция может пройти без ошибок, однако при этом переменная number получит значение 2 - результат преобразования числа -65535 к типу unsigned short. То есть опять же результат будет не совсем тот, который ожидается. Значение переменной - это всего лишь набор битов в памяти, которые интерпретируются в соответствии с определенным типом. И для разных типов один и тот же набор битов может интерпретироваться по разному. Поэтому важно учитывать диапазоны значений для того или иного типа при присвоении переменной значения.

 

Спецификатор auto

 

Иногда бывает трудно определить тип выражения. И согласно последним стандартам можно предоставить компилятору самому выводить тип объекта. И для этого применяется спецификатор auto. При этом если мы определяем переменную со спецификатором auto, эта переменная должна быть обязательно инициализирована каким-либо значением:

 

auto number = 5;

 

На основании присвоенного значения компилятор выведет тип переменной. Неинициализированные переменные со спецификатором auto не допускаются:

 

auto number;

 


Дата добавления: 2020-11-23; просмотров: 113; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!