префиксный инкремент
Модератор: Модераторы разделов
-
- Сообщения: 126
- ОС: archlinux
префиксный инкремент
К примеру:
{
int x=5;
x=++x + ++x;
cout << x;
}
На С++ у меня получилось 14. Но в разных языках разное число получается.
По идеи оператор ++х увеличивает исходное значение на единицу, получатся 6, ну и 6 + 6 = 12 как я понимаю, но видимо я не правильно понимаю.
Кто нибуть может объяснить почему 14?
{
int x=5;
x=++x + ++x;
cout << x;
}
На С++ у меня получилось 14. Но в разных языках разное число получается.
По идеи оператор ++х увеличивает исходное значение на единицу, получатся 6, ну и 6 + 6 = 12 как я понимаю, но видимо я не правильно понимаю.
Кто нибуть может объяснить почему 14?
маленький кавайный линуксоид ^_^
-
- Сообщения: 135
- ОС: FreeBSD 8.0-RELEASE amd64
Re: префиксный инкремент
Схема выполнения примерно такая:
1. ++x, ++x (6, 7)
2. x = x + x (7 + 7 = 14)
А что собственно смущает? И какой смысл это проверять синтаксисом других языков?!
1. ++x, ++x (6, 7)
2. x = x + x (7 + 7 = 14)
А что собственно смущает? И какой смысл это проверять синтаксисом других языков?!
-
- Сообщения: 126
- ОС: archlinux
Re: префиксный инкремент
Нет ни чего не смущает. Просто недавно начал изучать С++ и не совсем понял как в данном примере проходит вычисление. Я лично не проверял, в гугле нашел, что в разных языках разный результат =)
маленький кавайный линуксоид ^_^
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: префиксный инкремент
на усмотрение компилятора.
по стандарту, насколько я знаю, результат не определён. Это старый трюк... Кстати, в C вовсе не обязательно 14, зависит от компилятора и от CPU.
да, a+b+c тоже вычисляется на усмотрение компилятора, может (a+b)+c, а возможно a+(b+c)
-
- Сообщения: 2268
- Статус: Линукссаксовец
- ОС: MS Windows XP Home SP3
Re: префиксный инкремент
а что от перемены мест слагаемых сумма меняется?
А у операции префиксный инкремент приоритет больше чем у просто сложения.
Про порядок вычисления операций в C++ (и C) можно почитать например тут: http://www.intuit.ru/department/pl/cpp/3/3.html
Внимание: У меня под рукой нет машины с Linux. Я не использую эту ОС. Ответы я даю либо по памяти, либо мне помогает гугл. Тщательно читайте маны по тем командам и конфигурационным файлам, которые я упоминаю.
0xDEFEC8ED
0xDEFEC8ED
-
- Администратор
- Сообщения: 5413
- ОС: Gentoo
Re: префиксный инкремент
Возможные последовательности (в обратной польской нотации):
1) x->, ++, x<-, x->, ++, x<-, x->, x->, +, x<- (14)
2) x->, ++, x<-, x->, x->, ++, x<-, x->, +, x<- (13)
и даже
3) x->, x->, ++, x<-, ++, x<-, x->, x->, +, x<- (12)
И вообще. Эти 2 ++'а не разделены точкой следования. Значит, компилятор имеет право выполнить их даже параллельно, в разных потоках! (я таких не видел, но стандарт допускает). А что бывает когда пытаются параллельно выполнить 2 ++'а, я думаю, все тут знают.
1) x->, ++, x<-, x->, ++, x<-, x->, x->, +, x<- (14)
2) x->, ++, x<-, x->, x->, ++, x<-, x->, +, x<- (13)
и даже
3) x->, x->, ++, x<-, ++, x<-, x->, x->, +, x<- (12)
И вообще. Эти 2 ++'а не разделены точкой следования. Значит, компилятор имеет право выполнить их даже параллельно, в разных потоках! (я таких не видел, но стандарт допускает). А что бывает когда пытаются параллельно выполнить 2 ++'а, я думаю, все тут знают.
-
- Сообщения: 108
- ОС: Arch GNU/Linux
Re: префиксный инкремент
аналогичное обсуждение было тут: http://wasm.ru/forum/viewtopic.php?id=20504
THE TRUTH IS OUT THERE
Linux Registered User #450136
Linux Registered User #450136
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: префиксный инкремент
а что такое operator+() ?
я этого не написал. может он выполняет перефиксное умножение?

