2011-01-08 6 views
3

Это может показаться глупым вопросом, но почему на многих языках существует префикс и постфиксная версия операторови --, но нет похожих версий префикса/постфикса других операторов, таких как += или -=? Например, кажется, что если я могу написать этот код:Почему существует префикс/postfix ++, но нет префикса/postfix + =?

myArray[x++] = 137; // Write 137 to array index at x, then increment x 

я должен быть в состоянии написать что-то вроде

myArray[5 =+ x] = 137; // Write 137 to array index at x, then add five to x 

Конечно, такой оператор не существует. Для этого есть причина? Это похоже на странную асимметрию в C/C++/Java.

+1

Итак, вы спрашиваете, почему это разрешено только для специального случая ± 1? –

+0

@Goran Jovic- Точно. – templatetypedef

+6

Лично я поддерживаю синтаксис 'myArray [x ++++++++++++] = 137;'. –

ответ

6

Я предполагаю, что есть несколько причин, я думаю, что среди наиболее сильно взвешенного может быть:

  • там, вероятно, не думал, слишком много случаев реального использования (это не может быть даже в голове некоторые разработчики языка в начале)
  • pre/post increment отображается непосредственно на машинные операции (по крайней мере на нескольких машинах), поэтому они нашли свой путь на языке (обновление: оказывается, что это не совсем так, даже если это принято считать в вычислительных знаниях. См. ниже).

В то же время, хотя идея для операторов pre/post/increment/decment может быть подвержена влиянию машинных операций, похоже, что они не были помещены на язык специально, чтобы воспользоваться преимуществами такого. Вот что Деннис Ритчи должен сказать о них:

http://cm.bell-labs.com/cm/cs/who/dmr/chist.html

Томпсон пошел еще дальше, придумав ++ и - операторы, которые позволяют увеличить или уменьшить; их префикс или постфиксная позиция определяют, происходит ли изменение до или после значения операнда. Они не были в самых ранних версиях B, но появились на этом пути. Люди часто догадываются, что они созданы для использования режимов автоинкремента и автоматического декремента, предоставляемых DEC PDP-11, на которых C и Unix стали популярными. Это исторически невозможно, поскольку не было PDP-11, когда был разработан Б. PDP-7, однако, имел несколько ячеек памяти с автоматическим увеличением, с тем свойством, что ссылка на косвенную память через них увеличивала ячейку. Вероятно, эта функция предположила таких операторов для Томпсона; обобщение, чтобы сделать их как префикс, так и постфикс, было его собственным. Действительно, ячейки с автоматическим инкрементом не использовались непосредственно в реализации операторов, и более сильной мотивацией для инноваций было, вероятно, его наблюдение, что перевод ++ x был меньше, чем у x = x + 1.

1

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

+0

Я использую postfix ++ (и реже -) только и только для циклов. –

+0

@Goran: Это отлично подходит для C, но не для C++ (где операции postfix на итераторах могут быть довольно дорогими). –

+0

«Некоторые утверждают, что даже ++/- следует избегать, потому что они вызывают путаницу и несут ответственность за большинство ошибок переполнения буфера».: Я не покупаю этот аргумент. Это не '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '+ =' не поможет вам избежать переполнения буфера, если вы не обратите внимание на длину буфера. –

0

Если бы я должен был догадаться, что это общая приравнять:

x += 5;

... с:

x = x + 5;

И по понятным причинам, было бы бессмысленно писать:

x + 5 = x;

Я не уверен, как иначе вы могли бы подражать поведению 5 =+ x, используя только оператор +. Кстати, привет htiek!

+1

Ясно, что это возможно. В случае 'x + 5 = x' можно показать, что' 5 = 0' с вычитанием 'x' с обеих сторон. QED. ;-) –

4

Пока y не имеет побочных эффектов:

#define POSTADD(x,y) (((x)+=(y))-(y)) 
+6

Или с некоторой безопасностью побочных эффектов в C++: 'template T postadd (T & x, U increment) {T tmp = x; x = x + приращение; return tmp; } 'Но я настоятельно рекомендую избегать использования чего-то подобного (если есть веская причина для его использования, я бы хотел услышать оправдание - это может быть интересно). –

2

Я сделаю предположение. Существует множество прецедентов для ++i/i++, и во многих конкретных случаях прирост (pre/post) делает разницу. Я не могу сказать, сколько раз я видел код вроде while (buf[i++]) {...}. С другой стороны, += используется гораздо реже, так как редко имеет смысл сдвинуть указатель на 5 элементов одновременно.

Итак, просто не существует достаточно распространенного приложения, где важна разница между постфиксной и префиксной версией +=.

1

Поскольку - и ++ операторы Карта inc (rement) и dec (rement) инструкции (в дополнение к Сложение и вычитание) в CPU, и эти операторы предполагается отобразить инструкции, следовательно, почему они существуют как отдельные операторы.

+1

Но это справедливо только для одной архитектуры процессора, не так ли? Например, я не помню этого в MIPS. – templatetypedef

+0

Да, это правда для некоторых, я знаю, что я x86. – Mehrdad

+0

@templatetypedef: PDP-11 немного старше, чем MIPS, а C изначально был написан для работы с PDP-11. У всех остальных есть операторы pre- и post-increment и decment, потому что C имеет их. –

1

Java и C++ имеют операторы pre и post-increment и decment, потому что C имеет их. C имеет их, потому что C был написан, в основном, для PDP-11, а PDP-11 имеет инструкции INC и DEC.

В тот же день оптимизаторы компиляторов не существовали, поэтому, если вы хотели использовать оператор инкремента с одним циклом, либо вы написали ему ассемблер, либо ваш язык нуждался в явном операторе для него; C, являющийся переносным языком сборки, имеет явные операторы приращения и уменьшения. Кроме того, разница между ++i и i++ редко имеет значение сейчас, но это имело значение в 1972 году.

Имейте в виду, что C почти 40 лет.

+0

Однако поразительное количество вопросов SO/web по-прежнему, по-видимому, связано с «эффективностью» 'i ++' vs '++ i' vs' i = i + 1' ...: - / –