Как цикл For работает в VB.NET? - PullRequest
1 голос
/ 14 апреля 2009

Я думаю, что знаю это ... Я понятия не имел.

Это простой цикл For:

Dim i As Integer
Dim n As Integer = 10
Dim s As Integer = 1

For i = 0 To n Step s
    Console.WriteLine(i)
Next

компилируется в это (я поставил его через Refelctor, чтобы его было легче читать). Я даже не мог понять, что он делает со всеми этими битовыми сдвигами:

Dim n As Integer = 10
Dim VB$t_i4$L1 As Integer = 1
Dim VB$t_i4$L0 As Integer = n
Dim i As Integer = 0
Do While (((VB$t_i4$L1 >> &H1F) Xor i) <= ((VB$t_i4$L1 >> &H1F) Xor VB$t_i4$L0))
    Console.WriteLine(i)
    i = (i + VB$t_i4$L1)
Loop

Почему цикл For так изуродован?

Ответы [ 2 ]

8 голосов
/ 14 апреля 2009

Возможно, потому что это "общий способ" охватить все случаи. Помните, что for / step / next может идти в любом направлении с любым знаком приращения.

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

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

Также он создает копии параметров для предотвращения внешних помех (например, изменение s или n во время перечисления).

=== ОБНОВЛЕНИЕ ===

Я сомневаюсь, что кто-то все еще наблюдает за этим вопросом, но я вернулся к этому самородку просто ради полноты и потому, что у меня было немного времени. То, что делает VB, немного подло. Сдвиг битов S в основном создает целое число, основанное на знаке S (он копирует MSB из s, заканчиваясь на & hFFFFFFFF, если S отрицателен, и & h00000000, если S положителен).

XOR целочисленного значения с -1 эквивалентно (-value-1). XOR с 0, очевидно, NOP. Таким образом, если s отрицателен, он меняет оба значения (-1 отменяет друг друга), чтобы сравнить их, эффективно изменяя порядок сравнения без необходимости или условия, и, следовательно, без скачка в потоке программы. Если s положительный, он просто сравнивает их.

итак, для s <0 вы в итоге наберете </p>

while (-i-1)<=(-n-1) 
==> while -i <= -n
==> while i>=n

для s> 0 вы получите

while i <= n

Возвращает меня к моим 68k дням ASM, когда были такие хитрости, в которых повседневные вещи (такие как XOR.l D0, D0, потому что XOR для регистра с самим собой было быстрее, чем загрузка в него нуля ...): p

0 голосов
/ 14 апреля 2009

Полагаю, очевидный ответ заключается в том, что цикл For Next может быть записан как цикл Do While, и преобразование одного в другой означает, что вам нужно реализовать только один тип цикла в компиляторе. Я вижу, как это работает, но почему это делается, я понятия не имею.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...