在C语言中采用3中语法来实现循环,它们分别是while、for、do while,本文将分别说明这三种循环的实现,并对它们的运行效率进行比较。

do while

首先来看do while的实现:下面是简单的代码:
int nCount = 0;
int nMax = 10;
do
{
nCount++;
} while (nCount < nMax);
return 0;

下面对应的是它的汇编代码:

9:        int nCount = 0;
00401268 mov dword ptr [ebp-4],0
10: int nMax = 10;
0040126F mov dword ptr [ebp-8],0Ah
11: do
12: {
13: nCount++;
00401276 mov eax,dword ptr [ebp-4]
00401279 add eax,1
0040127C mov dword ptr [ebp-4],eax
14: } while (nCount < nMax);
0040127F mov ecx,dword ptr [ebp-4];exc = nCount
00401282 cmp ecx,dword ptr [ebp-8];比较nCount 和 nMax的值
00401285 jl main+26h (00401276);跳转到循环体中
15: return 0;
00401287 xor eax,eax

在汇编代码中首先执行了一次循环体中的操作,然后判断,当条件满足时会跳转回循环体,然后再次执行,当条件不满足时会接着执行后面的语句。

这个过程可以用goto来模拟:

    int nCount = 0;
int nMax = 10;
__WHILE:
nCount++;
if(nCount < nMax)
goto __WHILE;

while循环

不同于do while的先执行再比较,while采取的是先比较再循环的方式,下面是一个while的例子:

    int nCount = 0;
int nMax = 10;
while (nCount < nMax)
{
nCount++;
}
00401268   mov         dword ptr [ebp-4],0
10: int nMax = 10;
0040126F mov dword ptr [ebp-8],0Ah
11: while (nCount < nMax)
00401276 mov eax,dword ptr [ebp-4]
00401279 cmp eax,dword ptr [ebp-8]
0040127C jge main+39h (00401289)
12: {
13: nCount++;
0040127E mov ecx,dword ptr [ebp-4]
00401281 add ecx,1
00401284 mov dword ptr [ebp-4],ecx
14: }
00401287 jmp main+26h (00401276)
15: return 0;
00401289 xor eax,eax

从汇编代码上可以看出,执行while循环时会有两次跳转,当条件不满足时会执行一次跳转,跳转到循环体外,而条件满足,执行完一次循环后,会再次跳转到循环体中,再次进行比较。相比于do while来说,while执行了两次跳转,效率相对较低。

for 循环

for循环是首先进行初始化操作然后进行比较,条件满足时执行循环,再将循环变量递增,最后再次比较,执行循环或者跳出。下面是for的简单例子:

    int nMax = 10;
for (int i = 0; i < nMax; i++)
{
printf("%d\n", i);
}

下面是它对应的汇编代码:

9:        int nMax = 10;
00401268 mov dword ptr [ebp-4],0Ah
10: for (int i = 0; i < nMax; i++)
0040126F mov dword ptr [ebp-8],0 ;初始化循环变量
00401276 jmp main+31h (00401281);跳转到比较操作处
00401278 mov eax,dword ptr [ebp-8]
0040127B add eax,1
0040127E mov dword ptr [ebp-8],eax;这三句话实现的是循环变量自增操作
00401281 mov ecx,dword ptr [ebp-8];ecx = i
00401284 cmp ecx,dword ptr [ebp-4];比较ecx与i
00401287 jge main+4Ch (0040129c);跳转到循环体外
11: {
12: printf("%d\n", i);
00401289 mov edx,dword ptr [ebp-8]
0040128C push edx
0040128D push offset string "%d\n" (0042e01c)
00401292 call printf (00401540)
00401297 add esp,8
13: }
0040129A jmp main+28h (00401278);跳转到i++位置
14: return 0;
0040129C xor eax,eax

从上面的汇编代码可以看出for循环的效率最低,它经过了3次跳转,生成对应的汇编代码上,初始化操作后面紧接着是循环变量自增操作,所以首先在完成初始化后会进行一次跳转,跳转到判断,然后根据判断条件再次跳转或者接着执行循环体,最后当循环完成后会再次跳转到循环变量自增的位置,同样采用goto语句来模拟这个操作:

    int nMax = 10;
int i = 0;
goto __CMP;
__ADD:
i++;
__CMP:
if (i >= nMax)
{
goto __RETURN;
} __LOOP:
printf("%d\n", i);
goto __ADD;
__RETURN:
return 0;

continue语句

continue用于结束这次循环进入下一次循环,下面采用最复杂的for循环来说明continue语句:
int nMax = 10;
int i = 0;
for(;i < nMax; i++)
{
if (i == 6)
{
continue;
}
}

下面是它对应的汇编代码:

00401268   mov         dword ptr [ebp-4],0Ah
10: int i = 0;
0040126F mov dword ptr [ebp-8],0
11: for(;i < nMax; i++)
00401276 jmp main+31h (00401281)
00401278 mov eax,dword ptr [ebp-8]
0040127B add eax,1
0040127E mov dword ptr [ebp-8],eax
00401281 mov ecx,dword ptr [ebp-8]
00401284 cmp ecx,dword ptr [ebp-4]
00401287 jge main+43h (00401293)
12: {
13: if (i == 6)
00401289 cmp dword ptr [ebp-8],6;
0040128D jne main+41h (00401291);条件不满足组跳转到循环结束处
14: {
15: continue;
0040128F jmp main+28h (00401278)
16: }
17: }
00401291 jmp main+28h (00401278)
18: return 0;
00401293 xor eax,eax

