for循环结构的剖析.docxVIP

  • 4
  • 0
  • 约2.72千字
  • 约 3页
  • 2019-01-12 发布于湖北
  • 举报
for循环是我最喜欢的循环结构了,本来以为我对for循环已经很了解了,但在最近是使用之中不断的出问题,所以我又对for循环进行了一次比较深入的“研究”,研究结果使我大吃一惊,不得不感叹,C语言真的是高深莫测啊! 好了,感慨完了,让我们从头开始来聊一聊这个最熟悉但又最难以捉摸的for循环吧。 for循环是C语言中最基本的循环结构了,其典型应用是在已知循环次数时,进行的一系列循环操作。基本语法格式举例如下: for(i=0;i=100;i ) 括号中有三个表达式,其中第一个表达式用来给循环计数器赋初值,第二个表达式用来判断是否满足循环条件,第三个表达式用来改变循环计数器的值。 当然,这只是最基本的用法,这三个表达式并非只能针对同一个变量,甚至,并非每个都必须出现,这只是在循环体的不同位置进行运算的三个普通表达式而已。例如下面,计算n的阶乘,直到大于100为止: a=1; for(i=1;a=100;i ) a*=i; 另外,每个表达式的位置也并非只能放置一个表达式,要知道,C语言中有一种逗号表达式,用逗号将多个表达式分隔开,在处理上,当做一个表达式来对待,最右边的表达式运算结果即为整个表达式的值。基于此理论,上面的阶乘运算可以改写为下面的格式: for(a=1,i=1;a=100;i ) a*=i; 这样写有什么好处呢?当然绝不仅仅是为了扮酷,在结构上,能够将一个整体运算紧密的结合在一起,可以最大限度的减小程序修改时遗漏等失误。Ctrl C和Ctrl V应该在写程序及修改程序中经常用到吧,如果写成这样,在复制过程中想丢掉语句都难。 第二个表达式可以写成逗号表达式的形式吗?当然也可以,不过我现在先不举例,待会会和一些注意事项一起说明。现在我们先把for循环的结构剖析一下,看看for循环究竟是怎样运行的。 首先是第一个表达式,这个表达式虽然是在for循环的循环表达式中出现的,但却不在循环体内,其实是循环体前面紧邻循环体的一个表达式,这也是上面两个写法效果相同的原因。毕竟它本身就是在循环体外面的,前一个程序只是光明正大的给写在了外面。为了证实这一点,我们来看一下for循环的汇编代码(不同编译器可能会有所不同,这里是在Keil4.1下编译的,编译器版本是armcc 28,选择的处理器是8962,因此编译出来的汇编指令是ARM CortexM3的指令)。 第一种写法: 4: a=1; 0x000001A8 2101 MOVS r1,#0x01 5: for(i=1;a=100;i ) a*=i; 0x000001AA 2201 MOVS r2,#0x01 0x000001AC E001 B 0x000001B2 0x000001AE 4351 MULS r1,r2,r1 0x000001B0 1C52 ADDS r2,r2,#1 0x000001B2 2964 CMP r1,#0x64 0x000001B4 DDFB BLE 0x000001AE 6: } 第二种写法: 4: for(a=1,i=1;a=100;i ) a*=i; 0x000001A8 2101 MOVS r1,#0x01 0x000001AA 2201 MOVS r2,#0x01 0x000001AC E001 B 0x000001B2 0x000001AE 4351 MULS r1,r2,r1 0x000001B0 1C52 ADDS r2,r2,#1 0x000001B2 2964 CMP r1,#0x64 0x000001B4 DDFB BLE 0x000001AE 5: } 可以看出,二者编译出来的汇编代码完全一样。在这里,B是跳转指令,在跳转指令下面是循环体。循环体代码如下: 0x000001AE 4351 MULS r1,r2,r1 0x000001B0 1C52 ADDS r2,r2,#1 0x000001B2 2964 CMP r1,#0x64 0x000001B4 DDFB BLE 0x000001AE 了解一些汇编的不难看出来(我也是在验证这个for循环时看了一点ARM汇编,我参考的文档是Cortex-M3 Technical Reference Manual),B

您可能关注的文档

文档评论(0)

1亿VIP精品文档

相关文档