Краткое введение:
(Если вы хотите сразу перейти к делу, прокрутите вниз до раздела: Как следует инициализировать переменные в современном C++)
Лично мне не понравилось, как меня учили C++ во время моей программы по информатике. Даже предлагаемая литература отличалась от того, что обычно предлагают программисты на C++ в stackoverflow или блогах. Мы были вынуждены использовать C-стиль для кодирования наших заданий, и были наложены бессмысленные ограничения, например, std::string
нельзя было использовать, мы должны были использовать строки C-стиля char my_string[]
. Некоторые могут подумать, что это хороший способ изучения C++, но я с этим не согласен и объясню свою точку зрения в другой статье.
Недовольный тем, как меня учили C++ на программе Computer Science, я решил самостоятельно изучать современный C++. Мне не разрешили бы использовать некоторые новые функции, которые я обнаружил, но правда в том, что вы должны научиться работать над реальными проектами, а не только для того, чтобы получить оценку за задание.
Эти короткие статьи, которые я пишу (эта первая), основаны на моих заметках и наблюдениях, полученных после прочтения множества разных книг, блогов и просмотра презентаций C++. Я надеюсь, что эти статьи помогут другим изучающим C++ изучить новый синтаксис, который сделает их код более безопасным и легким для понимания.
Когда я сказал короткие статьи, я действительно имел в виду короткие. Идея в том, чтобы вы быстро прочитали ее и смогли сразу же применить полученные знания. Если вам нужно больше «мяса», потому что вам понравилась тема, вы можете проверить ссылки, которые я разместил в конце статьи. Ссылки приведут вас к другим источникам информации. Идея состоит в том, чтобы позволить вам углубиться в свои исследования.
Я начну с предположения, что у вас уже есть базовые знания в области программирования на C++ или любом другом языке.
Я буду компилировать и тестировать все свои коды, используя C++17.
Как вы должны инициализировать переменные в современном C++
Давайте посмотрим на несколько примеров:
int value_i{12}; double value_d{2.3}; int amount{}; std::string word{"Hello"};
Как видите, мы не используем ни =
, ни ()
. Здесь мы предпочитаем использовать фигурные скобки (или квадратные скобки) {}
, также известную в C++ как универсальная и равномерная инициализация. Использование {}
позволяет нам гарантировать, что переменная будет инициализирована. Если, например, у вас есть пустое {}
, такое как int amount{}
, компилятор инициализирует переменную amount
значением по умолчанию для типа, в данном случае 0 (ноль) для int
.
Использование неинициализированной переменной может вызвать неопределенное поведение, поскольку у нас нет возможности узнать значение переменной при запуске программы. Всем вычислениям, основанным на неинициализированных переменных, нельзя доверять. Когда переменная не инициализирована, например, int count;
, компилятор выделит блок памяти, который может содержать int
(4 байта). Однако мы не знаем, какое значение присутствует в этом блоке памяти. Это может быть 0 или любое значение int
.
Еще одно преимущество использования {}
заключается в том, что вы не сужаете свои значения. Вы всегда можете вписать меньшее значение в большее. Например, вы можете поместить char
в double
, но иногда возможно и обратное, и это может вызвать проблемы.
Представьте, что вы хотите создать переменную для хранения значения double
, но по ошибке (вы человек) вы кодируете переменную int
и инициализируете ее значением double
, используя =
(см. код ниже). Из-за =
компилятор сузит ваше значение double
, чтобы оно соответствовало вашей переменной int
. Однако это может быть не то, что вы хотели. Этой проблемы можно избежать, и компилятор может помочь вам увидеть проблему. Давайте посмотрим на пример ниже:
int cost_1 = 19.99; //it will narrow down to 19 int cost_2{29.99}; //the compiler will give you an error
В первом примере мы использовали переменную int
для хранения значения double
. В этом случае, в зависимости от вашего компилятора или от того, как вы его настроили, компилятор сузит число 19,99 до 19. Если вы не поймаете эту ошибку, ваши расчеты могут быть неверными, и вы можете потратить много времени, пытаясь выяснить, где ошибка. Однако, если вы используете второй пример с {}
, компилятор выдаст вам сообщение об ошибке: error: type 'double' cannot be narrowed to 'int' in initializer list
и не будет компилироваться. Благодаря этому вы сможете легко заметить свою ошибку и исправить ее.
Вот и все для этой первой короткой статьи. Я хотел сделать его быстрым для чтения, поэтому я остановлюсь здесь. В следующей статье мы продолжим разговор об инициализации с помощью {}
с объектами и с ключевым словом auto
.
Найдите ниже ссылку, связанную с этой статьей:
ES.23: предпочитать синтаксис инициализатора {}
Если у вас есть какие-либо вопросы, предложения, исправления и т. д., просто дайте мне знать в комментариях. Спасибо за чтение! :)