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

Изменение значение переменной в одном выражении - C++

Войти
Регистрация
Восстановить пароль
 
Ксю92
 Аватар для Ксю92
73 / 7 / 0
Регистрация: 29.03.2011
Сообщений: 94
13.06.2012, 05:25     Изменение значение переменной в одном выражении #1
Доброго утра! Написала такую нехитрую программку, посмотреть что будет, если вычислить j++ * ++j/j-- * --j... и тут я в ступоре....((( почему такой результат??
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
 
int main(int argc, char ** argv)
{
  int j, tmp;
 
  std::cout << "j-> "; std::cin >> j;
  tmp = j;
  std::cout << "j++ * ++j/j-- * --j  -> " << j++ * ++j/j-- * --j << "\n";
  j = tmp;
  std::cout << "tmp -> " << tmp << "\nj++ -> " << j++ << "\n++j -> " << ++j 
  << "\nj-- -> " << j-- << "\n--j -> " << --j << "\n";
 
  return 0;
}
вот что на выходе
xenia@glandule:~$ cd ~/Рабочий\ стол
xenia@glandule:~/Рабочий стол$ g++ t.cpp
xenia@glandule:~/Рабочий стол$ strip a.out
xenia@glandule:~/Рабочий стол$ ./a.out
j-> 5
j++ * ++j/j-- * --j -> 25
tmp -> 5
j++ -> 4
++j -> 4
j-- -> 4
--j -> 4
xenia@glandule:~/Рабочий стол$


точнее, меня интересует почему
tmp -> 5
j++ -> 4
++j -> 4
j-- -> 4
--j -> 4

а не
tmp -> 5
j++ -> 5
++j -> 6
j-- -> 6
--j -> 5

почему j++ * ++j/j-- * --j = 25 вроде поняла))
т.к. для j = 5 будет j++ = 5; ++j = 6 -> 5*6 = 30; j-- = 6 -> 30/6 = 5; --j = 5 -> 5*5 = 25

Заранее спасибки за объяснение))

Если это важно
ОС: Ubuntu 12.04 LTS 64-bit

xenia@glandule:~/Рабочий стол$ g++ --version
g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
Copyright (C) 2011 Free Software Foundation, Inc.
Это свободно распространяемое программное обеспечение. Условия копирования
приведены в исходных текстах. Без гарантии каких-либо качеств, включая
коммерческую ценность и применимость для каких-либо целей.

xenia@glandule:~/Рабочий стол$


Не по теме:

Более информативного названия темы, к сожалению, не придумала(((

Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.06.2012, 05:25     Изменение значение переменной в одном выражении
Посмотрите здесь:

C++ при вычислении выражении - одно значение,а в калькуляторе другое!
C++ Изменение значения статической переменной
C++ Изменение значения переменной во время исполнения
Изменение переменной перез указатель C++
Сбрасывается значение переменной C++
C++ Изменение переменной во вложенном цикле
Не могу сделать событие на изменение данных в переменной , int или CString C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
gray_fox
What a waste!
 Аватар для gray_fox
1246 / 1129 / 54
Регистрация: 21.04.2012
Сообщений: 2,354
Завершенные тесты: 3
13.06.2012, 05:28     Изменение значение переменной в одном выражении #2
Цитата Сообщение от Ксю92 Посмотреть сообщение
j++ * ++j/j-- * --j
Результат не определён, т.е. тут вообще может быть что угодно.
Ксю92
 Аватар для Ксю92
73 / 7 / 0
Регистрация: 29.03.2011
Сообщений: 94
13.06.2012, 05:29  [ТС]     Изменение значение переменной в одном выражении #3
Цитата Сообщение от gray_fox Посмотреть сообщение
Результат не определён, т.е. тут вообще может быть что угодно.
Почему? Ведь я явно ввожу значение в j
MrGluck
Ворчун
Эксперт С++
 Аватар для MrGluck
5676 / 3155 / 357
Регистрация: 29.11.2010
Сообщений: 8,452
13.06.2012, 05:34     Изменение значение переменной в одном выражении #4
предположим j = 5
Берем его и суммируем с самим собой, учитывая, что после того, как написали j++ j уже равна 6, а при операции ++j мы сначала добавляем 1, т.е. j уже становится равна 7. j++ * ++j это 5 * 7.
j-- На момент обращения j = 7, после равна 6. Выходит j++ * ++j / j-- = 5 * 7 / 7. При этом j = 6. Умножаем мы на --j, т.е. сначала отнимаем единицу, а потом умножаем. Выходит, что
j++ * ++j / j-- * --j == 5(j = 6) * 7(j = 7) / 7(j = 6) * 5(j = 5) == 5 * 7 / 7 * 5 == 25.
gray_fox
What a waste!
 Аватар для gray_fox
1246 / 1129 / 54
Регистрация: 21.04.2012
Сообщений: 2,354
Завершенные тесты: 3
13.06.2012, 05:36     Изменение значение переменной в одном выражении #5
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Ну я в формальных определениях не особо силён, надо искать на тему "точки следования" или как то так... Суть в том, что изменение значения переменной в одном выражении (до ';') определено как "undefined behaviour".

Добавлено через 1 минуту
Вот здесь есть про это: http://alenacpp.blogspot.com/2005/11...ce-points.html
Ксю92
 Аватар для Ксю92
73 / 7 / 0
Регистрация: 29.03.2011
Сообщений: 94
13.06.2012, 05:38  [ТС]     Изменение значение переменной в одном выражении #6
Цитата Сообщение от Ксю92 Посмотреть сообщение
почему j++ * ++j/j-- * --j = 25 вроде поняла))
т.к. для j = 5 будет j++ = 5; ++j = 6 -> 5*6 = 30; j-- = 6 -> 30/6 = 5; --j = 5 -> 5*5 = 25
Это я поняла))

