城市直播房产教育博客汽车
投稿投诉
汽车报价
买车新车
博客专栏
专题精品
教育留学
高考读书
房产家居
彩票视频
直播黑猫
投资微博
城市上海
政务旅游

C语言ampampampJava解析当ii后,结果究竟是什么

6月2日 桃花醉投稿
  前言:
  之前有朋友跟我讨论过一个问题,他问在java中,i1;之后的结果是什么,我一开始认为是2,但当他说答案是1的时候,我不得不想一个合理的解释,我想,可能是因为临时变量,当i赋值给i后,自增更改了临时变量,所以i值并没有改变。当我在为我的解释表示满意时,他们说在c语言下的答案是2,好吧,我只能说是编译器的实现不同,当然这个答案太没说服力了,所以寻找答案的任务就开始了。
  我先在《cprimer》上看见这样的解释:i的效率要比i的效率高,因为i必须要有一个临时变量来存放i本身的值,那么我之前只说对了临时变量,但原因是临时变量先用来存放i的值,然后i本身自增,之后,临时变量赋值给左边,这时,i的值又被自己之前的值覆盖了,所以又变成1,但这只是个推测,再说c语言中为什么是2?所以不得不反编译了
  java的jdk自带一个工具,javap,可以反编译,我们用它java编译器生成的jvm版汇编码,我会写下两段代码用来做对比,一种是一种常见的注意,我使用2作为初始值(也就是说它会被自增为3),因为1太特殊了,它在字节码中的变量名随处可见,而且不是加1么,所以我用2做初值,也方便查找。publicclassTest{publicstaticvoidmain(String〔〕args){inti2;System。out。println(i);}}
  javapcTest的字节码如下:publicclassTestextendsjava。lang。Object{publicTest();Code:0:aload01:invokespecial1;MethodjavalangObject。init:()V4:returnpublicstaticvoidmain(java。lang。String〔〕);Code:0:iconst21:istore12:iload13:iinc1,16:istore17:getstatic2;FieldjavalangSystem。out:LjavaioPrintS10:iload111:invokevirtual3;MethodjavaioPrintStream。println:(I)V14:return}0:iconst2将int型的常量2压栈1:istore1将int型值存入变量1中
  就是定义并初始化i的值。
  关键是这里:2:iload1保存变量1的值3:iinc1,1将变量1的值自增(i现在是3了)6:istore将之前的保存值放入变量i中(i现在又变成2了)
  其实在2:iload1时,i变量的值被放在了栈中,这就是我们说的临时存储之后,又被赋了过来
  看看Test2,你就会明白正常的运作:publicclassTest2{publicstaticvoidmain(String〔〕args){inti2;intj0;System。out。println(j);}}
  javapcTest2的字节码如下:publicclassTest2extendsjava。lang。Object{publicTest2();Code:0:aload01:invokespecial1;MethodjavalangObject。init:()V4:returnpublicstaticvoidmain(java。lang。String〔〕);Code:0:iconst21:istore12:iconst03:istore24:iload15:iinc1,18:istore29:getstatic2;FieldjavalangSystem。out:LjavaioPrintS12:iload213:invokevirtual3;MethodjavaioPrintStream。println:(I)V16:return}4:iload1变量1的值被保存(入栈)5:iinc1,1i自增8istore2弹栈,赋值给变量2。
  现在明白了吧,,到底发生了什么
  但是还没完,,,,,我们还没解释在c语言中发生了什么
  在gcc中,编译一个c程序要四个阶段,预处理,编译,汇编,链接。我们在编译阶段后停下,这样会得到ATT的汇编码,
  我们写下两种代码,类似于java版
  先看正常情况:includestdio。hintmain(){inti2;intj0;printf(jd,j);return0;}
  编译成汇编码:。filetest。c。section。rodata。LC0:。stringjd。text。globlmain。typemain,functionmain:pushlebpmovlesp,ebpandl16,espsubl32,espmovl2,28(esp)movl0,24(esp)movl28(esp),eaxmovleax,24(esp)addl1,28(esp)movl。LC0,eaxmovl24(esp),edxmovledx,4(esp)movleax,(esp)callprintfmovl0,eaxleaveret。sizemain,。main。identGCC:(Ubuntu4。4。34ubuntu5。1)4。4。3。section。note。GNUstack,,progbits
  包括movl。LC0,eax和之后语句的都和输出有关了。
  我们再把初始化有关的除去,关键的部分是:movl28(esp),eaxmovleax,24(esp)addl1,28(esp)
  保存了i的值,(放在eax中),之后又放入j中,i再自增,这就很符合大家心里的答案,那么如果是ii时自然就是i被赋值,再自增也就是大家心中的答案了,但是真是这样么?我们继续看includestdio。hintmain(){inti2;printf(id,i);return0;}
  对应的汇编码:。filetest2。c。section。rodata。LC0:。stringid。text。globlmain。typemain,functionmain:pushlebpmovlesp,ebpandl16,espsubl32,espmovl2,28(esp)addl1,28(esp)movl。LC0,eaxmovl28(esp),edxmovledx,4(esp)movleax,(esp)callprintfmovl0,eaxleaveret。sizemain,。main。identGCC:(Ubuntu4。4。34ubuntu5。1)4。4。3。section。note。GNUstack,,progbits
  关键部分就省一句了addl1,28(esp)这简直就是看我的test3。c吧includestdio。hintmain(){inti2;i;printf(id,i);return0;}
  产生的汇编码:aiqieraiqierlaptop:ctest3cattest3。s
  。filetest3。c。section。rodata。LC0:。stringid。text。globlmain。typemain,functionmain:pushlebpmovlesp,ebpandl16,espsubl32,espmovl2,28(esp)addl1,28(esp)movl。LC0,eaxmovl28(esp),edxmovledx,4(esp)movleax,(esp)callprintfmovl0,eaxleaveret。sizemain,。main。identGCC:(Ubuntu4。4。34ubuntu5。1)4。4。3。section。note。GNUstack,,progbits
  恩,在c语言中居然跟i;的汇编代码一样,按正常的逻辑(我们之前的分析),i2;i的值是3,已经没问题了,但是gcc会对编译器做一些优化,所以保存i的值,再赋值给i,这两条语句自然是鸡肋了,就被优化掉了。
  总结,我们发现对于i保存的临时值,java中是自增在返回临时值,而c语言中是返回临时值后,在自增,所以这就是为什么ii在这两种语言中不同的结果了,c我就不知道了,有兴趣的同学可以试试,python么,没有啦,呵呵,如果我的分析有什么不对之初,希望能与你一起探讨。
  另外,对现在我们的大多数朋友来说还是学编程技术最重要!栽一棵树最好的时间是十年前,其次是现在。对于准备学习编程的小伙伴,如果你想更好地提升你的编程核心能力(内功)不妨从现在开始!
  编程学习书籍分享:
  编程学习视频分享:
  整理分享(多年学习的源码、项目实战视频、项目笔记,基础入门教程)
  欢迎转行和学习编程的伙伴,利用更多的资料学习成长比自己琢磨更快哦!
  对于CC感兴趣可以关注小编在后台私信我:【编程交流】一起来学习哦!可以领取一些CC的项目学习视频资料哦!已经设置好了关键词自动回复,自动领取就好了!
