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

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

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.78
The_Immortal
1550 / 486 / 8
Регистрация: 04.04.2009
Сообщений: 1,891
#1

Постфиксные и префиксные *менты - C++

01.06.2012, 09:45. Просмотров 1079. Ответов 14
Метки нет (Все метки)

Только вчера узнал о существовании префиксного варианта декремента и инкремента:
C++
1
2
++example;
--example;
И что-то это меня еще больше запутало.

Вот 2 примера:

Первый:
C++
1
2
3
4
5
6
7
8
9
int main() {
int loopcount = 1;
 
while (--loopcount > 0)
      {
       cout<<loopcount;          
      }
system  ("pause");                   
}
- тут мы в цикл не попадаем: уменьшили на единицу, вернули значение, сравнили - не прошло. Все понятно.

Второй:

C++
1
2
3
4
5
6
7
8
9
int main() {
int loopcount = 1;
 
while (loopcount-- > 0)
      {
       cout<<loopcount;          
      }
system  ("pause");                   
}
- здесь почему-то мы в цикл попадаем и в цикле выводится значение 0.
Вопрос: в какой момент происходит -1? Сразу после условия? В нулевой строчке тела цикла или где вообще?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.06.2012, 09:45     Постфиксные и префиксные *менты
Посмотрите здесь:

Префиксные/Постфиксные выражения - C++
Вводится одно из таких выражений. Как мне проверить каким именно это выражение является и как нормально считать знаки и числа для...

Непонятный вывод: постфиксные и префиксные инкремент/декремент - C++
Под спойлером весь который можно просто скопипастить и запустить в онлайн компиляторе http://www.compileonline.com/compile_cpp11_online.php...

Префиксные и постфиксные операции инкремента и декремента + наследование - C++
Дано: Два класса(Counter и CountDn), следует при помощи наследования добавить функцию постфиксных операций. На то, что я набросал выдает...

Постфиксные и префексные операции при перегрузке - C++
Здравствуйте. Написал перегрузку. #include&lt;iostream&gt; using namespace std; class A { private: int a; public: ...

Префиксные и постфиксные ++/-- в чем разница? - C (СИ)
В чем разница в языке С ++count/count++ ? И можете, пожалуйста написать простой пример где видна эта разница

Дана квадратная матрица А порядка n. Получить матрицу АВ; эле- менты матрицы В вычисляются по формуле - Turbo Pascal
остались последние задачи :wall: Помогите хотябы в одной! Дана квадратная матрица А порядка n. Получить матрицу АВ; эле- менты...

Найти массив минимальных элементов в каждой строке, а затем в новом массиве отсортировать эле-менты по возрастанию - Turbo Pascal
Всем привет. Очень давно не работал с Pascal'ем и ни как не могу понять, что надо сделать, думаю у вас это получится лучше .... ...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
01.06.2012, 09:49     Постфиксные и префиксные *менты #2
При постфиксе сначала проверка значения операнда, а потом исполнение самого оператора, при префиксе наоборот.
Lordif
21 / 21 / 1
Регистрация: 18.04.2010
Сообщений: 87
01.06.2012, 10:09     Постфиксные и префиксные *менты #3
При префиксном
C++
1
b = ++a;
происходит сначала
C++
1
a + 1
и только потом значение a + 1 приравнивается к b
А у постфиксного
C++
1
b = a++;
Сначала к b приравнивается значение a, и только потом происходит увеличение a на 1
The_Immortal
1550 / 486 / 8
Регистрация: 04.04.2009
Сообщений: 1,891
01.06.2012, 11:16  [ТС]     Постфиксные и префиксные *менты #4
taras atavin,
Lordif,
спасибо большое (сорри, опять плюсики закончились почему-то )

Хотел вот еще что спросить. Использование подобных "сокращенных" вариантов действительно ли оптимизирует код, делает работу проги быстрее или без разницы?

