У меня есть следующий код на C++:
#include <iostream>
using namespace std;
int x;
void p(int a, int &b) {
cout << x << " " << a << " " << b << endl;
if (a < b) {
a = x+b;
}
else {
--x;
b += a;
a = x/2;
cout << x << " " << a << " " << b << endl;
p(b-x, a);
}
cout << x << " " << a << " " << b << endl;
}
int main() {
x = 17;
p(42, x);
cout << x << endl;
}
Вывод этого кода следующий, чего я не понимаю:
17 42 17
58 29 58
58 0 29
58 87 29
58 29 58
58
В частности, в mainx=17 присваивает глобальный параметр. Начинается расчет p(a=42,&b=17). Он печатает: x = 17 (global),a = 42 ,b = 17 (pointer). До сих пор хорошо!
Далее он переходит к if. if 42<17 не удовлетворяется и переходит к else, в котором x уменьшается на единицу так x=17-1=16. Не 58.
Что происходит? Может кто-нибудь объяснить?
@SamVarshavchik Я не знаю, как использовать отладчик. Я новичок в c++. Как я могу использовать отладчик в XCODE?
Знаете ли вы, что такое ссылки и что такое рекурсия? Эта программа может показаться простой, поскольку в ней не так много строк, но на самом деле она довольно сложна.
Лично я не знаю XCode и не использую Mac, но первый результат по запросу «xcode debugger» в Google показал мне эту многообещающую статью.
Если вы «новичок в C++», то вы, должно быть, изучаете C++ по хорошему учебнику. Какова тема главы в вашем учебнике по C++, из которой взята эта практическая задача?? Это действительно странный пример программы, который можно встретить во вводном курсе C++. Можете ли вы объяснить, как именно вы, изучая C++, столкнулись с такой бесполезной головоломкой по программированию, которая не имеет абсолютно никакой обучающей ценности с точки зрения преподавания основных фундаментальных концепций C++?
Дело в том, что вы обрабатываете в памяти две ссылки на одно и то же значение: Одна: глобальная x Вторая: ссылка передается как b, но это b является адресом x. Таким образом, оба x, b обрабатывают один и тот же блок памяти (целое число)
Я отредактировал код ОП, чтобы улучшить форматирование и сделать более понятным, что он делает.
«итак x=17-1=16. Не 58.»: Вы правильно рассмотрели все до --x; включительно, но затем пропустили рассмотрение побочных эффектов b += a;.
@ user17732522, потому что b += a; идет после --x.
@HomerJaySimpson Да, но это происходит до того, как будет напечатана вторая строка вывода. Поэтому его побочные эффекты могут повлиять на результат. В этом случае линия оказывает побочный эффект на значение объекта x, поскольку b является ссылкой на x.
@user17732522 user17732522 понял. Большое спасибо.





Ваш параметр b является ссылкой (т. е. псевдонимом) на переменную int. В данном случае это относится к глобальной переменной x, поскольку именно ее передает main(). Итак, x и b — это отдельные имена для одного и того же блока памяти, содержащего значение int. Таким образом, все, что вы делаете с x, отражается на b и наоборот.
Когда ваш код переходит к else в первый раз, значение x (и, следовательно, b) равно 17. Вы уменьшаете x (и, следовательно, b) на 1, а затем увеличиваете b (и, следовательно, x) на a (42). Итак, вы на самом деле увеличиваете x на 41, поэтому x становится 58 (17-1+42=58).
Да, кто-нибудь может это объяснить: ваш отладчик может это объяснить. Именно для этого и нужен отладчик: он запускает вашу программу по одной строке и показывает, что происходит. Используя отладчик, вы можете выполнять эту программу шаг за шагом, проверять значения всех переменных на каждом этапе и точно видеть, что происходит. Умение эффективно использовать отладчик — необходимый навык для каждого разработчика C++. Что показывает вам ваш отладчик, когда вы запускаете эту программу?