Передача переменной по значению имеет тот же результат, что и передача по ссылке - PullRequest
2 голосов
/ 18 января 2020
#include <iostream>
#include <vector>
using namespace std;
int main()
{
        vector <int> arr {12,13,14,15,16};
        for (auto & x: arr)
        {
                ++x;
                cout << x << " ";
        }

return 0;
}

VS

#include <iostream>
#include <vector>
using namespace std;
int main()
{
        vector <int> arr {12,13,14,15,16};
        for (auto x: arr)
        {
                ++x;
                cout << x << " ";
        }

return 0;
}

Вывод остается тем же самым, и мы получаем каждое значение в векторе, увеличивающееся на 1. Но мой учебник говорит об этом. Изображение из учебника Когда в моих учебниках написано "x предполагает копию каждого значения в векторе", что это значит?

Вот вывод кода на снимке экрана Вывод кода Первый вывод с & Второй вывод без &

Ответы [ 4 ]

2 голосов
/ 18 января 2020

Выход остается прежним

Если вы удаляете ссылку (&), вы только передаете значение x, а не x, поэтому, если у вас есть Код для изменения x любым способом, вам нужно будет передать его со ссылкой, как в первом примере, в противном случае вы изменяете только локальную переменную, а не исходную.

Печатные значения одинаковы, потому что в первом примере вы увеличиваете переменную и печатаете ее, во втором примере вы печатаете локальную переменную (ведь это просто копия), но также увеличивается.

Таким образом, если вы напечатаете вектор еще раз, вы увидите, что версия без ссылки не изменила его. Как видите ЗДЕСЬ

1 голос
/ 18 января 2020

Ваш пример не оптимален для понимания базового поведения, попробуйте что-то вроде:

#include <iostream>
#include <string>
#include <vector>
using namespace std;

void reference()
{
    cout << "reference" << endl;
    vector <int> arr {12,13,14,15,16};
  for (auto& x: arr)
    ++x;
  for (const auto& x : arr)
    cout << x << endl;
}

void value()
{
  cout << "value" << endl;
  vector <int> arr {12,13,14,15,16};
  for (auto x: arr)
    ++x;
  for (const auto& x : arr)
    cout << x << endl;
}

int main()
{
  value();
  reference();
  return 0;
}

Теперь результат будет:

value
12
13
14
15
16
reference
13
14
15
16
17

Как вы можете видеть, в в контрольном случае значения внутри векторов изменяются напрямую, потому что вы зацикливаетесь на vector, используя ссылки, так что x локально по отношению к l oop является ссылкой на фактическое значение внутри vector (а не копия, что происходит по значению).

Таким образом, любая модификация отражается на исходном элементе.

0 голосов
/ 18 января 2020

Дело в том, что значение вектора обрабатывается по ссылке и по значению. Ниже приведен другой тип обработки значений: https://en.cppreference.com/w/cpp/language/range-for

Когда значение элемента перехватывается по значению:

(auto x: arr), создается дополнительная копия, а затем мы используем его в for-l oop.

Когда значение перехватывается по ссылке:

(auto & x: arr), копия не генерируется, вместо этого берется адрес векторного элемента и значение используется в for-l oop. Таким образом, фактические векторные элементы / элементы в этом случае изменяются.

0 голосов
/ 18 января 2020

Я думаю, что вам нужно изменить элементы вашего вектора (увеличивая их на единицу), следовательно, если вы передаете векторные элементы по значению, l oop будет использовать копии ваших векторных элементов, а не самих ваших элементов.

Следовательно, вы должны использовать ссылки на свои векторные элементы.

В этом вы можете убедиться, воспользовавшись подсказкой в ​​комментарии.

...