Вы мне объясните, почему
Цитата Сообщение от Ксю92 Посмотреть сообщение
точнее, меня интересует почему
tmp -> 5
j++ -> 4
++j -> 4
j-- -> 4
--j -> 4

а не
tmp -> 5
j++ -> 5
++j -> 6
j-- -> 6
--j -> 5
тут j = tmp изначально
MrGluck
Ворчун
Эксперт С++
 Аватар для MrGluck
5676 / 3155 / 357
Регистрация: 29.11.2010
Сообщений: 8,452
13.06.2012, 05:40     Изменение значение переменной в одном выражении #7
В статье все написано.

Для себя тоже подчерпнул много интересного)
gray_fox
What a waste!
 Аватар для gray_fox
1246 / 1129 / 54
Регистрация: 21.04.2012
Сообщений: 2,354
Завершенные тесты: 3
13.06.2012, 05:46     Изменение значение переменной в одном выражении #8
Ксю92, тут (там, где с выводом) тоже самое: несколько раз изменяете значение переменной j. То, что там будет что то осмысленное, никто не гарантирует.
Ксю92
 Аватар для Ксю92
73 / 7 / 0
Регистрация: 29.03.2011
Сообщений: 94
13.06.2012, 05:48  [ТС]     Изменение значение переменной в одном выражении #9
Цитата Сообщение от MrGluck Посмотреть сообщение
Потому что std::cout<< j++ означает сначала вывести на экран, а потом добавить 1.
++j напротив сначала добавляет 1, потом выводит на экран.
вот смотрим на мой код
C++
1
2
std::cout << "tmp -> " << tmp << "\nj++ -> " << j++ << "\n++j -> " << ++j 
  << "\nj-- -> " << j-- << "\n--j -> " << --j << "\n";
j мы вводим с клавиатуры. Допустим, ввели 5
j++ выведется на экран 5; но j увеличится на 1 (теперь j = 6)
++j j увеличится на 1, и выведется на экран, т.е. выведется 7
j-- выведется также 7, т.к. сначала выводим текущее значение, а потом уменьшаем на 1 (теперь j = 6)
--j выведется 5, т.к. сначала уменьшили на 1, а потом вывели

НО ПОЧЕМУ ВЫВОДИТСЯ
j++ -> 4
++j -> 4
j-- -> 4
--j -> 4


Добавлено через 46 секунд
Сейчас статью буду читать)
gray_fox
What a waste!
 Аватар для gray_fox