-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: префиксный инкремент
/dev/random писал(а): ↑09.04.2009 00:04Значит, компилятор имеет право выполнить их даже параллельно, в разных потоках! (я таких не видел, но стандарт допускает). А что бывает когда пытаются параллельно выполнить 2 ++'а, я думаю, все тут знают.
думаю, что всё будет хорошо:
Код: Выделить всё
x1 = 5 | x2 = 5
++x1 | ++x2
x1+x2
ответ: 12
если конечно у нас есть 2 процессора, и у каждого есть своя память для хранения х1 и х2
-
- Сообщения: 2268
- Статус: Линукссаксовец
- ОС: MS Windows XP Home SP3
Re: префиксный инкремент
Мы говорим про конкретный язык программирования. Там нет такого операции. Там есть () которые меняют порядок выполнения операций и есть операция +
Если Вы изобретите свой язык программирования, можете придумывать там любые операции.
ответ: 12
если конечно у нас есть 2 процессора, и у каждого есть своя память для хранения х1
Вот только загвоздка в том, что ответ должен был быть 14
Внимание: У меня под рукой нет машины с Linux. Я не использую эту ОС. Ответы я даю либо по памяти, либо мне помогает гугл. Тщательно читайте маны по тем командам и конфигурационным файлам, которые я упоминаю.
0xDEFEC8ED
0xDEFEC8ED
-
- Администратор
- Сообщения: 5413
- ОС: Gentoo
-
- Сообщения: 585
- Статус: Программист С++
- ОС: Debian GNU/Linux
Re: префиксный инкремент
(trinimak) писал(а):К примеру:
...
x=++x + ++x;
...
Кто нибуть может объяснить почему 14?
Если вам интересен чисто академический аспект вычисления подобного выражения, тогда ясно. Однако в практическом (реальном) программировании таких выражений нужно просто избегать (всегда). Вот и вся мудрость.

-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: префиксный инкремент
вы не правы. речь про С++, а там только такая и есть. И скобки порядок тоже не определяют... Вот запятая - определяет.
Код: Выделить всё
int main()
{
int x = 5;
int y;
++x, ++x, y = x+x;
printf("%d\n", y);
return 0;
}
вот тут порядок определён, и ответ 14. А в выше приведённых примерах может получится всё что угодно(хоть 100).
откуда такая уверенность??
ЗЫЖ в С++ есть жёсткие правила, но они вовсе не интуитивно понятны:
что такое a+(b+c) можно понять только зная что такое a,b,c и как в них определён метод operator+(), да и после этого не известно, в каком именно порядке будет всё это выполнятся. инкремент - это та-же самая история с побочными эффектами: ++ не только увеличивает на 1, но ещё и возвращает значение. Как увеличивает и какое значение возвращает - ясно, вот только непонятно, в каком порядке это происходит.
-
- Сообщения: 2268
- Статус: Линукссаксовец
- ОС: MS Windows XP Home SP3
Re: префиксный инкремент
drBatty писал(а): ↑09.04.2009 14:42Код: Выделить всё
int main() { int x = 5; int y; ++x, ++x, y = x+x; printf("%d\n", y); return 0; }
вот тут порядок определён, и ответ 14. А в выше приведённых примерах может получится всё что угодно(хоть 100).
откуда такая уверенность??
Как я говорил ранее в Си определен порядок выполнения операций.
У операции "префиксное увеличение на единицу" приоритет выше чем у "+"
А так же "Если же операции одного и того же приоритета, они выполняются слева направо. "
исходя из этих правил, в выражении
++x + ++x
порядок вычисления будет: ++, ++, +
(1)_(3)_(2)
++x + ++x
Но если стандарт говорит, что ситуация неопределённая, значит так оно и есть

