c语言自动点名系统中,只是int i系统会自动赋值吗

当前位置: >
若有定义:double a=22;int i=0,k=18;,则不符合C语言规定的赋值语句是()A.a=a++,i++;& B.i=(a+k)&=(i+k);C.i=a%11;&& D.i=!a;若有定义:double a=22;int i=0,k=18;,则不符合C语言规定的赋值语句是()A.a=a++,i++;& B.i=(a+k)&=(i+k);C.i=a%11;&& D.i=!a;
所属学科:
试题类型:客观题
所属知识点:
试题分数:1.0 分
暂未组卷。
暂无学习笔记。
&&&&&&&&&&&&&&&希赛网 版权所有 & &&c语言中i+=3为什么比i=i+3运行快呢?
看c语言学的视频中,老师讲到这里的时候说i+=3是比i=i+3运行速度快的,这是真的吗?
按投票排序
你们老师的说法是错的,至少是严重过时的。如果i是简单类型比如int, float这种,绝大部分编译器下是一样快的,生成的机器码完全相同。如果是重载过的运算符,那就不好说了,看你函数的实现方式了。不过你既然说的是C不是C++,那不存在重载运算符的情况。
先回答问题,不是,至少在vs2013的编译器下不是默认情况下(无优化),两条代码的汇编指令是相同的开启优化后,编译器会用各种奇技淫巧优化这两条代码,完全超越了inc和add指令本身显然楼下果果的回答更加适合题主,我就在这里稍微写一点高深的(其实也不怎么深)/*无奈本人学识还甚浅(我刚大一好不好),把这些懂得相关编译器知识的人眼中常见的优化看作了黑科技,这个看上去很强大实际上展现出我菜菜的本质的答案因为赵百万赵先生的回复而使得赞同飙升,我的关注也飙升,感谢大家的支持,我还会继续努力大家别再关注了,我会不好意思的*/日18:31:16更新,这么多人赞我还是写好一点吧依照
和其他前辈所言,写了一段小程序来验证#include &stdio.h&
void inc_equal_add(int num, int add);
void inc_add_equal(int num, int add);
int main(void) {
int num, add;
scanf("%d %d", &num, &add);
inc_add_equal(num, add);
inc_equal_add(num, add);
void inc_equal_add(int num, int add) {
num = num + add;
void inc_add_equal(int num, int add) {
num += add;
//想必大家都看得懂代码,原谅我的渣命名然后在vs2013环境下查看汇编代码略去废话,直接进函数部分void inc_add_equal(int num, int add) {
00BC13D0 55
00BC13D1 8B EC
00BC13D3 81 EC C0 00 00 00
00BC13D9 53
00BC13DA 56
00BC13DB 57
00BC13DC 8D BD 40 FF FF FF
edi,[ebp-0C0h]
00BC13E2 B9 30 00 00 00
00BC13E7 B8 CC CC CC CC
eax,0CCCCCCCCh
00BC13EC F3 AB
dword ptr es:[edi]
00BC13EE 8B 45 08
eax,dword ptr [num]
00BC13F1 03 45 0C
eax,dword ptr [add]
00BC13F4 89 45 08
dword ptr [num],eax
00BC13F7 5F
00BC13F8 5E
00BC13F9 5B
00BC13FA 8B E5
00BC13FC 5D
00BC13FD C3
太长不看?直接切入正题: num +=
00BC13EE 8B 45 08
eax,dword ptr [num]
00BC13F1 03 45 0C
eax,dword ptr [add]
00BC13F4 89 45 08
dword ptr [num],eax
编译器干了什么?mov
eax,dword ptr [num]
把num取出来放进eax,eax就是cpu里的寄存器啦add
eax,dword ptr [add]
eax增加add的值,相当于cpu内部执行eax+=addmov
dword ptr [num],eax
eax的值再放回num为什么要取出来再加再放回去呢?我还没系统地学习这些知识,哪位前辈能讲解一下"为什么要取出来再加再放回去呢?"在x86汇编里mov和add(不止他俩还有很多)指令的源操作数和目的操作数不能同时为存储器操作数,即内存单元之间不能用mov指令直接传送或add相加,必须取出到工作寄存器(如eax,ebx)后再进行操作如果这是所谓运算速度快的语句的话,那我们来看看num = num + add是什么样的汇编代码num = num +
00BC142E 8B 45 08
eax,dword ptr [num]
eax,dword ptr [add]
dword ptr [num],eax
完全一样不是吗
所以结论是,不开启优化的情况下,+=和=+在cpu内部完全执行了相同的指令下面我们来看看开启优化后是什么样的情况开启完全优化(好像是Ox)我使用了如下的代码int main(void) {
int i = 2;
i = i + 1;
vs果然暴力,尼玛直接把i+=1和i=i+1这两条删掉了(没打printf编译器视为对i的运算没用,索性没有执行)//有人指出这是很正常的优化技巧,不是vs暴力不暴力的问题汇编代码只剩下xor eax eax
//也就是所谓的return 0
……为了不让编译器把这两条语句优化掉,我在程序最后加了printfint main(void) {
int i = 2;
i = i + 1;
printf("%d", i);
为了防止i的初值是0有可能使编译器又用些什么奇技淫巧,我把i的初值设为了2然后这优化,汇编代码是
int i = 2;
i = i + 1;
printf("%d", i);
000B1EE0 6A 04
000B1EE2 68 14 60 0B 00
000B1EE7 FF 15 C4 70 0B 00
dword ptr ds:[0B70C4h]
000B1EED 83 C4 08
000B1EF0 33 C0
尼玛它直接push 4了啊!!!编译期就已经算完答案了啊!!!要不要这样暴力!!!//啊其实这也是很正常的优化trick然后我每条加法运算后都加了printf,变成了这样
int i = 2;
i = i + 1;
printf("%d", i);
0 14 60 19 01
01191EE7 FF 15 C4 70 19 01
dword ptr ds:[11970C4h]
printf("%d", i);
01191EED 6A 04
01191EEF 68 18 60 19 01
01191EF4 FF 15 C4 70 19 01
dword ptr ds:[11970C4h]
01191EFA 83 C4 10
尼玛这push 3 push 4 是什么黑科技//啊其实这也是很正常的优化为了防止编译器在编译时就已经计算好答案,我加了一条i的输入语句(其实我早该这样的有木有!!现在修改答案都快精分了有木有!!!)然后,不贴代码了,差不多就和最上面的代码一样,只不过加数是1编译器把两条语句都编译成了mov eax word ptr [i]
果然都优化为了inc,优化为inc只在加数为1并且是整数运算时有用所以说,什么+=比=+快什么的完全就是yy而已,可能快一点的只有+=1、=+1这种情况(编译器可以优化汇编为inc),剩下的都是取值,加,赋值优化的力量
如果在x86-64架构上编译器为i=i+3;生成的CPU指令(汇编指令)是mov eax, [i]add eax, 3mov [i], eax而为i+=3;生成的机器码是add [i], 3的话,i=i+3;的确会比i+=3;慢一点。不过现在的编译器一般都会把这两条指令看成一样,而且在实际环境中还可能有优化,例如在孙明琦的答案中做的常量计算和替代,还有可能把变量i作为寄存器变量不存入内存,这些都会导致C语言指令执行速度的不同。
事情是这样的。我相信大部分计算机系的同学都是先从C语言这门课开始,后续才会有汇编,编译原理等知识的学习。如果对于一个刚刚入门学到C语言的+=运算符的人来说,老师这样的表述是没有任何问题的。可以这样理解,对于 i = i + 3; 这个表达式,有两个指令即+和=,所以计算机需要做两件事,先算出i + 3的值,再把这个值赋给i。而 i += 3; 这个表达式只有一个指令+=,计算机只需要做一件事让i自增3。所以你看,只做一件事当然要比做两件事快。而楼上全部回答给出的否定答案所说是你后续要学习的课程如汇编,编译原理里的知识。这里可以简单给题主普及一下,从代码到计算机运行的01机器码,中间还有很长的步骤,而编译的过程是由编译器来做这件事,这就是为什么你写C语言计算机也能运行,尽管它只认识0和1。而编译器也是一门很深的学问,发展至今已经非常厉害了,它不仅能看懂你的代码,并翻译给计算机,而且还能帮你做优化。你看你这里,编译器看懂了你的代码,并且知道+=要比分别做+和=快,但是运算结果是一样的,所以编译器就帮你自动优化啦。题主加油,后续的知识等你学到编译原理就懂了。
不同意这个观点。这几天在研究寄存器分配,早在Chaitin 1980年代的史诗级论文,Register Allocation via Coloring中,就已经指出这种写法是一样的,有理由相信任何一个像样的编译器都会把这两条语句视为等价。
你说i+=3比i=i+3运行快,那是在你的脑海中运算的。如果前者真的比后者快,我想即便是最愚蠢的编译器也会把后者换成前者来优化的吧?这种简单的语句,对于编译器来说,只要表达了意思即可,优化之后连他妈都不认得他这两句话的意思是相同的,因此,没区别。----------------------------------------------------------------------------------------------估计你老师的意思可能是:前者对编译器来说更容易处理一些,后者相对复杂。但是对于现在的编译器来讲,前者是蚊子,后者是苍蝇(更大个),编译器是奥尼尔,怎么捏都能捏死。
完全没有优化的话是这样的。比如自己写一个超简单的编译器的话,右边计算结果需要做为临时变量存在栈上再存到i的内存上。但是现在任何编译器都会做出优化的。
如果编译器傻到这两种表达式效率有区别,那还是用汇编好了……
严格的说,现在的编译器上,i+=3和i=i+3执行速度几乎完全相同。而且题主老师恐怕给题主灌输了一种a+=b和a=a+b效果等价,特地说明一下,它们是有不同点的。(当然,这里b是合法的右值,a也可以被赋值)。下面说一下a+=b和a=a+b的不同:1.计算a+=b只是求一次a的值,而计算a=a+b则会求两次a的值。p.s.这就是为什么很久很久以前a+=b会比a=a+b快的本质原因之一。例子:考虑一下以下两个表达式a[i++]+=2;a[i++]=a[i++]+2;上面的两个表达式中,第一个表达式的值的计算中,是同一个数组元素进行了操作;在第二个表达式中根据编译器执行的顺序点,是不同的两个数组元素进入操作。后面的数组元素加上二赋值给前一个数组元素里。2.优先级不同+=是赋值运算符,优先级低于加法运算。在不同情况下,+=的执行效率不够灵活。例子:考虑一下以下两个表达式i*=j+k;i=i*j+k;很显然,由于优先级,他们不相同。最后说一句。复合赋值运算符是为了方便书写才使用的,有时能让逻辑一目了然,如果说和执行速度有关,那就是误人子弟了。现在的处理器,无脑循环圈套圈很多层,才能让它们的速度降低一点。题主加油↖(^ω^)↗
虽然我不是软件专业毕业,但我是写代码的。从问题可以看出你还没学过编译原理与微机原理,如果学过了,那就肯定没学好。除了汇编之外的语言都是需要编译器依据词法与语法,语义分析之后才进入半机器状态的。最后一步是机器状态的具体实现,也就是实现最后的机器指令,这一步是与平台息息相关的,要看你是什么架构的机器,复杂指令集还是精简指令集,你是哈弗结构还是诺伊曼结构,你的芯片有哪些指令,你的代码会存放在什么位置,什么区段。其中的每一个环节都会影响最终的执行效率。大学老师很多也是雪渣过去的,大家都懂得。因为大牛老师都在当老板赚钱呢。老师的话要批判的听。
已有帐号?
无法登录?
社交帐号登录c语言中有如下定义:int i,j,*p,*q; 那么下列赋值是否正确?(1)p=&*&i;(2)i=*&j;
创未组7482
给你一个图解吧,希望你能采纳.
为您推荐:
其他类似问题
扫描下载二维码c语言程序设计期末试题A(含答案)_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
c语言程序设计期末试题A(含答案)
上传于||文档简介
&&c​语​言​程​序​设​计​期​末​试​题​A​(​含​答​案​)
阅读已结束,如果下载本文需要使用0下载券
想免费下载更多文档?
下载文档到电脑,查找使用更方便
还剩4页未读,继续阅读
你可能喜欢C语言所有题目以及答案_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
C语言所有题目以及答案
上传于||暂无简介
阅读已结束,如果下载本文需要使用0下载券
想免费下载更多文档?
下载文档到电脑,查找使用更方便
还剩13页未读,继续阅读
你可能喜欢}

我要回帖

更多关于 c语言赋值语句 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信