Ссылочные типы в современных языках программирования: указатели C, ссылки C++, связывание Python
& и
*. В C++ появилась ссылка -
второе имя ("алиас") существующего объекта, без явного разыменования и без
переназначения. В Python - механизм связывания:
имя привязывается к объекту (идентификатор + тип + значение).
C: указатели и их цена
В прошлом уроке роль
ссылочного типа в C играли указатели - переменные с физическими адресами памяти.
Техника мощная, но требовательная: программист вручную берет адрес
(&), вручную разыменовывает (*) и вручную следит,
чтобы не потерять память и не обратиться по мусорному адресу. Расплата
за ошибку - утечки и segmentation fault.
C++: ссылка как второе имя
Для упрощения и безопасности работы с памятью в C++ ввели ссылки. Ссылка - это альтернативное имя (алиас) уже существующего объекта: компилятор сам выполняет разыменование, без явных операций. Сравните две версии одной функции:
/* C: передаем указатель, разыменовываем вручную */
void square_c(int* num) {
*num = (*num) * (*num);
}
/* C++: передаем ссылку - "второе имя" переменной */
void square_cpp(int& num) {
num = num * num; /* меняет оригинал без явного разыменования */
}
Два ограничения делают ссылки безопаснее указателей: ссылку нельзя оставить неинициализированной и нельзя переназначить на другой объект после создания. Она навсегда привязана к своему участку памяти.
Python: не ссылки, а связывание
В Python классического ссылочного типа нет. Вместо него - механизм
связывания (binding). Каждый объект в Python - это тройка:
уникальный идентификатор (его возвращает функция id()), тип
и значение. Оператор = не копирует данные и не пишет в ячейку -
он связывает имя слева с объектом справа.
Разница со ссылками C++ видна при повторном присваивании:
count = 10
count2 = count # count2 связывается с тем же объектом, что и count
count2 = 25 # count2 связывается с НОВЫМ объектом 25
print(count, count2) # 10 25 - исходный count не изменился!
Ссылка C++ в такой ситуации изменила бы значение в общей ячейке. Имя в Python просто связывается с новым объектом, а старый остается неизменным.
id() возвращает идентификатор объекта. После count2 = count
значения id(count) и id(count2) совпадают - имена смотрят
на один объект. После count2 = 25 - уже нет.
Итог: ссылочные типы в современных языках программирования
Коротко: главное
- В классическом C ссылочного типа нет - только указатели с ручными & и *.
- Ссылка C++ - второе имя объекта: без явного разыменования, обязана быть инициализирована и не переназначается.
- В Python - связывание: имя привязывается к объекту (id + тип + значение).
- Переприсваивание в Python связывает имя с новым объектом, а ссылка C++ всегда работает с одной и той же ячейкой.
Проверьте себя
В Python выполнили: count = 10; count2 = count;
count2 = 25. Что напечатает print(count)?