Странный вывод, не так, как ожидалось

0

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

#include <cstdio>
#include <iostream>

using namespace std;
unsigned n = 4242;

int getRemainderOf(int m, int n, int& quotient);

static int l = 0;   
int main()
{

    int quotient;  // the value of which should be changed after calling the func.

    for(int i=-1; i<=1; ++i)
    {
        for(int j=-1; j<=1; ++j)
        {
            if( i && j )
            {

                cout << "("<< i*3 << "," << j*7 << ") "  <<( getRemainderOf(i*3, 7*j, quotient) ) << " " << quotient <<endl;

                cout << "("<< i*7 << "," << j*3 << ") "  << getRemainderOf(i*7, 3*j, quotient) << " "; cout << quotient <<endl;
            }
        }
    }

    return 0;
}

int getRemainderOf(int m, int n, int& quotient)
{
    ++l;
    cout << l <<endl;
    quotient = m / n;
    cout << " quotient " << quotient <<endl;
    return m % n;
}

поэтому то, что я ожидал увидеть в первой строке моего вывода, это остаток, а затем частное, которое я получаю после вызова функции getRemainderOf(). Но вместо этого, когда я отказываюсь от значения частного, я вижу, что значение частного является значением мусора. Поэтому значение переменной не изменяется, хотя я передал ее функции, используя ссылку. Самое забавное, что если я оставлю остаток (получив вызов функции) и частное, я получу его правильно. Я вижу, что проблема может заключаться в вызове функции в качестве аргумента функции operator <<, но я не понимаю, почему значение quotient не изменяется, так как я вызываю функцию до ее вывода. Эта ассоциативность операторов слева направо, так что неправильно? Не могли бы вы рассказать мне, в чем причина этого выхода.

Теги:
stream
reference
cout
iostream

2 ответа

0
Лучший ответ

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

int i = 10;
f(i, ++i);

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

5.2/4 Postfix Epressions [expr.post]

Когда вызывается функция, каждый параметр должен быть инициализирован соответствующим аргументом. [Примечание: такие инициализации индетерминированно упорядочены относительно друг друга (1.9) - примечание конца)

Поскольку они неопределенно упорядочены, компилятор имеет право оценивать ++i до первого аргумента и инициализировать его соответствующим параметром функции, а затем оценивать i и инициализировать его соответствующим параметром next.

Признак неопределенности аргумента функции аргумента функции применим здесь, потому что operator<<() является функцией, но он просто вызывается с синтаксисом оператора. Например, это то, как выглядит ваш код, если мы используем синтаксис operator-id:

std::operator<<(std::operator<<(std::operator<<(std::cout, "(").operator<<(i*3), ",").operator<<(j*7), ")").operator<<(getRemainderOf(i*3, 7*j, quotient)).operator<<(quotient);

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

Решением является последовательность действий по модификации объекта и его использование в вызове operator<<(). Вы уже достигли этого с разбиением вызова operator<<() на два оператора с точкой с запятой ; , поэтому функция должна быть вызвана до того, как будет напечатано quotient.

  • 0
    Привет, спасибо за ваш глубокий ответ, я наконец понял, в чем проблема. 10х, приятель :)
  • 0
    @ user3576192 Рад, что смог помочь! Не могли бы вы также принять мой ответ, нажав на галочку?
0

Порядок оценки аргументов функции не указан. В этих заявлениях

cout << "("<< i*3 << "," << j*7 << ") "  <<( getRemainderOf(i*3, 7*j, quotient) ) << " " << quotient <<endl;

cout << "("<< i*7 << "," << j*3 << ") "  << getRemainderOf(i*7, 3*j, quotient) << " "; cout << quotient <<endl;

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

cout << "("<< i*3 << "," << j*7 << ") "  <<( getRemainderOf(i*3, 7*j, quotient) ) ;
cout << " " << quotient <<endl;

Ещё вопросы

Сообщество Overcoder
Наверх
Меню