fbpx
维基百科

块 (编程)

计算机编程中,(block)或代码块是将源代码组织在一起的词法结构。块构成自一个或多个声明英语Declaration (computer programming)语句。编程语言允许创建块,包括嵌入其他块之内的块,就叫做块结构编程语言。块和子程序结构化编程的基础,结构化所强调的控制结构是用块来形成的。

在编程中块的功能是确使成组的语句被当作如同就是一个语句,限定在一个块中声明的对象如变量、过程和函数的词法作用域,使得它们不冲突于在其他地方用到的同名者。在块结构编程语言中,在块外部的对象名字在块内部是可见的,除非它们被声明了相同名字的对象所遮掩

历史

块结构的想法是在1950年代开发第一个Autocode英语Autocode期间发展出来的,并形式化于ALGOL 58ALGOL 60报告中。Algol 58介入了“复合”(compound)语句的概念,它只与控制流程有关[1]。随后的描述ALGOL 60的语法和语义的“修订报告”介入了块和块作用域的概念,这里的块构成自“一序列的声明,跟随着一序列的语句,并被包围在beginend之间...”在其中“所有声明以这种方式出现在一个块中,并只在这个块中有效。”[2]

语法

块在不同语言中使用不同的语法。两个广大的家族是:

  • ALGOL语言家族,ALGOL 60及其后继者如Pascal语言家族,使用关键字beginend或等价者来界定块。ALGOL 68使用圆括号:()C语言家族承袭了BCPL,使用花括号来界定块:{}
  • Lisp语言家族,使用具有语法关键字如prog[3]let[4]S-表达式来表示块,S-表达式是圆括号包围的前缀表示法

此外还有:

限制

受ALGOL影响的一些语言,支持带有声明的块,但不完全支持所有声明,例如C及其很多派生语言,不允许在块内的函数定义(嵌套函数英语nested function)。Pascal家族语言,在现存块的beginend内部,不支持使用带有自己声明的块,只支持复合语句,用来确使语句序列在ifwhilerepeat和其他控制语句内被组合在一起。

基本语义

块的语义是双重的。首先,它向编程者提供了建立任意大和复杂的结构并把它当作一个单元的一种途径。其次,它确使编程者能限制变量的作用范围,有时可以限制已经被声明了的其他对象的作用范围。

在原初的语言比如早期的FORTRANBASIC中,有一些内建的语句类型,很少或没有以有结构的方式扩展它们的方法。例如,直到1978年标准化FORTRAN 77之前,都没有“块状IF”语句,所以要写一个遵循标准的代码来实现简单的决定,编程者必须诉诸GOTO语句:

C 语言: ANSI标准FORTRAN 66 C 初始化要计算的值   PAYSTX = .FALSE.   PAYSST = .FALSE.   TAX = 0.0   SUPTAX = 0.0 C 如果雇员挣钱少于税金阈值则跃过税款扣除   IF (WAGES .LE. TAXTHR) GOTO 100   PAYSTX = .TRUE.   TAX = (WAGES - TAXTHR) * BASCRT C 如果雇员挣钱少于附加税阈值则跃过附加税扣除   IF (WAGES .LE. SUPTHR) GOTO 100   PAYSST = .TRUE.   SUPTAX = (WAGES - SUPTHR) * SUPRAT  100 TAXED = WAGES - TAX - SUPTAX 

甚至这个非常简要的FORTRAN片段,符合FORTRAN 66标准,却不容易看出这个程序的结构,因为结构不反映在语言中。没有仔细的研究的话,不容易看出执行给定语句所处的环境。

块允许编程者把一组语句当作一个单元,在这种风格的程序中,上例中出现在初始化中的那些缺省值,通过块结构,被分别放置在接近于作出决定的地方:

{ 语言: Jensen和Wirth Pascal } if wages > tax_threshold then begin paystax := true; tax := (wages - tax_threshold) * tax_rate end else begin paystax := false; tax := 0 end; if wages > supertax_threshold then begin pays_supertax := true; supertax := (wages - supertax_threshold) * supertax_rate end else begin pays_supertax := false; supertax := 0 end; taxed := wages - tax - supertax; 

