ImageVerifierCode 换一换
格式:DOC , 页数:27 ,大小:42.50KB ,
资源ID:4878177      下载积分:10 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.docduoduo.com/d-4878177.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录   微博登录 

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(TCL语言基础教程.doc)为本站会员(weiwoduzun)主动上传,道客多多仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知道客多多(发送邮件至docduoduo@163.com或直接QQ联系客服),我们立即给予删除!

TCL语言基础教程.doc

1、1TCL 语言基础教程导读:就爱阅读网友为您分享以下“TCL 语言基础教程”资讯,希望对您有所帮助,感谢您对 的支持!Tcl 语言参考 Tcl(“Tool Command Language”,即工具命令语言; Tcl 念作 “踢叩” “tickle” )是一种易学易用易 于扩展的脚本语言,实际上包 含了两个部分:一个语言和一个库。 首先,Tcl 是一种简单的脚本语言,主要使用于发布命令给一些交互程序如文本编辑器、调 试器和 shell。它有一个简单 的语法和很强可扩充性, Tcl 可以创建新的过程以增强其内建命令的能力。 其次,Tcl 是一个库包,可以被嵌入应用程序,Tcl 的库包含了一个分

2、析器、用于执行内建命 令的例程和可以使你扩充 (定义新的过程)的库函数。应用程序可以产生 Tcl 命令并执行,命令可以由用户产生,也 可以从用户接口的一个输入中读 取(按钮或菜单等) 。Tcl 和其他编程语言例如 C 不同,它是一种解释语言而非编译语言。Tcl 程序由一系列 Tcl 命令组成,在运行时由 Tcl 解释 器解释运行。Tcl 有大量的用 C/C+编写的扩展用于提供 Tcl 本身不具有的功能。其中2使用最广泛的 扩展是 TK,TK 提供了各种 OS 平台下 的图形用户界面 GUI(连强大的 Python 语言都不单独提供自己的 GUI,而是提供接口适配到 TK 上)。另一个流行的扩展

3、包是 Expect,它提供了通过终端自动执行命令的能力,例如 passwd, ftp, telnet 等命令驱动的外壳。3一、Tcl 程序基本结构 1、基本语法 Tcl 有类似于 shell 的语法, 一条 Tcl 的命令串包含了一条或多条命令用换行符或分号来隔开, 而每一条命令包含了一个 域(field)的集合,域使用空白(空格或 TAB)分开的,第一个域是一个命令的名字,其它的 是作为参数来传给它。 Tcl 解释器对一个命令的求值过程分为两部分:分析和执行。在分析阶段,Tcl 解释器运用 规则识别出命令并把命令分 成一个个独立的单词,同时进行必要的置换(substitution); 在执行

4、阶段,Tcl 解释器会把第 一个单词当作命令名,并查看这 个命令是否有定义, 如果有定义就激活这个命令对应的 C/C+过程, 并把所有的单词作为参 数传递给该命令过程,让命令过 程进行处理。Tcl 的 命 令 名 可 以 是 内 建 的 命 令 也 可 以 是 用 户 建 的 新 命 令 , 在 应 用 程 序 中 可 用 函 数 Tcl_CreateCommand 来创建新的命令。 所有的参数作为字符串来传递,命令自己会按其所需来解释的参数的。另外关于 Tcl 的注释有一个特殊的要求: 必须出现在 Tcl 解释器期望命令的第一个字符出 现的地方,才被当作注释。 例如: set a 100 #

5、 Not a comment4set b 101 ; # this is a comment 第一个例子中#及其后面的内容会被当作 set 的参数而非注释从而导致参数个数错误;但第 二个被解释为注释,因为 #前面有一个分号,而分号和换行一样被看作是命令的分隔符。脚步命令: (1)eval 命令 eval 命令是一个用来构造和执行 TCL 脚本的命令,其语法为: eval arg arg . 它可以接收一个或多个参数, 然后把所有的参数以空格隔开组合到一起成为一个脚本, 然后 对这个脚本进行求值。 (2)source 命令 source 命令读一个文件并把这个文件的内容作为一个脚本进行求值。例如

