Форум программистов, компьютерный форум, киберфорум
Наши страницы

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 17, средняя оценка - 4.88
RNT
Автор FAQ
3138 / 358 / 3
Регистрация: 08.08.2009
Сообщений: 1,126
#1

Скобки не работают с постфиксным инкрементом - C++

19.09.2010, 12:40. Просмотров 2196. Ответов 20
Метки нет (Все метки)

Почему скобки не работают с постфиксным инкрементом ? Программа должна вывести 1, а выводит 0. Без скобок приоритет постфиксного инкремента был ниже операции присваивания, а со скобками должен стать выше. Но почему-то приоритет не меняется.

C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
using namespace std;
 
int main ( )
{
    int var1=0, var2=0;
    var2= (var1++);
    cout <<  var2  << endl;
    return 0;
}
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.09.2010, 12:40
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Скобки не работают с постфиксным инкрементом (C++):

Объяснить разницу между префиксным и постфиксным инкрементом на простых примерах - C++
Можете объяснить разницу между i++ и ++i на просто примере с цифрами?

Разобрать кодик с постфиксным оператором - C++
Вот проблемный код: do *seq++ = *cod++ != '0' ? sign : -sign; while (n--); Мои рассуждения: тк стоит постфиксный...

Помогите чайнику с инкрементом... - C++
Здравствуйте! Понимаю, конечно, что вопрос наверное дурацкий... но я только начал знакомство с С++, а этот вопрос не дает покоя... int...

функция с инкрементом объекта. ++ - C++
Доброго времени суток. Прошу помочь в реализации функций. static HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); static...

Для каждой открывающей скобки найти позицию ей соответствующей закрывающей скобки - C++
Доброго времени суток. Подскажите пожалуйста алгоритм или путь к решению задачи, используя СТЕК Дана ПСП, ваша задача для каждой...

Фигурные скобки: Мне пишут что ошибка в закрытие скобки после return. - C++
#include &lt;iostream&gt; using namespace std; int main(){ int *ptr_number = new int; int *sum = new int(0); cin &gt;&gt; *ptr_number; ...

20
Manjak
269 / 175 / 7
Регистрация: 12.03.2010
Сообщений: 494
19.09.2010, 12:52 #2
При чем тут вообще приоритет операций? постфиксный инкремент возвращает старое значение переменной
1
RNT
Автор FAQ
3138 / 358 / 3
Регистрация: 08.08.2009
Сообщений: 1,126
19.09.2010, 15:20  [ТС] #3
Цитата Сообщение от Manjak Посмотреть сообщение
При чем тут вообще приоритет операций? постфиксный инкремент возвращает старое значение переменной
Если так, то переменной var в нижеприведенном исходнике должен быть присвоен 0, но присвоена 1

C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
using namespace std;
 
int main ( )
{
    int var = 0;
    var = var++;
    cout <<  var  << endl; //Выводит 1
    return 0;
}
0
ForEveR
В астрале
Эксперт С++
7994 / 4753 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
19.09.2010, 16:27 #4
RNT, Эм... У тебя одна переменная.
var = var++;
Здесь еще var которому ты приравниваешь равен 0.
cout << var << endl; var=1;

Попробуй лучше уж так:

C++
1
2
3
4
5
6
7
8
9
#include <iostream>
 
int main()
{
    int i=0;
    int var=i++;
    std::cout<<var<<' '<<i<<'\n';
    return 0;
}
1
CheshireCat
Эксперт С++
2907 / 1256 / 81
Регистрация: 27.05.2008
Сообщений: 3,449
19.09.2010, 16:35 #5
Цитата Сообщение от RNT Посмотреть сообщение
Если так, то переменной var в нижеприведенном исходнике должен быть присвоен 0, но присвоена 1
C++
1
 var = var++;
A может оказаться хоть "Hello, World!" :-) UB, однако....
1
ForEveR
В астрале
Эксперт С++
7994 / 4753 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
19.09.2010, 16:35 #6
CheshireCat, Да не. Там же в начале:

int var = 0;
1
CheshireCat
Эксперт С++
2907 / 1256 / 81
Регистрация: 27.05.2008
Сообщений: 3,449
19.09.2010, 16:47 #7
Не. Именно UB в чистом виде, и именно в этой строке - более одной модификации одной и той же переменной (var) до достижения точки следования.
2
RNT
Автор FAQ
3138 / 358 / 3
Регистрация: 08.08.2009
Сообщений: 1,126
19.09.2010, 17:13  [ТС] #8
Нашел в Википедии

http://ru.wikipedia.org/wiki/%D0%A2%...BD%D0%B8%D1%8F
Точки следования необходимы в ситуации, когда одна и та же переменная изменяется в выражении более одного раза. Часто в качестве примера приводят выражение i=i++, в котором происходит присваивание переменной i и её же инкремент. Какое значение примет i? Стандарт языка должен либо указать одно из возможных поведений программы как единственно допустимое, либо указать диапазон допустимых поведений (см. неуточняемое поведение), либо указать, что поведение программы в данном случае совершенно не определено (см. неопределённое поведение). В языках C и C++ вычисление выражения i=i++ приводит к неопределённому поведению, поскольку это выражение не содержит внутри себя ни одной точки следования.
Видимо, мой код вообще некорректен.
0
Manjak
269 / 175 / 7
Регистрация: 12.03.2010
Сообщений: 494
19.09.2010, 17:36 #9
На самом деле понять почему неправильно работает тот код достаточно просто, но обьяснять зачем eax, ecx регистры смысла не вижу, просто не надо так делать.