если конечно у нас есть 2 процессора, и у каждого есть своя память для хранения х1 и х2
А если память общая?
То помимо нарушенной вами информационной зависимости, будет еще и конкурунционная зависимость и в этом случае результат параллельного счета вообще непредсказуем и может быть разным при запусках одной и той же программы с одними и теме же начальными данными.
Внимание: У меня под рукой нет машины с Linux. Я не использую эту ОС. Ответы я даю либо по памяти, либо мне помогает гугл. Тщательно читайте маны по тем командам и конфигурационным файлам, которые я упоминаю.
0xDEFEC8ED
0xDEFEC8ED
-
- Сообщения: 2268
- Статус: Линукссаксовец
- ОС: MS Windows XP Home SP3
Re: префиксный инкремент
++x сначала увеличивает, потом возвращает
x++ сначала возвращает, потом увеличивает
выражение
x=5
y= ++x + x++
по логике должно вернуть y=12 и x=7
Внимание: У меня под рукой нет машины с Linux. Я не использую эту ОС. Ответы я даю либо по памяти, либо мне помогает гугл. Тщательно читайте маны по тем командам и конфигурационным файлам, которые я упоминаю.
0xDEFEC8ED
0xDEFEC8ED
-
- Администратор
- Сообщения: 5413
- ОС: Gentoo
Re: префиксный инкремент
nesk писал(а): ↑09.04.2009 14:57Как я говорил ранее в Си определен порядок выполнения операций.
У операции "префиксное увеличение на единицу" приоритет выше чем у "+"
А так же "Если же операции одного и того же приоритета, они выполняются слева направо. "
исходя из этих правил, в выражении
++x + ++x
порядок вычисления будет: ++, ++, +
Угу. Вот только этот порядок не определяет, что нужно суммировать.
Возможны такие ситуации:
1) Увеличить х на 1 (6), увеличить х на 1 (7), сложить х и х (14)
2) Увеличить х на 1 (6) и вернуть значение икса для последующего сложения, увеличить х на 1 (7) и вернуть значение икса для последующего сложения, сложить возвращённые значения (13)
и многие другие. Порядок вычисления операций не нарушается ни в одном из этих случаев.
Кроме того, определён лишь порядок вычисления _операций_, а не _операндов_. Порядок вычисления операндов определён лишь для операций "," и ":?". И слагаемые, как я уже говорил, могут вычисляться хоть параллельно. Тем, кто не понял или до сих пор считает иначе, гуглить на тему "точки следования".
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: префиксный инкремент
вовсе нет. компилятор только обязан обеспечить то, что результат ++ попадёт в сложение, но в каком порядке он будет это всё делать - не оговаривается. Конечно людям проще сначала посчитать части выражение, а потом считать целиком, однако для компьютеров это не так... Кроме того, компилятору допускается переставлять скобки, или вообще их убирать, да и порядок операций тоже на усмотрение компилятора. Например:nesk писал(а): ↑09.04.2009 14:57Как я говорил ранее в Си определен порядок выполнения операций.
У операции "префиксное увеличение на единицу" приоритет выше чем у "+"
А так же "Если же операции одного и того же приоритета, они выполняются слева направо. "
исходя из этих правил, в выражении
++x + ++x
порядок вычисления будет: ++, ++, +
a+(b+c)
компилятор может создать для такого выражения код, который вычисляет + в любом порядке. и скобки тут не помогут. Обычно такие выражения считаются с конца на х86, т.е. с последнего оператора, но это только моё наблюдение... В реальном коде необходимо обеспечить, то, что результат будет одинаковый при любом порядке расчётов.
конечноnesk писал(а): ↑09.04.2009 14:57А если память общая?
То помимо нарушенной вами информационной зависимости, будет еще и конкурунционная зависимость и в этом случае результат параллельного счета вообще непредсказуем и может быть разным при запусках одной и той же программы с одними и теме же начальными данными.

потому за такой код надо руки отрывать с корнем

UPD: проверил - мой c++ всё-таки скобки воспринимает, и порядок учитывает...
-
- Администратор
- Сообщения: 5413
- ОС: Gentoo
-
- Сообщения: 2268
- Статус: Линукссаксовец
- ОС: MS Windows XP Home SP3
Re: префиксный инкремент
да уж. грустная картина получается
x=5
y=++x + ++x + ++x + ++x
в итоге у=31

7+7+8+9
дальше интересней
x=5
y=++x + ++x + x++
y= 8 + 8 + 5 = 21
x=5
y=++x + x++ + ++x
получается y=19 x=8 вообще не понятно как.
x=5
y=++x + ++x + ++x + ++x
в итоге у=31

7+7+8+9
дальше интересней
x=5
y=++x + ++x + x++
y= 8 + 8 + 5 = 21
x=5
y=++x + x++ + ++x
получается y=19 x=8 вообще не понятно как.
Внимание: У меня под рукой нет машины с Linux. Я не использую эту ОС. Ответы я даю либо по памяти, либо мне помогает гугл. Тщательно читайте маны по тем командам и конфигурационным файлам, которые я упоминаю.
0xDEFEC8ED
0xDEFEC8ED
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: префиксный инкремент
вы к турниру на непонятное программирование готовитесь?

