首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Scheme 语言概要(2)数据类型1

Scheme 语言概要(2)数据类型1

四.数据类型1. 简单数据类型逻辑型(boolean)
最基本的数据类型,也是很多计算机语言中都支持的最简单的数据类型,只能取两个值:#t,相当于其它计算机语言中的 TRUE;#f,相当于其它计算机语言中的 FALSE。
Scheme语言中的boolean类型只有一种操作:not。其意为取相反的值,即:
1
2
(not #f) => #t
(not #t) => #f




not的引用,与逻辑非运算操作类似
1
2
3
4
5
6
guile> (not 1)
#f
guile> (not (list 1 2 3))
#f
guile> (not 'a)
#f




从上面的操作中可以看出来,只要not后面的参数不是逻辑型,其返回值均为#f。
数字型(number)
它又分为四种子类型:整型(integer),有理数型(rational),实型(real),复数型(complex);它们又被统一称为数字类型(number)。
如:复数型(complex) 可以定义为 (define c 3+2i)        
实数型(real)可以定义为 (define f 22/7)        
有理数型(rational)可以定义为 (define p 3.1415)        
整数型(integer) 可以定义为 (define i 123)      
Scheme语言中,数字类型的数据还可以按照进制分类,即二进制,八进制,十进制和十六进制,在外观形式上它们分别以符号组合 #b、 #o、 #d、 #x 来作为表示数字进制类型的前缀,其中表示十进制的#d可以省略不写,如:二进制的 #b1010 ,八进制的 #o567,十进制的123或 #d123,十六进制的 #x1afc 。
Scheme语言的这种严格按照数学定理来为数字类型进行分类的方法可以看出Scheme语言里面渗透着很深的数学思想,Scheme语言是由数学家们创造出来的,在这方面表现得也比较鲜明。
字符型(char)
Scheme语言中的字符型数据均以符号组合 "#\" 开始,表示单个字符,可以是字母、数字或"[ ! $ % & * + - . / : %lt; = > ? @ ^ _ ~ ]"等等其它字符,如:        
#\A 表示大写字母A,#\0表示字符0,        
其中特殊字符有:#\space 表示空格符和 #\newline 表示换行符。      
符号型(symbol)
符号类型是Scheme语言中有多种用途的符号名称,它可以是单词,用括号括起来的多个单词,也可以是无意义的字母组合或符号组合,它在某种意义上可以理解为C中的枚举类型。看下面的操作:
1
2
3
4
5
6
guile> (define a (quote xyz))  ;  定义变量a为符号类型,值为xyz
guile> a
xyz
guile> (define xyz 'a)  ; 定义变量xyz为符号类型,值为a
guile> xyz
a




此处也说明单引号' 与quote是等价的,并且更简单一些。符号类型与字符串不同的是符号类型不能象字符串那样可以取得长度或改变其中某一成员字符的值,但二者之间可以互相转换。
2. 复合数据类型可以说复合数据类型是由基本的简单数据类型通过某种方式加以组合形成的数据类型,特点是可以容纳多种或多个单一的简单数据类型的数据,多数是基于某一种数学模型创建的。
字符串(string)  由多个字符组成的数据类型,可以直接写成由双引号括起的内容,如:"hello" 。下面是Guile中的字符串定义和相关操作:
1
2
3
4
5
6
7
8
9
10
guile> (define name "tomson")
guile> name
"tomson"
guile> (string-length name)  ; 取字符串的长度
6
guile> (string-set! name 0 #\g)  ; 更改字符串首字母(第0个字符)为小写字母g (#\g)
guile> name
"gomson"
guile> (string-ref name 3)  ; 取得字符串左侧第3个字符(从0开始)
#\s




字符串还可以用下面的形式定义:
1
2
3
guile> (define other (string #\h #\e #\l #\l #\o ))
guile> other
"hello"




字符串中出现引号时用反斜线加引号代替,如:"abc\"def" 。
点对(pair)
我把它译成"点对",它是一种非常有趣的类型,也是一些其它类型的基础类型,它是由一个点和被它分隔开的两个所值组成的。形如: (1 . 2)  或 (a . b) ,注意的是点的两边有空格。
这是最简单的复合数据类型,同是它也是其它复合数据类型的基础类型,如列表类型(list)就是由它来实现的。
按照Scheme语言说明中的惯例,以下我们用符号组合 "=>" 来表示表达式的值。
它用cons来定义,如: (cons 8 9) =>(8 . 9)
其中在点前面的值被称为 car ,在点后面的值被称为 cdr ,car和cdr同时又成为取pair的这两个值的过程,如:
1
2
3
(define p (cons 4 5))   => (4 . 5)
(car p)         => 4
(cdr p)         => 5




还可以用set-car! 和 set-cdr! 来分别设定这两个值:
1
2
(set-car! p "hello")
(set-cdr! p "good")




如此,以前定义的 p 又变成了 ("hello" . "good") 这个样子了。
列表(list)
列表是由多个相同或不同的数据连续组成的数据类型,它是编程中最常用的复合数据类型之一,很多过程操作都与它相关。下面是在Guile中列表的定义和相关操作:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
guile> (define la (list 1 2 3 4 ))
guile> la
(1 2 3 4)
guile> (length la)  ; 取得列表的长度
4
guile> (list-ref la 3)  ; 取得列表第3项的值(从0开始)
4
guile> (list-set! la 2 99)  ; 设定列表第2项的值为99
99
guile> la
(1 2 99 4)
guile> (define y (make-list 5 6))  ;创建列表
guile> y
(6 6 6 6 6)




make-list用来创建列表,第一个参数是列表的长度,第二个参数是列表中添充的内容;还可以实现多重列表,即列表的元素也是列表,如:(list (list 1 2 3) (list 4 5 6))。
列表与pair的关系
回过头来,我们再看看下面的定义:
1
2
3
guile> (define a (cons 1 (cons 2 (cons 3 '()))))
guile> a
(1 2 3)




由上可见,a本来是我们上面定义的点对,最后形成的却是列表。事实上列表是在点对的基础上形成的一种特殊格式。
再看下面的代码:
1
2
3
4
5
6
7
guile> (define ls (list 1 2 3 4))
guile> ls
(1 2 3 4)
guile> (list? ls)
#t
guile> (pair? ls)
#t




由此可见,list是pair的子类型,list一定是一个pair,而pair不是list。
1
2
3
4
guile> (car ls)
1
guile> (cdr ls)
(2 3 4)




其cdr又是一个列表,可见用于pair的操作过程大多可以用于list。
1
2
3
4
5
6
7
8
    guile> (cadr ls)   ; 此"点对"对象的cdr的car
2
guile> (cddr ls)   ; 此"点对"对象的cdr的cdr
(3 4)
guile> (caddr ls)   ; 此"点对"对象的cdr的cdr的car
3
guile> (cdddr ls)   ; 此"点对"对象的cdr的cdr的cdr
(4)




上在的操作中用到的cadr,cdddr等过程是专门对PAIR型数据再复合形成的数据操作的过程,最多可以支持在中间加四位a或d,如cdddr,caaddr等。
下图表示了由pairs定义形成的列表:
这个列表可以由pair定义为如下形式:
1
(define x (cons 'a (cons 'b (cons 'c (cons 'd '())))))




而列表的实际内容则为:(a b c d)
由pair类型还可以看出它可以轻松的表示树型结构,尤其是标准的二叉树。
返回列表