Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
mariko_11
2 / 2 / 1
Регистрация: 11.03.2013
Сообщений: 64
#1

Что с выводом на консоль? - C++

10.02.2014, 21:42. Просмотров 384. Ответов 18
Метки нет (Все метки)

Имеется классическая функция рекурсивного поиска чисел Фибоначчи. Вывод на консоль ведёт себя неожиданно.

Вот в этом варианте

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
 
using namespace std;
 
long long int counter=0;
 
template <class T>
T fib(T n)
{
 
    counter++;
    if (n==0||n==1)
        return n;
    else
        return fib(n-1)+fib(n-2);
 
}
int main()
{
    long long int k=4;
 
    cout << fib(k) << "\t" << counter << endl;
 
    cout << "Hello World!" << endl;
    return 0;
}
на консоль выводится, что значение счётчика равно 0. Почему ? Причём оно действительно меняется во время работы функции. Стоит только заменить вывод на
C++ (Qt)
1
cout << fib(k) << "\t"; cout << counter << endl;
,
всё начинает работать нормально. Это что же, получается, в cout сначала попадает значение глобальной переменной и только потом результат расчёта чисел Фибоначчи? А с какой стати? Вызов функции идёт раньше.

Добавлено через 9 минут
Вот ещё что обнаружилось:
C++ (Qt)
1
2
3
int a=1;
 
    cout << a << "\t" << ++a << endl;
Компилятор сообщает, что результат может быть не определён. Выводятся две двойки. И вот почему ? Вообще где можно почитать про очерёдность выполнения в таком случае ?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.02.2014, 21:42     Что с выводом на консоль?
Посмотрите здесь:

Что с программой - когда запускаю, консоль пустая C++
Прoблемa с выводом в консоль. Почти сразу закрывается. C++
C++ Ошибка с выводом в консоль
не могу понять что с выводом C++
C++ как проверить что в консоль вводился только английский алфавит?
C++ При компиляции консоль появляется на несколько секунд не смотря на то что
Что то с выводом в консоль C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
programina
 Аватар для programina
1912 / 597 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
10.02.2014, 21:50     Что с выводом на консоль? #2
Цитата Сообщение от mariko_11 Посмотреть сообщение
на консоль выводится, что значение счётчика равно 0. Почему ?
потому что cout сначала узнает counter , а затем выполняет функцию фибоначи.

Вот так должно работать:
C++
cout << fib(k) << "\t";
cout << counter << endl;
DrOffset
6817 / 4028 / 924
Регистрация: 30.01.2014
Сообщений: 6,847
10.02.2014, 21:57     Что с выводом на консоль? #3
Цитата Сообщение от mariko_11 Посмотреть сообщение
Компилятор сообщает, что результат может быть не определён. Выводятся две двойки. И вот почему ? Вообще где можно почитать про очерёдность выполнения в таком случае ?
Порядок вычисления аргументов не определен. Нельзя закладываться на поведение типа такого:
C++
1
foo(a, a++);
Т.к. в зависимости от реализации порядок может быть произвольным. Следовательно в общем случае предсказать результат нельзя. Отсюда правило, нельзя допускать одновременного доступа на чтение и на запись (или несколько раз на запись) одной и той же переменной в одном выражении. Раньше (в стандарте) был термин "точка следования". В гугле много ссылок.

Почитать также можно в стандарте (как и все остальное связанное с языком):
8.3.6/9:
The order of evaluation of function arguments is unspecified.
Байт
Эксперт C
 Аватар для Байт
15043 / 9445 / 1383
Регистрация: 24.12.2010
Сообщений: 17,482
10.02.2014, 22:12     Что с выводом на консоль? #4
Цитата Сообщение от mariko_11 Посмотреть сообщение
C++
1
cout << a << "\t" << ++a << endl;
Ежели не желаете себе головной боли, лучше эти штучки бросить. Писать по-честному
C++
1
2
cout << a << "\t" << a+1 << endl;
++a;
Исследуете возможности и закоулки? Бог в помощь!
Поймите, K&R просто шутили тогда от избытка молодой своей энергии и от естественного восторга перед творением своим. Да, синтаксически все правильно. А вот семантику этого хозяйства надо знать на приличном уровне.

Не по теме:

"Фома, идите как все, по камушкам"

mariko_11
2 / 2 / 1
Регистрация: 11.03.2013
Сообщений: 64
10.02.2014, 22:28  [ТС]     Что с выводом на консоль? #5
Если не знать возможности и закоулки, может случиться быдлокод. Так что про камушки было лишнее.
Байт
Эксперт C
 Аватар для Байт
15043 / 9445 / 1383
Регистрация: 24.12.2010
Сообщений: 17,482
10.02.2014, 22:42     Что с выводом на консоль? #6
mariko_11, Ежели желаете себе головной боли - да кто ж посмеет вас остановить! Ваша голова - вам ее и лечить!
Цитата Сообщение от mariko_11 Посмотреть сообщение
может случиться быдлокод
Может. Уже случился. Ваш код невнятен и труден в разборке. Я не завидую тем, кто в вашем коде будет разбираться по долгу службы. Надеюсь, это произойдет еще не скоро.
mariko_11
2 / 2 / 1
Регистрация: 11.03.2013
Сообщений: 64
10.02.2014, 22:49  [ТС]     Что с выводом на консоль? #7
Цитата Сообщение от Байт Посмотреть сообщение
mariko_11, Ежели желаете себе головной боли - да кто ж посмеет вас остановить! Ваша голова - вам ее и лечить! Может. Уже случился. Ваш код невнятен и труден в разборке. Я не завидую тем, кто в вашем коде будет разбираться по долгу службы. Надеюсь, это произойдет еще не скоро.
А никак нельзя было ответить без хамства? Про внятность учебного кода из трёх строчек, предназначенного для различных экспериментов над ним, - порадовало особенно. А если уж случится обнаружить неожиданное свойство, о котором особо не говорят, на форуме спрашивать, конечно же, нельзя. Это ж вы...пендрёж, не иначе. Делать нечего больше, что ли, - так самоутверждаться за счёт задающих вопросы?
alsav22
5410 / 4806 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
10.02.2014, 22:56     Что с выводом на консоль? #8
Точки следования
Байт
Эксперт C
 Аватар для Байт
