大学IT网 - 最懂大学生的IT学习网站! QQ资料交流群:367606806
当前位置:大学IT网 > C++技巧 > 编程及C/C++初学者常见问题(FAQ)

编程及C/C++初学者常见问题(FAQ)(11)

关键词:编程C/C++初学者FAQ常见问题  阅读(5246) 赞(32)

[摘要]本文意在集中解决新手学习C/C++语言时将遭遇到的各类问题,本文主要分析概念原理和解决方案,不讨论具体程序语法,立足于让初学者能运行起第一个程序。其他事宜如解释入门语法等本文基本不涉及。
当你开始照书上的例子编写第一个C程序时,很快就会问出这个问题。回想平时见到的那些程序,他们通常都有标题栏,有菜单和工具栏,可以用鼠标在上面点来点去好像还有很多别的功能。可是这个程序似乎完全不同,难道出了什么问题。其实没有问题,这是一个控制台程序。

   世界上有各种各样的程序。几乎所有的程序都要和用户交流,接受用户的输入,送出运行的结果,但他们接受和送出的方式是不一样的。程序与用户交流的方式被称为界面,还记得早期科幻电影里那种出现在计算机屏幕上可以和人对话的巨大人脸吗,那就是界面的一种。事实上这种界面到现在还没有实现,人类的想象力总是能超前实际技术很多。

   界面有好多种。有些程序不需要界面,因为他们根本不和用户交流,他们和其它的程序交流,你可以叫他无界面,典型的例子就是驱动程序,你什么时候见过驱动程序运行的样子。现在常见的windows下的程序所使用的则称为图形用户界面(GUI:Graphics User Interface)。简单来说,就是所有的输入和输出都使用图形的方式。他接受用户图形化的输入,譬如用户用定位设备(鼠标、轨迹球、手写板)输入坐标、绘图,把程序的输出反映在可以显示图形的设备上,譬如显示器、打印机、头戴式监视器,通常这种程序会提供菜单、工具条等方式而极大地方便用户。这种程序直观明了,一般用户能很容易的掌握使用,只需要点击就可以完成大部分的任务。魔兽世界和WORD就是典型的GUI程序。

   但其实图形界面的编程是相当复杂的。你能想象其实每次你都要画出显示器上所有的东西,窗口移动缩放时,你需要重画窗口里的每一样东西,在多窗口并存的时候,如果你的窗口被别人的窗口挡住了一部分(这是很常见的情况),你需要控制窗口上哪部分被显示、哪些被遮挡,鼠标移动的时候,你需要把被鼠标遮住的部分盖住,并重画鼠标,当鼠标点击时,你需要判断鼠标的位置,还要判断这个点击是你的程序的,还是别人的,当鼠标点击到菜单的时候,你要确定是菜单还是按钮,是哪个菜单项,然后执行相应的操作。所有这些情况,都必须解决。有些,操作系统可以帮你解决,但你要知道怎样才能让他帮你做,还有些就必须你自己想办法,种种问题使得图形界面的编程变得异常复杂。由于处理图形的需要,图形界面对硬件的要求也比较高。画面绚丽的3D游戏,远比记事本程序对系统的要求要高的多。虽然现代的计算机早已能够满足这些要求,但早期的计算机并不是这样强大的。

   所以,在早期(也不远,大约是6、70年代)的时候,程序的界面并不是图形,而是字符的。用户在键盘上输入文字,比如dir,系统找到相对应的命令,然后执行,执行的结果也是以一行行文字的形式输出在可以输出文字的设备上(当然也主要是显示器),用户阅读文字,进行下一步的操作。现代的一些科幻片,在表现黑客侵入或者是操作高级设备(比如美国国防部的核武器系统)时,往往出现操作员在啪啪啪啪快速打字,然后突然一回车,就大功告成的场景,很少会出现卡通化的菜单和工具栏。想想黑客帝国的那个接线员,你见过他什么时候抓着鼠标吗。这种方式就叫命令行界面(Command Line Interface),由于操作员通常是坐在一个操作台前,而这个操作台确实可以控制整个系统,所以也被称为控制台界面(Console Interface)。控制台下运行的程序,就是控制台程序,运行控制台程序的系统,就叫控制台环境。

    控制台看起来很高级,很酷很眩,黑客们操作的时候也显得很高深。其实反倒是比较容易编程实现的。因为你只要处理和输出字符就可以,系统自然会把字符放在屏幕上适当的位置。你不用去管字体大小颜色这些事,更别说窗口菜单鼠标这些不存在的东西,只要把注意力全部放在程序的功能上。电脑系统也不用消耗资源来画图,系统自然比较高效。所以,命令行界面一出现,就得到了广泛的应用,他的历史可比图形界面古老多了。和GUI程序比起来,命令行的程序通常很难看,操作也不直观。但由于它的高效和快捷,命令行方式的程序迄今仍然在使用,在很多时候,人们宁可使用命令行的程序来完成某些工作。在现代,FreeBSD、Linux和其它的UNIX系统,默认都是控制台环境,DOS就是一个标准的控制台环境,windows系列操作系统,也提供了控制台环境。而很多的GUI程序,借鉴控制台方式,仍然保留有直接使用键盘操作的方法。比如魔兽争霸,几乎每个命令都有快捷键的以加速操作。

实际上,很多系统管理员更偏爱控制台程序,除了他比图形化程序更高效之外还有一个原因。同样要增加实现一个选项,控制台只要增加一个输入字符作为开关,而图形界面至少需要增加一个按钮,想想看,屏幕上是可以增加的按钮多还是可以增加的字符数多呢。所以控制台程序往往更能实现纷繁复杂的功能,只要你记得住指令。

让我们打开在Windows下打开一个控制台环境并使用几个控制台程序感受一下。至于其它的操作系统,基本上本身就是控制台环境。就不需要演示了。假如你使用的是Windows2000或Windows XP,点击开始,找到程序->附件,在里面有一个叫“命令提示符”的快捷方式,点击运行他。如果是Windows 98,在程序组里设法找到一个叫MS-DOS方式的快捷方式,运行它。

你是不是看到了一个窗口,没有菜单,没有工具栏,只有标题栏和最大最小化的按钮,这就是win2000下的控制台环境,在这里就可以运行控制台程序。现在,输入"dir",然后回车。你看到了输出吧。这就是控制台程序的运行了。只要输入命令再回车,就可以运行了。再来运行一个,time。再来一个,ipconfig。最后再来一个,help。他给出了当前系统提供的各种命令,你可以看着提示分别试一试。其实不止可以运行这些,试试 notepad,你发现了什么。explorer,calc,cdplayer,freecell等等都是可以这样运行的哦。

   玩够了,好吧,输入exit,再回车。控制台环境就被关闭了。

   控制台程序容易编写,易于理解,所以对于初学者,控制台程序是理想的选择。本教程以后的部分所讲的程序,在没有特别说明的情况下,都是控制台程序。在学会了控制台程序的基础上,再转到窗口程序就比较轻松了。

好像不能建立一个单独的文件来编译

        ————工程和项目的问题

   有一件很明显的事情是,当软件项目变得很大的时候,仅仅使用一个文件来完成所有的内容是不现实的。以《魔兽世界》这款游戏为例,游戏中需要声音、动画、图片这样的素材,也需要地图编辑、人工智能、光影渲染这些不同的模块,在制作的时候,需要有不同的部门完成不同的工作,工作中所使用的文件和工具都不相同,不可能生成同一个文件。这时,就存在一个协调的问题。因此,对于流行大型的开发工具来说,他们不是以单个文件为单位进行处理的,而是以项目为单位。一个开发项目包含一个到几个工程,每个工程都包含有大批的文件,有源代码,有程序所使用的图片音乐等资源,还有编译时需要纪录的各种参数。每次编译都要完全编译整个工程(当然在优化状态可以只考虑更新变动的部分)。即使源代码只有一个非常小的文件,也必须为它生成一个工程才可编译。

   显然工程对于类似魔兽世界这样的大型项目的编写是十分必要的,但在新手练习的小程序上,使用工程就象你只想在家给你的小狗搭个窝,却拉来了整个中国长江三峡工程开发总公司,实在有点小题大做。而且,以后我们要编写很多这样的小程序,如果每一个都兴建工程,那会生成多少垃圾文件啊。所以,我们需要一种只编译单独文件的方法。幸运的是,不论哪种开发工具,他们都提供了这样的方法。虽然这种方法通常不会在菜单上直接出现,但他确实是常用的和正确的方法。

