Что такое оператор «->» в C / C ++?

avatar
GManNickG
29 октября 2009 в 06:57
867095
29
9479

Прочитав Скрытые возможности и темные уголки C ++ / STL на comp.lang.c++.moderated, я был полностью удивлен, что следующий фрагмент скомпилирован и работает как в Visual Studio 2008, так и в G ++ 4.4.

Вот код:

#include <stdio.h>
int main()
{
    int x = 10;
    while (x --> 0) // x goes to 0
    {
        printf("%d ", x);
    }
}

Вывод:

9 8 7 6 5 4 3 2 1 0

Я бы предположил, что это C, поскольку он также работает в GCC. Где это определено в стандарте и откуда оно взялось?

Источник
Spongman
29 июля 2021 в 00:16
2

если вы используете его в цикле for, он требует обязательного подмигивания: for (int x = 10; x --> 0 ;) ...

Ответы (29)

avatar
Bradley Mackey
15 июня 2021 в 08:09
9178

--> не является оператором. Фактически это два отдельных оператора, -- и >.

Код условия уменьшает x, возвращая исходное (не уменьшенное) значение x, а затем сравнивает исходное значение с 0 с помощью оператора >.

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

while( (x--) > 0 )
Moshe Bildner
19 мая 2021 в 13:26
3

Я видел, как его в шутку называют оператором «даунто» (codegolf.stackexchange.com/questions/16226/…)

paxdiablo
3 июля 2021 в 01:18
0

Я думаю, вам действительно не нужны круглые скобки вокруг x--, хотя это еще больше усиливает разделение. Вероятно, было бы достаточно просто более четко связать токены с чем-то вроде while (x-- > 0).

avatar
Poarthur
29 июля 2021 в 07:40
3

На самом деле, вы можете "создать" оператор -> просто для удовольствия)

class MyClass {
    class Helper
    {
        MyClass* ptr;
        Helper(MyClass* _this): ptr{_this} {}
    public:
        Helper(const Helper&) = delete;
        Helper(Helper&&) = delete;
        void operator=(const Helper&) = delete;
        void operator=(Helper&&) = delete;
        operator MyClass()
        {
            auto tmp = *ptr;
            tmp._value++;
            return tmp;
        }
        friend MyClass;
        void operator>(int){std::cout << "Operator -->" << std::endl;}
    };

    int _value = 0;
public:
    MyClass() = default;
    MyClass(int value): _value{value} {}
    Helper operator--(int)
    {
        _value--;
        return Helper(this);
    }
    int get() const noexcept
    {
        return _value;
    }
    bool operator>(int num) const noexcept
    {
        return _value > num; 
    }
};

int main()
{
    MyClass obj(5);
    obj > 1;            //operator >
    obj--;              //operator --
    MyClass b = obj--;  //still works
    std::cout << b.get() << std::endl;      //4
    std::cout << obj.get() << std::endl;    //3
    b --> 5;            //operator -->
    //But there is at least one problem
    auto c = obj--;     //auto can deduce a private type :(
}

Но, как я уже сказал, это только для развлечения;)

avatar
3 июня 2021 в 20:01
7

Вместо обычного оператора стрелки (->) вы можете использовать оператор бронебойной стрелы: --x> (обратите внимание на эти острые зазубрины на кончике стрелки). Он добавляет +1 к пробитию брони, поэтому завершает цикл 1 быстрее, чем обычный стрелок. Попробуйте сами:

int x = 10;
while( --x> 0 )
    printf("%d ", x);
chqrlie
3 июня 2021 в 22:30
1

мило :) чтобы узнать поведение ОП, используйте оператор бронебойного пробивания в упор: while( --x>-1 )

avatar
2 июня 2021 в 05:47
1

Вот что вы имеете в виду.

while((x--) > 0)

Мы слышали в детстве,

Стой, не давай, отпусти (روکو مت ، انے دو)

Если запятая вводит в заблуждение

Стой, не отпускай. (روکو ، مت انے دو)

То же самое происходит и в программировании, ПРОБЕЛ вносит путаницу. : D

chqrlie
2 июня 2021 в 08:16
0