15043 / 9445 / 1383
Регистрация: 24.12.2010
Сообщений: 17,482
10.02.2014, 23:40     Что с выводом на консоль? #9
Цитата Сообщение от mariko_11 Посмотреть сообщение
без хамства
Уважаемый. Если вы мне покажете, где именно вы усмотрели хамство с моей стороны, буду весьма благодарен. Всеми способами старюсь этого избежать. Хотя, если по-честному, иногда и хочется.
mariko_11
2 / 2 / 1
Регистрация: 11.03.2013
Сообщений: 64
10.02.2014, 23:46  [ТС]     Что с выводом на консоль? #10
Это как раз тот случай: если надо объяснять, то не надо объяснять.
Байт
Эксперт C
 Аватар для Байт
15043 / 9445 / 1383
Регистрация: 24.12.2010
Сообщений: 17,482
10.02.2014, 23:50     Что с выводом на консоль? #11
Цитата Сообщение от mariko_11 Посмотреть сообщение
Это как раз тот случай: если надо объяснять, то не надо объяснять.

Не по теме:

ИМХО, вы далеко пойдете. Демагогия - ваш конек. желаю удачи.

mariko_11
2 / 2 / 1
Регистрация: 11.03.2013
Сообщений: 64
10.02.2014, 23:53  [ТС]     Что с выводом на консоль? #12
По поводу последней статьи:
Несколько присваиваний подряд
Интересный момент с таким кодом:
int a=1, b=2, c=3;
a=b=c=0;
Стандарт как-то очень нечетко описывает такую ситуацию. Он говорит, что операция должна происходить справа налево, но ничего не говорит дополнительно по поводу того, когда должен быть результат этой операции записан в переменную. Точек следования внутри выражения нет, что значит, что компилятор может теоретически творить здесь что угодно и не обязательно все переменные в итоге будут равны 0.
А не всё ли равно, когда результат записывается в переменные? Значения-то определены.
DrOffset
6817 / 4028 / 924
Регистрация: 30.01.2014
Сообщений: 6,847
10.02.2014, 23:56     Что с выводом на консоль? #13
Друзья, не ссорьтесь. Закоулки знать надо (иначе можешь не понять что написал другой, но менее опытный любитель закоулков), но знать и границы дозволенного. Есть ситуации, когда оно нужно, а есть - когда вредно. Профессионализм - в умении различать эти ситуации.

По поводу закоулков есть где поучиться.
И далее, там много частей.
В основном в контексте reverse engineering, хоть (вроде) и не сказано об этом явно.
programina
10.02.2014, 23:57
  #14

Не по теме:

Цитата Сообщение от mariko_11 Посмотреть сообщение
если надо объяснять, то не надо объяснять
Что-то философское. Это Лао-Цзы?
Единство и борьба противоположностей...
Инь-янь...

DrOffset
6817 / 4028 / 924
Регистрация: 30.01.2014
Сообщений: 6,847
11.02.2014, 00:01     Что с выводом на консоль? #15
Цитата Сообщение от mariko_11 Посмотреть сообщение
А не всё ли равно, когда результат записывается в переменные? Значения-то определены.
Алена в этом случае немножко перестаралась. Тут реально будет все нормально. Просто порядок зануления не определен. Но нулями в итоге будут все.
mariko_11
11.02.2014, 00:02  [ТС]
  #16

Не по теме:

Это когда очевидные вещи не очевидны. Бесполезно распинаться.

programina
11.02.2014, 00:03
  #17

Не по теме:

Цитата Сообщение от mariko_11 Посмотреть сообщение
Это когда очевидные вещи не очевидны. Бесполезно распинаться
Вы хотите сказать Метать бисер перед свиньями?

mariko_11
11.02.2014, 00:04  [ТС]
  #18

Не по теме:

Типа того.

MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.02.2014, 00:11     Что с выводом на консоль?
Еще ссылки по теме:

C++ Запускаеться только консоль результаты не показывает,что нужно исправить?
Что-то не так с выводом матрицы C++
Что-то не то с выводом сохранённых данных из бинарного файла C++
Что надо сделать, чтобы консоль после вызова не закрывалась C++
Подключение к Access из консольного приложения MVS2012 и выборка данных c выводом в консоль C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
DrOffset
6817 / 4028 / 924
Регистрация: 30.01.2014
Сообщений: 6,847
11.02.2014, 00:11     Что с выводом на консоль? #19
Поправлюсь, в новом стандарте даже более четкая формулировка:
5.17/1
The assignment operator (=) and the compound assignment operators all group right-to-left. All require a
modifiable lvalue as their left operand and return an lvalue referring to the left operand. The result in all
cases is a bit-field if the left operand is a bit-field. In all cases, the assignment is sequenced after the value
computation of the right and left operands, and before the value computation of the assignment expression.
With respect to an indeterminately-sequenced function call, the operation of a compound assignment is
a single evaluation.
[Note: Therefore, a function call shall not intervene between the lvalue-to-rvalue
conversion and the side effect associated with any single compound assignment operator.
—end note ]
Yandex
Объявления
11.02.2014, 00:11     Что с выводом на консоль?
Ответ Создать тему
Опции темы

Текущее время: 14:18. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru