1.3 软件是指令和数据的集合
下面介绍软件,即程序的基础。所谓程序,其实非常简单,只不过是指令和数据的集合。无论程序多么高深、多么复杂,其内容也都是指令和数据。所谓指令,就是控制计算机进行输入、运算、输出的命令。把向计算机发出的指令一条条列出来,就得到了程序。这里成套出现的输入、运算、输出,就是之前在硬件的基础一节中说明过的流程。向计算机发出的指令与计算机硬件上的行为一一对应是理所当然的。
在程序设计中,会为一组指令赋予一个名字,可以称之为“函数”“语句”“方法”“子例程”“子程序”等。这里稍微说些题外话,在计算机行业,明明是同一个东西,却可以用各种各样的术语来指代它,这种现象请诸位注意。如果只想用一个名字的话,一般情况下笔者推荐称之为函数,因为这个名字通俗易懂。
程序中的数据分为两类,一类是作为指令执行对象的输入数据,一类是从指令的执行结果得到的输出数据。在编程时程序员会为数据赋予名字,称其为“变量”。看到变量和函数,诸位也许会联想到数学吧。正如数学中函数的表记方法那样,在很多编程语言中都使用着类似于下面的这种语法。
y = f(x)
这句话表示若把变量x输入到函数f中,经过函数内部的某种运算后,其结果就会输出到变量y中。因为计算机是先把所有的信息都表示成数字后才对其进行运算的,所以编程语言的语法类似数学算式也就不足为奇了。但是在程序中有一点与数学不同的是,变量和函数的名字都可以由一个以上的字符构成,比如下面这种情况。
output = operate(input)
也就是说,使用由多个字符构成的长名字也是可以的。甚至可以说,写成这样的情况更加普遍。
下面我们就举一个例子作为证据来证明程序是指令和数据的集合。请诸位看代码清单1.1。这里列出了一段用名为C语言的编程语言编写的程序。C语言中要在每条指令的末尾写一个分号“; ”。第一行的“int a, b, c; ”表示接下来要使用名为a、b、c的整数变量,其中int是integer(整数)的缩写,用于告诉计算机“要用的是整数”。下一行的“a = 10”表示把整数10赋值给变量a。同样地,“b = 20; ”表示把整数20赋值给变量b。等号“=”是赋值给变量的指令。再来看最后一行的“c = Average(a, b); ”,这一行表示把变量a和b传给函数的参数,并将运算结果赋值给变量c。其中使用了一个名为Average的神秘函数,它的作用是返回两个参数的平均值。通过上面这个例子,诸位就应该能明白程序确实只是由指令和数据构成的了吧。
代码清单1.1 C语言的程序示例片段
int a, b , c; a = 10; b = 20; c = Average(a, b);
虽然程序就是这样,但是那些稍微有些编程经验的人也许会说:代码清单1.1所示的程序逻辑简单,而真正的程序是使用了各种各样的语法、比这复杂得多得多的东西,绝不是用指令和数据的集合就能解释清楚的。其实并不是像他们想的那样,无论是多么复杂的程序,都只不过是指令和数据的集合。下面我们再拿出一个证据。
在一般的编程过程中,都要先编译再执行。所谓编译就是把用C语言等编程语言编写的文件(源文件)转换成用机器语言(原生代码)编写的文件。假设我们先把代码清单1.1中的代码保存到文件MyProg.c中,然后经过编译就可以生成可执行的程序文件MyProg.exe了。接下来使用能查看文件内容的工具查看MyProg.exe,其内容应该与代码清单1.2类似。可以看到里面仅仅是数值的罗列(这里用十六进制数表示)。
代码清单1.2 机器语言的程序示例
C7 45 FC 01 00 00 00 C7 45 F8 02 00 00 00 8B 45 F8 50 8B 4D FC 51 E8 82 FF FF FF 83 C4 08 89 45 F4 8B 55 F4 52 68 1C 30 42 00 E8 B9 03 00 00 83
请选择一个代码清单1.2中的数值,随便哪个都可以。这个数值代表什么呢?是表示赋值或加法等指令的种类呢,还是表示将成为指令执行对象的数据呢?也有这样的可能(不过这终归是想象),第一个数值C7表示指令,第二个数值45表示数据。在诸位所使用的Windows个人计算机中,应该会有若干个以.exe为扩展名的可执行程序文件。无论是哪个程序,其内容都是数值的罗列,每个数值要么是指令,要么是数据。