Этой идеей можно злоупотреблять для дальних целей в стиле лука и стрел: while((x --)> 0)

Numan Gillani
2 июня 2021 в 08:21
0

Это до понимания, все, что человеку кажется простым и понятным, для него это нормально. Основная цель - прояснить концепцию и стать успешным разработчиком :)

chqrlie
2 июня 2021 в 08:28
0

Конечно. И ИМХО while (x --> 0) понятно и действенно. x принимает все значения от начального до 0 включительно, что идеально подходит для цикла перечисления значений индекса для массива как для знаковых, так и для беззнаковых типов x.

avatar
chqrlie
12 марта 2021 в 17:19
2

--> - это не оператор, это сочетание -- (постдекремент) и > (больше, чем сравнение).

Цикл будет выглядеть более знакомым как:

#include <stdio.h>
int main() {
    int x = 10;
    while (x-- > 0) { // x goes to 0
        printf("%d ", x);
    }
}

Этот цикл является классической идиомой для перечисления значений между 10 (исключенная верхняя граница) и 0 включенной нижней границей, полезной для перебора элементов массива от последнего к первому.

Начальное значение 10 - это общее количество итераций (например, длина массива), плюс одно плюс первое значение, используемое внутри цикла. 0 - это последнее значение x внутри цикла, поэтому комментарий x переходит в 0 .

Обратите внимание, что значение x после завершения цикла равно -1.

Обратите также внимание на то, что этот цикл будет работать таким же способом , если x имеет беззнаковый тип , например size_t, что является сильным преимуществом size_t, что является сильным преимуществом 8372318782 над >.

По этой причине я на самом деле поклонник этого удивительного синтаксиса: while (x --> 0). Я считаю эту идиому привлекательной и элегантной, точно так же, как for (;;) vs: while (1) (которая выглядит сбивающе похожей на while (l)). Он также работает на других языках, синтаксис которых основан на C: C ++, Objective-C, java, javascript, C # и многих других.

chqrlie
12 марта 2021 в 17:20
1

Интересно, почему этот ответ был автоматически сделан вики сообщества ...

GManNickG
12 марта 2021 в 20:42
1

У вас достаточно репутации, чтобы знать: а) это вопрос сообщества вики, поэтому все ответы - вики сообщества, и б) этот ответ - просто дублирование множества существующих ответов на вопрос десятилетней давности.

chqrlie
12 марта 2021 в 21:11
1

@GManNickG: Я не знал о неявной связи между вопросами и ответами для статуса вики сообщества, не все очевидно, даже после тысяч часов работы над сайтом, но я еще не слишком стар, чтобы учиться. Что касается ответа , перефразируя другие ответы, я просто хотел подчеркнуть аспект, который не рассматривается в других ответах и ​​не очевиден для случайных читателей: while (n-- > 0) идеально подходит для типов unsigned.

GManNickG
12 марта 2021 в 21:34
0

Справедливо. Может быть, комментарий к существующему ответу более уместен?

chqrlie
12 марта 2021 в 21:37
0

@GManNickG: Я прокомментировал различия подписанных / неподписанных в ответе GoodPerson . Мой ответ показывает, насколько этот цикл прост и подходит для перечисления элементов массива. Ни один из ответов не касается этого ... давайте посмотрим, могут ли другие модераторы удалить его.

avatar
Good Person
12 марта 2021 в 12:03
289

Это то же самое, что и

while (x--)
Mateen Ulhaq
4 декабря 2011 в 21:32
171

Разве это не должно быть for(--x++;--x;++x--)?

Cole Johnson
23 марта 2013 в 18:39
11

@DoctorT вот для чего нужен unsigned

chqrlie
12 марта 2021 в 17:14
6

while (x --> 0) не то же самое, что while (x--), если x имеет тип со знаком, первый цикл не выполняется вообще, если x имеет отрицательное значение, но второй повторяется много раз, пока не будет вызывает неопределенное поведение, когда x достигает INT_MIN.

