“Hello World”在编程的世界里是个“梗”,说的是所有教编程的老师在第一节课都会让学生们在计算机屏幕上输出一个“Hello World!”。
瑞问:“为什么第一节课都要学‘Hello World!’?”
其实,在计算机屏幕上输出一个什么东西,并不是编程语言天然该有的功能。因为计算机发明的最初目的,只是能够快速运算,所以,C语言发明的时候,也将注意力放在如何运算上。但很快,人们就发现,计算机运行程序、做了运算,不知道如何将结果告诉我们。这就意味着,无论运算能力有多强大,如果不能把结果告诉我们,那么这个运算都毫无意义。于是,让计算机把运行结果显示出来,就成了编程的首要任务。
瑞问:“有道理!那么,计算机到底怎么在屏幕上显示内容呢?”
计算机发展的早期,有过很多显示方案,最终人们发现,显示器是最棒的输出设备。然而,把内容显示到显示器上,并不容易。显示屏上密密麻麻地布满了点,我们称其为像素点。这些像素点的亮与灭形成了显示器上的图案,比如,我们要显示“5”,在显示器上显示的是5的图像点阵。将5这个数字转换成图像点阵,是一个复杂的过程。
然而,把要显示的内容传输到显示器上,这个过程更复杂。我尝试着将这个过程简单地描述出来:显示器上的像素点,是和存储器的某个区域对应的。存储器其实分为两个类型,有一类存储器处于计算机最核心的位置,称为内存。程序操作内存很容易。将需要显示的内容放在内存里,计算机里的一个硬件装置叫显卡,它负责将那段内存区域的内容转移到显示器对应的像素点。
在计算机发展的早期,人们要显示的内容比较简单,现在变得越来越复杂了,我们不仅要输出给显示器,还有打印机、耳机,未来肯定会出现更多输出设备。当时,每增加一个输出设备,就要修改计算机硬件设计,专门支持新设备,这太麻烦了,所以人们想到了更好的办法。计算机只需将信息从内存送到外边,这个操作统称为输出。在设计计算机的时候,所有的输出设备一视同仁,不针对具体设备进行专门的设计,新发明的输出设备自己想办法用合适的方式显示,这样计算机的设计就简化了下来。输入设备也用了同样的设计方案,组合在一起简称I/O(Input/Output)。
瑞说:“听起来相当复杂,不好理解。”
把东西显示到屏幕上,很复杂,需要几百行的程序,初学者根本不可能完成这样的任务。好在有编程的前辈把那一大堆程序统一成一个叫printf()的程序。我们只要在程序里写“printf()”,就能将结果输出到显示器上。而至于这几百行程序在处理什么,以及其间发生什么事情,我们不需要关心。
瑞问:“printf后面有两个小括号,那是干什么的?”
printf告诉计算机即将显示东西,而括号中的信息就是我们需要显示的内容。小括号是个不错的设计,看上去像是填空题,例如,运行printf("Hello World!"),就能在显示器上显示出“Hello World!”。另外,还有一点需要提醒,printf()不是C语言自身的功能,所以你还需要再写一句话“#include<stdio.h>”,告诉程序:我需要使用stdio.h里面的输入输出功能。
还有一些细节,我需要进一步解释一下。在C语言中,单词拼写正确、大小写正确,十分重要。在严谨的计算机中,“A”和“a”是完全不同的东西。编程语言的初学者,常常会在大小写上出错。为此,有些编程语言人性化地不区分大小写,但是这个“人性化”会增加计算机的计算负担,在C语言被发明的年代,计算机硬件性能完全不足以提供这样的“人性化”。
瑞问:“stdio.h是个名字吗?”
#include可以解释成“我需要使用别人的程序”。需要使用的程序放在<>中。stdio.h仅仅是一个名字。但是你能看到一个优秀的程序员在起名字的时候,会尽可能让别人一眼看懂,如std是英文Standard(标准)的缩写,i和o分别代表Input(输入)和Output(输出)。
还记得我前面解释程序是什么的时候说过,给人一张纸,上面写了很多命令,人会照着去做。人的习惯是从纸的第1行开始向下看,而计算机不是这样的,它会寻找一个特定的位置执行你所写的程序。我们将这个位置称为程序的入口。
瑞问:“程序入口怎么写?是规定好的吗?”
我们买回家的计算机,本身已经包含了一些程序,其中最重要的程序就是操作系统。我们使用计算机时下达的每条命令,都会被操作系统获取并翻译成由计算机硬件执行的一系列动作。而我们编写的程序,也是运行在操作系统这个程序之上的。可以这么理解:操作系统就是一个太空的空间站,我们所编写的程序是要到达这个空间站的飞船;无论是哪个国家的飞船,无论是货运飞船还是客运飞船,都需要和空间站连接在一起。
要连接,就需要一个接口。C语言所编写的程序和操作系统之间的接口的名字叫作int main(){},这是一个标准的写法,因为接口就是这么定义的,你会看到其中也有一对小括号。随着学习越来越深入,你会发现C语言里有一些规则,有助于我们触类旁通地去理解另外一个地方出现的相同符号。这里的小括号也是允许你填写信息的。现在我们并不需要填什么,但是即便什么都不填,小括号也必须写。
后面还有一对大括号,你跟计算机说的话、编写的程序都放在这对大括号里。思考一下,如果由你来设计C语言,是否有更好的方案?其他的编程语言确实也有不同的做法,不过不同的做法各有优缺点,{}的设计其实还不错。
瑞说:“接口为什么要有小括号?我还是不明白。”
这个目前先当成固定写法记住,时间久了才能理解。