笨鸟先飞学编程系列之二基础代码的编写.doc_第1页
笨鸟先飞学编程系列之二基础代码的编写.doc_第2页
笨鸟先飞学编程系列之二基础代码的编写.doc_第3页
笨鸟先飞学编程系列之二基础代码的编写.doc_第4页
笨鸟先飞学编程系列之二基础代码的编写.doc_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

笨鸟先飞学编程系列之二 基础代码的编写通过上次课题的讲述,相信大家一定对什么是数据及数据的定义和使用方法有一定的了解了,在看本次课题之前希望大家能趁热打铁,再到网上下本C语言的教程,最好是买本数来巩固下变量相关的知识。大家明白了怎么定义变量,怎么给变量赋值了,自然的就应该进一步了解一下一些详细的代码怎么编写了。今天我们的任务比较简单,就讲一下如何编写代码及实现代码的流程控制。应该说这个是非常简单的东西了,本来我没打算讲它,可是本着一步一个脚印的原则,我还是简要的说一下。在本次课题之后,我会紧跟着出一个函数的专题,来作为代码篇的完善,至此大家应该能独立的写自己的程序了。本次课题知识点不是很多(也不少,但是都很简单。),主要是在于多写,多练,知道自己能把一些现实的问题转换成代码来解决问题。不多废话,先说下本次课题要写的主要内容:1. 程序的运算和逻辑判断2. 三种程序流程控制结构详解。3. 养成良好的代码编写风格。4. 结束语下面开始进入正题。一、 程序的运算和逻辑判断。说计算是电脑最基本的功能,相必没有人会反对的。做程序,自然最基础的就是这些运算了。我知道,看这个破烂文章的朋友对数据应该都是不感冒的。不过大家放心,这里牵扯的运算都很简单,就是小学的加、减、成、除、取余数,是、非、与或和位移,没别的了。先让我们来了解下算术运算。1. 算术运算。加减乘除相比大家都应该很了解的。这里我不想费太多的篇幅讲述这些大家都明白的知识,我把要说的知识列出来,大家自己了解就好。用于算术运算的运算符有:我想不用我说,加、减、成、除这些运算符大家都接触过的,关于“%”运算符,其实就是取余数;用这些运算符可以将一些数字,变量等连接起来,进行运算,这样的式子叫做表达式。例如:int i =5;i +7; / 这里就是一个表达式。“=”这个运算符其实不属于算术运算,它也并非是我们数学课上讲的“等于”,而是一个“赋值”运算符,它用来将一个常量(数字、字母等)赋值给一个变量的赋值运算符,由于我们进行算术运算以后,通常都会将运算结果保存到一个变量中,所以,我把这个赋值运算符归类到这里。而我们日常的“等于”运算符是:“= =”,它属于逻辑运算符,我们将在下一节中讲到它。关于“+ 、 ”这两个运算符,上图中已经说明了,它是对变量的对自己的自加或者自减运算,等同于:变量 = 变量+1; 或者 变量 = 变量 1;现在让我们来举几个例子,来说明下这些算术运算符的用法。void main()int x = 1;int y = 2;int z = 20;x +;/ 等同于x = x + 1; y -;/ 等同于y = y - 1; z /= x;/ 等同于z = z / 1;printf(%d, %d, %dn, x, y, z); / 打印 x,y,z 的结果。z %= x;/ 计算得出 z / x 以后的余数x = x+y;z -= x;printf(%d, %d, %dn, x, y, z); / 打印 x,y,z 的结果。请先不要看下面的截图,先看下这个程序,分析一下,这两次的输出结果会是多少,然后对比下图: 看下就算的是不是正确,如果正确了,那恭喜你,基础的算术运算就算通过了,接下来,我们需要调试这段代码,来熟悉一些相关的汇编命令,具体操作如下图所示:在代码上右击鼠标,选择如下命令:我们来详细分析一下我们现在看到的代码:1: #include stdio.h2:3: void main()4: 00401010 push ebp00401011 mov ebp,esp;/ 将现有的堆栈给了EBP寄存器。00401013 sub esp,4Ch;/ 分配x4C大小的堆栈空间用来运算。00401016 push ebx00401017 push esi00401018 push edi;/ 保存寄存器环境。00401019 lea edi,ebp-4Ch;/ 这里用ebp寄存器减去一个偏移来定位我们定义的变量,0040101C mov ecx,13h;/ 这里-4Ch是用来定位到堆栈头,把堆栈内容改成int3中断以免内存泄露。00401021 mov eax,0CCCCCCCCh;/ 以上操作是保存堆栈环境,分配堆栈空间。00401026 rep stos dword ptr edi;/ 在下一次课题讲述函数时,我们会讲到,这里大家可以略过。5: int x = 1;00401028 mov dword ptr ebp-4,1;/ ebp-4是我们的变量x,dword ptr是用来修饰这个变量是DWORD类型(也就是整型)。6: int y = 2;0040102F mov dword ptr ebp-8,2;/ MOV就是汇编指令,相当于我们C语言中= 赋值运算符,它的具体用法自己百度。7: int z = 20;00401036 mov dword ptr ebp-0Ch,14h8:9: x +; / 等同于x = x + 1;0040103D mov eax,dword ptr ebp-400401040 add eax,1; / add指令就是我们C语言的+运算符,还有一个INC指令相当于我们的+运算符00401043 mov dword ptr ebp-4,eax10: y -; / 等同于y = y - 1;00401046 mov ecx,dword ptr ebp-800401049 sub ecx,10040104C mov dword ptr ebp-8,ecx11:12: z /= x; / 等同于z = z / 1;0040104F mov eax,dword ptr ebp-0Ch00401052 cdq00401053 idiv eax,dword ptr ebp-400401056 mov dword ptr ebp-0Ch,eax13: printf(%d, %d, %dn, x, y, z);00401059 mov edx,dword ptr ebp-0Ch0040105C push edx0040105D mov eax,dword ptr ebp-800401060 push eax00401061 mov ecx,dword ptr ebp-400401064 push ecx00401065 push offset string %d, %d, %dn (0042001c)/ 传递参数,具体规则将在下次课题“函数”中讲述。0040106A call printf (004010f0); / 调用printf函数打印结果0040106F add esp,10h; / 这里是C条用的对战平衡方式。(具体将在下次课题“函数”中讲述)14:15: z %= x;00401072 mov eax,dword ptr ebp-0Ch00401075 cdq00401076 idiv eax,dword ptr ebp-400401079 mov dword ptr ebp-0Ch,edx16:17: x = x+y;0040107C mov edx,dword ptr ebp-40040107F add edx,dword ptr ebp-800401082 mov dword ptr ebp-4,edx18: z -= x;00401085 mov eax,dword ptr ebp-0Ch00401088 sub eax,dword ptr ebp-40040108B mov dword ptr ebp-0Ch,eax19: printf(%d, %d, %dn, x, y, z);0040108E mov ecx,dword ptr ebp-0Ch00401091 push ecx00401092 mov edx,dword ptr ebp-800401095 push edx00401096 mov eax,dword ptr ebp-400401099 push eax0040109A push offset string %d, %d, %dn (0042001c)0040109F call printf (004010f0)004010A4 add esp,10h20: 004010A7 pop edi; / 恢复寄存器环境004010A8 pop esi004010A9 pop ebx004010AA add esp,4Ch; / 平衡堆栈004010AD cmp ebp,esp004010AF call _chkesp (00401170); / DEBUG 模式程序专用的堆栈检查函数。004010B4 mov esp,ebp004010B6 pop ebp004010B7 ret相信你根据上述代码中的提示,应该能将这个汇编代码看的差不多,当然,看不明白也没有关系,我们需要掌握的汇编指令及其用法很少,就下面几个:mov/lea:赋值/取地址。add:加法指令。sub:减法指令。div/idiv:除法指令。mul/imul:乘法指令。这些汇编指令的具体用法大家自己百度或者参考相关资料,这里不做详细说明, 下面开始我们的逻辑、关系运算。2. 逻辑、关系运算。提起什么逻辑运算,或者什么关系运算,看名字貌似很复杂的。不过这里可能让大家放心的是,这些运算我们日常生活中经常用到,无非就是 真的,假的,是,不是,并且,或者之类的操作。用于逻辑运算的运算符有如下几个:运算符含义& 与(并且)|或(或者)!非(不是)用于关系运算的运算符有如下几个:这些运算无非就是为了判断一个表达式成立不成立,在C语言中,只要表达式的值不为零并且符合关系运算符的要求,那这个表达式就成立的,就可以用上述的两种运算符进行比较运算,一般情况下,这些运算符会配合下节我们要讲述的流程控制语句来使用,所以这里我就不给出具体用法的例子了,有情趣的朋友,可以继续看下面章节中的例子到现在我想主要的运算我都讲完了,虽然不是很详细,但是我想,只要大家坚持努力,多多百度,这些知识一定会掌握好的。小学的时候,我们学过四则运算,在运算的时候,遵循先乘除,后加减,有括弧的先算括弧里面的,这个规则在这里一样使用,只不过在编程环境中,运算符很多,所以需要有个更为详细的运算符优先级表。这里我把它贴出来,但是还希望大家能够尽量的使用括弧来让人看的容易,以免出错,具体优先级表转载如下:更详细的用法可以参考如下链接:/linux/article/development/soft/20060909/4128.html二、 三种程序流程控制结构详解。有了上述的运算,我想大家都可以写出一些很简单的代码了,但是我们在写代码的时候,肯定会遇到类似这样的问题: 有时候,我们写的代码必须要在达到某种条件之后才可以执行,否则不让运行。 有时候,我们写的代码很庞大,很罗嗦,因为它有几种可能需要我们来写出几个程序。 有时候,我们写的代码需要一直重复执行直到某种条件不成立了才不执行。只要你遇到过上述的问题,那我们这节课的内容就正是你所需要的。不多废话,进入正题:1. 顺序结构到现在为止,我们写的所有的代码都是顺序结构的,所谓顺序结构,就是代码从第一条指令开始执行,直到执行完最后一条。中间不会落下任何一条指令。想必大家现在应该能理解什么是顺序结构了,所以我不想再这里浪费太多的篇幅,直接进入下一小节。2. 分支结构所谓分支结构,就是代码在达到某种条件的时候,执行某些指令,否则就执行别的指令。分支结构是改变代码执行顺序最简单的方式,所以大家一定可以很容易的掌握它的,下面让我们一个一个的来看。a) if else结构这个结构算是编程中最基础的结构了,它有三种格式,我在这里列出来,大家可以根据实际情况选择使用哪个:第一种格式:if (条件表达式)/条件成立时执行这里的语句第二种格式:if (条件表达式) /条件成立时执行这里的语句 else/条件不成立时执行这里的语句 第三种格式:if (条件表达式1) /条件表达式1成立时执行这里的语句 else if (条件表达式2)/ 这里的else if可以有无限多个(如果有很多个时可以参考使用switch语句)。 /条件表达式2成立时执行这里的语句 else /条件表达式都不成立时执行这里的语句 为了更好的说明这个语句的用法,我举个例子:int MaxNum(int num001, int num002, int num003)if (num001 = num002)if (num001 = num003)return num001;/ 将 num001 作为函数的结果返回出来。 elsereturn num003;elseif (num002 = num003)return num002; elsereturn num003;说明:上述代码中的功能是从提供的三个数:num001、num002、num003中选出最大的数来。至于与这些if有关的汇编指令就是跳转,像sub,cmp,test,之类的比较指令来影响相应的标志寄存器还有JE,JNE,JB,JNB之类的跳转指令来跳转到指定的代码中执行,大家可以像我们分析算术运算的方式一样,去调试它,去分析它,去掌握这些比较和跳转指令的用法。这里我就省下篇幅,继续我们的switch结构。b) switch 结构上小节中讲述的if语句,是用于少数分支时的处理语句,它写起来方便,代码简洁明了,但是如果一些表达式的结构可能有5种甚至更多种结果,需要我们分别作出不同的处理时,最好的选择就是用wsitch语句。先说明一下switch结构的语法格式:switch(表达式结果或者存放结果的变量)case 结果1:/ 当switch后的括弧中的值是结果时,就执行这里的语句.;break;/ break是用来跳出分支结构的关键字,如果这里没有它,只要结果是结果1,那从结果1开始向下的所有指令都会被执行(包括结果2,结果3)。case 结果2:/ 当switch后的括弧中的值是结果时,就执行这里的语句.;break;/ 如果这里没有这个关键字时,只要上面的结果是结果2,那从结果2开始向下的所有指令都会被执行(包括结果3,结果4)。case 结果3:/ 当switch后的括弧中的值是结果时,就执行这里的语句.;break;/ 同上case 结果N:/ 当switch后的括弧中的值是结果N时,就执行这里的语句.;break;default:/ 当switch后的括弧中的值不是上面列出的任何一个值时,就执行这里的语句.;这里写的可能有点模糊,我给出一个代码片段,我说明一下switch语句的用法:PGAME_CHAR_INFO pGCI = GetCharInfoPoint();switch (pGCI-dwZhiYe)case 1:lstrcpyW(szTemp, L灵剑0);break;case 2:lstrcpyW(szTemp, L日羽0);break;case 3:lstrcpyW(szTemp, L枪侠0);break;case 4:lstrcpyW(szTemp, L萨满0);break;case 5:lstrcpyW(szTemp, L法皇0);break;case 6:lstrcpyW(szTemp, L药王0);break;default:lstrcpyW(szTemp, L未知0);break;其实,这个switch的汇编形式跟if结构很像,唯一的区别就是每个分支后面都会有一个break跳转(JMP)指令,大家可以自己试着去调试这段代码,分析一下尽量掌握这些代码的汇编形式。3. 循环结构所谓循环结构,就是一直重复执行某段指定的语句,知道条件不满足了为止。a) for循环结构好,按照我们的习惯,我先写出这个语句的基本语法结构:for (初始值; 满足条件; 增量)要循环的语句;例如下面的代码:#include stdio.hvoid main()int i = 10;/ 循环打印输出0到之间的所有自然数。for (int x = 0; x i; x+)printf(%dn, x);打印结果如下:通过这个结果和上面的语法结构,我们可以猜测出for语句的执行流程如下图所示:左图中描述了for语句的执行流程,先从上面的语句中执行到for关键字,然后开始初始化操作,在判断一下循环的条件是否满足:如果条件满足,则继续按照绿色的箭头执行,开始执行要循环的语句,执行完以后,会来到增量(或叫 步长)这个语句对计数器(记录循环次数的变量)进行增加,然后在去判断是否满足循环条件,如果满足继续执行要循环的语句,如此循环。直到条件不满足了,按照紫色箭头所示,跳出循环继续执行后面的语句。现在让我们来调试跟踪一下上面的那段程序, 确切的体会下电脑是如何执行循环语句的:1: #include stdio.h2:3: void main()4: 00401010 push ebp00401011 mov ebp,esp00401013 sub esp,48h00401016 push ebx00401017 push esi00401018 push edi00401019 lea edi,ebp-48h0040101C mov ecx,12h00401021 mov eax,0CCCCCCCCh00401026 rep stos dword ptr edi5: int i = 10;00401028 mov dword ptr ebp-4,0Ah; / 初始化变量i6:7: / 循环打印输出0到之间的所有自然数。8: for (int x = 0; x i; x+)0040102F mov dword ptr ebp-8,0; / 初始化x变量00401036 jmp main+31h (00401041); / 强制跳到1041 这个位置00401038 mov eax,dword ptr ebp-80040103B add eax,1; / 自变量加一,继续判断比较0040103E mov dword ptr ebp-8,eax00401041 mov ecx,dword ptr ebp-8; / 开始比较i和x两个变量00401044 cmp ecx,dword ptr ebp-400401047 jge main+4Ch (0040105c); / 如果ebp-8得值(也就是x的值)大于等于i的值则跳出循环9: 10: printf(%dn, x);00401049 mov edx,dword ptr ebp-80040104C push edx0040104D push offset string %dn (0042001c)00401052 call printf (004

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论