6、: source e:/tcl&c/hello.tcl 注意路径的描述应该和 UNIX 相同,使用/ 而不是 。2、置换( Substitution)set x 10 set y 100 + x上面命令执行后,y 的值是“100 + x”而不是我们期望的110。这是因为 Tcl 解释器在分析命令 时,把所有的命令参数都当作5字符串看待,所以 x 被看作了字符串 “100 + x”的一部分。如果我们想使用 x 的值10 ,就 必须告诉 Tcl 解释器:我们在这里期望的 是变量 x 的值,而非字符x。怎么告诉 Tcl 解释器呢,这就要用到 Tcl 语言中提供的置换功 能。 Tcl 提供三种形式的置

7、换:变量置换、命令置换和反斜杠置换。每种置换都会导致一个或多 个单词本身被其他的值所代替。置换 可以发生在包括命令名在内的每一个单词中,而且置换可以嵌套。 (1)变量置换(variable substitution) 变量置换由一个符号标记,变量置换会导致变量的值而非变量(标识符)本身被插入到字 符串中。set x 10 set y 100 + $x 这时,y 的值还不是我们想要的值110,而是 10+100,因为 Tcl 解释器把 10+100 看成是一个 字符串而不是表达式;y 要想得到值 110,还必须用命令置换,使得 Tcl 会把 10+100 看成一个表达式并求值。(2)命令置换(c

8、ommand substitution) 命令置换是由括起来的 Tcl 命令及其参数,命令置换会导致某一个命令的所有或部分单词 (参数)被另一个命令的结果所代替。set x 10 set y expr 100+$x6这时,y 的值就是 110 了。这里当 Tcl 解释器遇到字符时,它就会把随后的 expr 作为一个命 令名,从而激活与 expr 对应的 C/C+过 程,并把 expr 命令中变量置换后得到的10+110 传递给该命令过程进行处理。 注意, 中必须是一个合法的 Tcl 脚本,长度不限。中脚本的值为最后一个命令的返回值, 例如:有了命令置换, 实际上就表示命令之间是可以嵌套的, 即

9、一个命令的结果可以作为别的命令 的参数。 (3)反斜杠置换( backslash subtitution) Tcl 语言中的反斜杠置换类似于 C 语言中反斜杠的用法,主要用于在单词符号中插入诸如换 行符、空格、$等被 Tcl 解释器当作 特殊符号对待的字符。例如: set msg multiple space 如果没有的话,Tcl 会报错,因为解释器会把这里最后两个单词之间的空格认为是分隔符,于是发现 set 命令有多于两个参数, 从而报错。加入了后,空格不被当作分隔符, multiple space被认为是一个单词(word)。 (4)双引号和花括号 除了使用反斜杠外,Tcl 提供另外两种方

10、法来使得解释器把分隔符和置换符等特殊字符当作 普通字符,而不作特殊处理,这就 要使用双引号和花括号()。 Tcl 解释器对双引号中的各种分隔符将不作处理,但是对换行符及和两种置换符会照常 处理。而在花括号中,所有特殊字符 都将成为普通字7符,失去其特殊意义,Tcl 解释器不会对其作特殊处理。8二、Tcl 变量数据类型 Tcl 只支持一种数据类型:字符串(string) 。所有的命令,命令的所有的参数,命令的结果, 所有的变量都是字符串。请牢记 这一点,所有的东西都是字符串。 (然而字符串的实际解释是依赖于其所处上下文。它有三 种形式:命令 , 表达式和表) 。Tcl 变量根据其结构的复杂程度分

