Почему у меня есть разные выводы в этом коде C ++, которые я не мог понять? - PullRequest
0 голосов
/ 23 ноября 2018

Я не мог понять вывод этой программы даже после отладки, особенно в строке, где вы найдете "f (:: x) = h (x)", что это значит?Может ли кто-нибудь помочь мне, пожалуйста, понять программу на C ++ и как она работает, чтобы понять выходные данные.

#include<iostream>
using namespace std;
int x = 6;
int h(int & x)
{
    x = 2*x; 
    return x;
}
int g(int m)
{
    return x++;
}
int& f(int &x)
{
    x+=::x; 
    return x;
}

int main()
{
   int x = -1;
    f(::x) = h(x);
    cout<<f(x)<<" "<<g(x)<<" "<<h(x)<<" "<<x<<" "<<::x<<endl;
    f(::x) = g(x);
    cout<<f(x)<<" "<<g(x)<<" "<<h(x)<<" "<<x<<" "<<::x<<endl;
    return 0;
}

после компиляции выходных данных:
-5 -2 -4 -2 -2
-11 -2 -10 -5 -2

Ответы [ 3 ]

0 голосов
/ 23 ноября 2018

Thera - две переменные с одинаковым именем x .Глобальный x: ":: x" и локальный "x".

f(::x) = h(x);

Эта строка преобразуется в 3 операции:

  • h (x) -> -1 * 2 -> возвращает -2 и x = -2
  • f (:: x) -> f (6) -> :: x = 12 и возвращает ссылку на ':: x'
  • :: x = -2
cout << f(x) << " " << g(x) << " " << h(x) << " " << x << " " << ::x << endl;

В этой строке порядок оценки вызовов не указан, поэтому значения, отображаемые на консоли, могут отличаться.Например, мой вывод:

-5 -2 -4 -5 -1
-10 -1 -10 -10 0

Вы должны понимать основные правила:

int h(int &x);

int & x - означает, что x не копия, это ссылка .Если вы измените эти переменные внутри функции - она ​​изменится снаружи.

int g(int m);

int m - означает, что m является копией.Изменения внутри функции не влияют на нее снаружи

int & f(int &x);

Это означает, что функция возвращает ссылку на некоторую переменную.

0 голосов
/ 23 ноября 2018

Часть проблемы в том, что код был написан в ужасно запутанном стиле.В частности, есть глобальная переменная с именем x и локальная переменная с именем main с именем xf(::x) = h(x) :: означает, что аргумент f является глобальным, а аргумент h - локальным.Давайте начнем с переименования всех переменных:

#include<iostream>
using namespace std;
int x = 6;
int h(int &y){y = 2*y; return y;}
int g(int m){return x++;}
int & f(int &z){z+=x; return z;}
int main()
{
    int w = -1;
    f(x) = h(w);
    cout<<f(w)<<" "<<g(w)<<" "<<h(w)<<" "<<w<<" "<<x<<endl;
    f(x) = g(w);
    cout<<f(w)<<" "<<g(w)<<" "<<h(w)<<" "<<w<<" "<<x<<endl;

    return 0;
}

Теперь становится немного более очевидным, что h изменяет свой аргумент, g изменяет глобальный, а f изменяет свой аргумент и используетglobal.

Выходные данные не определены стандартом, поскольку вы не знаете, в каком порядке вызываются функции.


f(x) = h(w)

Средства:

  • вызвать функцию h, передав ей значение w по ссылке.По возвращении w будет удерживать -2, и это тоже будет результатом функции.
  • вызывает функцию f, передавая ей значение x по ссылке.При возврате x будет удерживать 12, а функция вернет x по ссылке.Обратите внимание, что это может произойти до или после вызова h.
  • . Присвойте значение, возвращаемое h (-2), ссылке, возвращенной f.
* 1039.* Поскольку все это происходит внутри вызовов функций, не существует неопределенного поведения, но имеется поразительное большое количество возможных выходных данных.
0 голосов
/ 23 ноября 2018

Давайте перепишем это так, чтобы не было никаких столкновений имен.Обратите внимание, что многие из этих функций изменяют передаваемый им объект, поэтому при выводе значения меняются.Поскольку порядок, в котором происходят эти изменения, не определен, общий результат может отличаться для любых двух оценок.

#include<iostream>

int global = 6;

int h(int & h_param){ h_param = 2 * h_param; return h_param; }
int g(int ){ return global++; }
int & f(int & f_param){ f_param += global; return f_param; }

int main()
{
    int local = -1;
    f(global) = h(local);
    std::cout << f(local) << " " << g(local) << " " << h(local) << " " << local << " " << global << std::endl;
    f(global) = g(local);
    std::cout << f(local) << " " << g(local) << " " << h(local) << " " << local << " " << global << std::endl;
    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...