Assembler
1
2
3
4
5
001017F5  mov         eax,dword ptr [var]  
001017F8  mov         dword ptr [var],eax  
001017FB  mov         ecx,dword ptr [var]  
001017FE  add         ecx,1  
00101801  mov         dword ptr [var],ecx
1
RNT
Автор FAQ
3138 / 358 / 3
Регистрация: 08.08.2009
Сообщений: 1,126
20.09.2010, 18:42  [ТС] #10
Цитата Сообщение от Manjak Посмотреть сообщение
При чем тут вообще приоритет операций? постфиксный инкремент возвращает старое значение переменной
А когда все-таки происходит увеличение переменной ? После того, как выполнится вся строка ?
0
Manjak
269 / 175 / 7
Регистрация: 12.03.2010
Сообщений: 494
20.09.2010, 19:30 #11
Для "var = var++" сразу выполняется оператор = а потом уже ++.
А посфиксный инкремент работает так
C++
1
2
3
4
5
{
    int retVal = val;
    ++val;
    return retVal;
}
1
Kastaneda
Jesus loves me
Эксперт С++
4756 / 2960 / 243
Регистрация: 12.12.2009
Сообщений: 7,517
Записей в блоге: 2
Завершенные тесты: 1
22.09.2010, 08:21 #12
Цитата Сообщение от RNT Посмотреть сообщение
А когда все-таки происходит увеличение переменной ? После того, как выполнится вся строка ?
Вот же:
Цитата Сообщение от Manjak Посмотреть сообщение
Assembler
1
2
3
4
5
001017F5  mov         eax,dword ptr [var]  
001017F8  mov         dword ptr [var],eax  
001017FB  mov         ecx,dword ptr [var]  
001017FE  add         ecx,1  
00101801  mov         dword ptr [var],ecx
Здесь видно, что сначала происходит присваивание, а потом инкремент.
0
Evg
Эксперт CАвтор FAQ
18919 / 6879 / 504
Регистрация: 30.03.2009
Сообщений: 19,372
Записей в блоге: 30
22.09.2010, 11:03 #13
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Manjak, вроде бы уже тут поясняли. То, что ты видишь в коде - это построение кода конкретно на твоём компиляторе. Другой компилятор может посторить другой код. Undefined Behaviour означает, что нельзя даже теоретически предложить "правильный" выход из сложившейся ситуации, а потому какждый компилятор в какждом UB случае ведёт себя так, как звёзды встали

Добавлено через 1 час 40 минут
Ну и, чисто для демонстрации того, что такое Undefined Behaviour. Запускал на sparc'е, поскольку только на нём имею возможность запустить на двух разных компиляторах

C
1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
 
int a = 0, b = 0;
 
int
main (void)
{
  a = b++ + b++;
  printf ("a=%d b=%d\n", a, b);
}
Компилятор gcc выдаёт "a=0 b=1"
Компилятор sun cc выдаёт "a=1 b=2"

Теперь немного перепишем исходник: переменные вместо глобальных сделаем локальными

C
1
2
3
4
5
6
7
8
9
#include <stdio.h>
 
int
main (void)
{
  int a = 0, b = 0;
  a = b++ + b++;
  printf ("a=%d b=%d\n", a, b);
}
Компилятор gcc выдаёт "a=0 b=2"
Компилятор sun cc выдаёт "a=0 b=2"

Итого получили как минимум три различных результата
4
Black Fregat
2396 / 1211 / 302
Регистрация: 31.05.2009
Сообщений: 4,804
22.09.2010, 11:21 #14
Вот тут на эту тему вполне толково разжевано: http://alenacpp.blogspot.com/2005/11/sequence-points.html
1
Kastaneda
Jesus loves me
Эксперт С++
4756 / 2960 / 243
Регистрация: 12.12.2009
Сообщений: 7,517
Записей в блоге: 2
Завершенные тесты: 1
22.09.2010, 11:23 #15
Evg, а можете объяснить, почему в данном случае поведение локальной переменной отличается от глобальной?
0
22.09.2010, 11:23
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.09.2010, 11:23
Привет! Вот еще темы с ответами:

Дана строка, содержащая латинские буквы и скобки. Если скобки расставлены правильно - вывести 0. Иначе - номер позиции, где есть ошибочная скобка - C++
Дана строка, содержащая латинские буквы и круглые скобки. Если скобки расставлены правильно (то есть каждой открывающей соответству-ет одна...

не работают скобки в коде при создании tshape - C++ Builder
вот код //--------------------------------------------------------------------------- void __fastcall TForm1::Shape1MouseDown(TObject...

Разница между префиксным и постфиксным написанием - Java SE
Здравствуйте. Пытался объяснить человеку про префиксное и постфиксное прибавление 1 (знаком ++). Вроде бы все понятно , если мы создаем...

Какие циклы относится префиксным и постфиксным циклам - C#
какие циклы относится префиксным и постфиксным циклам?


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru