- 浏览: 685762 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (297)
- J2SE (78)
- swt/飞信 (20)
- mysql/mssql (17)
- 设计模式 (5)
- windows (18)
- 闲言碎语 (19)
- struts 1.x (6)
- JVM (6)
- tomcat/jetty (8)
- jquery/javascript (15)
- web前端 (6)
- J2EE (0)
- PHP (6)
- 算法设计 (17)
- 数据结构 (3)
- C/C++ (6)
- linux (19)
- 程序打包 (8)
- eclipse/myeclipse (10)
- 其他杂项 (13)
- 应聘 (9)
- spring/spring mvc (4)
- Maven/Ant (2)
- ERROR (1)
- nosql/hbase (1)
- hibernate (3)
- Solr/Lucene (1)
最新评论
-
乔木1937:
太感谢了,看到你的文章终于解决这个问题了!
[转载]通过端口 1433 连接到主机 localhost 的 TCP/IP 连接失败。错误:“Connection refused: connect。 -
xianweisi:
竟然还有马
精简JRE - 实例Swing计算器 with 精简JRE(续) -
Javkburd:
我刚也遇到这个问题,然后也把默认端口改成了1433,只差最后没 ...
[转载]通过端口 1433 连接到主机 localhost 的 TCP/IP 连接失败。错误:“Connection refused: connect。 -
yeshaoting:
kingbinchow 写道 最近的爪哇岛 没有什么货进项呀 ...
jQuery方法区别(四)click() bind() live() delegate()区别 -
kingbinchow:
最近的爪哇岛 没有什么货进项呀!
jQuery方法区别(四)click() bind() live() delegate()区别
【C语言】while与for执行效率对比
C语言编译环境: Microsoft Visual C++ 6.0(SP6)
测试程序
#include "stdio.h" void forTest() { int num = 1234; // 迭代次数 long sum = 0; // 保存加法结果 for(int i=0;i<num;i++) // 传统for循环写法 { sum = sum + i; // 计算结果 } printf("forTest:%d\n",sum); } void whileTest() { int num = 1234; // 迭代次数 long sum = 0; // 保存加法结果 while((num--)>0) { sum = sum + num; // 计算结果 } printf("whileTest:%d\n",sum); } void main() { forTest(); whileTest(); }
汇编片段
whileTest()函数汇编后的指令:
--- D:\VC\ForWhile\ForWhile.cpp ------------------------------------------------------------------------------------------
17: void whileTest() 18: { 0040D760 push ebp 0040D761 mov ebp,esp 0040D763 sub esp,48h 0040D766 push ebx 0040D767 push esi 0040D768 push edi 0040D769 lea edi,[ebp-48h] 0040D76C mov ecx,12h 0040D771 mov eax,0CCCCCCCCh 0040D776 rep stos dword ptr [edi] 19: int num = 1234; 0040D778 mov dword ptr [ebp-4],4D2h 20: long sum = 0; 0040D77F mov dword ptr [ebp-8],0 21: 22: while((num--)>0) 0040D786 mov eax,dword ptr [ebp-4] 0040D789 mov ecx,dword ptr [ebp-4] 0040D78C sub ecx,1 0040D78F mov dword ptr [ebp-4],ecx 0040D792 test eax,eax 0040D794 jle whileTest+41h (0040d7a1) 23: { 24: sum = sum + num; 0040D796 mov edx,dword ptr [ebp-8] 0040D799 add edx,dword ptr [ebp-4] 0040D79C mov dword ptr [ebp-8],edx 25: } 0040D79F jmp whileTest+26h (0040d786) 26: 27: printf("whileTest:%d\n",sum); 0040D7A1 mov eax,dword ptr [ebp-8] 0040D7A4 push eax 0040D7A5 push offset string "whileTest:%d\n" (00422fac) 0040D7AA call printf (0040d6e0) 0040D7AF add esp,8 28: } 0040D7B2 pop edi 0040D7B3 pop esi 0040D7B4 pop ebx 0040D7B5 add esp,48h 0040D7B8 cmp ebp,esp 0040D7BA call __chkesp (0040d6a0) 0040D7BF mov esp,ebp 0040D7C1 pop ebp 0040D7C2 ret
--- No source file -------------------------------------------------------------------------------------------------------
分析:
0040D760~0040D776: 保存栈现场 总共10条指令
0040D778: 迭代次数 总共1条指令
0040D77F: 保存加法结果 总共1条指令
0040D786~0040D79F: while循环 总共10条指令
0040D7A1~0040D7AF: 打印结果 总共5条指令
0040D7B2~0040D7C2: 恢复栈现场 总共9条指令
合计: 36条指令
forTest()函数汇编后的指令:
--- D:\VC\ForWhile\ForWhile.cpp ------------------------------------------------------------------------------------------
4: void forTest() 5: { 0040D3F0 push ebp 0040D3F1 mov ebp,esp 0040D3F3 sub esp,4Ch 0040D3F6 push ebx 0040D3F7 push esi 0040D3F8 push edi 0040D3F9 lea edi,[ebp-4Ch] 0040D3FC mov ecx,13h 0040D401 mov eax,0CCCCCCCCh 0040D406 rep stos dword ptr [edi] 6: int num = 1234; 0040D408 mov dword ptr [ebp-4],4D2h 7: long sum = 0; 0040D40F mov dword ptr [ebp-8],0 8: 9: for(int i=0;i<num;i++) 0040D416 mov dword ptr [ebp-0Ch],0 0040D41D jmp forTest+38h (0040d428) 0040D41F mov eax,dword ptr [ebp-0Ch] 0040D422 add eax,1 0040D425 mov dword ptr [ebp-0Ch],eax 0040D428 mov ecx,dword ptr [ebp-0Ch] 0040D42B cmp ecx,dword ptr [ebp-4] 0040D42E jge forTest+4Bh (0040d43b) 10: { 11: sum = sum + i; 0040D430 mov edx,dword ptr [ebp-8] 0040D433 add edx,dword ptr [ebp-0Ch] 0040D436 mov dword ptr [ebp-8],edx 12: } 0040D439 jmp forTest+2Fh (0040d41f) 13: 14: printf("forTest:%d\n",sum); 0040D43B mov eax,dword ptr [ebp-8] 0040D43E push eax 0040D43F push offset string "forTest:%l\n" (00422e80) 0040D444 call printf (0040d6e0) 0040D449 add esp,8 15: } 0040D44C pop edi 0040D44D pop esi 0040D44E pop ebx 0040D44F add esp,4Ch 0040D452 cmp ebp,esp 0040D454 call __chkesp (0040d6a0) 0040D459 mov esp,ebp 0040D45B pop ebp 0040D45C ret
--- No source file -------------------------------------------------------------------------------------------------------
分析:
0040D3F0~0040D406: 保存栈现场 总共10条指令
0040D408: 迭代次数 总共1条指令
0040D40F: 保存加法结果 总共1条指令
0040D416~0040D439: for循环 总共12条指令
0040D43B~0040D449: 打印结果 总共5条指令
0040D44C~0040D45C: 恢复栈现场 总共9条指令
合计: 38条指令
程序中二个方法语句区别在于一个是for循环,一个是while循环.
对应于,查看到上述二段汇编指令段while循环比for循环少了二条指令.
程序中for循环用的是传统写法,做下更改将for(int i=0;i<num;i++)改为for(;(num--)>0;),其汇编指令为:
--- D:\VC\ForWhile\ForWhile.cpp ------------------------------------------------------------------------------------------
4: void forTest() 5: { 0040D3F0 push ebp 0040D3F1 mov ebp,esp 0040D3F3 sub esp,48h 0040D3F6 push ebx 0040D3F7 push esi 0040D3F8 push edi 0040D3F9 lea edi,[ebp-48h] 0040D3FC mov ecx,12h 0040D401 mov eax,0CCCCCCCCh 0040D406 rep stos dword ptr [edi] 6: int num = 1234; 0040D408 mov dword ptr [ebp-4],4D2h 7: long sum = 0; 0040D40F mov dword ptr [ebp-8],0 8: 9: for(;(num--)>0;) 0040D416 mov eax,dword ptr [ebp-4] 0040D419 mov ecx,dword ptr [ebp-4] 0040D41C sub ecx,1 0040D41F mov dword ptr [ebp-4],ecx 0040D422 test eax,eax 0040D424 jle forTest+41h (0040d431) 10: { 11: sum = sum + num; 0040D426 mov edx,dword ptr [ebp-8] 0040D429 add edx,dword ptr [ebp-4] 0040D42C mov dword ptr [ebp-8],edx 12: } 0040D42F jmp forTest+26h (0040d416) 13: 14: printf("forTest:%d\n",sum); 0040D431 mov eax,dword ptr [ebp-8] 0040D434 push eax 0040D435 push offset string "forTest:%l\n" (00422e80) 0040D43A call printf (0040d6e0) 0040D43F add esp,8 15: } 0040D442 pop edi 0040D443 pop esi 0040D444 pop ebx 0040D445 add esp,48h 0040D448 cmp ebp,esp 0040D44A call __chkesp (0040d6a0) 0040D44F mov esp,ebp 0040D451 pop ebp 0040D452 ret
--- No source file -------------------------------------------------------------------------------------------------------
0040D3F0~0040D406: 保存栈现场 总共10条指令
0040D408: 迭代次数 总共1条指令
0040D40F: 保存加法结果 总共1条指令
0040D416~0040D42F: for循环 总共10条指令
0040D431~0040D43F: 打印结果 总共5条指令
0040D442~0040D452: 恢复栈现场 总共9条指令
合计: 36条指令
由此可见,for循环习惯写法for(int i=0;i<num;i++)执行效率低于for(;(num--)>0;)写法,而for(;(num--)>0;)写法执行效率与while((num--)>0)相同.
因此,一棒子打死说for循环执行效率比while循环慢是不对的.
评论
围观?
都老贴了
这个没有研究,有空看看 .
VC6实在是太旧了.
好吧...
对编译优化不太了解,了解后再进行对比吧.
VC6实在是太旧了.
这么高深的东西还不会。
还有待进一步提高~---
<div class="quote_div">
<p>非常不错.学习啦..</p>
</div>
<p>哈哈...</p>
对这些法则了解不深...
学设计模式的时候也就学了点皮毛.
版块也没必要区分太细.
因为之前写了一篇【Java语言】while与for执行效率对比,然后想看看C里面的情况,就有了这篇.
后面的只是附加之笔.
见谅,我们可以继续这个话题.
不知道分析的是否全面....
<div class="quote_div">
<p> </p>
<div class="quote_title"> 写道</div>
<div class="quote_div">public static int testFor(){<br> int i;<br> int sum = 0;<br> for (i = 0;i < 100;i++){<br> sum = sum + i;<br> }<br> return sum;<br> }<br> public static int testWhile(){<br> int i;<br> int sum = 0;<br> i = 0;<br> while ( i < 100){<br> sum = sum + i;<br> i ++;<br> }<br> return sum;<br> }</div>
<p>字节码指令为:</p>
<p> </p>
<pre name="code" class="java">public static int testFor();
Code:
0: iconst_0
1: istore_1
2: iconst_0
3: istore_0
4: goto 14
7: iload_1
8: iload_0
9: iadd
10: istore_1
11: iinc 0, 1
14: iload_0
15: bipush 100
17: if_icmplt 7
20: iload_1
21: ireturn
public static int testWhile();
Code:
0: iconst_0
1: istore_1
2: iconst_0
3: istore_0
4: goto 14
7: iload_1
8: iload_0
9: iadd
10: istore_1
11: iinc 0, 1
14: iload_0
15: bipush 100
17: if_icmplt 7
20: iload_1
21: ireturn
</pre>
<p>
完全一样</p>
</div>
<p>也是通过字节码得出来的结果呀.</p>
<p>我还以为有什么其他的理论呢.</p>
<p>不错~~</p>
<div class="quote_title"> 写道</div>
<div class="quote_div">public static int testFor(){<br> int i;<br> int sum = 0;<br> for (i = 0;i < 100;i++){<br> sum = sum + i;<br> }<br> return sum;<br> }<br> public static int testWhile(){<br> int i;<br> int sum = 0;<br> i = 0;<br> while ( i < 100){<br> sum = sum + i;<br> i ++;<br> }<br> return sum;<br> }</div>
<p>字节码指令为:</p>
<p> </p>
<pre name="code" class="java">public static int testFor();
Code:
0: iconst_0
1: istore_1
2: iconst_0
3: istore_0
4: goto 14
7: iload_1
8: iload_0
9: iadd
10: istore_1
11: iinc 0, 1
14: iload_0
15: bipush 100
17: if_icmplt 7
20: iload_1
21: ireturn
public static int testWhile();
Code:
0: iconst_0
1: istore_1
2: iconst_0
3: istore_0
4: goto 14
7: iload_1
8: iload_0
9: iadd
10: istore_1
11: iinc 0, 1
14: iload_0
15: bipush 100
17: if_icmplt 7
20: iload_1
21: ireturn
</pre>
<p>
完全一样</p>
兄台为何如此肯定.
给讲讲呗.
发表评论
-
sizeof函数与表达式操作无关
2012-03-21 16:12 1706引子: 在3 ... -
C++函数的调用与参数传递
2011-11-01 10:36 2088C++函数的调用与参数传递 根据函数参数传递的 ... -
百度一面算法题(字符串拷贝)
2011-10-24 12:32 1271完成下述字符串拷贝函数,要求: 1. 将s ... -
百度一面算法题(字符串拷贝)
2011-10-24 12:31 0完成下述字符串拷贝函数,要求: 1. 将src ... -
百度一面算法题(字符串拷贝)
2011-10-10 13:09 15完成下述字符串拷贝函数,要求: 1. 将src_str ... -
[C/C++]华为机试题 2011-9-17
2011-09-18 09:24 1567问题描述: 过滤输入字符串中的重复字符. ... -
[不同编译器]函数参数求值顺序分析(附前置与后置++执行效率)
2011-03-04 11:52 1705[不同编译器]函数参数求值顺序分析(附前置与后置++执行效率) ...
相关推荐
- **优点**:C语言执行效率高,对内存管理有直接控制,适合编写系统级和嵌入式程序。 - **关键字和语法**:`main`函数、`for`和`while`循环、指针操作、结构体、数组等。 - **内存管理**:C语言需要手动分配和...
首先,C语言是计算机科学中的基础编程语言,它的语法简洁、执行效率高,特别适合进行系统级编程和算法实现。通过学习C语言,你可以深入理解计算机的工作原理,为学习其他高级语言打下坚实的基础。 在"蓝桥杯C语言...
3. **效率提升**:由于`foreach`是专门针对数组设计的循环结构,因此在内部实现了更高效的处理方式,避免了传统`for`和`while`循环中可能出现的冗余操作。 4. **语言特性**:在PHP这样的动态类型语言中,`foreach`...
21. **Java和C语言的异同点**:对比两种语言的语法、执行效率和适用场景。 22. **C语言编程技术的分析研究**:分析C语言的各种编程技巧,如递归、循环、函数指针等。 23. **C语言循环语句的应用研究**:深入研究...
C语言中的控制结构包括条件语句(if-else)、循环(for、while、do-while)以及开关语句(switch-case)。这些题目会训练初学者如何根据条件执行不同的代码块,以及如何用循环实现重复操作,这对理解程序流程控制至...
在C语言程序设计教学中,for循环语句是学生在学习程序设计基础知识后接触到的一种循环控制结构,是实现程序重复执行的重要手段之一。它的教学设计直接关系到学生能否有效地掌握循环结构程序设计的思想和方法,进而...
2. **do-while循环**:与while循环不同,do-while循环会先执行一次循环体内的代码,然后再检查条件。这意味着即使条件一开始就不满足,循环体内的代码也会被执行至少一次。 ```c do { // 语句体(执行部分) } ...
3. **C语言知识点**:试题涵盖了C语言的关键知识点,如变量与数据类型、运算符与表达式、流程控制语句(如if、switch、for、while)、函数、数组、指针、结构体与联合体、文件操作等。 4. **编程技巧**:通过历年...
总的来说,do-while和for循环是C语言中控制循环的基本工具,它们提供了灵活的方式来重复执行代码块,根据不同的需求选择合适的循环结构可以极大地提高代码的效率和可读性。在编写循环时,要特别注意条件判断的位置、...
C语言是一种广泛使用的高级编程语言,以其强大的表达能力、灵活性、高执行效率和良好的可移植性著称。在计算机程序设计领域,C语言经常作为入门语言,但其循环结构等概念对于初学者而言难度较大。循环结构是程序控制...
为了加深理解,文章通过一个典型的程序实例,分别使用While、Do-While和For语句实现了相同的循环算法,对比分析了不同循环结构在表达和执行过程中的差异。最终,文章得出结论,For语句在书写上更为灵活,功能上更为...
- 在英语中,句子的阅读顺序决定了理解的逻辑,而在C语言中,虽然书写顺序很重要,但执行顺序可能由控制结构(如if、for、while等)决定,这与英语的线性阅读方式有所不同。 3. **功能与结构**: - 英文文章由...
与`while`不同,`do...while`循环会先执行一次循环体,再检查条件表达式。这意味着`do...while`循环至少会执行一次。当条件不满足时,循环停止。同样,这里有一个使用`do...while`计算1到100的和的例子。对比`while`...
15. **C语言的扩展和C++的联系**:对比C语言与C++,理解C语言作为C++基础的重要性。 在学习过程中,通过实践编程项目和解决实际问题,你可以逐步提升C语言的编程技能。此外,与其他学习者交流,分享经验,也是提高...
通过对比这三种循环语句的编译结果,可以发现`do-while`循环在生成汇编代码时更为简洁,而`while`和`for`循环在多数情况下具有相同的编译效率。 #### 双层循环的编译效率 当涉及到双层循环时,编译器的优化变得...
C语言是一种面向过程的、结构化的编程语言,它的语法简洁明了,执行效率高,适合编写系统软件和应用软件。C语言的关键元素包括变量、常量、数据类型、运算符、控制结构(如if-else、switch-case、for、while等)、...
8. `do`:与`while`一起构成do-while循环。 9. `double`:声明双精度浮点数类型变量。 10. `else`:与if语句配合,表示条件不成立时执行的代码块。 11. `enum`:定义枚举类型,一组命名的整数值。 12. `extern`:...