Урок №10. Переменные, Инициализация и Присваивание



Книга Урок №10. Переменные, Инициализация и Присваивание

При разработке на языке C++, мы работаем с объектами, которые создаем, изменяем и уничтожаем. Объекты представляют собой участки памяти, способные хранить данные. Можно сравнить их с почтовым ящиком, куда мы помещаем информацию и откуда её забираем. Все компьютеры обладают оперативной памятью, которую используют программы. При создании объекта выделяется определенный объем оперативной памяти. Большинство объектов в языке C++ являются переменными.

Переменные

Простой стейтмент a = 8; кажется простым: мы устанавливаем значение 8 для переменной a. Но что представляет собой переменная a? a - это идентификатор объекта.

В рамках данного урока мы изучим только переменные, содержащие целые числа. Целое число - это число, которое не имеет дробной части, например: -11, -2, 0, 5 или 34.

Для создания переменной используется оператор объявления (разницу между объявлением и определением переменной мы рассмотрим позже). Вот пример объявления переменной a типа integer (которая может содержать только целые числа):

int a ;

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

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

a = 8 ;

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

После этого мы сможем отобразить данное значение на экране, используя std::cout:

std :: cout << a ; // выводим значение переменной a (ячейка памяти под номером 150) на экран

l-values и r-values

В языке программирования C++ все переменные считаются l-values. l-value (или "л-значение") - это значение, которое имеет свой уникальный адрес в памяти. Поскольку все переменные имеют адреса, то они все являются l-values (например, переменные a, b, c - все они являются l-values). Буква "l" в термине происходит от слова "left", потому что только значения l-values могут находиться слева в операциях присваивания (в противном случае, будет ошибка). Например, попытка выполнить операцию 9 = 10; вызовет ошибку компиляции, так как 9 не является l-value. Число 9 не имеет своего адреса в памяти, поэтому нельзя присвоить ему значение (9 = 9 - это недопустимо).

Понятие r-value противоположно l-value (переводится как «л-значение» , произносится как «эл-валью» ). r-value — это значение, которое не имеет постоянного адреса в памяти. Примерами таких значений могут быть отдельные числа (например, 7 , которое равно 7 ) или математические выражения (например, 3 + х , где значение равно х плюс 3 ).

Ниже приведены несколько примеров операций присваивания с использованием r-values:

int a ; // объявляем целочисленную переменную a

a = 5 ; // 5 имеет значение 5, которое затем присваивается переменной а

a = 4 + 6 ; // 4 + 6 имеет значение 10, которое затем присваивается переменной а

int b ; // объявляем целочисленную переменную b

b = a ; // a имеет значение 10 (исходя из предыдущих операций), которое затем присваивается переменной b

b = b ; // b имеет значение 10, которое затем присваивается переменной b (ничего не происходит)

b = b + 2 ; // b + 2 имеет значение 12, которое затем присваивается переменной b

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

b = b + 2 ;

В данном случае переменная b используется в двух различных контекстах. Слева b выступает в качестве l-value (переменная с адресом в памяти), а справа b используется как r-value и имеет свое собственное значение (в данном случае, 12). При выполнении данного оператора, компилятор обрабатывает следующее:

b = 10 + 2 ;

Здесь уже ясно, какое значение присваивается переменной b.

Не стоит сильно беспокоиться о l-values или r-values в данный момент, так как мы еще вернемся к этой теме на последующих занятиях. Главное, что нужно запомнить сейчас — это то, что в левой части операции присваивания всегда должно быть l-value (у которого есть свой адрес в памяти), а в правой части операции присваивания — r-value (у которого есть определенное значение).

Инициализация vs. Присваивание

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

После того, как переменная была объявлена, ей можно присвоить значение, используя оператор присваивания (знак равенства =):

int a ; // это объявление переменной

a = 8 ; // а это присваивание переменной a значения 8

В C++ есть возможность объявить переменную и сразу же присвоить ей значение, что называется инициализацией (или "определением").

int a = 8 ; // инициализируем переменную a значением 8

Инициализация переменной возможна только после ее объявления.

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

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

Неинициализированные переменные

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

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

#include

int main ( )

{

// Объявляем целочисленную переменную a

int a ;

// Выводим значение переменной a на экран (a - это неинициализированная переменная)

std :: cout << a ;

return 0 ;

}

В данном случае компилятор назначает переменной a определенную ячейку в оперативной памяти, которая в настоящий момент не используется. Затем значение переменной a выводится. Однако на экране мы не увидим ничего, так как компилятор не позволит этому произойти - будет выдана ошибка о том, что переменная a не была инициализирована. В старых версиях Visual Studio компилятор мог показать некорректное значение (например, 7177728, что является мусором), которое находилось в той ячейке памяти, которую он назначил переменной.

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

Важно всегда присваивать начальное значение переменным. Это обеспечит стабильность работы программы и исключит возможность ошибок при компиляции.

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

Тест

Какой результат будет получен при выполнении данных операций?

int a = 6 ;

a = a - 3 ;

std :: cout << a << std :: endl ; // №1

int b = a ;

std :: cout << b << std :: endl ; // №2

// В этом случае a + b является r-value

std :: cout << a + b << std :: endl ; // №3

std :: cout << a << std :: endl ; // №4

int c ;

std :: cout << c << std :: endl ; // №5

Отвечайте на вопросы в комментариях! (Если у вас есть вопросы, также пишите в комментариях!)

149   0  

Comments

    Ничего не найдено.