YongSir

专业程序员伪装者

小朋友的编程-三

上两次阅读部分的意味更加浓厚一些,都是些很细小的知识,这篇文章我们将试着尝试一些更加实际的体验,去直观感受一下什么是编程,当然前半段会有一部分编程语言发展历史的介绍,耐心看完啦。

你已经知道了编程就是跟机器交互的过程,而我们告诉机器该怎么做,靠的是一种叫做编程语言的工具。你还知道机器内部所有的信息其实都是各种数字电路的信号,我们习惯使用01来代表数字信号,换言之机器能认识的其实只有0101,这种机器能直接 认识和执行的由一系列01010 组成的东西我们称之为机器语言

事实上最原始的编程,就是科学家们利用0101的组合去一步一步指示机器去完成功能的,但是只用0101又一个很大的问题,那就是虽然机器明白了,人却不懂了。具体来说如科学家A编的程序可能只有A自己知道,科学家B是无论如何都看不懂的,就算是对A自己,过了一段时间之后可能也都忘了当时是怎样编程了的。如果都是像0101这般不直观不友好的机器语言,项目就不可能让更多的人参与,机器所能完成的工作也就不可能像我们今天这样多姿多彩。怎么办呢?如果我们有一种人类能看懂而机器又能认识的语言就好了,可惜不行,因为我们前边提到了机器能也只能认识0101这样的机器语言,于是科学家从人类的实际生活中受到启发,生活中比如你想跟一个法国的小朋友交流,你会中文而她只会法语,你就会想着找个翻译就解决了你们的语言问题,于是科学家们就约定了一个总体原则,那就是所有的编程语言都最终可以被翻译成机器能认识的机器语言,这样就解决了上述问题。

按照上述的发展历程,在机器语言之上,一种更友好的编程语言被发明出来,那就是汇编语言,真实的汇编语言长得是这个样子的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
.section .data
#数据段,定义以ascii编码的字符串“hello, xiao ze qiu!\n”,并以output来表示内存的起始地址
output:
.ascii "hello, xiao ze qiu!\n"
.section .text
.global _start
#程序以_start:开始运行
_start:
#调用write系统,eax为4表示write,ebx表示要写入的文件描述符,
#1表示标准输出,也就是终端,ecx表示字符串开头的内存地址,edx表示长度
movl $4,%eax
movl $1,%ebx
movl $output,%ecx
movl $12,%edx
int $0x80
#调用退出系统,1表示退出,0为正常退出,这里和c语言main函数的返回值应该是一个意思
movl $1,%eax
movl $0,%ebx
int $0x80

你是不是有些蒙了,看起来好难好复杂的样子啊!其实上述程序干的事情很简答,只是在屏幕上跟你打个招呼而已 – “hello, xiao ze qiu!”,但是写起来却要那么长一串,所以在这里要心疼一下早编程的前辈们��,这个例子就暴漏了汇编语言的弱点,那就是虽然总算比0101有好一些,但实在是太麻烦了,难道编程语言就不能像我们平时说话那样,表达明确又简单吗?

其实是可以的,那就是人们终于在受不了汇编之后,又发明了很多种更接近人类语言的编程语言,我们统称它们为高级编程语言,它们有很多很多,据统计有250多种并且还在不断的被发明出来,因为它们各自要解决的问题和使用领域的不同,根据不用的设计理念就有了如此多的数量,但肯定都比汇编简单太多太多,比如上述打招呼如果用C语言来实现就是:

1
2
3
4
5
6
#include <stdio.h>

int main() {
printf("hello, xiao ze qiu!"); // print 就是打印的意思,printf指的是打印之后自动换行而已
return 0;
}

是不是简单了很多也好懂了很多:-), 其实还有更简单比如有一门叫JavaScript的语言中只需要一句话:

1
console.log("hello, xiao ze qiu!") // console 就是控制台,就是windows系统上那个命令行的黑框框的东西,你自己先在电脑上试试,看能不能找到

如果还是觉得麻烦,还有最简单的,比如在一门叫Python的编程语言中就是:

1
print("hello, xiao ze qiu!")

是不是很简单,这样的对人友好的高级编程语言很接近于我们日常使用的语言,于是跟机器交流就变得容易多了,这才促进了整个计算机科学的发展。

所以我们稍稍总结一下,编程语言的发展基本上是这样的: 机器语言 ~> 汇编语言 ~> 高级语言, 我们通常意义的编程就是,利用接近人类自然语言的高级语言给机器规定动作。


下面就开始思考一个个具体的问题,让我们对生活中习以为常的逻辑行为做一些具体的仔细的整理。
不防就从对现实生活中模仿开始,比如我们知道周一到周五是上课时间,而周六日是休息不上课的,就这样简单的一句话,当我们试着把每个过程说清楚,用代码的方式就像是这样:

1
2
3
4
首先是一个日期
然后把它转化成星期
如果是在周一到周五,那么正常上课
如果是周六或者周日,那么不用上课

这里边蕴含着一种选择结构,如果把它画成逻辑流程图,会更直观一些:

生活中还有其他的逻辑流程,比如再考虑这样一个例子,考试的时候你需要把全部的题做完才能交卷,这样的逻辑图是怎样的呢?我可以画出来是这样的:

跟第一种不同的是这里边不光有选择结构还附带的有循环结构的逻辑,所谓循环逻辑就是直到满足一定的条件才会退出循环,否则就会一直执行的一种结构

事实上还有一种顺序结构就是按顺序一步一步来,上述的每个箭头都代表从这一步到下一步的顺序执行,它是最符合我们人类直觉最自然的结构,所以不必额外提出来。

现在,如果你能仔细在思考一下,就会发现这个世界上所有的事情,都最终可以用上边这3种基本逻辑结构通过组合来实现,有的是选择分支多一些,有的是循环多一些,比如我们让上边考试的例子在具体一些,那就加上考试是有时间的因素,一个考试的完整流程可能是这样的,先说代码:

1
2
3
4
开始
开始做题,并开始计时
如果时间到了就必须交卷,退出
如果时间没到,就把所有题做完,退出

这里边的时间逻辑是最主要的,只要时间到了就必须交卷,不管做没有做完,还有另一种情况是时间没走完但做完了也可以交卷,文字不容易说明,不防也化成逻辑流程图:

注意图中有2条不一样的线,红色的表示同时进行,因为一开始计时就代表着可以开始做题;另外一条蓝色的线,代表每次做题都会去检测时间是否到了,如果到了就马上交卷,如果没到就继续计时和做题,基本就是2个并行分支一个计时,一个检测是否做完,在每个分支内部又是选择和循环的组合。所以这就是编程全部秘密,编程就是将某个功能,按照基本步骤进行逻辑划分,拆成一个一个简单的顺序或者选择或者循环的结构,从而最终达到某种确定的结果

当然这里我们是通过文字和流程图实现的,实际的计算机编程中,我们只需要把上述,改为使用计算机能理解的编程语言实现了而已,所以只要你学会了将一个复杂过程一步一步的逻辑分解,就可以说已经学会了编程,这么一看,其实你已经无意识的使用了很多年的编程,只是你不知道罢了,所以编程不是什么神秘的事,相反它之非常平常。

那具体是怎样把这些逻辑通过编程语言来实现呢?其实我们只需要借助一点点数学就可以了,比如我下边简单的列举几个,看看你自己能不能看出来它是属于什么结构的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 一个 = 就是普通的等号," == " 这个才表示 比较数值

// -------------- 1 --------------
var x = 0 // 不要管前边的var,你可以把x当成方程中的自变量一样,下边还有几个简单的单词,你应该可以自己查到的,试试吧
if (x == 0) {
// 情况1之下做点儿什么
}else {
// 情况2之下做点儿什么
}

// -------------- 2 --------------
var x = 10
while(x > 5) { // while 单词表示 当什么什么时候
// 做点儿什么,比如输出x
console.log(" >> " + x)
x = x - 1
}

// -------------- 3 --------------
// x-- 是 x = x-1 的一种简写
for (var x = 10; x > 5; x--) {
// 做点儿什么,比如输出x
console.log(" -- " + x)
}

1很简单,就是个只有2个分支的选择结构,我们称之为 if-else语句
2通过单词也能大概猜到是个循环结构,我们称之为 while语句
3呢,其实3也是一种循环结构,这种语句在编程中称之为 for语句, 它只是比2中的 while语句 写起来更简单一些罢了, 2和3都表示一种循环结构,它们的执行结果如图

好了,这次只是让你简单的认识一下编程,至于各种语句应该怎么写,将在后续慢慢去了解,现在你只要能够知道顺序/选择/循环这3种结构,并学会把生活中的事情分解成一步一步的上述3种结构就可以了