从上面的汇编代码可以看到,continue语句也是一个跳转语句,它会直接跳转到循环体的开始位置。对于for来说相对特殊一些(我觉得循环变量自增并不属于循环体),由于第一次进入循环时并没有执行循环变量自增,所以它会跳转到循环变量自增的位置,其他则直接到循环开始处。

C语言循环的实现的更多相关文章

  1. Go语言循环判断的使用~

    Go 语言条件语句 条件语句需要开发者通过指定一个或多个条件,并通过测试条件是否为 true 来决定是否执行指定语句,并在条件为 false 的情况在执行另外的语句. 下图展示了程序语言中条件语句的结 ...

  2. R语言 循环

    R语言循环 可能有一种情况,当你需要执行一段代码几次. 通常,顺序执行语句. 首先执行函数中的第一个语句,然后执行第二个语句,依此类推. 编程语言提供允许更复杂的执行路径的各种控制结构. 循环语句允许 ...

  3. C语言-循环结构及break、continue

    循环结构 --1-- 结构循环 1.1 while循环 1.2 do…while循环 1.3 for循环 --2-- break和continue 2.1 break关键字 2.2 continue关 ...

  4. go语言循环语句 for

    Go语言中的循环语句只支持for关键字,而不支持while和do-while结构. sum := 0 for i := 0; i < 10; i++ { sum += i } 无限循环的写法: ...

  5. C语言循环的嵌套

    注:参考网络资源拟制,如雷同请见谅循环的嵌套:一个循环体语句中又包含另一个循环语句,称为循环嵌套.嵌套注意事项:1.使用循环嵌套时,内层循环和外层循环的循环控制变量不能相同.2.循环嵌套结构的书写,最 ...

  6. 08-C语言循环

    目录: 一.for循环 二.break,continue 三.循环嵌套 四.while 五.do while 六.三个循环的对比 七.空语句 回到顶部 一.for循环 标识每次循环,循环终止条件,循环 ...

  7. Go 语言循环语句

    在不少实际问题中有许多具有规律性的重复操作,因此在程序中就需要重复执行某些语句. 以下为大多编程语言循环程序的流程图: Go 语言提供了以下几种类型循环处理语句: 循环类型 描述 for 循环 重复执 ...

  8. c语言循环案例

    do while #include <stdio.h> #include <stdlib.h> int main() { int a = 1,b = 10; do { b -= ...

  9. GO语言学习(十一)Go 语言循环语句

    Go 语言提供了以下几种类型循环处理语句: 循环类型 描述 for 循环 重复执行语句块 循环嵌套 在 for 循环中嵌套一个或多个 for 循环 语法 Go语言的For循环有3中形式,只有其中的一种 ...

随机推荐

  1. 【Android】定位与解决anr错误记录

    问题描写叙述 cocos2d-x游戏项目androidproject接入sdk.支付成功后,java代码回调lua方法.产生了anr. 怎样定位anr? watermark/2/text/aHR0cD ...

  2. 《C程序猿从校园到职场》勘误

    (本人正在參加2015博客之星评选.诚邀你来投票,谢谢:username=zhouzxi">http://vote.blog.csdn.net/blogstar2015/candida ...

  3. Struts2中validate数据校验的两种常用方法

    本文主要介绍Struts2中validate数据校验的两种方法及Struts2常用校验器.  1.Action中的validate()方法 Struts2提供了一个Validateable接口,这个接 ...

  4. 数学之美?编程之美?数学 + 编程= unbelievable 美!

    欢迎大家前往腾讯云社区,获取更多腾讯海量技术实践干货哦~ 作者:Rusu 导语 相信大家跟我一样,偶尔会疑惑:曾经年少的时候学习过的那么多的复杂的数学函数,牛逼的化学方程式,各种物理原理.公式,到底有 ...

  5. gulp的基本用法

    这几天简单的研究了一下gulp的用法,gulp对于初学者来说还是很友好的. 官方给出gulp的优点如下: 1.通过代码优于配置的策略,Gulp 让简单的任务简单,复杂的任务可管理. 2.Gulp 严格 ...

  6. 浅析node.js

    大家好,今天来给大家讨论node.js这个东西,说起这个东西啊,可能大家已经很熟悉了,因为现在市场上运用的越来越广泛,毕竟它的优点还是有目共睹的! 那么,什么是node.js呢?官方给出了这样的定义: ...

  7. 有限等距性质RIP

    参考博客:http://blog.csdn.net/jbb0523/article/details/44565647 压缩感知测量矩阵之有限等距性质(Restricted Isometry Prope ...

  8. 自学Zabbix3.4-资产清单inventory

    当监控的设备越来越多,有时候搞不清楚哪台服务器.网络设备是什么配置,abbix专门设置了设备资产管理功能.我们创建或者编辑主机的时候,可以看到清单(inventory)功能.里面大致包含mac地址.硬 ...

  9. linux(ubuntu) 搭建java程序运行环境

    一:简介 ubuntu 系统的和linux差不多,我们需要在系统上搭建java程序运行环境,需要安装jdk,mysql这两个软件,tomcat是绿色版,直接通过taz -zxvf tomcat 就可以 ...

  10. InfluxDB:cannot use field in group by clause

    最近在使用InfluxDB时,发现一个很奇怪的问题,一个本来正常的功能,做了一次改动后,就不能正常显示了. 一.查询语句 SELECT MEMORY FROM "ACM_PROCESS_MO ...