Урок №28. Детальнее об инициализации, присваивании и определении переменных

  Юрий  | 

    | 

  Обновл. 24 Мар 2019  | 

 18030

 ǀ   11 

Этот урок является более детальным продолжением урока №10.

Адреса и переменные

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

Наименьшая единица памяти — бит (с англ. «binary digi), который может содержать либо значение 0, либо значение 1. Вы можете думать о бите, как о переключателе света — либо свет выключен (0), либо включен (1). Чего-то среднего между ними нет. Если просмотреть случайный кусочек памяти, то всё, что вы увидите, будет …011010100101010… или что-то в этом роде. Память организована в последовательные части — адреса. Подобно тому, как мы используем адреса в реальной жизни, чтобы найти определённый дом на улице, так и здесь: адреса позволяют найти и получить доступ к содержимому, которое находится в определённом месте в памяти. Возможно, это удивит вас, но в современных компьютерах, у каждого бита по отдельности нет своего собственного адреса. Наименьшей единицей с адресом является байт (который состоит из 8 битов).

Поскольку все данные компьютера — это лишь последовательность битов, то мы используем тип данных (или просто «тип»), чтобы сообщить компилятору, как интерпретировать содержимое памяти. Вы уже видели пример типа данных: int (целочисленный тип данных). Когда мы объявляем целочисленную переменную, мы говорим компилятору, что «кусочек памяти, который находится за таким-то адресом, следует интерпретировать как целое число».

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

Кроме int, есть много других типов данных в C++, большинство из которых мы детально рассмотрим в соответствующих уроках.

Фундаментальные типы данных в С++


В C++ есть встроенная поддержка определённых типов данных. Их называют основными типами данных (или ещё «фундаментальные/базовые/встроенные типы данных»).

Вот список основных типов данных в C++:

Категория Тип Значение Пример
Логический тип данных bool true или false true
Символьный тип данных char, wchar_t, char16_t, char32_t Один из ASCII-символов ‘c’
Тип данных с плавающей запятой float, double, long double Десятичная дробь 3.14159
Целочисленный тип данных short, int, long, long long Целое число 64
Пустота void Пустота

Определение переменных

Вы уже знаете, как определить целочисленную переменную:

Принцип определения переменных других типов аналогичен:

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

Обратите внимание, переменной типа void здесь нет — об этом детальнее мы поговорим в следующем уроке.

Инициализация переменных


При объявлении переменной мы можем присвоить ей значение в этот же момент. Это называется инициализацией переменной.

C++ поддерживает два основных способа инициализации переменных:

Копирующая инициализация (или ещё «инициализация копированием») с помощью знака равенства (=):

Прямая инициализация с помощью круглых скобок:

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

uniform инициализация

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

В попытке обеспечить единый механизм инициализации, который будет работать со всеми типами данных, в C++11 добавили новую форму инициализации, которая называется uniform инициализация:

Инициализация переменной с пустыми скобками указывает на инициализацию по умолчанию (переменной присваивается нуль):

В uniform инициализации есть ещё одно дополнительное преимущество: вы не можете присвоить переменной значение, которое не поддерживает её тип данных — компилятор выдаст предупреждение или сообщение об ошибке. Например:

Правило: Используйте uniform инициализацию.

Присваивание переменных


Когда переменной присваивается значение после её объявления (не в момент объявления), то это копирующее присваивание (или просто «присваивание»):

В C++ нет встроенной поддержки форм прямого/uniform присваивания, есть только копирующее присваивание.

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

В одном стейтменте можно определить сразу несколько переменных одного и того же типа данных, разделяя их имена запятыми. Например, следующие 2 фрагмента кода выполняют одно и то же:

Кроме того, вы даже можете инициализировать несколько переменных в одной строке:

Есть три ошибки, которые совершают новички при определении нескольких переменных в одном стейтменте:

Первая ошибка: Указывать каждой переменной её (один и тот же) тип данных. Это не столь ужасная ошибка, так как компилятор легко её обнаружит и сообщит вам об этом:

Вторая ошибка: Использование разных типов данных в одном стейтменте. Переменные разных типов должны быть определены в разных стейтментах. Эту ошибку компилятор также легко обнаружит:

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

Хороший способ запомнить эту ошибку — использовать прямую или uniform инициализацию:

Так понятнее, что значение 5 присваивается только переменным b и d.

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

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

Где определять переменные?

Более старые версии компиляторов языка С вынуждали пользователей определять все переменные в верхней части функции:

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

Такой стиль написания кода имеет несколько преимуществ.

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

Во-вторых, определение переменных только там, где они необходимы, сообщает нам о том, что эти переменные не влияют на код выше, что делает программу проще для понимания.

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

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

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

Оценить статью:

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (226 оценок, среднее: 4,96 из 5)
Загрузка...

Комментариев: 11

  1. Аватар Andrey:

    Где можно скачаться весь пройденный курс? Иногда приходться находиться в таких местах, где нет интернета и нет возможности заниматься.

    1. Юрий Юрий:

      Я думаю немного позже, я сделаю pdf-ник с половиной курса. Потом, когда все уроки доперевожу — сделаю pdf-ник целого курса.

  2. Аватар Torgu:

    Здравствуйте, где можно скачать IDE с поддержкой C++11? Не хочется упускать возможности использования "Uniform Initialization". Хотя порограмма не старая — Visual Studio 2017

    1. Юрий Юрий:

      Смотрите урок 4 — в нем детально рассписывается как устанавливать Visual Studio и где скачать. Если вы скачиваете с оф. сайта и ничего лишнего в настройках не изменяете, то C++11 и uniform инициализация в Visual Studio 2017 используются по умолчанию.

  3. Аватар Виталий:

    "int value{5};"
    а здесь точно нет ошибок?
    по логике должно быть "int nValue{5};"
    или я ошибаюсь?

    1. Юрий Юрий:

      Это названия переменных. Имена переменных могут быть разными. Здесь они разные — не одинаковые во всех примерах.

  4. Аватар Сергей:

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

    1. Юрий Юрий:

      Будем продолжать дальше 🙂

    2. Аватар Илья:

      Поддерживаю предыдущего комментатора — сайт отличный! Автору спасибо и успехов! Супер! Надеюсь на продолжение работы по переводу!

      1. Юрий Юрий:

        И Вам спасибо 🙂

    3. Аватар илья:

      сайт отличный, не поспоришь!

Добавить комментарий для Юрий Отменить ответ

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