2007
06-10

    本贴计划集中解决新手学习C/C++语言时将遭遇到的各类问题,答案大部分为本论坛已发贴,请认真阅读。
    本贴不具体讨论程序细节,主要分析概念原理和解决方案。
    作者将持续更新,为保持版面整洁,拒绝回帖。如有问题,可另行发贴提出。


C语言帝国 FAQ》有 19 条评论

  1. 碧蓝右耳 说:

    一、入手准备
    FAQ是啥
    我为啥要学编程
    编程是什么
    如果这就是编程,那语言是怎么回事
    听说编程很难,是真的么,那我能学会吗?
    好吧你说服我了,我打算开始,该怎么做
    那么,下一步怎么干
    我碰到问题了,谁能帮我
    我英语\XX不会,咋办
    关于态度、情绪和其他

    二、C语言的问题
    C语言是什么
    C++语言是什么
    为何要选择纯C
    C/C++语言和其他语言有什么关系
    我为什么要学C/C++语言而不是别的

    三、其它一些重要的概念
    为什么要编程————因为机器的特点
    程序到底是怎么回事————是操作而不是结果
    你们老是提到编译器,那是什么
    我的程序和一般的程序不一样,什么原因————控制台和图形界面的差异
    好像不能建立一个单独的文件来编译阿————工程和项目的问题
    难道一切都要从头干起————函数、API、类、控件、开发包与软件复用
    关于图形库的补充说明——–可选择的图形库

    四、教材、习题和示例
    能推荐几本好书么
    光看书似乎不解决问题,难道要做题
    OJ是什么
    哪里有可用的OJ
    哪里有代码示例可看

    五、选择编译器
    有哪些编译器可用
    他们在哪里
    怎么安装他们—-特别解释 MingW版GCC的安装

    六、TC下常见的问题解决
    用TC创建第一个程序
    TC的库路径设置
    TC下的图形编程设置
    我的程序在TC下可以编译,在VC/GCC下为什么出错

    七、其它编译器问题
    用VC创建程序
    用DEV-CPP创建程序
    用MingW创建程序
    用Lcc-win32创建程序

  2. 碧蓝右耳 说:

    FAQ是啥
        FAQ就是Frequently Asked Questions,也就是常见问题解答。这玩意儿通常是一些所谓的高手或者前辈为了节省回答新手的大量简单重复问题所耗费的时间精力而采用的一种偷懒手法。一旦完成,高手只要一努嘴,“看FAQ去”就万事大吉了。实在是居家旅行杀人越货之必备良药,因此在各大论坛已经有大泛滥的趋势。
        本篇FAQ主要为C语言帝国论坛和分群的大量新手编写,重点是如何运行起第一个程序,不涉及语法、数据结构和算法等内容。如果你已经通过计算机二级或水平相似的考试,就不必再往下看了。同时,本FAQ只讨论C语言,其他语言如C++ Java 等均不涉及,如有此类需求,自行解决。

    我为啥要学编程
        这个问题有两层意思。首先是编程为啥要学,很简单,因为这玩意不是生来就会,属于一门手艺,自然要通过学习才能掌握。你怎么也得花上几年来学英语不是。
        第二层涵义才是重点,为啥我要学它。答案因人而异。有人为了上学有人为了考试,有人为了求职挣钱,还有人就是吃饱撑没事做自虐。什么为了开发智力啊证明自己啊寻找成就感啊,那都属于自虐,在下便属于自虐一族。没啥说的,确定你的目的,想继续深入的,往下看,没信心的趁早走人,外面帅哥美女多的是,不要浪费大好时光青春年华在一台破机器上,ok?

    编程是什么
        编程就是编制程序。程序是让计算机发挥功能的命令的集合。程序有两种形式,让计算机真正执行的是电脉冲形式,叫机器码,程序员编制的通常是文本形式,叫源代码。使用一个称为编译器的工具,可以把源代码转变为机器码。而编程就是产生那些源代码的工作。

    如果这就是编程,那语言是怎么回事
        文本形式的源代码,其实有些规定的。就像我们和老美用英语交流。首先你得说英文单词,不能冒法语词汇日文假名出来,其次你得按语法讲话,不能一个个单词往外蹦。程序也是类似,有词汇和语法上的一些规定,这些规定就统称为一门语言。因为这件事是人想出的办法,规定也是人定的,所以各家有各家的高招,不同的规定就形成了不同的语言。

    听说编程很难,是真的么,那我能学会吗?
        你觉得说中文难么?你能流利的说普通话是不是。但是你知道么,汉语是世界上最难学习掌握的语言。稍后我会介绍计算机的特征,你就会明白知道基本上编程这件事的难度等价于指挥IQ<20的壮汉。任何一种计算机语言的难度都不会超过英语,更比不上汉语。那么你认为你能不能学会编程呢。
        请记住学会和学好是两个层次,就像中学生作文和文学出版物之间的差异。达到学会那个程度,只要小学三年级的基础就可以开始了,也就是识字就行。而如果要学好,最好是初高中毕业的水准,也就是略懂英文和解析几何。当然还有更高的层次,在那个档次上,你将被称为大师或者黑客,那是相当于诺贝尔文学奖的水平。至于那个程度怎么达到,不在本FAQ讨论之列。

    好吧你说服我了,我打算开始,该怎么做
        首先去找台机器,从来没听说谁没有电脑就能学习编程的。然后,确保你的健康状况和基本计算机操作水平,最好能有网络连接,物质上就达到要求了。
        没人可以无师自通,天才也不行。所以你要做的第一件事是找一本好的入门教材,最好是经典作品。反复地看教材,要牢记一点,你所提出的大部分问题,教材上都有解释,只是你没有认真看而已。反复的看,直到你觉得你已经可以编写出那本教材了,才可以丢弃他。教材比老师好的原因是,你可以带教材上厕所去卧室,而老师不行。当然,如果你有老师,那就更好。他可以给你解释教材上没有的问题,但记住老师也是人,你不动脑子就去找他,他会厌烦的。不要鄙视你的老师,即使他其它方面不如你,至少在编程这件事上他能做你的老师就是他比你强的硬道理。
        你以为光看语法书不练嘴就能说好英语么,显然不是。编程也一样,熟能生巧在任何地方都是一样的。首先看懂教材上的那些例子,确保看懂之后,按着他的思路把它默写出来,当你尝试过就会知道看懂和默写是两个完全不同的程度。然后就可以做书后面的习题,独立想,不要看答案或提示。等到整本书后面的习题你都能做对的时候,你就算入门了。然后去找等级考试二级三级的题目来做,等到也可以准确无误的时候,恭喜你,C语言(或者其他语言)可以算是通过了。如果你的目的是去考试,现在就出发吧。但如果你想要以编程谋生,sorry,你还欠火候。这其中的差别就相当于大学英语四级作文和畅销英文小说之间的差异。

    那么下一步怎么干
        只需要考试的朋友,不需要看这一段。想谋生或自虐的这边请。
        通过C语言只是编程的第一步而已。你掌握了大量的单词并且熟悉语法还不能让你写出优美的英语小说。你要学习修辞手法、谋篇布局这类文学技巧,也需要掌握历史典故、谚语俗话和文化背景这些文字外的东西,如果要畅销,还需要超凡的主题生动的故事跌宕的情节。编程圈子里有和这些类似的东西。
        算法和数据结构就是程序里的修辞手法谋篇布局。人类编程虽然不过几十年,但运用程序所解决的问题,已经覆盖世界的每个角落各个方面。各种各样的问题,被前辈的大师提炼归纳。有些人们直接找出了解决的方法,有些人们找到了寻找解决方法的途径,还有些人们索性证明了在现阶段是不可能解决的。这些解决方案就被统称为算法。学习算法就是学习前人的智慧,少走弯路。连老牛爵士都是站在巨人的肩膀上,除非你认为你比老牛还牛,凭空就能解决别人十几年才想清楚的问题。
        学算法很简单,也是找教材,做习题。教材容易找,但新手往往找不到合适的习题。我的建议是,在完成教材上的所有习题之后,可以去找编程竞赛的练习题来做,也就是所谓的OnlineJudge,我会在后续具体谈谈这个东西。
        相当于历史典故、谚语俗话的东西,就是各个编译器和平台上的接口和库了。如果你在程序里要读写文件,你不要以为你需要亲自写个程序去控制硬盘的磁头伸缩,或者是光驱的透镜移动或者是U盘的地址定位。除非你是想做个window或者Linux那样的操作系统(那样的兄弟会来看这篇FAQ还真是奇迹),否则所有包括文件操作、网络通讯、人机界面(键鼠屏打印机)这些,都是由操作系统提供的现成模块,只等着你来使用。这些模块通常称为应用程序接口,不同的操作系统提供的不一样。在接口的基础上,很多编译器和程序员做了进一步的包装形成了库,你可以比直接使用接口更方便地使用这些库而达到同样的功能。
        由于系统的不一致,编译器的不同,所以在学库之前,先要确定你所要工作的平台和环境,还有应用方向。Windows下编游戏和Linux下做数据库用的库是大相径庭的。然后就是同样的一套步骤,找教材,做练习。这个教材通常就是官方文档,windows下最好最全的就是MSDN,其他平台自行搜索。可以去找习题,但更好的方案是去找一个实际的小型应用,在使用中学习效果无与伦比。编写一个QQ,绝对能让你对网络操作部分了如指掌。在这个阶段,你已经可以写出实用的程序了,为什么还要做题呢。
        优秀的文学作品有个共同的特征,他们虽然立足于本民族文化,但却关心全人类共通的思想感情,体现终极的人文关怀。优秀的程序虽然应用方向不同平台各异,但他们一定完全符合计算机原理,用最合理的数学模型来展现。如果你想成为合格的程序员,计算机原理和相关的数学知识是一定要补习的理论课。
        除了看书和做题之外,还有一个内容不可缺少,就是阅读别人的程序。没有哪个作家不大量阅读别人的作品,同样你也可以从别人的代码中吸取营养。代码就是程序的全部,是真实的实现方法,一切都在代码中,甚至有时长篇累牍的说明还不如几行代码清晰明白。今天的程序员是幸运的,开源运动的发展使得他们能够无偿而方便地得到世界上最优秀的并且是实际运作中的代码,几乎遍布任何应用领域。只要你有心,可以找到任何想要的代码。但读代码也是辛苦的事,请阅读和你水平相当的代码,差距太大会是严重的打击。
        学习库和学习算法可以同时进行,在你完成这两个阶段的时候,你已经是一个合格甚至是优秀的程序员了。
        超凡的主题跌宕的情节,这个东西其实就是你的程序的应用方向。如果说前面都是练习的话,这就是你自主创新的时候到了。大部分人只能在老板的安排下被动作程序,少数人才能做自己喜欢的东西。想想看,QQ、3DMAX、WOW是多么知名的程序,有一天你的程序会和他们一样知名。不过我还是不得不给你泼冷水,这需要不懈的努力、敏锐的眼光和少量的运气,只有极少数的程序员能做到这一点。不过,有梦想,才能不断前进,不是么。

    我碰到问题了,谁能帮我
        郑钧说,记得没人会同情你,我亲爱的兄弟。这真是至理名言。编程这件事,基本上是不能指望有人帮你的。
        当你遇到编程遇到问题,首先应该是去看编译器提供的信息。它可是最直接的来源,相当于案发现场,从没听说刑警不看尸检报告就直接破案的。现代的编译器已经不止编译那么简单,编译本身就能送出大量的提示,调试功能更是强大到可以让你检视程序运行的每一步都发生了什么变化,只要你能看懂。机器的问题,就应该用机器来解决,而不是用人的肉眼来看。
        然后就去查教材和文档。手边的教材能解决70%以上的问题,如果还不够,上网去查。如果找不到,请记住有个东西叫搜索引擎,国内最著名的两个,google baidu。99%的问题可以得到解决。
        如果你有老师,可以试着向他请教。不要抱太大的希望,虽然他收你学费,但他也不是万能的。
        如果还是不行,确认你已经努力过而没有答案,那么你可以考虑提问,去论坛、新闻组或者群,都可以提问。
        在你确定要提问之前,请先阅读这篇文章《提问的智慧》
    http://www.vcgood.com/bbs/forum_posts.asp?TID=1581&PN=1&TPN=1
        这个也行,《提问的智慧 图片版》 http://www.vcgood.com/bbs/forum_posts.asp?TID=1573&PN=1&TPN=1

    我英语\XX不行,咋办
        看不懂英语,那编程还有什么前途。数学不行,成为大师的希望不大了。不能上网,你完蛋一半。没有机器,难道要我买给你。指法不行,练去。
        记得没人会同情你,我亲爱的兄弟。不会就去学吧,没有什么是不可跨越的障碍。
        请记住这段话:在信息时代,任何主观障碍都不存在。如果你要研发什么新技术的话,只需要一台便宜的二手电脑、一张linux光盘和一个上网账号,再加上为之献身的决心,你就可以达到想要的任何编程深度。这话是谁说的,自己查。

    关于态度、情绪和其他
        和技术无关,关于学习态度和方法的一些提示。
        《循序渐进学编程 》
    http://www.vcgood.com/bbs/forum_posts.asp?TID=1353&PN=2
        《一个程序员给初学编程人的建议》  http://www.vcgood.com/bbs/forum_posts.asp?TID=265&PN=1
        《 c语言学习经验–请不要做浮躁的人》 http://www.vcgood.com/bbs/forum_posts.asp?TID=1359&PN=2
        《成为软件高手的几个忌讳》 http://www.vcgood.com/bbs/forum_posts.asp?TID=155&PN=8
        《程序员四大忌》  http://www.vcgood.com/bbs/forum_posts.asp?TID=174&PN=8  

  3. 碧蓝右耳 说:

    C语言是什么
        C语言是一种计算机编程语言。语言是什么,请查阅上面的内容。
        1970年前后,AT&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~100000行,就很难从总体上把握它的复杂性了。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++大。
        lisp Scheme 这是和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++语言,开源代码的80%是C/C++.任何一家硬件软件公司,当他开发一款能够编程的设备或是软件,必然会提供C语言的接口函数。其他的语言,就不一定有这样的好处了。不论是计算机图形学、加密解密还是计算机编程的其他领域,C/C++简直就是编程界的普通话。根据 International Data Corporation 的统计,C/C++ 是全球开发者使用最多的编程语言。如果确实要投身编程界,不懂C/C++的话,根本就是Mission Impossible。
        如果你还不明白,我只需举一个小例子。假设你现在有机会去学习一门外语,投入时间差不多,你会选择学习英语呢,还是坦桑尼亚的斯瓦希里语呢。(斯瓦希里语流行于非洲东部,为肯尼亚坦桑尼亚等国的官方语种)
        当然,并不是说其他语言不值得学习,存在即是合理,今天存在的各种语言,当然都有它存在的价值,多学一点没有坏处。没有人禁止你在学会英语的基础上再学习法语日语等等。无论过去、现在还是将来,天底下不存在哪一门语言非学不可才能成为高手,思想最重要,“不会XXX语言不算真正的高手”之类的言论实在无聊之至。学C/C++,主要还是通过他学习编程思想。真正的武林高手,难道会局限于手里的那把大剑吗。
    但我们还是强烈建议初学者从C语言开始,因为除了上面所提的好处,C语言还足够的简单。初学者或许会觉得C很难,但请记住,那些是编程之难,不是C之难。当你学过三种以上语言的时候,就会越发体会到C的简单。

  4. 碧蓝右耳 说:

    为什么要编程————因为机器的特点
      编程这件事存在,完全是迫不得已。人们发明了计算机,想让它做事。但机器有三大特点,使得如果要让机器做事,完全不像吩咐人那么简单。
        第一个特点就是机器很傻。很多人希望自己像计算机一样聪明,我说如果那样你就完了。举例来说,从三个数里选出最大最小值,人类可以一眼就看出,但机器只能先从两个里找出最大的,在把这个最大的和第三个比较,然后再这样重复一遍找出最小值。如果是四五个数,机器也是这样反复操作。这就类似工地上搬砖,人类的做法一次搬很多很多砖,用推车或者别的码得高高地运到目的地。计算机的做法是每趟只搬一块砖,你没看错,每趟一块。
        那为什么计算机这么厉害呢,因为他的第二个特点,快。机器可以不知疲倦地用同一方法,重复重复再重复地做某件事,而且每次重复都相当的快。他搬砖不是每趟一块么,但他每趟来回的时间很短,比如低于0.00……001秒,不管砖头有多少,十万块也好十亿块也罢,按同一方法处理,没有差别不会厌烦直到全部处理完。结果从总体来比较,机器就比人强了。还是以选最大最小数为例,人可以用肉眼检视三四个数,但超过100个数就要用其他的方法。对机器来说,三个和三万个数只是重复次数的差别。单调快速的重复,这就是机器的诀窍。
        更重要的一点,机器和我们言语不通。就是说,我们不可能一抬手一挑眉毛就吩咐他做事。不要和我抬杠说你可以用鼠标画圈让机器做事,也可以声控。那都已经不是纯粹的机器了。机器和我们处在一个不同的感知空间,所以他不能理解我们的话语。我们要命令他,必须用他能够理解的形式。从根本来说,就是电脉冲。
        基于这三个特点,要让机器做事情,就必须让把我们的要求转化成最简单适于重复的命令集合,而且是电脉冲形式。这种命令就是常说的计算机指令,而这种命令集合就是程序,所谓编程,就是制造这些程序的工作。
        比如我们要让机器在屏幕上显示一幅图,首先我们要把这幅图分解成很多很多的小方格,也就是所谓像素,每个像素只有一个颜色,每个颜色都用一个很长的数字表示,然后所有这些数字转化成内存里的电平信号,再用另外的电路信号来一个个的把这些电平送到显像电路。所有这些电平和信号的集合就是程序。

    程序到底是怎么回事————是操作而不是结果
        计算机本身什么也做不了,必须依靠程序来指挥他做事。程序就是操作流程的顺序,或者说是顺序排列的多个操作过程,他是方法的描述。
        有一次我的朋友王二老板要做家具,这可是他的老本行。他先把原木分割成木条木板,再把木条木板弯曲到指定的形状,然后把他们放置到适当的位置,接着设法固定他们,最后雕花抛光和上漆,一张漂亮的摇椅就做好了。这整个的流程如果记录下来,就是一个程序。任何程序都有三个要素,执行者、操作对象(也称为资源)和操作方法(指令)。在做家具这个程序里,王二就是执行者,木头就是他所对付的资源,在指令的持续作用下,木头(资源)的状态(如形状大小、颜色位置等)不断发生变化。最后,在程序结束时,木头变成了家具。
        电脑程序和上面一样,是方法的描述。只是这些程序的执行者不再是人,而是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才改变人为给定的这块内存的状态以表现出计算结果。
        通常,我们把计算机的物理实体部分称为硬件包括电路板、机箱、键盘鼠标等,而把不可见的非实体部分称为软件,软件大体就是程序和主要由程序产生的数据。广义的说,乐谱、菜谱、工作手册、仪器的操作说明也是某种程序,我们不妨称之为类程序。

    你们老是提到编译器,那是什么
        还能问出这个问题,说明你没有仔细看前面的文字。不过我不介意再解释一次。
        是的,我刚刚说过,程序其实是电脉冲形式的指令的集合。对机器这是绝对正确的。但你认为人类可以直接操作电脉冲么,当然不能。所以最早的时候,程序员们是通过反复的拨动开关或者插拔插头来做这件事的,就像老电影里的电话接线员们。后来技术进化了,人们可以把脉冲信号设置在打了孔的纸带上,有孔就是通,没洞就是断,用纸带机可以在电脉冲和纸带之间转换。老电影里的工程师们经常拿起一条长长的纸带来阅读。真是高深莫测阿。不过即使这样,要理解程序还是很困难,更别说阅读编写和修改了,人毕竟不是机器呀。其实人们最习惯用来表达思想的方法是文字,于是人们设想能否直接写出文字形式的程序。通过不懈的反复的程序到工具工具到程序的工作,这个目标实现了。今天人们可以写出文本形式的称为源代码的程序,然后再利用称为特定的工具把代码转换成机器能理解的电脉冲形式,也就是目标程序。这种转换工具就叫做编译器,作用相当于翻译,以前是纯粹的机电设备,到了现代他也成了程序的一种。
        从某个角度来说,其实没有任何人能被称为程序员,编译器才是真正的程序制造者。人所制造的只是源代码。
        在这里顺便讲解下编译和解释的差别。编译器的工作相当于翻译,而我们知道其实翻译有口译和笔译两种工作模式。程序员写完所有的源代码,由编译器一次性转为可执行文件留待以后执行,这种类似笔译的模式我们称为编译。程序员每次输入一行或数行代码,编译器马上把他转换并执行,并等待程序员的后续输入,这种类似即时口译的方式就称为解释,此时编译器就被叫作解释器。C/C++ pascal等语言是编译型的,perl python等语言就是解释型的,java语言很特殊,他先编译成一种中间代码,然后在不同的机器上边解释边执行,这样就能实现跨平台运行。一般来说,编译型要比解释性的效率高些,但解释型在编程的时候容易排错,界面友好。不管用哪种语言编程,你总需要一个编译/解释器。
        现代的编译器,往往不止是编译器,他还会包含有着色搜索等功能的代码编辑器,支持单步调试并行调试的调试器,能够读入文件的多个版本并进行比较分析的版本控制,编辑图标等的资源编辑器,在大型项目中用于统一协调的项目管理,和用于自动化代码生成的向导工具等等。这样的编译器,我们就称它为集成开发环境,最著名的代表就是微软的VisualStudio系列。

    我的程序和一般的程序不一样,什么原因————控制台和图形界面的差异
        当你开始照书上的例子编写第一个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、类乃至控件,开发必备,就象旅行时必需携带的包裹一样,于是被统称为开发包。有些开发包是编译器自带的,如标准库等等。有些包是第三方厂商提供的,比如微软的DirectX系列开发包,专为游戏编程所设计。所有开发包都需要编译器的支持,有的要编译器提供内部实现,有的要编译器给于连接,有的要编译器生成代码。不同的编译器提供的方式不太相同,这就造成了编译器之间的差异,有时,甚至导致某个开发包不能在某款编译器上使用。
        为了进一步提高程序员的工作效率,很多编译器还发明了另一些方法,相当于直接用一间间的房子叠在一起做成居民楼,你几乎只要刷刷外墙漆,就可以完成了,这被称为应用程序框架。可惜,不同的厂商的方法根本不同,这进一步扩大了编译器之间的差异。
        不管未来怎样,至少现在,编程的规模变得越来越大,也越来越需要更多人的智慧。每个人的智慧都是有限的,不应该被浪费,充分使用每个人的智慧,才能取得成功。软件复用就是整合所有人智慧的方式之一。从你编程的第一天开始,请牢牢记住:软件复用。要复用,复用,再复用。

    关于图形库的补充说明——–可选择的图形库
        黑客们很偏爱控制台,但对于用户来说,图形界面是他们更喜欢的。我们也喜欢编写GUI程序,因为那看起来确实更友好也更有成就感。那么,怎样才能编写GUI,需要什么东西呢。
        答案是:图形库。每一个操作系统,都会提供一套API(不理解的回看上面一小节),如果该系统支持GUI,那么它的API中就会有一个图形子系统和窗口管理子系统。其中图形子系统包括了基本图形元素的绘制,比如画点线面、显示文字图片和上色渲染等等,窗口管理子系统则包括窗口和窗口元件的绘制、窗口的遮盖、移动调整等等。在Windows下,图形子系统就叫GDI(Graphics Device Interface)。其他平台也有类似的接口,在TC下可以通过扩展的graphic.h来实现画图,不过窗口的支持要另行实现。此外,为了应对3D绘图在速度和效果上的需求,有专门的3D加速图形库被开发出来,最著名的就是DirectX和OpenGL。其中前者只能用于Win平台,但除了图形之外还整合其他很多功能,后者跨平台,能在从家用到大型商务等各方面使用而且性能卓越。
        但是即使有图形库窗口管理库,GUI编程仍然是相当的繁琐。首先是要完成某个工作必须填写大量按部就班的代码,而且这些代码在程序内部和各个程序之间重复着。这提示人们应该在图形库的基础上作进一步的抽象。举例来说就是要在画点画线函数的基础上做出画圆的模块。幸运的是,这些工作已经有人完成了,而且是不止一套。
        这些东西按照功能强弱,有的叫图形用户界面库,有的则叫应用程序框架。在windows下,使用VC的人 可以选择MFC ATL,使用Delphi和BCB的,可以用VCL,至于VB,它本身就是和图形库捆绑在一起。如果你选择.net阵营,.net framework 就是你最好的选择。
        如果你希望程序不止在windows使用,那么跨平台的QT GTK+ wxWindow 都是你的好选择。他们在保证效率的同时,适当抽象,抚平了底层操作系统的差异。
       对于学习C++的人来说,上述库都是可以用的。但如果你是C语言死忠,就我的认知,可以直接用API,否则只有一个选择:GTK+。实体书比较少,相关资料推荐去线上查。

  5. 碧蓝右耳 说:

    能推荐几本好书么
        当然,FAQ的目的之一就是这个。不过纯C的教材和C++的教材要分开说。

        先说纯C的教材
        第一本:Brian W.Kernighan和Dennis M.Ritchie 的《C程序设计语言》。
        此书简称K&R,由C语言的创建者撰写,是全球销售最多的C语言教材,其品质不容置疑。不过不适合入门,适于在入门之后巩固提高。实体书有原版和译本购买,电子版英文较多。

        第二本:谭浩强的《C程序设计》。
        优点在于,面向中国学生,语言易于理解,而且全书篇幅小,看过的人多,容易找到人请教。但是各方面的概念不深入,浅尝辄止。因此适合第一次入门学习,例题做完基本就可以抛弃了。有实体书和电子版下载。

        第三本:H.M.Deitel和P.J.Deitel的《C程序设计教程》。
        作者是父子,从事语言教材的编写合计超过40年,本书被美国众多高校选用为教材,既可入门也可翻阅,甚好。

        第四本:王大刚先生的《C语言编程宝典》。
        质量不错,与老谭的书处于同一级别。无实体书,只有网络版,在本群论坛有转载:
    http://www.vcgood.com/bbs/forum_posts.asp?TID=1560&PN=2

        第五本:无名作者的《C语言初学者入门讲座》
        本群论坛转载,作者未知,质量同上一本。
    http://www.vcgood.com/bbs/forum_posts.asp?TID=1294&PN=4

        第六本:Kenneth A.Reek 的《C和指针 》
        进阶读物,把指针一章演绎为一本书可见其技术精度。指针是C的灵魂,能领会本书中的理念,才能算是真正明白了C指针的奥妙,才算懂得了C。

        第七本:Andrew Koenig 的 《C陷阱与缺陷》
        进阶读物,在认真读完上面的入门书之前,暂勿阅读。本书畅销14年历久不衰,足证品质。

        最后一本:ISO C89规范/C99规范
        一切关于C语言的疑问,只有一件东西最权威,那就是ISO的规范。但这不是正式出版物,是类似法律文本的技术说明,而且只有英文版。新手阅读,提防吐血而亡。

        再说C++的教材,C++比C复杂的多,所以教材也就纷繁芜杂。既有综合性入门性的,也有专项深入的,阅读要循序渐进,以下分阶段介绍(以下文字有部分引用自他人评介)。
        首先是毫无基础的时候,先要初步掌握语法并形成编程的概念
        level 0:
        仍然是K&R,Brian W.Kernighan和Dennis M.Ritchie 的《C程序设计语言》。
        尽管C++之父亲口说,最好把C++看作一门新语言来学习,但我个人认为,一开始学习C至少有两大好处。相比C++,C还是非常简单的,易于掌握,避免你过早陷入C++的语法泥潭。同时,学C能让你对计算机的底层运行有所认识,建立良好的概念。
       
        H.M.Deitel和P.J.Deitel的《C++程序设计教程》。
        又是这对父子。有很多号称C++入门的书,但经我的观察,如果要选择能推荐给毫无编程概念的新手用的书,这本算是佼佼者了。此父子的《C程序设计教程》我已推荐了。

        钱能的《C++程序设计教程》
        国内C++教材中较好的一本,作者是教师,总结多年教学实践的经验写成的,比较适合国内学生。
        PS:老谭也有一本C++教材,在此就不太推荐了,它完全是用C的思维来看C++。

        当读者有一定c/c++基础
        推荐的阅读顺序:
        level 1
        从<<essential c++>>开始,短小精悍,可以对c++能进一步了解其特性
        以<<c++ primer>>作字典和课外读物,因为太厚不可能一口气看完
        C++之父Bjarne Stroustrup的 <<the c++ programming language>>,简称BS的TCPL,全面而深入的书,缺点也是太厚。
        这个阶段 也可以延用前阶段Detiel父子的教材。

        level 2
        然后从<<effective c++>>开始转职,这是圣经,请遵守10诫,要经常看,没事就拿来翻翻
        接着是<<exceptional c++>>,个人认为Herb Sutter主席大人的语言表达能力不及Scott Meyers总是在教育第一线的好
        顺下来就是<<more effective c++>>和<<more exceptional c++>>,请熟读并牢记各条款
        当你读到这里,应该会有一股升级的冲动了

        level 3
        <<insied the c++ object model>>看过后如一缕清风扫去一直以来你对语言的疑惑,你终于能明白compiler到底都背着你做了些什么了,这本书要细细回味,比较难啃,最好反复看几遍,加深印象
        看完上一本之后,这本<<The design and evolution of c++>>会重演一次当年C++他爹在设计整个语言过程中的历程

        level 4
        <<the c++ standard library>>是stl的字典,要什么都可以查得到
        学c++不能不学stl,那么首先是<<effective stl>>,它和圣经一样是你日常行为的规范
        <<generic programming and the stl>>让你从oo向gp转变
        光用不行,我们还有必要了解stl的工作原理,那么<<stl源码剖析>>会解决你所有的困惑

        level 5
        对于c++无非是oo和gp,想进一步提升oo,<<exeptional c++ style>>是一本主席这么多年的经验之谈,是很长esp的
        一位stl高手是不能不去了解template的,<<c++ template>>是一本百科全书,足够你看完后对于gp游刃有余
        <<modern c++ design>>是太过聪明的人写给明眼人看的

        和C一样,同样有最后一本书
        ISO+IEC+14882-1998 C++规范。这可不是宝典圣经,这就是C++的法律,一切疑问以此为准到此打住。不过,拖个小尾巴,具体情况取决于编译器实现。

    光看书似乎不解决问题,难道要做题
        当然要做题,而且做题也要循序渐进。
        首先是教材正文中的示例,然后是书后的练习题。
        第二步可以做国家等级考试二级三级的C语言题。在线上可以找到,大量二级题库。三级题推荐南开的三级100题。此外本群共享文件中也有一些这一难度的题目。
        正如前面讲过,当第二步的题目都做完后,语法已经不是问题,应该开始学习数据结构和算法。这个方面的练习题可以去各大OJ。OJ是什么,请看下一节。

    OJ是什么
        OJ是OnlineJudge的缩写。OnlineJudge是一种在线裁判系统。她可以对程序原代码进行编译和执行,并通过预先设计的测试数据来检验程序原代码的正确性。
        首先,他是一个在线的题库,有很多习题,你可以任选其中之一来解答。然后,系统的编译器能够编译执行你所提交的代码。如果编译通过,针对每个题目,系统将使用自带的多组测试数据检验你的程序,如果程序都能得到正确的输出,那么你顺利地解决了这个问题。最后,系统还能对所有参与答题的用户进行统计和排名。
        OJ的题目大部分是关于算法的。题目的输入输出通常是命令行方式,而非图形界面。也就是说,要关注的不是平台的兼容性、文件的格式抑或窗口的布置这种无关紧要的细节,而是问题本身的逻辑实现。一个用户提交的程序在Online Judge系统下执行时将受到比较严格的限制,包括运行时间限制,内存使用限制和安全限制等。用户程序执行的结果将被Online Judge系统捕捉并保存,然后再转交给一个裁判程序。该裁判程序或者比较用户程序的输出数据和标准输出样例的差别,或者检验用户程序的输出数据是否满足一定的逻辑条件。最后系统返回给用户一个状态,通过、错误、超时、溢出或是无法编译。
        Online Judge系统来自ACM和IOI大赛。由美国计算机协会(ACM Association for Computing Machinery)发起和组织的ACM国际大学生程序设计竞赛(简称ACM/ICPC)是目前世界上规模最大的计算机学科赛事。IOI则是国际信息学奥林匹克竞赛,和数学奥林匹克竞赛一样著名。Online Judge系统是IOI或ACM的训练题库,同时也是ACM和IOI的评分系统。

    哪里有可用的OJ
         以下几个OJ都很不错,请随意进入。也可以自行搜索,国内很多学校的OJ正在热火朝天的建设中。
         myOJ  
    http://myoj.kuye.cn/
         建站人员自称是专为中学生OI选手训练使用,由中学生和中学教师共同开发的,也是给中学生和中学教师使用的。优点是题目难度较低,而且题目都是中文版易于阅读。

         浙江大学宁波理工学院 http://acm.nit.net.cn/
         也是适合新手的OJ,题目难度由低到高不等。中文题不少。

         USACO  http://ace.delos.com/usacogate/
         全美计算机奥林匹克竞赛(USACO)的训练网站,特点是做完一关才能继续往下做,与前面的OJ不同的是测试数据可以看到,并且做对后可以看标准解答,所以如果大家刚开始的时候在上面那些OJ上总WA却找不到原因的话,可以试着来这里做做,看看测试数据一般是从什么地方阴你的。
         以上三个推荐新手前往。

         浙江大学的Online Judge http://acm.zju.edu.cn/
         国内最早也是最有名气的OJ,有很多高手在上面做题。特点是数据比较刁钻,经常会有你想不到的边界数据,很能考验思维的全面性。

         北京大学的Online Judge  http://acm.pku.edu.cn/
         建立较ZOJ晚一些,但题目加得很快,现在题数和ZOJ不相上下,特点是举行在线比赛比较多,数据比ZOJ上的要弱,有时候同样的题同样的程序,在ZOJ上WA(wrong answer),在POJ上就能AC(accomplished)

         西班牙的Universidad de Valladolid  http://acm.uva.es/
         世界上最大最有名的OJ,题目巨多而且巨杂,数据也很刁钻,全世界的顶尖高手都在上面。据说如果你能在UVA上AC一千道题以上,就尽管向IBM、微软什么的发简历吧,绝对不会让你失望的。

         俄罗斯乌拉尔大学  http://acm.timus.ru/
         也是一个老牌的OJ,题目不多,但题题经典。

    哪里有代码示例可看
        这个可以自己google或baidu。
        如果你已经能够做一些OJ的题了,那么可以考虑看一些开源软件的代码。
    http://sourceforge.net/ 是全球最大的开源软件集中地,确定一个应用主题上去找就会有收获。

  6. 碧蓝右耳 说:

    有哪些编译器可用
        一般国内学习有以下几款可以用:TC VC GCC LCC-Win32,以下分别介绍。

        TC 是Borland公司出品的Turbo C的简称,运行于DOS平台,win下可在控制台下使用。国内常用2.0版作为学习和考试的平台,为于1989年发布的产品,距今大约20年。另有3.0版本也可以使用,3.0比2.0多了C++语言支持。Turbo C 提供了两种编译环境:一种是类似于UNIX环境的命令行,包含一个TCC编译器和一个MAKE实用程序;一种是集成开发环境,由编辑器、编译器、MAKE实用程序和RUN实用程序,还有一个调试器组成。
        TC2 具有编译速度快、代码优化效率高等优点,所以在当时深受喜爱。但由于DOS环境已经不是应用主流,所以TC基本不能用来作为软件开发平台。即使在今天,由于TC对系统要求低,操作简便容易上手,他仍然是新手学习C语言的入门编译器之一。传闻Borland已在2002年放开TC的所有权,如果属实,那么使用Tc不再存在任何法律问题。

        VC 指的是Microsoft公司的集成开发工具套装VisualStudio中的C/C++语言集成开发环境Visual C++。
        目前可以使用的版本有VC6.0,和2005(即VC8)。VC2002/2003是过渡产品,可以不考虑。截至本文最后更新时,2008测试版已发行,2008正式版即将推出。
    VC的编辑编译调试都可以在同一个窗口内完成,在Win下兼容性最好,代码效率高,被广泛用作Win下各类程序的开发,可以说是Win平台下的标准开发工具。使用VC意味着和微软同一阵营,文档有微软的官方文档MSDN作为最权威的参考,示例代码数量巨大,学习投资得到有效保护。纯粹学习和开发win本地应用可使用VC6,如果需要进行.net程序开发,就要用2005版。
        VC系列的缺点有三:第一是体积庞大,VC6不包含MSDN容量为250M左右,包含则再加1G。VC2005不包含MSDN容量为2.7G,包含再加1.6G。第二是操作复杂学习门槛高,如果要在集成环境编译,必须建立工程和一批附属文件,同时还要熟悉集成环境的使用。第三:VC是有版权的软件。按照法律规定不付费购买是不可以使用VC的,因教学目的可以免费使用,但不能用于商业活动。不过显然国内的兄弟根本不理会这一套。
        VC6有一点要说明,VC6是没有中文版的。你所看到的中文版是某些人汉化的结果。虽然简洁明快,但在有些时候会出现莫名其妙的问题,还是直接使用英文版为好。 
        VC2005分为好几个版本,其中有一套叫做Express版的值得一提。他是微软送出的免费版,专门提供给学生和爱好者使用,功能上有删节,主要是图形界面和大量的工业用库和工具被裁减,而且基本只能在命令行编译。不过对于学习C/C++语言本身是完全足够的。如果有版权顾虑,可以选择它。

        GCC  GNU Compiler Collection 也即是 GNU 编译器家族。
        GCC是开源软件,是自由软件的旗舰项目,是可以在多种硬体平台上编译出可执行程序的超级编译器,其执行效率与一般的编译器相比平均效率要高20%~30%。
        GCC 不仅仅能支持 C 语言,它还支持 Ada 语言、C++ 语言、Java 语言、Objective C 语言、Pascal 语言、COBOL语言,以及支持函数式编程和逻辑编程的 Mercury 语言等等等等。另一方面,说到 GCC 对于各种硬件平台的支持,概括起来就是一句话:无所不在。几乎所有有点实际用途的硬件平台,甚至包括有些不那么有实际用途的硬件平台。
        根本无需再用什么语言来描述GCC的优点。几乎所有的开源软件和自由软件都是使用GCC编译的。如果要评选世界上编译出程序最多的编译器,除了GCC没有谁能担当这个荣誉。GCC的卓越是不言而喻的,连微软的员工也在使用GCC,学习GCC就是和世界上最优秀的程序员并肩作战。
        GCC最早是在Unix平台上开发的,所以在Solaris/Linux/BSD等Unix平台上是默认组件。通过黑客们的努力,GCC已经被移植到Windows平台,而且性能绝无缩水。Win平台下的GCC有两种形式,一种是集成开发环境的,典型的是DEV-CPP,另一种是纯粹编译器和命令行指令集合,以MingW项目为首。
        GCC的缺点是对新手不友好,命令行编译方式需要学习才能彻底掌握。

        LCC-Win32
        这是个小巧的纯C集成开发环境,目前最高版本4.0,和上面三个编译器相比,它有很多明显的优势。
        第一她很小巧,全部安装不过30M多,相比VS2005这种庞然大物,简直是迷你的不行。虽小却不缩水,他的确能够编译出Win下的可执行程序,这一点是同样小巧的TC做不到的。可以肯定地说他是Win平台下体积最小的C环境。第二他完全支持C99标准。VS2005基本不能支持C99标准,GCC可以支持C99,但需要适当的配置,而LCC-Win32原生支持,无需任何调节。第三点最关键,它是自由软件,也就是说,他和GCC一样可以免费使用,而且作出的程序也可以自由的销售。缺点是,缺少中文文档和无中文版是最大的不便。

        还有其它一些编译器,比如Borland的C++编译器BCB系列其中包括免费BCB5命令行版,Intel的Intel CPP Compiler等。在《C++编译器推荐目录》一文中有一个收集的编译器列表,各位可以前往参观。Blog:http://blog.csdn.net/sunwhite 。编译器如此之多,在下就不一一介绍了。

    他们在哪里
        理论上来说,这个问题应该自行通过搜索引擎解决,但我们还是不厌其烦的提供帮助。
        TC20可在众多编程入门论坛找到,在本论坛的空间也可。
    http://www.programfan.com/showdown.asp?id=152 此处也有。
        VS6和VS2005建议直接买盘,要找建议通过电驴或BT等工具。
        此处也有VC6
    http://www.vcgood.com/bbs/forum_posts.asp?TID=222&PN=1
        此地址为VS2005 http://www.vcgood.com/bbs/forum_posts.asp?TID=606&PN=1
        GCC的dev-cpp版本在此,http://www.bloodshed.net/devcpp.html
        GCC的MingW版本在此 http://www.mingw.org/download.shtml
        lcc-win32可在 http://www.cs.virginia.edu/~lcc-win32/    找到,英语很简单,很容易找到下载点,下载之前要填个名字。且本论坛空间也有。

    怎么安装他们
          除了GCC之外,上面提到的其他编译器都是很容易安装的。他们或者是简单的压缩包,释放即可,或者是标准的windows安装程序,相信大家都很熟悉。GCC的安装别具一格,要特别提一提。
          dev-cpp版本的GCC是标准的windows安装程序,但MingW版本不是。MingW版本的GCC继承了UNIX应用程序的风格,简单来说就是小工具的集合。MingW就像一大堆积木组成的,你需要哪个功能,就把哪个模块下载并复制到适当的位置,他就可以工作。
          具体操作流程如下:(说明软件中所提版本以页面上最新为准)
         
          1.下载
    到MinGW的主页下载各个组件的最新版本:
    http://www.mingw.org/download.shtml
    以下几个组件是必须的
    binutils    其中包括ld,as等编程需要的程序组
    gcc-core    C语言编译器
    mingw32-make-3.80.0-3    Make程序
    mingw-runtime    其中包括编译程序的大部分头文件和库文件(不包括Win32API)
    w32api    这个里面是Win32 API 的头文件和库文件
    其他组件可以根据需要下载,反正多装不影响。作者机器上还有如下组件:
    gcc-g++     C++编译器
    gdb     调试器
    mingw-insight 调试器的图形化界面
    软件包都提供了源代码版(src)和二进制版(bin),下载二进制版本即可。

     2.解压
    下载后,全部解压缩到同一个目录中,比如 C:\MinGW目录中。如果存在重名现象,通常都是许可证等的文件,可以覆盖掉或者不复制。
    因为这些程序包都是使用GNU的压缩工具生成的,所以文件名不是zip,通常是.tar.gz。你可以用WinRAR打开,此作者推荐著名的工具 7-zip 。

      3. 设置环境变量如下:(假设mingw安装在C:\MinGW,且注意GCC的版本)
    PATH : C:\MinGW\bin; (如果安装过其他c++编译器,务必把你要使用的编译器路径放在最前面)
    LIBRARY_PATH :C:\MinGW\lib
    C_INCLUDE_PATH :C:\MinGW\include
    CPLUS_INCLUDE_PATH :C:\MinGW\include\c++\3.2.3;C:\MinGW\include\c++\3.2.3\mingw32;
    C:\MinGW\include\c++\3.2.3\backward;C:\MinGW\include

  7. 碧蓝右耳 说:

    用TC创建第一个程序
        用TC编辑和编译都很方便。
        首先是菜单 File->new,在编辑区也就是那一大块蓝色的地方输入你的代码,然后file->save,会提示输入文件名并保存在合适的路径。
        选择菜单Complie->compile或者按快捷键Alt+F9,就可以编译你的程序。编译成功后可以用菜单Run->Run或者按快捷键Ctrl+F9可以运行它,如果发现画面一闪而过,可以用菜单window->user screen或者按快捷键Alt+F5来查看。
        如果编译失败,通常会给出提示,并且光标会停在第一个出错点,请仔细阅读。如果你要寻求帮助,也最好把错误提示贴给大家看。反复修改,直到程序通过。

    TC的库路径设置
        使用TC会遇到的第一个问题是库的路径设置。
        当新手第一次用TC学习C语言,他们信心满满地照着书上的例子输入代码(这个例子往往是HelloWorld),存盘,编译,希望能看到想象中的结果,但却惊讶的发现TC报错。能看明白TC说的是缺少文件的人已属不错,大部分是不知道问题发生在哪里。
        排除输入错误这类问题之后,这种情况通常只剩下一个原因,那就是TC的库文件的路径设置错误,解决方式如下。
        目前安装TC通常不是使用安装文件,而是用解压缩的方式放到硬盘上的。这种方式会释放出一个名为TC20或者TC30的目录,里面有全套文件,包括默认的运行参数。这个默认参数所记载的TC目录的位置通常是C:\TC20,这就是问题所在。如果你的TC确实在那个位置,万事大吉,可惜通常情况不是这样的。
        动手解决之前,首先检查你目前TC所在的路径,确保路径经过的每一个目录的名字都不超过8个字符,也没有中文或其他语言的字符,就是说确保目录名称都是8个英文字符或数字。我假设你的TC安装在X:\foo\code\TC
        然后打开你的TC,打开Options菜单,可以用鼠标点击,也可以按键盘的Alt+O。用方向键移动到Directories菜单,回车之后就能看到一个窗口,这就是设置的地方。
        在第一个输入栏里写上X:\foo\code\TC\include,这是头文件所在的目录。
        在第二个输入栏里写上X:\foo\code\TC\lib,这是库文件所在的目录。
        第三个输入栏是输出文件的路径,也就是编译完成的程序所在的位置。第四个是TC启动时搜索源代码的路径。这两个路径你都可以设为你喜欢的位置。
        然后就可以ok确认。请选择Options菜单下的save命令来保存,避免以后再次设置。
        至此问题解决。再次编译程序就可以通过。
        PS:使用安装文件方式安装不会出现这个问题,但我已经很少看到TC的安装包了。

    TC下的图形编程设置
        很奇怪我们的教材却乐此不疲地要求学生们练习TC下的编程,而且是图形编程。因为这实在是太落伍而没有实际价值的要求。当然作为图形编程的练习,因为他够简单,也就可以理解了。
        这个部分最好的文档就是上面提到过的王大刚先生的教材,其中专门有一章图形函数,详细讲解了所有的问题和事项。
    http://www.cnread.net/cnread1/dnwl/cxsj/c/cyyb/041.htm  
       鉴于有很多人不习惯认真地看文档,而偏爱直接发言。他们即使看完文档也还是会提问为什么我的TC图形程序不能运行。我就再麻烦一点,先讲一下两个最有可能导致无法运行的原因。
        第一:使用图形函数时要确保有显示器图形驱动程序*BGI, 同时将集成开发环境Options/Linker中的Graphics lib选为on, 只有这样才能保证正确使用图形函数。图形驱动程序由Turbo C出版商提供, 文件扩展名为.BGI。根据不同的图形适配器有不同的图形驱动程序,你可以在TC的安装目录下找到他们。
        第二: 在屏幕作图之前, 必须根据显示器适配器种类将显示器设置成为某种图形模式, 在未设置图形模式之前, 所有图形函数均不能工作。设置屏幕为图形模式, 可用下列图形初始化函数:
           void far initgraph(int far *gdriver, int far *gmode, char *path);
        其中gdriver和gmode分别表示图形驱动器和模式, path是指图形驱动程序所在的目录路径。
        典型用法是 initgraph(&gdriver, &gmode, “c:\\tc”);
        注意path应形如”c:\\tc的形式,使用两个 \ 来转义表示单个字符\
        其他问题请自行查阅文档。
        也可查阅此帖
    http://www.vcgood.com/bbs/forum_posts.asp?TID=1188&PN=1

    我的程序在TC下可以编译,在VC/GCC下为什么出错
        很简单,如果程序只涉及C语言本身和标准库,那么在任何平台都是可以运行的。而你运行出错的那些程序一定是调用了TC平台特有的服务和函数。比如,上一节提到的TC下的图形函数,在VC中完全不被支持,由GDI系统取代了,在Unix下的GCC中也要调用其它的图形函数库。同样的还有TC下的内存驻留程序,调用中断(如int13h进行硬盘读写操作)的程序。但此类程序可以在TC中编译通过后,由Win提供模拟DOS环境运行。
        这也是我们建议新手尽量少用TC作为开发平台的原因。

  8. 碧蓝右耳 说:

    用VC创建第一个程序
        用VC创建程序取决于你的编译方式。
        如果你选择命令行编译,你可以用你喜欢的任意文本编辑器编辑源代码(通常我们就用VC的环境),保存为后缀为.c的文件。然后转到命令行,输入 cl ,回车。你应该看到这样的话:
    Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80×86
    Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

    usage: cl [ option... ] filename… [ /link linkoption... ]

        这是VC的编译器程序 cl.exe在无输入时的结果。如果你没有看到cl的招呼,而是这样的一段话:
    ‘cl’ 不是内部或外部命令,也不是可运行的程序或批处理文件。
        这说明你没有安装VC,或是你安装的VC存在某些错误。其实也不是什么严重的错误,就是程序没有设置路径。假设你的VC安装在 D:\vs60,那么在控制台输入 SET PATH=d:\vs60VC98\Bin;%PATH% 就可以了。
        假设你的程序在 E:\cppcode 名为 Demo.cpp 那么输入:
    cl Demo.cpp
    一切顺利的话,就是这样的文字:
    Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80×86
    Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

    demo.cpp
    Microsoft (R) Incremental Linker Version 6.00.8168
    Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

    /out:demo.exe
    demo.obj

    这是告诉你编译成功,编译出了一个名叫demo.exe的可执行文件。如果输入:
    cl /Fea.exe demo.cpp
    编译出的可执行文件就叫a.exe,这是用参数控制编译的过程和结果,以后常常会用到。现在可以键入 demo.exe(或是a.exe),运行程序。
    这就是使用VC在控制台编译程序,是我个人推荐的编译方法。

        如果你选择在集成环境中编译,那么要在VC中选择菜单->file->new->Projects->Win32 Console Application,输入你的程序名,选择路径,在之后的操作中选择An Empty Project,这样就新建了一个空的控制台工程。
        然后再菜单 file->new->Files->C++ Source File,填上文件名。
        然后你就可以在打开的编辑区中编辑。最后,单击工具栏上的 save all 按钮,以保存你所有的工作。要记住编程是个体力活,经常保持你的成果是非常明智的。
        要把他编译成可执行的程序。选择菜单 Build->Build Hello.exe,稍等片刻。你会看到在屏幕下方出现了一个新的窗口,上面会依次出现如下的文字:

     Compiling…
     Demo.cpp
     Linking…

     Hello.exe – 0 error(s), 0 warning(s)

    如果看到以上文字,尤其是最后一句,表示程序顺利的编译成了可执行代码。
    如果情况是类似这样:

     Compiling…
     Demo.cpp
     E:\cppcode\Hello\Demo.cpp(8) : error C2143: syntax error : missing ‘;’  before ‘string’
     Error executing cl.exe.

     Hello.exe – 1 error(s), 0 warning(s)

    这表示程序有错而无法通过编译,你需要寻找出错误并修改。对于本例,是输入错误,请检查大小写,标点符号和中英文状态。改正之后,重新保存文件,再次编译,以上过程要反复的进行,直到编译通过。
    编译通过的程序就可以运行了。选择菜单 Build ->Execute Hello.exe。
    如果一切顺利,你应该看到了运行的结果。一个黑底白字的窗口,上面有两排字:

     Hello World!
     Press any key to continue

      其中第一句是程序运行的结果,第二句是操作系统告诉我们,随意按一个键,便可结束该程序。

    VC下的入门教程 可参见此帖 http://www.vcgood.com/bbs/forum_posts.asp?TID=1214&PN=1

    用DEV-CPP创建程序
         使用DEV-CPP的操作类似于用VC在集成环境下创建,也是新建工程,输入代码,然后编译连接,最后运行。差别只在于菜单和快捷键的设置。总体来说,DEV-CPP的编译速度要比VC慢一些。

    用MingW创建程序
        用MingW操作类似于用VC在命令行下编译。不同之处是控制台的命令是gcc 。命令类似于gcc demo.cpp,在Win下默认输出文件为a.exe
        MingW不自带编辑器,因此用户要自己选择合适的编辑器,通常我们推荐Editplus gvim和Emacs这三款。后两款功能强大到无以复加,但需要学习。
    GCC的简单使用教程见以下几帖
       
    http://www.vcgood.com/bbs/forum_posts.asp?TID=1197&PN=1
        http://www.vcgood.com/bbs/forum_posts.asp?TID=517&PN=1
        http://www.vcgood.com/bbs/forum_posts.asp?TID=340&PN=1
    Vi编辑器的使用可参见此帖
        http://www.vcgood.com/bbs/forum_posts.asp?TID=141&PN=2

    用Lcc-win32创建程序
        Lcc-win32的使用类似于dev-cpp,不同点是它的项目设置不在项目目录里的单独文件中,而是直接记录在注册表。
        有关Lcc-win32的资料可以参考lcc-win32的使用说明 
    http://www.blogjava.net/bluesky/archive/2005/11/30/21919.aspx

  9. 碧蓝右耳 说:

    FAQ暂到此结束,如有问题,欢迎提出。

  10. wsgc01 说:

    非常感谢
    顶起!

  11. zhangyong007 说:

    十分收益啊!!谢谢!

  12. 困C之斗 说:

    我可真想拜你为师

  13. hengood 说:

    不愧是C语言帝国,介绍的是相当全面,很有价值!

  14. jupiter 说:

    看完楼主的文章,对C有了一个感性的认识,谢谢~~~

  15. hiroki 说:

    感谢楼主啊

  16. IT小学生 说:

    谢谢楼主,我茅塞顿开

  17. adugmin 说:

    非常感谢

  18. lzqlovezizi 说:

    Tongue

     
    我全打印出来了
     
    嘿嘿
  19. huihaode 说:

    The open-face large cheap moncler
    bulletin boards that are sold in most office supply stores and mega marts can
    be helpful, but they leave your display unprotected. This means a heavy rain
    can turn your signs to mush, and anyone with a pen and too much time on their
    hands can draw mustaches on every member of the Ladies Who Lunch Charity Board
    - not a good look.Enclosed cork bulletin boards combine the ease of use of a
    regular cork board with the protecting power of a sturdy wood or aluminum
    cabinet and break-resistant acrylic windows or tempered glass found in enclosed
    display cases. Many enclosed corkboards come with front door cam locks for
    added security. Outdoor enclosed bulletin boards are built with an extra layer
    of protection to withstandNorth Face
    Jackets Outlet
     the elements -
    particularly water that can damage the printed materials you want to display.DCY

留下一个回复