11、为“简单变量”和“数组变量”两类。(1)简单变量 一个 Tcl 的简单变量包含两个部分:名字和值,其中名字和值都可以是任意字符串。不过为 了更好的使用变量置换功能,变量名 最好按 CC+语言中标识符的命名规则命名。这是因为 Tcl 解释器在分析一个变量置换时, 只把从符号往后直到第一个不是字母、数 字或下划线的字符之间的单词符号作为要被置换的变量的名字。例如: set a 2 set a.1 5 set b $a.1 在最后一个命令行,我们希望把变量 a.1 的值付给 b,但是 Tcl 解释器在分析时只把$符号之 后直到第一个不是字母、数字或下划线 的字符(这里是.)之间的单词符号 (这里是a

12、) 当作要被置换的变量的名字,所以 Tcl 解释器把 a 置换成 2,然后把字符串“2.1”付给变量 b。这9显然与我们的初衷不同。 当然,如果变量名中有不是字母、数字或下划线的字符又要用变量置换,可以用花括号把变 量名括起来。例如: set b $a.1(2)数组变量 数组是一些元素的集合。Tcl 的数组和一般编程语言中的数组有很大的区别。在 Tcl 中,不 能单独声明一个数组,数组只能和数组 元素一起声明。数组中数组元素的名字包含两部分:数组名和数组中元素的名字,Tcl 中数 组元素的名字(下标可以为任何字符串。 例如: set day(monday) 1 set day(tuesday)

13、 2(3)重用结构及其操作 1、string 结构及其操作 因为 TCL 把所有的输入都当作字符串看待,所以 TCL 提供了较强的字符串操作功能【format】 语法:format formatstring vlue value.format 命令类似于 ANSIC 中的 sprintf 函数,它按 formatstring 提供的格式,把各个 value 的 值组合到 formatstring 中形成一 个新字符串,并返回。例如: set msg format “%s is %d years old” $name $age10【scab 】 语法:scanstring formatsting

14、 varName varName .scan 命 令可 以认 为是 format 命 令的 逆, 其功 能类 似 于 ANSI C 中 的 sscanf 函 数。 它按 formatsting 提供的格式分析 string 字 符串,然后把结果存到变量 varName 中,注意除了空格和 TAB 键之外,string 和 formatsting 中的字符和%必须匹配。例如: scan “some 26 34” “some %d %d” a b【regexp 】 语法:regexp switchs - exp string matchVar subMatchVar subMatchVar.reg

15、exp 命令用于判断正规表达式 exp 是否全部或部分匹配字符串 string,匹配返回 1,否则 0。 regexp 可以设置一些开关(switchs ,来控制匹配的具体方式,如:-nocase,-line 等,其中 - 表示这后面再没有 开关( switchs了,即使后面有以-开头的参数也被当作正规表达式的一部分。 如果 regexp 命令后面有参数 matchVar 和 subMatchVar,则所有的参数被当作变量名,如果 变量不存在,就会被生成。 regexp 把匹配整个正规表达式的子字符串赋给第一个变量, 匹配正规表达式的最左边的子表 达式的子字符串赋给第二个变 量,依次类推,例如

16、: regexp (0-9+) *(a-z+) “ there is 100 apples” total num word 1 puts “ $total ,$num,$word” 显示结果为:100 apples ,100,apples11其他具体的正则表达式规则请参考 Tcl 语言手册【regsub】 语法: regsub switchs exp string subSpec varnameregsub 的第一个参数是一个整个表达式,第二个参数是一个输入字符串,这一点和 regexp 命令完全一样,也是当匹配 时返回 1,否则返回 0。不过 regsub 用第三个参数的值来替换字符串 st

17、ring 中和正规表达式匹 配的部分,第四个参数被认为是 一个变量,替换后的字符串存入这个变量中。例如: regsub there “They live there lives “ their x puts $x 显示结果为:They live their lives【sting 】 语法:string subcmd arg arg.string 命令具有强大的操作字符串的功能,并通过其中的 subcmd 来区别具体将要执行的 string 操作。他们中的一些如下: string length string string range string first last string index

18、 string charIndex string tolower string first last string replace string first last newstring string equal -nocase -length int string1 string212string match -nocase pattern string 如果 pattern 匹配 string,那么返回 1,否则返回 0. 如果有 -length 参数, 那么只比较前 intstring compare -nocase -length int string1 string2 个字符 str

19、ing first string1 string2 startindex 在 string2 中从头查找与 string1 匹配的字符序列,如果 找到,那么就返回 匹配的第一个字母所在的位置 (0-based)。如果没有找到,那么返回-1。 string trim string chars 返回值为:从 string 字符串的首尾删除掉了字符集合 chars 中的字符 后的字符串。如果没有 给出 chars,那么将删除掉 spaces、tabs 、newlines 、carriage returns 这些字符 .2、list 结构及其操作 list 这个概念在 TCL 中是用来表示集合的。TC

20、L 中 list 是由一堆元素组成的有序集合,list 可以嵌套定义,list 每个元素可以是 任意字符串,也可以是 list。Tcl 提供了很多基本命令对 list 进行操作:【list】 语法:list value value.这个命令生成一个 list,list 的元素就是所有的 value【concat】 语法:concat list list.这个命令把多个 list 合成一个 list.13【llength】 语法: llength list 返回 list 的元素个数。【lindex】 语法:lindex list index 返回 list 的第 index 个(0-based

21、)元素。 【lrange】 语法:lrange list first last 返回 list 的第 first (0-based)到第 last (0-based)元素组成的串,如果 last 的值是 end。就是从第 first 个直到串的最后。【linsert】 语法:linsert list index value value.?返回一个新串,新串是把所有的 value 参数值插入 list 的第 index 个(0-based)元素之前得到。 【lappend】14语法:lappend varname value value.?把每个 value 的值作为一个元素附加到变量 varn

22、ame 后面, 并返回变量的新值, 如果 varname 不存在,就生成这个变 量。【lreplace】 语法:lreplace list first last value value .返回一个新串,新串是把 list 的第 firs (0-based)t 到第 last 个(0-based)元素用所有的 value 参 数替换得到的。如果没有 value 参数,就表示删除第 first 到第 last 个元素。【lsort 】 语法:lsort options? list 这个命令返回把 list 排序后的串。options 可以是如下值: -ascii 按 ASCII 字符的顺序排序比较

23、.这是缺省情况。 -dictionary 按字典排序,与-ascii 不同的地方是: (1)不考虑大小写 (2)如果元素中有数字的话,数字被当作整数来排序.【lsearch】15语法:lsearch -option list pattern 返回 list 中第一个匹配模式 pattern 的元素的索引, 如果找不到匹配就返回-1。 option 取-exact、 -glob、 -regexp 是三 种模式匹配的技术,缺省时使用-glob 匹配。 【join】 语法:join list joinString这个命令把 list 的所有元素合并到一个字符串中,中间以 joinString 分开。

24、缺省的 joinString 是空格。【split】 语法:split string splitChars把字符串 string 按分隔符 splitChars 分成一个个单词,返回由这些单词组成的串。如果 splitChars 是一个空字符 , string 被按字符分开。如果 splitChars 没有给出,以空格为分隔符。3、file 结构及其操作 TCL 提供了丰富的文件操作的命令。通过这些命令你可以对文件名进行操作(查找匹配某一 模式的文件)、以顺序或随机 方式读写文件、检索系统保留的文件信息(如最后访问时间)。163.1 基本文件 I/O pwd 和 UNIX 下的 pwd 命令完

25、全一样,没有参数,返回当前目录的完整路径。 cd 命令也和 UNIX 命令也一样,使用一个参数,可以把工作目录改变为参数提供的目录。以下这个名为 tgrep 的过程,可以说明 TCL 文件 I/O 的基本特点: proc tgrep pattern filename set f open $filename r while gets $f line if regexp $pattern $line puts stdout $line close $f open 命令返回一个字符串用于表识打开的文件。当调用别的命令(如:gets,puts,close, 对 打开的文件进行操作 时,就可以使用这个

26、文件标识符。TCL 有三个特定的文件标识: stdin,stdout 和 stderr ,分 别对应标准输入、标准输出和 错误通道,任何时候你都可以使用这三个文件标识。3.2 随即文件访问 默认文件输入输出方式是连续的:即每个 gets 或 read 命令返回的是上次 gets 或 read 访问 位置后面的字节,每个 puts 命令写数据是接着上次 puts 写的位置接着写。 TCL 提供了 seek,tell 和 eof 等命令使用户可以17非连续访问文件。 每个打开的打开文件都有访问点,即下次读写开始的位置。文件打开时,访问点总是被设置 为文件的开头或结尾, 这取决于打开文件时使用的访问

27、模式。每次读写后访问位置按访问的字节数后移相应的位 数。seek fileId offset origin 把 fileId 标识的文件的访问点设置为相对于 origin 偏移量为 offset 的位置。origin 可以是 start,current, end,默认是 start。tell fileId 返回 fileId 标识的文件的当前访问位置。 eof fileId 如果到达 fileId 标识的文件的末尾返回 1,否则返回 0。3.3 文件操作和获取文件信息【grob】 语法:glob switches pattern pattern .glob 命令的模式采用 string mat

28、ch 命令的匹配规则,返回匹配这个(些)模式的所有文件的 列表。如: glob *.c *.h glob */ 只返回当前目录的所有子目录。 【file】 语法:file subcmd arg arg.18file 通过众多的 subcmd 子操作提供强大的文件操作和访问能力。他们中的一些如下: file exists name file extension name file mkdir dir dir . file copy -force - source target file rename -force - source target file delete -force - path

29、name pathname . 三、Tcl 表达式(1)操作数 Tcl 表达式的操作数通常是整数或实数。 整数一般是十进制的, 但如果整数前两个字符是 0x 则这个整数被看作是十六进制的。 Tcl 的实数的写法与 ANSI C 中完全一样。(2)运算符 Tcl 中的运算符的语法形式和用法跟 ANSI C 中完全一致。另外,Tcl 中提供了大量的常用数学函数来增强自身的数学运算和处理能力,这些函数的形 式和用法大都与 ANSI C 中的数学函数 完全一致。19四、Tcl 流程控制 TCL 中的控制流和 C 语言类似,包括 if、 switch 、for、while、foreach 、 break

30、、 continue 等 命令。 (1)条件语句 if $x0 . elseif $x1 . elseif $x2 else . 注意,上例中 一定要写在上一行,因为如果不这样,TCL 解释器会认为 if 命令在换行符 处已结束,下一行会被当成新的命令, 从而导致错误的结果。在 Tcl 的其他流程控制命令的书写中也要注意这个问题。书写中还要 注意的一个问题是 if 和 之间应该有一个 空格,否则 TCL 解释器会把if作为一个整体当作一个命令名,从而导致错误。switch option $x ab incr t1 c incr t2 default incr t320 其中可选参数 optio

31、n,表示进行匹配的方式。 TCL 支持三种匹配方式: -exact 方式,-glob 方式,-regexp 方式,缺省情况表示-glob 方式。-exact 方式表示的是精确匹配,-glob 方式的匹配方式和 string match 命令的匹配方式 相同,-regexp 方式是正规表达式匹配方式。 条件中 a 的后面跟一个 表示使用和下一个模式相同的脚本,default 表示匹配任意值。一 旦 switch 命令 找到一个模式匹配,就执行相 应的脚本,并返回脚本的值作为 switch 命令的返回值。 (2)循环语句 for init test reinit body 参数 init 是一个初

32、始化脚本,第二个参数 test 是一个表达式,用来决定循环什么时候中断, 第三个参数 reinit 是一个重新初始化 的脚本,第四个参数 body 也是脚本。如: set b “ “ for set i expr llength $a -1 $i=0 incr i -1 lappend b lindex $a $i while 的例子假设变量 a 是一个链表,下面的脚本把 a 的值复制到 b: set b “ “ set i expr llength $a -1 while $i=021lappend b lindex $a $i incr i -1 foreach 命令的两种形式:1、for

33、each varName list body 第一个参数 varName 是一个变量,第二个参数 list 是一个表( 有序集合),第三个参数 body 是循环体。 每次取得链表的一个元素,都会执行循环体一次。如: set b “ “ foreach i $a set b linsert $b 0 $i 2、foreach varlist1 list1 varlist2 list2 . body 本语句是上一个的增强形式:可以有多个变量、列表对参与条件判断五、Tcl 过程 TCL 支持过程的定义和调用,在 TCL 中,过程可以看作是用 TCL 脚本实现的命令,效果与 TCL 的固有命令相似。我

34、们可以在任何 时候使用 proc 命令定义自己的过程,TCL 中的过程类似于 C 中的函数。22TCL 中过程是由 proc 命令产生的。例如: proc add x y expr $x+$y proc 命令的第一个参数是你要定义的过程的名字, 第二个参数是过程的参数列表, 参数之间 用空格隔开,第三个参数是一个 TCL 脚本,代表过程体。 proc 生成一个新的命令,可以象固有命令一样调用: add 1 2 3 在定义过程时,你可以利用 return 命令在任何地方返回你想要的值。return 命令迅速中断过 程,并把它的参数作为过程的结果。 (1)局部变量和全局变量 对于在过程中定义的变量

35、, 因为它们只能在过程中被访问, 并且当过程退出时会被自动删除, 所以称为局部变量;在所有过 程之外定义的变量我们称之为全局变量。TCL 中局部变量和全局变量可以同名,两者的作 用域的交集为空:局部变量的作用域是 它所在的过程的内部;全局变量的作用域则不包括任何过程的内部。这一点和 C 语言有很 大的不同。如果我们想在过程内部引用一个全局变量的值,可以使用 global 命令。(2)缺省参数和可变参数 可以定义具有缺省参数值的过程, 我们可以为过程的部分或全部参数提供缺省值, 如果调用 过程时未提供那些参数的值,那 么过程会自动使用缺省值赋给相应的参数。 和 CC+中具有缺省参数值的函数一样,

36、 有缺省 值的参数只能位于参数列表的后部,23即 在第一个具有缺省值的参数后面的所有参数,都只能是具有缺省值的参数。24TCL 的过程定义还支持可变个数的参数, 如果过程的最后一个参数是 args, 那么就表示这个 过程支持可变个数的参数,位于 args 以前的参数象普通参数一样处理, 但任何附加的参数都需要在过程体中作特殊处理, 过程的 局部变量 args 将会被设置为一个列表, 其元素就是所有附加的变量。如果没有附加的变量,args 就设置成一个空串。(3)引用:upvar 命令语法:upvar level otherVar myVar otherVar myVar . upvar 命令使

37、得用户可以在过程中对全局变量或其他过程中的局部变量进行访问。 upvar 命令的第一个参数 otherVar 是我们希望以引用方式访问的参数的名字,第二个参数 myVar 是这个过程中的局部变量的名字, 一旦使用了 upvar 命令把 otherVar 和 myVar 绑定,那么在过程中对局部变量 myVar 的读写 就相当于对这个过程的调用者中 otherVar 所代 表的局部变量的读写。下面是一个例子: proc temp arg upvar $arg b set b expr $b+2 proc myexp var set a 4 temp a return expr $var+$a 则

38、: myexp 7 13 这个例子中,upvar 把$arg(实际上是过程 myexp 中的变量 a)和过程 temp 中的变量 b 绑定, 对 b 的读写就相当于对 a 的读写。upvar 命令语法中的 level 参数表示: 调用 upvar 命令的过程相对于我们希望引用的变量 myVar 在调用栈中相对位置。例如: upvar 2 other x 这个命令使得当前过程的调用者的25调用者中的变量 other,可以在当前过程中利用 x 访问。 缺省情况下,level 的值为 1,即当前过 程(上例中的 temp)的调用者(上例中的 myexp)中的变量(上例中 myexp 的 a)可以在当前过程26中利用局部变量(上例中 temp 的 b)访问。 如果要访问全局变量可以这样写: upvar 0 other x 那么,不管当前过程处于调用栈中的什么位置,都可以在当前过程中利用 x 访问全局变量 other。27百度搜索“就爱阅读”,专业资料,生活学习,尽在就爱阅读网,您的在线图书馆

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报