Я просто где-то прочел, что это приветствуется в виду того, что время выполнения программы действительно становится меньше благодаря использованию таких штук.
А в другой литературе прочитал, что это полный бред, что современные оптимизирующие компиляторы используют минимально необходимое кол-во инструкции машинного языка, независимо от применяемых для декремента/инкремента операторов.
Lordif
21 / 21 / 1
Регистрация: 18.04.2010
Сообщений: 87
01.06.2012, 11:35     Постфиксные и префиксные *менты #5
Даже если это и не оптимизирует программу, так (на мой взгляд) облегчает чтение кода.
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
01.06.2012, 11:41     Постфиксные и префиксные *менты #6
a+=b - не сокращённый вариант, а прямой.
C++
1
a+=
не сложение + присваивание, а увеличение, так как операция add помещает результат тоже в один из своих операндов. В результате
C++
1
a=a+b;
делается так:
1. создать вспомогательную переменную c.
2. скопировать a в c.
3. выполнить c+=b.
4. скопировать c в a.
5. уничтожить с.
Это эквивалентно
C++
1
a+=b;
, но треубет лишних операций по сохранению ещё одного регистра в стек и восстановлению из стека, а по сравнению с самим текстом
C++
1
2
3
4
{int c;
c=a;
c+=b;
a=c;}
именно a=a+b - сокращённая запись. Но ничего общего с оптимизацией это не имеет, так как компиляторы в состоянии самостоятельно заменить
C++
1
a=a+b
на
C++
1
a+=b;
А с другой стороны если внутреннее представление типа достаточно сложно, например, если это комплексное число в тригонометрической форме, то внутри оператора увеличения заводится локальная переменная, которую так уже не соптимизиурешь. Тогда всё наоборот и += реализуется с помощью + и =.

Добавлено через 2 минуты
Цитата Сообщение от Lordif Посмотреть сообщение
b = ++a;
а это действительно только сокращение, заменяется на
C++
1
2
3
4
{
 ++a;
 b=a;
}
.

Добавлено через 1 минуту
C++
1
b=a++;
на
C++
1
2
3
4
{
 b=a;
 a++;
}
Добавлено через 2 минуты
+= для встроенных типов составным оператором сложения и присваивания только называется, так как с точки зрения человека из неделимых состоит действительно из двух, не считая адресации. Но на низком уровне это часто не так. Ну и для некоторых пользовательских типов это может соответствовать особенностям внутренней реализации.
Evg
Эксперт CАвтор FAQ
17462 / 5700 / 361
Регистрация: 30.03.2009
Сообщений: 15,639
Записей в блоге: 26
01.06.2012, 23:43     Постфиксные и префиксные *менты #7
Цитата Сообщение от The_Immortal Посмотреть сообщение
Использование подобных "сокращенных" вариантов действительно ли оптимизирует код, делает работу проги быстрее или без разницы?
По скорости разницы нет. Но иногда укорачивает исходный код программы и делает её более удобочитаемой и понятной

Цитата Сообщение от The_Immortal Посмотреть сообщение
Я просто где-то прочел, что это приветствуется в виду того, что время выполнения программы действительно становится меньше благодаря использованию таких штук
Лет 20-30 назад это действительно было так из-за того, что памяти на машинах было очень мало, а потому компиляторы были не достаточно эффективными. На современных машинах памяти выше крыши, процессоры быстрые, а потому современные компиляторы генерируют эффективный код хоть так, хоть эдак

Цитата Сообщение от The_Immortal Посмотреть сообщение
А в другой литературе прочитал, что это полный бред, что современные оптимизирующие компиляторы используют минимально необходимое кол-во инструкции машинного языка, независимо от применяемых для декремента/инкремента операторов
В части компиляторов они правы. В части того, что это бред - не совсем. Потому что если такое пишут в книге 30-летней давности, то это была правда (на момент написания книги)

Добавлено через 33 минуты

=====================================

taras atavin, "a += b" и "a = a + b" в общем виде НЕ являются эквивалентами

Следующие два кода отработают НЕ эквивалентно (и именно поэтому появилась операция +=)

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
 
