当前位置:文档之家› C语言及C++初学者秘籍(附一部分推荐文章)

C语言及C++初学者秘籍(附一部分推荐文章)

C语言及C++初学者秘籍(附一部分推荐文章)
C语言及C++初学者秘籍(附一部分推荐文章)

C语言及C++初学者秘籍

本文原为本人在论坛所发若干帖,意在集中解决新手学习C/C++语言时将遭遇到的各类问题,网友反馈情况良好,集合修订后作为个人作品贴于此处。

本贴主要分析概念原理和解决方案,不讨论具体程序语法,立足于让初学者能运行起第一个程序。其他事宜如解释入门语法等本文基本不涉及。

目录

一、开始之前

FAQ 那是什么

为何有这篇FAQ

编程为何物

如果这就是编程,那语言是怎么回事

我为啥要学编程

听说编程很难,是真的么,那我能学会吗?

我真的可以么

还一定要有台电脑么

好吧你说服我了,我打算开始,该怎么做

那么,下一步怎么干

我碰到问题了,谁能帮我

我能看懂别人的程序,但自己做就觉得无从下手,怎么会这样

我英语\XX不会,咋办

关于态度、情绪和其他

二、选择C/C++语言

C语言是什么

C++语言是什么

为何要选择纯C

C/C++语言和其他语言有什么关系

我为什么要学C/C++语言

Python语言作者的另一推荐

三、一些重要的概念-----计算机原理

编程的对象是什么————计算机

程序到底是怎么回事————是操作而不是结果

为什么要编程————因为机器的特点

你们老是提到编译器,那是什么-----代码翻译机

给我解释下啥叫编程语言————各路江湖武功

语言之后要确定的事情------操作系统和平台

编程时什么东西最重要----源代码

我的程序和一般的程序不一样,什么原因————控制台和图形界面的差异

好像不能建立一个单独的文件来编译————工程和项目的问题

难道一切都要从头干起————函数、API、类、控件、开发包与软件复用

关于图形库的补充说明--------可选择的图形库

四、教材、习题和示例

能推荐几本好书么

首先是纯C的教材

然后是C++的教材

接下来是Windows编程

Unix/Linux/BSD系统

数据结构和算法

各种图形以及其它库

软件工程思想

找书的诀窍

光看书似乎不解决问题,难道要做题

OJ是什么

哪里有可用的OJ

哪里有代码示例可看

五、选择编译器

有哪些编译器可用

还有些可以配合编译器的开发环境

他们在哪里

怎么安装他们----特别解释MingW版GCC的安装

六、TC下常见的问题解决

用TC创建第一个程序

TC的库路径设置

TC下的图形编程设置

我的程序在TC下可以编译,在VC/GCC下为什么出错

七、其它编译器问题

用VC创建程序

用DEV-CPP创建程序

用MingW创建程序

用Lcc-win32创建程序

八、结束语

程序员成长的六个阶段

=========================================分割线================================ 一、开始之前

FAQ 那是什么

FAQ就是Frequently Asked Questions,也就是常见问题解答。这玩意儿通常是一些所谓的高手或者前辈为了节省回答新手的大量简单重复问题所耗费的时间精力而采用的一种偷懒手法。一旦完成,高手只要一努嘴,“看FAQ去”就万事大吉了。实在是居家旅行杀人越货之必备良药,因此在各大论坛已经有大泛滥的趋势。

本篇FAQ为学习C语言、C++语言的大量新手编写,重点是如何运行起第一个程序,不涉及语法、数据结构和算法等内容。如果你已经通过计算机二级或水平相似的考试,甚至你是职业选手或是大师级的人物,就不必再往下看了。同时,本FAQ只讨论C/C++语言,其他语言如Java VB python等均不涉及,虽然阅读本文前四章节也会对学习这些语言有所帮助,但深入学习还是请阅读这些语言的专门教材。

为何有这篇FAQ

本文是为那些对编程新手所准备的,如果你自认已经不是新手,那么请离开把时间放到更有用的地方。如果你是那种对编程一无所知,迫切想知道他是怎么回事,或者仅仅编写了几个小程序,却遇到一大堆问题,而在论坛或是其它地方又得不到帮助,但心中又有雄心壮志想要做绝世高手顶尖黑客或者想要以程序为生的入门级新人,那么你恰好是本文的服务对象,请详细阅读以下的文字,我想应该会对你有所帮助。而且请你了解,本文的这部分内容所要介绍的是那些普遍性的概念,与具体任何一种语言都无关。

正如我们所知,市场上充斥着无数的编程教材,同时可以肯定的是,目前已经面世的教材(包括正式出版物和网络上的教程),穷一人一生之力是看不完的。在这些书中,有大量的垃圾书,大量的平庸之作,还有少量的精品。而即使是这少量的精品,也不可能看全。既然书这么多,我为什么那么闲还要来写一篇呢,有这时间,我还能多画几张效果图挣俩钱花呢。

情况是这样的,市场上的书虽多,但其中几乎没有几本是面向初学者的。我所指的初学者,是指从来没有编写过程序,甚至是连编程二字都没有听说过的人。这样的书是如此之少,以至于要去购买或是阅读到他们都是很困难的事。在我个人的学习生涯中我认识到很多编程教材有个糟糕的倾向。他们要么是一下子告诉你所有的事,好像你能在千分之一秒中突然从菜鸟变成好手,要么就是认为有些事你早就应该知道,拿你当熟手看,导致你有一种赤身裸体被抛弃于猛兽横行的非洲旷野的感觉。你还没有穿上衣服走出帐篷,连刀子都没有摸过,他们就试图告诉你草原上有多少可以捕获的猎物以及他们的位置,告诉你几百种武器和毒药的使用秘籍,告诉你两百条以上的陷阱安放要领。你没有经过丝毫的练习,甚至还没有杀死过一只刚出壳的小鸡,他们就要你独自去捕猎数十头饥饿的狮子。这种看似荒谬的情况从过去持续到今天,至今仍然存在。这并不是说那些写教材的朋友都是傻瓜,这件事当然有它的原因,因为他们面向的读者是程序员。程序员就象是猎人,他们更换语言就像猎人更换武器一样,不管他使用哪一种武器,捕猎的基本原理没有变化,变化的只是武器的使用方法。对一个成熟的猎人而言,再强调基本原理就没有必要,所以教材们对人所共知的一些事也就避而不提。一个成熟的猎人,她心中的捕猎知识是浑然一体的,武器的选择,野兽的习性,陷阱的安放,怎样做和为什么这样做都结合在一起,没有哪一部分可以独立出来,一部分一部分的教给别人是极度困难的的,要教就只能混杂在一起。程序员的情况类似,知识体系是完整系统的,谈到一个问题总会牵扯到另一个,最后的结果就是别人总是希望并想当然的认为你可以一口吃成一个胖子。

这样的后果就是,一些很明显的事情,老手认为那是你应该知道的因而不予回答,而新人却发现没有任何地方可以找到解释,也不知道该到哪里去找答案。(不懂得如何找答案也是新人的特点之一)。有一个典型例子与这种情况很类似,鼠标,我们已经习以为常并且很熟练地使用着,但是很多第一次接触电脑的人那却是完全摸不着头脑的东西。在各地的论坛里,总有大量的新人提出诸如“学C++好还是VC,VC++好?”“C++也可以编窗口程序吗?”这样的毫无常识的问题。我的FAQ就是为了来一次性解决这种问题的。

编程为何物

编程就是编制程序。程序是让计算机发挥功能的命令的集合。程序有两种形式,让计算机真正执行的是电脉冲形式,叫机器码,程序员编制的通常是文本形式,叫源代码。使用一个称为编译器的工具,可以把源代码转变为机器码。而编程就是产生那些源代码的工作。这个工作类似于谱曲、编菜谱、写工作手册。我们知道,谱曲并不是一蹴而就的,往往需要反复的修改,直到最后满意为止,编程也是一样,接近工作时间的30%是完成粗制成品,剩下的70%时间是在不断的修改,这是相当枯燥和乏味的。有志于投身编程的朋友们,不要忘记这一点。

如果这就是编程,那语言是怎么回事

文本形式的源代码,其实有些规定的。就像我们和老美用英语交流。首先你得说英文单词,不能冒法语词汇日文假名出来,其次你得按语法讲话,不能一个个单词往外蹦。程序也同样有词汇和语法上的一些规定,这些规定就构成一门语言。显然任何一门编程语言都是人造语言。人造的东西,因发明人的想法而不同,就形成了不同的语言。

我为啥要学编程

这个问题有两层意思。首先是编程为啥要学,很简单,因为这玩意不是生来就会,就像木匠活一样属于一门手艺,自然要通过学习才能掌握。你怎么也得花上几年来学英语不是。

第二层涵义才是重点,为啥我要学它。答案因人而异。有人为了上学有人为了考试,有人为了求职挣钱,还有人就是吃饱撑没事做自虐。什么为了开发智力啊证明自己啊寻找成就感啊,那都属于自虐,在下便属于自虐一族。没啥说的,确定你的目的,也许只是好奇想接触下啥是编程,也许是有课业的任务,也许是想以后靠他找工作,或者是羡慕那些黑客。总之,想继续深入的,往下看,没信心的趁早走人,外面帅哥美女多的是,不要浪费大好时光青春年华在一台破机器上,ok?

听说编程很难,是真的么,那我能学会吗?

你觉得说中文难么?你能流利的说普通话是不是。但是你知道么,汉语是世界上最难学习掌握的语言。稍后我会介绍计算机的特征,你就会明白知道基本上编程这件事的难度等价于指挥IQ<20的壮汉。任何一种计算机语言的难度都不会超过英语,更比不上汉语。那么你认为你能不能学会编程呢。

请记住学会和学好是两个层次,就像中学生作文和报刊出版物之间的差异。达到学会那个程度,只要有小学三年级的知识基础就可以开始了,也就是识字就行。而如果要学好,那需要初高中毕业的文化水准,也就是应该略懂英文和解析几何。当然还有更高的技术层次,比如在相当于职业作家的水平上,你将被称为专业程序员。而如果你被称为大师,那就是诺贝尔文学奖。抵达那个程度需要付出艰苦的努力,至于怎么达到,不在本FAQ讨论之列。

我真的可以么

如果你已经看完前面的部分到达这里,显然你是确实想要学习编程的新手。不论你是为了什么目的来学习,在看了我上面的话之后是不是很有信心呢,不过我要打击你一下,不是谁都学得好编程的。人人学开车,但不是谁都能上赛道,舒马赫更是只有那么一个。

就像有些惊险刺激的游乐设施禁止高血压心脏病患者参与一样,编程作为一项耗费智力和体力的活动,对参与者也有一定的要求,先来看看吧,满足这些条件,你就可以放心大胆的开始。

先说体质要求。太祖说:身体是革命的本钱。健康的身体对编程大有益处,但并不是说残疾人就不能

参与。就目前的技术水平,除了脑瘫和目盲这两项,其他的肢体残缺根本不妨碍。霍金先生在这样严重的情况下还能持续研究的事实,还不够激励你么。

紧随其后的是足够的精力和时间。Dear friend,只要你能静坐20分钟安静的看完这篇FAQ,你的体能就达标了。如果你想告诉我,你能够一天在电脑前连续操作18小时以上,我要说的是,年轻人,虽然你很威猛,但请注意保养身体。只要每天您能抽出30分钟来学习,那你的时间也合格了。当然有更多时间确实会更好,不过也没必要每天12小时,编程并不是世界上最重要的事,我们还有别的事要做(这是对非职业选手说的)。必须认识到,学习编程重要的是持之以恒,而不是依靠爆发力,每天半小时比一周一次6小时效果好的多。

第三个要求是你要略微懂一点计算机。不错,只要略懂就可以了。因为这正是本文的主要目的:向略懂计算机的人介绍编程。那么,怎么才算略懂呢。

如果你能够前往这几个网站并浏览:https://www.doczj.com/doc/c82784872.html, https://www.doczj.com/doc/c82784872.html, 和https://www.doczj.com/doc/c82784872.html,,那么你的水平已经超过我的想象,完全能胜任接下来的学习。不用现在就前往,你知道怎样操作就可以了。

如果你还不会上网,没事。你会不会打字,不需要打得很快,也不需要会打中文,只要你能把键盘上的26个字母和十个数字挨个输入一遍我就认为你已经通过。然后,对于Windows用户,你能不能打开记事本程序,在里面打几个字并且存成一个文件。如果你说能,OK,你合格了。

你还不会打字或是不会用记事本?这样的话,你最好还是先学一学基本操作,否则本文对于你实在是毫无用处。

你找不到记事本程序,请让您边上的人指导一下,可能你还没有安装这个程序。有可能您不是Windows 用户,联系给你装机的人或公司,或是你们的网管,让她给你可用的文本编辑器,通常会是vi或Emacs,当然也可能是别的,只要你会编辑并存储一个文件,就可以了。

你连电脑都没见过??@#$%^&*!!!! 这样的话,本教程对你根本没有用处,你还是看见过电脑以后再来阅读本教程吧。

最后一点,你需要有顽强的毅力。编程并不象你想象的那样轻松,不是野餐和聚会。尤其是对于职业程序员都应掌握的C++,她可以用两句话来形容:三年不开张,开张吃三年。千万记住,C++被称为是真正的程序员使用的语言不是没有理由的,她的复杂度和性能超出你的想象。有无数的编程新手,在第一个月不到就放弃了,你最好确定你不是他们中的一员。毅力没有尺子可以来度量,在这里我只能先祝愿各位读者都能坚持到最后。

还一定要有台电脑么

不幸的是,到目前为止,是的。在老年时期,贝多芬可以凭空作曲而不依靠钢琴之类的东西。但几乎没有哪个程序员不依靠电脑而只在大脑里编写,尤其是开始学习的阶段。

作为编程的另一方面,一台合适的计算机也是不可缺少的。用各种语言所编写的程序被运行在各种各样的机器和设备上,从掌上设备到巨型服务器,从台式电脑到微波炉,所有能够自动运行的地方都有程序的身影。但是很遗憾,并不是只要能够运行的设备就可以用来进行编程的,这就像虽然可能洗衣机也能发出悦耳的声音,但你不能指望用洗衣机来录制流行歌曲(嗯,也许SONY有这样的产品,我保留意见)。我们主要还是用个人电脑来学习编程。目前大部分语言,所需要的电脑并不如你想象的那样高级(.net系列不在我们的讨论之列,他的集成环境对系统要求很高)。就我所知,即使是主频只有30MHz,640K的内存,也是可以用来编写小规模C/C++程序的,只不过感觉不是那么畅快而已。当然作为学习,我们还是需要有比较称手的设备。不错,最重要的就是称手两个字,所谓称手,就是不会由于设备的问题,妨碍你的思考,不需要高速的处理器,也不需要巨大的显示器,更不需要海量的硬盘,只要称手。编程不是豪华海上旅游,而是修行。修行不需要五星级饭店,但也要有破屋以遮风雨,否则感冒发烧了,怎样来修行呢。

那么还是来谈一谈电脑的要求吧。

只要你的电脑能运行DOS,就及格了。如果能够比较好的运行Windows 98操作系统(说实话,98死机是免不了的,只要不常死机就可以),硬件上就达到80分的要求了,如果能运行Windows 2000的话,那已经是满分了。如果比这还高档,那简直好的超出想象,甚至可以参加奥运拿金牌去。满分的那种设备,能够流畅运行.net环境的,在2008年1月份,全新的低于人民币一千元,二手设备甚至三百元不到。如果你实在囊中羞涩,可以考虑到毕业前夕的大学去碰碰运气,也许能遇到大肆的前辈们送你一台。在你看到本FAQ的时候,去任何一个电脑商场,随便购买一台,都可以符合要求。在下强烈建议你买一台自己的设备,那种自由是公共机房无法给予的。当然你执意要去机房的话,我也不反对。但你能看到这份教材,就连一台能运行win2000的机器都弄不到吗,怎么说现在也已经是双核时代了。

我希望你的机器上装着以下操作系统之一:Windows 2000, FreeBSD, Windows XP, Windows98, Linux ,MS-DOS或任何厂商的UNIX。我强烈推荐使用WindowsXP+SP2和FreeBSD这两个系统进行学习,本文中所有的程序在这两个系统都可以顺利运行通过,我将详细介绍在这两个系统下的设置,这对新手尤其重要。当然我也没有忘记其它系统的兄弟,相应的设置也不会遗漏。我没有提到Mac OS系列是因为我对她还不熟悉,但我不反对你拥有她。如果你的机器没有以上任何一个操作系统,请联系提供给你机器的人,如果不是你的机器忘记安装操作系统的话,那她极有可能是军方的机密设备,总之你小心为妙。

软件方面,依据不同的语言需要安装不同的软件。

如果学习C/C++。使用FreeBSD,Linux,Solias等UNIX系统的,推荐安装GCC,该程序是默认被安装的,总在系统的某处,初学者不必考虑版本问题。使用Microsoft操作系统的,建议使用VC 6.0或VC2005/2008,或者GCC的windows移植版。由于版权问题,如果不想破费的话,VC6要用VC2005的免费学习版来代替,BCB的命令行编译版和GCC的Win32版本来就都是免费的。GCC的Win32版有Dev-cpp,MinGW等不同发行形式。

其他语言都要按照相关的资料安装和设置。比如本文作者偏爱的Python语言,那是非常的方便,只要去python的主页直接下载对应不同平台的可执行包既可。

这些编译器怎样安装和设置我会在随后的章节里详细说明。毕竟,好多人的学习热情就是被这样的细节所消耗掉的。

除此之外,拥有以下两件法宝将使您如虎添翼。

一:一个被大家称作高手的喜欢玩计算机的人,这种人通常被叫做黑客或者极客。拥有他(她),你在遇到问题的时候,可以求他帮忙。记得给他点好处,吃个饭什么的。

二:便捷的Internet连接。可以上网意味着你可以干很多事,譬如可以和线上的高手(譬如我)即时联系,到论坛和usenet寻求帮助等等。这在有时是极有价值的。

好了,不要着急,还有一点点准备工作我们就可以出发了。

好吧你说服我了,我打算开始,该怎么做

首先确保你的健康状况和基本计算机操作水平,我上面说过的机器也已经找好了吧,从来没听说谁没有电脑就能学习编程的(以后科技进步到人机合一的程度,也许可以实现)。如果能有网络连接,那简直达到了完美的境界。

没人可以无师自通,天才也不行。所以你要做的第一件事是找一本好的入门教材,最好是经典作品。反复地看教材,要牢记一点,你所提出的大部分问题,教材上都有解释,只是你没有认真看而已。反复地阅读,直到你觉得你已经可以编写出那本教材了,才可以丢弃他。教材比老师好的理由之一是,你可以带教材上厕所去卧室,而老师不行。当然,老师也有比教材优越的地方,那就是他可以给你解释教材上没有的问题。但记住老师也是人,你不动脑子就去找他,他会厌烦的。不要鄙视你的老师,即使他其它方面不如你,至少在编程这件事上他能做你的老师就是他比你强的硬道理。

你以为光看语法书和背诵单词而不练嘴就能说好英语么,显然不对。编程也是,熟能生巧在任何地方都是一样的。首先看懂教材上的那些例子,确保看懂之后,按着他的思路把它默写出来,当你尝试过就会知道看懂和默写是两个完全不同的程度。然后就可以做书后面的习题,独立想,不要看答案或提示。等到整本书后面的习题你都能做对的时候,你就算入门了。然后去找等级考试二级三级的题目来做,等到也可以准确无误的时候,恭喜你,C语言(或者其他语言)可以算是通过了。如果你的目的是去考试,现在就出发吧。但如果你想要以编程谋生,sorry,你还欠火候。这其中的差别就相当于大学英语四级作文和畅销英文小说之间的差异。

那么下一步怎么干

只需要考试的朋友,不需要看这一段。想谋生或自虐的这边请。

通过C语言(或者其它语言)考试只是编程的第一步而已。你掌握了大量的单词并且熟悉语法还不能让你写出优美的英语小说。你要学习修辞手法、谋篇布局这类文学技巧,也需要掌握历史典故、谚语俗话和文化背景这些文字外的东西,如果要畅销,还需要超凡的主题生动的故事跌宕的情节。编程圈子里有和这些类似的玩意儿。

算法和数据结构就是程序里的修辞手法谋篇布局。人类编程虽然不过几十年,但运用程序所解决的问题,已经覆盖世界的每个角落各个方面。各种各样的问题,被前辈的大师提炼归纳。有些人们直接找出了解决的方法,有些人们找到了寻找解决方法的途径,还有些人们索性证明了在现阶段是不可能解决的。这些解决方案就被统称为算法。学习算法就是学习前人的智慧,少走弯路。连牛顿爵士都是站在巨人的肩膀上,除非你自觉比老牛还牛,凭空就能解决别人十几年才想清楚的问题,那我也无话可说。

学算法很简单,也是找教材,做习题。教材容易找,但新手往往找不到合适的习题。我的建议是,在完成教材上的所有习题之后,可以去找编程竞赛的练习题来做,也就是所谓的OnlineJudge,我会在后续深入讨论这个东西。

相当于历史典故、谚语俗话、文化背景的东西,就是各个编译器和平台上的接口和库了。假设现在有个程序要读写文件,不要误认为你需要亲自写个程序去控制硬盘的磁头伸缩,或者是光驱的透镜移动或者是U盘的地址定位。除非你是想做个window或者Linux那样的操作系统(那样的兄弟会来看这篇FAQ还真是奇迹),否则所有包括文件操作、网络通讯、人机界面(键鼠屏打印机)这些,都是由操作系统提供的现成模块,只等着你来使用。这些模块通常称为应用程序接口,不同的操作系统提供的不一样。在接口的基础上,很多编译器和程序员做了进一步的包装形成了库,你可以比直接使用接口更方便地使用这些库而达到同样的功能。

由于系统的不一致,编译器的不同,所以在学库之前,先要确定你所要工作的平台和环境,还有应用方向。Windows下编游戏和Linux下做数据库用的库是大相径庭的。然后就是同样的一套步骤,找教材,做练习。这个教材通常就是官方文档,windows下最好最全的就是MSDN,Unix/Linux平台有大量的文档,分布于man页和各种手册上,其他平台自行搜索。可以去找习题,但更好的方案是去找一个实际的小型应用,在使用中学习效果无与伦比。编写一个QQ或者BT,绝对能让你对网络操作部分了如指掌。在这个阶段,你已经可以写出实用的程序了,为什么还要执着于做题呢。

优秀的文学作品有个共同的特征,他们虽然立足于不同的本民族文化,但却关心全人类共通的思想感情,体现着终极的人文关怀,我们都会为奥塞罗流泪不是么。优秀的程序虽然应用方向不同平台各异,但他们一定完全符合计算机原理,用最合理的数学模型来展现。如果你想成为合格的程序员,计算机原理和相关的数学知识是一定要补习的理论课。

除了看书和做题之外,还有一个内容不可缺少,就是阅读别人的程序。没有哪个作家不大量阅读别人的作品,同样你也可以从别人的代码中吸取营养。代码就是程序的全部,是真实的实现方法,一切都在代码中,甚至有时长篇累牍的说明还不如几行代码清晰明白。今天的程序员是幸运的,开源运动的发展使得他们能够无偿而方便地得到世界上最优秀的并且是实际运作中的代码,几乎遍布任何应用领域。只要你有心,可

以找到任何想要的代码。但读代码也是辛苦的事,请阅读和你水平相当的代码,差距太大将会是严重的身心打击。

学习库和学习算法可以同时进行,在你完成这两个阶段的时候,你已经是一个合格甚至是优秀的程序员了。

超凡的主题跌宕的情节,这个东西其实就是你的程序的应用方向。如果说前面都是练习的话,这就是你自主创新的时候到了。很多人都只是在老板的安排下为了工资而被动做些既不喜欢又没有价值的流水线产品,少数人才有机会做自己喜欢的东西。想想看,QQ、3DMAX、WOW、IE、Apache甚至Windows都是多么知名的程序,有朝一日你的程序将会和他们一样知名。不过我还是不得不给你泼冷水,这需要不懈的努力、敏锐的眼光和少量的运气,只有极少数的程序员能做到这一点。不过,有梦想才能不断前进,不是么。

我碰到问题了,谁能帮我

郑钧说,记得没人会同情你,我亲爱的兄弟。这真是至理名言。编程这件事,基本上是不能指望有人帮你的。

当你遇到编程遇到问题,首先应该是去看编译器提供的信息。它可是最直接的来源,相当于案发现场,从没听说刑警不看尸检报告就直接破案的。现代的编译器已经不止编译那么简单,编译本身就能送出大量的提示,调试功能更是强大到可以让你检视程序运行的每一步都发生了什么变化,只要你能看懂。机器的问题,就应该用机器来解决,而不是用人的肉眼去检查。

然后就去查教材和文档。手边的教材能解决70%以上的问题,如果还不够,上网去查。如果找不到,请记住有个东西叫搜索引擎,国内最著名的两个,google baidu。99%的问题可以得到解决。

如果你有老师,可以试着向他请教。不要抱太大的希望,虽然他收你学费,但他也不是万能的。

如果还是不行,确认你已经努力过而没有答案,那么你可以考虑提问,去论坛、新闻组或者群,都可以提问。

在你确定要提问之前,请先阅读这篇文章《提问的智慧》

https://www.doczj.com/doc/c82784872.html,/jh/29/8675.html

https://www.doczj.com/doc/c82784872.html,/bbs/forum_posts.asp?TID=1581&PN=1&TPN=1

这个也行,《提问的智慧图片版》

https://www.doczj.com/doc/c82784872.html,/viewthread.php?tid=750796&extra=page%3D1

https://www.doczj.com/doc/c82784872.html,/bbs/forum_posts.asp?TID=1573&PN=1&TPN=1

我能看懂别人的程序,但自己做就觉得无从下手,怎么会这样

正如你所知道,刚开始学习的时候,我们总会作一些习题,等到后来涉及实际的应用程序,我们也可以把它们都看成是大型的习题。这个问题就变成了,为什么你能看懂别人的解题程序,而自己写不出来。这个问题其实每个刚开始学习编程的人都会遇到,你所见到的各位达人大牛都曾经有过这段经历。所以不要为这种情况而怀疑自己的能力。

为什么会有这样的情况出现呢,因为思维模式。

在小学的数学教材里,有一种题型,叫应用题。他会给出很多生活中的场景,然后让你用数学知识来解决。在解这种题时,其实分为三个步骤,首先是要提取出数理模型,比如常见的追击相遇这类问题,就要使用速度时间模型,然后把这个模型数学化,找出各个变量之间的关系,确定已知量和未知量,形成可求解的方程,最后求解。