难道一切都要从头干起

       ————函数、API、类、控件、开发包与软件复用

   还有件事也很明显,随着工程项目的越来越浩大,每一次都从零开始编写一个项目是不经济也是不现实的。我们注意到,不论是程序还是源代码,都有以下两个特性。第一,他们都是人类智慧的成果,每一行源代码都凝聚了程序员的聪明才智,花费了开发者的时间和金钱。第二:几乎每一行源代码本身都可以毫不费力的零成本的被复制到另一处,另一个代码块、另一个程序甚至另一个项目。基于这样的特性我们认识到,如果能够重复利用已经编写过的程序和源代码,尤其是那些在使用中已经被证明强壮而正确高效的程序,就能够节约巨大的人力物力财力时间。即使只能使用其中的一小部分,也是了不起的成就。这就叫做软件复用。从编程出现的第一天起,人们就意识到这一点,并为实现软件复用而努力。软件复用最重要的好处就是能够让程序员不再把有限的智慧放到早已解决过的问题上,而是投身新的问题,也就是:不要再重复发明轮子。开放源代码的一个重要理由就是为了软件复用。

   软件复用的一个行之有效的方法是使用函数。所谓函数,就是把一些具有固定功能的代码段组合在一起,并给予一个名字。在需要这些功能的时候,只要在适当的地方填入函数的名字。在编程时使用函数而不是纯粹手工打造,就像在盖楼时使用砖块而不是用粘土堆砌,是不小的进步。盖楼时使用的砖块,既可以自己制造,也可以到市场上去购买。购买来的砖块,虽然有某些差异,但总是遵循某些共同特性。这些砖块虽然总是一块块地使用,但总是一车车的大量购买。函数也一样,市场上总是有专业公司提供函数出售,他们出售的函数按照功能聚集在一起,成为函数库。虽然不同公司的函数库可能具有相同的名字和功能,但内部是怎样完成的却不尽相同。大部分现代编程语言,在规定了语言本身的语法和词汇(当然其中也包括了函数的使用方法)的同时,还会规定一个函数库。这个函数库只规定了每个函数的名称和用途。至于函数的具体实现方案,有的是由语言本身直接定义,有的是由实现该语言的编译器的厂商提供。而使用这种语言的用户,只要在需要的时候使用,而不用去管函数库内部的问题,大大提高了效率。这个库就叫做标准函数库。通常,现成的函数库都是经过了大量的检验证明是高效而强健的,要比自己徒手打造的函数好用的多,所以在可能的情况下,要充分使用已有的函数库,尤其是标准函数库。C语言之所以如此强大,原因之一就是它有一个强大完备的标准函数库。而C语言之所以如此难学,原因之一也是在于它有一个强大完备的标准函数库。

   软件通常是运行在操作系统下。从软件复用的角度看,操作系统如果能提供某些通用的服务,程序就可以集中注意力做自己的事。这些服务包括文件读写、设备操作、网络通讯、窗口绘制等等。否则,程序就会把大把的精力浪费在这些基础工作上。幸运的是,几乎所有的现代操作系统都提供了这样的服务。这些服务以函数的形式出现,在程序使用这些服务,就象使用函数一样。这些函数形式的系统服务,就叫做应用程序接口(Application Program Interface),即API。遗憾的是,不同的操作系统,提供的API通常是不同的。使用某个操作系统的API而编写的程序,搬动到另一操作系统时,由于API不能相互对应,也就不能运行了。这就是编程要针对平台的原因了。

   



相关评论