avatar
23 января 2021 в 07:32
19
char sep = '\n'  /1\
; int i = 68    /1  \
; while (i  ---      1\
                       \
                       /1/1/1                               /1\
                                                            /1\
                                                            /1\
                                                            /1\
                                                            /1\
                            /           1\
                           /            1 \
                          /             1  \
                         /              1   \
                         /1            /1    \
                          /1          /1      \
                           /1        /1        /1/1> 0) std::cout \
                              <<i<<                               sep;

Для больших чисел в C ++ 20 представлены некоторые более продвинутые функции циклов. Сначала, чтобы поймать i, мы можем построить обратный цикл-де-цикл и отклонить его на std::ostream. Однако скорость i определяется реализацией, поэтому мы можем использовать новый оператор скорости C ++ 20 <<i<<, чтобы ускорить ее. Мы также должны поймать это, построив стену, если мы этого не сделаем, i покинет область видимости, и обращение к ней приведет к неопределенному поведению. Чтобы указать разделитель, мы можем использовать:

 std::cout \
           sep

и у нас есть цикл for от 67 до 1.

Anchith Acharya
15 мая 2021 в 14:23
3

Я пришел сюда искать бронзу, а нашел золото ...

avatar
Zohaib Ejaz
30 декабря 2020 в 17:46
29

Обычным способом мы определяем условие в круглых скобках цикла while «()» и условие завершения внутри фигурных скобок «{}», но этот -- & > - это способ определить все сразу. Например:

int abc(){
    int a = 5
    while((a--) > 0){ // Decrement and comparison both at once
        // Code
    }
}

Он говорит: уменьшите a и запустите цикл до тех пор, пока время a не станет больше, чем 0

По-другому все должно было быть так:

int abc() {
    int a = 5;
    while(a > 0) {
        a = a -1 // Decrement inside loop
        // Code
    }
}

В обоих случаях мы делаем одно и то же и достигаем одинаковых целей.

v010dya
14 июля 2017 в 19:07
5

Это неверно. Код в вопросе выполняет: «тест-запись-выполнение» (сначала тест, запись нового значения, выполнение цикла), ваш пример - «тест-выполнение-запись».

Kotauskas
12 мая 2019 в 10:59
0

@ v010dya Исправил ответ, теперь это test-write-execute как в вопросе, спасибо, что указали!

Stefan Fabian
29 декабря 2020 в 09:49
0

@ S.S.Anne Ваше изменение все еще неверно. a-- через некоторое время не должно быть.

chqrlie
12 марта 2021 в 12:20
0

В обоих случаях мы делаем одно и то же и достигаем одних и тех же целей. Не совсем: оба цикла повторяются 5 раз, но окончательное значение a после завершения цикла будет -1 в первом случае и 0 во втором.

avatar
Garry_G
28 октября 2020 в 23:00
33

Почему все сложности?

Простой ответ на исходный вопрос:

#include <stdio.h>

int main()
{
    int x = 10;
    while (x > 0)
    {
        printf("%d ", x);
        x = x-1;
    }
}

Он делает то же самое. Я не говорю, что вы должны делать это так, но он делает то же самое и ответил бы на вопрос в одном посте.

x-- - это просто сокращение для вышеупомянутого, а > просто нормальное значение больше operator. Нет большой загадки!

В наши дни слишком много людей усложняют простые вещи;)

pix
27 октября 2016 в 15:32
19

Этот вопрос не о сложностях, а о ** скрытых функциях и темных углах C ++ / STL **

Öö Tiib
13 мая 2017 в 09:30
25

Программа здесь дает другой вывод, чем исходный, потому что x здесь уменьшается после printf. Это хорошо демонстрирует, насколько «простые ответы» обычно неверны.

Anthony
15 декабря 2017 в 18:33
3

The OP's way: 9 8 7 6 5 4 3 2 1 0 и The Garry_G way: 10 9 8 7 6 5 4 3 2 1

CITBL
5 января 2019 в 17:05
3

Это не то же самое. Переместите свой x=x-1 перед printf, тогда вы можете сказать «он делает то же самое».

avatar
Kalana
28 октября 2020 в 22:58
23

