Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 25, средняя оценка - 4.96
Feuer
75 / 75 / 6
Регистрация: 13.10.2008
Сообщений: 144
#1

Помогите чайнику с инкрементом... - C++

13.10.2008, 22:28. Просмотров 3098. Ответов 12
Метки нет (Все метки)

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

Код
int i=0;
cout<<"i = "<<i<<", (i++)= "<<i++<<endl;
cout<<"i = "<<i;
Как мне казалось, поскольку инкремент постфиксный, то i должно увеличится только ко второй строке, однако результат выполнения таков:
i = 1, (i++)= 0
i = 1
Наверное я чего-то не знаю.... объясните, пожалуйста...
http://www.cyberforum.ru/cpp-beginners/thread324357.html
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.10.2008, 22:28
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Помогите чайнику с инкрементом... (C++):

Скобки не работают с постфиксным инкрементом
Почему скобки не работают с постфиксным инкрементом ? Программа должна вывести...

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

Окажите услугу чайнику)
Блин, я новичок в С++ - никак не могу разобраться с 2 заданиями( Помогите...

Объясните чайнику в чем ошибка
#include &lt;iostream&gt; using namespace std; int main() { setlocale(LC_CTYPE,...

Связный список- Объясните чайнику
Всем привет! В универе проходим односвязные списки. Схему-пример принципа...

12
Skaffi
1 / 1 / 1
Регистрация: 13.10.2008
Сообщений: 10
14.10.2008, 00:10 #2
привет)

все просто) если ты напишешь вот так:
C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
using namespace std;
 
int main()
{
int i=0;
cout<<"i = "<<i;
cout<<"(i++)= "<<i++<<endl;
cout<<"i = "<<i<<endl;
}
то будет работать, как ты и предполагаешь:

сначала i=0;
потом значение (i++)=0; а i увеличивается на 1, т.е. i=1

Добавлено через 1 минуту 56 секунд
НАВЕРНО, перед тем, как выполнить cout твоего кода, сначала вычисляется i++, следовательно и значение i меняется...
1
Alirp
57 / 52 / 3
Регистрация: 04.05.2008
Сообщений: 272
14.10.2008, 08:15 #3
Приоритер операции ++ больше чем у операции <<, а так как они в одной строке, поэтому инкремент и выполняется раньше. Посмотри приоритеты операций и порядок их выполнения.
http://www.cyberguru.ru/programming/...de-page35.html
0
igor_nf
118 / 12 / 3
Регистрация: 21.08.2007
Сообщений: 222
14.10.2008, 16:34 #4
Цитата Сообщение от Alirp Посмотреть сообщение
Приоритер операции ++ больше чем у операции <<, а так как они в одной строке, поэтому инкремент и выполняется раньше. Посмотри приоритеты операций и порядок их выполнения.
http://www.cyberguru.ru/programming/...de-page35.html
Боюсь ты ошибаешься. Я сходил по представленной ссылке и не обнаружил там приоритета оператора <<, что впрочем и не удивительно (здесь, я надеюсь, ты различаешь операцию двоичного сдвига и оператор потокового вывода).
0
Ranofer
3 / 3 / 0
Регистрация: 04.09.2008
Сообщений: 20
14.10.2008, 16:47 #5
"При перегрузке операций сохраняются количество аргументов, приоритеты операций и правила ассоциаций, используемые в стандартных типах данных" - учебник Павловской Т.А.
А операция потокового вывода, это помоему перегруженная операция сдвига..
Но..
Программа
C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <windows.h>
using namespace std;
int main(){
    int i=0;
    cout << "i = " << i << ", (i++)= " << i++ << endl;
    cout << "i = " << i << endl;
    system("pause");
    return 0;
}
выдает
i = 0, (i++)= 0
i = 1
0
Vourhey
Почетный модератор
6490 / 2264 / 187
Регистрация: 29.07.2006
Сообщений: 12,534
14.10.2008, 17:16 #6
Пергрузка операций тут не при чем. Приоритет тоже. Ты читаешь строку слева направо. Никто же не обещал, что операторы потоков буду делать также. Поясняю:
Код
. начинаем выполнение cout
00411A05  mov         eax,dword ptr [i]   грузим текущее значение i в EAX. теперь там 0.
00411A08  mov         dword ptr [ebp-0D0h],eax    .запомнил адрес? 
00411A0E  mov         ecx,dword ptr [i]     . следующие три операции - это инкремент
00411A11  add         ecx,1 
00411A14  mov         dword ptr [i],ecx     . теперь i равно единице
00411A17  mov         esi,esp 
00411A19  mov         edx,dword ptr [__imp_std::endl (41A344h)] 
00411A1F  push        edx      .помещаем символ перехода на новую строку.
00411A20  mov         edi,esp 
00411A22  mov         eax,dword ptr [ebp-0D0h]     .помнишь еще? здесь 0
00411A28  push        eax        .грузим теперь 0
00411A29  push        offset string ", (i++)= " (417868h)     .наша строка, где 0
. обрати внимание на этом шаге у нас уже есть
"(i++)= " 0 endl; 
00411A2E  mov         ebx,esp
00411A30  mov         ecx,dword ptr [i] 
00411A33  push        ecx      .а вот теперь уже грузим i. А он единица.
00411A34  push        offset string "i = " (417800h)     .строку..
00411A39  mov         edx,dword ptr [__imp_std::cout (41A348h)] 
00411A3F  push        edx       .поток cout
00411A40  call        std::operator<<<std::char_traits<char> > (411159h)   .собственно, вызов
Понятно теперь почему?

