Не меняется переменная, переданная в функцию по указателю

Рейтинг: -1Ответов: 2Опубликовано: 02.03.2023

Имеется следующая функция, в которую передается указатель на элемент стэка, но когда я изменяю top в функции, в основной программе не меняется.

 struct Node {   
    int elem = 0;   
    Node* next = nullptr;
}; 

void delete_even_elements(Node* top) {
    top = top->next;
}

Ответы

▲ 3

Сам-то указатель Вы передаёте по значению, а это передача копии. Функция может изменить только эту копию, так как она знает, где лежит эта копия, но оригинал в вызывающем коде сохраняет своё значение, так как функция не знает, где он лежит. Функция может изменить данные по адресу, записанному в указателе, но это Вы не пытаетесь делать. Вот представьте себе: у Вас в шкафу висит шуба, Вы берёте лист бумаги № 1 и пишете: «Шуба в шкафу», кладёте его в ксерокс, копируете текст на лист №2 и эту копию бросаете с балкона, Ваш друг подбирает лист бумаги №2, забирается по водосточной трубе к Вам в квартиру, ищет шубу в шкафу, заглядывает в карман, обнаруживает лист бумаги №3, где написано: «Пальто в шкафу рядом с шубой», закрашивает на листе бумаги №2 текст, напечатанный ксероксом, и пишет вместо него: «Шуба в шкафу рядом с шубой», потом сжигает лист №2, выходит в окно и спускается по трубе, после этого Вы достаёте лист бумаги №1 из ксерокса и видите, что он не изменился. Он и не может измениться, так как друг не знает, где этот лист лежит. Может, Вы его сразу после копирования переложили под ковёр? Друг – функция, лист бумаги №1 – переданный указатель, лист бумаги №2 – указатель, полученный функцией. Вам надо написать: «Записка лежит в ксероксе». Возвращаясь к программе, скажем, что надо передать параметр не по простому указателю, а по двойному указателю, то есть по указателю на указатель:

void delete_even_elements(Node **top)
{
    *top = (*top)->next;
}

. Есть альтернатива – передать параметр по ссылке на указатель:

void delete_even_elements(Node *&top)
{
 top = top->next;
}

.

▲ -1
void delete_even_elements(Node*& top)
{
    top = top->next;
}