(x --> 0) означает (x-- > 0).

  1. Вы можете использовать (x -->)
    Output: 9 8 7 6 5 4 3 2 1 0
  1. Вы можете использовать (-- x > 0) Это означает (--x > 0)
    Output: 9 8 7 6 5 4 3 2 1
  1. Вы можете использовать
(--\
    \
     x > 0)

Output: 9 8 7 6 5 4 3 2 1

  1. Вы можете использовать
(\
  \
   x --> 0)

Output: 9 8 7 6 5 4 3 2 1 0

  1. Вы можете использовать
(\
  \
   x --> 0
          \
           \
            )

Output: 9 8 7 6 5 4 3 2 1 0

  1. Вы также можете использовать
(
 x 
  --> 
      0
       )

Output: 9 8 7 6 5 4 3 2 1 0

Точно так же вы можете попробовать множество методов для успешного выполнения этой команды.

avatar
Peter Mortensen
28 октября 2020 в 22:53
3

Этот --> вообще не оператор. У нас есть оператор типа ->, но не типа -->. Это просто неправильная интерпретация while(x-- >0), которая просто означает, что x имеет оператор пост-декремента, и этот цикл будет выполняться до тех пор, пока он не станет больше нуля .

Другой простой способ написать этот код - while(x--). Цикл while будет остановлен всякий раз, когда он получит ложное условие, и здесь есть только один случай, то есть 0. Поэтому он остановится, когда значение x уменьшится до нуля .

avatar
Neeraj Bansal
28 октября 2020 в 22:50
3

Здесь -- - унарный оператор пост декремента.

 while (x-- > 0) // x goes to 0
 {
     printf("%d ", x);
 }
  • Вначале условие будет оцениваться как (x > 0) // 10 > 0
  • Теперь, поскольку условие истинно, оно войдет в цикл с уменьшенным значением x-- // x = 9
  • Вот почему первое напечатанное значение - 9
  • И так далее. В последнем цикле x=1, значит условие истинно. Согласно унарному оператору, значение изменилось на x = 0 во время печати. ​​
  • Теперь x = 0, который оценивает условие (x > 0 ) как ложное, и цикл while завершается.
avatar
RageZ
20 октября 2020 в 03:43
578

Это

#include <stdio.h>

int main(void) {
  int x = 10;
  while (x-- > 0) { // x goes to 0
    printf("%d ", x);
  }
  return 0;
}

Просто пробел делает вещи забавными, -- уменьшает, а > сравнивает.

avatar
Shubham
25 апреля 2020 в 10:16
1358

Это эквивалент

while (x-- > 0)

x-- (пост-декремент) эквивалентен x = x-1, поэтому код преобразуется в:

while(x > 0) {
    x = x-1;
    // logic
}
x--;   // The post decrement done when x <= 0
avatar
unsynchronized
8 января 2020 в 22:51
3486

Или что-то совсем другое ... x перемещается на 0.

while (x --\
            \
             \
              \
               > 0)
     printf("%d ", x);

Не совсем математически, но ... каждая картинка рисует тысячу слов ...

paxdiablo
3 июля 2021 в 01:14
3

Итак, в этом случае использования, будет ли наклон линии, например: каждая строка, являющаяся \ _ вместо \, определять, насколько быстро она падает до нуля? :-)

avatar
Kirill V. Lyadvinsky
2 октября 2019 в 08:08
2479

Это очень сложный оператор, поэтому даже ISO / IEC JTC1 (Объединенный технический комитет 1) разместил его описание в двух разных частях стандарта C ++.

Если шутить, это два разных оператора: -- и >, описанные соответственно в §5.2.6 / 2 и §5.9 стандарта C ++ 03.

avatar
doc
11 октября 2017 в 02:51
1455

x может перейти к нулю даже быстрее в обратном направлении:

int x = 10;

while( 0 <---- x )
{
   printf("%d ", x);
}

8 6 4 2

Вы можете управлять скоростью с помощью стрелки!

int x = 100;

while( 0 <-------------------- x )
{
   printf("%d ", x);
}

90 80 70 60 50 40 30 20 10

;)

DeusXMachina
15 февраля 2021 в 23:52
41

«Управлять скоростью можно стрелкой!». Спасибо, ненавижу.

