第一讲
由于要用NS2做仿真但网上这方面资料又不够齐全,所以就在当当网上订购了一本方路平主编的《NS-2网络模拟基础与应用》。刚把前两章内容看完发现里面有不少错误,在阅读过程中还发现书中的有些语言不够简练,不易于理解,所以为了更好地学习也为了以后查阅方便,将阅读过程中读到的知识点做个总结(就称为Reading Notes on NS2吧),望能够快速地掌握它。 [1] Tcl命令格式
基本的Tcl命令格式为:Command arg1 arg2 arg3 ... 例如:
% puts stdout {Hi,I am wcdj!} ;#%是NS2系统的提示符 Hi,I am wcdj! #输出 [2] 变量
Tcl中的变量名由字母、数字、下划线组成。 注意:
(1)变量名第一个字母可以是数字; (2)变量名长度没有限制; (3)变量名区分大小写;
(4)Tcl中在使用变量之前不需要事先声明; (5)$符号用来取变量的值; [3] Tcl关键字 有17个
argc argv argv0 embed-args env
tcl_interactive tcl_library tcl_patchlevel tcl_platform tcl_promptl tcl_prompt2 tcl_vesion auto_path auto_index auto_noload auto_noexec geometry [4] set命令
用来给变量赋值:set 变量名 变量值 注意:
(1)如果set命令后直接跟一个参数,则返回的是这个变量的值; 例如:
% set var1 a ;#给变量var1赋值为a a
% set var2 $var1 ;#把var1的值赋给变量var2 a
% set var1 ;#返回变量var1的值 a
[5] unset命令
用来删除变量:unset var1 var2 ... 注意:
(1)一条unset命令可以删除任意多个变量; (2)如果删除没有定义的变量,解释器将报错; [6] info命令
用来查看变量是否存在。 例如:
if {![info exists foobar]}{ ;#查看变量foobar是否存在 set foobar 0 }else{
incr foobar }
[7] 替代 (1)字符替代
$符号用来取变量的值; (2)命令替代
[]中的命令为嵌套命令,返回的执行结果作为上一层命令的参数,如果在一条命令中包含多个[],解释器按照从左到右的顺序执行; 例如:
% set len [string length foobar] ;#string length返回字符串的长度 6
(3)反斜杠替代
/符号用在特殊字符之前表示字符本身,使特殊字符失去特殊的功能; 例如:
“/$”表示“$”本身 注意:
(1)/符号还可以作为续行符(类似C/C++中); [8] 组合
双引号\和大括号{}可以把多个以空格为分隔符的字符串组合在一起作为一个命令。(但是有区别) 注意:
(1)双引号在组合体中允许进行替代; (2)大括号在组合体中不允许进行替代; 例如:
% set s Hello Hello
% puts stdout \ The length of Hello is 5. 如果换成{},则输出
% puts stdout {The length of $s is [string length $s].} The length of $s is [string length $s]. [9] 格式化输出
format命令用来格式化输出。 例如:
% puts [format \ 注意:
(1)在Tcl中,puts自动在末尾添加一个换行符。 [10] 组合和代替的总结
(1)执行顺序一般先组合后代替;
(2)Tcl需要决定如何组织命令参数;(最简单的是,所有参数都由空格分开,另外{}或者\可以把多个参数当做一个简单的参数)
(3)在{}中不进行替代;
(4)在\中可进行替代;(在\中嵌套\时,必须使用/\表示) [11] 数学运算
expr命令把运算表达式作为一个字符串传给解释器,解释器运算完成后把值转换成字符串并返回给Tcl脚本。 例如:
% expr 7.2/4 1.8
% set len [expr[string length foobar]+7] 13 注意:
(1)if语句内部嵌入了expr命令,所以在它的布尔表达式中并不需要显示调用expr命令; 例如:
if{$answer==\[12] 过程
Tcl中用proc来定义过程,概念跟C语言中的函数类似。(过程一旦被定义,就可以像内置命令那样使用)
基本的命令格式为:proc name arglist body 例如:
#定义了一个三角形中根据两边长度求第三边长度的过程; #sqrt是expr支持的数学函数;
#变量c是过程中的局部变量,只在过程体内有效(变量的作用域和C语言中的概念相同); #return的作用是返回过程的结果; proc Diag {a b} {
set c [expr sqrt($a*$a+$b*$b)] return $c }
#上面过程可以简化为如下 proc Diag {a b} {
return [expr sqrt($a*$a+$b*$b)] }
% puts \ the diagonal of a 3,4 right triangle is 5 [13] 流程控制命令 (1)条件命令 if、swtich (2)循环命令
while、foreach、for (3)错误捕获命令 catch
(4)结构调整命令
break、continue、return、error 注意:
(1)在if、while、for命令中,都内嵌了expr命令。(所以不用显示调用expr命令)
[14] if条件命令
基本格式为:if expression then body1 else body2 ;#关键字then可以省略 例如: if{$x==0} {
puts stderr \ }else{
set slope [expr $y/$x] }
#下面是一个包含elseif控制的例子 if{$key<0} {
incr range 1 }elseif{$key==0} { return $range }else{
incr range -1 }
[15] switch控制命令
基本格式为:switch flags expression pat1 body1 pat2 body2...default bodyn
flags的取值为三种:-exact、-glob、-regexp。(flags值可以省略,其默认值为-exact) (1)-exact精确匹配(表达式的值和需要匹配的值必须完全相同) switch -exact -- $grade{ A {puts \ B {puts \ C {puts \ default {puts \ }
(2)-glob通配符匹配,字符串中*表示任意字符串,使用?表示任意单个字符。 #如果value的值以X字母开头,则执行第一个过程体 switch -glob -- $value{ X* {puts \ Y* {puts \ }
(3)-regexp正则表达式匹配
#body1执行的条件是变量value的取值末尾为“er”,body2的执行条件是value的开头必须是tab键
switch -regexp -- $value/ ^er {body1}/ /t###{body2}/ {[0-9]*}{body3} [16] for循环命令
基本格式为:for initial test final body 例如:
for {set i 0} {$i<5} {incr i} { set sum [expr $sum+$i]
}
[17] foreach循环命令
基本格式为:foreach loopVar valueList commandBody 例如:
#用{}建立列表 set i 0
foreach value {1 2 3} { set i [expr $i*$value] }
#用list建立列表 set a 1 set b 2
foreach value [list $a $b[string length foo]] { set i [expr $i*$value] }
[18] while命令
基本格式为:while boolExpr body #求解自然数阶乘的例子 proc Factorial {x} {
set i 1; set product 1 ;#分号的作用相当于换行 while{$i<=$x} {
set product [expr $product*$i]
incr i ;#incr命令是让变量每次加1,等价于set i [expr $i+1] }
return $product }
% Factorial 10 3628800
[19] catch命令
catch命令用于捕获运行时的错误。catch递归地调用Tcl解释器来执行脚本,如果脚本中有一个错误,catch将返回一个非零的整数值,对应于一个异常返回代码。如果脚本没有任何错误,catch将返回0(TCL_OK)并设置这个变量为脚本返回的值。 基本格式为:catch command resultVar 例如:
if{[catch { open $someFile w} fid] } {
puts stderr \ exit 1 }
[20] break、continue和return命令 break退出循环;
continue跳过本次循环继续执行下次循环;