第一篇:游戏编程入门
游戏编程入门
经常有人问我,没有编程经验的人该如何开始开发游戏。在此之前,我总是一个个的尽力回答。然而,后来提相同问题的人数增长到难以处理的地步。我决定,是时候把我所有的建议写成文章,作为一个大概。
这篇文章是针对那些想要开发自己游戏,但几乎没有编程经验的人。事实上,我假设读者没有任何编程经验。我主要讨论游戏开发的程序和设计方面,而不是艺术性。我也不准备讲述如何进入游戏行业(这方面已经有足够的资料),而只是让你逐步的开始开发自己的游戏。最后,我所指出的这条道路也并不能作为唯一的,或是最好的路径来学习开发游戏,但至少对我和一些人很有用。选择一门语言
你要做的第一件事就是选择一门开发语言。你有很多选择,包括
Basic,Pascal,C,C++,Java,等等。也经常会有人争论对于初学者那一门语言是最好的。对于这一系列流行语言的讨论,你可以参看John Hattan的著作,What Language Do I Use?(我用什么语言?)
我的建议是以C和C++开始。有些人会说这些语言对初学者来说太高级了,但因为我自己就是学C++,我并不同意这一说法。而且,C/C++是当今使用最广泛的语言(译者认为应该是汉语。。),所以你可以找到大量学习资料和帮助。你先学C或C++都无所谓,因为只要学了一个,再学另外一个就很容易。但是,如果你先学C++,请保证在学习面向对象编程之前能理解和使用过程编程(等编程熟练再去学习类)。(译者:C是过程性语言,C++是面向对象语言)
如果你开始学习C/C++,发现太难,那再学一个简单一点的也没关系,比如Basic或Pascal。但是我真的认为,如果你坚持努力,而且有好的资料,学C/C++应该没有太大问题。
你的下一个问题可能会是:“我该怎么学C/C++?”我很高兴你这样问。最好的办法是上课。有老师可以回答你的问题,帮助你产生很大进步,编程练习作业也可以保证你能用到所学的东西。
如果你不觉得上课是个好主意,那最好的办法就是买一些好书。不要花太多时间去选一本什么“超级宝典”或“万用全书”,因为你最终可能会买几本。我建议你去一家书店,然后拿几本比较入眼的C或C++书看,直到找到一本或几本你能看懂,并且可以拿来学习的。同时,你可能会想要一些更深入的,或者一些材料,但是你一旦对于这门语言有了一些了解,我相信你应该有自己更好的选择。在这里,我有必要花一些时间,来说我看到很多初学者所关心的一个事情,特别是年轻人:没有钱买书和其他东西。首先,有很多免费资源可以利用,图书馆,Macmillan Computer Publishing(/personal),有成千上百的编程书籍。但是如果你真的想要成为一个好的程序员,还是应该投入一部分资金。应当想方设法(合法的)帮助你弄到一些钱。
网上也有很多C/C++的学习指南。但是我认为那只能作为补充而不是你自学的主要资源。
选择正确的编译器
你写的程序,或者代码,是以文本方式储存的,你甚至可以用记事本写C/C++程序。但是总需要有东西把他们转换成为可执行文件。对于C和C++,那就是编译器。
可用的编译器有好多种,包括很多免费的。选择一款自己适合的编译器很重要,免费的编译器就有这样的好处,你可以把它们试个遍,然后从中选择自己最喜欢的。然而,免费编译器比起商业版,可能会缺失一些功能和大部分服务。幸运的是,多数商业版编译器也兼售介绍版或学习版,这要便宜得多,通常功能却不见得少,唯一的限制是你不能发布用它编译的程序(短时间内你也根本用不着)。
总之,选择编译器取决于你能花多少钱,用什么操作系统,和为什么平台开发。如果要为windows开发,我强烈推荐Microsoft Visual C++。他强大的开发环境使得很多事做起来更方便,毫无疑问没有其他编译器更适合开发windows应用程序。如果你是个学生,你还可以折价买到。(译者:爽!)如果你在DOS平台开发,你最好的选择可能是DJGPP,免费的哦~。
选择开发平台
尽管最终你很可能为好几个平台开发,总要先选择一个来学。当你在学这门语言,还没有接触到图像的时候,你可能会想使用非图形用户界面的操作系统,比如DOS,Unix.这样可以避免接触高层,比如windows编程,让你集中精力学习语言本身。
一旦你做好开发游戏的准备,那么,应该考虑是否改变平台,让我们来看看每个选项的特征。
windows:如果你想成为游戏行业的专家,或者如果你想让许多人来玩你开发的游戏,那么,这就是你要选择的平台。因为多数你的用户使用windows,而且现在我也看不出有什么改变的迹象。当今大多数的windows游戏都是由一种你可能听说过技术---DirectX---开发的。你可以DirextX这个库直接访问硬件,这意味着你可以开发高性能的游戏。
DOS:DOS过去是占统治地位的游戏平台,但是已经一去不复返了。尽管可能有一些特殊爱好者还在为DOS开发游戏,现在没有一个为DOS开发的商业游戏,他也将继续衰落,直到微软不再支持。如果你只是想开发游戏,还是不要选择DOS,如果你非要这么做,也不要太久。记住:由于存在大量DOS游戏开发的书,可能还有人辩护从这些书中学习DOS游戏开发。但是,windows游戏开发的书越来越多,那些辩解也变得越来越无力。
Linux:Linux是Unix的一种,由于很多原因后来变得流行,包括稳定性,价格,和反微软情绪。尽管Linux用户还是相当少,但是围绕着他的热情和不断增长的市场潜力使其也成为不错的选择。
Macintosh:MAC有大量忠实粉丝并不能说明什么,几乎每一个和我讨论的MAC狂热者都需要更多更好的游戏。我没有见过多少MAC游戏开发资源,但我相信还是有的,因此这也是一个选择。
consoles:console(就是PS,N64,DC等等)的游戏市场十分巨大,当然
console游戏开发的前景也不错。然而以非商业的形式开发console游戏,出于各种原因,在现在似乎行不通。如果你开发console,很可能是在被商业游戏开发组雇用之后。
开始进入主题
现在是时候讨论开发游戏了。简单起见,我假设你选择用C/C++在windows平台开发,可能你选择别的,但大多数我说的还是有用的。
首先,甚至在你打算开始开发游戏之前,你必须很好掌握C和C++.你应该懂指针,数组,结构体,函数,可能还有类。如果你精通他们,就可以开始做游戏了。
这篇文章可能不能教会你所有关于开发游戏的东西。幸运的是,也没有这个必要。这方面有很多书,网上也有很多指南。GameDev.net应该有所有你想要的东西,这里我建议你怎么开始:
找一本或几本书。对于windows游戏开发初学者,Tricks of the Windows Game Programming Gurus是个完美的开始。除此之外,还有许多好书.读透这些书,试试所有的例子,不懂得部分多读几遍。
网上指南作为补充。除了弄清书上读到的,他们还涉及一些书上没有谈及的主题。
向专家寻求帮助。如果你不能在书上或指南找到问题的答案,好好利用我们的论坛和聊天室。那里有好多专家愿意帮助别人。
这并不是要你按照顺序执行的,而是可以同时并且不断的重复执行。
光学习还是不够的,你必须运用你所学到的。从一个小游戏开始,然后在这个基础上前进。你可以看一下Geoff Howlands 的著作: How do I Make Games?
A Path to Game Development.开始,自己独立工作。不要急着加入团队,那样只会减缓学习过程。而且一旦你有了自己的几个游戏,你可以为团队做出更大的贡献。
还有关于书,你应该不仅仅看游戏开发的书。为了能够开发出你看到商店出售的游戏,你应该钻研比大多数游戏开发书籍更高级的一些主题。有一些可以在网上找到,但你也应该选一些图形学,人工智能,网络,物理学等方面的书。计算机科学学位看来唾手可得,但因为你被迫上这些课的时候可能认为他们和游戏开发无关----你错了!
包装
这里有一些提示很有用
不要只积累知识,用它:你永远不会知道会理解一些东西知道你是用他们。用你学的东西作些演示。做作书上的练习。
经常玩游戏:这样做会使你做出更好的游戏。而且可以减轻编程的枯燥。帮助别人:能帮别人的地方尽量帮助别人,教别人的过程中自己会学到更多。有始有终:不要有这样的想法“我能够完成这个游戏了,但是我又有一个新的想法,那就直接做下一个。”你可以学得更多如果你完成他,你也可以用事实证明你不是只会空谈。所以,尽量不要做很大很复杂的游戏,直到你有了一定经验。
开始吧!你现在可以开始准备QUAKE4了。可能你不是不是很了解,但是至少应该知道如何开始这条道路,找多些资料,加上多年努力工作,他一定会实现!
第二篇:学习编程入门2
接触编程有两年多了,也算积累了一些经验,希望能给刚入门的朋友一些帮助,文章仅代表本人观点,如有错误之处,还请多多包涵。
1.我该学什么语言?
VB、VC、Delphi、Java……面对各种各样的编程语言,你是不是被弄昏了头脑呢?该学什么?“学VC吧!”许多高手说。并且还举了很有说服力的例子:“学VB只要两个月,学VC要一年,如果先学VB再学VC,所用时间仍然是一年,但学了VC再学VB,所用时间将不到两个月。”这句话没错,的确是这样的。但是刚入门的初学者都能学VC?把每个人都看得这么高?一些初学者把VC当成自己的入门语言,结果能学到最后的只有少部分人!我们不能奢望所有初学者都是在十分熟悉Windows的情况下才开始接触编程的,实际上,很多人就是在学习编程的过程中逐渐深入了解系统的,要是所有人都选择VC作为“入门级语言”……
初学者应该根据自身情况来选择语言,如果你刚开始接触系统,应该去学VB,因为VB很好学,基础最重要;当然,还有Delphi,它介于VB与VC之间。除非你比较熟悉Windows,否则别急着学VC,你会因此神经衰弱的。
2.切忌同时学习多种语言
有没有试过同时学英语俄语德语波兰语法语日语?最后八成会变成鸭子。学编程也一样,如果你才高八斗机敏过人玉树临风,那么随便你同时学VC、VB、Delphi等等等等,没人会拦你,但如果是初学者呢?去做鸭子吧。同时学这么多种语言还不如踏踏实实学好学精一门适合自己的语言!初学者往往什么语言都要去了解一下,更有甚者连一些概念都不熟悉就什么都学,面对他们,我都要自愧不如了,但我还是要劝他们一句:一样一样的学,没有人能一步登天!别以为同时学多种语言就很“光彩”,当心最后仍是七窍通了六窍。
无论学哪门语言,都要把它学好再想其它,别“花心”,如果你是学VB的,至少要熟悉VB编程并且能熟练使用API的时候,你才应该去学其它语言,学VC更要注意,否则最后只能“无所不学,而一无所知”,只学一种语言时遇到困难还是好处理的,但是同时学这么多种,你保证都不遇上问题?小心几种语言的问题一起来压你!
3.要有主见
许多初学者爱跟着潮流走,外面流行什么他就跟着做什么(追“猩”族?)今天流行VB他就学VB,明天流行Delphi他就把VB忘了,再到VB.Net、C#……人云亦云,随波逐流,“专家”说什么语言好他就投奔什么语言,“走在科技前沿”,但是到最后又能学到什么?不仅丢了西瓜,连个绿豆都没拣着。这年头“世界变化快”,我知道,但是它怎么变就随它去,总不见得把你变成今天张三明天李四吧?“月亮走,我也走”的思想要不得,别管外面流行什么,如果不是大众需要,你只管学好你该学的语言就行。
4.别看轻其他语言
经常有人说“XX语言差,学了没前途!”要是让我评价一句,恐怕是你没前途吧?你凭什么说它差?没有一种语言是十全十美的,即使它再“差”,只要它还没有被外界宣布完全淘汰,它就有存在的理由!曾经有人对我说:“我的老师经常教育我,VB太差了,所以我要把以前学过的忘掉。”且不说这家伙随波逐流,单是他老师就够酷了,呵呵,不知道他的老师是圈子里的哪位资深专家呢?只怕是个三角猫吧!VB虽然存在一些局限性,但它的语法很好理解,数据库编程很方便,配合API也能完成一些复杂工作,这就叫差?多少个优秀程序不是用VB这个“没前途”的语言写出来的?多少个程序员不用VB?你看见他们没前途了吗?
5.不可缺少的教材
虽然从古到今一直有“尽信书,宁可无书”的遗训,但是我们可别因此“无书”哦!也许你天资聪明,自学电脑不用教材,但是自学电脑可以凭现象和经验,学编程能凭空摸索?连变量、过程等概念都不知道,还能
看懂for(i=1;i<50;i++)的意思?要学编程绝对不能少教材资料,如果连这都不舍得买,那么你最好别学了。还有一点,关于网络教程,我个人认为它太过于零散了,即使是一本完整的电子书也尽量不要看(除非实在买不到),难道你要一边写代码一边ALT+TAB?我宁愿慢慢翻一本书,也不愿盯着屏幕看半天!现在市面上的教材参差不齐,光买一本是明显不够的,基础的、高级的都要买回来慢慢研究,至少也要3本吧?市价低于20元的书最好不要考虑了,看看它的厚度!书本的厚度通常与含金量是成正比的(厚厚一本垃圾?你衰),最好选一些比较常见的出版社出版的书籍,尽量别买少见的,质量没得保证!我的一个同学就买了一本20元的垃圾,整本书连个完整的例程都没有,还大言不惭“基本入门”,误人子弟啊!现在那同学看的是我借给他的清华大学出版社出版的《中文 Visual Basic 6.0 傻瓜书》。
一个小窍门:如果你不知道该买什么书,最好找个高手一起去,让他帮你选本好的,如果你身边没有高手,那就找厚点的!或者书名带有“疑难解答”或“API”,这些书质量一般都可以。
6.关于英语
由于大多数语言的母语都是英语,这就导致了一些初学者望而却步,但是英语对于编程很重要吗?实际上编程需要的英语很少,都是比较基础的词汇语法,它和一般的英语不一样,即使你连一篇英语文章都看不下去,但只要有点英语基础的,你就不用怕“不会”!(当然前提是一些基础词汇如If、For、Next、While、include等必须看得懂,否则先去补习一点英语再说)就算英语再好,没学过编程也不会看得懂程序源码,难道没学过编程能知道StrComp等于String Compare?学编程与英语水平无关,我们学的是编程而不是英语!
7.编程大忌——组装
VB最大的方便之处是它和ActiveX能很好组合,MS和第三方厂商为VB开发了许多ActiveX控件,为初学者提供了很好的学习机会,但是一些初学者却满足于此,做一个程序用了一大堆别人的控件,加上一点微不足道的代码,就以为学会了编程,却不知这样根本没有入门!ActiveX是别人做的东西,写了多少代码才到你用的!别幻想ActiveX无所不能,从另一个方面说,它正是VB的累赘!会用ActiveX又有什么了不起?API会吗?复杂点的代码会写吗?会自己开发ActiveX吗?做一个用到通用对话框的程序,只会用comdlg32.ocx的ShowOpen方法,却不会用GetOpenFileName这个API来打开,而且使用ActiveX会让你的程序挂上一大堆OCX,加重程序开销,更要命的是ActiveX会导致许多不可预料的错误,如控件过期、控件没有注册等,任何一个错误都会让你的程序无法运行,许多初学者搞不清ActiveX与程序文件的关系,发布软件时忽略了程序需要的ActiveX,导致程序在其他环境无法运行,我早期发布的IIS Cracker就因为不得已用了两个ActiveX而成为我最头痛的事(有些东西不用ActiveX做不出来,没办法)如果一个程序出现控件错误,而作者又没有提供相应的控件,那么我要做的就是把这个程序删除!在此提醒各位一句:写程序不是组装!别以为用VB画个窗体,加几个ActiveX就学会了编程,你根本连编程的门槛都没入!
8.循序渐进
许多初学者刚开始接触编程就急着写一些较高级的代码,却忽略了最重要的基础,他们也许热情高涨,也许有心学编程,但是却没能静下心学编程基础,这将导致付出时间多而收获少的后果,举个例子吧,你刚入门,连一个简单的程序都不会做,就算我给你个木马程序的全部源代码(谁要独裁者的代码?呵呵)你又能看懂多少?学习要一步一步来,没有扎实的基础,谁都不可能写出好程序。当然,学习的方法也不能不提,尽管学VB、Delphi不需要专门学Basic、Pascal,但是学VC就不能不学C/C++了,否则你会前进得很辛苦!别信什么“速成班”、“24小时学会XXX”,那种是喂猪的!经验要靠练习来积累,不能只学理论,编程不是让你纸上谈兵的,平时不多练习,别想写出什么好程序!学习时要从简单做起,先熟练简单编程,在这个基础上要写出高级点的程序就不困难了,遇到难题别被吓着,努力克服它(除非是由于语言的局限性而做不到的),如果暂时做不出来,可以先搁一段时间,但别把它忘了。等你学到更高一层的技术
后,再回头研究过去的难题,将会事半功倍。
9.在学好一种语言的基础上,继续学习其他语言
别误会,这不是让你同时学习N种语言,而是在学好一种语言后,继续学其它语言,例如学好VB后,可以改学C、Delphi等,不要守着VB不放,多一种语言就多一条出路,如果你觉得自己学得够好了,那就别犹豫,马上改学另一种语言(喂喂,你怎么把VB的书给烧了?不是让你放弃已经学会的语言啊)还是那句话,切忌同时学习多种语言!如果你对自己掌握的水平没信心,最好还是别想其它了!
多学几种语言的好处是显而易见的,一来可以做到几种语言同时配合,二来对扩大知识面也有很大帮助。注意:学VB/Delphi后马上学VC是错误的,你必须先学会C!
10.用多种语言配合,多利用各种语言的长处
前面已经提到过,各种语言都有短处,但是它们一般都能互相弥补,VB的局限性导致一些复杂工作不能实现,VC强大,但是界面难做(个人想法),这时你可以用VB写界面,VC写DLL供VB调用。例如VB的指针、位运算操作麻烦且执行速度比较慢,在一些特殊应用环境里,就必须用VC写DLL了,其实写个DLL并非难事,甚至比写个VC的MFC程序还要简单。
11.多收集信息
学编程不能闭门造车,有些知识是书本上没有的,应该多使用搜索引擎,多搜集研究前辈们做的源代码,吸收一些新知识和优秀思路,有助于提高编程水平,另外还应该参与一些论坛的讨论,积累一些经验。
第三篇:编程入门基础知识点总结
一、常量
数字常量
i.普通数字:1,35,2.7 ii.指数形式:2.45e-2等价于2.45*10-2 注意e大小写皆可,e前面的数字不能省,就算是1也不能省,后面的数字一定要是整数
iii.长整型,单精度浮点型:3235L,32.5F 分别表示3235是长整型数据,32.5是单精度浮点型左,若不写上L,F则表示3235是整型,32.5是双精度浮点型,L,F大小写皆可
字符常量
i.普通字符常量:用单引号把一个字符括起来,如‟A‟,‟@‟
ii.转义字符常量:一对单引号括起来并以“”开头的字符序列,如‟n‟(回车)、‟123‟(8进制123对应的字符), ‟x23‟(16进制23对应的字符) 字符串常量
用一对双引号把一个字符序列括起来,如“ABCef”,系统存放字符串常量,每个字符分配一个字节,各字符所占字节紧邻,并且字符串末尾会给再开一个字节里面放一个’ ’做为结束标志。
符号常量
定义格式 #define 符号常量名 符号常量值,如#define N 20则定义了符号常量N,其值为20,注意符号常量名和符号常量值之间是用空格隔开,而不是写上=号,#define和符号常量名之间也有空格的。
题目:P7—1,5,6,7,9,10
二、标识符
命名规则
以数字,字母,下划线这三类字符组成,但只能以字母或下划线开头,而不能也数字开头,另外不能将关键字做为标识符。32个关键字表在P365附录B 变量名,函数名,符号常量名全都是标识符 题目:P7—2,3,4
三、变量
变量的定义格式
类型名 变量名;如 int a;定义了一个整型常量a。变量名是由人类随便定义的,符合命名规则的前提下,爱写啥就写啥。所以什么flag,cc,y1或者函数名fun,find等全部是自定的用来做为名字而已,没有更特别的意义。
类型名
int 整型,long 长整型: 用于存放整数,只是数值范围不同
float 单精度浮点型 double 双精度浮点型:用于存放实数,数值范围,精度不同
char字符型:用于存放字符
变量赋值,初始化
int a=3;定义的同时初始化
a=6*9;定义后在程序中进行赋值
变量的值
只有在赋值操作时才会被改变,即将其放在等号左边时才会改变它的值,或自增自减操作:a=5,a++,a--,像a+3并未改变a的值,只是使用了a的值而已. 自增自减运算
变量++,++变量,变量--,--变量
使变量的值自增1或自减1 等价于 变量=变量+1 变量=变量-1 ++,--放于变量前后效果的区别:
当自增自减运算做为表达式的一部分时,++,--放在变量前面是先自增自减再使用变量的值,放在变量后面则是先使用变量的值,再自增自减。如x=3;printf(“%d”,++x);则相当于执行了++x;printf(“%d”,x);这样的操作所以打印出4 再如x=3;printf(“%d”,x++);则相当于执行了printf(“%d”,x);x++;这样的操作,则打印出3,当然最后x的值还是4。
四、表达式
运算符和运算对象
一个运算符都有若干个运算对象,如 + 必然要跟两个运算对象才能进行加法运算:3+5。C语言里称需要跟n个运算对象的运算符为n元运算符。一元运算符有:!,(类型名)二元运算符有:+,-,*,/,%(求余), =,+=,-=,*=,/=,%=,< , > , <=, >=, = =(等于),!=(不等于),&&(且), ||(或)多元运算符有:, 运算符的优先级和结合性
i.优先级:同一个运算对象左右两边若同时有两个运算符,则这两个运算符优先级高的先进行运算。
ii.结合性:若同一个运算对象左右两边的两个运算符优先级相同,则根据结合性判断先进行哪个运算,自左自右结合性的先算左边的运算符,自右自左的先算右边的运算符。
iii.各运算符的优先级和结合性见P365附录C 强制类型转换
格式:(类型名)表达式。将后跟的表达式的值的数据类型转换为与圆括号内的类型名一致的类型。注意类型名一定要用()括起来。
算术表达式
i.算术运算符:+,-,*,/,%(求余)ii.由算术运算符加上运算对象构成算术表达式,如3+3*6-9/2 iii.值:跟我们小学时学的一样,就是表达式的计算结果 iv.整数除以整数结果取整数部分,故1/3得到的值是0 v.5%3 结果为2,想想小学除法,求余得到的是余数不是商。 赋值表达式
i.赋值运算符:=,+=,-=,*=,/=,%= ii.赋值表达式:变量=表达式,如x=3+6,x+=6-9,x+=x*=3+4 注意等号左边只能是变量
iii.复合赋值运算符的运算:以/=为例:x/=表达式 等价于 x=x/(表达式)iv.值:=号左边的变量最终的值 关系表达式
i.关系运算符:< , > , <=, >=, = =(等于),!=(不等于)ii.由关系运算符加上运算对象构成关系表达式,如3>=4, 2==a iii.值:满足相应运算符所指定的关系的值为1,否则为0 逻辑表达式
i.逻辑运算符:&&(且), ||(或),!(非)ii.由逻辑运算符加上运算对象构成逻辑表达式,如3&&4, x||!y iii.值:满足相应运算符所指定的关系的值为1,否则为0 iv.进行 ||或 运算时,若||左边的表达式值为1,则不再对右边的表达式v.进行运算。进行 &&且 运算时,若&&左边的表达式值为0,则不再对右边的表达式进行运算。 逗号表达式
i.逗号运算符:,ii.用逗号将各种表达式连续起来构成逗号表达式,如3+4,a=9,8*a iii.值:组成逗号表达式的各个表达式中的最后一个的值,如上例为8*a 题目:P7—11~17 P8—18~33
五、输入输出函数
scanf(“格式控制串”,变量地址表列);如scanf(“%d%c%d”,&a,&ch,&b);
scanf(“%4f”,&x);注意:
i.格式控制串可控制截取用户输入的前几个字符给变量,但不能控制输入几位小数给变量,如不能写成scanf(“%4.2f”,&x);ii.第二个参数给的是地址,即要么是&+变量名或数组元素名的形式,要么就是一个数组名或指针变量名,如int *p,a;p=&a;scanf(“%d”,p);iii.考试时注意看题目给你写好的scanf的格式 1.若其格式控制串内各格式符用“,”隔开如scanf(“%d,%c,%d”,&a,&ch,&b);那输入时也要用逗号隔开,如此例输入时应:3,+,5 2.若是这种格式scanf(“%d %d”,&a,&b);则输入时应:3 5;3.若是这种格式scanf(“%d%c%d”,&a,&ch,&b);则输入时应3+5,若写成3 + 5则a=3,ch=‘ ’(空格),b=任意值
(自己上机运行看看结果)
printf(“格式控制串”,输出项表列);如float x=7.5;printf(“%8.2f”,x);此处的意思是将x打印出来,且占8列,保留两位小数。自己上机运行看看效果。
常用格式符汇总:
i.%d:输入输出整型数据,%ld:输入输出长整型数据 ii.%c:输入输出字符型数据
iii.%f:输出单(双)精度浮点型数据,输入单精度型数据。
%lf:输入双精度型数据
iv.%s:输入输出一个字符串,用printf输出字符串时,输出项书写时可
为字符串常量,或字符数组名。如printf(“%s”,”hello”);或char str[10]=”hello”;printf(“%s”,str);v.%u:输入输出无符号整型,%o:输入输出八进制数,%x:输入输出十六进制数
getchar();函数调用后返回用户输入的一个字符,故需再定义一个变量来存放这个字符,即使用时应 char c;c=getchar();意思就是接收用户输入的一个字符,并将其赋值给变量c。
putchar(字符常量或字符变量名);
如char c=‟A‟;putchar(c);或putchar(„A‟);都会向屏幕输出字符A。
六、C语言的语句
表达式语句:由表达式末尾加上分号构成。
函数调用语句:由函数调用表达式加上分号构成。空语句: ;
选择结构语句:if语句 switch语句
循环语句:for语句 while语句 do while语句
复合语句:用花括号{}将以上任意语句括起来构成一条复合语句。
七、C程序的基本结构
void main(){
声明部分:用来定义变量和声明自定义函数的原型,需以“;”结尾,如int x;
执行语句部分:第六点里介绍的各种语句,如x=3;printf(“%d”,x);} main函数外可写自定义函数。如 int max(){
return 0;}
八、选择结构语句
if(表达式)语句1 else 语句2
如果if语句的圆括号内的表达式值为非0,则执行语句1,值为0则执行语句2。
i.表达式可为任意表达式,if语句执行的实质是判断表达式的值是否为0来决定执行语句1还是语句2。另外请在此处表达严重关切,不管是高ii.手还是菜鸟经常会把判断两个数相等的符号“==”写成了一个等号“=”成为了赋值运算,这样的写法不会引发编译错误,但结果会与原意大大不同,所以考试前请再三提醒自己。
语句1和语句2都只能是一个语句,若要跟多条语句,切记用一对{}括起来,构成复合语句;也不要随便在圆括号后加“;”,因“ ;”构成一条空语句,这会使后面跟的语句1不再属于if语句的组成部分。
iii.if语句的三种结构
1.单边: if(表达式)语句
2.双边:if(表达式)语句1 else 语句2 3.多层(重点掌握): if(表达式1)语句1 else if(表达式2)语句2 else if(表达式3)语句3 …
else 语句n 条件运算符 表达式1? 表达式2 : 表达式3
若表达式1的值非0,则取表达式2的值做为整个表达式的值,否则取表达式3的值为整个表达式的值。如 3>4? 1:2 该表达式的值为2 switch语句
switch(表达式){ case 表达式1:语句
case 表达式2:语句
…
case 表达式n:语句
default: 语句 } 语句执行过程:先计算表达式的值,然后判断该值与表达式1到表达式n中的哪个相等,若与表达式i的值相等,则执行表达式i后的所有语句,当遇到break;语句时结束整个switch语句的执行。表达式1到表达式n的值都不相等的情况下执行default后跟的语句。每个case后可跟多条语句。
九、循环结构
for循环语句
for(表达式1;表达式2;表达式3)循环体语句 语句执行过程: 1.计算表达式1 2.判断表达式2的值是否为0,若为0,语句执行结束,若不为0,进入步骤3 3.执行循环体语句(需注意的是循环体语句只能有一个语句,若要包含多个语句要用一对{}括起来,构成一条复合语句,此处也不要随便加上 “;”,因一个“;”可构成一条空语句,这会使得后面真正的循环体语句不属于for循环语句的部分)。进入步骤4 4.计算表达式3,然后重新进入步骤2 while循环语句 do while循环语句
i.while(表达式)循环体语句 执行过程:
1.判断表达式的值是否为非0,若是进入步骤2,否则结束语句执行。2.执行循环体语句,重新回到步骤1。ii.do 循环体语句
while(表达式); 执行过程:
1.执行循环体语句,进入步骤2
2.判断表达式的值是否为非0,若是重新回到步骤1,否则结束语句执行。
这里要注意的地方跟for语句一样,即循环体语句只能有一个语句,若要包含多个语句要用一对{}括起来,构成一条复合语句,此处也不要随便加上 “;”,因一个“;”可构成一条空语句,这会使得后面真正的循环体语句不属于while循环语句的部分,另外do while循环的while(表达式)后是要加“;”的。 break语句:放在循环体内实现的功能是结束其所在的那层循环的执行。
十、数组
定义格式:数据类型
数组名[整型常量];如 int a[10];定义了一个整型数组,数组名为a,这个数组含有10个元素。
引用数组元素: 格式:数组名[下标]
切记下标值从0开始。下标可为常量,表达式,变量等,如int i=3; a[0]=5;a[3*2]=9; a[i]=7;
初始化:数据类型
数组名[整型常量]={数据表列};将数据表列的各个值依次赋值给数组的各个元素。如int a[5]={0,1,2,3,4};则数组a各元素a[0]到a[4]的值分别为0,1,2,3,4 遍历数组元素
数组定义后,我们不能对数组进行整体的操作,如int a[10];不能用a=3这样的操作将数组的各元素都赋值为3;而只能一个一个元素的进行赋值,如a[0]=3;a[1]=3;a[2]=3…a[9]=3; 当然此时我们就可以借助于一个for循环来控制下标的变化从而对数组的各个元素进行赋值 for(i=0;i<10;i++)a[i]=3;
当然这只是用for循环遍历数组各元素的最简单的例子,一般考试考的是找出数组元素的某种特性的极值,比如最大值,最小值,或对数组各元素进行排序,这时我们就可以使用for循环来遍历数组的各元素,然后在当前循环中得到一个元素再对其进行处理。如i=2时访问到的元素是a[2],你就可以问问它,你是不是最小值啊。 整型数组
int a[10];整型数组里的各个元素存放的是整数。a[3]=3; 字符型数组
char str[20];字符型数组里的各个元素存放的是字符。
str[3]=‟A‟;
十一、字符串函数
gets(字符数组名或字符指针变量);
如char str[10],* str2;str2=str;则gets(str);或gets(str2);都是接收用户输入的字符串如“ABC”存入到字符数组str中
puts(字符数组名或字符指针变量或字符串常量);
如char str[10]=”china”;char *str2;str=str2;则puts(str);或puts(str2);或 puts(“china”);都会在屏幕上打印出 china strlen(字符数组名或字符指针变量);字符串测长函数
char str[20]=”hello world!”;
int len;len=strlen(str);得出的结果是len的值为12 strcat(字符串1的地址,字符串2的地址);
将字符串2的内容连接到字符串1的尾部。char str1[20]=”ABC”,str2[20]=”xyz”;strcat(str1,str2);
则程序运行的结果是str1内存放的字符串变为ABCxyz,当然str2存放的字符串还是xyz。
strcmp(字符串1的地址,字符串2的地址);
比较串1和串2哪个比较大。比较大小的依据是,两个字符串从左往右相应位置上第一个不相等的字符ASCII码值之差。char str1[20]=”ABCE”,str2[20]=”ABDE”;int i;i=strcmp(str1,str2);第一个不相等的字符为str1的‘C’和str2的‘D’,而二者相差-1,故-1做为strcmp函数执行的结果返回到被调用的位置,该位置位于赋值表达式内,故将其值赋值给i,即此时i的值就是-1. strcpy(字符串1的地址,字符串2的地址);
将字符串2的内容复制到字符串1内。char str1[20]=”ABC”,str2[20]=”xyz”;strcpy(str1,str2);此时str1的内容为”xyz”,当然str2的内容没变 strcpy(str1,”uvw”);此时str1的内容又变成了“uvw“。
十二、函数
函数定义
函数类型
函数名(形式参数列表){
内部变量定义和声明部分
执行语句
} 如:
int max(int x , int y){ int z;
z= x > y ? x : y;
return(z);} 注意点:
1.函数类型是指返回值的类型,即要与return语句后跟的表达式的值的类型一致。若函数类型为void则说明该函数无返回值,即函数体里不能出现return 语句。2.形式参数列表里定义的变量要记得给它们指定类型,而且如果同时要定义多个,应在每个前面都分别指定类型名,而不能写成int x,y;3.函数体里能写的语句跟main函数一样,在开头可定义所需要的变量,后面跟上一堆执行语句。 函数调用流程
以上面的函数为例,在main函数进行调用: void main(){ int a,b,c;
scanf(“%d%d”,&a,&b);printf(“%d”,max(a,b));或 c=max(a,b);printf(“%d”,c)以上两种方法都会在屏幕中打印出a,b间的较大值。
调用函数的格式 函数名(实际参数列表);调用的时候像什么函数类型,形式参数的类型就不要加上去了。max(a,b)中max就是函数名,写上变量名a,b是实际参数列表,执行这个调用语句时,会先把a,b的值给相应位置的形式参数即执行了x=a,y=b这样的操作,然后开始执行max函数的函数体的语句。当max函数体里执行到一个return语句时,则max函数结束执行,将return后的表达式的值返回给main函数调用max函数的那个位置,即若上面a=3,b=5则max(a,b)return后的表达式的值应该是5也就是说执行完max后把5返回到调用max的位置可看成printf(“%d”,5);或另一种解法的c=5。}
十三、指针
指针变量的声明: 类型名 * 指针变量名; 通过指针变量访问它所指向的普通变量的值
先将普通变量的地址赋值给指针变量,再通过指针运算符* 得到普通变量的值。int *p,x,y;x=3;p=&x;则printf(“%d”,*p);会打印出3即x的值 y=*p;则y的值变为3 *p=5;则x的值变为5 指针变量加上(减去)一个位移的效果
若指针变量存入的是数组元素的地址,则其加一减一得到的是那个数组元素下一个或前一个元素的地址。int a[10];p=&a[3];*p得到的是a[3]的值。
若p++;此时p存放的是a[4]的地址&a[4];*p得到的就是a[4]的值。或p--;此时p存放的是a[2]的地址&a[2],*p得到的就是a[2]的值。
行指针
i.主要是对于二维数组来说的,二维数组每行都有自己的地址,第0行地址用 数组名 表示,第i行地址为 数组名+i;而想要得到二维数组里一个元素的地址,必需先得到其所在行的地址,然后再由那个地址得到元素的地址,比如说 int a[3][4];定义了一个二维数组,该二维数组第0行的地址为a,第1行的地址为a+1,第2行的地址为a+2,想从行的地址得到元素的地址,需在行地址前加上指针运算符“*”,即*a就是第0行首个元素的地址即a[0][0]的地址,而a[0][2]的地址就是在a[0][0]的地址基础上加上位移量2,即*a+2,然后想得到a[0][2]这个元素的值呢就再加上一个指针运算符“*”,即*(*a+2),类似地,想得到a[2][2]这个元素的值呢就是*(*(a+2)+2)ii.定义行指针变量: 类型名
(*变量名)[数组长度];
如int(*p)[4],a[3][4];p=a;此时就可把p当成a来用,用法同上所述。
判断是否合法访问数组元素:若是指针法访问,判断指针后跟的是否地址;若是下标法访问,判断下标有无越界。
函数指针:函数名即为函数的地址(指针)
i.函数指针变量的定义: 类型名(*变量名)(形参列表);如 int(*p)();ii.赋值:指针变量=函数名;设有个函数其函数名为max,则要将该函数的地址给p的话只要执行如下语句即可 p = max;
指针数组:指针数组的数组元素都是指针变量,是用来存放变量的地址的,定义格式为 类型名 * 变量名[数组长度];如int * p[10]; 指向指针的指针:指针变量也是一种变量,故在内存中也有对应的一个地址,而要存放指针变量的地址,就要求助于用来存放指针变量的地址的指针变量,定义格式
类型名 ** 变量名;如 int *p1;int **p2;int a=3;可进行赋值p1=&a;p2=&p1;则a、*p1和 **p2的值都是3.十四、宏定义
无参宏定义 #define 标识符
值
定义后,出现所定义的标识符的地方都将以定义时指定的值来代替。
#define M 2+3 main(){ int x;
x=M*M;则x的值为2+3*2+3=11若想得到的结果是(2+3)*(2+3)则定义时也写成这样 #define M(2+3)} 注意#define、标识符、值之间都要用空格隔开,且宏定义结尾不需加分号。 带参宏定义
#define 标识符(参数表)值
#define S(x,y)x*y main(){ int a=3,b=4,c=5,d=6;
printf(“a*b=%dn”, S(a,b));此时会打印出 a*b=12
printf(“a+b*c+d=%dn” , S(a+b,c+d));此时会打印出a+b*c+d=29,带参宏定义执行时是将a+b这样一个表达式代替x,c+d这样一个表达式代替y,所以S(a+b,c+d)进行的是a+b*c+d的运算,而不是将a+b的值给x,c+d的值给y然后再做x*y,这点跟函数调用传递参数是不一样的。}
自定义类型名typedef:对已存在的类型名取一个外号。
i.基本格式:typedef 原类型名
新类型名;ii.typedef int INTEGER;则int a,b;等价于INTEGER a,b;iii.typedef int NUM[10];则 int a[10];等价于 NUM a;a即为一个有10个元素的数组的数组名。
iv.typedef int * INTEGER;则int *a,*b;等价于INTEGER a,b;
十五、结构体,共用体,枚举类型
结构体
i.结构体类型的定义及变量的定义
struct 结构体名
{类型 成员1;
类型 成员2;
……
类型 成员n;
}变量名;如
struct student { char name[10];long num;int score[4];}st1;定义类型时同时定义变量
struct student st2;定义类型后,用类型名定义变量 还有一种 struct
{ char name[10];long num;int score[4];}st3;不给类型名,直接定义变量
ii.结构体变量所占字节数:各成员各占字节数之和,如以上st1,st2,st3的字节数皆为10+4+2*4=22 iii.结构体数组的定义及初始化
struct student a[3]={{ “zhang”,20030001,89,90,91,92},{“liu”,20030002,68,69,70,71},{“li”,20030003,57,58,59,60} } iv.结构体成员的访问
1.结构体变量名.成员名 如st1.name[2] 2.通过指针访问:struct student *st;st=&st1;(*st).num 或 st->num 共用体
i.共用体类型的定义及变量的定义
union 共用体名 { 类型
成员名1;
…
类型
成员名n;
};
变量的定义与结构体类似,也有三种方法。union data {
int i;char ch;float f;}d1;定义类型时同时定义变量
union data d2;定义类型后,用类型名定义变量
union {
int i;char ch;float f;}d3;不给类型名,直接定义变量
ii.共用体变量所占字节数:各成员所占字节数的最大值,如上d1,d2,d3所占字节数皆为4.(单精度浮点型变量所占字节数最多为4).iii.共用体成员的访问
1.共用体变量名.成员名 如d1.f 2.通过指针访问:union student *d;d=&d1;(*d).num 或 d->num 枚举类型
i.枚举类型的定义:
enum 枚举名{枚举元素名1,枚举元素名2,…,枚举元素名n}; ii.枚举元素的值:
默认值分别为0、1、…、n-1。枚举元素的值也可在定义时重指定,对于没有指定值的元素,按顺序加1
如enum weekday{sun=7,mon=1,tue,wend,thur,fri,sat};则sun值为7,mon值为1,tue值为2,wend值为3,thur值为4,fri值为5,sat值为6
十六、Turbo C的使用
菜单激活: F10
菜单切换:左右方向键在不同菜单间切换,上下方向键在同一个菜单不同选项间切换。
载入文件:两种方法:1.找到源文件所在位置,直接将其拉到Turbo C快捷方式上;2.F3 运行程序: ctrl+F9
看程序运行结果:alt+F5 进入编辑状态:菜单Edit 保存: F2
插入状态切换: Insert键
第四篇:powerbuilder编程简单入门(个人总结)
2011-4 by 邵家鑫 From Tsinghua 一种简单的powerbuilder10数据库编程介绍
1、需求分析与数据库建立
进行需求分析(需求分析文档),确定数据关系,建立各种数据表,建立数据库(Access),设置ODBC数据源(控制面板->管理工具->数据源ODBC->“用户DSN”菜单下点“添加”选相应的数据源驱动程序,如果用Access2003建立的,则选第三项“Driver do Microsoft Access(*.mdb),然后点击“完成”->输入数据源名,如mydata,然后点击“选择”按钮选择建好的数据库,最后点“确定”,如下图所示)
2、界面设计(功能界面、重要数据表维护界面)
界面设计主要分为几个部分
(1)按照管理系统所需的功能设计界面。
首先画出所有可能的业务流程(数据的各种可能输入、修改、删除业务,数据的输出、显示业务)
(2)按照需要维护的表设计界面(往往给最高权限管理员直接修改数据用)
3、开始程序编写
(1)新建一个workspace(new->workspace->workspace)(2)在workspace下建立一个目标
(new->Target->application),可取名frame
2011-4 by 邵家鑫 From Tsinghua(3)在目标下建一个主窗口
可取名w_main,窗体名一般以w_开头(new->PB Object->Window),将其Window Type设为“mdihelp!”
(4)为主窗口建一个主菜单
可取名m_frame,菜单名一般以m_开头(new->PB Object->Menu)(5)程序中设置ODB ODBC 点击按钮,选中“ODB ODBC”项,然后单击右边“New”按钮,弹出如下对话框,设置Profile Name和Data Source,如图所示。
(6)建立配置文件
配置文件取名“config.ini”,内容如下:
[MyDB] DBMS=ODBC AutoCommit=False DBParm=ConnectString='DSN=mydata;UID=;PWD='
(7)自动连接数据库与退出程序关闭数据库的编写
2011-4 by 邵家鑫 From Tsinghua 首先建立Global Variables如下: string gs_userid,gs_username //登录用户标识、用户姓名 string gs_root_path,gs_ini_path
//应用路径和主配置文件路径
其次申明Global External Functions如下:
FUNCTION int GetComputerNameA(ref string computername,ref long size)LIBRARY “KERNEL32.DLL” alias for “GetComputerNameA;Ansi” FUNCTION long GetCurrentDirectoryA(long nBufferLength, REF string szBuffer)LIBRARY “KERNEL32.DLL” alias for “GetCurrentDirectoryA;Ansi” FUNCTION long SetCurrentDirectoryA(string szPathName)LIBRARY “KERNEL32.DLL” alias for “SetCurrentDirectoryA;Ansi” //end prototypes 在程序的总入口(进入“”)Open事件中写入以下代码: // Profile moneyandfriends string ls_1
//设置应用根目录
gs_root_path = space(255)GetCurrentDirectoryA(255, gs_root_path)if right(gs_root_path,1)= '' then gs_root_path = left(gs_root_path,len(gs_root_path)1)if pos(ps_sql, “group by ”)> 0 then
ls_end = right(ps_sql, len(ps_sql)pos(ps_sql, “order by ”)+ 1)
ls_where = mid(ps_sql, pos(ps_sql, “where ”)+6, len(ps_sql)-len(ls_front)-len(ls_end)-6)else
ls_where = mid(ps_sql, pos(ps_sql, “where ”)+6, len(ps_sql)-len(ls_front)-6)end if
2011-4 by 邵家鑫 From Tsinghua ls_return = ls_front + “where(” + ls_where +“)and ” + ps_where + “ ” + ls_end else if pos(ps_sql, “group by ”)> 0 then
ls_front = left(ps_sql, pos(ps_sql, “group by ”)pos(ps_sql, “group by ”)+ 1)elseif pos(ps_sql, “order by ”)> 0 then
ls_front = left(ps_sql, pos(ps_sql, “order by ”)pos(ps_sql, “order by ”)+ 1)else
ls_front = ps_sql
ls_end = “" end if ls_return = ls_front + ” where “ + ps_where + ” “ + ls_end end if return ls_return(2)在窗口中声明局部变量用来记录最初的没有where语句的窗口的SQL查询语句 string is_original_sql
(3)声明局部变量ls_old_select, ls_new_select,如下使用 string ls_old_select, ls_new_select ls_old_select = dw_ttxx.GetSQLSelect()if is_original_sql = ”" then is_original_sql = ls_old_select else //避免条件被循环添加
ls_old_select = is_original_sql end if
ls_new_select = f_change_where(ls_old_select, is_conditions)dw_窗口.SetSQLSelect(ls_new_select)
第五篇:编程入门基础知识总结
编程入门基础知识总结
基本知识
程序
= 算法 + 数据结构,算法是对操作的描述,数据结构是对数据的描述。伪代码:pseudo code 程序一般包括:
(1)预处理命令:#include等(2)全局声明部分
(3)函数:函数首部(声明)、函数体(局部声明+执行部分)程序执行过程
源程序-->编译成目标程序obj-->连接目标程序成可执行文件 类:数据成员+成员函数 命名空间
实际上就是一个由程序设计者命名的内存区域。程序员可以根据需要指定一些有名字的空间域,把一些全局实体分别放在各个命名空间中,从而与其它全局实体分隔开,解决名字冲突,防止全局命名空间污染。
C++库的所有标识符(标准头文件中函数、类、对象、类模版)都是在std命名空间定义的 A 的ASCII码值65
a 的97 1.数据类型
•基本类型:整型、浮点型、字符型、布尔型
•构造类型:枚举、数组、结构体类型(struct)、公用体(union)、类类型 •指针类型 •引用类型 •空类型:null int 4
unsigned int 4
short int 2
unsigned short int 2
long int 4 unsigned long int 4 char 1
uchar 1 float 4
double 8
long double 8 无符号:不用保存符号位,故比有符号多了一位
有符号:数值用补码存放(无论正负),最高位为符号位
VC中,long double与double字节数相同,故long double是无用的 GCC中,long double则有12个字节
无负值的量可以定义为unsigned int,如年龄、学号等,以增大存储范围。short int,long int,unsigned int这些类型后面的int可以省略 整型表示:
十进制,后面加L 或 l 八进制,前面加0 十六进制,前面加0x 浮点数表示:
默认为双精度型double 后面加 f 或 F 则为单精度float 后面加 l 或 L 则为长精度型long double 指数形式 数符
数字部分
指数部分
a = 3.14e2
a=0.314e4
a=31.4e1
a=3140e-1
浮点数,不管是用小数形式还是指数形式表示,在内存中都是以指数形式表示的,且数字部分必须小于1 如3.14159 在内存中表示为
+.314159,数字部分为.314159,是小于1的 字符型
字符型在内存中存储的是ASCII码,也是整型,故而可以把字符型赋给整型 字符串后面,编译系统会加个' '作为结束符 符号常量
用符号代表一个常量,如#define
PI 3.14159 在编译时,系统会把符号常量替换成具体的值
2.变量
变量:程序运行期间,值可变的量
变量名:代表内存中的一个存储单元,在编译连接时由系统给每一个变量分配一个地址 标识符:标识实体名字的有效字符序列,字母、数字、下划线
常变量:定义变量时加上const,运行期间值不可变,也即只读变量 区别#define 定义的符号常量与const定义的常变量 符号常量只是用一个符号代表一个常量,在编译时把所有符号常量替换为指定的值,它没有类型,在内存中不存在以符号常量命名的存储单元 常变量具有变量的特征,具有类型,在内存中有以它命名的存储单元,与一般变量不同的是,常变量代表的存储单元值不可变。
强定义的好处
1.保证变量名使用的正确,不正确会在编译时报错
2.每个变量指定为一确定类型,在编译时就能为其分配存储单元 3.编译时即可检查变量进行的运算是否合法。
3.运算符 二进制位运算 & 二进制 按位与 |
二进制按位或 ^ 按位异或 << 左移位 >> 右移位
++--自加自减运算符 ++i 使用i之前,i先自加 i++ 使用i之后,i再自加 ++--结合方向为自右向左 例:!x++
先取非,再++(i++)+6 先i+6,后i++,不管有无括号,都是先运算,再自加
(++i)+6 先自加,再加6-i++ :i左面是符号运算符,右面是自加运算符,设i等于3,运算过程相当于-(i++),即-i=-3-3+1=-2 a =-i++:a结果为-3,先赋值,再自加; 5-i++ =?
答案2
?待测试
i=1,j=2,则a = i+++j ?
答案:3 因为相当于a=(i++)+j;i=1,j=2,则a=i+(++j)?
答案:4
赋值运算符=的优先级小于++--运算符
示例:
int arr[] = {6,7,8,9,10};sint *ptr = arr;*(ptr++)+= 123;printf(“%d,%d”,*ptr,*(++ptr));解:
*(ptr++)+= 123;相当于 *ptr +=123;*ptr++;故arr[0] = 129;ptr指向arr[1] printf函数从右向左压栈,运算顺序:++ptr;输出结果: 8 8 cout也是自右向左压栈。
逗号运算符
又称顺序求值运算符
a = 3*4,a*5 则
a=? 答案 12 ?
注意逗号运算符优先级最低。注:整个逗号表达式的值为60(a=3*4=12,12*5 =60)x=(a=3,6*3)
则 x=18 x=a=3,6*a
则 x=3
3.内存存储
浮点数在内存里和整数存储方式不同
float a =1.0f;cout<<(int)a==(int&a);(int&a)相当于把该浮点数地址开始的sizeof(int)个字节当成int型数据输出,其值并不为1
(int)a显示转换等于1
4.类型转换
转换本质:按存储单元中的存储形式直接传送
(1)浮点型赋给整型,舍弃小数部分
(2)double型赋给float,防止溢出错误
(3)int,short,long赋给char,原封不动取低八位
(4)signed赋给unsigned,符号位照搬。负数以补码形式存放,-1赋给unsigned int,结果为65536.整数不会变,除非两个长度不同(int,long)发生截断
5.C++输入输出
C++输入输出包含三个方面的内容
(1)对系统指定的标准设备的输入输出。即从键盘输入、输出到显示器屏幕,称标准输入输出,简称标准I/O
(2)以外出磁盘文件为对象进行输入输出,称文件I/O
(3)对内存中指定空间进行输入输出,通常指定一个字符数组作为存储空间,称字符串输入输出,简称串I/O
在C++中,输入输出流被定义为类。C++的I/O库中的类称为流类,用流类定义的对象称流对象。
C++中输入输出是调用输入输出流库中的流对象cin、cout实现的,即I/O不是C++本身定义的,而是编译系统的I/O库中定义的。
I/O控制符#include
setprecision(n)设置精度为n,十进制输出时,n代表有效数字位数包括整数和小数;
fixed(固定小数位数)和scientific(指数)形式输出时,n指小数位数(不包括整数部分)
double a = 123.4567890123456
cout << a;
//十进制输出,输出123.456
默认精度为6
cout< //十进制,输出123.456789 精度为9 cout< //恢复默认精度 cout< //固定位数,123.456789,此时精度表示小数位数,精度为默认的6 6.getchar()和 putchar() cout< //读入的实际是ASCII码,故输出为字符ASCII码,97,而非读入的字符 cout<<(c=getchar());//输出为字符 while((c=getchar())!='n'){} //循环读入字符的控制 7.函数与模版 函数原型:不同具体形参的函数声明 如:float add(float,float) 主要作用:根据函数原型,在程序编译阶段对调用函数的合法性进行全面检查。 函数重载:同一函数名定义的多个函数,这些函数的参数个数,参数类型,参数顺序至少有一项不同,一个函数不能既是重载函数,又是带默认参数的函数。 函数模版:适用于函数个数相同,函数体相同,而只有类型不同的情况 [cpp] view plain copy 01.#include 03.template 05.{ 06.if(b>a)a = b; 07.if(c>a) a = c; 08.return a; 09.} 10.int main() 11.{ 12.int a=1,b=2,c=3; 13.cout< 14.float d=1.1,e=2.2,f=3.3; 15.cout<< T(d,e,f); 16.} 变量作用域:变量有效范围,有四种: 文件作用域 file scope 函数作用域 function scope 块作用域 block scope 函数原型作用域 function prototype scope 递归函数:函数体中,直接或间接调用函数本身的函数。 变量的存储类别:外部、局部(相对于函数而言) 全局变量(也即外部变量) 静态局部变量(static) 自动变量(不加static的局部变量) 寄存器变量(register)存放在CPU中,而非内存中,这样在使用时就省去了从内存中载入寄存器的过程。但只是建议性的,优化编译系统自动识别使用频繁的变量,从而自动将变量放入寄存器中。 extern声明的外部变量 即提前引用申明,表示该变量是将在下面定义的全局变量或在其它文件中定义(本文件中不用extern,引用该变量的外部文件用extern进行声明) static声明的静态外部变量 只能被本文件使用,而不能被外部文件使用的全局变量,这样不同文件中的全局变量不会相互干扰,为程序模块化、通用化提供方便。 注:全局变量也是静态存储的。 内部函数与外部函数 内部函数:static 声明,文件内使用 外部函数:另一个文件里extern声明,表示是其它文件的函数,extern可以省略 宏定义 #define PI 3.14 定义符号常量 #define Area(a,b) a*b //定义函数功能,下面当作函数来用。 #include <> 在系统目录寻找,找不到报错 ' ' 在当前目录寻找,找不到报错 字符数组 (1)char str[] = “i am happy”; 数组长度为11,而非10,因为后面有一个' ' (2)char str[] = {'i','a','m','h','y'} 数组长度为5,系统不会自动为其在后面加' ' 因此,(1),(2)是不同的 输出字符数组:cout< string类 字符数组是C中的处理方式,C++中用string类,#include 字符串变量中不会存放' ',只存放字符串本身,故string str =“hello”;的长度为5,要注意。 字符串变量存储的实际是字符串的指针,4个字节,sizeof(string)= 4; string name[]={“i”,“am”,“happy”}; sizeof(name)= 3*4 = 12; 变量与指针: int *p = &i; //int型指针变量,定义时的*只是表示指针类型 p是指针变量,其值是变量i的地址,*p则是存储单元,*&a与*p同,都表示变量a 指向数组的指针 int a[10] = {}; int *p; p = &a[0];//与下面等价,都指向数组第一个元素,因为数组名本身就是表示数组的地址 p = a;************************* *p++ 相当于*(p++),先得到*p的值,p再++移到下一个元素 (*p)++则是使*p的值+1 二维数组的指针表示: *(*(p+i)+j) 表示 a[i,j] ************************* int(*p)[n] p为指向含n个元素的数组的指针 int *p[n] 定义指针数组P 函数指针 指向函数的指针,主要用作形参 int max(int,int); int(*p)(int,int); p = max;赋值(地址) p(1,2)//调用 引用 int a = 10; int &b = a;b是对a的引用 引用传递,引用型变量作为函数形参 [cpp] view plain copy 01.//值会改变 02.main{ 03.int i=5,j=6; 04.swap(i,j) 05.} 06.void swap(int &a, int &b)//这里的&不是“a的地址”,而是指“a是一个引用型变量”,&是个声明符 07.{ 08.int temp; 09.temp = a; 10.a= b; 11.b=temp; 12.} 传递变量地址:形参是指针变量,实参是变量地址,这种虚实结合的方法仍然是“值传递”方式,只是实参的值是变量地址而已。 [cpp] view plain copy 01.//值会改变 02.main() 03.{ 04.int i=5,j=6; 05.swap(&i,&j) 06.} 07.void swap(int *p1, int *p2)//这里的*号也只表示是指针类型 08.{ 09.int temp; 10.temp = *p1; 11.*p1 = *p2; 12.*p2 = temp; 13.} 结构体变量 struct 作函数参数时有三种形式 (1)用结构体变量名作形参 这时形参要开辟内存单元,实参中全部内容通过值传递方式一一传递给形参,时空开销大,效率低 (2)用指向结构体变量的指针作形参,只有四个字节 void printed(student *p){ cout< num; } (3)用结构体变量的引用变量作形参 Student stu; print(stu); void print(Student &stu){ cout } new delete 动态内存分配 new 类型(初值),返回地址,分配失败返回NULL float *f = new float(3.14); int *i = new int(6); int *k = new int[5][4];//数组 delete 变量 delete f;delete i; 数组 delete [] k; Enum 枚举类型 声明枚举类型 enum weekday{sun,mon,tue,wed,thu,fri,sat};定义枚举变量 weekday workday,week_end;变量赋值: workday = mon; 或 workday = weekday(2);枚举常量对应值从0开始,0,1,2,3..typedef 声明新类型 typedef int INTEGER,相当于为int起了个别名,下面程序中就可以直接用INTEGER作int用了 主要为了方便系统移植,如long int在VC中4个字节,在GCC中占8个字节,直接用int的话可能会溢出,用INTEGER就不用担心了,只要把ypedef int INTEGER 声明语句一改就行 运算符重载 方法是定义一个重载运算符的函数,在需要执行被重载的运算符时,系统就自动调用该函数,以实现响应运算。即运算符重载是通过定义函数实现的,运算符重载实际上是函数重载。格式: 函数类型 operator 运算符名称(形参表列) {对运算符的重载处理} 例如:将 + 用于Complex类(复数)的加法运算,函数原型如下: Complex operator +(Complex& c1, Complex& c2); 注:operator 是关键字,operator + 就是函数名,可以描述为: 函数operator +重载了运算符+ 整数加可以想象为调用如下函数 int operator +(int a,int b) { return a+b;} [cpp] view plain copy 01.#include 03.class Complex 04.{ 05.public: 06.Complex(){real=0;imag=0;} 07.Complex(double r, double r){real=r;imag=i;} 08.Complex operator +(Complex &c2);//声明重载运算符的函数 09.void display(); 10.private: 11.double rea; 12.double imag; 13.}; 14.Complex Complex::operator +(Complex &c2)//定义重载运算符的函数 15.{ 16.Complex c; 17.c.real = real + c2.real; 18.c.imag = imag + c2.imag; 19.return c; 20.} 21.void Complex::display() 22.{ 23.cout< 24.} 25.int main() 26.{ 27.Complex c1(3,4), c2(5,-10),c3; 28.c3 = c1 +c2; //运算符+ 用于复数运算 29.cout<<“c1=”;c1.display; 30.cout<<“c2=”;c2.display; 31.cout<<“c1+c2=”;c3.display; 32.return 0; 33.} 34.运行结果: 35.c1 =(3,4i) 36.c2 =(5,-10i) 37.c1+c2 =(8,-6i) 重载运算符的规则 (1)C++不允许用户自己定义新的运算符,只能对已有的C++运算符进行重载。 (2)C++允许重载绝大部分的运算符 (3)重载不能改变运算符运算对象的个数 (4)重载不能改变运算符的优先级别 (5)重载不能改变运算符的结合性 (6)重载运算符的函数不能有默认的参数(7)重载的运算符必须和用户定义的自定义类型的对象一起使用,其参数至少一个是类对象(或类对象的引用)。也就是说参数不能全部是C++的标准类型,以防止用户修改用于标准类型数据的运算符的性质。 (8)用于类对象的运算符一般必须重载,但有两个例外,运算符“=”和“&”不必用户重载 (9)应当使重载运算符的功能类似于该运算符作用于标准类型数据时所实现的功能,否则不易使人理解程序 (10)运算符重载函数可以是类的成员函数,也可以是类的友元函数,还是计费成员函数也非友元函数的普通函数。