paradocslover
19 марта 2021 в 04:30
9

Удачный ответ на вопрос.

avatar
SjB
3 января 2016 в 17:48
232

Этот код сначала сравнивает x и 0, а затем уменьшает x. (Также сказано в первом ответе: вы уменьшаете x, а затем сравниваете x и 0 с помощью оператора >.) См. Вывод этого кода:

9 8 7 6 5 4 3 2 1 0

Теперь мы сначала сравниваем, а затем уменьшаем, увидев на выходе 0.

Если мы хотим сначала уменьшить, а затем сравнить, используйте этот код:

#include <stdio.h>
int main(void)
{
    int x = 10;

    while( --x> 0 ) // x goes to 0
    {
        printf("%d ", x);
    }
    return 0;
}

Этот вывод:

9 8 7 6 5 4 3 2 1
H-005
31 июля 2020 в 06:02
4

--x> 0 Это x в космическом корабле, идущем к 0 (Луне)?

avatar
Rajeev Das
30 апреля 2015 в 22:50
137

Это комбинация двух операторов. Первый -- предназначен для уменьшения значения, а > предназначен для проверки того, больше ли значение правого операнда.

#include<stdio.h>

int main()
{
    int x = 10;

    while (x-- > 0)
        printf("%d ",x);

    return 0;
}

Вывод будет:

9 8 7 6 5 4 3 2 1 0            
avatar
cool_me5000
30 апреля 2015 в 22:49
191

Мой компилятор распечатает 9876543210, когда я запустил этот код.

#include <iostream>
int main()
{
    int x = 10;

    while( x --> 0 ) // x goes to 0
    {
        std::cout << x;
    }
}

Как и ожидалось. while( x-- > 0 ) на самом деле означает while( x > 0). x-- пост декрементирует x.

while( x > 0 ) 
{
    x--;
    std::cout << x;
}

- это другой способ записать одно и то же.

Приятно, что оригинал выглядит как «пока x идет в 0».

Tim Leaf
5 мая 2010 в 15:30
5

Результат не определен только тогда, когда вы увеличиваете / уменьшаете одну и ту же переменную более одного раза в одном и том же операторе. Это не относится к данной ситуации.

Bernhard Barker
22 мая 2015 в 12:28
16

while( x-- > 0 ) actually means while( x > 0) - Я не уверен, что вы пытались сказать там, но то, как вы это сформулировали, подразумевает, что -- не имеет никакого значения, что, очевидно, очень неправильно.

Mark Lakata
24 февраля 2020 в 16:41
0

Чтобы довести до ума @Dukeling, этот ответ не тот же , что и исходный пост. В исходном сообщении x будет -1 после выхода из цикла, а в этом ответе x будет 0.

avatar
NguyenDat
23 апреля 2015 в 09:02
338

В одной книге, которую я прочитал (я не помню правильно, какую книгу) сказано: Компиляторы пытаются разобрать выражения до самого большого токена , используя правило левого и правого.

В данном случае выражение:

x-->0

Разбирает самые большие токены:

token 1: x
token 2: --
token 3: >
token 4: 0
conclude: x-- > 0

То же правило применяется к этому выражению:

a-----b

После синтаксического анализа:

token 1: a
token 2: --
token 3: --
token 4: -
token 5: b
conclude: (a--)-- - b

Надеюсь, это поможет понять сложное выражение ^^

avatar
Peter Mortensen
12 апреля 2014 в 09:55
125

C и C ++ подчиняются правилу «максимального количества еды». Таким же образом a --- b переводится в (a--) - b, в вашем случае x-->0 преобразуется в (x--)>0.

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

david
28 августа 2014 в 00:41
5

Это то, что предполагал ОП: что "((а) ->)" было максимальным пережевыванием. Оказывается, исходное предположение OP было неверным: «->» не является максимально допустимым оператором.

Roy Tinker
11 июля 2015 в 01:04
4

Также известен как жадный разбор, если я правильно помню.

user207421
11 сентября 2016 в 02:21
2

@RoyTinker Greedy сканирование. Парсер не имеет к этому никакого отношения.

avatar
AndroidLearner
12 апреля 2014 в 09:52
127

