C语言代码重构案例分析
以下是我在反编译的过程中遇到的一个很有意思的函数(参数名是我修改后的, 方便大家理解), 接下来会一步一步将它重构成一个易于理解的函数.

startX, startY, width, height 都是非负数.

循环替换
首先从最内层的循环开始

do while 语句我们不常用, 并且它的循环条件是放在最后的, 不太利于理解循环, 如果能替换成 for 语句或 while 语句那就比较好. 对于这个循环, 熟悉代码的话很容易转成 for 循环, 初始条件是 v8 = -width, 终止条件是 v8 < 0, 修改迭代变量的语句是v8++.


合并变量
对外层的循环做同样的处理之前, 需要先处理一下它的迭代变量 v9.

这里对 height 的操作完全是可以去掉了. 因为, 在使用循环体内对 height 的操作出现在开始和末尾处, 而循环体的其他部分, v9 和 height 的值一直相等.

将 v9 的初次赋值外提, 然后所有循环中 height 的地方全部用 v9 替代, 最后去掉无用代码就得到了上面的代码. 接着, 用for循环替换外层的 do while 循环.


变量替换
这样的代码现在还不够好 : (1) 内外层的迭代变量变化量不统一, 一个是 v9--, 一个是v8++, 一个减一个加, 有点别扭; (2) 数组的索引一般是正数, 虽然用负数来索引数组是合法的, 但很容易出错, 一不小心就数组越界了.
首先使用变量替换的方法处理外层循环, 令 y = height - v9, 则 y 的初值为0, 终止条件变为
v9 = height - y, v9 是正数, 因而等价于 y < height,
v9-- 等价于 y++ , 因为 v9 + y = height, y与v9的和保持不变.于是外层循环变为 :

同理, 令 x = v8 + width, 则 x 的初值为0, 终止条件为 v8 = x - width, v8 是负数, 因而等价于x < width, v8++等价于 x++, 因为 x - v8 = width, x 和 v8的差保持不变.


指针与数组的转换
这样的代码还不够完美 :

光是看这样的代码, 还是有点难以理解对参数array做了什么.
1. 每次外层循环, v6 增加了32, 也就是 y = 0 时初始v6指针 + 0, y = 1 时 + 32, y = 2 时 + 62. 所以, 可以将v6初值放到第一层循环中.

32 * startY + 32 * y 可以合并为 32 * (startY + y).
2. 使用指针运算继续将对array的操作放到第二层循环中.
v6[x - width] = *(v6 + x - width),
v6 = &array[32 * (startY + y) + startX + width] = array + 32 * (startY + y) + startX + width,
那么 *(v6 + x - width) = *(array + 32 * (startY + y) + startX + width + x - width), 消去width得到
*(array+ 32 * (startY + y) + startX + x) = array[32 * (startY + y) + startX + x]
最终结果为

这样, 就很容易看出来, 这个array其实是一个二维数组, 每行有32个元素, 有多少行不知道. 而这个函数的作用是将左上角为 (startX, startY), 大小为(width, height) 的区域全部设置为value.
