В программировании на компьютере блок или блок кода или блок кода — это лексическая структура исходного кода , которая сгруппирована вместе. Блоки состоят из одного или нескольких объявлений и операторов . Язык программирования , который позволяет создавать блоки, включая блоки, вложенные в другие блоки, называется языком программирования с блочной структурой . Блоки имеют основополагающее значение для структурного программирования , где управляющие структуры формируются из блоков.
Блоки имеют две функции: группировать операторы, чтобы их можно было рассматривать как один оператор, и определять области действия для имен , чтобы отличать их от тех же имен, используемых в других местах. В языке программирования с блочной структурой объекты, названные во внешних блоках, видны внутри внутренних блоков, если только они не замаскированы объектом , объявленным с тем же именем.
Идеи блочной структуры были разработаны в 1950-х годах во время разработки первых автокодов и были формализованы в отчетах Algol 58 и Algol 60. Algol 58 ввел понятие «составного оператора», которое было связано исключительно с потоком управления . [1] Последующий пересмотренный отчет , описывающий синтаксис и семантику Algol 60, ввел понятие блока и области действия блока , при этом блок состоял из «последовательности объявлений, за которыми следовала последовательность операторов и которые были заключены между begin и end...», в котором «каждое объявление появляется в блоке таким образом и действительно только для этого блока». [2]
Блоки используют разный синтаксис в разных языках. Два больших семейства:
begin
" и " end
" или эквивалентными. В C блоки разделяются фигурными скобками - " {
" и " }
". ALGOL 68 использует круглые скобки.(
" и " )
", используются в пакетном языке MS-DOS.prog
или let
(как в семействе Lisp )if ~ then ~ elif ~ else ~ fi
case ~ in ~ out ~ esac
for ~ while ~ do ~ od
Некоторые языки, поддерживающие блоки с объявлениями, не полностью поддерживают все объявления; например, многие языки, производные от C, не допускают определения функций внутри блока ( вложенные функции ). И в отличие от своего предка Algol, Pascal не поддерживает использование блоков с их собственными объявлениями внутри начала и конца существующего блока, а только составные операторы, позволяющие группировать последовательности операторов в if , while , repeat и других управляющих операторах.
Семантическое значение блока двояко. Во-первых, он предоставляет программисту способ создания произвольно больших и сложных структур, которые можно рассматривать как единицы. Во-вторых, он позволяет программисту ограничивать область действия переменных, а иногда и других объявленных объектов.
В ранних языках, таких как Fortran IV и BASIC , не было блоков операторов или структур управления, кроме простых форм циклов. Условные операторы были реализованы с помощью условных операторов goto :
ЯЗЫК C: СТАНДАРТ ANSI FORTRAN 66 C ИНИЦИАЛИЗИРОВАТЬ ЗНАЧЕНИЯ ДЛЯ РАСЧЕТА PAYSTX = . FALSE . PAYSST = . FALSE . TAX = 0.0 SUPTAX = 0.0 C ПРОПУСТИТЬ НАЛОГОВЫЙ ВЫЧЕТ, ЕСЛИ РАБОТНИК ЗАРАБАТЫВАЕТ МЕНЕЕ НАЛОГОВОГО ПОРОГА IF ( WAGES . LE . TAXTHR ) ПЕРЕЙТИ К 100 PAYSTX = . TRUE . TAX = ( WAGES - TAXTHR ) * BASCRT C ПРОПУСТИТЬ ВЫЧЕТ SUPERTAX, ЕСЛИ РАБОТНИК ЗАРАБАТЫВАЕТ МЕНЕЕ SUPERTAX ПОРОГА IF ( WAGES . LE . SUPTHR ) ПЕРЕЙТИ К 100 PAYSST = . TRUE . SUPTAX = ( ЗАРАБОТНАЯ ПЛАТА - SUPTHR ) * SUPRAT 100 НАЛОГООБЛОЖЕННЫЙ = ЗАРАБОТНАЯ ПЛАТА - НАЛОГ - SUPTAX
Логическая структура программы не отражена в языке, и анализ того, когда выполняется тот или иной оператор, может быть затруднен.
Блоки позволяют программисту рассматривать группу операторов как единое целое, а значения по умолчанию, которые должны появляться при инициализации в этом стиле программирования, могут, с помощью блочной структуры, располагаться ближе к решению:
{ Язык: Jensen и Wirth Pascal } if wages > tax_threshold then begin paystax := true ; tax := ( wages - tax_threshold ) * tax_rate { Блочная структура упрощает просмотр того, как можно реорганизовать код для ясности, а также упрощает выполнение, поскольку структуру внутреннего условного оператора можно легко вынести из внешнего условного оператора, а последствия этого легко предсказать. } if wages > supertax_threshold then begin pays_supertax := true ; supertax := ( wages - supertax_threshold ) * supertax_rate end else begin pays_supertax := false ; supertax := 0 end end else begin paystax := false ; pays_supertax := false ; tax := 0 ; supertax := 0 end ; облагаемый налогом := заработная плата - налог - сверхналог ;
Использование блоков в приведенном выше фрагменте Паскаля проясняет намерение программиста и позволяет объединять полученные блоки во вложенную иерархию условных операторов. Структура кода более точно отражает ход мыслей программиста, что облегчает его понимание и изменение.
Приведенный выше исходный код можно сделать еще более понятным, если полностью убрать внутренний оператор if из внешнего, разместив два блока один за другим для последовательного выполнения. Семантически в этом случае разница невелика, а использование блочной структуры, поддерживаемое отступами для удобства чтения, позволяет программисту легко рефакторить код.
В примитивных языках переменные имели широкую область действия. Например, целочисленная переменная IEMPNO могла использоваться в одной части подпрограммы Fortran для обозначения номера социального страхования (ssn) сотрудника, но во время работ по техническому обслуживанию той же подпрограммы программист мог случайно использовать ту же переменную IEMPNO для другой цели, и это могло привести к ошибке, которую было трудно отследить. Блочная структура упрощает для программистов контроль области действия до минутного уровня.
;; Язык: Стандартная схема R5RS ( let (( empno ( ssn-of employee-name ))) ( while ( is-manager empno ) ( let (( employees ( length ( underlings-of empno )))) ( printf "~a has ~a employees working underhis:~%" employee-name employees ) ( for-each ( lambda ( empno ) ;; Внутри этого лямбда-выражения переменная empno ссылается на ssn ;; подчиненного. Переменная empno во внешнем выражении, ;; ссылающаяся на ssn менеджера, затенена. ( printf "Name: ~a, role: ~a~%" ( name-of empno ) ( role-of empno ))) ( underlings-of empno )))))
В приведенном выше фрагменте схемы empno используется для идентификации как менеджера, так и его подчиненных по их соответствующему ssn, но поскольку подчиненный ssn объявлен во внутреннем блоке, он не взаимодействует с переменной с тем же именем, которая содержит ssn менеджера. На практике соображения ясности, вероятно, заставят программиста выбрать разные имена переменных, но у них есть выбор, и сложнее внести ошибку непреднамеренно.
В некоторых языках переменная может быть объявлена в области действия функции даже внутри вложенных блоков. Например, в JavaScript переменные, объявленные с помощью, var
имеют область действия функции.