编程的情况与此类似。首先要建立一个抽象描述模型,然后建立数学表达,接下来略有不同,不是亲自求解,而是给出求解的方法,也就是算法,最后把算法转化为程序。而新人通常之所以会卡壳,是由于

这个流程中有两个难关。建立模型不是问题,数学表达也不难,但找出算法却是非常艰难的事情,即使找到正确的算法,要把它写成正确的代码也不容易。新人常说我在学习XX语言,XX语言真复杂啊。其实学习语言本身只能保证你在最后一步,也就是翻译代码那里少出错误,即使你顺利的学习了一万种语言,你也会觉得编程很难,如果你没有学习算法的话。

让我们找个具体的例子来说明,假设现在有个题目要找N个正整数中的最大值。显然这个题目模型很清楚,本身就是数学问题,也不需要数学表达了。接下来就是解法,新手这时就卡在这个地方了。

刚接手这个题目,很多人就会想用一种类似人类的快捷操作,比如三个数,瞥一眼就可以找出最大值,四个数也毫无问题,甚至十个数也是一下子。这时我问你,你怎么把这个瞥一眼的动作表示成程序,另外如果N大于10000怎么办。哑口无言。原因是,人类的头脑过于聪明,可以同时处理很多事务,也就是可以并行处理一定量的数据(当然大规模数据就要另外对待)。而计算机,很遗憾,没有这种能力。有人要和我抬杠,现在不是有多处理器多核多线程等各种各样的并行处理的计算机了么。我要告诉你,那些都是不同层次的概念。目前这个时代的计算机,在出现革命性的变化之前,从CPU指令的层次来说,都是单线程单参数工作的。再说明白一点,这些机器任何时候只能一次处理两个数,而且其中一个还必须已经在CPU 内部了,任何N>=3个数相加都必须转化成持续的两个数相加,就是先把第一个第二个加起来得到结果之后,才能和第三个相加,照此重复求得所有的和。这时目前的科技无法改变的铁律。

这个时候我要请你记住一个重要的思想:编程中任何问题都要分解到足够小,小到机器可以一次解决的程度。回到刚才的那个题目:寻找N个正整数中的最大值。我们知道直接解决是不可能的。而按照刚才讲过的铁律,我们知道直接找到两个数中的最大值是一次可以做到的。怎样从2个扩展到N个呢。这里就是算法的天下了。一种很常见的想法是,完全可以从两个中找出最大值,再让他和接下来的一个比较,这就是N=3的情况,再把三个中的最大值和第四个比较,这就解决了N=4,以此类推,我们似乎找到了通用的算法,是的,找到前N-1个中的最大值,然后与第N个比较。不要怀疑,这个算法方向是正确的。接下来就是把它细化使他能变成代码。你注意到,首先要设法从1增加到N,而且每次前进一步都要做类似的操作。显然用一个循环来实现。每一次循环中,都需要将保留的最大值和当前的这第n个数比较,如果最大值比他大,那就保留,否则就要把最大值替换成新的。这就是条件语句的作用了。写完这个循环之后,还有些小细节,比如这个最大值在于第一个数比较之前应该是多少呢,太大的话,可能会比整个数列的数都大,这就会出问题,常用的做法是,就让他等于第一个数。然后包括读入那N个数,输出这个最大值这些琐碎的细节就属于收尾工作了,没什么可多谈的。

当然,即使是这样的小题,也不仅这一种算法。你记不记得有一种叫做单淘汰赛的机制,最后顶点的就是最大值。用在这个地方正合适。不过,如果要把这个淘汰赛算法实现成程序的话,如何实现分组,如何表达这个淘汰过程和取出顶点的值,正是算法描述里要解决的。这个就是排序里很有名的最大堆排序。一旦算法描述齐备,程序编写不过是打字校对的工作。

现在你明白本节讨论的情况的实质在哪里了吧,是的,是算法。为什么你可以看懂别人的程序呢,因为他的算法隐含在程序中已经被实现了。就像你读一段高明小说家的风景人物描写,总能在眼前浮现出那幅画面。但轮到自己写,却描绘不出那样的画面。一方面是因为你胸无成竹,不知道怎样找到可实现的算法,另一方面是即使你找到了算法,也是爱你在心口难开,也不清楚怎样去表达他。

算法总是从问题出发,通过一定的模式,逐渐细化再细化,直到可以直接转成程序。新手很难一下子领会怎样的算法是可以实现的。但好在新手接触的问题不是很难,算法通常很清楚明白,所以重点先要解决后面那个表达的问题。这就是为什么我建议各位默写教材上的例题程序的原因。很显然对于那些例题,只要你用心看过就会领会他的算法。那么,你再默写一遍,即使和他的原程序样子不一样,也总算是把这个算法表达出来了。反复这样练习,这个表达问题不就解决了么。而且在这个过程中,至少你学到了一个算法。基于此原则,任何你遇到的可以看懂的例程,我都建议你默写它。尤其是例如等级考试的题库的标准答案那样的东西,以及开源的精品代码。

我英语\XX不行,咋办

无法回避的事实,今日世界中的信息技术,绝大部分是欧美人的发明,更明白地说,是美国人的功劳。顺理成章的,各种资料文档技术手册,尤其是记载最新技术的,都是用美国通用语也就是英语撰写的。可能在其他领域不懂英语没有什么问题,但在IT业,不懂英语就是无法掌握最先进的技术,基本等于没有出头之日。

话说回来,不是说你一定要有个托福雅思的高分才能去学编程的。就编程本身而言。他所需要的英语水平不过是死记硬背三五个单词而已。你在看好莱坞大片时,一部片子下来总能记住主角和主要配角的名字吧,C语言全部关键字一共32个,而其中有6到7个的使用率超过78%。这样你还有什么可担心的。但是,要想成为高手,阅读大量的相关资料是免不了的,这个时候,英语就显出它的重要性了。

刚才谈过算法。前辈们已经总结出很多算法和产生算法的方法,我们可以直接学习。如果你积极进取,总有一天,你会发现有需要自己开创新的算法的时候。这个时候,数学功底会帮你很大的忙。也许只是数学工具在起作用,但更有可能是你的大脑受过的数学思想训练在帮助你。总之,为了前途着想,提高数学素养是没错的。这不是说多背数学公式和多做数学题,而是指一种数学的思维方式。

看不懂英语,那编程还有什么前途。数学不行,成为大师的希望不大了。不能上网,你完蛋一半。没有机器,难道要我买给你。指法不行,练去。

记得没人会同情你,我亲爱的兄弟。不会就去学吧,没有什么是不可跨越的障碍。

请记住这段话:在信息时代,任何主观障碍都不存在。如果你要研发什么新技术的话,只需要一台便宜的二手电脑、一张linux光盘和一个上网账号,再加上为之献身的决心,你就可以达到想要的任何编程深度。这话是一位大牛说的,那是谁,回想一下提问的智慧,然后自己上线查。

关于态度、情绪和其他

和技术无关,关于学习态度和方法的一些提示。

《循序渐进学编程》

https://www.doczj.com/doc/c82784872.html,/bbs/forum_posts.asp?TID=1353&PN=2

《一个程序员给初学编程人的建议》

https://www.doczj.com/doc/c82784872.html,/bbs/forum_posts.asp?TID=265&PN=1

《c语言学习经验--请不要做浮躁的人》

https://www.doczj.com/doc/c82784872.html,/bbs/forum_posts.asp?TID=1359&PN=2

《成为软件高手的几个忌讳》

https://www.doczj.com/doc/c82784872.html,/bbs/forum_posts.asp?TID=155&PN=8

《程序员四大忌》

https://www.doczj.com/doc/c82784872.html,/bbs/forum_posts.asp?TID=174&PN=8

=========================================分割线================================

二、选择C/C++语言

C语言是什么

C语言是一种计算机编程语言。语言是什么,请查阅上面的内容。

1970年前后,A T&T 贝尔实验室的Ken Thompson根据BCPL语言设计出较先进的并取名为B的语言,之后Dennis Ritchie在此基础上设计发明了C语言, 并首次在UNIX操作系统的DEC PDP-11 计算机上使用。随后,C语言和UNIX操作系统一起,攻占了计算机世界的大片领地。

在发展的过程中,出现了许多略有差别的C语言版本。1989年,美国国家标准研究所(ANSI)为C 语言制定了一套ANSI标准, 成为现行的C语言标准,就是所谓的C89。当然经过10年的发展,在C89的基础上又颁布了C99标准。现在流行的大部分编译器完全支持C89,部分编译器完全支持C99。对于初学者来说,掌握经典的C89即可。

C++语言是什么

C++和C的关系非比寻常。1979年,当Bjarne Stroustrup在新泽西州的Murray Hill实验室工作时,发明了C++。Stroustrup 最初把这种新语言称为“带类的C”,1983年,改名为C++。C++通过增加面向对象的特性扩充了C。因为C++产生在C的基础之上,因此它包括了C所有的特征、属性和优点。在这个意义上,你可以认为C++是C语言的进化,这个进化的原因是复杂性(complexity)。一旦一个程序的代码超过25 000~100 000行,就很难从总体上把握它的复杂性了。C++突破了这个限制,帮助程序员理解并且管理更大的程序。

当然今天的C++已经不只是C的进化那么简单,他还包含了其它很多很多的新内容,它是如此的复杂以至于你要花上几倍于学习C的时间来学习他。但由于他和C的历史渊源,所有支持C++的编译器都能支持C。因此他俩也就被合称为C/C++语言。

C++对于C的进化着重体现在规模上,几乎C++的所有新特性,都是为大规模编程服务的。如果说C 语言编程是单兵小组作战的话,C++编程就是集团军运动。

为何要选择纯C

在某些时候,我们不得不只使用C语言而不是C++,这种情况称为纯C编程。最常见是因为以下两个原因:

C++的语法很复杂,所以C++的编译器很难制作。因此在很多平台上没有现成的C++编译器,而C编译器因为足够简单,几乎到处都有,这时就只能用纯C。实际上最初的C++编译器也是用C语言来实现的。

仍然是因为C++很复杂,为了实现很多特性,做出的程序往往比用C做的类似功能程序体积要大很多,在程序的空间和时间要求比较高的时候,也只好选择纯C。

上面两种情况经常共同出现,实例之一就是嵌入式设备。各种单片机往往没有足够的内存和处理器能力,在上面实现C++编译器也比较困难,因此往往是纯C开发,而非C++。

C/C++语言和其他语言有什么关系

java 只要用一句话就可以概括,它是一种简化了的跨平台的C++语言。掌握了C++的人,学习java几乎是轻而易举。

basic pascal delphi(其实是objectPascal) perl python 还有其他诸如此类的语言,或者与c处于同一档次,或者与C++处于一个水平,学过C/C++之后,再去学习他们是很容易的事。作者个人比较偏爱和看好python,它的很多特性使他极有前途。

lisp Scheme是和C的思维方式完全不同的一类,被称为函数式编程语言,在人工智能等领域有奇妙的应用。有兴趣的朋友可以去领略,如果你要成为一个大师,至少要学习其中的一种。

我为什么要学C/C++语言

考试的人不用讨论这个问题,他们没有选择。如果我们有选择,为什么我们学习C语言而不是别的。

首先因为C本身是非常优秀的,他是世界上最伟大的编程语言之一。许多人认为C语言的产生标志着现代计算机语言时代的开始。它成功地综合处理了长期困扰早期语言的矛盾属性。C语言是功能强大、高效的结构化语言,简单易学,而且它还包括一个无形的方面:它是程序员自己的语言。它的设计、实现、开发由真正的从事编程工作的程序员来完成,反映了现实编程工作的方法。它的特性经由实际运用该语言的人们不断去提炼、测试、思考、再思考,使得C语言成为程序员们喜欢使用的语言。

在编程规模越来越大的今天,用C往往会遭遇协作型的问题,而C++在保持了C的高效的同时,实现了大规模协作的可能,因而成为了真正工业化的语言。

C/C++的优秀,使得他是主流的,在20世纪70年代末和80年代初,C成为了主流的计算机编程语言,至今仍被广泛使用。今天几乎所有的操作系统、大部分的(大于70%)的应用软件,90%以上的大型游戏都是用C/C++编写的。在对运行速度和资源占用有严格要求的领域,比如游戏、即时控制、嵌入系统,基本都是C语言内嵌汇编语言的天下。今天只有一种语言的性能比C强,那就是汇编,优化过的C程序的速度大约是汇编的95%-98%。但汇编基本不是常人用的。所以实际上C就是最快的语言。

主流的就意味着资料丰富。不论是编程时所需要的文档,还是学习的示例代码,甚至是平台提供的接口和库,C/C++语言版本都是最丰富的。业界的算法研究理论研讨,大部分都是C/C++语言,开源代码的78%以上是C/C++.任何一家硬件软件公司,当他开发一款能够编程的设备或是软件,必然会提供C语言的接口函数。其他的语言,就不一定有这样的好处了。不论是计算机图形学、加密解密还是计算机编程的其他领域,C/C++简直就是编程界的普通话。根据International Data Corporation 的统计,C/C++ 是全球开发者使用最多的编程语言。如果确实要投身编程界,不懂C/C++的话,根本就是Mission Impossible。