投诉 评论 转载

聊聊手机上的指纹功能日更第316365天大家好,今天是大年初一,大船在这里祝大家新年快乐,虎年身体健康,事业有成,阖家欢乐。接下来和大家聊一聊手机上的指纹功能。大船印象中最早在手……C语言ampampampJava解析当ii后,结果究竟是什么前言:之前有朋友跟我讨论过一个问题,他问在java中,i1;之后的结果是什么,我一开始认为是2,但当他说答案是1的时候,我不得不想一个合理的解释,我想,可能是因为临……银联开通新功能一键开关所有银行卡双免服务N海都记者夏雨晴实习生刘梓怡海都讯4月3日,中国银联官网发布消息,对小额免密免签的闪付服务,开通一键开关功能,后续持卡人可以在1个App内,开关多张银行卡的小额业务。此外……宁德时代推出钠离子电池PK比亚迪锂电池,曾毓群能否击败王传福为什么要击败?两个国产都发扬光大不好么?为什么要窝里斗?联合起来占领国际市场不香么??这不能说谁击败谁,宁德时代推出钠离子电池,比亚迪也会推出它的新产品,科技是日新月异,……蓝色光标X阿里达摩院打造虚拟直播间已售出34间近日,蓝色光标公布与阿里巴巴达摩院共同打造的虚拟直播间业务进展:已签约售出34间,价格为9。9万元间,购买品牌涵盖母婴、美妆、保健、家清、3C等多品类企业。其中一家美妆品牌透露……国行港版美版的iPhone13系列,价格相差多少?一起来看看苹果最新发布的iPhone13系列手机,相信大家最关心的一定是价格,国行的价格大家已经知道了,今天畅玩君特总结了各主要地区的iPhone13系列的价格,主要为国行,港版,美版,……华为2022年04月11日新消息华为华为2022年04月11日新消息美国给世界提醒英国禁用华为是它劝的网友:要这么直白么?华为5G新机Mate40EPro5G今日开售售价6……京北方与京东方,名字好业绩靓板块热(1)京北方002987,主营为金融机构提供信息技术服务和业务流程外包服务,A股总股本2。249亿股,流通A股9298万股。2021年中报划每股0。54元,预期2021年全年划……电商特供产品,质量不能缩水春节临近,全国多地集中开展2022年新春打假专项行动,对较为畅销的电商特供商品加强监督抽检,受到广大网友称赞。目前,质量不达标等问题已成为电商特供商品的痛点,其该如何回归物美价……世界上昂贵的三种香烟,最后一种,一盒相当于一辆宝马车!第三名:Behike雪茄烟来自古巴,价值15000欧元,约合人民币15万元。雪茄采用的原料是七至九年的烟叶,包装十分精致,盒内装有40根的雪茄烟,一根价格约375欧元。……澳门轻轨正式开通,免费乘搭!内附购物攻略热烈庆祝澳门轻轨正式开通!即日起至年底,免费!免费!免费!免费时间即日起至12月31日运营时间周一至周四上午6:30晚上23:15周五至周日公共假期上午……本来想买华为P50Pro,因为没有5G不得不放弃,刚好入手m买的是pro使用的是骁龙888plus的处理器,属于高端产品。颜色选的是晨晖金,有点偏粉,十分漂亮。拍照功能非常不错的三颗大底主摄,5000万主摄6400万长焦6400万黑白,……
realme新机即将来袭,配置硬核,深泽直人亲自操刀13台根服务器均不在中国,一旦发生紧急情况,网络会瘫痪吗?时隔一年小米再抛百亿港元回购计划对业务和前景充满信心富士康回应昆山工厂停产已将生产转移到其它地方腾讯虚惊一场面向未来的100项颠覆性技术创新iOS15。3正式版来了,有必要升小巨人也能大创新(经济新方位中小微企业发展)汽车业新一轮抢人大战白热化IQOO8昨天正式发布,犹豫想买的建议看看段伟文颠覆性科技创新需要顾及社会和伦理丨告别2021提问思想外媒评选国内外目前最佳机型,苹果三星上榜,国产出人意料
生命在于什么作文音乐殿堂直播助力戏曲文化传承推动传统文化创新发展热议聚热点网 对话人生四十而大惑之大惑在哪里呢?北方人最爱的5道下酒菜,实惠又好吃,老酒鬼最后一个经典实习工作计划房屋常识想问下装修如何提取公积金父爱的作文掺在米粥里的爱校园的一角作文400字由一枚烟花想到的Baby你可不可以不勇敢!三美齐聚或成事实?杨紫,加油上汽通用为什么会在武汉投资建设汽车工厂?

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找江西南阳嘉兴昆明铜陵滨州广东西昌常德梅州兰州阳江运城金华广西萍乡大理重庆诸暨泉州安庆南充武汉辽宁