2013-07-30 2 views
6

я следующий исходный код в C:Как работает оператор декремента в выражении while?

#include<stdio.h> 

void main() 
{ 
    int i=0, x=3; 
    while((x---1)) 
    { 
     i++; 
    } 
    printf("%d", i); 
} 

Как это время заявление работы и почему это напечатать 2 вместо 1?

+6

Мне все еще нравится оператор '->' лучше: 'while (x -> 0) {...}' – nneonneo

+2

@nneonneo предлагает «x идет к нулю» :) Математики и авторы представления IOCCC должны любить, что , –

+1

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

ответ

10

Потому что x---1 действительно просто x-- - 1, который дает значение x - 1 перед декрементами x.

Учитывая, что x имеет начальное значение 3, цикл выполняется 2 раза (один раз с x = 3, один раз с x = 2, затем следующий раз x равен 1, поэтому x - 1 равно 0, а цикл не равен больше).

Итак, i начинается с 0 и он увеличивается в два раза, так что заканчивается время 2.

+1

Спасибо, теперь я понял, что x декрементируется только оператором x--. Я не знаю, почему я думал, что он уменьшался дважды: один раз по x-1 и после с помощью x--. Но поскольку это не x = x-1, это не изменяет его значение на этот. Принял меня, чтобы добраться до него, хотя :) –

5

(x---1) == (x-- -1)

потому что компилятор пытается выбрать больший маркер первым, так --- истолкован как -- & -

Expression x-- - 1 означает первый 1вычитается из текущего значения x вследствие - минус. Затем x значение уменьшилось на 1 из-за постфиксного оператора декремента --.

Например, в первой итерации до x = 3, так что в то время как условие 2 (то есть 3 - 1) после этого x декрементируется, и до следующей итерации x = 2.

x = 3, i =0;

  • 1-итерации:while(2), а в петле i становится 1

x = 2, i = 1;

  • 2-итерации:while(1), а в петле i становится 2

x = 1, i = 2;

  • Теперь x - 1 = 0, что дает while(0) и петли перерывов и i не увеличивают.

Таким образом, после Регулирующее i: 2

примечание еще один момент: i не увеличивается, как разрыв контура, потому что i++ в то время как-блок {}, но x декрементируется к 0. После цикла, если вы печатаете x, тогда вывод будет 0.

2

while((x---1)) эквивалентно while((x-- -1 != 0)), что, в свою очередь, является такой же, как написание while(x-- != 1). Поскольку значение x-- является значение xперед декремента, это то же самое, как

while(x != 1) { 
    x--; 
    ... 
} 

, который работает в два раза, если x начинается на 3

3

Так что это время, вероятно, имеет больше смысла, если вы посмотрите на нее еще с некоторыми пробелами:

while((x-- - 1)) 

он использует пост декремент так х модифицируется после возвращения его текущее значение, так что на самом деле эквивалентно этому :

while((x - 1)) 

и цикл будет выполняться до тех пор, пока выражение false или в данном случае 0 что эквивалентно false. Таким образом, бег выглядит следующим образом:

x x - 1 i 
============= 
3  2  1 x - 1 not 0 so increment i 
2  1  2 x - 1 not 0 so increment i 
1  0  2 Loop exits here and does not increment i again 

В этот момент цикл завершается, и вы попали в printf.

Смежные вопросы