Jump to content

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

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

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

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

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

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

  • Операторы pre -increment и pre -decrement увеличивают (или уменьшают) свой операнд на 1, а значением выражения является результирующее увеличенное (или уменьшенное) значение.
  • Операторы post -increment и post -decrement увеличивают (или уменьшают) значение своего операнда на 1, но значением выражения является значение операнда до операции увеличения (или уменьшения).

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

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

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

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

int x;
int y;

// Increment operators
// Pre-increment: x is incremented by 1, then y is assigned the value of x
x = 1;
y = ++x;    // x is now 2, y is also 2

// Post-increment: y is assigned the value of x, then x is incremented by 1
x = 1;
y = x++;    // y is 1, x is now 2

// Decrement operators
// Pre-decrement: x is decremented by 1, then y is assigned the value of x
x = 1;
y = --x;    // x is now 0, y is also 0

// Post-decrement: y is assigned the value of x, then x is decremented by 1
x = 1;
y = x--;    // y is 1, x is now 0

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

# Pre-increment: y = ++x
x = 1
x = x + 1  # x is now 2  (can be written as "x += 1" in Python)
y = x      # y is also 2

# Post-increment: y = x++
x = 1
y = x      # y is 1
x = x + 1  # x is now 2


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

// Sum the elements of an array
float sum_elements(float arr[], int n)
{
    float  sum = 0.0;
    int    i   =   0;

    while (i < n)
        sum += arr[i++];    // Post-increment of i, which steps
                            //  through n elements of the array
    return sum;
}

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

// Copy one array to another
void copy_array(float *src, float *dst, int n)
{
    while (n-- > 0)        // Loop that counts down from n to zero
        *dst++ = *src++;   // Copies element *(src) to *(dst),
                           //  then increments both pointers
}

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

  • Оператор инкремента можно продемонстрировать на примере:
    #include <stdio.h>
    int main()
    {
        int c = 2;
        printf("%d\n", c++); // this statement displays 2, then c is incremented by 1 to 3.
        printf("%d", ++c);   // this statement increments c by 1, then c is displayed.
        return 0;
    }
    
    • Выход:
      2
      4
      

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

[ редактировать ]

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

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

Паскаль , 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. Указатели и массивы» . О'Рейли Медиа, Инк. 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. ^ «Уменьшить символ языка Wolfram» . Центр языковой документации Wolfram.
  13. ^ «Новые возможности Swift 2.2» . Официальный сайт Swift.
  14. ^ «Выпущен Swift 3.0!» . Официальный сайт Swift.
  15. ^ «Удалить ++ и -- операторы» . Быстрая эволюция .
  16. ^ Ричи, Деннис М. (март 1993 г.). «Развитие языка Си» . Уведомления ACM SIGPLAN . 28 (3): 5. дои : 10.1145/155360.155580 .
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: 6edfd70a1a36c7d2a5d116d841c91351__1721339820
URL1:https://arc.ask3.ru/arc/aa/6e/51/6edfd70a1a36c7d2a5d116d841c91351.html
Заголовок, (Title) документа по адресу, URL1:
Increment and decrement operators - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)