程序员

如何编写程序的笔记:序章

2016-05-05  本文已影响972人  胡一波

序章:如何编写程序

1.序幕

本书使用的是编辑器DrRacket,使用的是其中的选择语言——教学语言——程序设计初级,选择之后重新点击运行即可。
该编辑器的下半屏幕是交互区,上半屏幕是定义区,编辑文件以后,可以保存以后,点击运行,从而在下方的交互区看到输出结果。比如,在定义区输入:

(+ 1 1)

你会看到底部交互区呈现的结果是:

2

这样,你就可以输入下面这几个表达式,看看交互区会得到什么结果:

(+ 2 2) 
(* 3 3) 
(- 4 2) 
(/ 6 2) 

结果应该是4 9 2 3,就好像你期待的一样。下面,是不得不进行的术语定义时间。


术语

> (+ 2 2)
4
> (sqr 3)
9
> (sin 0)
0
> (cos pi)
#i-1.0

介绍了足够的术语后,下面继续。我们可以发现,这里的DrRacket可以加总两个以上的数字,还可以嵌套

> > (+ 2 (+ 2 3))
7
> (+ 2 3 2)
7

第一个是所谓的嵌套算数,正如在学校里面学到的。而第二个则是火箭算数,且它看起来是自然的,如果你总是将操作符和操作数用括号包围起来的话。在教学语言——HtDP——BSL中,你可以任意使用嵌套表达式,其中表达式的左端是操作符,右端是操作数,嵌套层级则随你使用:

> (+ 2 (+ (* 3 3) 4)) 
15
> (+ 2 (+ (* 3 (/ 12 4)) 4)) 
15
> (+ (* 5 5) (+ (* 3 (/ 12 4)) 4)) 
38

但是,要注意:括号必须是成对的,既不能多,也不能少。比如下面这个表达式,在作业中是没有问题的:

> (+ (1) 2)
function call: expected a function after the open parenthesis, but found a number

结果会报错……

P.S. 你可以将光标移动到操作符的附近,按下<kbd>F1</kbd>,然后你就可以获取所需要的帮助文档了。

如果你不知道一个操作符有什么用,就在交互区输出示例,然后查看结果。这也是之后阅读代码所需要的技能。

2. 数字之外的内容

如果程序只能处理数字,会跟mathematics一样无聊(虽然看这个的人可能已经在使用或者之后需要使用它)。但幸运的是,这里可以处理数字以外的东西,比如:文本、布尔值、图片等等。

下面是文本处理的示例程序:

(string-append "hello" "world")
(string-append "hello" " " "world")
(string-append "hel" "lo world")

当你输入病运行上述代码的时候,下面的交互区会显示:

"helloworld"
"hello world"
"hello world"

为了理解发生了什么,你需要知道:在BSL中,文本是用双引号包围起来的字符。当DrRacket对字符串求值的时候,会返回字符本身。所以HelloWorld在这里特别简单,只需要输入"Hello world!"即可。

string-append本身则是操作符之一,作用是将多个字符串从左到右顺序连接起来,只是连接了字面值,而没有加入换行符之类的内容。如果想知道更多与字符串相关的操作符,可以按下<kbd>F1</kbd>,然后搜索Begin,点击Beginning Student

如果你已经做了上面所述的工作,你应该能看到这些内置(或者说预定义)的,与字符串相关的操作符了。然后,就可进行相关的操作,如下:

> (+ (string-length "Hello world!") 20)
32

然后,DrRacket会对表达式进行求值,打印结果。这意味着,你的输入可以不只是数字,输入和输出的类型可以不同,比如下面展示的类型转换函数:

> (number->string 42)
"42"
> (string->number "42")
42

恩……如果你希望能得到四二之类的答案,可能要大失所望了——这并不是一个字符串操作符能做到的事情……

而这第二个操作符会使人产生疑惑:如果输入的不是一个数字字符串,二是其他东西,会怎么样呢:

> (string->number "Hello")
#false

得到了一个布尔值的错误。在DrRacket中,布尔值由两个值表示:#true/#false。自然,其也能够支持逻辑运算符andornot。虽然把数字转换为布尔值不可行,但是可以将两个以上的数字“转换”为布尔值:

(> 10 9)
(< -1 0)
(= 42 42)
(= 3 4)
; 返回值
#true
#true
#true
#false

你可以开始尝试下面这几个表达式(>= 10 10)(<= 3 4)(string=? "design" "tkinter")。虽然最后一个长得有点奇怪,但是要相信自己:你可以的~

在进入真正的编程之前,会展示一种额外的数据:图片。如果需要将图片插入交互区,你只需要将下面这张图:

image.png

插入交互区,就可以看到DrRacket返回图片本身了。

P.S. 你可以使用插入菜单,并点击插入图片来完成这个壮举。

这里,BSL可以理解图片,如同理解数字和字符串一般。除此之外,该语言还支持一个,。这些包可以像扩展你的词典一般,为你的程序词典添加新的内置函数。我们在教学中会使用这些包,并称其为教学包

现在,我们可以使用包2htdp/image,其支持对图片的计算:

火箭程序实例.PNG

输入如图所示的程序以后,你可以得到一个返回值:1176,因为这个图的面积为28 X 42 像素。当然,你还可以使用一些函数来进行画图,如circle函数和rectangle函数:

(circle 10 "solid" "red")
(rectangle 30 20 "outline" "blue")

除此之外,DrRacket还支持图像之间的组合,如下:

(overlay (circle 5 "solid" "red")
         (rectangle 20 20 "solid" "blue"))

将两张图片的构造函数换个顺序,你会发现结果有所不同:

(overlay (rectangle 20 20 "solid" "blue")
         (circle 5 "solid" "red"))

在这里,你可以将overlay视作string-append,其像后者一样,操作数的先后会影响结果,与此同时,你还可以对其使用前面的求宽度操作符:

(image-width (square 10 "solid" "red"))
(image-width
 (overlay (rectangle 20 20 "solid" "blue")
          (circle 5 "solid" "red")))
          
; 结果
10
20

除了这些,你还应该知道另外两个操作符:empty-sceneplace-image。前者创建一个场景,属于特殊的矩形;后者则将一张图放置到这样的场景中。

(place-image (circle 5 "solid" "green")
             50 80
             (empty-scene 100 100))

你看,结果如下:

empty-scene实例.png

其中,这幅场景的原点(0, 0)位于左上角,y值向下递增;x值向左递增。所以你看到的坐标(50, 80)是在那里。

现在总结一下这节的内容:

我们不再只是处理数字,而且可以处理字符串,布尔值以及图片。计算现在依旧意味着:给表达式传入特定的值,如字符串,数字,布尔值或者图片。但是,你下次就可以让这个火箭“飞起来”了。

上一篇下一篇

猜你喜欢

热点阅读