int G;
 
int* get_ptr (void)
{
  printf ("aaa\n");
  return &G;
}
 
int main (void)
{
  *(get_ptr()) += 1;
  return 0;
}
и

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
 
int G;
 
int* get_ptr (void)
{
  printf ("aaa\n");
  return &G;
}
 
int main (void)
{
  *(get_ptr()) = *(get_ptr()) + 1;
  return 0;
}
Avazart
7100 / 5277 / 267
Регистрация: 10.12.2010
Сообщений: 23,267
Записей в блоге: 17
06.06.2012, 17:11     Постфиксные и префиксные *менты #8
Операция ++i выполняется быстрее чем i++ так как часто последняя реализуется через первую (и если не учитывать оптимизацию)
Примером тому STL.
Evg
Эксперт CАвтор FAQ
17462 / 5700 / 361
Регистрация: 30.03.2009
Сообщений: 15,639
Записей в блоге: 26
06.06.2012, 17:29     Постфиксные и префиксные *менты #9
Цитата Сообщение от Avazart Посмотреть сообщение
Примером тому STL
То, что есть в STL, называется "перегруженный оператор", а не "операция". И к данному вопросу отношения не имеет
Avazart
7100 / 5277 / 267
Регистрация: 10.12.2010
Сообщений: 23,267
Записей в блоге: 17
06.06.2012, 17:33     Постфиксные и префиксные *менты #10
А разве оператор не выполняет оперции?
Toshkarik
1139 / 856 / 51
Регистрация: 03.08.2011
Сообщений: 2,384
Завершенные тесты: 1
06.06.2012, 17:38     Постфиксные и префиксные *менты #11
Выполняет, и может выполнять не одну операцию, но сам он операцией не является. Операторы это всего лишь функции. По этой причине Вы не можете перегрузить операторы для встроенных типов.
Avazart
7100 / 5277 / 267
Регистрация: 10.12.2010
Сообщений: 23,267
Записей в блоге: 17
06.06.2012, 17:46     Постфиксные и префиксные *менты #12
Ну так я и не писал operator++ я писал i++.
Именно поэтому я сказал про STL по тому как не представляю ситуацию в которой нужно было бы создавать пользовательский класс и перегружать данные операторы что бы использовать для прохода по элементам
Evg
Эксперт CАвтор FAQ
17462 / 5700 / 361
Регистрация: 30.03.2009
Сообщений: 15,639
Записей в блоге: 26
06.06.2012, 17:56     Постфиксные и префиксные *менты #13
Цитата Сообщение от Avazart Посмотреть сообщение
я писал i++
Тогда докажи, что в коде

C
1
2
int i;
i++;
префиксный оператор ++ работает быстрее постфиксного. Ибо ты утверждал, что "Операция ++i выполняется быстрее чем i++"
Avazart
7100 / 5277 / 267
Регистрация: 10.12.2010
Сообщений: 23,267
Записей в блоге: 17
06.06.2012, 18:09     Постфиксные и префиксные *менты #14
Ну подразумевал другое... согласен неправильно выразился...
C++
1
for(some_iterator i=c.begin();i!=c.end();++i) ;
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.06.2012, 18:22     Постфиксные и префиксные *менты
Еще ссылки по теме:

Дан одномерный массив из 40 элементов. Сформировать второй массив, в котором сначала идут все четные эле-менты - Delphi
Дан одномерный массив из 40 элементов. Сформировать второй массив, в котором сначала идут все четные эле-менты первого массива, затем нули,...


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

Или воспользуйтесь поиском по форуму:
Toshkarik
1139 / 856 / 51
Регистрация: 03.08.2011
Сообщений: 2,384
Завершенные тесты: 1
06.06.2012, 18:22     Постфиксные и префиксные *менты #15
В данном случае ++i это перегруженный оператор для итератора.
Yandex
Объявления
06.06.2012, 18:22     Постфиксные и префиксные *менты
Ответ Создать тему
Опции темы

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