在很多时候,我们需要循环序列,比如循环读取数组的8个元素,便需要索引指针(index)从0-7-0变化,
常规而言,会写出下面的代码
1 | if (++index >= 8) |
或者
1 | index = (++index >= 8)? 0:index; |
观察到这是连续循环操作,所以我们可以用%
的方式,来省掉一个判断语句,如下所示
1 | index = (++index)%8; |
因为++
优先级高于%
,所以进而简化为1
index = ++index%8;
特别注意: 这里是前置递加操作,不要写成后置,如下所示1
index = index++%8;
如果写成后置的,会出现什么情况呢?
分别将二者反汇编(ARM反汇编),如下所示
1 | MOVS R1, #8 |
1 | ADDS R4, R4, #1 |
翻译成C语言如下
1 | index = index%8; |
1 | index = index + 1; |
编译器不支持取余运算,所以需要数学计算,取余等于
A%B = A - (A/B)*B
对此,不做过多解释,重点关注ADD那句的位置,正确的表达式会先计算index的值,然后再取余;
而错误的,则先取余,再递增;
所以,正确的语句index = ++index%8
会输出0 - 1 - 2 ... 7 - 0
序列,错误的会输出1 - 2 ... 7 - 8 - 1
序列