如果你还不明白,我只需举一个小例子。假设你现在有机会去学习一门外语,投入时间差不多,你会选择学习英语呢,还是斯瓦希里语呢。(斯瓦希里语流行于非洲东部,为肯尼亚坦桑尼亚等国的官方语种) 当然,并不是说其他语言不值得学习,存在即是合理,今天存在的各种语言,当然都有它存在的价值,多学一点没有坏处。没有人禁止你在学会英语的基础上再学习法语日语等等。况且为了找工作等现实原因,学习其他语言也是非常正常和必要的。无论过去、现在还是将来,天底下不存在哪一门语言非学不可才能成为高手,思想最重要,“不会XXX语言不算真正的高手”之类的言论实在无聊之至。学C/C++,主要还是通过他学习编程思想。真正的武林高手,难道会局限于手里的那把大剑吗。

但我们还是强烈建议初学者从C语言开始,因为除了上面所提的好处,C语言还足够的简单。初学者或许会觉得C很难,但请记住,那些是编程之难,不是C之难。当你学过三种以上语言的时候,就会越发体会到C的简单。

Python语言作者的另一推荐

虽然如上所述,C/C++语言有如此之多的好处,但他也不是完美无缺的,第一个致命弱点是复杂性。为了应付千奇百怪的需求,C++提供了很多奇妙的语法从而实现了各种现代编程特性,这就使得C++变得异常复杂。可以充分体现这个情况的一个事实就是,迄今为止,还没有哪个C++的编译器是100%完全实现C++官方标准的。如果有一个程序员对你夸口说他已经彻底掌握了C++的话,你基本可以断定他接触C++还没超过半年。幸好C语言还没有复杂性的困扰。但是开发效率也是C/C++的致命伤。因为过于接近硬件底层,C/C++程序在运行时几乎可以调动一切资源,取得最高的性能。但与此同时,C/C++程序员必须小心维护程序的运行状态,稍有不慎,轻则文件丢失内存泄露,重则死机甚至导致整个系统软硬件崩溃也是有可能的。所谓高收益必与高风险相伴就是这个道理。这就使得开发时必须小心谨慎,开发效率也就提不上去。

对于性能要求极高的程序,比如要求大量高速3D计算的计算机游戏、密集科学计算的工程软件、同时应付巨量用户的网页和数据库服务器,使用C++是当仁不让的选择。但是对于很多应用来说,些许的延

迟是可以忍受的。举例来说,在某个工程中想要得到圆周率的后十万位,如果此时我们不在乎0.25秒和1.25秒运算时间之间的差别的话,就可以选择开发效率极高,而计算速度相对较慢的其他语言来实现。

在所有这些其他语言中,本文作者强烈推荐的是Python语言。

由创始人Guido van Rossum在1989年圣诞节期间创造出来的Python语言,是一种面向对象的解释性的计算机程序设计语言,也是一种功能强大而完善的通用型语言,已经具有十多年的发展历史,成熟且稳定。Python 具有脚本语言中最丰富和强大的类库,足以支持绝大多数日常应用。这种语言具有非常简捷而清晰的语法特点,适合完成各种高层任务,几乎可以在所有的操作系统中运行。

