stringtranslate.com

Операторы увеличения и уменьшения

Операторы увеличения и уменьшения — это унарные операторы , которые увеличивают или уменьшают свой операнд на единицу.

Они обычно встречаются в императивных языках программирования . C -подобные языки имеют две версии (до- и пост-) каждого оператора с несколько разной семантикой.

В языках, синтаксически производных от B (включая C и его различные производные), оператор приращения записывается как ++, а оператор декремента записывается как --. Некоторые другие языки используют функции inc(x) и dec(x).

Оператор инкремента увеличивает, а оператор декремента уменьшает значение своего операнда на 1. Операнд должен иметь арифметический тип данных или тип данных указателя и должен ссылаться на изменяемый объект данных . Значения указателей увеличиваются (или уменьшаются) на величину, которая заставляет их указывать на следующий (или предыдущий) элемент, соседний в памяти.

На языках, поддерживающих обе версии операторов:

В языках, где приращение/уменьшение не является выражением (например, Go ), необходима только одна версия (в случае Go — только операторы post).

Поскольку оператор увеличения/уменьшения изменяет свой операнд, использование такого операнда более одного раза в одном и том же выражении может привести к неопределенным результатам. Например, в таких выражениях, как x - ++x, неясно, в какой последовательности следует выполнять операции вычитания и приращения. Такие выражения обычно вызывают неопределенное поведение , и их следует избегать.

В языках с типизированными указателями, таких как C, оператор приращения перемещает указатель на следующий элемент этого типа, увеличивая значение указателя на размер этого типа. Когда указатель (правильного типа) указывает на любой элемент массива, приращение (или уменьшение) приводит к тому, что указатель указывает на «следующий» (или «предыдущий») элемент этого массива. Таким образом, увеличение указателя на целое число делает его указателем на следующее целое число (обычно значение указателя увеличивается на 4); [1] увеличение указателя на структуру размером 106 байт приводит к тому, что он указывает на следующую структуру путем увеличения значения указателя на 106. [2]

Примеры

Следующий фрагмент кода C иллюстрирует разницу между операторами увеличения и уменьшения до и после :

интервал х ; интервал y ;  // Операторы приращения // Предварительное приращение: x увеличивается на 1, затем y присваивается значение x x = 1 ; у = ++ х ; // x теперь равно 2, y тоже равно 2     // Постинкремент: y присваивается значение x, затем x увеличивается на 1 x = 1 ; у = х ++ ; // y равно 1, x теперь равно 2     // Операторы декремента // Предварительное декремент: x уменьшается на 1, затем y присваивается значение x x = 1 ; у = -- х ; // x теперь равен 0, y тоже равен 0     // Пост-декремент: y присваивается значение x, затем x уменьшается на 1 x = 1 ; у = х -- ; // y равен 1, x теперь равен 0     

В языках, где нет этих операторов, эквивалентные результаты требуют дополнительной строки кода:

# Предварительное приращение: y = ++x x  =  1 x  =  x  +  1  # x теперь равно 2 (можно записать как "x += 1" в Python) y  =  x  # y также равно 2# Постинкремент: y = x++ x  =  1 y  =  x  # y равно 1 x  =  x  +  1  # x теперь равно 2


Оператор пост-инкремента обычно используется с индексами массива . Например:

// Суммируем элементы массива float sum_elements ( float arr [], int n ) { float sum = 0.0 ; интервал я = 0 ;             while ( i < n ) sum += arr [ i ++ ]; // Пост-инкремент i, который проходит // через n элементов массива return sum ; }          

Оператор пост-инкремента также часто используется с указателями :

// Копируем один массив в другой void copy_array ( float * src , float * dst , int n ) { while ( n -- > 0 ) // Цикл, ведущий обратный отсчет от n до нуля * dst ++ = * src ++ ; // Копирует элемент *(src) в *(dst), // затем увеличивает оба указателя }                

Эти примеры также работают на других C-подобных языках, таких как C++ , Java и C# .

Поддержка языков

В следующем списке, хотя и не является полным и всеобъемлющим, перечислены некоторые основные языки программирования, поддерживающие операторы ++/ --приращения/уменьшения.

(Apple Swift когда-то поддерживал эти операторы [12] , но в версии 3 поддержка была удалена.)

Pascal , Delphi , Modula-2 и Oberon предоставляют одни и те же функции, но они называются inc(x) и dec(x).

Примечательно, что Python и Rust не поддерживают эти операторы.

История

Эта концепция была введена в язык программирования B примерно в 1969 году Кеном Томпсоном . [13]

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

Смотрите также

Рекомендации

  1. ^ Ричард М Риз. «Понимание и использование указателей C». «Глава 4. Указатели и массивы». O'Reilly Media, Inc. 2013. ISBN  9781449344184.
  2. ^ Ричард Петерсен. «Введение в C с C++». 2019. Рисунок 12-12.
  3. ^ «Руководство пользователя GNU Awk» . Фонд свободного программного обеспечения.
  4. ^ «8.3. Конструкция двойных круглых скобок» . Проект документации Linux.
  5. ^ Ричи, Брайан В. Керниган; Деннис М.; Ричи, Деннис (1988). Язык программирования Си (2-е изд., [Начдр.] изд.). Энглвуд Клиффс, Нью-Джерси: Прентис Холл. п. 18. ISBN 0-13-110362-8.{{cite book}}: CS1 maint: несколько имен: список авторов ( ссылка )
  6. ^ «Операторы увеличения/уменьшения» . cppreference.com.
  7. ^ «Оператор ++ (Справочник C#)» . Сеть разработчиков Microsoft.
  8. ^ «Перегрузка оператора». dlang.org.
  9. ^ «Операторы GP и их приоритеты».
  10. ^ «Об операторах присваивания».
  11. ^ «Увеличение символа языка Wolfram» . Центр языковой документации Wolfram.
  12. ^ «Базовые операторы». разработчик.apple.com.
  13. ^ Ричи, Деннис М. (март 1993 г.). «Развитие языка Си». Уведомления ACM SIGPLAN . 28 (3): 5. дои : 10.1145/155360.155580 .