Добавлено через 5 минут 50 секунд
Если совсем у тебя плохо с ассемблером, то перевожу, как интерпретируется строка:
Код
cout<<"i = "<<i<<", (i++)= "<<i++<<endl;
Первым делом инкрементриую i, запоминаю его предыдущее значение. В конец помещаю переход на новую строку, за ним, я вывожу предыдущее значние i (0), потом в строку толкаю '(i++)= ', потом туда же толкаю уже текущее значение i, и затем строку 'i = '.
Вот и вся марихуана...

Добавлено через 5 минут 30 секунд
Цитата Сообщение от Ranofer Посмотреть сообщение
Но..
Программа
Код
#include <iostream>
#include <windows.h>
using namespace std;
int main(){
    int i=0;
    cout << "i = " << i << ", (i++)= " << i++ << endl;
    cout << "i = " << i << endl;
    system("pause");
    return 0;
}
Молодой человек, Вы гоните. Первая программа у вас аналогичная. Пробелы ничего не меняют.

Добавлено через 14 секунд
Смотри выше, я написал, почему.
0
Feuer
75 / 75 / 6
Регистрация: 13.10.2008
Сообщений: 144
14.10.2008, 22:22  [ТС] #7
Спасибо всем, кто откликнулся!
Отдельное спасибо Vourhey!!
0
Ranofer
3 / 3 / 0
Регистрация: 04.09.2008
Сообщений: 20
15.10.2008, 10:21 #8
Цитата Сообщение от Vourhey Посмотреть сообщение
Молодой человек, Вы гоните. Первая программа у вас аналогичная. Пробелы ничего не меняют.
За объяснение спасибо. =)
Не понял только в каком месте я гоню.
Во-первых, программа не моя я ее скопировал из первого поста и расставил пробелы для удобства. Скомпилировал, запустил и получил..
Код
i = 0, (i++)= 0
i = 1
Добавлено через 11 часов 25 минут 25 секунд
Так, что-то я совсем запутался.

Я видоизменил программу..
Код
#include <iostream>
using namespace std;
int main(){
    int i=0;
    cout << "i = " << i << ", (i++)= " << i++ << ", i = " << i << endl;
    cout << "i = " << i << ", (i++)= " << i++ << ", i = " << i << endl;
    system("pause");
    return 0;
}
и она выдает..
Код
i = 0, (i++)= 0, i = 1
i = 1, (i++)= 1, i = 2
Похоже компилятор забивает на приоритет операции инкремента и читает строку слева-направо. То есть выводит на экран:
1. "i = ",
2. текущее значение i, равное нулю,
3. ", (i++)= ",
4. посчитав и запомнив инкремент, выводит предыдущее значение i, равное нулю (если бы инкремент был префиксный, то тут была бы единица),
5. "i = "
6. текущее значение i, равное единице.