Python语言有两大关键特点。首先他被称为是一门清晰的语言。因为它的作者在设计它的时候,总的指导思想是,对于一个特定的问题,只要有一种最好的方法来解决就好了。这在由Tim Peters写的python 格言(称为The Zen of Python)里面表述为:There should be one-- and preferably only one --obvious way to do it。这正好和Perl语言(另一种功能类似的高级动态语言)的中心思想TMTOWTDI(There's More Than One Way To Do It)完全相反。Python语言是一种清晰的语言的另一个意思是,它的作者有意的设计限制性很强的语法,使得不好的编程习惯(例如if语句的下一行不向右缩进)都不能通过编译。这样有意的强制程序员养成良好的编程习惯。简单来说,几乎所有的python程序看起来都是一个样子的,而相对的,人们说,到哪里去找一段随机字符,读一段perl程序就行。

第二个特点是他被称为胶水语言。哦,这可不是说他会把你的手指给粘住。他的意思是他可以象胶水一样,把用其他语言制作的模块拼合起来。很多人是这样用python语言制作大型程序的:他们先用python 做出一个可用的程序,再把其中最影响性能的部分用C/C++语言重新写成模块(在已经满足要求的时候,根本就无需替换)。不用担心配合的问题,python的可扩充性完全可以胜任要求。可扩充性可说是Python 作为一种编程语言的特色。新的内置模块(module)可以用C/C++或其他语言写成。同时也可为现成的C/C++或其他语言模块加上Python的接口。这样一来,我们既能充分享受到python快速开发带来的效率,又能够实现足够强大的性能。

再加上设计极为出色的三大内置数据类型:异构列表、元组、字典和从函数式语言学来的列表解析、对象自省、方法动态生成等突出特性,使得它的功能变得极为强大的同时程序又相当简洁。想想看,你能在C程序运行的同时,改变自身的代码让他再次以另一面貌运行么,python就可以轻松地做到。同样的功能,用python实现所需的语句仅仅是C的十分之一到二十分之一,而开发(包括调试)所需要的时间更可能只需要百分之一。

Python在编程领域的占有率一直处于稳步上升之中,根据2007年末最新的统计数据,Python排名第七。前六名分别是Java,C,VB,C++,PHP和Perl. 作为一个很年轻的语言,Python的位置已经相当令人振奋了。随着微软将Python纳入.Net 平台(官方行为),相信Python的将来会更加强劲发展。Python 很可能会成为.Net平台快速开发的主流语言。欲了解这方面情况,请参考Iron Python的相关信息。

著名的搜索引擎Google 大量使用Python,NASA等大站也在用。更加令人吃惊的是,在Nokia智能手机所采用的Symbian操作系统上,Python成为继C++,Java之后的第三个编程语言!可见Python的影响力之巨大。

作者个人的观点是,Python语言是少有的一种可以称得上即简单又功能强大的编程语言。对于工程师会计师这类非职业程序员(本人就是),在平时需要某种语言来编写程序解决一些小问题的时候(例如做个土方计算,分析某种投资的收益,批处理一些文件的改名压缩之类),python是比C语言更好的选择。即使对职业程序员,python也是称手的工具。总之,python就是手边的语言。

=========================================分割线================================

三、其它一些重要的概念—计算机原理

编程的对象是什么————计算机

如果你看到的这篇文章是电子版的话,你眼前的东西就是计算机,也就是俗称电脑的东西。这样的说法对普通用户来说是已经足够了,但是电气工程师认为一堆电路板、缆线、马达、和机壳的组合才算,联想的销售人员认为他们卖的那些方块才是计算机,而中央军委的人大概觉得银河5才能称得上。程序员的看法和他们并不完全相同。程序员看来,只要能自动计算的东西,就是计算机。这个说法的重点在于自动和计算这两个词。广义的计算是指能对外界的某种输入做出反应,不一定就是数学运算。比如电梯就可以对按键做出反应,所以她也是能计算的。自动是说计算是通过自身的运作来完成的,不需外界干预。在有电的时候,电梯就可以自动运行,这样看来电梯也是计算机。算盘虽然能计算,但不是自动完成的,如果把打算盘的人一起算上,那就是不错的计算机了。使用指纹或虹模的智能锁、秦始皇陵里的机关和自动钢琴似乎也都是一种计算机。情况确实是这样,计算无处不在,计算机也无处不在。如果你有兴趣的话,可以把我们的世界看作一台巨大的计算机,然后就觉得我们是生活在Matrix里,不过打住,我现在没兴趣和你讨论哲学问题。通常在实际编程中,程序员只考虑现代数字电子计算机,也就是使用电能为动力,在运算时以电子电路和逻辑代数为基础的计算机。他们用途广泛,种类也是极其繁多,手机、PC、服务器是比较常见的样子,电梯、收银台、智能门禁则是各种隐藏的版本。虽然设备的外在形式千变万化,但现代电子计算机的基本原理和体系结构并没有太大的变化,这体系结构的问题我们会在以后详细讨论。就本文的读者—新手程序员而言,回答什么是计算机这一问题,请回头看本段的第一句话。

程序到底是怎么回事————是操作而不是结果

计算机本身什么也做不了,必须依靠程序来指挥他做事。程序就是操作流程的顺序,或者说是顺序排列的多个操作过程,他是方法的描述。

有一次我的朋友王二老板要做家具,这可是他的老本行。他先把原木分割成木条木板,再把木条木板弯曲到指定的形状,然后把他们放置到适当的位置,接着设法固定他们,最后雕花抛光和上漆,一张漂亮的摇椅就做好了。这整个的流程如果记录下来,就是一个程序。任何程序都有三个要素,执行者、操作对象(也称为资源)和操作方法(指令)。在做家具这个程序里,王二就是执行者,木头就是他所对付的资源,在指令的持续作用下,木头(资源)的状态(如形状大小、颜色位置等)不断发生变化。最后,在程序结束时,木头变成了家具。

电脑程序和上面一样,是方法的描述。只是这些程序的执行者不再是人,而是CPU,命令也变成了CPU 的指令(无法想象怎么给CPU下“吃口菜”的指令),而资源则是CPU可以改变其状态的东西,通常是内存,当然端口硬盘等等也是,不过一般应用程序都只使用内存就可以完成工作。

有一点要注意,CPU其实并不知道自己在做什么,是程序在指挥CPU的运作。这一点比较难理解,让我举例说明。来看一个算盘的计算,要使用算盘,只需要一件东西:口诀。记熟口诀(当然还有它对应的操作),就可以用算盘计算。在这个用算盘计算的过程里,口诀就是程序,指导着计算过程。算盘自身并不知道自己在计算,他只产生了物理上的一些变化(算珠位置的变化),做珠算的人同样也不需要知道,他只需要按照口诀调整算珠的位置。当程序结束的时候,算珠必定会处在某个位置上,这个位置的状态可以按照某种约定被读出,被读成某个数值,比如下面4个算珠全都在中档而上面的珠子没有落下的状态就是4。

操作和储存状态的设备并不需要知道状态是怎么转换成信息的,转换由阅读者来完成。显示器在显示图像的时候,总是这样进行:

坐标(1,1)黑色、坐标(1,2)白色、坐标(1,3)白色、坐标(1,4)白色、坐标(1,5)白色、(1,6)白色、(1,7)白色、(1,8)白色、(1,9)白色、(1,10)黑色……(2,1)黑色、(2,2)黑色、(2,3)黑色、(2,4)白色、、(2,5)白色、(2,6)白色、(2,7)白色、(2,8)白色、(2,9)白色、(2,10)黑色…………虽然显示器只是在适当的坐标显示黑色或是白色,但我们

却在显示器上看到了文字、图片和动画,你不会认为显示器知道这些是鸟山明的漫画吧。

计算机也是一样。比如计算圆周率的程序,CPU只是不断地对某一块内存进行操作,当程序结束的时候,这块内存恰好处在某种特殊的状态。而按照事先的约定,这个状态在被读出来的时候,它正好和圆周率相同。于是我们说,算出了圆周率,其实CPU只是在那里象手指头一样拨动内存的算珠而已。这种算珠极其简单,他只有两个位置,0和1,拨动它也很方便,电流就可以,但这种算珠实在太多,使得他们能组合起来表示很复杂的信息,就象只有黑白两色的屏幕点当数量足够多的时候,就可以用来表现有趣的漫画。

所以程序代表人期望电脑能做的事(注意不是电脑要做的事,这一直混淆着许多人),当人需要做这些事时,人提供指令,再给出某些资源以期电脑能对其做正确的改变。程序只是方法的描述,本身是不能发生任何效用的,直到它被执行,人为给定它一块内存,告诉它计算结果的精度及计算结果的存放位置后,他通过控制CPU才改变人为给定的这块内存的状态以表现出计算结果。

通常,我们把计算机的物理实体部分称为硬件包括电路板、机箱、键盘鼠标等,而把不可见的非实体部分称为软件,软件大体就是程序和主要由程序产生的数据。广义的说,乐谱、菜谱、工作手册、仪器的操作说明也是某种程序,我们不妨称之为类程序。

为什么要编程————因为机器的特点

编程这件事存在,完全是迫不得已。人们发明了计算机,想让它做事。但机器有三大特点,使得如果要让机器做事,完全不像吩咐人那么简单。

第一个特点就是机器很傻。很多人希望自己像计算机一样聪明,我说如果那样你就完了。举例来说,从三个数里选出最大最小值,人类可以一眼就看出,但机器只能先从两个里找出最大的,在把这个最大的和第三个比较,然后再这样重复一遍找出最小值。如果是四五个数,机器也是这样反复操作(我想这个例子我已经讲过了)。这就类似工地上搬砖,人类的做法一次搬很多很多砖,用推车或者别的把砖码得高高地然后运到目的地。计算机的做法是每趟只搬一块砖,你没看错,每趟一块。

那为什么计算机这么厉害呢,因为他的第二个特点,快而不乱。机器可以不知疲倦地用同一方法,重复重复再重复地做某件事,而且每次重复都相当的快。这一点是人类做不到的,让一个人搬一堆砖,也许没什么问题,但是一车砖就会让人疲惫不堪,如果有一轮船的砖,想必大多数人想都不想就放弃了,即使有坚持去做的人,他的动作质量也只会越来越差。但机器不同,他搬砖不是每趟一块么,但他每趟来回的时间很短,比如低于0.00……001秒,不管砖头有多少,十万块也好十亿块也罢,按同一方法处理,既没有差别也不会厌烦直到全部处理完。从总体来比较结果,机器就比人强了。还是以选最大最小数为例,人可以用肉眼检视三四个数,但超过100个数就要用其他的方法。对机器来说,三个和三万个数只是重复次数的差别。单调快速的重复,这就是机器的诀窍。

更重要的一点,机器和我们言语不通。就是说,我们不可能一抬手一挑眉毛就吩咐他做事。不要和我抬杠说你可以用鼠标画圈让机器做事,也可以声控。那都已经不是纯粹的机器了。机器和我们处在一个不同的感知空间,所以他不能理解我们的话语。我们要命令他,必须用他能够理解的形式。从根本来说,就是电脉冲。

基于这三个特点,要让机器做事情,就必须让把我们的要求转化成最简单适于重复的命令集合,而且是电脉冲形式。比如我们要让机器在屏幕上显示一幅图,首先我们要把这幅图分解成很多很多的小方格,也就是所谓像素,每个像素只有一个颜色,每个颜色都用一个很长的数字表示,然后所有这些数字转化成内存里的电平信号,再用另外的电路信号来一个个的把这些电平送到显像电路。所有这些电平和信号的集合就是程序。而编程,就是制造这些程序的工作。

也许有一天,我们不再需要编程序,程序员这个职业也不复存在。不过我想如果那天到来,那就是机器已经能完全理解人类的语言和思想的时代了。在肉眼所及的范围里,似乎还看不到呢。

你们老是提到编译器,那是什么-----代码翻译机

这个问题经常被问到,我在前面的文字略微解释了一下。不过我不介意再解释一次。

是的,我刚刚说过,程序其实是电脉冲形式的指令的集合。对机器这是绝对正确的。但你认为人类可以直接操作电脉冲么,当然不能。所以最早的时候,程序员们是通过反复的拨动开关或者插拔插头来做这件事的,就像老电影里的电话接线员和发报员。后来技术进化了,人们可以把脉冲信号设置在打了孔的纸带上,然后让纸带穿过有灯管的感应器,有孔电路就通,没有就是断,由纸带机实现了在电脉冲和纸带之间转换。老电影里的工程师们经常拿起一条长长的纸带来阅读。真是高深莫测啊。不过即使这样,要理解程序还是很困难,更别说阅读编写和修改了,人毕竟不是机器。其实人们最习惯用来表达思想的方法是文字,于是人们设想能否直接写出文字形式的程序。通过不懈的工作,这个目标实现了。今天人们可以写出文本形式的称为源代码的程序,然后再利用特定的工具把代码转换成机器能理解的电脉冲形式,也就是目标程序。这种转换工具就叫做编译器,作用相当于翻译,以前是纯粹的机电设备,到了现代他也成了程序的一种。

从某个角度来说,其实没有任何人能被称为程序员,编译器才是真正的程序制造者。人所制造的只是源代码。从这个角度往下想的话,其实是程序在制造程序,换言之,程序在借助人类之手自我进化。

在这里顺便讲解下编译和解释的差别。编译器的工作本质上类同于翻译,而我们知道其实翻译有口译和笔译两种工作模式。程序员写完所有的源代码,由编译器一次性转为可执行文件留待以后执行,这种类似笔译的模式我们称为编译。程序员每次输入一行或数行代码,编译器马上把他转换并执行,并等待程序员的后续输入,这种类似即时口译的方式就称为解释,此时编译器就被叫作解释器。C/C++ pascal等语言是编译型的,perl python等语言就是解释型的,java语言很特殊,他先编译成一种中间代码,然后在不同的机器上边解释边执行,这样就能实现跨平台运行,成为半编译模式。微软的.net也是这种机理。现代的新型解释性语言很多都是半编译的,兼顾了运行效率和跨平台性。一般来说,编译型要比解释型的运行效率高些,因为不需要等待程序员的输入,也便于系统优化,但解释型在编程的时候容易排错,界面友好,而且通常程序编写比较方便。不管用哪种语言编程,你总需要一个编译/解释器。

现代的编译器,往往不止是编译器,他还会包含有着色和搜索等功能的代码编辑器,支持单步调试并行调试的调试器,能够读入文件的多个版本并进行比较分析的版本控制,编辑图标等的资源编辑器,在大型项目中用于统一协调的项目管理,和用于自动化代码生成的向导工具等等。这样的编译器,我们就称它为集成开发环境(IDE : Integrated development environment ),最著名的代表就是微软的VisualStudio系列。

给我解释下啥叫编程语言————各路江湖武功

菜谱、仪器的操作说明可以用法语来写、也可以用中文来写,不影响实质效果。因为人类生存在同一个四维物理时空中,具有相同或类似的感知。虽然人类的语言五花八门,但都可以通过翻译得到正解。仪器操作说明、一般的菜谱,所描述的都是人类世界的事物,人类可以理解,因此它们可以用人类的语言来描述。但计算机程序显然与菜谱有不同,他是指挥计算机用的。首先CPU所能感受到的物理空间和与人类的感受严重不同,很多概念根本无法传达,其次没有大脑的计算机并不懂得人类的语言,何况人类的语言并不那么完美,很多事不能精确的描述,所以人类的语言不论英语还是中文都不能胜任这个任务。这个情况和音乐有点类似,解决方案是发明一种人造语言专门用于这个领域。比如五线谱就是一种专门的供音乐使用的人造语言(简谱也是,不过那是国人的自创,有点地方话的味道)。于是就有一些专门的纯粹用于计算机的语言被创造出来。

其中最早的一种基于电路原理,直接用0和1来表示电路的开关通断,不断的拨动开关,就形成了程序。这种语言就是机器语言,它可以直接被计算机听懂,但遗憾的是,人类虽然可以看懂这种语言,但它不符合我们通常的交流习惯,很难被人所阅读,更不要说修改了。

后来人们提出这样一个方案,我们可以先按某种方法和规则,生成一个我们能看懂的指令序列(就是源代码),再通过某个转化的工具(就是编译器),把它变成机器可以运行的指令(也就是可执行程序)。这

个我们能看懂的指令序列的规则的总和(也就是词汇和语法),就是我们通常说的计算机语言,为了和机器语言相区别,被称为高级语言。相应的规则,被称为语法。由于语法和词汇的不同,常见的语言有很多种,本文将介绍的就是C/C++语言,其他著名语言有BASIC、Pascal、JA VA、COBOL、Python、汇编等等,他们各有所长,在不同的领域发挥着作用。但由于计算机的体系结构大致相同,这些语言也大同小异,具有共通之处。这情况很好理解,通常真实世界的拳法看起来都有点相似,只有漫画这类幻想作品里才会有手脚飞出或者口吐火焰眼下喷水这种怪异的事情发生。这个编程语言的共通之处也就是我前面讲过的算法和数据结构、平台和库这类东西。由于历史原因,大部分计算机语言借用了部分英语的词汇作为基本词汇,但绝不是说必须先学英语才能学习编程。如果只因为那几个屈指可数的英文单词而放弃学习编程,我只能说这样的人乘早离开为好。

顺便提一句,本文作者(也就是我),一向认为那个叫易语言的中文编程语言是个不折不扣的笑话。理由很简单,其他流行的语言都有自己的独到之处,就像武当剑少林拳打狗棒一样在江湖上占有一席之地,而这个语言除了有几个中文标识符之外,一无所长。而这几个中文标识符也不过是使用了文本替换的方式把C语言的几个特定词汇换成了意思相对应的中文而已。任何一个文本编辑器都可以做到这一点。形象的表现一下,这就是有个猥琐的家伙特地身穿全套阿拉伯长袍练了整路正宗少林长拳然后大声叫嚷这就是他发明的具有民族特色的中东石油大亨拳。

语言之后要确定的事情------操作系统和平台

在众多的程序里,有一大类特殊的程序,他们就叫操作系统。操作系统是最基础的程序,他让计算机运行起来,所有的硬件都做好准备,接受别的程序给予的指令。相对的,其他程序就叫应用程序。操作系统和应用程序的关系,就象人的基本意识和数学水平一样。想让一个连基本意识都没了的人(植物人)参加数学高考,看来你和我都疯了。一般的计算机都是硬件、操作系统和应用程序相互分离的,需要的时候分别安装。有些特殊的设备直接把操作系统做在硬件里,比如各种电子游戏机,可以开机,但是要有游戏光盘或游戏卡才能玩,还有些计算机把操作系统和应用程序都做在一起,放在机器内部,前几年很流行的俄罗斯方块掌上游戏机和电子宠物就是这样的设备。但总体而言,没有操作系统的计算机,就像没有灵魂的身体,是无法动弹的。这种情形,回想一下你那只进了水彻底完蛋了的手机就明白了。

编写操作系统要比通常想象的困难的多,它涉及到大量的背景知识和底层操作。所有连本篇FAQ都还不能消化的新学者应该完全打消诸如自己制作操作系统的念头,有实力之后再来尝试也不迟。

提供给钢琴和手风琴的乐谱并不是完全一样的,这是一种共识。为什么,因为这是两种不同的乐器。同样,在这个世界上有很多种的计算机,他们相互之间的差别也很大。每一种计算机都需要操作系统,而某一款计算机可能有好几种操作系统可以使用,就象黄种人可以说中文,也可以说日语。特定的计算机和特定的操作系统的组合,就被称为平台。就像钢琴曲不是给京韵大鼓使用的,对印度土著说中国成语也不会有什么好效果,编程通常都要针对某种平台来做。有一些高级语言号称能够跨平台,也就是可以在很多平台上运行,但作者认为那样多少会有性能上的损失或者意想不到的问题出现,所谓有得必有失就是这个了。

就像我在前面谈到库的时候已经提到过,如果你想要在编程上面有所成就,你不得不选定一个平台深入地钻研。个人认为,初学者不适宜同时在两个完全性质不同的平台上学习,不同的特性绝对会把你搞晕,在你确认掌握了一个之后再学习另一个,相互借鉴的作用才能体现出来。

编程时什么东西最重要----源代码

按照一般编程语言的规则编写的程序通常都是文字形式的,虽然还不能直接执行,但可以转换成可执行的程序,它是真正程序的源头,于是被称为源代码。编程的主要工作就是在制造源代码。由于源代码几乎人人都能看懂,而源代码又可以生成真正的程序,所以取得了源代码,就相当于取得了程序的一切,包

括程序本身和程序背后的思想。基于此,大型软件公司要把他们的源代码严密的保护起来,而开源组织的第一条规则就是开放源代码。而作为初学者的你,请妥善保管你所写下的每一段源代码,这都是你积累的财富。

我的程序和一般的程序不一样,什么原因----控制台和图形界面

当你开始照书上的例子编写第一个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不能相互对应,也就不能运行了。这就是编程要针对平台的原因了。

有时候,有些大型程序,比如Autodesk公司的AutoCAD,当你对他的某些功能不满或是感到有改进的必要时,它提供了编程改变的可能,相对于第一次开发来说这就叫二次开发。二次开发时,原始程序所提供的那些服务也被称为API。

使用砖块盖楼确实很方便,但如果能使用预制板,那就更方便了。比函数更高一级的可以复用的程序模块叫做类。类的使用比函数复杂,但是它可以更广泛的复用,是更高级的软件复用形式。类,同样可以聚集成类库。能够使用类的语言,就会规定标准类库。C++比C更强大,更难学,就是因为,C++除了具有C所有的函数库之外,还有一个完整强大的标准类库。

在类库当中,有一种很特殊的类,称为控件(control)。控件在快速的窗口程序开发中特别有用。它可以实现拖放式的编程。举例来说,想要编写一个有一个按钮的窗口程序。那么只要先创建一个窗口程序的工程,这个工程会自带一个窗口控件,而且直接显示在工作区里,然后再用鼠标把按钮控件从控件板上拖到窗口里需要的位置,按钮就摆放好了。至于按钮的功能,就需要程序员来编程实现。将来编译运行之后,程序的外观就和设计的外观一模一样。控件极大的提高了编程效率,但因为它需要自动生成某些代码,所以需要编辑环境的支持,支持控件的编辑环境总体来说比较少。控件的总和,就是控件库。

所有这些,函数、API、类乃至控件,开发必备,就象旅行时必需携带的行李一样,于是被统称为开发包(SDK : Software Development Kit)。最著名的SDK就是windows提供的Win32SDK了。有些开发包是编译器自带的,如标准库等等。有些包是第三方厂商提供的,比如微软的DirectX系列开发包专为游戏编程所设计。所有开发包都需要集成开发环境(内带编译器)的支持,有的要编译器提供内部实现,有的要编译器给于连接,有的要编译器生成代码。不同的编译器提供的方式不太相同,这就造成了编译器之间的

C语言文本编辑器

附件二116755043.doc 【学生用】 西北农林科技大学信息工程学院数据结构与C语言综合训练实习报告 题目:文本编辑器 学号2011013228 姓名马跃 专业班级电子商务112 指导教师景旭 实践日期2010年7月5日-7月16日

目录 一、综合训练目的与要求 (1) 二、综合训练任务 (1) 三、总体设计 (1) 四、详细设计说明 (2) 五、调试与测试 (9) 六、实习日志 (14) 七、实习总结 (15) 八、附录:核心代码清单 (15)

一、综合训练目的与要求 正文本综合训练是计算机科学与技术、信息管理与信息系统、软件工程专业重要的实践性环节之一,是在学生学习完《程序设计语言(C)》、《数据结构》课程后进行的一次全面的综合练习。本课综合训练的目的和任务: 1 巩固和加深学生对C语言、数据结构课程的基本知识的理解和掌握 2 掌握C语言编程和程序调试的基本技能 3利用C语言进行基本的软件设计 4 掌握书写程序设计说明文档的能力 5提高运用C语言、数据结构解决实际问题的能力 二、综合训练任务 本综合训练是计算机科学与技术、信息管理与信息系统、软件工程专业重要的实践性环节之一,是在学生学习完《程序设计语言(C)》、《数据结构》课程后进行的一次全面的综合练习。本课综合训练的目的和任务: 1巩固和加深学生对C语言、数据结构课程的基本知识的理解和掌握 2掌握C语言编程和程序调试的基本技能 3利用C语言进行基本的软件设计 4掌握书写程序设计说明文档的能力 5提高运用C语言、数据结构解决实际问题的能力 三、总体设计 1.设计题目------文本编辑系统 2.已知技术参数和设计要求 1分别统计出其中英文字母数和空格数及整篇文章总字数; 2统计某一字符串在文章中出现的次数,并输出该次数;(采用模式匹配算法) 3删除某一子串,并将后面的字符前移; 4实现某一个字符的替换; 5实现某一个字符串的替换;

C语言期末复习文档.docx

期末考试题型: 程序设计基础题型举例 ?、选择题 1、 C 语言规定:在一个源程序中,main 函数的位置—B ________ 。 A. 只能在程序头部; B.可以在程序任何位 置; C.必须在#include ^Uttdefine 语句后面; D.只能在程序最后面。 2、 在使用TurboC2.0环境编辑程序时,运行某程序使用的菜单项为_A_。 A. RUN B. FILE C. EDIT D. OPTION 3、 下面标识符中止确的是—B _______ o A. $a#b B. sum C. 1A23BC D.Y ?M ?D 4、 在C 语言屮(以16位PC 机为例),存储一个整型、字符型、双精度实型变量 所需的字节数是 ____ C_0 A.4、1、4 B.4、1、4 C.2、1、8 D. 2、2、8 5、 下面的变量说明中 _____ B ________ 是止确的。 A. Char : a, b, c ; B ? Char a, b, c ; C. Char a ; b ; c ; D. Char a, b, c 6、判断char 型变量ch 是否为大写字母的止确表达式是—C ________ C. (ch>=/A ,)&&(ch<=T) D. (W<= ch)AND(/Z ,>= ch) 7、已知int x=10,y=20,z=30;以下语句执行后x,y,z 的值是 ____ D _____ if(x>y) z=x; x=y; y=z; 、 选择题 30分 二、 填空题或程序填空 三、 判断题 10分 四、 分析题 20分 五、 编程题 20— 20分 30分 A. /A ,<=ch<=7, B. (ch>=W)&(ch<=T)

C语言与数据结构实验指导(完整版)

Harbin Institute of Technology C语言与数据结构 实验指导书 刘梅索莹田文龙 哈工大电子与信息工程学院 电子工程系

实验1实验平台 一、实验目的 1.掌握Microsoft Visual C++ 6.0集成环境的使用方法。 2.掌握C程序在Microsoft Visual C++ 6.0开发环境中的编辑、编译、链接和运行全过程 二、实验内容 1)启动Microsoft Visual C++ 6.0开发环境 双击桌面应用程序图标或云兄“开始”菜单程序组中的Microsoft Visual C++ 6.0应用程序,启动VC++,如图所示 图1.1 VC++初始界面 2)建立C源程序文件 方法1:单机工具栏的“新建文本文件”按钮,打开文本文件编辑界面如下图所示 图1.2文本文件编辑界面 方法2:执行“文件”->“新建”命令,在“文件”选项卡下选择C++ Source File 文件类型,然后输入C源程序文件名和保存文职,如图所示,然后单击“确定”按钮,打开源程序文件编辑界面,如图1.4所示。

