Я конвертировал алгоритм C ++ в C #. Я наткнулся на это для цикла:
for (u = b.size(), v = b.back(); u--; v = p[v])
b[u] = v;
Это не дает ошибки в C ++, но в C # (не может преобразовать int в bool). Я действительно не могу понять это для цикла, где условие?
Может кто-нибудь объяснить, пожалуйста?
PS. Просто чтобы проверить, чтобы адаптировать ВЕКТОР к СПИСКУ, b.back () соответствует b [b.Count-1]?
u--
. Точки с запятой используются для разграничения различных частейfor
утверждения.; u-- != 0;
b
,u
,v
и т.д. Единственная причина , почему они были названы так потому , что кто - то хотел , чтобы выглядеть умным, делая их код нечитаемым.do
значит в C ++», - получат тысячи обращений от новичков, ищущих учебник.Ответы:
Состояние
for
цикла находится посередине - между двумя точками с запятой;
.В C ++ нормально помещать почти любое выражение в качестве условия: все, что оценивается как ноль, означает
false
; ненулевое означаетtrue
.В вашем случае условие таково
u--
: когда вы конвертируете в C #, просто добавьте!= 0
:источник
u = b.size() - 1
.Много точных ответов, но я думаю, что стоит написать эквивалентный цикл while.
Эквивалентно:
Вы можете рассмотреть возможность рефакторинга в формат while () при переводе на C #. На мой взгляд, это понятнее, меньше ловушек для новых программистов и одинаково эффективно.
Как уже отмечали другие, - но чтобы мой ответ был завершен - чтобы он работал в C #, вам нужно изменить
while(u--)
наwhile(u-- != 0)
.... или
while(u-- >0)
на тот случай, если у тебя отрицательный результат. (ХОРОШО,b.size()
никогда не будет отрицательным - но рассмотрим общий случай, когда, возможно, что-то еще инициализировало вас).Или, чтобы сделать это еще яснее:
Лучше быть ясным, чем кратким.
источник
while (u-- >0)
формой. Если интервал испорчен, вы можете закончить циклом «до нуля»while (u --> 0)
, который на первый взгляд может запутать всех. ( Я не уверен, действительно ли это C #, но это в C, и я думаю, что это может быть также и в C ++? )for
вместо того, чтобыwhile
точно указать, что вы помещаете инициализацию и увеличение / уменьшение в одну инструкцию, и это не обязательно усложняет понимание кода. В противном случае, мы не должны использоватьfor
вообще.--
токен, за которым следует>
токен. Два отдельных оператора. Цикл "до нуля" - это просто прямая комбинация пост-декремента и "больше, чем". Перегрузка операторов C ++ не создает новые операторы, а просто переназначает существующие.Условие
u--;
, потому что он находится во втором положении из за инструкции.Если значение
u--;
отличается от 0, оно будет интерпретировано какtrue
(то есть неявно приведено к логическому значениюtrue
). Если вместо этого его значение равно 0, оно будет приведено кfalse
.Это очень плохой код .
Обновление: я обсуждал написание цикла for в этом посте . Его рекомендации можно резюмировать в следующих параграфах:
Этот пример явно нарушает эти рекомендации.
источник
Это будет C # форма вашего цикла.
Просто замените эквивалент для size () и back ().
Что он делает, так это переворачивает список и сохраняет в массиве. Но в C # у нас напрямую есть определенная системой функция для этого. Таким образом, вам не нужно писать этот цикл также.
источник
v = b.back();
из за intializer не просто изменить, как она работает, так какv = p[v]
перегружаетсяv = b.back();
выполнялся один раз перед началом итераций иv = p[v]
выполнялся в начале каждой итерации. В этой версии C #v = p[v]
все еще выполняется в начале каждой итерации, ноv = b.back();
выполняется сразу после нее, изменяя значениеv
для следующей инструкцииb[u] = v;
. (возможно вопрос был отредактирован после того, как вы его прочитали)v = b.back()
. Он выполняется на каждой итерации цикла, а не только на первой - мы не знаем, чтоback()
делает (есть ли побочные эффекты? Изменит ли это внутреннее представлениеb
?), Поэтому этот цикл не эквивалентен циклу в вопрос.v = b.back()
его переместить за пределы цикла, над ним. (Также, если вы пытаетесь ответить кому-то, используйте@
перед его именем, чтобы мы получили уведомление)это инициализация.
это условие.
это итерация
источник
Условие является результатом
u--
, которое является значениемu
до того, как оно было уменьшено.В C и C ++ переменная может
int
быть преобразована в bool путем неявного!= 0
сравнения (0 - этоfalse
все, что естьtrue
).b.back()
последний элемент в контейнереb[b.size() - 1]
, когдаsize() != 0
.источник
В C все ненулевое значение находится
true
в «логических» контекстах, таких как условие завершения цикла или условный оператор. В C # вы должны сделать это проверить явным:u-- != 0
.источник
Как утверждают другие, тот факт, что C ++ имеет неявное приведение к логическому
u--
значению, означает условное значение , которое будет истинным, если значение будет отличным от нуля.Стоит добавить, что у вас ложное предположение, спрашивая «где условное». И в C ++, и в C # (и в других языках с аналогичным синтаксисом) вы можете иметь пустое условное выражение. В этом случае всегда истинно, поэтому цикл продолжается вечно, или до некоторых других условий выходов он (через
return
,break
илиthrow
).Действительно, любая часть оператора for может быть пропущена, в этом случае она просто не выполняется.
В общем,
for(A; B; C){D}
илиfor(A; B; C)D;
становится:Любой из A, B, C или D может быть пропущен.
В результате этого, некоторые пользу
for(;;)
для бесконечных циклов. Я делаю это потому, что хотяwhile(true)
это более популярно, я читаю это как «пока истина не станет правдой», что звучит несколько апокалиптически по сравнению с моим чтениемfor(;;)
как «навсегда».Это дело вкуса, но так как я не единственный человек в мире, которому нравится
for(;;)
, стоит знать, что это значит.источник
все ответы верны: -
Цикл for может использоваться различными способами:
источник
В приведенном выше коде,
u
иv
инициализируются сb.size()
иb.back()
.Каждый раз , когда проверяется условие, оно выполняет декремент заявления тоже есть
u--
.for
Цикл будет выходить , когдаu
будет0
.источник
Ошибка, возникшая в самом C #, устраняет сомнения. Цикл for ищет
условие прекратить. И, как мы знаем,
но C # не может обработать это самостоятельно в отличие от C ++. Итак, условие, которое вы ищете
но вы должны явно дать условие в C # как
или
Но все же старайтесь избегать такого рода практики кодирования.
Изложенное выше в ответе является одной из самых упрощенных версий вашего
источник
Если вы привыкли к C / C ++, этот код не так сложен для чтения, хотя он довольно лаконичен и не так хорош для кода. Итак, позвольте мне объяснить части, которые больше Cism, чем что-либо еще. Прежде всего, общий синтаксис цикла C for выглядит следующим образом:
Код инициализации запускается один раз. Затем условие проверяется перед каждым циклом и, наконец, приращение вызывается после каждого цикла. Итак, в вашем примере вы найдете условие
u--
Почему
u--
работает как условие в C, а не C #? Потому что C неявно преобразует многие вещи слишком быстро, и это может вызвать проблемы. Для числа все, что ненулевое, является истинным, а ноль - ложным. Так что он будет отсчитывать от b.size () - 1 до 0. Наличие побочного эффекта в условии немного раздражает, и было бы предпочтительнее поместить его в инкрементную часть цикла for, хотя большая часть C Код делает это. Если бы я писал это, я бы сделал это примерно так:Причина этого, по крайней мере для меня, яснее. Каждая часть цикла for выполняет свою работу и ничего больше. В исходном коде условие модифицировало переменную. Часть приращения делала то, что должно быть в блоке кода и т. Д.
Оператор запятой также может привести вас к циклу. В C что-то похожее
x=1,y=2
выглядит как одно утверждение в отношении компилятора и вписывается в код инициализации. Он просто оценивает каждую из частей и возвращает значение последней. Так, например:распечатал бы 2.
источник