Вот.
0
Vourhey
Почетный модератор
6490 / 2264 / 187
Регистрация: 29.07.2006
Сообщений: 12,534
15.10.2008, 12:56 #9
Цитата Сообщение от Ranofer Посмотреть сообщение
Похоже компилятор забивает на приоритет операции инкремента и читает строку слева-направо. То есть выводит на экран:
1. "i = ",
2. текущее значение i, равное нулю,
3. ", (i++)= ",
4. посчитав и запомнив инкремент, выводит предыдущее значение i, равное нулю (если бы инкремент был префиксный, то тут была бы единица),
5. "i = "
6. текущее значение i, равное единице.

Вот.
Вот? Для твоей первой задачи я тебе объяснил почему. А сейчас у меня нет времени повторять уже пройденное. Продизассемблируй и узнаешь. Вот.

P. S. а еще многое зависит от реализации операторов потоковых для конкретного компилера и его либ. Вот.
0
Ranofer
3 / 3 / 0
Регистрация: 04.09.2008
Сообщений: 20
15.10.2008, 16:08 #10
Цитата Сообщение от Vourhey Посмотреть сообщение
а еще многое зависит от реализации операторов потоковых для конкретного компилера и его либ. Вот.
То есть для одной и той же программы:
Код
    int i=0;
    cout << "i = " << i << ", (i++)= " << i++ << endl;
    cout << "i = " << i << endl;
могут быть 2(или более) различных результата:
Код
i = 1, (i++)= 0
i = 1
Код
i = 0, (i++)= 0
i = 1
в зависимости от реализации потоковых операторов для конкретного компилера и его либ?
0
Vourhey
Почетный модератор
6490 / 2264 / 187
Регистрация: 29.07.2006
Сообщений: 12,534
15.10.2008, 17:28 #11
Судя по тому, что одинаковые программы. Эта:
Код
cout << "i = " << i << ", (i++)= " << i++ << endl;
дает тебе
i = 0, (i++)= 0

и тот же самый код:
Код
cout<<"i = "<<i<<", (i++)= "<<i++<<endl;
дает тебе
i = 1, (i++)= 0

то легко

Добавлено через 6 минут 1 секунду
Этот код
Код
#include <iostream>
#include <windows.h>
using namespace std;
int main(){
    int i=0;
    cout << "i = " << i << ", (i++)= " << i++ << endl;
    cout << "i = " << i << endl;
    system("pause");
    return 0;
}
дает одинаковый результат и в gcc, и в VS2008.

И такой же код:
Код
int i=0;
cout<<"i = "<<i<<", (i++)= "<<i++<<endl;
cout<<"i = "<<i;
дает тот же результат.

И это, блин, правильно. Потому что пробелы ничего не решают. И я не верю тебе, что эти одинаковые программы выводят различный результат.
0
Ranofer
3 / 3 / 0
Регистрация: 04.09.2008
Сообщений: 20
15.10.2008, 18:45 #12
Посмеялся

Только результат... "i = 1, (i++)= 0" получается не у меня, а у Feuer.
У меня же "i = 0, (i++)= 0".

Программа одна и та же (и не надо меня в пробелы тыкать ), скопирована у Feuer.

пс. Компилирую в dev-c++ (g++)
0
Vourhey
Почетный модератор
6490 / 2264 / 187
Регистрация: 29.07.2006
Сообщений: 12,534
15.10.2008, 21:25 #13
Ну да, я вас спутал.
ОК. Тем более, какие тогда вобще вопросы? Разная реализация, если по разному себя ведет. Проблемы не вижу в переписке операторов вывода/вывода потока.
Я объяснил Feuer, почему у него так работает. Не понимаю, что еще нужно? Продизассемблируй свой код и узнаешь, почему у тебя нули. И VS и g++ в моем случае дают результат Feuer.

P. S. когда человек не втыкает его тыкают...
0
15.10.2008, 21:25
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.10.2008, 21:25
Привет! Вот еще темы с решениями:

Нужна професиональная подсказка чайнику.
Добрый день всем уважаемые программисты. Я новый юзер в этом деле, изучать...

МАЭСТРО-ЧАЙНИКУ!!!!!!!!!!!Visual studio C++
Прошу помощи в решении некоторых моих задач: 1.Задан массив из к символов....

Поясните чайнику что тут не так
Всем доброго времени суток. Вот как уже месяц учусь на компьютерного инженера....

Объясните человеческим языком мне чайнику что такое singleton, статический класс. Зачем они нужны. Что рекомендуете прочитать мне для начала
Объясните человеческим языком мне чайнику что такое singleton, статический...


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

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

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