Типы данных и переменные в C++
Назначение компилятора - обрабатывать информацию (данные). Он берёт данные и что-то делает с ними. В данном уроке мы рассмотрим как C++ интерпретирует информацию.
Информация - это то, что имеет какое-либо значение (в любом контексте). Это может быть: количество денег в банковском аккаунте, возраст в профиле на сайте, количество очков в игре, текст в книге, музыкальный трек, видео клип на ютубе. Информация может иметь разный размер. Мы начнём с совсем маленьких единиц данный доступных в C++.
Литералы в C++
Литерал - это просто кусок данных как есть. По-английски literal - буквальный, точный. В вашем коде будет много литералов. Примеры литералов:
Поэтому, если в коде вы видите число, текстовую строку, отдельный символ - всё это литералы. Они вписаны в код. Пример литерала из прошлого урока - строка "Hello World\n", которую мы печатали в консоли.
Как видно, существуют разные литералы: текстовые, числовые, которые в свою очередь тоже различаются. В C++ все данные должны иметь тип .
Типы данных (data types) в C++
В C++ есть определённый набор типов данных (data types). Каждый тип данных имеет свой размер - количество занимаемой памяти.
Целочисленные (integer) типы данных в C++
C++ имеет несколько типов данных для представления целых чисел. Одна причина на это - поддержка старых систем, другая - это позволяет сохранить память. Главное различие между разными целочисленными типами - они занимают разное количество памяти и могут хранить разные диапазоны чичел.
Наименьший тип - char. Он занимает один байт памяти (8 бит). Это очень мало и главная проблема с char, что он может хранить только 256 значений: от 0 до 255 или от -128 до 127. Традиционно char использовался для хранения текста. Данного типа было достаточно чтобы закодировать все буквы английского алфавита (52 для верхнего и нижнего регистров), различные символы пунктуации и математические знаки, а также алфавит другого языка (для нас - русского).
int. Занимает 4 байта (32 бита) и может хранить около 4.3 миллиарда значений. Когда мы видели слово int перед функцией main, это была отсылка к данному типу.
long long - занимает 8 байт. Почему слово long повторяется два раза? Потому что раньше, когда у компьютеров было меньше памяти тип long был зарезервирован, чтобы хранить 4 байта. В те времена тип int занимал 2 байта. Поэтому, когда компьютеры стали более мощными, вместимость типа int была увеличена.
Числа со знаком (signed) и без (unsigned)
Для C++ есть разница имеет ли число знак или нет. Давайте взглянем на тип char. Он может хранить 256 значений. По умолчанию он хранит числа со знаком, поэтому полный диапазон char от -128 до 127. Мы можем заставить C++ интерпретировать любое число как без знака (unsigned.) Это увеличит диапазон положительных чисел в два раза. Поэтому unsigned char имеет диапазон от 0 до 255. Любой целый тип можно интерпретировать как без знака.
Числа с плавающей точкой (float data types) в C++
Числа с плавающей точкой (float) - числа вида 0.1, 1.5, 0.132589869235982 и т.д. Для компьютера существует большая разница между целыми числами и числами с плавающей точкой, так как они хранятся в памяти совершенно по разному.
Тип float занимает 4 байта. Он может хранить числа гораздо большие чем тип int. Но они будут не такими точными как целые - почти всегда существует погрешность. Мы обсудим этот интересный факт позже.
Другой тип для чисел с плавающей точкой - double. Он занимает 8 байт и может хранить огромне числа.
Булево значение (bool) в C++
bool занимает 1 байт, но может хранить только два значения. Теоретически достаточно одного бита для данного типа, но современные компьютеры имеют адресацию для доступа к отдельным байтам, поэтому для bool был щедро выделен целый байт. В C++ есть специальные ключевые слова для булевых значений: true (истина) и false (ложь).
Как хранить текст в C++?
Как мы видели ранее, тип char хранит целые числа. И в то же время он может использоваться для хранения текста. Существует такое понятие, как кодирование: было решено, что каждому числу в диапазоне от 0 до 127 будет назначен отдельный символ (буква, математический или пунктуационный знак...). Существует множество кодировок, но наиболее распространённая - ASCII. В этой кодировке число 65 обозначает латинскую букву A, 97 - a, число 48 представляет символ числа 0, а 57 - символ числа 9. Поэтому, когда на экране вы видите число 0, внутри комьютера данный символ представлен числом 48. Такое соглашение дл ASCII. ASCII кодирует 7 байт - 128 разных значений. Ещё один бит и дополнительные 128 значений могут использоваться для символов другого алфавита (кириллица, хинди...).
В C++ есть два разных текстовых литерала: с одинарными кавычками (single quoted) и с двойными (double quoted). В одинарные кавычки мы можем поместить только один символ - символьный литерал: 'a', '1', 'b'... В двойные кавычки мы можем поместить несколько символов: "Hey", "Some text"...
Юникод (unicode) в C++
В типе char всего 256 значений. Из них ASCII кодирует только 128 значений. Как нетрудно догадаться, в char невозможно закодировать все алфавиты мира. Для решения этой проблемы используется юникод (unicode). Юникод такая же кодировка как и ASCII. Более того, первые 128 значений юникода совпадают с ASCII (некоторые типы юникода). Существует множество кодировок юникода. В C++ юникод может быть представлен типами: wchar_t (широкая строка - wide string - 2 bytes), char16_t (UTF-16 - 2 байта), char32_t (UTF-32 - 4 байта). Все эти типы имеют свой литерал: L"Some text" - литерал wchar_t, u"Some text" - литерал char16_t, U"Some text" - литерал char32_t.
Когда нет типа - пустота (void) в C++
Существуют ситуации когда нам нужно сказать компилятору, что в данном месте нет никакого типа. Для этих случаев используется ключевое слово void (пустота).
Также в C++ есть специальный тип - nullptr. Мы его обсудим, когда дойдём до указателей.
Переменные
Переменная - это участок памяти, который имеет имя и тип данных. Память - это последовательность байт. Мы можем сказать компилятору зарезервировать участок памяти, а затем использовать этот участок как нам захочется.
Объявление переменных в C++
Чтобы использовать любую переменную, сначала нужно её объявить (declare). Для этого нужно указать тип данных и имя:
a, c1, pointsOfThePlayer - имена переменных. Имя должно начинаться с буквы латинского алфавита и может содержать цифры и символ подчёркивания _. Для переменных a и pointsOfThePlayer компилятор зарезервирует 4 байта, а для переменной c1 - 1 байт. С этого момента компилятор знает, какой тип у каждой переменной и мы не можем смешивать типы. Например, компилятор не даст сохранить значение float в переменную a.
Операция присваивания (assignment)
Одна из главных операций в любом языке программирования - присваивание (assignment). Это всего лишь знак =. Она берёт то, что находится справа от знака и помещает в левую часть.
С этого момента, в памяти, которая зарезервирована для i1, хранится значение 1000, а в участок представленный c1, помещено число 97, которое представляет символ 'a' в кодировке ASCII.
Когда мы объявляем переменную и присваиваем её значение в одной строке, это называется инициализацией (initialization). Данный вид инициализации был унаследован от языка C. В C++ можно инициализировать переменные по-другому:
В первой строке мы используем круглые скобки, во второй - фигурные. Фигурные скобки были добавлены в стандарте C++ 11.
Печать переменных
В уроке Hello World мы видели как напечатать строковой литерал. Давайте посмотрим как можно вывести переменную.
В C++ мы можем напечатать любую информацию с помощью cout. Мы просто поменяли строковой литерал на переменную. Но если вы скомпилируете и запустите данный код, вы увидите в консоли 12 - значения будут на одной строке и неясно, что здесь два разных значения. Мы можем их разделить:
Ключевое слово endl вставляет символ новой строки. Обратите внимание, что мы можем исопльзовать операцию << много раз.
Разделить строки можно разными способами:
На первой строке с выводом мы разделили значения с помощью endl. На второй мы спользовали символьный литерал с пробелом. Третья строка исопльзует переменную c1, которая хранит \n. \n - специальный символ, который переводит строку. В ASCII он имеет значение 10.
Вывод
В C++ больше типов, но мы обсудили самые важные.
Упражнения
- Объявите переменную но неинициализируйте её. Напечатайте значение. Попробуйте разные типы: int, char, float.