ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 11.04.2025

Просмотров: 159

Скачиваний: 0

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

Неизменяемость и указатели

Что неизменяемо?

всё изменяемо:

int

*

p;

*pointer = 0;

pointer = nullptr;

адрес:

int

* const

cp;

*const_pointer = 0;

const_pointer = nullptr;

значение:

const

int

*

pc;

*pointer_to_const = 0;

pointer_to_const = nullptr;

и то, и другое:

const

int

* const

cpc;

*const_pointer_to_const = 0;

const_pointer_to_const = nullptr;

Курс ТП, осень 2014 г.

© Кафедра УиИ НИУ «МЭИ»

13


Тип данных «ссылка»

• Ссылка — новое имя ячейки памяти.

double

x = 1;

Амперсанд перед именем переменной.

double

y = 3;

Инициализация:

double& z = x;

«привязка» к значению (переменной);

z = 2;

обязательна

• иначе — «новое имя» для чего?

// x == 2, y == 3, z == 2

z = y;

Действия над ссылкой

равнозначны действиям

// x == 3, y == 3, z == 3

над привязанной переменной.

y = 4;

// x == 3, y == 4, z == 3

Привязку изменить нельзя.

Курс ТП, осень 2014 г.

© Кафедра УиИ НИУ «МЭИ»

14

Применение ссылок

Сокращение кода:

double& middle = data [ data . size() / 2 ]; middle = 42;

// data [ data . size() / 2 ] == 42

double& x = change_a_or_b ? a : b; x += 2;

Неизменяемые ссылки:

const double& middle = data [ data . size() / 2 ]; middle = 42;

Неизменяемость всегда относится к значению.

Курс ТП, осень 2014 г.

© Кафедра УиИ НИУ «МЭИ»

15


Неизменяемые параметры

Будет создана копия значения a и помещена в x.

void f (int x) {

void f (const int x) {

x = 42;

// …

// x == 42

}

Копию нельзя изменить

}

Копия разрушается.

• и обычно не нужно.

int a = 0; f (a);

// a == 0

Действия

 А если x — вектор или строка?

над копией

• Большого размера?

не влияют

на аргумент.

 Зачем вообще копия?

• Нужна независимость x и a.

• Обычно нужна неизменяемость.

Курс ТП, осень 2014 г.

© Кафедра УиИ НИУ «МЭИ»

16

Передача без копирования

• Передача по ссылке:

void function ( vector<int>& data ) { … }

Нет копирования.

Аргумент и data связаны.

Передача по неизменяемой ссылке:

void function ( const vector<int>& data ) { … }

Копирования нет.

Случайно изменить data нельзя.

Изменять параметры — плохая практика!

Имеет смысл использовать по умолчанию.

Кроме int, double, … (пользы нет, вреда — тоже).

Курс ТП, осень 2014 г.

© Кафедра УиИ НИУ «МЭИ»

17


Рекурсия

Вызов функцией самой себя.

Для случаев, когда

задача

часть решения

такая же задача

с другими условиями

путь(от Новокосино до Авиамоторной) =

«Новокосино — Новогиреево» + путь(от Новогиреево до Авиамоторной)

Курс ТП, осень 2014 г.

© Кафедра УиИ НИУ «МЭИ»

18

Рекурсивный вызов

// 23 = 8

= =

∙ −1,

> 0

power ( 2, 3 );

,

1,

= 0 =

double power ( 2, 3) {

=

∙ ( , − 1),

> 0

if (3 == 0)

1,

= 0

return 1;

условие окончания

return 2 * power ( 2, 3 − 1 );

}

4

double power (double a, int n) {

double power ( 2, 2) {

if (n == 0)

if (2 == 0)

return 1;

return a * power ( a, n − 1 );

return 1;

}

return 2 * power ( 2, 2 − 1 );

}

2

double power ( 2, 1) {

double power ( 2, 0) {

if (1 == 0)

if (0 == 0)

return 1;

return 1;

return 2 * power ( 2, 1 − 1 );

return 2 * power ( 2, 0 − 1 );

}

1

}

Курс ТП, осень 2014 г.

© Кафедра УиИ НИУ «МЭИ»

19


Рекурсия (продолжение)

Вызов функции расходует часть ограниченной области памяти — стека.

 Этот расход возвращается по выходе из функции.

 Глубокая рекурсия сильно расходует стек.

Бесконечная рекурсия невозможна.

!

Ошибка: «Stack overflow» («переполнение стека»).

 Прямая рекурсия

Косвенная рекурсия

power()

Проложить путь к соседней станции.

В каком порядке

Искать путь по двум разным маршрутам.

объявлять функции?

Курс ТП, осень 2014 г.

© Кафедра УиИ НИУ «МЭИ»

20