C++, передача по ссылочной переменной не обновляется в той же строке, в которой вызывается функция
В моей программе на C++ у меня есть эта функция,
char MostFrequentCharacter(ifstream &ifs, int &numOccurances);
и в main() этот код,
ifstream in("file.htm");
int maxOccurances = 0;
cout <<"Most freq char is "<<MostFrequentCharacter(in, maxOccurances)<<" : "<<maxOccurances;
Но это не работает, хотя я получаю правильный символ, maxOccurance остается нулевым. Но если я заменю приведенный выше код в основном с этим,
ifstream in("file.htm");
int maxOccurances = 0;
char maxFreq = MostFrequentCharacter(in, maxOccurances);
cout <<"Most freq char is "<<maxFreq<<" : "<<maxOccurances;
Тогда он работает правильно. Мой вопрос, почему это не работает в первом случае.
4 ответа
В C++
cout << a << b
По ассоциативности оценивает:
(cout << a) << b
но компилятор может свободно оценивать их в любом порядке.
т.е. компилятор может оценить b
будет первый a
тогда первый <<
операция и вторая <<
операция. Это потому, что нет точки последовательности, связанной с <<
Для простоты рассмотрим следующий код, который эквивалентен:
#include<iostream>
int main()
{
int i = 0;
std::cout<<i<<i++;
return 0;
}
В приведенном выше исходном коде:
std::cout<<i<<i++;
оценивает вызов функции:
operator<<(operator<<(std::cout,i),i++);
В этой функции вызывать ли operator<<(std::cout,i)
или же i++
оценивается первым - Unspecified. то есть:
operator<<(std::cout,i)
может быть оценен первым или i++
может быть оценен первым или
Некоторая Magic Ordering реализована компилятором
Учитывая вышеизложенное, нет способа определить это упорядочение и, следовательно, объяснение также невозможно.
Соответствующая цитата из стандарта C++03:
Раздел 1.9
Некоторые другие аспекты и операции абстрактной машины описаны в этом международном стандарте как неопределенные (например, порядок оценки аргументов функции). Там, где это возможно, этот международный стандарт определяет набор допустимого поведения. Они определяют недетерминированные аспекты абстрактной машины.
Поскольку в первом случае значение maxOccurances в выражении разрешается до вызова MostFrequentCharacter. Хотя это не должно быть так, это неопределенное поведение.
Вы можете получить разные результаты с разными компиляторами или опциями компилятора. Если вы попробуете то же самое на VC++, например, я думаю, вы увидите другие результаты.
Вы просто должны отметить, что там, где вы видите <<
вы на самом деле звоните operator<<
метод - так что компилятор определяет значение аргументов для передачи в эту функцию до изменения вашей переменной.
Другими словами, то, что у вас есть, похоже на
operator<<(operator<<(cout, f(x)), x);
... и так как порядок вычисления аргументов функции не определен, это зависит от компилятора.
Cout работает справа налево в вашем компиляторе, поэтому сначала оценивается самый правый, а затем левый.:) Таким образом, значение указанной переменной не изменилось.