注意:输入C源程序文件名时必须带上扩展“.c”,否则默认创建的是扩展名为“.cpp”的C++文件。 3)编辑源文件 方法1:在如图1.2所示的文本文件编辑界面中输入源程序代码,如图1.5所示。方法2:在如图1.4所示的C源程序文件编辑界面中编辑源程序代码,如图1.6所示。 图1.3新建文件 图1.4 C源程序文件编辑界面

图1.5文本文件编辑界面编辑源文件 图1.6 C源程序编辑界面编辑源文件 4)保存源文件 源文件编辑结束后,执行“文件”->“保存”命令保存文件,文本文件编辑界面中编辑的源文件保存时必须在文件名后加上扩展名“.c”,否则保存的是扩展名为txt的文本文件,不能编译运行。 5)组件文件 执行“组建”->“组建”命令或直接按F7功能键或单机工具栏Build按钮,可以对源文件进行编译、链接而不运行改程序。当然也可以先执行“组建”->“编译”(快捷键Ctrl+F7)命令编译文件,再执行“组建”->“组建”(快捷键F7)命令链接文件。 由于VC++有工作区的要求,所以组建时,系统提示需要建立工作区,如图1.7所示。单机“是”按钮,系统会自动建立工作区,组建后的结果如图1.8所示。

C语言编译全过程介绍

C语言的编译链接过程要把我们编写的一个c程序(源代码)转换成可以在硬件上运行的程序(可执行代码),需要进行编译和链接。编译就是把文本形式源代码翻译为机器语言形式的目标文件的过程。链接是把目标文件、操作系统的启动代码和用到的库文件进行组织,形成最终生成可执行代码的过程。过程图解如下: 从图上可以看到,整个代码的编译过程分为编译和链接两个过程,编译对应图中的大括号括起的部分,其余则为链接过程。 1.编译过程 编译过程又可以分成两个阶段:编译和汇编。 编译 编译是读取源程序(字符流),对之进行词法和语法的分析,将高级语言指令转换为功能等效的汇编代码,源文件的编译过程包含两个主要阶段: 编译预处理 读取c源程序,对其中的伪指令(以# 开头的指令)和特殊符号进行处理。 伪指令主要包括以下四个方面:

1)宏定义指令,如# define Name TokenString,# undef等。 对于前一个伪指令,预编译所要做的是将程序中的所有Name用TokenString替换,但作为字符串常量的 Name则不被替换。对于后者,则将取消对某个宏的定义,使以后该串的出现不再被替换。 2)条件编译指令,如# ifdef,# ifndef,# else,# elif,# endif等。 这些伪指令的引入使得程序员可以通过定义不同的宏来决定编译程序对哪些代码进行处理。预编译程序将根据有关的文件,将那些不必要的代码过滤掉。 3)头文件包含指令,如# include "FileName" 或者# include < FileName> 等。 在头文件中一般用伪指令# define定义了大量的宏(最常见的是字符常量),同时包含有各种外部符号的声明。 采用头文件的目的主要是为了使某些定义可以供多个不同的C源程序使用。因为在需要用到这些定义的C源程序中,只需加上一条# include语句即可,而不必再在此文件中将这些定义重复一遍。预编译程序将把头文件中的定义统统都加入到它所产生的输出文件中,以供编译程序对之进行处理。 包含到c源程序中的头文件可以是系统提供的,这些头文件一般被放在/ usr/ include目录下。在程序中# include它们要使用尖括号(< >)。另外开发人员也可以定义自己的头文件,这些文件一般与c源程序放在同一目录下,此时在# include中要用双引号("")。 4)特殊符号,预编译程序可以识别一些特殊的符号。 例如在源程序中出现的LINE标识将被解释为当前行号(十进制数),FILE则被解释为当前被编译的C源程序的名称。预编译程序对于在源程序中出现的这些串将用合适的值进行替换。 预编译程序所完成的基本上是对源程序的“替代”工作。经过此种替代,生成一个没有宏定义、没有条件编译指令、没有特殊符号的输出文件。这个文件的含义同没有经过预处理的源文件是相同的,但内容有所不同。下一步,此输出文件将作为编译程序的输入而被翻译成为机器指令。 编译、优化阶段 经过预编译得到的输出文件中,只有常量;如数字、字符串、变量的定义,以及C语言的关键字,如main, if , else , for , while , { , } , + , - , * , \ 等等。 编译程序所要作得工作就是通过词法分析和语法分析,在确认所有的指令都符合语法规则之后,将其翻译成等价的中间代码表示或汇编代码。 优化处理是编译系统中一项比较艰深的技术。它涉及到的问题不仅同编译技术本身有关,而且同机器的硬件环境也有很大的关系。优化一部分是对中间代码的优化。这种优化不依赖于具体的计算机。另一种优化则主要针对目标代码的生成而进行的。 对于前一种优化,主要的工作是删除公共表达式、循环优化(代码外提、强度削弱、变换循环控制条件、已知量的合并等)、复写传播,以及无用赋值的删除,等等。 后一种类型的优化同机器的硬件结构密切相关,最主要的是考虑是如何充分利用机器的各个硬件寄存器存放有关变量的值,以减少对于内存的访问次数。另外,如何根据机器硬件执行指令的特点(如流水线、RISC、CISC、VLIW等)而对指令进行一些调整使目标代码比较短,执行的效率比较高,也是一个重要的研究课题。 经过优化得到的汇编代码必须经过汇编程序的汇编转换成相应的机器指令,方可能被机器执行。

C语言预处理命令总结大全

C语言预处理命令总结大全 (2012-02-13 17:18) 标签: C语言预处理分类:C编程 C程序的源代码中可包括各种编译指令,这些指令称为预处理命令。虽然它们实际上不是C语言的一部分,但却扩展了C程序设计的环境。本节将介绍如何应用预处理程序和注释简化程序开发过程,并提高程序的可读性。ANSI标准定义的C 语言预处理程序包括下列命令: #define,#error,#include,#if,#else,#elif,#endif,#ifdef,#ifndef,#undef,#line,#pragma等。非常明显,所有预处理命令均以符号#开头,下面分别加以介绍。 一 #define 命令#define定义了一个标识符及一个串。在源程序中每次遇到该标识符时,均以定义的串代换它。ANSI标准将标识符定义为宏名,将替换过程称为宏替换。命令的一般形式为: #define identifier string 注意: 1该语句没有分号。在标识符和串之间可以有任意个空格,串一旦开始,仅由一新行结束。 2宏名定义后,即可成为其它宏名定义中的一部分。 3 宏替换仅仅是以文本串代替宏标识符,前提是宏标识符必须独立的识别出来,否则不进行替换。例如: #define XYZ this is a tes 使用宏printf("XYZ");//该段不打印"this is a test"而打印"XYZ"。因为预编译器识别出的是"XYZ" 4如果串长于一行,可以在该行末尾用一反斜杠' \'续行。 #defineLONG_STRING"this is a very long\ string that is used as an example" 5 C语言程序普遍使用大写字母定义标识符。 6 用宏代换代替实在的函数的一大好处是宏替换增加了代码的速度,因为不 存在函数调用的开销。但增加速度也有代价:由于重复编码而增加了程序长度。 二 #error 命令#error强迫编译程序停止编译,主要用于程序调试。 #error指令使预处理器发出一条错误消息,该消息包含指令中的文本.这条指令的目的就是在程序崩溃之前能够给出一定的信息。 三 #include

C语言概述及如何在VS2010中进行C语言编程

第1章概述 作为本书的开始,我们不涉及C语言的语法和使用细节,先来看一看这门语言的相关背景,以及其在计算机程序中举足轻重的地位。然后,为给后面的学习作准备,来看看如何建立C语言的开发环境。最后,抛砖引玉,说说笔者自己的C语言学习经验。 1.1C语言简介 本节先来看一看C语言的相关背景介绍。在众多的计算机语言之中,它到底处于一个什么样的位置?相对于其他计算机语言而言,它有什么优势和弱点?另外,C语言适合做些什么样的软件开发?带着这些问题开始本节的学习。 1.1.1C语言的位置 图1.1是计算机语言发展过程的一个简单的示意图,只展示了一些主流的计算机语言的出现时间和顺序,不是很全,但是足以显示C语言与其他语言的关系了。 图1.1计算机语言发展史(简)

第1章概述 从图1.1中可以看出,所有的高级语言都起于Fortran,之后就有不同的分支了。C语言也是其中的一个分支,主要起源于BCPL语言(Basic Combined Pogramming Language),是对BCPL语言的一种简化。C语言之所以被称为C语言,是因为BCPL语言被称为B语言,C语言不能再取BCPL的首字母了,因此,取BCPL的第二个字母C,C语言因此得名。 C语言诞生于20世纪70年代,之后不断完善、标准化。目前流行的C语言编译系统大多数是以ANSI C(美国国家标准协会(ANSI)对C语言发布的标准)为基础进行开发的。但不同版本的C编译系统所实现的语言功能和语法规则略有差别。现在比较通用的是1990年,国际标准化组织ISO(International Organization for Standards)接受的1989年的ANSI C标准,并以它作为ISO C90标准——ISO/IEC9899:1990。 1.1.2C语言的优缺点 任何一种计算机语言都有它的优势和不足,C语言也是如此。不要以为C语言都那么老了,是不是没用了,也不要以为C语言是万能钥匙,什么问题都能解决好。 1.C语言的优势 C语言的优点细数起来,估计手指加脚趾都不够用,但是这些优点可以总结为一点,那就是“灵活”。C语言的灵活主要体现在同一件事情可以通过好几种方式实现,并不会定死什么问题非得用什么方式来解决。C语言之所以灵活,是因为它有下面这些属性,保证了它天生就是一种灵活的语言。 ?结构丰富多变:C语言提供了三种基本的程序设计结构,通过这三种程序设计结构,就能够完成所有的计算机逻辑。而且每种结构中,又有略有差别的不同的形 式,你可以选择自己喜欢的任意形式来完成需要的功能。 ?提供了多种基本运算:C语言提供了30多种运算符号,分为15个运算优先级,不仅可以完成基本的数学运算,还可以完成类似于计算机底层操作的位运算。有 的运算符号在不同情况下的含义和使用方式也是不同的,而且可以通过强制结合 来改变运算符的优先级。 ?丰富的数据类型:数据类型决定了一种语言可以用来操作什么样的数据。C语言的数据类型真可谓丰富,从基本的几种数据类型,到复杂数据类型,再到可以自 定义的数据类型。从某种程度上来说,C语言可以用来操作任何类型的数据。 ?程序设计自由,语法限制不大:C语言代码在书写的时候,从书写格式到代码组织限制都不是很大,所以写代码的风格可谓百花齐放,什么样的都有。只要符合 最基本的要求,无论你怎么写,都是对的。只不过代码风格不好,不利于阅读和 理解。 对于上面提到的C语言的各种优点,在没有接触C语言之前,可能大家还体会不到。不要紧,相信大家学完这本书之后,回过头来看看这一部分内容,一定会有所感悟的。 2.C语言的不足 一个事物,往往最强的地方也就是它最弱的地方。C语言的弱点也正是由于它的“灵活”造成的。因为太灵活了,怎么样都行,对计算机的控制太过自由,稍不留意就会出现错误!所以,能灵活运用C语言,也是一种能力啊。 ·3·

