Ну это пример простецкий, а если в этом блоке меняются значения локальных переменных, что мне их все в процедуру кидать? А если таких блоков в реальном листинге несколько десятков, а если вложенность подобных условий многоуровневая? А если язык не позволяет пользоваться указателями (например их там просто не существует)) )?
Вы все ничего не поняли!
Во первых конструкция: Если (УСЛОВИЕ) Тогда {...}
Подразумевает любое составное УСЛОВИЕ, но! Это составное условие рассчитывается сразу, например многие компиляторы используют метод обратной польской записи (Ну что там многие, почти все), так вот, если мы зададим составное условие вида:
(СуществетОбъект(Объект)=Да)и(Объект.Атрибут=1)
Компилятор тупо проверит существоние объекта и значение атрибута этого объекта, в случае если объект существует все нормально, но если объекта нет, тогда вторая часть составного условия вызовет исключения типа обращение к несуществующему объекту, области памяти, нарушение доступа и т.д. на вкус компилятора.
Компилятор? Классический компилятор (ala gcc в контексте c++ кода) это корректно скомпилирует.
В рантайме код if case1 && case2 отработает корректно. Корректная работа этого кода означает кейс:
– выполняется самое левое условие,
– если предыдущее условие истинно, то выполняется следующее,
– ...
– возвращается значение в "условный оператор".
Среда выполнения в которой нет JIT не может работать иначе.
Выше под компилятором подразумевался JIT?
Если так, то придется тебя растроить, в Java, .Net, ObjC и прочих наборах технологий, которе мне знакомы JIT может вызвать некоторые сложности в условных операторах, передаче вычисляемых параметров в функции, но описанная ситуация в них невозможна.
Поэтому в таких проверках придеться использовать 2 конструкции Если (if), первой проверяем существование объекта и если он есть, то его атрибут.
Алгоритм который написал Раздолбайкер правильный с точки зрения задачи и реализации на любом языке, но в нем есть минус 1 и тот же блок кода приходится переписывать 2 раза! (в версии Раздолбайкера "пролет")примерно так:
Если "сигареты не найдётся" = нет
{
пролет
}
иначе
{
Если "спички есть" = нет тогда
{
Покурил
}
иначе
{
пролет
}
}
Блок-схема в топике, иллюстрирует немного другую конструкцию, она позволяет выйти из второго условия в другую ветку первого. Так вот вопрос: почему ее нет в языках?
Можно конечно так написать:
Если "сигареты не найдётся" = нет
{
goto l1
}
Если "спички есть" = нет тогда
{
Покурил
goto l2
}
:l1 пролет
:l2 ....
Но как известно в открытую использовать безусловный переход на метку не православно...
А теперь самый главный вопрос. ПОЧЕМУ при вычислении условия меняется значение локальных переменных?
Проблема в дизайне приложения, а не в языках.
Такой странной фичи нигде нет, потому что она не нужна. В контексте других языков описанная ситуация в подавляющем большинстве случаев решается конструкцией if (case1 && case2), в остальных случаях, с которыми я не сталкивался, но могу предположить – это проблема не языка.