PS:
x++ + ++x смотрится красивее

-
- Сообщения: 2268
- Статус: Линукссаксовец
- ОС: MS Windows XP Home SP3
Re: префиксный инкремент
Это красиво, но просто
x=5
y=x++ + ++x
y=12
хотя уже понятно, что не везде и не всегда
Внимание: У меня под рукой нет машины с Linux. Я не использую эту ОС. Ответы я даю либо по памяти, либо мне помогает гугл. Тщательно читайте маны по тем командам и конфигурационным файлам, которые я упоминаю.
0xDEFEC8ED
0xDEFEC8ED
-
- Сообщения: 296
- ОС: fedora, mandriva
Re: префиксный инкремент
Код: Выделить всё
int x = 5;
x = ++x + ++x;
cout << x;
будет 14, так как порядок не определён только для вычислений ++x (какое будет вычислено первым, а какое - вторым)
+ не сможет сложить свои выражения, если они не будут вычислены

-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: префиксный инкремент
Начинаем сначала:
operator+(type &) не является точкой следования.
точки следования:
Код: Выделить всё
x++, x++;
x++ ? x++ : x++;
x++ || x++;
x++ && x++;
x++; x++;
вроде-бы ничего не забыл. в остальных случаях порядок вычисления не определён. по стандарту.
в том числе и
Код: Выделить всё
f(x++, x++);
и в результате работы исходного кода может получится 12,13, и 14... или вообще неизвестно что.
-
- Сообщения: 296
- ОС: fedora, mandriva
Re: префиксный инкремент
да, порядок-то не определён, но что это меняет ?
там только для сложения результатов порядок не определён и очерёдности их предварительного вычисления
операция там ++x, если бы была x++, тогда конечно - у меня 12
там только для сложения результатов порядок не определён и очерёдности их предварительного вычисления
операция там ++x, если бы была x++, тогда конечно - у меня 12
-
- Сообщения: 2268
- Статус: Линукссаксовец
- ОС: MS Windows XP Home SP3
Re: префиксный инкремент
а сколько будет
x=5
y= ++x + ++x + ++x + ++x + ++x
?
И почему?
Внимание: У меня под рукой нет машины с Linux. Я не использую эту ОС. Ответы я даю либо по памяти, либо мне помогает гугл. Тщательно читайте маны по тем командам и конфигурационным файлам, которые я упоминаю.
0xDEFEC8ED
0xDEFEC8ED
-
- Сообщения: 427
- Статус: Zz
- ОС: Calculate
Re: префиксный инкремент
От 30 до 50. От компилятора зависит.
-
- Сообщения: 2268
- Статус: Линукссаксовец
- ОС: MS Windows XP Home SP3
Re: префиксный инкремент
Угу. именно так

Но вопрос предназначался Folderx'у
Внимание: У меня под рукой нет машины с Linux. Я не использую эту ОС. Ответы я даю либо по памяти, либо мне помогает гугл. Тщательно читайте маны по тем командам и конфигурационным файлам, которые я упоминаю.
0xDEFEC8ED
0xDEFEC8ED
-
- Сообщения: 296
- ОС: fedora, mandriva
Re: префиксный инкремент
выполняется операция сложения после того, как вычислены оба её операнда
6, 7
7+7 = 14
8
14+8 = 22
и так далее
в итоге у меня получилось 41, а откуда от 30 до 50 ?
как может получиться 30 ?
6, 7
7+7 = 14
8
14+8 = 22
и так далее
в итоге у меня получилось 41, а откуда от 30 до 50 ?
как может получиться 30 ?
-
- Сообщения: 2268
- Статус: Линукссаксовец
- ОС: MS Windows XP Home SP3
Re: префиксный инкремент
Ну да, это в конкретном компиляторе, но стандартом не определено.
А вот объясните каким образом вот тут
x=5
y=++x + x++ + ++x
Получилось
y=19 x=8
( я конечно понимаю как, но блин это нелогично, неправильно, и непредсказуемо
Внимание: У меня под рукой нет машины с Linux. Я не использую эту ОС. Ответы я даю либо по памяти, либо мне помогает гугл. Тщательно читайте маны по тем командам и конфигурационным файлам, которые я упоминаю.
0xDEFEC8ED
0xDEFEC8ED
Спасибо сказали:
-
- Сообщения: 120
- ОС: LFS, slackware