C语言编程要点程序的编写和编译

C语言编程要点---第18章程序的编写和编译 第18章程序的编写和编译 本章讲述在编译程序时可以使用的一些技术。在本章中,你将学到专业C程序员在日常编程中所使用的一些技巧。你将会发现,无论是对小项目还是大项目,把源代码分解成几个文件都是很有益处的。在生成函数库时,这一点更为重要。你还将学到可以使用的各种存储模式以及怎样为不同的项目选择不同的存储模式。如果你的程序是由几个源文件组成的,那么你可以通过一个叫MAKE的工具来管理你的项目(project)。你还将学到“.COM"文件和".EXE"文件的区别以及使用“.COM”文件的一个好处。 此外,你还将学到用来解决一个典型的DOS问题的一些技巧,这个问题就是“没有足够的内存来运行DOS程序”。本章还讨论了扩展内存、扩充内存、磁盘交换区、覆盖管理程序和DOS扩展程序的用法,提出了解决"RAM阻塞”这一问题的多种方法,你可以从中选择一种最合适的方法 . 程序是应该写成一个源文件还是多个源文件? 如果你的程序确实很小又很紧凑,那么当然应该把所有的源代码写在一个“.C”文件中。然而,如果你发现自己编写了许多函数(特别是通用函数),那么你就应该把程序分解成几个源文件(也叫做模块)。 把一个程序分解成几个源文件的过程叫做模块化程序设计(modular programming)。模块化程序设计技术提倡用几个不同的结构紧凑的模块一起组成一个完整的程序。例如,如果一个程序中有几种实用函数、屏幕函数和数据库函数,你就可以把这些函数分别放在三个源文件中,分别组成实用模块、屏幕模块和数据库模块。 把函数放在不同的文件中后,你就可以很方便地在其它程序中重复使用那些通用函数。如果你有一些函数还要供其它程序员使用,那么你可以生成一个与别人共享的函数库(见18.9)。 你永远不必担心模块数目“太多”——只要你认为合适,你可以生成很多个模块。一条好的原则就是保持模块的紧凑性.即在同一个源文件中只包含那些在逻辑上与其相关的函数。如果你发现自己把几个没有关系的函数放在了同一个源文件中,那么最好停下来检查一下程序的源代码结构,并且对模块做一下逻辑上的分解。例如,如果要建立一个通信管理数据库,你可能需要有这样一个模块结构: --------------------------------------------------------- 模块名内容 --------------------------------------------------------- Main.c maln()函数 Screen.c 屏幕管理函数 Menus.c 菜单管理函数 Database.c 数据库管理函数 Utility.c 通用功能函数 Contact.c 通信处理函数 Import.c 记录输入函数 Export.c 记录输出函数 Help.c 联机帮助支持函数 ---------------------------------------------------------- 请参见: 18.10 如果一个程序包含多个源文件,怎样使它们都能正常工作? . 各种存储模式之间有什么区别? DOS用一种段地址结构来编址计算机的内存,每一个物理内存位置都有一个可通过段地址一偏移量的方式来访问的相关地址。为了支持这种段地址结构,大多数C编译程序都允许你用以下6种存储模式来创建程序: ----------------------------------------------------------------------- 存储模式限制所用指针 ----------------------------------------------------------------------- Tiny(微) 代码、数据和栈一64KB Near

文本编辑器 C语言程序

文本编辑器 C语言课程设计报告 目录 1.设计目的及要求 1.1设计目的 1.2设计要求 1.3题目解析 2.总体设计 3.详细设计 3.1流程图 3.2程序解析 4.调试分析 5.设计总结 6.心得体会 7.答辩记录 8.教师意见

1.设计目的及要求 1·1设计目的 编一个程序对一个指定的文本文件进行处理,要具有统计功能,编辑功能以及查找功能等。 1·2设计要求 A)读取一个指定文本文件,每行以回车结束,显示在屏幕上 B)统计功能:统计字符数,单词数,行数,并输出 C)编辑功能 1)将所有小写字母改成大写字母,将新的文本输出; 2)将所有大写字母改成小写字母,将新的文本输出; 3)输入被替换的字符串,及替换的内容,将新的文本输出; D)查找功能 1)输入一个字符,在文本中查找是否存在该字符,若存在,统计 其个数,并将信息输出; 2)输入一个单词,在文本中查找是否存在该字符,若存在,统计 其个数,并将信息输出; 1.3题目解析 课程的第一要求就是读取一个指定的文本文件,而且之后还有对字符串,字符数组的运用,所以要使用文本函数将文本中的字符输入到字符数组中。完成第一步之后就是对字符串的处理了。 2·总体设计 因为是对指定的文本文件进行处理,所以需要首先运用fscanf函数将文本文件中的字符读入到指定的数组中,然后才能进行处理。 对于字符串的处理,首先在头文件中使用#include,因为下文要使用有关字符串的函数。具体的要用到strlen函数。 3·详细设计

3·1流程图

3.2程序解析 #include #include void main() { char file[30]="\0",m[15]="\0";//file 是文件地址,m 是下面case 1里用的 int c,n,s;//c 用于switch ,n ,s 是case 1里用的 printf("请输入源文件地址:"); scanf("%s",file); char a[2000]="\0",b[2000]="\0"; FILE *fp=fopen(file,"r");//这是打开文件并把文件地址指针给fp if(!fp)//若是没能打开则运行 { printf("源文件不存在或地址输入错误!\n"); } int i=0; fscanf(fp,"%c",&a[i]);//读取第一个字符给a[0] while(a[i++]) //读取字符并输出 { fscanf(fp,"%c",&a[i]); 注释: fscanf 函数用于从磁盘文件中读入数据,送到程序中进行处理,其一般表达形式为: fscanf (文件指针,格式字符串,输入参数列表) 与fprintf 函数类似,fscanf 函数调用时同样返回int 型数值,其返回值有两种: 函数调用成功时:返回时间输入的字符数 函数调用失败时:返回EOF

如何在C语言中自已写头文件

如何在C语言中自已写头文件 标签:C语言头文件分类:专业文献 2008-07-23 16:13 一些初学C语言的人,不知道头文件(*.h文件)原来还可以自己写的。只知道调用系统库函数时,要使用#include语句将某些头文件包含进去。其实,头文件跟.C文件一样,是可以自己写的。头文件是一种文本文件,使用文本编辑器将代码编写好之后,以扩展名.h 保存就行了。头文件中一般放一些重复使用的代码,例如函数声明,变量声明,常数定义,宏的定义等等。当使用#include语句将头文件引用时,相当于将头文件中所有内容,复制到#include处。为了避免因为重复引用而导致的编译错误,头文件常具有 #ifndef LABEL #define LABEL //代码部分 #endif 的格式。其中,LABEL为一个唯一的标号,命名规则跟变量的命名规则一样。常根据它所在的头文件名来命名,例如,如果头文件的文件名叫做hardware.h, 那么可以这样使用: #ifndef __HARDWARE_H__ #define __HARDWARE_H__ //代码部分 #endif 这样写的意思就是,如果没有定义__HARDWARE_H__,则定义__HARDWARE_H__,并编译下面的代码部分,直到遇到#endif。这样,当重复引用时,由于__HARDWARE_H__已经被定义,则下面的代码部分就不会被编译了,这样就避免了重复定义。 另外一个地方就是使用include时,使用引号与尖括号的意思是不一样的。使用引号(“”)时,首先搜索工程文件所在目录,然后再搜索编译器头文件所在目录。而使用尖括号(<>)时,刚好是相反的搜索顺序。假设我们有两个文件名一样的头文件hardware.h,但内容却是不一样的。一个保存在编译器指定的头文件目录下,我们把它叫做文件I;另一个则保存在当前工程的目录下,我们把它叫做文件II。如果我们使用的是#include ,则我们引用到的是文件I。如果我们使用的是#include “hardware.h”,则我们引用的将是文件II。笔者以前就遇到过一个同事问,为什么他修改了那个头文件里面的内容,好象跟没有修改一样?就是因为他有两个一样的头文件(就像我们刚描述的那样),他是使用#include引用的,而他修改时,却是当前工程所在的目录下的那个文件 怎样引用自己编写的头文件? 在linux下自己编写的函数并定义了x.h头文件。但在其他文件中引用该x.h头文件编译的时候总是提示无法编译。而直接引用x.c的文件就可以。这些文件都是在同一目录下的。难道gcc编译器在编译的时候需要什么选项么? 如果是自己定义的头文件在同一个目录下的可以直接引用,但要使用“”号才能引用,即用#include"x.h"就可以了。而#include 是去编译器头文件所在目录中查找,如果该include中的头文件, 在标准库中已经定义好了, 用户也可以用#include 直接引用。

Linux GCC(C语言编辑器)

Linux GCC(C语言编辑器) 摘要: 要想读懂本文,你需要对C语言有基本的了解,本文将介绍如何使用gcc编译器。首先,我们介绍如何在命令行方式下使用编译器编译简单的C源代码。然后,我们简要介绍一下编译器究竟作了那些工作,以及如何控制编译过程。我们也简要介绍了调试器的使用方法。 GCC rules 你能想象使用封闭源代码的私有编译器编译自由软件吗?你怎么知道编译器在你的可执行文件中加入了什么?可能会加入各种后门和木马。Ken Thompson是一个著名的黑客,他编写了一个编译器,当编译器编译自己时,就在'login'程序中 留下后门和永久的木马。幸运的是,我们有了gcc。当你进行configure; make; make install 时,gcc在幕后做了很多繁重的工作。如何才能让gcc为我们工作呢?我们将开始编写一个纸牌游戏,不过我们只是为了演示编译器的功能,所以尽可能地精简了代码。我们将从头开始一步一步地做,以便理解编译过程,了解为了制作可执行文件需要做些什么,按什么顺序做。我们将看看如何编译C程序,以及如何使用编译选项让gcc按照我们的要求工作。步骤(以及所用工具)如下:预编译(gcc -E),编译(gcc),汇编(as),和连接(ld)。 开始... 首先,我们应该知道如何调用编译器。实际上,这很简单。我们将从那个著名的第一个C程序开始。(各位老前辈,请原谅我)。 #include int main() { printf("Hello World!\n"); } 把这个文件保存为game.c。你可以在命令行下编译它:

gcc game.c 在默认情况下,C编译器将生成一个名为a.out 的可执行文件。你可以键入如下命令运行它: a.out Hello World 每一次编译程序时,新的a.out 将覆盖原来的程序。你无法知道是哪个程序创 建了 a.out。我们可以通过使用-o 编译选项,告诉gcc我们想把可执行文件叫什么名字。我们将把这个程序叫做 game,我们可以使用任何名字,因为C没有Java那样的命名限制。 gcc -o game game.c game Hello World 到现在为止,我们离一个有用的程序还差得很远。如果你觉得沮丧,你可以想一想我们已经编译并运行了一个程序。因为我们将一点一点为这个程序添加功能,所以我们必须保证让它能够运行。似乎每个刚开始学编程的程序员都想一下子编一个1000行的程序,然后一次修改所有的错误。没有人,我是说没有人,能做到这个。你应该先编一个可以运行的小程序,修改它,然后再次让它运行。这可以限制你一次修改的错误数量。另外,你知道刚才做了哪些修改使程序无法运行,因此你知道应该把注意力放在哪里。这可以防止这样的情况出现:你认为你编写的东西应该能够工作,它也能通过编译,但它就是不能运行。请切记,能够通过编译的程序并不意味着它是正确的。 下一步为我们的游戏编写一个头文件。头文件把数据类型和函数声明集中到了一处。这可以保证数据结构定义的一致性,以便程序的每一部分都能以同样的方式看待一切事情。 #ifndef DECK_H #define DECK_H #define DECKSIZE 52

c语言课程设计C语言文本编辑器