Фактически, x является постдекрементным и с этим условием проверяется. Это не -->, это (x--) > 0

Примечание: значение x изменяется после проверки условия, потому что оно пост-декремент. Возможны и подобные случаи, например:

-->    x-->0
++>    x++>0
-->=   x-->=0
++>=   x++>=0
Florian F
1 сентября 2014 в 09:46
6

За исключением того, что ++> вряд ли можно использовать через некоторое время (). Оператором «доходит до ...» будет ++ <, что нигде не выглядит так хорошо. Оператор -> - счастливое совпадение.

underscore_d
12 ноября 2016 в 17:57
2

@BenLeggiero Это могло бы «работать» в смысле генерации кода, который что-то делает (в то же время приводя в ярость читателей, которым не нравится фальшивый умный код), но семантика другая, поскольку использование предкремента означает, что он будет выполнять на одну итерацию меньше. В качестве надуманного примера он никогда не выполнит тело цикла, если x начнется с 1, но while ( (x--) > 0 ) будет. {edit} Эрик Липперт рассмотрел оба вопроса в своих примечаниях к выпуску C # 4: blogs.msdn.microsoft.com/ericlippert/2010/04/01/…

avatar
Test
28 февраля 2013 в 17:28
254

Так или иначе, у нас есть оператор "переходит к". "-->" легко запомнить как направление, а «пока x стремится к нулю» означает прямое.

Кроме того, на некоторых платформах он немного более эффективен, чем "for (x = 10; x > 0; x --)".

Ganesh Gopalasubramanian
13 ноября 2009 в 03:22
21

Не всегда может быть правдой, особенно когда значение x отрицательно.

Pete Kirkham
21 июня 2010 в 08:57
17

Другая версия не делает то же самое - с for (size_t x=10; x-->0; ) тело цикла выполняется с 9,8, .., 0, тогда как другая версия имеет 10,9, .., 1. В противном случае довольно сложно выйти из цикла до нуля с помощью беззнаковой переменной.

tslmy
15 июня 2013 в 02:49
6

Я думаю, что это немного вводит в заблуждение ... У нас нет буквально «переходит к» оператору, так как нам нужен другой ++> для выполнения инкрементальной работы.

SamB
6 декабря 2013 в 06:57
23

@Josh: на самом деле переполнение дает неопределенное поведение для int, так что он может так же легко съесть вашу собаку, как привести x к нулю, если он начинается с отрицательного результата.

Marc van Leeuwen
30 августа 2014 в 20:08
4

Это очень важная идиома для меня по причине, указанной в сообщении @PeteKirkham, поскольку мне часто нужно выполнять убывающие циклы по беззнаковым величинам вплоть до 0. (Для сравнения, идиома пропуска тестов на ноль, такая как запись while (n--) вместо беззнакового n, ничего не дает вам и для меня сильно затрудняет читаемость.) У нее также есть приятное свойство: вы указываете еще один , чем начальный индекс, который обычно является тем, что вам нужно (например, для цикла по массиву вы указываете его размер). Мне также нравится --> без пробелов, так как это упрощает распознавание идиомы.

Marc van Leeuwen
30 августа 2014 в 20:16
0

... На самом деле, я несколько сожалею, что запись while(0<--n) не делает то же самое, что запись while(n-->0), и первое, как правило, не то, что вам нужно. С другой стороны, по крайней мере в C ++, вы можете заставить его спускаться в два раза быстрее с помощью while(0<----n).

Horse SMith
21 ноября 2014 в 02:12
1

x=10; while(x --> 0) не то же самое, что for(x=10; x>0; x--) ... с другой стороны, это то же самое, что и for(x=10-1; x=>0; x--).

Narfanar
26 мая 2015 в 07:57
1

