2016-01-29 2 views
0

У меня есть этот кодНесколько операторов в течение

for(int l = 1 ; l <= c ; l++, Sleep(500*min(l, 8))) //... <= 4000 msec 
    { 
     .... 
    } 

это было бы эквивалентно это?

for(int l = 1 ; l <= c ; l++) //... <= 4000 msec 
    { 
     Sleep(500*min(l, 8)) 
     .... 
    } 

Я хочу переписать исходный код на C#. Является ли второй подход тем же, что и в C#?

+1

заключительная часть из 'для (;; )' эквивалентно тому, что происходит на * end * цикла. И в вашем исходном случае 'l ++' происходит до 'Sleep'. – BoBTFish

+0

@BoBTFish Не могли бы вы разобраться? –

+0

Вы потеряете один 'l' счет, что делает' int l = 0' в модифицированной версии поможет вам –

ответ

2

Они не эквивалентны, так как третья часть цикла for выполняется в конце каждого цикла. В соответствии с docs это синтаксис для цикла for.

for (initializer; condition; iterator) { 
    body 
} 

Где

В разделе итератора определяет, что происходит после каждой итерации тела цикла.

В оригинальном случае l++ не происходит до того Sleep, так это эквивалентный код:

for(int l = 1 ; l <= c ; l++) //... <= 4000 msec 
{ 
      ...... 
     Sleep(500*min(l+1, 8)) // note the +1 
} 
+0

Технически l ++ происходит до вызова Sleep в его цикле, поэтому первый сон в его цикле будет на 1 секунду, а для вашего - 500 мс. – Neil

+0

@Neil Вот почему он добавил 1 к 'l' при вызове' Sleep' –

+0

Хорошо, но будет ли он работать так же, если я напишу тот же код в C#? Например: 'for (int l = 1; l <= c; l ++, Sleep (500 * min (l, 8)))' ?? –

4

Нет, они не эквивалентны. Условие остановки цикла for выполняется после кода в следующем блоке { }.

Таким образом, эквивалентность

for(int l = 1; l <= c;) 
{ 
    /*loop body*/ 
    l++, Sleep(500 * min(l, 8)); 
} 

Оператор выражение сепаратор (,) может быть заменен терминатором ; заявление. Поскольку оба являются точками последовательности, Sleep получает добавочное значение l.

+0

Обратите внимание, что 'l' увеличивается до' Sleep' в оригинал. – BoBTFish

+0

К сожалению. Глупый старый кот. – Bathsheba

+0

Хорошо, но будет ли это работать, если я напишу один и тот же код на C#? Например: 'for (int l = 1; l <= c; l ++, Sleep (500 * min (l, 8)))' ?? –

1

Не совсем, код эквивалентен

for(int l = 1 ; l <= c;) //... <= 4000 msec 
{ 
    // loop body goes here 
    ... 

    // statements from the last part of the for(...;...;...) statement are executed at the end of the loop 
    l++; 
    Sleep(500*min(l, 8)); 
} 
+0

За исключением того, что 'l ++' должен быть выполнен перед вызовом 'Sleep'. –

+0

@KenWayneVanderLinde вы правы, отредактировал ответ. – maddin45

0
for(int l = 0 ; l <= c ; l++, Sleep(500*min(l, 8))) //... <= 4000 msec 
    { 
    .... 
    } 

Примечание изменение int l = 1 к Int l = 0, потому что вы будете один отсчет вперед, так что вы должны подсчитывать его за счет сокращения одного счета. Так что я сделал l к 0

+0

Это вообще не отвечает на вопрос. Фактически, он изменяет исходный цикл, а не делает новый цикл правильным. –

1

No. Ваш исходный код эквивалентен

{ 
    int l = 1 ; 
    while(l <= c) 
    { 
     .... 
     l++, Sleep(500*min(l, 8)); //... <= 4000 msec 
    } 
} 

, а модифицированная версия

{ 
    int l = 1 ; 
    while(l <= c) //... <= 4000 msec 
    { 
     Sleep(500*min(l, 8)); 
     .... 
     l++; 
    } 
} 

Как вы можете видеть, l увеличивается после того, как используется для расчета Sleep() времени, а не раньше, как изначально. Кроме того, Sleep() вызывается до того, как выполняется основная часть тела цикла, а не после него.

0

Интересная альтернатива:

for(int l = 2 ; l <= c+1; l++) //... <= 4000 msec 
{ 
    // ... 
    Sleep(500*min(l, 8)) 
} 

Подобный ответ Габриэля, но + 1 перемещается за пределы проверки, которая сохраняет все остальное смотрит то же самое. (код считается подозрительным при добавлении одного к l, чтобы компенсировать «пропущенный» приращение).

Поскольку вопрос касается также переноса кода на C#, вот уместная информация. Хотя ваши два примера кода не эквивалентны, они оба переводят непосредственно на код C# (с эквивалентом C#, равным Sleep). Для C# более сложный пример, найденный в the docs, дает понять, что когда секция итератора цикла for содержит несколько выражений, они оцениваются слева направо. В C++ встроенный оператор запятой также оценивает слева направо (см. here, в разделе «Встроенный оператор запятой»).

+0

Хорошо, но будет ли работать то же самое, если я напишу один и тот же код в C#? Подобно этому (в C#): 'for (int l = 1; l <= c; l ++, Thread.Sleep (500 * min (l, 8)))' ?? - Это то же самое, что и моя версия на C++? (первая версия) –

+0

@ user200312 Вторая форма, безусловно, работает на обоих языках.Я * верю *, первая форма тоже, потому что я думаю, что оба языка определяют оценку слева направо для оператора запятой (не на 100% уверен, но я был бы очень удивлен, если бы это было ложно). –

+0

«Я верю, что первая форма также работает, потому что я думаю, что оба языка определяют оценку слева направо для оператора запятой (не на 100% уверен, но я был бы очень удивлен, если бы это было ложно)». что меня действительно интересует –

0

Я думаю, что есть некоторые путаницы в отношении C# 'для' петель здесь. C# делает разрешает такой же тип цикла 'for' как исходный (C++?) Код (т. Е. Несколько операторов в третьем разделе):

for (int l = 1; l <= c; l++, System.Threading.Thread.Sleep(500 * Math.Min(l, 8))) 
{ 
    //.... 
} 

Если вы хотите еще другой способ написания этого - даже если «за» петли выше работ:

int l = 1; 
while (l <= c) 
{ 
    //.... 
    l += 1; 
    System.Threading.Thread.Sleep(500 * Math.Min(l, 8)); 
} 
Смежные вопросы