文本编辑器 文本编辑器是最常用的文档创建和编辑工具。随着计算机科学与技术的发展,用来处理文本的编辑器随处可见,并且形式多样。 比如,Windows下的记事本,写字板,EditPlus,UltraEdit 等都是十分优秀的文本编辑器和处理工具。在本章中,我们将向读者讲解如何利用C语言来发展开发一个简易的文本编辑器。 1设计目的 利用C语言的单链表数据结构及相关函数,本章编程实现了一个与DOS操作系统下的Edit相似的文本编辑器。再次文本编辑器中,用户可以通过快捷和选择菜单项,完成基本的文本编辑器和文件处理工作。 通过文章的介绍,读者可以了解文本编辑器的开发过程,掌握菜单的开发技巧,加深对文件操作的理解。更重要的是,希望此程序能抛砖引玉,引领读者掌握编程的方法和技巧,开发出更优秀的程序。 2 功能描述 如图.1 所示,文本编辑器主要由五大功能模块构成,它们分别是文件操作模块,文本编辑模块,剪切操作模块,菜单控制模块和帮助及其他模块。下面分别简要介绍功能模块的功能。

(1)文件操作模块。在文件操作模块中,主要完成文件的创建,打开,保存和另存操作。用户可以选择File 菜单上的New 子菜单来完成新建文本文件操作;选择File 菜单上的Save 子菜单来完成保存文件操作选择File菜单上的Open子菜单来完成打开文件操作;选择Flie 菜单上的Saveas 子菜单来完成文件的另存为操作。在文件的打开,保存和另存为操作中,系统会提示用户输入文件路径及文件名。值得一提的是,当用户打开一个文件时,指定的文件必须存在,否则系统会报错。 (2)文本编辑器模块。在文本编辑器模块中,主要完成在编辑 窗口中以添加或插入的方式输入字符,删除光标所在当前位置的单个字符或前一个位置的单个字符,朝上下左右 4 个方向的光标移动操作。当光标所在位置及后面的位置没有字符时,系统会以添加的方式输入字符;当光标所在位置及后面的位置有字符时,系统会已插入的方式输入字符。用户可以使用Backspace键 删除光标前一个字符,也可以使用Del 键删除当前位置的字符或删 除Ctrl+ 左移(右移)键i 选定了的多个字符。用户可以使用左移键(J),右移键(f),上移键(T)和下移键(J)来移动光标位置。 (3)剪贴板操作模块。在剪贴板操作模块中,主要完成对已选定文本的剪切,复制,粘贴工作。如果用户要剪切文本以便可以将它移动到其他位置,可通过Ctrl+X 左移键(右移键)先选定文本, 然后选择Edit 菜单上的Cut 子菜单或按Ctrl+X 快捷键来完成剪切任

linux下使用vi编辑器编写并执行c程序实验报告

课程名称:操作系统原理 实验名称:“helloworld”程序 专业:计算机科学与技术 年级/班级: 学号: 实验地点: 实验日期: 姓名: 实验类型:验证性 指导教师: 实验目的: 熟悉linux基本命令;学会使用VI编辑器;掌握在linux系统下编译C程序的方法。 实验仪器及耗材: 1、机房电脑; 2、CentOS-6系统。 实验原理: 通过CentOS-6系统中的终端编写命令并执行,从终端进入vi编辑器编写C程序代码保存后退回终端利用命令执行程序输出HelloWorld!!!。 实验内容及步骤: 1.添加一个新用户(以自己的名字命名); 2.为新建用户设置口令; 3.用who命令显示登录到系统上的用户; 4.pwd显示当前工作目录 5.cd要求:先转到/root目录下;再转到根目录 6.列出根目录下的文件和目录的详细信息 7.在你的用户家目录下创建新目录“os” 8.删除“os”目录 9.建立一个实验文件file1.txt,要求:建在/home目录下;文件内容为:I love os1,…, I love os5 10.显示文件file1.txt的权限

11.用文字设定法将file1.txt权限设置为rw-r—r-x 12.用数字设定法将file.txt权限设置为rwxrw-r— 13.用chown将file1.txt所属的组改为root用chown将file1.txt属主改为root 14.用cat在/home目录下再建文件file2.txt,内容为I love os6,…,I love os10 15.用cat显示file2.txt的内容 16.用cat将file1.txt和file2.txt的内容合并起来放到file3.txt中。 17.显示file3文件的后3行内容。 18.为file3.txt建立硬链接文件myfile1.txt。 19.file3.txt建立软链接文件myfile2.txt。 20.删除file3.txt,比较两种链接的区别。 21.显示所有的作业及其进程号。 22.终止一个正在运行的进程。 23.使用VI编辑器创建一个名字为“后两位学号姓名hello.c”的文件,并且写入C语 言代码实现显示“hello 姓名!” 24.对源程序进行编译链接。 25. 执行程序。 注意事项: 1、执行命令时所处的用户及根目录; 2、C程序输入标点符号是所处的输入法。 实验数据(现象)记录及结果处理: [ztg@localhost 桌面]$ su root 密码: [root@localhost 桌面]# adduser ActorH adduser: user 'ActorH' already exists [root@localhost 桌面]# su ActorH [ActorH@localhost 桌面]# passwd 更改用户ActorH 的密码。 新的密码: 无效的密码:它基于字典单词 无效的密码:过于简单 重新输入新的密码: passwd:所有的身份验证令牌已经成功更新。 [ActorH@localhost 桌面]$ ls -l 总用量88 -rwxrwxr-x. 1 ztg ztg 4709 10月31 09:36 actor ...... -rw-rw-r--. 1 ztg ztg 0 10月25 09:36 新文件~ [ActorH@localhost 桌面]$ su root 密码: [root@localhost 桌面]# cat > file1.txt 1 2

C语言编译预处理命令

编译预处理命令 文件包含: 把指定的文件插入到预处理命令行所在的位置并取代该命令行,即把指定的文件和当前的源程序文件连接成一个源文件。 #include<文件名> 在文件包含目录中去查找指定的文件,并将该文件添加到源文件中。 一个被包含的文件中可以含有文件包含命令来包含另一个文件。 #include“文件名” 命令中文件名的位置是当前源文件的位置,若在当前目录中未找到该文件,则再到“包含目录”中去查找。 宏 用一个标识符表示一个字符串,称为宏,被定义为宏的标识符称为宏名。在编译预处理时对程序中所有出现的宏名用宏定义中的字符串去代换,这就是宏替换。它是由系统编译程序时自动完成的。 无参宏定义 #define 标识符字符串 如 #define PI 3.14 使用宏时要注意: (1)宏定义是用宏名来表示一个字符串,在宏展开时用字符串取代宏名。(2)宏定义不是变量定义或语句,在行末不能加分号,如果加上分号则分号也成为字符串的一部分。 (3)宏定义可以出现在程序的任何地方,其作用域是宏定义命令所在位置开始到源程序结束。如果要终止其作用域可使用#undef命令。 (4)宏定义允许嵌套,在宏定义的字符串中可以使用已经定义的宏名。在宏展开时将逐层替换。 (5)#define PI 3.1415926 #define AREA PI*y*y 有参宏定义 #define 宏名(形参表)字符串 对带参数的宏,在调用中不仅要进行宏展开,而且还要用实参去替换形参。 带参宏调用的语法格式如下: 宏名(实参表);

#define M(x) x+1 K=M(3); K=3+1 定义有参宏时要注意以下几点: (1)有参宏定义中,宏名和形参表之间不能有空格出现。 (2)在函数中,调用时要把实参的值赋给形参,进行“值传递”。而在带参宏调用中,只是符号替换,不存在值传递问题。 (3)宏定义中的形参只能是标识符,而宏调用中的实参可以是表达式。 宏替换中对实参表达式不做计算直接照原样替换,字符串内的形参通常用括号括起来以避免出错。 在使用宏时不仅要将形式参数用括号括起来,还应将其整体用括号括起来。 #define S(y) ((y)*(y)) 条件编译 条件编译可以按不同的条件去编译不同的程序段。 1#ifdef #ifdef 标识符 程序段1 #else 程序段2 #endif 功能:如果标识符已被#define定义过,则对程序段1进行编译,否则对程序段2进行编译。格式中的#else部分可以没有,即: #ifdef 标识符 程序段 #endif 2、#ifndef 语法格式如下: #ifndef 标识符 程序段1 #else 程序段2 #endif 功能与ifdef形式的功能正好相反。 3、#if 常量表达式 #if 常量表达式 程序段1 #else 程序段2 #endif 功能:如果常量表达式的值为真(非0),则对程序段1进行编译,否则对程序段2进行编译,因此可以使程序在不同条件下,完成不同的功能。 上面介绍的条件编译实现的逻辑也可以用条件语句来实现,但是用条件语句将会

利用C语言程序编辑GDSII文件(zz)

https://www.doczj.com/doc/c82784872.html,/pc/pccon.php?id=6632&nid=168700 本文虽说是介绍用C语言程序来编辑GDSII文件,其实用什么程序语言来写 都是可以,只不过选择C语言,有利用大家交流和应用,而且无论你使用的是windows,还是其他操作系统 都可以运行该程序。 从这篇文章中,本人并不希望读者仅看到程序的本身,最终目的是希望大家能够初步了解到GDSII file的格式。 首先,将如图所示的版图,通过工具输出名字m2t.DB GDSII格式的database。 在unix系统用使用 %od -x m2t.DB 查看文件的十六进制格式,显示如下: 0000000 0006 0002 0005001c 0102 0068 0002 001b 0000020 000b 0015 001b 0068 0002 001b 000b 0026 0000040 00300010 0206 464c 4154 3034 4f46 2e44 0000060 4200 0014 0305 3e41 8937 4bc6 a7ef 3944 0000100 b82f a09b 5a51 001c 0502 0046 0001 0001 0000120 0008 0000 0000 0068 0002 0017 000f 001c 0000140 0008 0008 0606 6d32 7400 0004 08000006 0000160 0d02 00060006 0e02 0000002c 1003 ffff 0000200 fdf8 ffff fdf8 0000 0208 ffff fdf8 0000 0000220 0208 0000 0208 ffff fdf8 0000 0208 ffff 0000240 fdf8 ffff fdf80004 11000004 07000004 0000260 04000000 0000 0000 0000 0000 0000 0000 0000300 0000 0000 0000 0000 0000 0000 0000 0000 显示第一段表明字符的位置,可以忽略,其他将依次向大家解释。 0006 0002 0005 其中0006表示这段所用的字节数为6(0006h)个字节,0002表示一个代码HEADER,常见的如: 0102:BGNLIB,0206:LIBNAME,0900:PATH,0D02:LAYER等共69种,0002中00是HEADER记录类型,02则表示这个记录的类型,此类型称为datatype共有6种:0:no data present; 1:bit array; 2:two-byte signed integer; 3:four-byte signed integer; 4:four-byte real; 5:eight-byte real; 6:ascii string 最后两个字节0005表示文件格式的版本5(0005h) 001c 0102 0068 0002 001b 000b 0015 001b 0068 0002 001b 000b 0026 0030 001c表示本段字节数28(001c),0102为BGNLIB,datatype为02。0068-0030 表示database最终访问 时间,格式为年、月、日。注意年份要加上1900,如0068h=104,104+1900=2004以此计算时间为 2004.2.27 11:21 27秒到2004.2.27 11:38 48秒。

C语言中.h与.c解析

C语言中.h和.c文件解析 简单的说其实要理解C文件与头文件(即.h)有什么不同之处,首先需要弄明白编译器的工作过程,一般说来编译器会做以下几个过程: 1.预处理阶段 2.词法与语法分析阶段 3.编译阶段,首先编译成纯汇编语句,再将之汇编成跟CPU相关的二进制码,生成各个目标文件(.obj文件) 4.连接阶段,将各个目标文件中的各段代码进行绝对地址定位,生成跟特定平台相关的可执行文件,当然,最后还可以用objcopy生成纯二进制码,也就是去掉了文件格式信息。(生成.exe文件) 编译器在编译时是以C文件为单位进行的,也就是说如果你的项目中一个C文件都没有,那么你的项目将无法编译,连接器是以目标文件为单位,它将一个或多个目标文件进行函数与变量的重定位,生成最终的可执行文件,在PC上的程序开发,一般都有一个main 函数,这是各个编译器的约定,当然,你如果自己写连接器脚本的话,可以不用main函数作为程序入口!!!! main .c文件目标文件可执行文件 有了这些基础知识,再言归正传,为了生成一个最终的可执行文件,就需要一些目标文件,也就是需要C文件,而这些C文件中又需要一个main函数作为可执行程序的入口,那么我们就从一个C文件入手,假定这个C文件内容如下: #include #include "mytest.h" int main(int argc,char **argv) { test = 25; printf("test.................%d\n",test); } 头文件内容如下: int test; 现在以这个例子来讲解编译器的工作: 1.预处理阶段:编译器以C文件作为一个单元,首先读这个C文件,发现第一句与第二句是包含一个头文件,就会在所有搜索路径中寻找这两个文件,找到之后,就会将相应头文件中再去处理宏,变量,函数声明,嵌套的头文件包含等,检测依赖关系,进行宏替换,看是否有重复定义与声明的情况发生,最后将那些文件中所有的东东全部扫描进这个当前的C 文件中,形成一个中间“C文件”。 2.编译阶段:在上一步中相当于将那个头文件中的test变量扫描进了一个中间C文件,那么test变量就变成了这个文件中的一个全局变量,此时就将所有这个中间C文件的所有变量,函数分配空间,将各个函数编译成二进制码,按照特定目标文件格式生成目标文件,在这种格式的目标文件中进行各个全局变量,函数的符号描述,将这些二进制码按照一定的标

相关主题
文本预览
相关文档 最新文档