序对(pair)
序对是scheme的基础概念,在构造复合数据结构中起到“粘接剂”的作用。通过cons构造序对,例如(cons 1 2)就构成了一个序对,可以这样表示'(1 . 2),它包含两个元素分别为1、2。用盒子与指针方式表示法很形象的描述序对的结构。car和cdr也是scheme的基本过程,它们分别取由cons构成的序对的左边部分和右边部分。所以在scheme解释器里输入命令(car '(1 . 2))将得到1,输入(cdr '(1 . 2))得到2。序对的两个元素之间有点如'(1 . 2),只是为了和表的区别。下面会讲到'(1 2)是由命令(list 1 2)产生的表,它由两个序对链接起来的。
第一幅图就是(cons 1 2)构成的序对,盒子就是存储的数字1、2,分别有两个指针指向它们,左边的指针是car,右边的cdr。通过cons组合的序对又可以作为子元素组成序对的序对。第二幅图就是以两个序对作为子元素组成的序对的序对,这时顶层序对的car是'(1 . 2),也就是1和2组成的序对。第三幅图看上去比较复杂,实际是第一和第二幅图所说的方法组合。
表(list)
表是一种数据结构,它可以通过序对方式表示。scheme中用基本过程list可以生成表,例如(list 1 2 3 4)得到的表就相当于通过(cons 1 (cons 2 (cons 3 (cons 4 nil )))),指针与盒子表示法如下图:
上图形象的描述了序对与表的关系。最后一个序对的cdr为空表,表示结束。结合上图可以非常容易知道(car (list 1 2 3 4))的值为1;(cdr (list 1 2 3 4))就是由2、3和4组成的表,'( 2 3 4)。
附加:
在了解了序对与表的区别和联系后,还有几个容易让人迷糊的形式,会影响对这两个概念的理解。序对由cons产生,在盒子与指针的表示方法中可以看出,它包含两个指针分别代表car和cdr,和指针指向的盒子,里面存放着元素的值。为了和表有区别,把两个元素组成的序对表示成'(1 . 2)形式,而没有点的形式'(1 2)代表了(list 1 2)产生的表。
仔细观察上图就能体会到序对和表的区别。联系它们的表示方式,猜测下(car '(1 . 2))、(car '(1 2))、(cdr '(1 . 2))和(cdr '(1 2))的值分别是多少?