上述的Pascal片段,符合ISO 7185标准化的1974年版规定,使用块明晰了编程者的意图,代码的结构更加密切的反映出编程者的思考。使用块结构,依靠缩进支持其可读性,使其更加容易理解和修改。

在原初的语言中,变量有着宽广的作用范围。例如,一个叫做IEMPNO的整数变量可以用在一个Fortran子例程的某部份中,指示一个雇员的社会安全号码(ssn),但是在相同子例程的维护工作中,一个编程者可能偶然的使用了相同的变量IEMPNO,用于了不同的用途,这可能导致一个难于跟踪的缺陷。块结构使得编程者易于控制作用范围到细微级别。

;; 语言: R5RS标准Scheme (let ((empno (ssn-of employee-name))) (while (is-manager empno) (let ((employees (length (underlings-of empno)))) (printf "~a has ~a employees working under him:~%" employee-name employees) (for-each (lambda(empno) ;; 在这个lambda表达式之内变量empno指称一个下属的ssn。 ;; 在外部的表达式中变量empno指称的管理者的ssn,被遮蔽了。 (printf "Name: ~a, role: ~a~%" (name-of empno) (role-of empno))) (underlings-of empno))))) 

在上述Scheme片段中,empno被用来标识管理者和他的下属二者自己分别的ssn,但是因为下属ssn被声明于内部的块之中,它与包含管理者ssn的同名变量不相互影响。在实践中,出于清晰性的考虑,编程者更可能选择明显不同的变量名字,但是即使选择重名也难于不经意的介入一个缺陷。

提升

在一些情境下,在一个块中的代码的求值,如同这个代码实际上是写在块的顶部或块的外部一样。这经常通俗的叫做“提升”(hoisting),这包括了:

  • 循环不变代码外提,是将在循环内不变的代码在循环之前求值的编译器优化。
  • 变量提升,是JavaScript的辖域规则,在这里变量有函数辖域,并且表现得如同它们被声明(而非定义)在函数的顶部一样。

参见

引用

  1. ^ Perlis, A. J.; Samelson, K. Preliminary report: international algebraic language. Communications of the ACM (New York, NY, USA: ACM). 1958, 1 (12): 8–22. doi:10.1145/377924.594925. 
  2. ^ John Backus; Friedrich L. Bauer; J. Green; C. Katz; John McCarthy; Alan Jay Perlis; Heinz Rutishauser; K. Samelson; B. Vauquois; J. H. Wegstein; A. van Wijngaarden; M. Woodger. Peter Naur , 编. 3 (5). New York, NY, USA: ACM: 299–314. May 1960 [2009-10-27]. ISSN 0001-0782. doi:10.1145/367236.367262. (原始内容存档于2007-06-25). 
  3. ^ John McCarthy, Paul W. Abrahams, Daniel J. Edwards, Timothy P. Hart, Michael I. Levin. (PDF) 2nd. MIT Press. 1985 [1962] [2021-09-23]. ISBN 0-262-13011-4. (原始内容 (PDF)存档于2021-03-02). The LISP 1.5 program feature allows the user to write an Algol-like program containing LISP statements to be executed. ……The program form has the structure - (PROG, list of program variables, sequence of statements and atomic symbols...) An atomic symbol in the list is the location marker for the statement that follows. 
  4. ^ Kent M. Pitman英语Kent Pitman. . 1983, 2007 [2021-10-14]. (原始内容存档于2021-12-21). LET is used to bind some variables to some objects, and then to evaluate some forms (those which make up the body) in the context of those bindings. ……LET* Same as LET but does bindings in sequence instead of in parallel. 