1246 / 1129 / 54
Регистрация: 21.04.2012
Сообщений: 2,354
Завершенные тесты: 3
13.06.2012, 05:49     Изменение значение переменной в одном выражении #10
Цитата Сообщение от Ксю92 Посмотреть сообщение
++ выведется на экран 5; но j увеличится на 1 (теперь j = 6)
++j j увеличится на 1, и выведется на экран, т.е.
т.е. дважды изменяешь значение одной переменной в одном выражении. всё, приехали)
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
13.06.2012, 05:52     Изменение значение переменной в одном выражении #11
Сообщение было отмечено автором темы, экспертом или модератором как ответ
включаем у gcc опцию -Wsequence-point и смотрим, что он по этому поводу думает
Ксю92
 Аватар для Ксю92
73 / 7 / 0
Регистрация: 29.03.2011
Сообщений: 94
13.06.2012, 05:57  [ТС]     Изменение значение переменной в одном выражении #12
Цитата Сообщение от gray_fox Посмотреть сообщение
т.е. дважды изменяешь значение одной переменной в одном выражении. всё, приехали)
gray_fox, не не)) все верно) выведется на экран 5 но значение j увеличится на 1 (теперь j = 6)

Добавлено через 3 минуты
Цитата Сообщение от alex_x_x Посмотреть сообщение
включаем у gcc опцию -Wsequence-point и смотрим, что он по этому поводу думает
Вот что он думает))
xenia@glandule:~$ cd ~/Рабочий\ стол
xenia@glandule:~/Рабочий стол$ g++ t.cpp -Wsequence-point
t.cpp: В функции «int main(int, char**)»:
t.cpp:31:73: предупреждение: операция над «j» может дать неопределенный результат [-Wsequence-point]
t.cpp:31:73: предупреждение: операция над «j» может дать неопределенный результат [-Wsequence-point]
t.cpp:31:73: предупреждение: операция над «j» может дать неопределенный результат [-Wsequence-point]
t.cpp:33:128: предупреждение: операция над «j» может дать неопределенный результат [-Wsequence-point]
xenia@glandule:~/Рабочий стол$ strip a.out
xenia@glandule:~/Рабочий стол$ ./a.out
j-> 5
j++ * ++j/j-- * --j -> 25
tmp -> 5
j++ -> 4
++j -> 4
j-- -> 4
--j -> 4
xenia@glandule:~/Рабочий стол$


P.S. В принципе, это ответ на мой вопрос))

Добавлено через 24 секунды
alex_x_x, спасибки!))
CyBOSSeR
Эксперт C++
 Аватар для CyBOSSeR
2295 / 1665 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
17.07.2012, 00:47     Изменение значение переменной в одном выражении #13
Ксю92, на самом деле в Вашем примере все очевидно, как уже сказали переменная модифицируется дважды не переходя через точку следования. Есть менее очевидные способы наступить на грабли:
C++
1
2
3
4
void foo(int, int);
 
int i = 1;
foo(i, ++i); // UB
C++
1
2
3
int a = [1, 2, 3, 4];
int i = 0;
a[i] = ++i; // UB
C++
1
2
int a = 0, b = 1, c = 2;
(a += b) += c; // UB
В С++11 дела с этим обстоят лучше, т.к. вместо точек следования было введено отношение sequenced before.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.07.2012, 01:05     Изменение значение переменной в одном выражении
Еще ссылки по теме:

Функция отслеживающая изменение состояния переменной C++
C++ Как найти максимальное значение в одном столбце матрице?
C++ Один и тот же объект в одном выражении модифицируется несколько раз - неопределенное поведение
Изменение переменной C++
C++ Изменение переменной каждые n раз

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

Или воспользуйтесь поиском по форуму:
Troll_Face
 Аватар для Troll_Face
599 / 399 / 4
Регистрация: 26.04.2012
Сообщений: 2,070
17.07.2012, 01:05     Изменение значение переменной в одном выражении #14
собственно вторую часть кода все правильно вывел (по которой был вопрос). а вот почему формула в ответе 30 дала - ХЗ...
Миниатюры
Изменение значение переменной в одном выражении  
Yandex
Объявления
17.07.2012, 01:05     Изменение значение переменной в одном выражении
Ответ Создать тему
Опции темы

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