C語言代碼重構(gòu)案例分析
????以下是我在反編譯的過程中遇到的一個(gè)很有意思的函數(shù)(參數(shù)名是我修改后的, 方便大家理解), 接下來會(huì)一步一步將它重構(gòu)成一個(gè)易于理解的函數(shù).

startX, startY, width, height 都是非負(fù)數(shù).

循環(huán)替換
????首先從最內(nèi)層的循環(huán)開始

????do while 語句我們不常用, 并且它的循環(huán)條件是放在最后的, 不太利于理解循環(huán), 如果能替換成 for 語句或 while 語句那就比較好. 對(duì)于這個(gè)循環(huán), 熟悉代碼的話很容易轉(zhuǎn)成 for 循環(huán), 初始條件是 v8 = -width, 終止條件是 v8 < 0, 修改迭代變量的語句是v8++.
? ??

????

合并變量
????對(duì)外層的循環(huán)做同樣的處理之前, 需要先處理一下它的迭代變量 v9.

????這里對(duì) height 的操作完全是可以去掉了. 因?yàn)? 在使用循環(huán)體內(nèi)對(duì) height 的操作出現(xiàn)在開始和末尾處, 而循環(huán)體的其他部分, v9 和 height 的值一直相等.

????將 v9 的初次賦值外提, 然后所有循環(huán)中 height 的地方全部用 v9 替代, 最后去掉無用代碼就得到了上面的代碼. 接著, 用for循環(huán)替換外層的 do while 循環(huán).


變量替換
????這樣的代碼現(xiàn)在還不夠好 : (1) 內(nèi)外層的迭代變量變化量不統(tǒng)一, 一個(gè)是 v9--, 一個(gè)是v8++, 一個(gè)減一個(gè)加, 有點(diǎn)別扭; (2) 數(shù)組的索引一般是正數(shù), 雖然用負(fù)數(shù)來索引數(shù)組是合法的, 但很容易出錯(cuò), 一不小心就數(shù)組越界了.
????首先使用變量替換的方法處理外層循環(huán), 令 y = height - v9, 則 y 的初值為0, 終止條件變?yōu)?
v9 = height - y, v9 是正數(shù), 因而等價(jià)于 y < height,?
v9-- 等價(jià)于 y++?, 因?yàn)?v9 + y = height, y與v9的和保持不變.于是外層循環(huán)變?yōu)?:

????同理, 令 x = v8 + width, 則 x 的初值為0, 終止條件為 v8 = x - width, v8 是負(fù)數(shù), 因而等價(jià)于x? < width, v8++等價(jià)于 x++, 因?yàn)?x - v8 = width, x 和 v8的差保持不變.?


指針與數(shù)組的轉(zhuǎn)換
????這樣的代碼還不夠完美 :

????光是看這樣的代碼, 還是有點(diǎn)難以理解對(duì)參數(shù)array做了什么.
? ? 1. 每次外層循環(huán), v6 增加了32, 也就是 y = 0 時(shí)初始v6指針 + 0, y = 1 時(shí) + 32, y = 2 時(shí) + 62. 所以, 可以將v6初值放到第一層循環(huán)中.

????32 * startY + 32 * y 可以合并為 32 * (startY + y).
????2. 使用指針運(yùn)算繼續(xù)將對(duì)array的操作放到第二層循環(huán)中.
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]
????最終結(jié)果為

????這樣, 就很容易看出來, 這個(gè)array其實(shí)是一個(gè)二維數(shù)組, 每行有32個(gè)元素, 有多少行不知道. 而這個(gè)函數(shù)的作用是將左上角為 (startX, startY), 大小為(width, height) 的區(qū)域全部設(shè)置為value.
