



全文预览已结束
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
关于C语言中运算的讨论姜文周在语言教学中讲到例程序时输出结果分析没有问题。例程序#include stdio.hmain() int i=2,l; k= i + + i+ +i+; printf(n i=%d , k=%d,i,k);输出 i=5 ,k=6在讲到例2时遇到了问题例2#include stdio.hmain() int i,l; i=2; k= +i + ( +i) + (+i); printf(n i=%d , k=%d,i,k);原讲义中说是输出 i=5 ,k=15该讲义以前用过,所以备课时没有仔细分析,授课时学生分析结果应该是i=5 , k=12,当公布结果时引起学生的讨论,由于课堂时间有限没有仔细讨论,承诺下次课前专门讨论。课后将例2程序在计算机上行发现了问题。在TC 2.0编译器下运行,输出是:i=5 ,k=15在VC 6.0编译器下运行,输出是:i=5 ,k=13显然同一个程序在不同的编译器上运行结果不一样,引起兴趣。在百度网上搜索“+i+i+i ”看到了一些讨论的帖子,受到启发,首先看看这些帖子贴1j=(+i)+(+i)+(+i)=(+i)+(+i)+(+i) 计算机在计算j=(a+b)+(c+d)+(e+f)先计算(a+b)+(c+d),并把结果存储(例如:存储在j中),然后再计算j+(e+f)=j; 所以计算机先计算了两个+i(前两项i为3,+i先于+号);也就是j=3+3;然后j=6+(+i)(最后的i为4),也就是j=6+4=10。 首先+i=2,再计算第二个i,此时计算机里i=3,第一个i也=3,第二个i也=3,因为计算机里只有一个i,因此原式=(3+3)+4=10,记住计算机里只有一个i,算第二个时第一个i改变了。 贴2 j=+i+i+i 根据最大可读入原则应该解释成 j=+(i+)+(i+)+i而+(i+)这个是有错误 因为 i+只能作为右值,而前增运算符需要左值。而j=(+i)+(+i)+(+i)在不同的编译器中结果是不样的比如tuborC中为 15 VC中为13(象楼上鱼鹰说的) , 这和编译器的结构有关,讨论起来没有多少意义 。结合帖子的讨论我们再看例2的处理过程。 i=2; k= +i + ( +i) + (+i);我们将这个表达式分为A、B、C三个部分,具体如下: i=2; k= +i + ( +i) + (+i); A B C1. 通常的理解按照C语言的算术优先级的定义,这个表达式的计算次序是:(1) 依据括号的优先级高及同级自左向右的规定,先计算B: 这时i的初值是2,经过+运算后i的值变为2,B表达式的值为3;(2) 然后计算C:这时i的初值是3,经过+运算后i的值变为4,C表达式的值为4;(3) 然后计算A:这时i的初值是4,经过+运算后i的值变为5,C表达式的值为5;(4) 然后将计算表达式A+B的值,5+3 ,结果为8;这个结果用D表示。(5) 然后将计算表达式D+C的值,8+4 ,结果为12;(6) 因此我们12作为整个表达式的结果并赋给K;处理结束。2. TC的处理例2的程序在TC 2.0编译器的处理下,输出的结果是i=5 ,k=15,这是为什么?一个基本概念:编译器在对运算符进行处理时是采用堆栈的模式一次仅对该运算符的运算对象进行运算。(1) 首先按照从左向右扫描:扫描到A部分后,再扫描遇到+,因为+运算符的优先级高于+,因此执行+运算符,但是并没有立即计算A表达式的值(+运算符的先加价后取值,在TC中表现为先执行完表达式中所有同级的运算,再取值),这时i的值变化为3;(2) 继续扫描到B部分,同样先执行+运算,i的值变为4,B表达式的值也没有计算;(3) 同理对C部分处理后i的值变为5,C表达式的值也没有进行处理;(4) 再继续扫描遇到;,因此开始执行“取值”动作,这时i的值是5,因此A表达式的值为5、B表达式的值为5、C表达式的值为;(5) 然后执行A+B运算得到结果为10,用T代表;(6) 然后执行T+C运算得到结果15.因此在TC编译器产生的执行程序计算结果为i=5 ,k=15 。为了验证我们的分析是正确的,我们将程序修改为:#include stdio.hmain() int i,k,j; i=2; k=+i+ (+i) + (+i); printf(n 1. i=%d , k=%d n ,i,k); i=2; k=+i+ (+i) + (+i) + (+i); printf(n 2. i=%d , k=%d n ,i,k); i=2; k=+i+ +i + +i; printf(n 3. i=%d , k=%d n ,i,k); i=2; k=+i+ +i + +i + +i; printf(n 4. i=%d , k=%d n ,i,k); i=2; k=+i+ +i +10+ +i; printf(n 5. i=%d , k=%d n ,i,k); i=2; k=+i+ +i + +i + 10 + +i; printf(n 6. i=%d , k=%d n ,i,k); getch();输出结果是:1. i=5 ,k=15 2. i=6 ,k=24 3. i=5 ,k=15 4. i=6 ,k=24 5. i=6 ,k=25 6. i=6 ,k=34 其中1. 的是原来程序的输出,2.的在原来程序的基础上增加一次+运算产生的输出,3.、4.的输出在1.、2.的基础上验证括号的影响,5.、6.是在1.、2.的基础上验证中间有其他表达式的影响。结论是:TC的处理是在一个表达式中先执行完所有同级的运算,再执行下一步的操作;括号没有影响,因为+运算符的优先级仅次于括号。3. VC的处理我们再看看在VC中的的情况,我们使用例2程序,并记录输出,如下:例2#include stdio.hmain() int i,l; i=2; k= +i + ( +i) + (+i); printf(n i=%d , k=%d,i,k);输出结果是: i=5 ,k=13 我们把计算部分同样分为三个部分,以便分析 i=2; k= +i + ( +i) + (+i); A B CVC编译器的处理遵循基本规则,但是不是整个表达式连续扫描,同优先级的统一计算。(1) 依据括号的优先级高及同级自左向右的规定,先计算B: 这时i的初值是2,经过+运算后i的值变为2,B表达式的值没有取值;(2) 然后查看其后的运算符是+,因此计算A:这时i的初值是3,经过+运算后i的值变为4,同样A表达式还没有取值;(3) 因为A前面没有运算符,因此这是要计算A表达式的值和B表达式的值,因为这时i的值已经是4,因此A、B表达式的值分别是4、4,A+B的运算结果是8,这个结果用T表示;(4) 然后将计算C部分,先执行+运算,i的值变为5,因为C的后面没有其他运算符了,因此就取得C表达式的值 5;(5) 然后将计算表达式T+C的值,8+5 ,结果为13;(6) 因此我们13作为整个表达式的结果并赋给K;处理结束。为了说明我们的分析是可信的,将程序进行扩充。#include stdio.hmain() int i,k,j; i=2; k=+i+ (+i) + (+i); printf(n 1. i=%d , k=%d n ,i,k); i=2; k=+i+ (+i) + (+i) + (+i); printf(n 2. i=%d , k=%d n ,i,k); i=2; k=+i+ (+i) + (+i) + (+i); printf(n 3. i=%d , k=%d n ,i,k); i=2; k=+i+ (+i) + (+i) + (+i); printf(n 4. i=%d , k=%d n ,i,k); /* getch(); */ 输出结果是:1. i=5 ,k=13 2. i=6 ,k=19 3. i=6 ,k=20 4. i=6 ,k=24 程序中表达式可以表述为,i的初值都是1,4个表达式为: 1. k=+i+ (+i) + (+i); 2. k=+i+ (+i) + (+i) + (+i); 3. k=+i+ (+i) + (+i) + (+i); 4. k=+i+ (+i) + (+i) + (+i);第一个前面已经分析过,再看第2个表达式: 2. k=+i+ (+i) + (+i) + (+i); A B C D对应的输出是:i=6 ,k=19 (1) 依据括号的优先级高及同级自左向右的规定,先计算B: 这时i的初值是2,经过+运算后i的值变为2,B表达式的值没有取值;(2) 然后查看其后的运算符是+,因此计算A:这时i的初值是3,经过+运算后i的值变为4,同样A表达式还没有取值;(3) 因为A前面没有运算符,因此这是要计算A表达式的值和B表达式的值,因为这时i的值已经是4,因此A、B表达式的值分别是4、4,A+B的运算结果是8,这个结果用T表示;(4) 然后将计算C部分,先执行+运算,i的值变为5,因为C的后面的运算符是+算符了,因此就取得C表达式的值 5;(5) 然后将计算表达式T+C的值,8+5 ,结果为13,这个结果用S表示;(6) 然后扫描到D表达式部分,同样先执行+运算,i的值变为6,继续扫描遇到;,因此计算D表达式的值,结果为6,这个值作为D部分的值;(7) 然后进行 S + D的计算,13+6结果为19,因此我们19作为整个表达式的结果并赋给K;处理结束。再看第3个表达式: 3. k=+i+ (+i) + (+i) + (+i); A B C D对应的输出是:i=6 ,k=20 (1) 依据括号的优先级高及同级自左向右的规定,先计算B: 这时i的初值是2,经过+运算后i的值变为2,B表达式的值没有取值;(2) 然后查看其后的运算符是+,因此计算A:这时i的初值是3,经过+运算后i的值变为4,同样A表达式还没有取值;(3) 因为A前面没有运算符,因此这是要计算A表达式的值和B表达式的值,因为这时i的值已经是4,因此A、B表达式的值分别是4、4,A+B的运算结果是8,这个结果用T表示;(4) 然后将计算C部分前的左括号,要对对应概括号的表达式进行处理,该括号内有两个子表达式C、D,先对C子表达式的+运算执行,i的值变为5,因为是在一个括号内所以并没有立即取C的值,因此C子表达式的值为空;(5) 继续扫描,到+后,需要处理D子表达式,同样先执行+运算,i的值变为6,然后执行D子表达式前的+运算,因此要取C的值,这时i的值已经是6,因此C字表达式的值为6,同理D子表达式的值也是6,6+6
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 航道工程立项报告
- 贷款房屋装修合同版
- 2025年山东钢铁集团有限公司校园招聘模拟试题附带答案详解及完整答案详解一套
- 2025年工业互联网平台IPv6技术升级下的工业互联网平台智能运维解决方案报告
- 互联网医疗平台在线问诊2025年质量控制与医疗资源配置研究报告
- 2025年网络文学IP开发全产业链跨界合作与价值创造研究报告
- 2025年度环保型住宅小区地面车位租赁管理公约
- 2025年度生态农业苗木种植基地建设与运营管理合同
- 2025年综合医院新生儿护理岗位人员就业服务合同范本
- 2025年夫妻共同财产分割协议离婚办理流程详解及指南
- 2025餐饮业简易劳动合同范本下载
- HSK三级水平考试试题及答案
- 2025年一级建造师《机电工程管理与实务》考前强化模拟练习题库500题(含答案)
- 酒店装修工期管理措施
- 高效能电机研发项目可行性研究报告
- 海南编制考试试题及答案
- 汽车与交通设备行业新能源汽车动力电池热管理系统技术发展报告
- 2025-2030中国移动卫星终端设备行业发展分析及发展趋势与投资前景预测研究报告
- 智慧公交可行性研究报告
- 销售人员廉洁自律心得体会
- 造价咨询应急管理制度
评论
0/150
提交评论