编程, 在计算机编程中, block, 或代码块是将源代码组织在一起的词法结构, 块构成自一个或多个声明, 英语, declaration, computer, programming, 和语句, 编程语言允许创建块, 包括嵌入其他块之内的块, 就叫做块结构编程语言, 块和子程序是结构化编程的基础, 结构化所强调的控制结构是用块来形成的, 在编程中块的功能是确使成组的语句被当作如同就是一个语句, 限定在一个块中声明的对象如变量, 过程和函数的词法作用域, 使得它们不冲突于在其他地方用到的同名者, 在块结构编程语言中. 在计算机编程中 块 block 或代码块是将源代码组织在一起的词法结构 块构成自一个或多个声明 英语 Declaration computer programming 和语句 编程语言允许创建块 包括嵌入其他块之内的块 就叫做块结构编程语言 块和子程序是结构化编程的基础 结构化所强调的控制结构是用块来形成的 在编程中块的功能是确使成组的语句被当作如同就是一个语句 限定在一个块中声明的对象如变量 过程和函数的词法作用域 使得它们不冲突于在其他地方用到的同名者 在块结构编程语言中 在块外部的对象名字在块内部是可见的 除非它们被声明了相同名字的对象所遮掩 目录 1 历史 2 语法 3 限制 4 基本语义 5 提升 6 参见 7 引用历史 编辑块结构的想法是在1950年代开发第一个Autocode 英语 Autocode 期间发展出来的 并形式化于ALGOL 58和ALGOL 60报告中 Algol 58介入了 复合 compound 语句的概念 它只与控制流程有关 1 随后的描述ALGOL 60的语法和语义的 修订报告 介入了块和块作用域的概念 这里的块构成自 一序列的声明 跟随着一序列的语句 并被包围在begin和end之间 在其中 所有声明以这种方式出现在一个块中 并只在这个块中有效 2 语法 编辑块在不同语言中使用不同的语法 两个广大的家族是 ALGOL语言家族 ALGOL 60及其后继者如Pascal语言家族 使用关键字begin和end或等价者来界定块 ALGOL 68使用圆括号 和 C语言家族承袭了BCPL 使用花括号来界定块 和 Lisp语言家族 使用具有语法关键字如prog 3 或let 4 的S 表达式来表示块 S 表达式是圆括号包围的前缀表示法 此外还有 越位规则 源于ISWIM使用缩进表示块结构 采用越位规则的语言有occam Python和Genie等 在ALGOL 68和此后1974年Edsger W Dijkstra的守卫命令语言中 条件和迭代代码块可选的使用块保留字反写来终止 比如 b if b then elif then else b fi b b case b in out b esac b 和for while b do b b od b 继承此风格的有Bourne shell等 类似的 有的结构化编程语言如FORTRAN 77 Modula 2 Ada和Visual Basic等 对控制结构加结束关键字 比如 IF THEN ELSIF THEN ELSE END 限制 编辑受ALGOL影响的一些语言 支持带有声明的块 但不完全支持所有声明 例如C及其很多派生语言 不允许在块内的函数定义 嵌套函数 英语 nested function Pascal家族语言 在现存块的begin和end内部 不支持使用带有自己声明的块 只支持复合语句 用来确使语句序列在if while repeat和其他控制语句内被组合在一起 基本语义 编辑块的语义是双重的 首先 它向编程者提供了建立任意大和复杂的结构并把它当作一个单元的一种途径 其次 它确使编程者能限制变量的作用范围 有时可以限制已经被声明了的其他对象的作用范围 在原初的语言比如早期的FORTRAN和BASIC中 有一些内建的语句类型 很少或没有以有结构的方式扩展它们的方法 例如 直到1978年标准化FORTRAN 77之前 都没有 块状IF 语句 所以要写一个遵循标准的代码来实现简单的决定 编程者必须诉诸 a href Goto html title Goto GOTO a 语句 C 语言 ANSI标准FORTRAN 66 C 初始化要计算的值 PAYSTX FALSE PAYSST FALSE TAX 0 0 SUPTAX 0 0 C 如果雇员挣钱少于税金阈值则跃过税款扣除 IF WAGES LE TAXTHR GOTO 100 PAYSTX TRUE TAX WAGES TAXTHR BASCRT C 如果雇员挣钱少于附加税阈值则跃过附加税扣除 IF WAGES LE SUPTHR GOTO 100 PAYSST TRUE SUPTAX WAGES SUPTHR SUPRAT 100 TAXED WAGES TAX SUPTAX 甚至这个非常简要的FORTRAN片段 符合FORTRAN 66标准 却不容易看出这个程序的结构 因为结构不反映在语言中 没有仔细的研究的话 不容易看出执行给定语句所处的环境 块允许编程者把一组语句当作一个单元 在这种风格的程序中 上例中出现在初始化中的那些缺省值 通过块结构 被分别放置在接近于作出决定的地方 语言 Jensen和Wirth Pascal if wages gt tax threshold then begin paystax true tax wages tax threshold tax rate end else begin paystax false tax 0 end if wages gt supertax threshold then begin pays supertax true supertax wages supertax threshold supertax rate end else begin pays supertax false supertax 0 end taxed wages tax supertax 上述的Pascal片段 符合ISO 7185标准化的1974年版规定 使用块明晰了编程者的意图 代码的结构更加密切的反映出编程者的思考 使用块结构 依靠缩进支持其可读性 使其更加容易理解和修改 在原初的语言中 变量有着宽广的作用范围 例如 一个叫做IEMPNO的整数变量可以用在一个Fortran子例程的某部份中 指示一个雇员的社会安全号码 ssn 但是在相同子例程的维护工作中 一个编程者可能偶然的使用了相同的变量IEMPNO 用于了不同的用途 这可能导致一个难于跟踪的缺陷 块结构使得编程者易于控制作用范围到细微级别 语言 R5RS标准Scheme let empno ssn of employee name while is manager empno let employees length underlings of empno printf a has a employees working under him employee name employees for each lambda empno 在这个lambda表达式之内变量empno指称一个下属的ssn 在外部的表达式中变量empno指称的管理者的ssn 被遮蔽了 printf Name a role a name of empno role of empno underlings of empno 在上述Scheme片段中 empno被用来标识管理者和他的下属二者自己分别的ssn 但是因为下属ssn被声明于内部的块之中 它与包含管理者ssn的同名变量不相互影响 在实践中 出于清晰性的考虑 编程者更可能选择明显不同的变量名字 但是即使选择重名也难于不经意的介入一个缺陷 提升 编辑在一些情境下 在一个块中的代码的求值 如同这个代码实际上是写在块的顶部或块的外部一样 这经常通俗的叫做 提升 hoisting 这包括了 循环不变代码外提 是将在循环内不变的代码在循环之前求值的编译器优化 变量提升 是JavaScript的辖域规则 在这里变量有函数辖域 并且表现得如同它们被声明 而非定义 在函数的顶部一样 参见 编辑基本块 块辖域 闭包 计算机科学 控制流程引用 编辑 Perlis A J Samelson K Preliminary report international algebraic language Communications of the ACM New York NY USA ACM 1958 1 12 8 22 doi 10 1145 377924 594925 John Backus Friedrich L Bauer J Green C Katz John McCarthy Alan Jay Perlis Heinz Rutishauser K Samelson B Vauquois J H Wegstein A van Wijngaarden M Woodger Peter Naur 编 Report on the Algorithmic Language ALGOL 60 3 5 New York NY USA ACM 299 314 May 1960 2009 10 27 ISSN 0001 0782 doi 10 1145 367236 367262 原始内容存档于2007 06 25 John McCarthy Paul W Abrahams Daniel J Edwards Timothy P Hart Michael I Levin LISP 1 5 Programmer s Manual PDF 2nd MIT Press 1985 1962 2021 09 23 ISBN 0 262 13011 4 原始内容 PDF 存档于2021 03 02 The LISP 1 5 program feature allows the user to write an Algol like program containing LISP statements to be executed The program form has the structure PROG list of program variables sequence of statements and atomic symbols An atomic symbol in the list is the location marker for the statement that follows Kent M Pitman 英语 Kent Pitman The Revised Maclisp Manual 1983 2007 2021 10 14 原始内容存档于2021 12 21 LET is used to bind some variables to some objects and then to evaluate some forms those which make up the body in the context of those bindings LET Same as LET but does bindings in sequence instead of in parallel 请检查 date 中的日期值 帮助 取自 https zh wikipedia org w index php title 块 编程 amp oldid 74991340, 维基百科,wiki,书籍,书籍,图书馆,

文章

,阅读,下载,免费,免费下载,mp3,视频,mp4,3gp, jpg,jpeg,gif,png,图片,音乐,歌曲,电影,书籍,游戏,游戏。