Ну тоже while(0 <=-- x). Но это становится глупо (erp

Artelius
21 августа 2020 в 01:36
1

При любом уровне оптимизации компилятора нет разницы в эффективности. Вывод сборки идентичен.

avatar
3 декабря 2011 в 02:33
400

Совершенно чудаковатый, но я буду использовать это:

#define as ;while

int main(int argc, char* argv[])
{
    int n = atoi(argv[1]);
    do printf("n is %d\n", n) as ( n --> 0);
    return 0;
}
StevePoling
7 марта 2021 в 19:43
3

Я знаю, это выглядит круто, но боюсь, что это обманчиво. Причина, по которой вы пишете C ++ вместо машинного языка, заключается в том, что вы хотите передать свое намерение следующему парню, читающему ваш код. Эта конструкция нарушает принцип наименьшего удивления. Это ментальная «опасность путешествия».

paxdiablo
3 июля 2021 в 01:21
3

«когда n приближается к нулю» - это круто, в каком-то смысле, с точки зрения компьютерных вычислений :-)

avatar
muntoo
29 октября 2011 в 21:42
147

-- - оператор декремента, , а > - оператор больше, чем .

Эти два оператора применяются как один, например -->.

underscore_d
12 ноября 2016 в 17:56
14

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

avatar
22 ноября 2010 в 19:02
158

Отсутствует пробел между -- и >. x пост-декрементируется, то есть уменьшается после проверки условия x>0 ?.

user529758
2 августа 2012 в 19:16
45

Пробел не пропущен - C (++) игнорирует пробелы.

Jens
25 апреля 2013 в 21:16
29

@ H2CO3 В целом это не так. Есть места, где необходимо использовать пробелы для разделения токенов, например в #define foo() по сравнению с #define foo ().

Kevin P. Rice
4 декабря 2013 в 20:35
31

@Jens Как насчет: «Пробел не пропущен - C (++) игнорирует ненужные пробелы.»?

avatar
Grumdrig
19 ноября 2009 в 19:46
389
while( x-- > 0 )

вот как это разбирается.

avatar
18 ноября 2009 в 12:47
458

Использование --> имеет историческое значение. Уменьшение было (и остается в некоторых случаях) быстрее, чем приращение на архитектуре x86. Использование --> предполагает, что x собирается на 0, и обращается к тем, кто имеет математическое образование.

burito
30 декабря 2009 в 05:16
517

Не совсем так. Уменьшение и увеличение занимают одинаковое количество времени, преимуществом этого является то, что сравнение с нулем происходит очень быстро по сравнению со сравнением с переменной. Это верно для многих архитектур, а не только для x86. Что-нибудь с инструкцией JZ (переход, если ноль). Поковыряясь, можно найти множество циклов "for", которые записываются задом наперед, чтобы сэкономить циклы при сравнении. Это особенно быстро на x86, так как при уменьшении значения переменной устанавливается соответствующий нулевой флаг, поэтому вы можете выполнить переход без необходимости явно сравнивать переменную.

Joey Adams
12 апреля 2010 в 15:07
31

Ну, уменьшение в сторону нуля означает, что вам нужно сравнивать только с 0 на итерацию цикла, а итерация по направлению к n означает сравнение с n каждой итерацией. Первое, как правило, проще (и на некоторых архитектурах автоматически проверяется после каждой операции с регистром данных).

Bernhard Barker
22 мая 2015 в 12:55
1

Это было бы лучше в качестве сноски в другом ответе или комментарии - он явно не объясняет, что означает -->, а именно то, что было задано.

Mark K Cowan
8 июля 2015 в 11:26
8

В ASM x86 LOOP <address> уменьшает регистр ECX, затем переходит к <address>, если уменьшение ECX не привело к нулю. Уменьшение счетчика цикла до нуля позволяет компилятору сгенерировать одну команду LOOP, тогда как для увеличения или подсчета до других значений требуются отдельные инструкции INC / DEC / ADD / SUB, сравнения и условного перехода. Современные компиляторы часто могут преобразовывать другие циклы в цикл counter --> 0, если значение counter не используется в цикле.

Mark K Cowan
8 июля 2015 в 11:32
4

Продолжая мой предыдущий комментарий: MOV ECX, value, @start:, <code>, LOOP @start - эквивалент ASM для x86 для counter = value - 1; while (counter --> 0) { <code>; }. Обратите внимание, что он будет заблокирован, если value изначально равен нулю, поэтому перед циклом требуется дополнительная проверка.