TCL语言基础资料
- 格式:pdf
- 大小:19.57 KB
- 文档页数:6
Tcl语言基础(TCL语言Tcl tick 的构成在下面的清单中,将会发现第一个很常见的示例程序,它是用Tcl 实现的。
这是一个完整的脚本:第一行命令调用 tclsh 环境,第二行命令执行实际工作。
用您所选择的文本编辑器创建该脚本,输入chmod +x hello.tcl 使之成为可执行文件,然后执行它以测试您这件“作品”。
~/tcltk$ cat hello.tcl#!/usr/bin/tclshputs stdout {Hello, World!}~/tcltk$ ./hello.tclHello, World!Tcl 和 Tk 是解释型的、可扩展脚本语言。
与 BSD 许可证十分相似,该许可证允许在任何情况下自由使用该软件,只要在所有副本中保留该版权并且在任何分发中一字不差地传递通告。
这个许可证条款使Tcl/Tk 成为自由软件。
Tcl/Tk 是一种解释型环境。
可以通过添加预编译的C 函数来扩展Tcl 解释器,可从 Tcl 环境内部调用 Tcl 解释器。
可以为特定目的或一般的以及广泛使用的而定制这些扩展。
我们将在教程的后面看一些扩展并着重看一下第一个扩展—非常流行的 Expect。
在接下来的几屏中,将回顾 T cl 语言的一些主要特性,从元字符和全局变量到运算符、数学函数以及核心命令。
毕竟,这些命令使Tcl/Tk 成为有特色的,逐步发展的语言。
请记住,在本教程中没有篇幅涉及每条命令。
这里只突出一部分,以后您可以更进一步了解Tcl/Tk。
#!/usr/bin/tclsh# filename hello2.tcl# This program code shows# metacharacter usageputs stdout "Hello, World! \a"puts stdout {Hello, World! \a}set Pints 6set Days 7puts stdout "The answer to the universe is [ $Pints * $Days]!\n"***~/tcltk$ ./hello2.tclHello, World!Hello, World! \aThe answer to everything is 42!Tcl 元字符元字符是在Tcl/Tk 环境的上下文中有特殊含意的字符或字符对,它们包括分组语句、封装字符串、终止语句以及其它,如下表所示。
Tcl基础学习(1):简单⽂本输出(puts)与变量赋值(set)Tcl是⼀种解释语⾔,每条语句被⼀次解析并⽴即执⾏,该语⾔在脚本遇到错误后会⽴即停⽌。
Tcl在其脚本中遵循的基本语义:每条Tcl语句以换⾏符/分号 " ; " 结束如果⼀条语句跨多⾏,应在⾏尾加反斜杠 “\” ,才能在下⼀⾏继续执⾏每条语句及参数都被视为字符串格式如果字符串内有多个单词,使⽤双引号 “” 和⼤括号{}包括成⼀个单独的单元有空格分隔的多个单词则被认为是命令的多个参数(每个参数相当于⼀个单元)以“#”开头的语句认为是Tcl的注释puts:输出字符串的命令1.#This is a comment befor the commandputs "hello,world!”;#This is a comment afer the commandhello,world!2.puts "hello,world!” #This is a comment afer the commandwrong # args: should be "puts ?-nonewline? ?channalID? string"3.puts {hello,world! -1}hello,world! -14.puts hello world!;cannot find a channal named 'hello'set:Tcl赋值命令当set赋予两个参数进⾏调⽤时:set varName ?value?1. 如果value被指定,变量varName的内容被设置为Value2. 如果varName只包含字母字符,没有圆括号那它就是标量变量3. 如果varName中有varName(index)的形式,那它及时关联数组的元素获取数组中的索引值:array names varName返回值:indexset abc "123";#变量abc赋值为123123set def(1) 123;#def为数组变量,1为索引,123为数组变量def(1)的赋值123set def(test) 123;#def为数组变量,test为索引(索引可以为字符),123为数组变量def(1)的赋值123array names def;# array names 获取数组def中的索引值test 1当需要使⽤puts对变量进⾏求值时,需要使⽤美元符号 $set a 15;#a为变量名,15为变量的值puts $a;#打印a的值15符号 $的使⽤$在变量求值时有特殊含义,在想要使⽤对$打印时,必须在前⾯加上反斜杠"\"在使⽤$对变量求值时,不能放在⼤括号内例如:puts {Value is $a}; #命令⽆效在⼤括号内使⽤$只有⼀种情况,即对表达式进⾏计算时 eg:expr $x+2; expr{$x+2};。
TCL语言基础变量置换:它是由一个$符号标记,变量置换会导致变量的值插入一个单词符号中。
set x 10例如:set y $x+100 //y的值是10 + 100如果主要想得到值110,还必须用命令置换。
命令置换:命令置换是由[]括起来的TCL命令及其参数,命令置换会导致一个命令的所有或部分单词符号被另一个命令的结果所代替例如:set y [expr $x + 100] //y的值是110set y [expr $x + 100 ; set b 300 ] //y的值为300,因为了的值为300反斜杠置换:类似于C中反斜杠的用法,主要用于在单词符号中插入诸如换行符、空格、[、$等被TCL解析器当作特殊符号对待的字符。
例如:set msg multiple\space //这里最后两个单词间的空格不是分隔符,msg的值为:multiple spaceset msg money \ \$3333\ \nArray\ a\[2] //这个命令的执行结果为:money $3333 Array a[2] 将一个变量赋值给一个变量时,需用$符号如:set EndUser000 …8613000000000‟set EndUser $ EndUser000相关命令unser这个命从解析器中删除变理,后面可以有任意个参数,每个参数是一个变量名,删除数组的例子:%put $day(Monday)%put $day(Tuesday) 2%unset day%put $day(Tuesday)append命令把文本加到一个变量的后面例如:%set txt hellohello%append txt …! How are you‟hello ! How are you.Incr命令把一个变量值加上一个整数。
Incr要求变量原来的值和新加的值都必须是整数%set b a a%incr b expected integer but got “a”%set b 2 2%incr b 3 5List命令集List命令语法:list? Value value…?这个命令生成一个list,list的元素就是所有的value.例:%list 1 2 {3 4} 12{34}Concat命令语法:concat list ? list…?这个命令把多个list合成一个list,每个list变成新list的一个元素Lindex命令语法:lindex list index返回list的第index个(0-based)元素。
TCL基础教程——(1)入门TCL学习记录最近学习了tcl,有一些体会,写出来供大家一起交流和切磋!p.s.:由于鄙人只是用tcl进行常规流程控制和仿真验证平台的搭建,因此涉及到较为高级的用法以及tk界面的东东就没有涉猎,如果有哪位仁兄对高级用法很有心得,可以与我联系哦。
Note:鄙人此处挑拣了tcl中较为基本,也是十分实用的几个方面做粗略描述,后面还提出了一个较小的工程设计。
虽然不是很完整,但个人认为麻雀虽小,五脏也是聚全了^_^。
细节性的东西还劳烦大家参考active state的tcl manual。
一.Tcl是一种基于字符串的、解释性命令的语言,语法规则简单、易学。
Variable substitution: $, nestableCommand substitution: [], 其实,有了command substitution 实际上就表示命令可以嵌套,即:一个命令的结果可以作为别的命令的参数。
Backslash substitution: \, 与c语言类似,反斜杠主要用于在字符中插入诸如换行符、空格、[、$等被tcl解释器当作特殊符号对待的字符。
双引号和花括号除反斜杠歪,tcl提供另外两种方法来使得解释器把分隔符和置换符等特殊字符当作普通字符。
Tcl 解释器对双引号中的各种分隔符将不做处理,但是对换行符以及$、[]两种置换符还会做特殊处理。
而在花括号中,所有特殊字符都将成为普通字符,失去其特殊意义。
二、数组数组是一些元素的集合。
Tcl的数组和普通的计算机语言中的数组有很大的区别。
在tcl中,不能单独申明一个数组,数组只能和数组元素一起申明。
(感觉更像是c语言中的结构体)tcl不支持复杂的数据类型,这一点是tcl受指责最多的方面。
e.g.:set day(Monday) 1set day(Tuesday) 2数组的置换和简单的变量置换类似:e.g.:set a Mondayset day(Monday) 1set b $day(Monday) //b的值为1,即day(Monday)set c $day($a) //c的值为1,即day(Monday)三、listList这个概念在tcl中是用来表示集合的。
TCL语⾔笔记:TCL基础语法⼀、什么是TCLTcl 全称是 Tool command Language。
它是⼀个基于字符串的命令语⾔,基础结构和语法⾮常简单,易于学习和掌握。
Tcl 语⾔是⼀个解释性语⾔,所谓解释性是指不象其他⾼级语⾔需要通过编译和联结,它象其他 shell 语⾔⼀样,直接对每条语句顺次解释执⾏。
Tcl 数据类型简单。
对 Tcl 来说,它要处理的数据只有⼀种——字符串。
Tcl 将变量值以字符串的形式进⾏存储,不关⼼它的实际使⽤类型。
⼆、TCL的基本语法1.输出:tcl使⽤”puts"关键字来作为输出语句[语法] : puts ?-nonewline? ?channelId? stringTcl 的输出命令是“puts”,将字符串输出到标准输出channelId。
语法中两个问号之间的参数为可选参数。
puts hello结果=> helloputs –nonewline "hello hello"结果=>hello hello但如果输出⼀段有空格的⽂本,则要⽤双引号或者花括号括起来-nonewline 选项告诉 puts 不输出回车换⾏。
注意:双引号和花括号的作⽤是将多个词组织成⼀个变元,但他们是有差别的!这种差别就是在处理“替换操作”时,前者允许替换发⽣,⽽后者则可能会阻⽌替换。
关于两者⽤法与差别以后会陆续讲到。
在这⾥两者作⽤相同。
2.赋值: tcl 使⽤“set”关键字来定义参数,不必指定变量值的类型,因为变量值的类型仅⼀种——字符串。
为变量赋值时,会为变量开辟⼀段内存空间来存储变量值。
[语法] set varName [value]set a Hello ;#定义变量 a 并赋值=>Helloputs $a ;#输出变量值=>Helloset a “Hello world” ;#重新赋值=>Hello worldset a “Hello world”=> Test Tcl ;#输出变量值,此时不加”$”puts $a=>Hello world ;#输出变量值,此时要加”$”puts a=> a ;#输出字符”a”set b $a=>Hello worldputs $b=>Hello world ;#将 a 的值赋给 b3.替换(1):$“$”符实现引⽤替换,⽤以引⽤参数值。
Tcl语言参考Tcl("Tool Command Language",即工具命令语言;Tcl念作“踢叩”"tickle")是一种易学易用易于扩展的脚本语言,实际上包含了两个部分:一个语言和一个库。
首先,Tcl是一种简单的脚本语言,主要使用于发布命令给一些交互程序如文本编辑器、调试器和shell。
它有一个简单的语法和很强可扩充性,Tcl可以创建新的过程以增强其内建命令的能力。
其次,Tcl是一个库包,可以被嵌入应用程序,Tcl的库包含了一个分析器、用于执行内建命令的例程和可以使你扩充(定义新的过程)的库函数。
应用程序可以产生Tcl命令并执行,命令可以由用户产生,也可以从用户接口的一个输入中读取(按钮或菜单等)。
Tcl和其他编程语言例如C不同,它是一种解释语言而非编译语言。
Tcl程序由一系列Tcl 命令组成,在运行时由Tcl解释器解释运行。
Tcl有大量的用C/C++编写的扩展用于提供Tcl本身不具有的功能。
其中使用最广泛的扩展是TK,TK提供了各种OS平台下的图形用户界面GUI(连强大的Python语言都不单独提供自己的GUI,而是提供接口适配到TK上)。
另一个流行的扩展包是Exp-ect,它提供了通过终端自动执行命令的能力,例如passwd,ftp,telnet等命令驱动的外壳。
一、Tcl程序基本结构1、基本语法Tcl有类似于shell的语法,一条Tcl的命令串包含了一条或多条命令用换行符或分号来隔开,而每一条命令包含了一个域(field)的集合,域使用空白(空格或TAB)分开的,第一个域是一个命令的名字,其它的是作为参数来传给它。
Tcl解释器对一个命令的求值过程分为两部分:分析和执行。
在分析阶段,Tcl解释器运用规则识别出命令并把命令分成一个个独立的单词,同时进行必要的置换(substitution);在执行阶段,Tcl解释器会把第一个单词当作命令名,并查看这个命令是否有定义,如果有定义就激活这个命令对应的C/C++过程,并把所有的单词作为参数传递给该命令过程,让命令过程进行处理。
本文由sunny_test贡献 doc1。
TCL 语言基础资料 一 脚本语言详细介绍 21 世纪的高级编程语言 摘要: 摘要 Perl 和 Tcl 等脚本语言代表一种与 c 或 JavaTM 为代表的系统程序设计语言完全不同的 编程形式. 脚本语言为"胶着"应用程序而设计, 它使用无类型方法来实现高级编程和比系统 程序设计语言更快的发展应用. 计算机速度的增长和混合应用的改变使脚本语言在今后的应 用中越来越重要. 关键字: 关键字 组件框架,面向对象编程,脚本,强类型,系统编程 1.简介 1.简介 在过去的十五年里,人们编写计算机程序的方法发生了根本的转变.这种转变是从 c 或 c++等系统程序设计语言到 Perl 或 Tcl 等脚本语言的过渡.虽然很多人参与了转变,却 很少有人意识到它的发生, 更不用说知道为什么会发生. 这篇文章是我关于为什么在下个世 纪脚本语言可以比系统程序设计语言更好的处理许多编程工作的一点看法. 与系统程序设计语言相比,不同的脚本语言为不同的工作而设计, 这导致了语言间的根本 不同.系统程序设计语言起源于像内存字等最初期的计算机元素,它为建立数据结构和算法 而创建.相反的,脚本语言为胶着而设计:他们假设已经存在一套强大的组件,而它主要是 把组件连在一起. 系统程序设计语言使用强类型定义来帮助处理复杂事务, 而脚本语言使用 无类型定义来简化组件间的联系,并提供快速应用开发. 脚本语言和系统程序设计语言互为补充, 并且二十世纪六十年代以来的大多数主要的计 算机平台都同时提供这两种类型的语言. 这些语言在组件框架中有着典型的应用: 组件由系 统程序设计语言创建, 并由脚本语言组合在一起. 然而, 速度更快的机器, 更好的脚本语言, 图形用户界面和组件构造重要性的不断提高, 因特网的发展等发展趋势大大提高了脚本语言 的应用.在今后的十年中,这种趋势将继续,而且越来越多的完全使用脚本语言和系统程序 设计语言书写的应用程序将主要用来创建组件. 2.系统程序设计语言 2.系统程序设计语言 为了理解脚本语言和系统程序设计语言的不同,最好先了解一下系统程序设计语言是如 何发展的.系统程序设计语言是作为除汇编语言外的另一种选择而引入的.在汇编语言里,实 际上机器的每一个细节都被反映在程序里.每个状态代表一个简单的机器指令,而程序员必 须处理像寄存器分配和程序调用顺序等低层细节.因此,用汇编语言编写和维持大型程序是 很困难的. 二十世纪五十年代后期像 Lisp,Fortran 和 Algol 等高层语言开始出现.这些语言里的状 态和机器指令不再完全一致,编译程序把过程程序中的每个状态翻译成一系列二进制指令. 经过一段时间,一系列系统程序设计语言包括 PL/1,Pascal,C,C++和 Java 由 Algol 发展而来. 系统程序设计语言没有汇编语言的效率高,但他们使应用程序更快的发展起来,因此,系统程 序设计语言在大型应用项目的发展中几乎完全取代了汇编语言. 系统程序设计语言与汇编语言在两个方面有所不同:它是高层语言并且是强类型."高层 "意味着很多细节被自动处理以便编程人员可以写更少的代码而做同样的工作.例如: ★编译程序处理寄存器分配,所以编程人员不需要写代码来在寄存器和内存间转移数据 ★自动设计程序调用顺序:编程人员不需要担心调用栈之间的参数转移 ★编程人员可以使用像 while 和 if 等简单的关键字来控制结构,编译器执行所有的指令细节 来完成控制结构 平均每行系统程序设计语言代码翻译成大约五条机器指令,与此相比,每行汇编语言代 码翻译成一条机器指令(由 5 个不同的人写的 8 个 c 文件的非正式分析中,我发现这个比率为 每行 3 到 7 条指令;Capers Jones 从大量语言的研究中发现对于一个给定的工作,汇编语言 需要的代码长度大约是系统程序设计语言代码长度的 3-6 倍)不管是什么语言,编程人员每 年可以写大体上相同数量的代码行,因此,系统程序设计语言允许用比汇编语言快得多的语 言写应用程序. 汇编语言和系统程序设计语言的第二个不同是类型设置.我使用"类型"来说明信息的意 义在它被使用前就被特殊化.在强类型语言中编程人员声明如何使用每条信息,并避免此信 息被用于其他方式.在弱类型语言中信息应用是没有优先权限制:信息的意思完全由它的使 用方法确定,而不是任何初始约定. 现代计算机基本上是无类型的:内存中的任何字对任何类型的值比如整型,浮点数,指针 或结构体都是有效的.值的意思由它的使用方法确定:如果指向一个内存字,那么他就被认为 是结构体;如果一个字涉及一个整型加结构体,那么他就被认为是整型,如此等等.相同的字 在不同的时间可用于不同的方法. 与此相反,现在的系统程序设计语言是强类型定义的.例如: ★系统程序设计语言中的每个变量都必须被声明为整型或指针或字符串等特殊类型,并且必 须用于适合这种类型变量的方法 ★数据与代码完全分离:创建新的代码很困难或根本不可能. ★变量可以集中在结构体中或者定义好的子结构体和过程或方法的对象中以便于使用;一种 类型的对象不能用于期待其他类型对象处. 确定类型由几个好处.第一,声明变量如何使用使大型程序更易于管理并区分那些必须 被分别对待的变量.第二,编译器可以利用类型信息来侦测某些类型的错误,比如,试图把一 个浮点值作为一个指针.第三,定义类型能使编译器更好的执行特殊代码.例如,如果编译器 知道一个变量总是对整型值有效,那么他就可以产生一个整型指令来操纵这个变量;如果编 译器不知道变量的类型,那么他就必须产生额外的指令在运行时检查变量类型. 总之,系统程序设计语言被设计来处理与汇编语言相同的工作,即随机地产生请求.系统 程序设计语言比汇编语言层次更高,类型更强.这就使请求产生更迅速并且处理更容易,除了 在运行时有一点损失,图示 1 是汇编语言和其他几种系统程序设计语言的比较. 3.脚本语言 3.脚本语言 脚本语言,像 Perl,Python,Rexx,Tcl,Visual Basic 和 Unix shells 代表了与系统程序 设计语言完全不同的编程.脚本语言假设已经存在了一系列由其他语言写成的有用的组件. 脚本语言不希望随机地产生请求,他希望主要是把组件接在一起.例如,Tcl 和 Visual Basic 可以被用于在屏幕上安排一系列用户图形控制,而 Unix shells scripts 被用于把过滤程序 集合入管道.脚本语言常用于扩展组件特性,但他们很少用于复杂的算法和数据结构;这些东 西常由组件提供.脚本语言有时涉及胶着语言或系统整体语言. 为了简化连接组件的工作,脚本语言被设计为无类型的:所有的东西无论是看起来还是 使用起来都是完全一样的,因此他们可以互换.例如,在 Tcl 或 Visual Basic 中一个变量可以 一会儿处理字符串,一会儿又处理整型.代码和数据也常可互换,因此,可以用一个程序写另 一个程序,然后高速执行,脚本语言一般是面向字符的,因为它为许多不同的事物提供了一致 的描述. 无类型语言使组件更容易连在一起.在使用时没有优先级限制,并且所有的组件及其值 都用统一的方式描述.除此之外,任何组件和值都可以在任何情况下使用;为某一目的而设计 的组件可以被用于设计者完全没有预见过的完全不同的目的.例如,在 Unix shells 中,所有 的过滤程序从输入读入字节流,并把字节组成的字符串写入输出;任何两个程序都可以通过 把一个的输出连到另一个的输入而把两者联系起来. 下面的 shell 命令把三个过滤堆在一起来计算选中区域中包含单词"scripting" 的行 数: select | grep scripting | wc select 程序读入当前显示选中的文本并把它输出;grep 程序读取输入并把包含 "scripting"的行输出;wc 程序对输入的行数求和.其中的每个 程序都可以用于许多其他情 况来做不同的工作. 系统程序设计语言的强类型本质上阻止重用.类型鼓励编程人员创建包含不相容接口 的类型("接口很好,接口越多越好").每个接口需要特别类型的对象,而编译器不允许接口使 用任何其他类型的对象,即使那样有用.为了使用一个已经存在的接口的新的对象,就必须写 转换代码以便在对象的类型和接口期望的类型间进行翻译.这反过来又需要重编译部分或全 部分布式二进制形式的应用程序,在普通情况下这是不可能的. 为了能看出无类型语言的优点,考虑下面的 Tcl 命令: button .b -text Hello! -font {Times 16} -command {puts hello} 这个命令创建了一个新的按钮来显示 16 点 Times 字体,当用户敲击控制键时显示一段 小的信息.它把六种不同的类型混合成一个单一的状态:一个命令名(button),一个按钮控制 (.b),所有权名字(-text, -font, 和-command),简单字符串(Hello! 和 hello),包含铅字名 (Times)及字点大小(16)的字体名(Times 16)和 Tcl 脚本(puts hello).Tcl 代表所有这些非 正式字符串.在这个例子中可以在任何一个命令中为属性赋值,而未赋值的属性使用给定的 缺省值.在这个例子中 20 个以上的属性是不特别赋值的. 同样的例子在 Java 中用两种方法执行时需要 7 行代码.使用 C++和微软基本类(MFC) 需要三个过程 25 行代码,在微软基本类中仅仅设置字体就需要几行代码: CFont *fontPtr = new CFont(); fontPtr->CreateFont(16, 0, 0,0,700, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE, "Times New Roman"); buttonPtr->SetFont(fontPtr); 大部分代码是由强类型造成的.为了设置按钮字体,必须运用 SetFont 方法,但这个方法 必须通过指针传给 CFont 对象,这反过来需要声明和初始化一个新的对象.为了初始化 CFont 对象必须唤醒它的 CreateFont 方法,但 CreateFont 有一个需要 14 个特殊化引数的固定接 口.在 Tcl 中字体(Times 铅字,16 点)的基本特征不用声明或转换就可以立即使用.另外,Tcl 允许在创建按钮的命令中直接包含按钮行为,而 C++和 Java 中需要把它放在单独声明的方法 中. (实际上可以用隐藏基本语言的复杂性的图形开发环境处理一个像这样的不重要的例子: 用户在表中输入合适的值,而开发环境输出代码.然而,在更多复杂情况像按计划产生合适值 或接口的条件任务中开发人员必须在基本语言下编写代码) 这可能看起来脚本语言的无类型特性不能发现错误,但实际上脚本语言和系统程序设计语言 一样安全.例如在上面的按钮例子中如果字体大小被置成非整型字符串,就像 xyz,那么就会 出现错误.不同的是当一个值被使用时脚本语言在最后一刻进行错误检查,而强类型在编译 时发现错误这就避免了运行时的检查.然而提高效率的代价是限制信息如何使用:这导致了 更多的代码和更不易改变的程序. 脚本语言和系统程序设计语言的另一个重要不同是脚本语言是被解释而系统程序设计 语言是被编译.被解释的语言由于没有编译时间而提供快速的转换.通过允许用户运行时编 写应用程序,解释器使.应用程序更加灵活,例如,许多整体线路的综合分析工具,包括 Tcl 解 释器;程序用户编写 Tcl 脚本来使他们的设计具体化并控制工具操作.通过快速设计代码解 释器可以实现强大的功能.例如,一个基于 Tcl 的网页浏览器可以通过把网页中的 HTML 转换 为使用一些常规表达替代物的 Tcl 脚本,从而从语法上分析网页然后执行脚本把页面翻译显 示在屏幕上. 脚本语言不如系统程序设计语言效率高,部分是因为他们使用解释器而不是编译器,而且 因为他们基本组件的选择标准是功能强大和易于使用而不是有效地对应基本硬件.例如,脚 本语言经常使用长度可变的字符串,而同样的情况下系统程序设计语言使用对应一个机器字 的二进制值;脚本语言经常使用哈希表,而系统程序设计语言使用变址阵列. 幸运的是,脚本语言的性能不经常是一个主要的问题.脚本语言应用程序通常比系统程 序设计语言的应用程序要小,并且脚本应用程序的执行受组件执行的支配,而这些组件是系 统程序设计语言提供的典型工具. 脚本语言比系统程序设计语言更高级,平均一个指令可以做更多的工作.一个典型的脚 本语言指令执行成百上千条机器指令,而一个典型的系统程序设计语言指令执行大约五条机 器指令(参图一).部分不同是因为脚本语言使用翻译器,这不如系统程序设计语言中被编译 的代码.但是主要的不同是因为脚本语言的初期操作有更强大的功能.例如,Perl 中唤醒一 个常规表达替代和唤醒一个整型加法一样简单.在 Tcl 中,变量会有与它相联系的图标,因此, 设置变量会导致侧面影响.例如,一个图标可能会被用于保持变量的值在屏幕上持续更新. 表 1.表的每行描述了被执行了两遍的应用程序,一遍使用系统程序设计语言,像 C 或 Java, 一遍使用脚本语言,像 Tcl.代码率列给出了两个应用程序的代码行率(>1 意味着系统编程语 言需要更多的代码),作用率列给出了开发率.在大多数情况下两个版本由不同的开发者执行. 表中的信息由 comp.lang.tcl 新闻组中对文章进行答复的不同人提供.. 由于上面描述的特性,脚本语言允许基于胶着的应用程序的快速发展.表 1 提供了有趣 的支持.它描述了几个在系统程序设计语言下执行后又在脚本语言中重新执行的应用程序, 或反过来也是一样的. 在每种情况下脚本版本都比系统编程版本需要更少的代码和更短的开发时间,不同点的 变化从 2 到 60.脚本语言第一次执行时好处不显著,这使人联想到任何在第一次执行经验上 的重执行都会更好,而脚本和系统编程的真正不同相差 5 到 10 倍,而不是表中的极端点.脚本 的好处同样依赖于应用程序.在表中的最后一个例子中,应用程序的图形用户界面部分是基 于胶着的,而模拟装置部分却不是;这可能解释为什么脚本应用程序不如其他应用程序获益 多. 总之,脚本语言被设计成胶着应用程序,他们提供比汇编或系统程序设计语言更高层的 编程,比系统程序设计语言更弱的类型,和解译后的开发环境.脚本语言牺牲执行速度来提高 开发速度. 4.不同的任务, 4.不同的任务,不同的工具 不同的任务 脚本语言不是系统程序设计语言的替代品,反过来也一样.他们各自适合不同类型的工 作.把胶着和系统合为一体,应用程序可以比脚本语言快 5-10 倍;系统程序设计语言将需要 大量复本和转换代码来连接各块.而这直接使用脚本语言.对于复杂的算法和数据结构,系统 程序设计语言的强类型使程序更易于管理.执行速度是关键.系统程序设计语言可以比脚本 语言运行快 10-20 倍,因为它产生更少的运行时检查. 在决定是否使用脚本语言或系统程序设计语言处理一项特殊任务时考虑以下问题: ★应用程序的主要工作是否是把已经存在的组件联系起来 ★应用程序是否要操纵不同种类类型的事物 ★应用程序是否包含图形用户界面 ★应用程序是否做大量字符串操作 ★应用程序函数是否能快速解决问题 ★应用程序是否需要可扩展 如果这些问题回答"是"就表明这个应用程序使用脚本语言会更好.另一方面,如果对下 面的问题回答"是"就表明系统程序设计语言更适合这个应用程序: ★应用程序是否执行复杂的算法或数据结构 ★应用程序是否操纵大量数据集(像图像中的所有像素)因而执行速度很重要 ★应用程序的函数是否已经定义好,并且很少改动 在过去的 30 年中,大多数主要的计算机平台同时提供系统编程和脚本语言. 例如, 第一 个脚本语言虽然粗糙, 却是一个 JCL(作业控制语言),它被用于在 OS/360 中把工作等级按顺 序排好.个别工作等级由 PL1,Fortran 或汇编语言书写,那时是系统程序设计语言.在二十 世纪八十年代时 Unix 机器上,c 被用于系统编程而 sh,csh 等壳编程被用于脚本.在二十世 纪九十年代的 PC 时代里,c 和 c++被用于系统编程 e 而 Visual Basic 用于脚本.在现在已 基本成形的网络时代中,Java 被用于系统编程而像 JavaScript , Perl 和 Tcl 等语言被用 于脚本. 脚本和系统编程是共生的,共同使用,他们能产生格外强大的编程环境:系统程序设计 语言用于产生令人兴奋的组件,然后用脚本语言把他们组装起来.例如,Visual Basic 的 主要吸引力是系统编程者可以用 c 编写 ActiveX 组件,而不太老练的编程者可以在 Visual Basic 应用中使用这些组件. Unix 下编写用于唤醒用 c 编写的应用程序的壳脚本很容易. 在 Tcl 普及的一个原因是可以编写执行新命令的 c 代码来扩展该语言的能力. 5.脚本呈上升趋势 脚本语言已经存在了很长时间,但最近几年几个因素的综合结果使它的重要性提高了. 最重要的因素是应用程序综合向胶着应用程序发展的变换. 这种变换的三个实例是图形用户 界面,因特网和组件框架. 图形用户界面出现于二十世纪八十年代早期, 并在二十世纪八十年代晚期得以普及. 在 许多编程项目中图形用户界面占了一半甚至更多的比重. 图形用户界面基于胶着应用: 他的 目标不是创建新的功能, 而是把图形控制集合和应用程序内部函数联系起来. 我不担心任何 快速发展的环境因为图形用户界面基于系统程序设计语言, 不论是 Windows 环境,Macintosh Toolbox 或 Unix Mctif,图形用户界面基于 c 或 c++等已被证明难以掌握,使用不灵活,生 成结果不灵活的语言.一些这样的系统有很好的图形工具来设计屏幕输出并隐藏基本语言, 而一旦设计者不得不编写代码时一切变得困难起来, 像为接口元素提供行为. 所有好的快速 开发图形用户界面环境都基于脚本语言:Visual Basic,Hyperlard 和 Tcl/tk,随着图形用 户界面的普及,脚本语言也越来越流行. 因特网的增长也使脚本语言变得大众化. 因特网只是一种胶着工具, 它不创建任何新的 计算结果或数据; 它只是简单的把大量已经存在的事物联系起来. 因特网编程工作的完美工 作之一是让所有连接的组件在一起工作,像脚本语言.例如:Perl 因编写 CGI 脚本而流行, JavaScript 因编写网页而流行. 基于脚本的第三个例子是组件框架,像 ActiveX,OpenDoc 和 JavaBeans.虽然系统程序 设计语言可以很好的创建组件, 但脚本更适合组装组件到应用程序中. 没有一个好的脚本语 言来操纵组件, 组件框架的大部分功能就都没有了. 这可以部分解释为什么组件框架在个人 电脑上(Visual Basic 提供了方便的脚本工具)比在像 Unix/CORBA 等组件框架中不包含脚 本的平台上更成功. 脚本语言继续普及的另一个原因是脚本技术的提高.现代脚本语言像 Tcl 和 Perl 离早 期脚本语言像 JCL 的公开宣布已经很远.例如,JCL 不提供基本反复而早期 Unix 外壳不提 供过程,即使在今天,脚本技术仍然相对不成熟.例如,Visual Basic 不是真正的脚本语 言:它最初执行像一个简单的系统程序设计语言,然后修改使之更适合脚本.以后的脚本语 言将比现在使用的更好. 脚本技术得益于计算机硬件的加速发展. 过去常常用系统程序设计语言在复杂的应用程 序中获得可接受的执行. 某些情况下甚至系统程序设计语言也不够有效, 因此不得不用汇编 编写应用程序.然而,今天的机器比 1980 年的快 100-500 倍,并且仍在继续以每 18 个月翻 一番的速度增长.今天,许多应用程序可以用解释后的程序执行,并且仍然有出色的执行. 例如,Tcl 脚本可以操纵几千个对象同时提供好的相互响应.由于计算机速度的不断提高, 脚本将对越来越大的应用程序产生吸引力. 脚本语言应用的不断增长最终导致编程群体的改变.二十年前大多数编程者是大型项目 的熟练的编程人员.那个时代的编程人员需要花几个月的时间掌握一门语言和它的编程环境, 系统程序设计语言就是为这些人设计的.然而,自从个人电脑出现以后,越来越多的非专业编 程者加入到编程者的行列.对这些人来说,编程不是他们的主要工作,而只是他们偶尔用来帮 助他们工作的工具.偶然编程的例子是简单的数据库查询或者是巨大的扩展片.偶然编程者 不希望花几个月的时间学习系统程序设计语言但他们可以花几个小时的时间学到足够的脚 本语言知识来写出有用的代码.由于脚本语言由简单的句法并且省略了对象线程等复杂的特 性,因而它比系统程序设计语言要容易学.例如,比较 Visual Basic 和 Visual C++,很少有偶 尔编程者会选择 Visual C++,而大部分会用 Visual Basic 建立有用的应用程序. 即使在今天,用脚本语言编写的应用程序的数目也远多于用系统程序设计语言编写的应 用程序的数目.在 Unix 系统中有比 C 程序更多的外部脚本,而在 Windows 下 Visual Basic 的编程者和应用程序都比 C 或 C++的要多.当然,多数大型和广泛使用的应用程序都是用系统 程序设计语言写成的,所以,如果比较代码总行数或是建立的副本数,则系统程序设计语言略 胜一筹.不管怎么样,脚本语言已经是应用程序开发的主动力,并且今后它的市场份额会继续 提高. 6.对象的作用 6.对象的作用 脚本语言在编程语言和软件工程中通常被专家忽视.取而代之,他们更注重像 C++和 Java 等面向对象系统程序设计语言.面向对象编程被认为是代表下一步编程语言发展的主流.像 强类型和继承等面向对象 特征 据说可以减少开发时间,提高软件重用率,并解决包括脚本 语言技巧等其他问题. 面向对象编程实际能提供多少好处?不幸的是,我还没有看到足够的数据可以确切地回答 这个问题.在我看来,对象只能提供一定的好处:或许能提高 20-30%的创作力,但决不会有两 倍,更不用说是十倍.现在抱怨 C++的和喜欢它的一样多,并且一些语言专家开始公开反对面 向对象编程.这一段剩下的部分用于解释为什么对象不能像脚本一样显著地提高创作力,并 讨论脚本语言中可以获得的面向对象编程的好处. 面向对象编程不能显著提高创作力的原因是他没有提高编程层次或鼓励重用.像 C++等面 向对象语言中编程者仍然使用需要用大量细节来描述和操纵的基本的小单元工作.理论上可 以开发强大的函数库包,并且如果这些函数库被广泛使用就将提高编程层次.然而,这样的函 数库却很少.大多数面向对象语言的强类型使包的定义受限制从而难以重用.每个包都需要 特殊类型的对象,如果两个包在一起工作,就必须写转换代码在两个包需要的类型间进行翻 译.面向对象语言的另一个问题是他们强调继承.当一个类借用为另一个类写的代码时执行 继承并不是一个好主意,它使软件难以管理和重用.它把类的执行绑在一起,因而没有另外一 个类任何一个其它类都不可理解:不知道其继承的方法在父类中如何执行,则无法理解子类; 而不知道其方法如何被子类继承,则无法理解父类.在一个复杂的类继承中,不理解它所继承 的所有其他的类就无法理解任何一个类.更糟的是,一个类无法从它继承的类中被分离以用 于重用.多重继承使这个问题变得更麻烦.执行继承导致和 goto 语句被重复执行时所看到的 一样的交错和不可靠.因此,面向对象系统经常不能处理复杂问题并缺少重用. 另一方面,脚本语言实际引起了有效的软件重用.在有趣的组件由系统程序设计语言建立 使他们使用了模块,随后用脚本语言把他们胶着在应用程序中.这种劳动的分割提供了为重 用的自然的框架结构.组件被设计为可重用的组件和脚本间有定义好的接口以利于组件的使 用.例如,在 Tcl 中组件是 C 中执行的常规命令.他们看起来更象是内在的命令,因而更容易在 Tcl 脚本中使用.在 Visual Basic 中组件是 ActiveX 的扩展,可用于从工具面板直接拖到窗 体中. 不管怎么样,面向对象编程至少提供了两个有用的特性.第一个是封装:对象用某种隐藏执行 细节的方法把数据和代码联系起来.这使管理大型系统更加容易.另一个有用的特性是接口 继承,这涉及提供同样方法的类和 APIs,即使他们有不同的执行,这时类之间可以相互转化, 从而鼓励重用. 幸运的是,对象的这些好处在脚本语言中可以像在系统程序设计语言中一样实现,并且所 有的脚本语言都提供面向对象编程.例如,Python 是面向对象脚本语言,Python 第五版包括 提供对象,Object Rexx 是 Rexx 的面向对象版本,而 Incr Tcl 是 Tcl 的面向对象版本.有一 点不同是,脚本语言中的对象事物类型的,而系统程序设计语言中的对象是强类型的. 7.其他语言 7.其他语言 这篇文章不是所有编程语言的全部特性记述.除了类型长度和编程层次以外还有许多编 程语言的其他特性,并且还有许多不能被明确定义为系统程序设计语言或脚本语言的其他有 趣的语言.例如,Lisp 系统的语言就处于脚本语言和系统程序设计语言之间,两方的特性它 都。