控制台和图形用户界面
Hello world
恐怕是家喻户晓的编程语言第一堂课了,当你开始照书上的例子编写Hello world
时,很快就会问出这个问题。回想平时见到的那些程序,他们通常都有标题栏,有菜单和工具栏,可以用鼠标在上面点来点去好像还有很多别的功能。可是这个程序似乎完全不同,难道出了什么问题?其实没有问题,这是一个控制台程序。
世界上有各种各样的程序。几乎所有的程序都要和用户交流,接受用户的输入,输出运行的结果,但它们接受和输出的方式是不一样的,程序与用户交流的方式被称为界面。还记得早期科幻电影里那种出现在计算机屏幕上可以和人对话的巨大人脸吗?或者《贝克街的亡灵》中被称为「茧」的游戏——那就是界面的一种。事实上这种界面到现在还没有实现,人类的想象力总是能超前实际技术很多。
界面有很多种,有些程序不需要界面,因为它们根本不必和用户交流,它们和其它的程序交流,你可以叫它无界面,典型的例子就是驱动程序,你什么时候见过驱动程序运行的样子?一般在Windows和Mac OS X下的程序所使用的则称为图形用户界面(GUI: Graphics User Interface),Linux下同样也有很多采用GUI的应用程序。简单来说,就是所有的输入和输出都使用图形的方式。它接受用户图形化的输入,譬如用户用定位设备(鼠标、轨迹球、手写板)输入坐标、绘图,把程序的输出反映在可以显示图形的设备上,譬如显示器、打印机、头戴式监视器,通常这种程序会提供菜单、工具条等方式而极大地方便用户。这种程序直观明了,一般用户能很容易的掌握使用,只需要点击就可以完成大部分的任务。魔兽世界和Word就是典型的GUI程序。
虽然GUI程序便于一般人使用,但其实图形界面的编程是相当复杂的。你能想象每次你都要画出显示器上所有的东西有多困难。窗口移动缩放时,你需要重画窗口里的每一样东西;在多窗口并存的时候,如果你的窗口被别人的窗口挡住了一部分(这是很常见的情况),你需要控制窗口上哪些部分被显示、哪些被遮挡;鼠标移动的时候,你需要把被鼠标遮住的部分盖住,并重画鼠标;当鼠标点击时,你需要判断鼠标的位置,还要判断这个点击是你的程序的,还是别人的;当鼠标点击到菜单的时候,你要确定是菜单还是按钮,以及是哪个菜单项,然后执行相应的操作。所有这些情况,都必须一一解决。其中有些是可以由操作系统解决的,但你要知道怎样利用操作系统提供的资源才能让它帮你做,还有些就必须你自己想办法,种种问题使得图形界面的编程变得异常复杂。
与此同时,由于图形处理的需要,图形界面对计算机硬件的要求也比较高。画面绚丽的3D游戏,远比记事本程序对系统的要求要高的多。虽然现代的计算机早已能够满足这些要求,但早期的计算机并不是这样强大的。所以,在早期(也不是很远,大约是上世纪七、八十年代)的时候,程序的界面并不是图形,而是字符的。用户在键盘上输入文字,比如dir,系统找到相对应的命令,然后执行,执行的结果也是以一行行文字的形式输出在可以输出文字的设备上(当然也主要是显示器),用户阅读文字,进行下一步的操作。
现代的一些科幻片,在表现黑客侵入或者是操作高级设备(比如美国国防部的核武器系统)时,往往出现操作员在啪啪啪啪快速打字,然后突然一回车,就大功告成的场景,很少会出现卡通化的菜单和工具栏。想想黑客帝国的那个接线员,你见过他什么时候抓着鼠标吗?这种方式就叫命令行界面(CLI: Command Line Interface),由于操作员通常是坐在一个操作台前,而这个操作台确实可以控制整个系统,所以也被称为控制台界面(Console Interface)。控制台下运行的程序,就是控制台程序;运行控制台程序的系统,就叫控制台环境。控制台看起来很高级,很酷很眩,黑客们操作的时候也显得很高深,其实反倒是比较容易编程实现的。因为你只要处理和输出字符就可以,系统自然会把字符放在屏幕上适当的位置。你不用去管字体大小颜色这些事,更甭提窗口、菜单和鼠标这些不存在的东西,只要把注意力全部放在程序的功能上。电脑系统也不用消耗资源来画图,系统自然比较高效。所以,命令行界面一出现,就得到了广泛的应用,它的历史可比图形界面古老多了。和GUI程序比起来,命令行的程序通常不那么漂亮,对普通用户来说操作也不直观。但由于它的高效和快捷,命令行方式的程序迄今仍然在使用,命令行方式不但没消失,相反,有许多系统反而更加加强这部分的功能,譬如 Windows7 下的 Windows PowerShell,按下“Windows”徽标键(键盘左下侧类似一个窗户的图案),输入PowerShell试试,进入后试试ls & tab,可以像Linux的终端一样自动补全噢~
在很多时候,人们宁可使用命令行的程序来完成某些工作,这一点在BSD、 Linux和其它的UNIX系统中体现较为明显。DOS就是一个标准的控制台环境,Windows系的操作系统,也提供了控制台环境,不过连鸡肋都不如就是。还有很多的GUI程序,借鉴控制台方式,仍然保留有直接使用键盘操作的方法。比如魔兽争霸,几乎每个命令都有快捷键以加速操作。
实际上,很多系统管理员更偏爱控制台程序,除了它比图形界面程序更高效之外还有一个原因:同样要增加实现一个选项,控制台只要增加一个输入字符作为开关,而图形界面至少需要增加一个按钮。想想看,屏幕上是可以增加的按钮多还是可以增加的字符数多呢?所以控制台程序往往更能实现纷繁复杂的功能,只要你记得住相应指令。
让我们在Windows下打开一个控制台环境并使用几个控制台程序感受一下。Linux下的后边附录部分会单独截图演示。假如你使用的是Windows XP,点击开始,找到程序->附件,在里面有一个叫“命令提示符”的快捷方式,点击运行它。Windows7下类似,也可以点击开始后输入cmd
. 还可以同时按住「Windows」徽标键和R,在弹出的窗口中输入cmd
。
你是不是看到了一个窗口,没有菜单,没有工具栏,只有标题栏和最大最小化的按钮,这就是Windows下的控制台环境,在这里就可以运行控制台程序。现在,输入dir
,然后回车。你看到了输出吧,这就是控制台程序的运行了。只要输入命令再回车,就可以运行了。再来运行一个,time
,再来一个,ipconfig
。最后再来一个,help
。他给出了当前系统提供的各种命令,你可以看着提示分别试一试。其实不止可以运行这些,试试 notepad
,你发现了什么?explorer
, calc
等等都是可以这样运行的哦。玩够了,好吧,输入exit
,再回车,控制台环境就被关闭了。有没有发现 Windows对命令行界面一点也不友好,相比之下Linux和MAC OS则对命令行界面友好地多,所以也才会有了cygwin之类的软件出现。
控制台程序容易编写,易于理解,所以对于初学者,控制台程序是比较好的选择。在学会了控制台程序的基础上,再转到窗口程序就比较轻松了。
图形用户界面编程
黑客们很偏爱Console,但对于普通用户来说,图形界面是他们更熟悉的。我们大多数人也喜欢编写GUI程序,因为那看起来似乎更友好也似乎更有成就感,那怎样才能编写GUI程序?
每一个操作系统,都会提供一套API,如果该系统支持GUI,那么它的API中就会有一个图形子系统和窗口管理子系统。其中图形子系统包括了基本图形元素的绘制,比如画点线面、显示文字图片和上色渲染等等,窗口管理子系统首先会包含图形子系统,再增加包括窗口和窗口元件的绘制、窗口的遮盖、移动调整,以及鼠标点击这类事件的传递处理等等这些内容。Windows下,图形子系统就叫GDI(Graphics Device Interface)。为了高效处理多媒体编程,微软在Windows95发布前夕开发出了DirectX——除了图形之外它还整合了很多其它功能,用它搞出了大量的Windows游戏。另一套著名的图形API则是跨平台&跨编程语言的OpenGL,渲染能力很强!!
另外值得一提的就是微软自Vista发布以来广泛用于界面开发的WPF,WPF 是下一代图形API 在桌面上的延伸。以WPF 撰写应用程序,具有更高的视觉品质,Win7丰富的界面效果很大程度上要归功于WPF的应用。
即使有图形库窗口管理库,GUI编程仍然是相当的繁琐。首先是要完成某个工作必须填写大量按部就班的代码,而且这些代码在程序内部和各个程序之间重复着,这提示人们应该在图形库的基础上作进一步的抽象。简单来说就是要在画点画线函数的基础上做出画二次曲线画立方体的模块。幸运的是,这些工作已经有人完成了,而且是不止一套。这些东西按照功能强弱,有的叫图形用户界面库,有的则叫应用程序框架。在Windows下,使用VC++的人可以选择MFC ATL,如果你选择.NET阵营,.NET Framework就是你最好的选择,结合C#开发比较方便。
如果你希望程序不止在Windows使用,那么跨平台的Qt, GTK+, wxWidgets 都是你的好选择。它们在保证效率的同时,适当抽象,抚平了底层操作系统的差异。对于学习C++的人来说,上述库都是可以用的,当然也有其它语言支持——比如Python。这三个平台相对来说QT的资料会多一些,但是有一定的版权问题困扰,不过个人使用没有问题。