stringtranslate.com

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

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

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

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

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

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

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

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

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

Примеры

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

int x ; int y ;  // Операторы инкремента // Преинкремент: x увеличивается на 1, затем y присваивается значение x x = 1 ; y = ++ x ; // x теперь равен 2, y также равен 2     // Пост-инкремент: y присваивается значение x, затем x увеличивается на 1 x = 1 ; y = x ++ ; // y равен 1, x теперь равен 2     // Операторы декремента // Преддекремент: x уменьшается на 1, затем y присваивается значение x x = 1 ; y = -- x ; // x теперь равен 0, y также равен 0     // Постдекремент: y присваивается значение x, затем x уменьшается на 1 x = 1 ; y = x -- ; // 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 ; int i = 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# .

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

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

Когда-то Swift от Apple поддерживал эти операторы, но начиная с версии 2.2 [13] они были устарели и удалены с версии 3.0. [14] [15]

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

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

История

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

Томпсон пошел еще дальше, придумав операторы ++ и --, которые увеличивают или уменьшают; их префиксная или постфиксная позиция определяет, происходит ли изменение до или после указания значения операнда. Их не было в самых ранних версиях 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". Free Software Foundation.
  4. ^ "8.3. Конструкция двойных скобок". Проект документации Linux.
  5. ^ Ритчи, Брайан В. Керниган; Деннис М.; Ритчи, Деннис (1988). Язык программирования C (2-е изд., [Nachdr.] изд.). Энглвуд Клиффс, Нью-Джерси: Prentice Hall. стр. 18. ISBN 0-13-110362-8.{{cite book}}: CS1 maint: несколько имен: список авторов ( ссылка )
  6. ^ "Операторы увеличения/уменьшения". cppreference.com.
  7. ^ "Оператор ++ (Справочник по C#)". Microsoft Developer Network.
  8. ^ «Перегрузка операторов». dlang.org.
  9. ^ «Операторы общей практики и их приоритеты».
  10. ^ «Об операторах присваивания».
  11. ^ "Увеличение символа языка Wolfram". Центр документации языка Wolfram.
  12. ^ "Уменьшение символа языка Wolfram". Центр документации языка Wolfram.
  13. ^ "Новые возможности Swift 2.2". Официальный сайт Swift.
  14. ^ "Swift 3.0 Released!". Официальный сайт Swift.
  15. ^ "Удалите операторы ++ и --". Swift evolution .
  16. ^ Ритчи, Деннис М. (март 1993 г.). «Развитие языка C». ACM SIGPLAN Notices . 28 (3): 5. doi : 10.1145/155360.155580 .