Почему из p=n получается p<n ? (Новогодняя шутка для "чайников")

Автор neft, 28 декабря 2011, 13:53

0 Пользователи и 1 гость просматривают эту тему.

neft

Выполните макрос и объясните конечный результат.

Sub Main()
Dim n, p As Integer

For n = 0 To 5
p = n
MsgBox n & " = " & p
Next

MsgBox "ВНИМАНИЕ!   p = " & p & "   n =" & n
End Sub

bormant

Макрос не выполнял, но предположу, что не исключена следующая реализация цикла FOR:

n = 0
WHILE n <= 5
  ...
  n = n + 1
WEND

Вот только закладываться на такое поведение (суть особенность реализации) -- не рекомендуется.
Автору на яд. Поддержать форум.

Kopusha

Ну, всё так, в последней итерации цикла n = 6, что не удовлетворяет условию, и тело цикла пропускается. Поэтому p так и остаётся 5.

neft

Вопрос на экзамене "подленького" преподавателя, пытающегося "завалить" миловидную студентку, не ответившую ему взаимностью:
ЦитироватьНо ведь вот тут написано
For n = 0 To 5, что означает, что n может меняться только от 0 до 5 (!)
Почему у вас, милочка, вдруг стало n=6 ?

Рыбка Рио

Цитата: neft от 29 декабря 2011, 11:36
Вопрос на экзамене "подленького" преподавателя, пытающегося "завалить" миловидную студентку, не ответившую ему взаимностью:
ЦитироватьНо ведь вот тут написано
For n = 0 To 5, что означает, что n может меняться только от 0 до 5 (!)
Почему у вас, милочка, вдруг стало n=6 ?
За такие слова преподавателю может быть придётся извиняться.  :)
Вести.Ru: Самые громкие извинения уходящего года:
ЦитироватьДэвид Кэмерон за сексизм

Британского премьера Дэвида Кэмерона обвинили в сексизме после того, как он во время оживленной дискуссии в Парламенте обратился к политику Анжеле Игл со словами: "Милочка моя, успокойтесь". Инцидент произошел в апреле. Осенью Кэмерон вновь оскандалился, сказав депутату Надин Доррис во время обсуждения поправки об абортах, что эта проблема, по всей видимости, знакома женщине не понаслышке. Спустя несколько дней премьер-министр публично попросил у Доррис прощения за несдержанность. А вот Анжела Игл извинений от политика пока не дождалась.
ubuntu 12.04 + LibO3.6.0

neft

#5
Ну, это если она догадается спрятать в каком-нибудь месте диктофон.

Но если не ответит, то законную "двоечку" всё равно получит.

bormant

neft,
а что, разве в каком-то руководстве по Бейсику зафиксировано такое поведение, при котором после цикла FOR значение переменной цикла равно последнему значению+шаг?
А на нет и суда нет.
Автору на яд. Поддержать форум.

neft

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

bormant

neft,
так вот у вас и пытаюсь выяснить, какой ответ вы считаете правильным. Вдруг вы где-то видели подобное поведение документированным, раз подобный вопрос достоин быть заданным на экзамене, так поделитесь, не уходите от ответа.
Пишущим на C/C++ в этом вопросе намного проще, их можно об этом спрашивать, потому как ответ есть в стандарте -- "undefined behaviour" -- поведение не определено.
Автору на яд. Поддержать форум.

neft

#9
Ну, документацию я так сразу не вспомню.
По памяти, если только:
n - это просто "счетчик", увеличивающий свое значение на "шаг" (Step)
Next (точнее, Next n) - операция, увеличивающая значение счетчика и передающая управление операции проверки значения "счетчика", т.е.
For n = 0 To 5 - проверяет удовлетворяет ли текущее значение счетчика условию 0 <= n <= 5
Если удовлетворяет, то выполняются операции внутри подпрограммы цикла For .. Next,
если не удовлетворяет, то происходит выход из этой подпрограммы и управление передается следующему за Next оператору.
Т.е. при последней проверке условия и при выходе значение n не попадает в заданную условием область значений, а отличается от него на "шаг".

"Шутка" (тоже по памяти) заключается в том, что если на выходе n=5, то из цикла For ... Next мы никогда не выйдем.


PS. Вы скажете, что при выходе из цикла счетчик может, например, обнуляться. Верно, это зависит от реализации счетчика, а пока была просто "шутка" про Basic.

bormant

#10
neft,
тогда вот вам другой вариант, ничего общего с вашими рассуждениями не имеющий:

mov cx, [start]
@loop:
mov [i], cx
...
add cx, [step]
cmp cx, [stop]
jle @loop
Автору на яд. Поддержать форум.

neft

bormant,
а теперь, пожалуйста, обычным человеческим языком (не assembler'ом) для "чайников", что вы хотите сказать?

bormant

#12
neft,
по крайней мере стал понятен источник заблуждений...

mov cx, [start]  -- запись в регистр cx начального значения счётчика
@loop: -- метка
mov [ii], cx -- запись в область памяти переменной ii начального значения счётчика
add cx, [step] -- увеличение счётчика в регистре на шаг цикла
cmp cx, [stop] -- сравнение счётчика с конечным значением
jle @loop -- переход, если меньше или равно
-- иначе -- выход из цикла.

Если не было перехода по метке @loop, значение переменной ii не было обновлено увеличенным значением.

Операций MOV [память], [память], ADD [память], [память] часто не существует в наборе команд.
Автору на яд. Поддержать форум.